PageSourceSearch

https://www.uranodiagnostics.com/js/lodash.js

js uranodiagnostics.com collected 2026-09-24 13:35:47 UTC 460,190 bytes, 14,430 lines download raw bytes

1/**
2 * @license
3 * lodash 4.0.1 (Custom Build) <https://lodash.com/>
4 * Build: `lodash -d -o ./lodash.js`
5 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8 * Available under MIT license <https://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 as the semantic version number. */
16  var VERSION = '4.0.1';
17
18  /** Used to compose bitmasks for wrapper metadata. */
19  var BIND_FLAG = 1,
20      BIND_KEY_FLAG = 2,
21      CURRY_BOUND_FLAG = 4,
22      CURRY_FLAG = 8,
23      CURRY_RIGHT_FLAG = 16,
24      PARTIAL_FLAG = 32,
25      PARTIAL_RIGHT_FLAG = 64,
26      ARY_FLAG = 128,
27      REARG_FLAG = 256,
28      FLIP_FLAG = 512;
29
30  /** Used to compose bitmasks for comparison styles. */
31  var UNORDERED_COMPARE_FLAG = 1,
32      PARTIAL_COMPARE_FLAG = 2;
33
34  /** Used as default options for `_.truncate`. */
35  var DEFAULT_TRUNC_LENGTH = 30,
36      DEFAULT_TRUNC_OMISSION = '...';
37
38  /** Used to detect hot functions by number of calls within a span of milliseconds. */
39  var HOT_COUNT = 150,
40      HOT_SPAN = 16;
41
42  /** Used as the size to enable large array optimizations. */
43  var LARGE_ARRAY_SIZE = 200;
44
45  /** Used to indicate the type of lazy iteratees. */
46  var LAZY_FILTER_FLAG = 1,
47      LAZY_MAP_FLAG = 2,
48      LAZY_WHILE_FLAG = 3;
49
50  /** Used as the `TypeError` message for "Functions" methods. */
51  var FUNC_ERROR_TEXT = 'Expected a function';
52
53  /** Used to stand-in for `undefined` hash values. */
54  var HASH_UNDEFINED = '__lodash_hash_undefined__';
55
56  /** Used as references for various `Number` constants. */
57  var INFINITY = 1 / 0,
58      MAX_SAFE_INTEGER = 9007199254740991,
59      MAX_INTEGER = 1.7976931348623157e+308,
60      NAN = 0 / 0;
61
62  /** Used as references for the maximum length and index of an array. */
63  var MAX_ARRAY_LENGTH = 4294967295,
64      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
65      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
66
67  /** Used as the internal argument placeholder. */
68  var PLACEHOLDER = '__lodash_placeholder__';
69
70  /** `Object#toString` result references. */
71  var argsTag = '[object Arguments]',
72      arrayTag = '[object Array]',
73      boolTag = '[object Boolean]',
74      dateTag = '[object Date]',
75      errorTag = '[object Error]',
76      funcTag = '[object Function]',
77      genTag = '[object GeneratorFunction]',
78      mapTag = '[object Map]',
79      numberTag = '[object Number]',
80      objectTag = '[object Object]',
81      regexpTag = '[object RegExp]',
82      setTag = '[object Set]',
83      stringTag = '[object String]',
84      symbolTag = '[object Symbol]',
85      weakMapTag = '[object WeakMap]';
86
87  var arrayBufferTag = '[object ArrayBuffer]',
88      float32Tag = '[object Float32Array]',
89      float64Tag = '[object Float64Array]',
90      int8Tag = '[object Int8Array]',
91      int16Tag = '[object Int16Array]',
92      int32Tag = '[object Int32Array]',
93      uint8Tag = '[object Uint8Array]',
94      uint8ClampedTag = '[object Uint8ClampedArray]',
95      uint16Tag = '[object Uint16Array]',
96      uint32Tag = '[object Uint32Array]';
97
98  /** Used to match empty string literals in compiled template source. */
99  var reEmptyStringLeading = /\b__p \+= '';/g,
100      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
101      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
102
103  /** Used to match HTML entities and HTML characters. */
104  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
105      reUnescapedHtml = /[&<>"'`]/g,
106      reHasEscapedHtml = RegExp(reEscapedHtml.source),
107      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
108
109  /** Used to match template delimiters. */
110  var reEscape = /<%-([\s\S]+?)%>/g,
111      reEvaluate = /<%([\s\S]+?)%>/g,
112      reInterpolate = /<%=([\s\S]+?)%>/g;
113
114  /** Used to match property names within property paths. */
115  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
116      reIsPlainProp = /^\w*$/,
117      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
118
119  /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
120  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
121      reHasRegExpChar = RegExp(reRegExpChar.source);
122
123  /** Used to match leading and trailing whitespace. */
124  var reTrim = /^\s+|\s+$/g,
125      reTrimStart = /^\s+/,
126      reTrimEnd = /\s+$/;
127
128  /** Used to match backslashes in property paths. */
129  var reEscapeChar = /\\(\\)?/g;
130
131  /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
132  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
133
134  /** Used to match `RegExp` flags from their coerced string values. */
135  var reFlags = /\w*$/;
136
137  /** Used to detect hexadecimal string values. */
138  var reHasHexPrefix = /^0x/i;
139
140  /** Used to detect bad signed hexadecimal string values. */
141  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
142
143  /** Used to detect binary string values. */
vendor: 5,530 bytes, lines 144-257
144  var reIsBinary = /^0b[01]+$/i;
145
146  /** Used to detect host constructors (Safari > 5). */
147  var reIsHostCtor = /^\[object .+?Constructor\]$/;
148
149  /** Used to detect octal string values. */
150  var reIsOctal = /^0o[0-7]+$/i;
151
152  /** Used to detect unsigned integer values. */
153  var reIsUint = /^(?:0|[1-9]\d*)$/;
154
155  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
156  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
157
158  /** Used to ensure capturing order of template delimiters. */
159  var reNoMatch = /($^)/;
160
161  /** Used to match unescaped characters in compiled string literals. */
162  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
163
164  /** Used to compose unicode character classes. */
165  var rsAstralRange = '\\ud800-\\udfff',
166      rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
167      rsComboSymbolsRange = '\\u20d0-\\u20f0',
168      rsDingbatRange = '\\u2700-\\u27bf',
169      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
170      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
171      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
172      rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
173      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
174      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
175      rsVarRange = '\\ufe0e\\ufe0f',
176      rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
177
178  /** Used to compose unicode capture groups. */
179  var rsAstral = '[' + rsAstralRange + ']',
180      rsBreak = '[' + rsBreakRange + ']',
181      rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
182      rsDigits = '\\d+',
183      rsDingbat = '[' + rsDingbatRange + ']',
184      rsLower = '[' + rsLowerRange + ']',
185      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
186      rsFitz = '\\ud83c[\\udffb-\\udfff]',
187      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
188      rsNonAstral = '[^' + rsAstralRange + ']',
189      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
190      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
191      rsUpper = '[' + rsUpperRange + ']',
192      rsZWJ = '\\u200d';
193
194  /** Used to compose unicode regexes. */
195  var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
196      rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
197      reOptMod = rsModifier + '?',
198      rsOptVar = '[' + rsVarRange + ']?',
199      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
200      rsSeq = rsOptVar + reOptMod + rsOptJoin,
201      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
202      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
203
204  /**
205   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
206   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
207   */
208  var reComboMark = RegExp(rsCombo, 'g');
209
210  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
211  var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
212
213  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
214  var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
215
216  /** Used to match non-compound words composed of alphanumeric characters. */
217  var reBasicWord = /[a-zA-Z0-9]+/g;
218
219  /** Used to match complex or compound words. */
220  var reComplexWord = RegExp([
221    rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
222    rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
223    rsUpper + '?' + rsLowerMisc + '+',
224    rsUpper + '+',
225    rsDigits,
226    rsEmoji
227  ].join('|'), 'g');
228
229  /** Used to detect strings that need a more robust regexp to match words. */
230  var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
231
232  /** Used to assign default `context` object properties. */
233  var contextProps = [
234    'Array', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function',
235    'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
236    'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
237    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
238    'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
239  ];
240
241  /** Used to make template sourceURLs easier to identify. */
242  var templateCounter = -1;
243
244  /** Used to identify `toStringTag` values of typed arrays. */
245  var typedArrayTags = {};
246  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
247  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
248  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
249  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
250  typedArrayTags[uint32Tag] = true;
251  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
252  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
253  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
254  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
255  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
256  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
257  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
258
259  /** Used to identify `toStringTag` values supported by `_.clone`. */
260  var cloneableTags = {};
261  cloneableTags[argsTag] = cloneableTags[arrayTag] =
262  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
263  cloneableTags[dateTag] = cloneableTags[float32Tag] =
264  cloneableTags[float64Tag] = cloneableTags[int8Tag] =
265  cloneableTags[int16Tag] = cloneableTags[int32Tag] =
266  cloneableTags[mapTag] = cloneableTags[numberTag] =
267  cloneableTags[objectTag] = cloneableTags[regexpTag] =
268  cloneableTags[setTag] = cloneableTags[stringTag] =
269  cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
270  cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
271  cloneableTags[uint32Tag] = true;
272  cloneableTags[errorTag] = cloneableTags[funcTag] =
273  cloneableTags[weakMapTag] = false;
274
275  /** Used to map latin-1 supplementary letters to basic latin letters. */
276  var deburredLetters = {
277    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
278    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
279    '\xc7': 'C',  '\xe7': 'c',
280    '\xd0': 'D',  '\xf0': 'd',
281    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
282    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
283    '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
284    '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
285    '\xd1': 'N',  '\xf1': 'n',
286    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
287    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
288    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
289    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
290    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
291    '\xc6': 'Ae', '\xe6': 'ae',
292    '\xde': 'Th', '\xfe': 'th',
293    '\xdf': 'ss'
294  };
295
296  /** Used to map characters to HTML entities. */
297  var htmlEscapes = {
298    '&': '&amp;',
299    '<': '&lt;',
300    '>': '&gt;',
301    '"': '&quot;',
302    "'": '&#39;',
303    '`': '&#96;'
304  };
305
306  /** Used to map HTML entities to characters. */
307  var htmlUnescapes = {
308    '&amp;': '&',
309    '&lt;': '<',
310    '&gt;': '>',
311    '&quot;': '"',
312    '&#39;': "'",
313    '&#96;': '`'
314  };
315
316  /** Used to determine if values are of the language type `Object`. */
317  var objectTypes = {
318    'function': true,
319    'object': true
320  };
321
322  /** Used to escape characters for inclusion in compiled string literals. */
323  var stringEscapes = {
324    '\\': '\\',
325    "'": "'",
326    '\n': 'n',
327    '\r': 'r',
328    '\u2028': 'u2028',
329    '\u2029': 'u2029'
330  };
331
332  /** Built-in method references without a dependency on `root`. */
333  var freeParseFloat = parseFloat,
334      freeParseInt = parseInt;
335
336  /** Detect free variable `exports`. */
337  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
338
339  /** Detect free variable `module`. */
340  var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
341
342  /** Detect free variable `global` from Node.js. */
343  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
344
345  /** Detect free variable `self`. */
346  var freeSelf = checkGlobal(objectTypes[typeof self] && self);
347
348  /** Detect free variable `window`. */
349  var freeWindow = checkGlobal(objectTypes[typeof window] && window);
350
351  /** Detect the popular CommonJS extension `module.exports`. */
352  var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
353
354  /** Detect `this` as the global object. */
355  var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
356
357  /**
358   * Used as a reference to the global object.
359   *
360   * The `this` value is used if it's the global object to avoid Greasemonkey's
361   * restricted `window` object, otherwise the `window` object is used.
362   */
363  var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
364
365  /*--------------------------------------------------------------------------*/
366
367  /**
368   * Adds the key-value `pair` to `map`.
369   *
370   * @private
371   * @param {Object} map The map to modify.
372   * @param {Array} pair The key-value pair to add.
373   * @returns {Object} Returns `map`.
374   */
375  function addMapEntry(map, pair) {
376    map.set(pair[0], pair[1]);
377    return map;
378  }
379
380  /**
381   * Adds `value` to `set`.
382   *
383   * @private
384   * @param {Object} set The set to modify.
385   * @param {*} value The value to add.
386   * @returns {Object} Returns `set`.
387   */
388  function addSetEntry(set, value) {
389    set.add(value);
390    return set;
391  }
392
393  /**
394   * A faster alternative to `Function#apply`, this function invokes `func`
395   * with the `this` binding of `thisArg` and the arguments of `args`.
396   *
397   * @private
398   * @param {Function} func The function to invoke.
399   * @param {*} thisArg The `this` binding of `func`.
400   * @param {...*} [args] The arguments to invoke `func` with.
401   * @returns {*} Returns the result of `func`.
402   */
403  function apply(func, thisArg, args) {
404    var length = args ? args.length : 0;
405    switch (length) {
406      case 0: return func.call(thisArg);
407      case 1: return func.call(thisArg, args[0]);
408      case 2: return func.call(thisArg, args[0], args[1]);
409      case 3: return func.call(thisArg, args[0], args[1], args[2]);
410    }
411    return func.apply(thisArg, args);
412  }
413
414  /**
415   * Creates a new array concatenating `array` with `other`.
416   *
417   * @private
418   * @param {Array} array The first array to concatenate.
419   * @param {Array} other The second array to concatenate.
420   * @returns {Array} Returns the new concatenated array.
vendor: 11,925 bytes, lines 421-826
421   */
422  function arrayConcat(array, other) {
423    var index = -1,
424        length = array.length,
425        othIndex = -1,
426        othLength = other.length,
427        result = Array(length + othLength);
428
429    while (++index < length) {
430      result[index] = array[index];
431    }
432    while (++othIndex < othLength) {
433      result[index++] = other[othIndex];
434    }
435    return result;
436  }
437
438  /**
439   * A specialized version of `_.forEach` for arrays without support for
440   * iteratee shorthands.
441   *
442   * @private
443   * @param {Array} array The array to iterate over.
444   * @param {Function} iteratee The function invoked per iteration.
445   * @returns {Array} Returns `array`.
446   */
447  function arrayEach(array, iteratee) {
448    var index = -1,
449        length = array.length;
450
451    while (++index < length) {
452      if (iteratee(array[index], index, array) === false) {
453        break;
454      }
455    }
456    return array;
457  }
458
459  /**
460   * A specialized version of `_.forEachRight` for arrays without support for
461   * iteratee shorthands.
462   *
463   * @private
464   * @param {Array} array The array to iterate over.
465   * @param {Function} iteratee The function invoked per iteration.
466   * @returns {Array} Returns `array`.
467   */
468  function arrayEachRight(array, iteratee) {
469    var length = array.length;
470
471    while (length--) {
472      if (iteratee(array[length], length, array) === false) {
473        break;
474      }
475    }
476    return array;
477  }
478
479  /**
480   * A specialized version of `_.every` for arrays without support for
481   * iteratee shorthands.
482   *
483   * @private
484   * @param {Array} array The array to iterate over.
485   * @param {Function} predicate The function invoked per iteration.
486   * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
487   */
488  function arrayEvery(array, predicate) {
489    var index = -1,
490        length = array.length;
491
492    while (++index < length) {
493      if (!predicate(array[index], index, array)) {
494        return false;
495      }
496    }
497    return true;
498  }
499
500  /**
501   * A specialized version of `_.filter` for arrays without support for
502   * iteratee shorthands.
503   *
504   * @private
505   * @param {Array} array The array to iterate over.
506   * @param {Function} predicate The function invoked per iteration.
507   * @returns {Array} Returns the new filtered array.
508   */
509  function arrayFilter(array, predicate) {
510    var index = -1,
511        length = array.length,
512        resIndex = -1,
513        result = [];
514
515    while (++index < length) {
516      var value = array[index];
517      if (predicate(value, index, array)) {
518        result[++resIndex] = value;
519      }
520    }
521    return result;
522  }
523
524  /**
525   * A specialized version of `_.includes` for arrays without support for
526   * specifying an index to search from.
527   *
528   * @private
529   * @param {Array} array The array to search.
530   * @param {*} target The value to search for.
531   * @returns {boolean} Returns `true` if `target` is found, else `false`.
532   */
533  function arrayIncludes(array, value) {
534    return !!array.length && baseIndexOf(array, value, 0) > -1;
535  }
536
537  /**
538   * A specialized version of `_.includesWith` for arrays without support for
539   * specifying an index to search from.
540   *
541   * @private
542   * @param {Array} array The array to search.
543   * @param {*} target The value to search for.
544   * @param {Function} comparator The comparator invoked per element.
545   * @returns {boolean} Returns `true` if `target` is found, else `false`.
546   */
547  function arrayIncludesWith(array, value, comparator) {
548    var index = -1,
549        length = array.length;
550
551    while (++index < length) {
552      if (comparator(value, array[index])) {
553        return true;
554      }
555    }
556    return false;
557  }
558
559  /**
560   * A specialized version of `_.map` for arrays without support for iteratee
561   * shorthands.
562   *
563   * @private
564   * @param {Array} array The array to iterate over.
565   * @param {Function} iteratee The function invoked per iteration.
566   * @returns {Array} Returns the new mapped array.
567   */
568  function arrayMap(array, iteratee) {
569    var index = -1,
570        length = array.length,
571        result = Array(length);
572
573    while (++index < length) {
574      result[index] = iteratee(array[index], index, array);
575    }
576    return result;
577  }
578
579  /**
580   * Appends the elements of `values` to `array`.
581   *
582   * @private
583   * @param {Array} array The array to modify.
584   * @param {Array} values The values to append.
585   * @returns {Array} Returns `array`.
586   */
587  function arrayPush(array, values) {
588    var index = -1,
589        length = values.length,
590        offset = array.length;
591
592    while (++index < length) {
593      array[offset + index] = values[index];
594    }
595    return array;
596  }
597
598  /**
599   * A specialized version of `_.reduce` for arrays without support for
600   * iteratee shorthands.
601   *
602   * @private
603   * @param {Array} array The array to iterate over.
604   * @param {Function} iteratee The function invoked per iteration.
605   * @param {*} [accumulator] The initial value.
606   * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
607   * @returns {*} Returns the accumulated value.
608   */
609  function arrayReduce(array, iteratee, accumulator, initAccum) {
610    var index = -1,
611        length = array.length;
612
613    if (initAccum && length) {
614      accumulator = array[++index];
615    }
616    while (++index < length) {
617      accumulator = iteratee(accumulator, array[index], index, array);
618    }
619    return accumulator;
620  }
621
622  /**
623   * A specialized version of `_.reduceRight` for arrays without support for
624   * iteratee shorthands.
625   *
626   * @private
627   * @param {Array} array The array to iterate over.
628   * @param {Function} iteratee The function invoked per iteration.
629   * @param {*} [accumulator] The initial value.
630   * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
631   * @returns {*} Returns the accumulated value.
632   */
633  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
634    var length = array.length;
635    if (initAccum && length) {
636      accumulator = array[--length];
637    }
638    while (length--) {
639      accumulator = iteratee(accumulator, array[length], length, array);
640    }
641    return accumulator;
642  }
643
644  /**
645   * A specialized version of `_.some` for arrays without support for iteratee
646   * shorthands.
647   *
648   * @private
649   * @param {Array} array The array to iterate over.
650   * @param {Function} predicate The function invoked per iteration.
651   * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
652   */
653  function arraySome(array, predicate) {
654    var index = -1,
655        length = array.length;
656
657    while (++index < length) {
658      if (predicate(array[index], index, array)) {
659        return true;
660      }
661    }
662    return false;
663  }
664
665  /**
666   * The base implementation of methods like `_.max` and `_.min` which accepts a
667   * `comparator` to determine the extremum value.
668   *
669   * @private
670   * @param {Array} array The array to iterate over.
671   * @param {Function} iteratee The iteratee invoked per iteration.
672   * @param {Function} comparator The comparator used to compare values.
673   * @returns {*} Returns the extremum value.
674   */
675  function baseExtremum(array, iteratee, comparator) {
676    var index = -1,
677        length = array.length;
678
679    while (++index < length) {
680      var value = array[index],
681          current = iteratee(value);
682
683      if (current != null && (computed === undefined
684            ? current === current
685            : comparator(current, computed)
686          )) {
687        var computed = current,
688            result = value;
689      }
690    }
691    return result;
692  }
693
694  /**
695   * The base implementation of methods like `_.find` and `_.findKey`, without
696   * support for iteratee shorthands, which iterates over `collection` using
697   * `eachFunc`.
698   *
699   * @private
700   * @param {Array|Object} collection The collection to search.
701   * @param {Function} predicate The function invoked per iteration.
702   * @param {Function} eachFunc The function to iterate over `collection`.
703   * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
704   * @returns {*} Returns the found element or its key, else `undefined`.
705   */
706  function baseFind(collection, predicate, eachFunc, retKey) {
707    var result;
708    eachFunc(collection, function(value, key, collection) {
709      if (predicate(value, key, collection)) {
710        result = retKey ? key : value;
711        return false;
712      }
713    });
714    return result;
715  }
716
717  /**
718   * The base implementation of `_.findIndex` and `_.findLastIndex` without
719   * support for iteratee shorthands.
720   *
721   * @private
722   * @param {Array} array The array to search.
723   * @param {Function} predicate The function invoked per iteration.
724   * @param {boolean} [fromRight] Specify iterating from right to left.
725   * @returns {number} Returns the index of the matched value, else `-1`.
726   */
727  function baseFindIndex(array, predicate, fromRight) {
728    var length = array.length,
729        index = fromRight ? length : -1;
730
731    while ((fromRight ? index-- : ++index < length)) {
732      if (predicate(array[index], index, array)) {
733        return index;
734      }
735    }
736    return -1;
737  }
738
739  /**
740   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
741   *
742   * @private
743   * @param {Array} array The array to search.
744   * @param {*} value The value to search for.
745   * @param {number} fromIndex The index to search from.
746   * @returns {number} Returns the index of the matched value, else `-1`.
747   */
748  function baseIndexOf(array, value, fromIndex) {
749    if (value !== value) {
750      return indexOfNaN(array, fromIndex);
751    }
752    var index = fromIndex - 1,
753        length = array.length;
754
755    while (++index < length) {
756      if (array[index] === value) {
757        return index;
758      }
759    }
760    return -1;
761  }
762
763  /**
764   * The base implementation of `_.reduce` and `_.reduceRight`, without support
765   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
766   *
767   * @private
768   * @param {Array|Object} collection The collection to iterate over.
769   * @param {Function} iteratee The function invoked per iteration.
770   * @param {*} accumulator The initial value.
771   * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
772   * @param {Function} eachFunc The function to iterate over `collection`.
773   * @returns {*} Returns the accumulated value.
774   */
775  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
776    eachFunc(collection, function(value, index, collection) {
777      accumulator = initAccum
778        ? (initAccum = false, value)
779        : iteratee(accumulator, value, index, collection);
780    });
781    return accumulator;
782  }
783
784  /**
785   * The base implementation of `_.sortBy` which uses `comparer` to define
786   * the sort order of `array` and replaces criteria objects with their
787   * corresponding values.
788   *
789   * @private
790   * @param {Array} array The array to sort.
791   * @param {Function} comparer The function to define sort order.
792   * @returns {Array} Returns `array`.
793   */
794  function baseSortBy(array, comparer) {
795    var length = array.length;
796
797    array.sort(comparer);
798    while (length--) {
799      array[length] = array[length].value;
800    }
801    return array;
802  }
803
804  /**
805   * The base implementation of `_.sum` without support for iteratee shorthands.
806   *
807   * @private
808   * @param {Array} array The array to iterate over.
809   * @param {Function} iteratee The function invoked per iteration.
810   * @returns {number} Returns the sum.
811   */
812  function baseSum(array, iteratee) {
813    var result,
814        index = -1,
815        length = array.length;
816
817    while (++index < length) {
818      var current = iteratee(array[index]);
819      if (current !== undefined) {
820        result = result === undefined ? current : (result + current);
821      }
822    }
823    return result;
824  }
825
826  /**
827   * The base implementation of `_.times` without support for iteratee shorthands
828   * or max array length checks.
829   *
830   * @private
831   * @param {number} n The number of times to invoke `iteratee`.
832   * @param {Function} iteratee The function invoked per iteration.
833   * @returns {Array} Returns the array of results.
834   */
835  function baseTimes(n, iteratee) {
836    var index = -1,
837        result = Array(n);
838
839    while (++index < n) {
840      result[index] = iteratee(index);
841    }
842    return result;
843  }
844
845  /**
846   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
847   * of key-value pairs for `object` corresponding to the property names of `props`.
848   *
849   * @private
850   * @param {Object} object The object to query.
851   * @param {Array} props The property names to get values for.
852   * @returns {Object} Returns the new array of key-value pairs.
853   */
854  function baseToPairs(object, props) {
855    return arrayMap(props, function(key) {
856      return [key, object[key]];
857    });
858  }
859
860  /**
861   * The base implementation of `_.unary` without support for storing wrapper metadata.
862   *
863   * @private
864   * @param {Function} func The function to cap arguments for.
865   * @returns {Function} Returns the new function.
866   */
867  function baseUnary(func) {
868    return function(value) {
869      return func(value);
870    };
871  }
872
873  /**
874   * The base implementation of `_.values` and `_.valuesIn` which creates an
875   * array of `object` property values corresponding to the property names
876   * of `props`.
877   *
878   * @private
879   * @param {Object} object The object to query.
880   * @param {Array} props The property names to get values for.
881   * @returns {Object} Returns the array of property values.
882   */
883  function baseValues(object, props) {
884    return arrayMap(props, function(key) {
885      return object[key];
886    });
887  }
888
889  /**
890   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
891   * that is not found in the character symbols.
892   *
893   * @private
894   * @param {Array} strSymbols The string symbols to inspect.
895   * @param {Array} chrSymbols The character symbols to find.
896   * @returns {number} Returns the index of the first unmatched string symbol.
897   */
898  function charsStartIndex(strSymbols, chrSymbols) {
899    var index = -1,
900        length = strSymbols.length;
901
902    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
903    return index;
904  }
905
906  /**
907   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
908   * that is not found in the character symbols.
909   *
910   * @private
911   * @param {Array} strSymbols The string symbols to inspect.
912   * @param {Array} chrSymbols The character symbols to find.
913   * @returns {number} Returns the index of the last unmatched string symbol.
914   */
915  function charsEndIndex(strSymbols, chrSymbols) {
916    var index = strSymbols.length;
917
918    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
919    return index;
920  }
921
922  /**
923   * Checks if `value` is a global object.
924   *
925   * @private
926   * @param {*} value The value to check.
927   * @returns {null|Object} Returns `value` if it's a global object, else `null`.
928   */
929  function checkGlobal(value) {
930    return (value && value.Object === Object) ? value : null;
931  }
932
933  /**
934   * Compares values to sort them in ascending order.
935   *
936   * @private
937   * @param {*} value The value to compare.
938   * @param {*} other The other value to compare.
939   * @returns {number} Returns the sort order indicator for `value`.
940   */
941  function compareAscending(value, other) {
942    if (value !== other) {
943      var valIsNull = value === null,
944          valIsUndef = value === undefined,
945          valIsReflexive = value === value;
946
947      var othIsNull = other === null,
948          othIsUndef = other === undefined,
949          othIsReflexive = other === other;
950
951      if ((value > other && !othIsNull) || !valIsReflexive ||
952          (valIsNull && !othIsUndef && othIsReflexive) ||
953          (valIsUndef && othIsReflexive)) {
954        return 1;
955      }
956      if ((value < other && !valIsNull) || !othIsReflexive ||
957          (othIsNull && !valIsUndef && valIsReflexive) ||
958          (othIsUndef && valIsReflexive)) {
959        return -1;
960      }
961    }
962    return 0;
963  }
964
965  /**
966   * Used by `_.orderBy` to compare multiple properties of a value to another
967   * and stable sort them.
968   *
969   * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
970   * specify an order of "desc" for descending or "asc" for ascending sort order
971   * of corresponding values.
972   *
973   * @private
974   * @param {Object} object The object to compare.
975   * @param {Object} other The other object to compare.
976   * @param {boolean[]|string[]} orders The order to sort by for each property.
977   * @returns {number} Returns the sort order indicator for `object`.
978   */
979  function compareMultiple(object, other, orders) {
980    var index = -1,
981        objCriteria = object.criteria,
982        othCriteria = other.criteria,
983        length = objCriteria.length,
984        ordersLength = orders.length;
985
986    while (++index < length) {
987      var result = compareAscending(objCriteria[index], othCriteria[index]);
988      if (result) {
989        if (index >= ordersLength) {
990          return result;
991        }
992        var order = orders[index];
993        return result * (order == 'desc' ? -1 : 1);
994      }
995    }
996    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
997    // that causes it, under certain circumstances, to provide the same value for
998    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
999    // for more details.
1000    //
1001    // This also ensures a stable sort in V8 and other engines.
1002    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
1003    return object.index - other.index;
1004  }
1005
1006  /**
1007   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1008   *
1009   * @private
1010   * @param {string} letter The matched letter to deburr.
1011   * @returns {string} Returns the deburred letter.
1012   */
1013  function deburrLetter(letter) {
1014    return deburredLetters[letter];
1015  }
1016
1017  /**
1018   * Used by `_.escape` to convert characters to HTML entities.
1019   *
1020   * @private
1021   * @param {string} chr The matched character to escape.
1022   * @returns {string} Returns the escaped character.
1023   */
1024  function escapeHtmlChar(chr) {
1025    return htmlEscapes[chr];
1026  }
1027
1028  /**
1029   * Used by `_.template` to escape characters for inclusion in compiled string literals.
1030   *
1031   * @private
1032   * @param {string} chr The matched character to escape.
1033   * @returns {string} Returns the escaped character.
1034   */
1035  function escapeStringChar(chr) {
1036    return '\\' + stringEscapes[chr];
1037  }
1038
1039  /**
1040   * Gets the index at which the first occurrence of `NaN` is found in `array`.
1041   *
1042   * @private
1043   * @param {Array} array The array to search.
1044   * @param {number} fromIndex The index to search from.
1045   * @param {boolean} [fromRight] Specify iterating from right to left.
1046   * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1047   */
1048  function indexOfNaN(array, fromIndex, fromRight) {
1049    var length = array.length,
1050        index = fromIndex + (fromRight ? 0 : -1);
1051
1052    while ((fromRight ? index-- : ++index < length)) {
1053      var other = array[index];
1054      if (other !== other) {
1055        return index;
1056      }
1057    }
1058    return -1;
1059  }
1060
1061  /**
1062   * Checks if `value` is a host object in IE < 9.
1063   *
1064   * @private
1065   * @param {*} value The value to check.
1066   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1067   */
1068  function isHostObject(value) {
1069    // Many host objects are `Object` objects that can coerce to strings
1070    // despite having improperly defined `toString` methods.
1071    var result = false;
1072    if (value != null && typeof value.toString != 'function') {
1073      try {
1074        result = !!(value + '');
1075      } catch (e) {}
1076    }
1077    return result;
1078  }
1079
1080  /**
1081   * Checks if `value` is a valid array-like index.
1082   *
1083   * @private
1084   * @param {*} value The value to check.
1085   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1086   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1087   */
1088  function isIndex(value, length) {
1089    value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1090    length = length == null ? MAX_SAFE_INTEGER : length;
1091    return value > -1 && value % 1 == 0 && value < length;
1092  }
1093
1094  /**
1095   * Converts `iterator` to an array.
1096   *
1097   * @private
1098   * @param {Object} iterator The iterator to convert.
1099   * @returns {Array} Returns the converted array.
1100   */
1101  function iteratorToArray(iterator) {
1102    var data,
1103        result = [];
1104
1105    while (!(data = iterator.next()).done) {
1106      result.push(data.value);
1107    }
1108    return result;
1109  }
1110
1111  /**
1112   * Converts `map` to an array.
1113   *
1114   * @private
1115   * @param {Object} map The map to convert.
1116   * @returns {Array} Returns the converted array.
1117   */
1118  function mapToArray(map) {
1119    var index = -1,
1120        result = Array(map.size);
1121
1122    map.forEach(function(value, key) {
1123      result[++index] = [key, value];
1124    });
1125    return result;
1126  }
1127
1128  /**
1129   * Replaces all `placeholder` elements in `array` with an internal placeholder
1130   * and returns an array of their indexes.
1131   *
1132   * @private
1133   * @param {Array} array The array to modify.
1134   * @param {*} placeholder The placeholder to replace.
1135   * @returns {Array} Returns the new array of placeholder indexes.
1136   */
1137  function replaceHolders(array, placeholder) {
1138    var index = -1,
1139        length = array.length,
1140        resIndex = -1,
1141        result = [];
1142
1143    while (++index < length) {
1144      if (array[index] === placeholder) {
1145        array[index] = PLACEHOLDER;
1146        result[++resIndex] = index;
1147      }
1148    }
1149    return result;
1150  }
1151
1152  /**
1153   * Converts `set` to an array.
1154   *
1155   * @private
1156   * @param {Object} set The set to convert.
1157   * @returns {Array} Returns the converted array.
1158   */
1159  function setToArray(set) {
1160    var index = -1,
1161        result = Array(set.size);
1162
1163    set.forEach(function(value) {
1164      result[++index] = value;
1165    });
1166    return result;
1167  }
1168
1169  /**
1170   * Gets the number of symbols in `string`.
1171   *
1172   * @private
1173   * @param {string} string The string to inspect.
1174   * @returns {number} Returns the string size.
1175   */
1176  function stringSize(string) {
1177    if (!(string && reHasComplexSymbol.test(string))) {
1178      return string.length;
1179    }
1180    var result = reComplexSymbol.lastIndex = 0;
1181    while (reComplexSymbol.test(string)) {
1182      result++;
1183    }
1184    return result;
1185  }
1186
1187  /**
1188   * Converts `string` to an array.
1189   *
1190   * @private
1191   * @param {string} string The string to convert.
1192   * @returns {Array} Returns the converted array.
1193   */
1194  function stringToArray(string) {
1195    return string.match(reComplexSymbol);
1196  }
1197
1198  /**
1199   * Used by `_.unescape` to convert HTML entities to characters.
1200   *
1201   * @private
1202   * @param {string} chr The matched character to unescape.
1203   * @returns {string} Returns the unescaped character.
1204   */
1205  function unescapeHtmlChar(chr) {
1206    return htmlUnescapes[chr];
1207  }
1208
1209  /*--------------------------------------------------------------------------*/
1210
1211  /**
1212   * Create a new pristine `lodash` function using the `context` object.
1213   *
1214   * @static
1215   * @memberOf _
1216   * @category Util
1217   * @param {Object} [context=root] The context object.
1218   * @returns {Function} Returns a new `lodash` function.
1219   * @example
1220   *
1221   * _.mixin({ 'foo': _.constant('foo') });
1222   *
1223   * var lodash = _.runInContext();
1224   * lodash.mixin({ 'bar': lodash.constant('bar') });
1225   *
1226   * _.isFunction(_.foo);
1227   * // => true
1228   * _.isFunction(_.bar);
1229   * // => false
1230   *
1231   * lodash.isFunction(lodash.foo);
1232   * // => false
1233   * lodash.isFunction(lodash.bar);
1234   * // => true
1235   *
1236   * // using `context` to mock `Date#getTime` use in `_.now`
1237   * var mock = _.runInContext({
1238   *   'Date': function() {
1239   *     return { 'getTime': getTimeMock };
1240   *   }
1241   * });
1242   *
1243   * // or creating a suped-up `defer` in Node.js
1244   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1245   */
1246  function runInContext(context) {
1247    context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1248
1249    /** Built-in constructor references. */
1250    var Date = context.Date,
1251        Error = context.Error,
1252        Math = context.Math,
1253        RegExp = context.RegExp,
1254        TypeError = context.TypeError;
1255
1256    /** Used for built-in method references. */
1257    var arrayProto = context.Array.prototype,
1258        objectProto = context.Object.prototype;
1259
1260    /** Used to resolve the decompiled source of functions. */
1261    var funcToString = context.Function.prototype.toString;
1262
1263    /** Used to check objects for own properties. */
1264    var hasOwnProperty = objectProto.hasOwnProperty;
1265
1266    /** Used to generate unique IDs. */
1267    var idCounter = 0;
1268
1269    /** Used to infer the `Object` constructor. */
1270    var objectCtorString = funcToString.call(Object);
1271
1272    /**
1273     * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1274     * of values.
1275     */
1276    var objectToString = objectProto.toString;
1277
1278    /** Used to restore the original `_` reference in `_.noConflict`. */
1279    var oldDash = root._;
1280
1281    /** Used to detect if a method is native. */
1282    var reIsNative = RegExp('^' +
1283      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1284      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1285    );
1286
1287    /** Built-in value references. */
1288    var Reflect = context.Reflect,
1289        Symbol = context.Symbol,
1290        Uint8Array = context.Uint8Array,
1291        clearTimeout = context.clearTimeout,
1292        enumerate = Reflect ? Reflect.enumerate : undefined,
1293        getPrototypeOf = Object.getPrototypeOf,
1294        getOwnPropertySymbols = Object.getOwnPropertySymbols,
1295        iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1296        propertyIsEnumerable = objectProto.propertyIsEnumerable,
1297        setTimeout = context.setTimeout,
1298        splice = arrayProto.splice;
1299
1300    /* Built-in method references for those with the same name as other `lodash` methods. */
1301    var nativeCeil = Math.ceil,
1302        nativeFloor = Math.floor,
1303        nativeIsFinite = context.isFinite,
1304        nativeJoin = arrayProto.join,
1305        nativeKeys = Object.keys,
1306        nativeMax = Math.max,
1307        nativeMin = Math.min,
1308        nativeParseInt = context.parseInt,
1309        nativeRandom = Math.random,
1310        nativeReverse = arrayProto.reverse;
1311
1312    /* Built-in method references that are verified to be native. */
1313    var Map = getNative(context, 'Map'),
1314        Set = getNative(context, 'Set'),
1315        WeakMap = getNative(context, 'WeakMap'),
1316        nativeCreate = getNative(Object, 'create');
1317
1318    /** Used to store function metadata. */
1319    var metaMap = WeakMap && new WeakMap;
1320
1321    /** Used to detect maps and sets. */
1322    var mapCtorString = Map ? funcToString.call(Map) : '',
1323        setCtorString = Set ? funcToString.call(Set) : '';
1324
1325    /** Used to convert symbols to primitives and strings. */
1326    var symbolProto = Symbol ? Symbol.prototype : undefined,
1327        symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
1328        symbolToString = Symbol ? symbolProto.toString : undefined;
1329
1330    /** Used to lookup unminified function names. */
1331    var realNames = {};
1332
1333    /*------------------------------------------------------------------------*/
1334
1335    /**
1336     * Creates a `lodash` object which wraps `value` to enable implicit method
1337     * chaining. Methods that operate on and return arrays, collections, and
1338     * functions can be chained together. Methods that retrieve a single value or
1339     * may return a primitive value will automatically end the chain sequence and
1340     * return the unwrapped value. Otherwise, the value must be unwrapped with
1341     * `_#value`.
1342     *
1343     * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1344     * may be enabled using `_.chain`.
1345     *
1346     * The execution of chained methods is lazy, that is, it's deferred until
1347     * `_#value` is implicitly or explicitly called.
1348     *
1349     * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1350     * fusion is an optimization to merge iteratee calls; this avoids the creation
1351     * of intermediate arrays and can greatly reduce the number of iteratee executions.
1352     * Sections of a chain sequence qualify for shortcut fusion if the section is
1353     * applied to an array of at least two hundred elements and any iteratees
1354     * accept only one argument. The heuristic for whether a section qualifies
1355     * for shortcut fusion is subject to change.
1356     *
1357     * Chaining is supported in custom builds as long as the `_#value` method is
1358     * directly or indirectly included in the build.
1359     *
1360     * In addition to lodash methods, wrappers have `Array` and `String` methods.
1361     *
1362     * The wrapper `Array` methods are:
1363     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1364     *
1365     * The wrapper `String` methods are:
1366     * `replace` and `split`
1367     *
1368     * The wrapper methods that support shortcut fusion are:
1369     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1370     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1371     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1372     *
1373     * The chainable wrapper methods are:
1374     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
1375     * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
1376     * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
1377     * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1378     * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
1379     * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
1380     * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
1381     * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invokeMap`,
1382     * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
1383     * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
1384     * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
1385     * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`,
1386     * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`,
1387     * `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`,
1388     * `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`,
1389     * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`,
1390     * `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`,
1391     * `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`,
1392     * `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`,
1393     * `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `without`,
1394     * `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, and `zipWith`
1395     *
1396     * The wrapper methods that are **not** chainable by default are:
1397     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1398     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1399     * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
1400     * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
1401     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1402     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1403     * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1404     * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
1405     * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
1406     * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
1407     * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
1408     * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
1409     * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
1410     * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
1411     * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
1412     * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
1413     * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
1414     * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
1415     * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
1416     * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
1417     * `upperCase`, `upperFirst`, `value`, and `words`
1418     *
1419     * @name _
1420     * @constructor
1421     * @category Seq
1422     * @param {*} value The value to wrap in a `lodash` instance.
1423     * @returns {Object} Returns the new `lodash` wrapper instance.
1424     * @example
1425     *
1426     * function square(n) {
1427     *   return n * n;
1428     * }
1429     *
1430     * var wrapped = _([1, 2, 3]);
1431     *
1432     * // returns an unwrapped value
1433     * wrapped.reduce(_.add);
1434     * // => 6
1435     *
1436     * // returns a wrapped value
1437     * var squares = wrapped.map(square);
1438     *
1439     * _.isArray(squares);
1440     * // => false
1441     *
1442     * _.isArray(squares.value());
1443     * // => true
1444     */
1445    function lodash(value) {
1446      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1447        if (value instanceof LodashWrapper) {
1448          return value;
1449        }
1450        if (hasOwnProperty.call(value, '__wrapped__')) {
1451          return wrapperClone(value);
1452        }
1453      }
1454      return new LodashWrapper(value);
1455    }
1456
1457    /**
1458     * The function whose prototype all chaining wrappers inherit from.
1459     *
1460     * @private
1461     */
1462    function baseLodash() {
1463      // No operation performed.
1464    }
1465
1466    /**
1467     * The base constructor for creating `lodash` wrapper objects.
1468     *
1469     * @private
1470     * @param {*} value The value to wrap.
1471     * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1472     */
1473    function LodashWrapper(value, chainAll) {
1474      this.__wrapped__ = value;
1475      this.__actions__ = [];
1476      this.__chain__ = !!chainAll;
1477      this.__index__ = 0;
1478      this.__values__ = undefined;
1479    }
1480
1481    /**
1482     * By default, the template delimiters used by lodash are like those in
1483     * embedded Ruby (ERB). Change the following template settings to use
1484     * alternative delimiters.
1485     *
1486     * @static
1487     * @memberOf _
1488     * @type Object
1489     */
1490    lodash.templateSettings = {
1491
1492      /**
1493       * Used to detect `data` property values to be HTML-escaped.
1494       *
1495       * @memberOf _.templateSettings
1496       * @type RegExp
1497       */
1498      'escape': reEscape,
1499
1500      /**
1501       * Used to detect code to be evaluated.
1502       *
1503       * @memberOf _.templateSettings
1504       * @type RegExp
1505       */
1506      'evaluate': reEvaluate,
1507
1508      /**
1509       * Used to detect `data` property values to inject.
1510       *
1511       * @memberOf _.templateSettings
1512       * @type RegExp
1513       */
1514      'interpolate': reInterpolate,
1515
1516      /**
1517       * Used to reference the data object in the template text.
1518       *
1519       * @memberOf _.templateSettings
1520       * @type string
1521       */
1522      'variable': '',
1523
1524      /**
1525       * Used to import variables into the compiled template.
1526       *
1527       * @memberOf _.templateSettings
1528       * @type Object
1529       */
1530      'imports': {
1531
1532        /**
1533         * A reference to the `lodash` function.
1534         *
1535         * @memberOf _.templateSettings.imports
1536         * @type Function
1537         */
1538        '_': lodash
1539      }
1540    };
1541
1542    /*------------------------------------------------------------------------*/
1543
1544    /**
1545     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1546     *
1547     * @private
1548     * @param {*} value The value to wrap.
1549     */
1550    function LazyWrapper(value) {
1551      this.__wrapped__ = value;
1552      this.__actions__ = [];
1553      this.__dir__ = 1;
1554      this.__filtered__ = false;
1555      this.__iteratees__ = [];
1556      this.__takeCount__ = MAX_ARRAY_LENGTH;
1557      this.__views__ = [];
1558    }
1559
1560    /**
1561     * Creates a clone of the lazy wrapper object.
1562     *
1563     * @private
1564     * @name clone
1565     * @memberOf LazyWrapper
1566     * @returns {Object} Returns the cloned `LazyWrapper` object.
1567     */
1568    function lazyClone() {
1569      var result = new LazyWrapper(this.__wrapped__);
1570      result.__actions__ = copyArray(this.__actions__);
1571      result.__dir__ = this.__dir__;
1572      result.__filtered__ = this.__filtered__;
1573      result.__iteratees__ = copyArray(this.__iteratees__);
1574      result.__takeCount__ = this.__takeCount__;
1575      result.__views__ = copyArray(this.__views__);
1576      return result;
1577    }
1578
1579    /**
1580     * Reverses the direction of lazy iteration.
1581     *
1582     * @private
1583     * @name reverse
1584     * @memberOf LazyWrapper
1585     * @returns {Object} Returns the new reversed `LazyWrapper` object.
1586     */
1587    function lazyReverse() {
1588      if (this.__filtered__) {
1589        var result = new LazyWrapper(this);
1590        result.__dir__ = -1;
1591        result.__filtered__ = true;
1592      } else {
1593        result = this.clone();
1594        result.__dir__ *= -1;
1595      }
1596      return result;
1597    }
1598
1599    /**
1600     * Extracts the unwrapped value from its lazy wrapper.
1601     *
1602     * @private
1603     * @name value
1604     * @memberOf LazyWrapper
1605     * @returns {*} Returns the unwrapped value.
1606     */
1607    function lazyValue() {
1608      var array = this.__wrapped__.value(),
1609          dir = this.__dir__,
1610          isArr = isArray(array),
1611          isRight = dir < 0,
1612          arrLength = isArr ? array.length : 0,
1613          view = getView(0, arrLength, this.__views__),
1614          start = view.start,
1615          end = view.end,
1616          length = end - start,
1617          index = isRight ? end : (start - 1),
1618          iteratees = this.__iteratees__,
1619          iterLength = iteratees.length,
1620          resIndex = 0,
1621          takeCount = nativeMin(length, this.__takeCount__);
1622
1623      if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
1624        return baseWrapperValue(array, this.__actions__);
1625      }
1626      var result = [];
1627
1628      outer:
1629      while (length-- && resIndex < takeCount) {
1630        index += dir;
1631
1632        var iterIndex = -1,
1633            value = array[index];
1634
1635        while (++iterIndex < iterLength) {
1636          var data = iteratees[iterIndex],
1637              iteratee = data.iteratee,
1638              type = data.type,
1639              computed = iteratee(value);
1640
1641          if (type == LAZY_MAP_FLAG) {
1642            value = computed;
1643          } else if (!computed) {
1644            if (type == LAZY_FILTER_FLAG) {
1645              continue outer;
1646            } else {
1647              break outer;
1648            }
1649          }
1650        }
1651        result[resIndex++] = value;
1652      }
1653      return result;
1654    }
1655
1656    /*------------------------------------------------------------------------*/
1657
1658    /**
1659     * Creates an hash object.
1660     *
1661     * @private
1662     * @returns {Object} Returns the new hash object.
1663     */
1664    function Hash() {}
1665
1666    /**
1667     * Removes `key` and its value from the hash.
1668     *
1669     * @private
1670     * @param {Object} hash The hash to modify.
1671     * @param {string} key The key of the value to remove.
1672     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1673     */
1674    function hashDelete(hash, key) {
1675      return hashHas(hash, key) && delete hash[key];
1676    }
1677
1678    /**
1679     * Gets the hash value for `key`.
1680     *
1681     * @private
1682     * @param {Object} hash The hash to query.
1683     * @param {string} key The key of the value to get.
1684     * @returns {*} Returns the entry value.
1685     */
1686    function hashGet(hash, key) {
1687      if (nativeCreate) {
1688        var result = hash[key];
1689        return result === HASH_UNDEFINED ? undefined : result;
1690      }
1691      return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1692    }
1693
1694    /**
1695     * Checks if a hash value for `key` exists.
1696     *
1697     * @private
1698     * @param {Object} hash The hash to query.
1699     * @param {string} key The key of the entry to check.
1700     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1701     */
1702    function hashHas(hash, key) {
1703      return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1704    }
1705
1706    /**
1707     * Sets the hash `key` to `value`.
1708     *
1709     * @private
1710     * @param {Object} hash The hash to modify.
1711     * @param {string} key The key of the value to set.
1712     * @param {*} value The value to set.
1713     */
1714    function hashSet(hash, key, value) {
1715      hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1716    }
1717
1718    /*------------------------------------------------------------------------*/
1719
1720    /**
1721     * Creates a map cache object to store key-value pairs.
1722     *
1723     * @private
1724     * @param {Array} [values] The values to cache.
1725     */
1726    function MapCache(values) {
1727      var index = -1,
1728          length = values ? values.length : 0;
1729
1730      this.clear();
1731      while (++index < length) {
1732        var entry = values[index];
1733        this.set(entry[0], entry[1]);
1734      }
1735    }
1736
1737    /**
1738     * Removes all key-value entries from the map.
1739     *
1740     * @private
1741     * @name clear
1742     * @memberOf MapCache
1743     */
1744    function mapClear() {
1745      this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
1746    }
1747
1748    /**
1749     * Removes `key` and its value from the map.
1750     *
1751     * @private
1752     * @name delete
1753     * @memberOf MapCache
1754     * @param {string} key The key of the value to remove.
1755     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1756     */
1757    function mapDelete(key) {
1758      var data = this.__data__;
1759      if (isKeyable(key)) {
1760        return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1761      }
1762      return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1763    }
1764
1765    /**
1766     * Gets the map value for `key`.
1767     *
1768     * @private
1769     * @name get
1770     * @memberOf MapCache
1771     * @param {string} key The key of the value to get.
1772     * @returns {*} Returns the entry value.
1773     */
1774    function mapGet(key) {
1775      var data = this.__data__;
1776      if (isKeyable(key)) {
1777        return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1778      }
1779      return Map ? data.map.get(key) : assocGet(data.map, key);
1780    }
1781
1782    /**
1783     * Checks if a map value for `key` exists.
1784     *
1785     * @private
1786     * @name has
1787     * @memberOf MapCache
1788     * @param {string} key The key of the entry to check.
1789     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1790     */
1791    function mapHas(key) {
1792      var data = this.__data__;
1793      if (isKeyable(key)) {
1794        return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1795      }
1796      return Map ? data.map.has(key) : assocHas(data.map, key);
1797    }
1798
1799    /**
1800     * Sets the map `key` to `value`.
1801     *
1802     * @private
1803     * @name set
1804     * @memberOf MapCache
1805     * @param {string} key The key of the value to set.
1806     * @param {*} value The value to set.
1807     * @returns {Object} Returns the map cache object.
1808     */
1809    function mapSet(key, value) {
1810      var data = this.__data__;
1811      if (isKeyable(key)) {
1812        hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1813      } else if (Map) {
1814        data.map.set(key, value);
1815      } else {
1816        assocSet(data.map, key, value);
1817      }
1818      return this;
1819    }
1820
1821    /*------------------------------------------------------------------------*/
1822
1823    /**
1824     *
1825     * Creates a set cache object to store unique values.
1826     *
1827     * @private
1828     * @param {Array} [values] The values to cache.
1829     */
1830    function SetCache(values) {
1831      var index = -1,
1832          length = values ? values.length : 0;
1833
1834      this.__data__ = new MapCache;
1835      while (++index < length) {
1836        this.push(values[index]);
1837      }
1838    }
1839
1840    /**
1841     * Checks if `value` is in `cache`.
1842     *
1843     * @private
1844     * @param {Object} cache The set cache to search.
1845     * @param {*} value The value to search for.
1846     * @returns {number} Returns `true` if `value` is found, else `false`.
1847     */
1848    function cacheHas(cache, value) {
1849      var map = cache.__data__;
1850      if (isKeyable(value)) {
1851        var data = map.__data__,
1852            hash = typeof value == 'string' ? data.string : data.hash;
1853
1854        return hash[value] === HASH_UNDEFINED;
1855      }
1856      return map.has(value);
1857    }
1858
1859    /**
1860     * Adds `value` to the set cache.
1861     *
1862     * @private
1863     * @name push
1864     * @memberOf SetCache
1865     * @param {*} value The value to cache.
1866     */
1867    function cachePush(value) {
1868      var map = this.__data__;
1869      if (isKeyable(value)) {
1870        var data = map.__data__,
1871            hash = typeof value == 'string' ? data.string : data.hash;
1872
1873        hash[value] = HASH_UNDEFINED;
1874      }
1875      else {
1876        map.set(value, HASH_UNDEFINED);
1877      }
1878    }
1879
1880    /*------------------------------------------------------------------------*/
1881
1882    /**
1883     * Creates a stack cache object to store key-value pairs.
1884     *
1885     * @private
1886     * @param {Array} [values] The values to cache.
1887     */
1888    function Stack(values) {
1889      var index = -1,
1890          length = values ? values.length : 0;
1891
1892      this.clear();
1893      while (++index < length) {
1894        var entry = values[index];
1895        this.set(entry[0], entry[1]);
1896      }
1897    }
1898
1899    /**
1900     * Removes all key-value entries from the stack.
1901     *
1902     * @private
1903     * @name clear
1904     * @memberOf Stack
1905     */
1906    function stackClear() {
1907      this.__data__ = { 'array': [], 'map': null };
1908    }
1909
1910    /**
1911     * Removes `key` and its value from the stack.
1912     *
1913     * @private
1914     * @name delete
1915     * @memberOf Stack
1916     * @param {string} key The key of the value to remove.
1917     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1918     */
1919    function stackDelete(key) {
1920      var data = this.__data__,
1921          array = data.array;
1922
1923      return array ? assocDelete(array, key) : data.map['delete'](key);
1924    }
1925
1926    /**
1927     * Gets the stack value for `key`.
1928     *
1929     * @private
1930     * @name get
1931     * @memberOf Stack
1932     * @param {string} key The key of the value to get.
1933     * @returns {*} Returns the entry value.
1934     */
1935    function stackGet(key) {
1936      var data = this.__data__,
1937          array = data.array;
1938
1939      return array ? assocGet(array, key) : data.map.get(key);
1940    }
1941
1942    /**
1943     * Checks if a stack value for `key` exists.
1944     *
1945     * @private
1946     * @name has
1947     * @memberOf Stack
1948     * @param {string} key The key of the entry to check.
1949     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1950     */
1951    function stackHas(key) {
1952      var data = this.__data__,
1953          array = data.array;
1954
1955      return array ? assocHas(array, key) : data.map.has(key);
1956    }
1957
1958    /**
1959     * Sets the stack `key` to `value`.
1960     *
1961     * @private
1962     * @name set
1963     * @memberOf Stack
1964     * @param {string} key The key of the value to set.
1965     * @param {*} value The value to set.
1966     * @returns {Object} Returns the stack cache object.
1967     */
1968    function stackSet(key, value) {
1969      var data = this.__data__,
1970          array = data.array;
1971
1972      if (array) {
1973        if (array.length < (LARGE_ARRAY_SIZE - 1)) {
1974          assocSet(array, key, value);
1975        } else {
1976          data.array = null;
1977          data.map = new MapCache(array);
1978        }
1979      }
1980      var map = data.map;
1981      if (map) {
1982        map.set(key, value);
1983      }
1984      return this;
1985    }
1986
1987    /*------------------------------------------------------------------------*/
1988
1989    /**
1990     * Removes `key` and its value from the associative array.
1991     *
1992     * @private
1993     * @param {Array} array The array to query.
1994     * @param {string} key The key of the value to remove.
1995     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1996     */
1997    function assocDelete(array, key) {
1998      var index = assocIndexOf(array, key);
1999      if (index < 0) {
2000        return false;
vendor: 6,750 bytes, lines 2001-2214
2001      }
2002      var lastIndex = array.length - 1;
2003      if (index == lastIndex) {
2004        array.pop();
2005      } else {
2006        splice.call(array, index, 1);
2007      }
2008      return true;
2009    }
2010
2011    /**
2012     * Gets the associative array value for `key`.
2013     *
2014     * @private
2015     * @param {Array} array The array to query.
2016     * @param {string} key The key of the value to get.
2017     * @returns {*} Returns the entry value.
2018     */
2019    function assocGet(array, key) {
2020      var index = assocIndexOf(array, key);
2021      return index < 0 ? undefined : array[index][1];
2022    }
2023
2024    /**
2025     * Checks if an associative array value for `key` exists.
2026     *
2027     * @private
2028     * @param {Array} array The array to query.
2029     * @param {string} key The key of the entry to check.
2030     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2031     */
2032    function assocHas(array, key) {
2033      return assocIndexOf(array, key) > -1;
2034    }
2035
2036    /**
2037     * Gets the index at which the first occurrence of `key` is found in `array`
2038     * of key-value pairs.
2039     *
2040     * @private
2041     * @param {Array} array The array to search.
2042     * @param {*} key The key to search for.
2043     * @returns {number} Returns the index of the matched value, else `-1`.
2044     */
2045    function assocIndexOf(array, key) {
2046      var length = array.length;
2047      while (length--) {
2048        if (eq(array[length][0], key)) {
2049          return length;
2050        }
2051      }
2052      return -1;
2053    }
2054
2055    /**
2056     * Sets the associative array `key` to `value`.
2057     *
2058     * @private
2059     * @param {Array} array The array to modify.
2060     * @param {string} key The key of the value to set.
2061     * @param {*} value The value to set.
2062     */
2063    function assocSet(array, key, value) {
2064      var index = assocIndexOf(array, key);
2065      if (index < 0) {
2066        array.push([key, value]);
2067      } else {
2068        array[index][1] = value;
2069      }
2070    }
2071
2072    /*------------------------------------------------------------------------*/
2073
2074    /**
2075     * Used by `_.defaults` to customize its `_.assignIn` use.
2076     *
2077     * @private
2078     * @param {*} objValue The destination value.
2079     * @param {*} srcValue The source value.
2080     * @param {string} key The key of the property to assign.
2081     * @param {Object} object The parent object of `objValue`.
2082     * @returns {*} Returns the value to assign.
2083     */
2084    function assignInDefaults(objValue, srcValue, key, object) {
2085      if (objValue === undefined ||
2086          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2087        return srcValue;
2088      }
2089      return objValue;
2090    }
2091
2092    /**
2093     * This function is like `assignValue` except that it doesn't assign `undefined` values.
2094     *
2095     * @private
2096     * @param {Object} object The object to modify.
2097     * @param {string} key The key of the property to assign.
2098     * @param {*} value The value to assign.
2099     */
2100    function assignMergeValue(object, key, value) {
2101      if ((value !== undefined && !eq(object[key], value)) ||
2102          (typeof key == 'number' && value === undefined && !(key in object))) {
2103        object[key] = value;
2104      }
2105    }
2106
2107    /**
2108     * Assigns `value` to `key` of `object` if the existing value is not equivalent
2109     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2110     * for equality comparisons.
2111     *
2112     * @private
2113     * @param {Object} object The object to modify.
2114     * @param {string} key The key of the property to assign.
2115     * @param {*} value The value to assign.
2116     */
2117    function assignValue(object, key, value) {
2118      var objValue = object[key];
2119      if ((!eq(objValue, value) ||
2120            (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
2121          (value === undefined && !(key in object))) {
2122        object[key] = value;
2123      }
2124    }
2125
2126    /**
2127     * The base implementation of `_.assign` without support for multiple sources
2128     * or `customizer` functions.
2129     *
2130     * @private
2131     * @param {Object} object The destination object.
2132     * @param {Object} source The source object.
2133     * @returns {Object} Returns `object`.
2134     */
2135    function baseAssign(object, source) {
2136      return object && copyObject(source, keys(source), object);
2137    }
2138
2139    /**
2140     * The base implementation of `_.at` without support for individual paths.
2141     *
2142     * @private
2143     * @param {Object} object The object to iterate over.
2144     * @param {string[]} paths The property paths of elements to pick.
2145     * @returns {Array} Returns the new array of picked elements.
2146     */
2147    function baseAt(object, paths) {
2148      var index = -1,
2149          isNil = object == null,
2150          length = paths.length,
2151          result = Array(length);
2152
2153      while (++index < length) {
2154        result[index] = isNil ? undefined : get(object, paths[index]);
2155      }
2156      return result;
2157    }
2158
2159    /**
2160     * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2161     *
2162     * @private
2163     * @param {number} number The number to clamp.
2164     * @param {number} [lower] The lower bound.
2165     * @param {number} upper The upper bound.
2166     * @returns {number} Returns the clamped number.
2167     */
2168    function baseClamp(number, lower, upper) {
2169      if (number === number) {
2170        if (upper !== undefined) {
2171          number = number <= upper ? number : upper;
2172        }
2173        if (lower !== undefined) {
2174          number = number >= lower ? number : lower;
2175        }
2176      }
2177      return number;
2178    }
2179
2180    /**
2181     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2182     * traversed objects.
2183     *
2184     * @private
2185     * @param {*} value The value to clone.
2186     * @param {boolean} [isDeep] Specify a deep clone.
2187     * @param {Function} [customizer] The function to customize cloning.
2188     * @param {string} [key] The key of `value`.
2189     * @param {Object} [object] The parent object of `value`.
2190     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2191     * @returns {*} Returns the cloned value.
2192     */
2193    function baseClone(value, isDeep, customizer, key, object, stack) {
2194      var result;
2195      if (customizer) {
2196        result = object ? customizer(value, key, object, stack) : customizer(value);
2197      }
2198      if (result !== undefined) {
2199        return result;
2200      }
2201      if (!isObject(value)) {
2202        return value;
2203      }
2204      var isArr = isArray(value);
2205      if (isArr) {
2206        result = initCloneArray(value);
2207        if (!isDeep) {
2208          return copyArray(value, result);
2209        }
2210      } else {
2211        var tag = getTag(value),
2212            isFunc = tag == funcTag || tag == genTag;
2213
2214        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2215          if (isHostObject(value)) {
2216            return object ? value : {};
2217          }
2218          result = initCloneObject(isFunc ? {} : value);
2219          if (!isDeep) {
2220            return copySymbols(value, baseAssign(result, value));
2221          }
2222        } else {
2223          return cloneableTags[tag]
2224            ? initCloneByTag(value, tag, isDeep)
2225            : (object ? value : {});
2226        }
2227      }
2228      // Check for circular references and return its corresponding clone.
2229      stack || (stack = new Stack);
2230      var stacked = stack.get(value);
2231      if (stacked) {
2232        return stacked;
2233      }
2234      stack.set(value, result);
2235
2236      // Recursively populate clone (susceptible to call stack limits).
2237      (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2238        assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2239      });
2240      return isArr ? result : copySymbols(value, result);
2241    }
2242
2243    /**
2244     * The base implementation of `_.conforms` which doesn't clone `source`.
2245     *
2246     * @private
2247     * @param {Object} source The object of property predicates to conform to.
2248     * @returns {Function} Returns the new function.
2249     */
2250    function baseConforms(source) {
2251      var props = keys(source),
2252          length = props.length;
2253
2254      return function(object) {
2255        if (object == null) {
2256          return !length;
2257        }
2258        var index = length;
2259        while (index--) {
2260          var key = props[index],
2261              predicate = source[key],
2262              value = object[key];
2263
2264          if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2265            return false;
2266          }
2267        }
2268        return true;
2269      };
2270    }
2271
2272    /**
2273     * The base implementation of `_.create` without support for assigning
2274     * properties to the created object.
2275     *
2276     * @private
2277     * @param {Object} prototype The object to inherit from.
2278     * @returns {Object} Returns the new object.
2279     */
2280    var baseCreate = (function() {
2281      function object() {}
2282      return function(prototype) {
2283        if (isObject(prototype)) {
2284          object.prototype = prototype;
2285          var result = new object;
2286          object.prototype = undefined;
2287        }
2288        return result || {};
2289      };
2290    }());
2291
2292    /**
2293     * The base implementation of `_.delay` and `_.defer` which accepts an array
2294     * of `func` arguments.
2295     *
2296     * @private
2297     * @param {Function} func The function to delay.
2298     * @param {number} wait The number of milliseconds to delay invocation.
2299     * @param {Object} args The arguments provide to `func`.
2300     * @returns {number} Returns the timer id.
2301     */
vendor: 4,428 bytes, lines 2302-2435
2302    function baseDelay(func, wait, args) {
2303      if (typeof func != 'function') {
2304        throw new TypeError(FUNC_ERROR_TEXT);
2305      }
2306      return setTimeout(function() { func.apply(undefined, args); }, wait);
2307    }
2308
2309    /**
2310     * The base implementation of methods like `_.difference` without support for
2311     * excluding multiple arrays or iteratee shorthands.
2312     *
2313     * @private
2314     * @param {Array} array The array to inspect.
2315     * @param {Array} values The values to exclude.
2316     * @param {Function} [iteratee] The iteratee invoked per element.
2317     * @param {Function} [comparator] The comparator invoked per element.
2318     * @returns {Array} Returns the new array of filtered values.
2319     */
2320    function baseDifference(array, values, iteratee, comparator) {
2321      var index = -1,
2322          includes = arrayIncludes,
2323          isCommon = true,
2324          length = array.length,
2325          result = [],
2326          valuesLength = values.length;
2327
2328      if (!length) {
2329        return result;
2330      }
2331      if (iteratee) {
2332        values = arrayMap(values, baseUnary(iteratee));
2333      }
2334      if (comparator) {
2335        includes = arrayIncludesWith;
2336        isCommon = false;
2337      }
2338      else if (values.length >= LARGE_ARRAY_SIZE) {
2339        includes = cacheHas;
2340        isCommon = false;
2341        values = new SetCache(values);
2342      }
2343      outer:
2344      while (++index < length) {
2345        var value = array[index],
2346            computed = iteratee ? iteratee(value) : value;
2347
2348        if (isCommon && computed === computed) {
2349          var valuesIndex = valuesLength;
2350          while (valuesIndex--) {
2351            if (values[valuesIndex] === computed) {
2352              continue outer;
2353            }
2354          }
2355          result.push(value);
2356        }
2357        else if (!includes(values, computed, comparator)) {
2358          result.push(value);
2359        }
2360      }
2361      return result;
2362    }
2363
2364    /**
2365     * The base implementation of `_.forEach` without support for iteratee shorthands.
2366     *
2367     * @private
2368     * @param {Array|Object} collection The collection to iterate over.
2369     * @param {Function} iteratee The function invoked per iteration.
2370     * @returns {Array|Object} Returns `collection`.
2371     */
2372    var baseEach = createBaseEach(baseForOwn);
2373
2374    /**
2375     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2376     *
2377     * @private
2378     * @param {Array|Object} collection The collection to iterate over.
2379     * @param {Function} iteratee The function invoked per iteration.
2380     * @returns {Array|Object} Returns `collection`.
2381     */
2382    var baseEachRight = createBaseEach(baseForOwnRight, true);
2383
2384    /**
2385     * The base implementation of `_.every` without support for iteratee shorthands.
2386     *
2387     * @private
2388     * @param {Array|Object} collection The collection to iterate over.
2389     * @param {Function} predicate The function invoked per iteration.
2390     * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2391     */
2392    function baseEvery(collection, predicate) {
2393      var result = true;
2394      baseEach(collection, function(value, index, collection) {
2395        result = !!predicate(value, index, collection);
2396        return result;
2397      });
2398      return result;
2399    }
2400
2401    /**
2402     * The base implementation of `_.fill` without an iteratee call guard.
2403     *
2404     * @private
2405     * @param {Array} array The array to fill.
2406     * @param {*} value The value to fill `array` with.
2407     * @param {number} [start=0] The start position.
2408     * @param {number} [end=array.length] The end position.
2409     * @returns {Array} Returns `array`.
2410     */
2411    function baseFill(array, value, start, end) {
2412      var length = array.length;
2413
2414      start = toInteger(start);
2415      if (start < 0) {
2416        start = -start > length ? 0 : (length + start);
2417      }
2418      end = (end === undefined || end > length) ? length : toInteger(end);
2419      if (end < 0) {
2420        end += length;
2421      }
2422      end = start > end ? 0 : toLength(end);
2423      while (start < end) {
2424        array[start++] = value;
2425      }
2426      return array;
2427    }
2428
2429    /**
2430     * The base implementation of `_.filter` without support for iteratee shorthands.
2431     *
2432     * @private
2433     * @param {Array|Object} collection The collection to iterate over.
2434     * @param {Function} predicate The function invoked per iteration.
2435     * @returns {Array} Returns the new filtered array.
2436     */
2437    function baseFilter(collection, predicate) {
2438      var result = [];
2439      baseEach(collection, function(value, index, collection) {
2440        if (predicate(value, index, collection)) {
2441          result.push(value);
2442        }
2443      });
2444      return result;
2445    }
2446
2447    /**
2448     * The base implementation of `_.flatten` with support for restricting flattening.
2449     *
2450     * @private
2451     * @param {Array} array The array to flatten.
2452     * @param {boolean} [isDeep] Specify a deep flatten.
2453     * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2454     * @param {Array} [result=[]] The initial result value.
2455     * @returns {Array} Returns the new flattened array.
2456     */
2457    function baseFlatten(array, isDeep, isStrict, result) {
2458      result || (result = []);
2459
2460      var index = -1,
2461          length = array.length;
2462
2463      while (++index < length) {
2464        var value = array[index];
2465        if (isArrayLikeObject(value) &&
2466            (isStrict || isArray(value) || isArguments(value))) {
2467          if (isDeep) {
2468            // Recursively flatten arrays (susceptible to call stack limits).
2469            baseFlatten(value, isDeep, isStrict, result);
2470          } else {
2471            arrayPush(result, value);
2472          }
2473        } else if (!isStrict) {
2474          result[result.length] = value;
2475        }
2476      }
2477      return result;
2478    }
2479
2480    /**
2481     * The base implementation of `baseForIn` and `baseForOwn` which iterates
2482     * over `object` properties returned by `keysFunc` invoking `iteratee` for
2483     * each property. Iteratee functions may exit iteration early by explicitly
2484     * returning `false`.
2485     *
2486     * @private
2487     * @param {Object} object The object to iterate over.
2488     * @param {Function} iteratee The function invoked per iteration.
2489     * @param {Function} keysFunc The function to get the keys of `object`.
2490     * @returns {Object} Returns `object`.
2491     */
2492    var baseFor = createBaseFor();
2493
2494    /**
2495     * This function is like `baseFor` except that it iterates over properties
2496     * in the opposite order.
2497     *
2498     * @private
2499     * @param {Object} object The object to iterate over.
2500     * @param {Function} iteratee The function invoked per iteration.
2501     * @param {Function} keysFunc The function to get the keys of `object`.
2502     * @returns {Object} Returns `object`.
2503     */
2504    var baseForRight = createBaseFor(true);
2505
2506    /**
2507     * The base implementation of `_.forIn` without support for iteratee shorthands.
2508     *
2509     * @private
2510     * @param {Object} object The object to iterate over.
2511     * @param {Function} iteratee The function invoked per iteration.
2512     * @returns {Object} Returns `object`.
2513     */
2514    function baseForIn(object, iteratee) {
2515      return object == null ? object : baseFor(object, iteratee, keysIn);
2516    }
2517
2518    /**
2519     * The base implementation of `_.forOwn` without support for iteratee shorthands.
2520     *
2521     * @private
2522     * @param {Object} object The object to iterate over.
2523     * @param {Function} iteratee The function invoked per iteration.
2524     * @returns {Object} Returns `object`.
2525     */
2526    function baseForOwn(object, iteratee) {
2527      return object && baseFor(object, iteratee, keys);
2528    }
2529
2530    /**
2531     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2532     *
2533     * @private
2534     * @param {Object} object The object to iterate over.
2535     * @param {Function} iteratee The function invoked per iteration.
2536     * @returns {Object} Returns `object`.
2537     */
2538    function baseForOwnRight(object, iteratee) {
2539      return object && baseForRight(object, iteratee, keys);
2540    }
2541
2542    /**
2543     * The base implementation of `_.functions` which creates an array of
2544     * `object` function property names filtered from those provided.
2545     *
2546     * @private
2547     * @param {Object} object The object to inspect.
2548     * @param {Array} props The property names to filter.
2549     * @returns {Array} Returns the new array of filtered property names.
2550     */
2551    function baseFunctions(object, props) {
2552      return arrayFilter(props, function(key) {
2553        return isFunction(object[key]);
2554      });
2555    }
2556
2557    /**
2558     * The base implementation of `_.get` without support for default values.
2559     *
2560     * @private
2561     * @param {Object} object The object to query.
2562     * @param {Array|string} path The path of the property to get.
2563     * @returns {*} Returns the resolved value.
2564     */
2565    function baseGet(object, path) {
2566      path = isKey(path, object) ? [path + ''] : baseToPath(path);
2567
2568      var index = 0,
2569          length = path.length;
2570
2571      while (object != null && index < length) {
2572        object = object[path[index++]];
2573      }
2574      return (index && index == length) ? object : undefined;
2575    }
2576
2577    /**
2578     * The base implementation of `_.has` without support for deep paths.
2579     *
2580     * @private
2581     * @param {Object} object The object to query.
2582     * @param {Array|string} key The key to check.
2583     * @returns {boolean} Returns `true` if `key` exists, else `false`.
2584     */
2585    function baseHas(object, key) {
2586      // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2587      // that are composed entirely of index properties, return `false` for
2588      // `hasOwnProperty` checks of them.
2589      return hasOwnProperty.call(object, key) ||
2590        (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2591    }
2592
2593    /**
2594     * The base implementation of `_.hasIn` without support for deep paths.
2595     *
2596     * @private
2597     * @param {Object} object The object to query.
2598     * @param {Array|string} key The key to check.
2599     * @returns {boolean} Returns `true` if `key` exists, else `false`.
2600     */
2601    function baseHasIn(object, key) {
2602      return key in Object(object);
2603    }
2604
2605    /**
2606     * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2607     *
2608     * @private
2609     * @param {number} number The number to check.
2610     * @param {number} start The start of the range.
2611     * @param {number} end The end of the range.
2612     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2613     */
2614    function baseInRange(number, start, end) {
2615      return number >= nativeMin(start, end) && number < nativeMax(start, end);
2616    }
2617
2618    /**
2619     * The base implementation of methods like `_.intersection`, without support
2620     * for iteratee shorthands, that accepts an array of arrays to inspect.
2621     *
2622     * @private
2623     * @param {Array} arrays The arrays to inspect.
2624     * @param {Function} [iteratee] The iteratee invoked per element.
2625     * @param {Function} [comparator] The comparator invoked per element.
2626     * @returns {Array} Returns the new array of shared values.
2627     */
2628    function baseIntersection(arrays, iteratee, comparator) {
2629      var includes = comparator ? arrayIncludesWith : arrayIncludes,
2630          othLength = arrays.length,
2631          othIndex = othLength,
2632          caches = Array(othLength),
2633          result = [];
2634
2635      while (othIndex--) {
2636        var array = arrays[othIndex];
2637        if (othIndex && iteratee) {
2638          array = arrayMap(array, baseUnary(iteratee));
2639        }
2640        caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2641          ? new SetCache(othIndex && array)
2642          : undefined;
2643      }
2644      array = arrays[0];
2645
2646      var index = -1,
2647          length = array.length,
2648          seen = caches[0];
2649
2650      outer:
2651      while (++index < length) {
2652        var value = array[index],
2653            computed = iteratee ? iteratee(value) : value;
2654
2655        if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
2656          var othIndex = othLength;
2657          while (--othIndex) {
2658            var cache = caches[othIndex];
2659            if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
2660              continue outer;
2661            }
2662          }
2663          if (seen) {
2664            seen.push(computed);
2665          }
2666          result.push(value);
2667        }
2668      }
2669      return result;
2670    }
2671
2672    /**
2673     * The base implementation of `_.invoke` without support for individual
2674     * method arguments.
2675     *
2676     * @private
2677     * @param {Object} object The object to query.
2678     * @param {Array|string} path The path of the method to invoke.
2679     * @param {Array} args The arguments to invoke the method with.
2680     * @returns {*} Returns the result of the invoked method.
2681     */
2682    function baseInvoke(object, path, args) {
2683      if (!isKey(path, object)) {
2684        path = baseToPath(path);
2685        object = parent(object, path);
2686        path = last(path);
2687      }
2688      var func = object == null ? object : object[path];
2689      return func == null ? undefined : apply(func, object, args);
2690    }
2691
2692    /**
2693     * The base implementation of `_.isEqual` which supports partial comparisons
2694     * and tracks traversed objects.
2695     *
2696     * @private
2697     * @param {*} value The value to compare.
2698     * @param {*} other The other value to compare.
2699     * @param {Function} [customizer] The function to customize comparisons.
2700     * @param {boolean} [bitmask] The bitmask of comparison flags.
2701     *  The bitmask may be composed of the following flags:
2702     *     1 - Unordered comparison
2703     *     2 - Partial comparison
2704     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2705     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2706     */
2707    function baseIsEqual(value, other, customizer, bitmask, stack) {
2708      if (value === other) {
2709        return true;
2710      }
2711      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2712        return value !== value && other !== other;
2713      }
2714      return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2715    }
2716
2717    /**
2718     * A specialized version of `baseIsEqual` for arrays and objects which performs
2719     * deep comparisons and tracks traversed objects enabling objects with circular
2720     * references to be compared.
2721     *
2722     * @private
2723     * @param {Object} object The object to compare.
2724     * @param {Object} other The other object to compare.
2725     * @param {Function} equalFunc The function to determine equivalents of values.
2726     * @param {Function} [customizer] The function to customize comparisons.
2727     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2728     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2729     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2730     */
2731    function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2732      var objIsArr = isArray(object),
2733          othIsArr = isArray(other),
2734          objTag = arrayTag,
2735          othTag = arrayTag;
2736
2737      if (!objIsArr) {
2738        objTag = getTag(object);
2739        if (objTag == argsTag) {
2740          objTag = objectTag;
2741        } else if (objTag != objectTag) {
2742          objIsArr = isTypedArray(object);
2743        }
2744      }
2745      if (!othIsArr) {
2746        othTag = getTag(other);
2747        if (othTag == argsTag) {
2748          othTag = objectTag;
2749        } else if (othTag != objectTag) {
2750          othIsArr = isTypedArray(other);
2751        }
2752      }
2753      var objIsObj = objTag == objectTag && !isHostObject(object),
2754          othIsObj = othTag == objectTag && !isHostObject(other),
2755          isSameTag = objTag == othTag;
2756
2757      if (isSameTag && !(objIsArr || objIsObj)) {
2758        return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2759      }
2760      var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2761      if (!isPartial) {
2762        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2763            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2764
2765        if (objIsWrapped || othIsWrapped) {
2766          return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2767        }
2768      }
2769      if (!isSameTag) {
2770        return false;
2771      }
2772      stack || (stack = new Stack);
2773      return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2774    }
2775
2776    /**
2777     * The base implementation of `_.isMatch` without support for iteratee shorthands.
2778     *
2779     * @private
2780     * @param {Object} object The object to inspect.
2781     * @param {Object} source The object of property values to match.
2782     * @param {Array} matchData The property names, values, and compare flags to match.
2783     * @param {Function} [customizer] The function to customize comparisons.
2784     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2785     */
2786    function baseIsMatch(object, source, matchData, customizer) {
2787      var index = matchData.length,
2788          length = index,
2789          noCustomizer = !customizer;
2790
2791      if (object == null) {
2792        return !length;
2793      }
2794      object = Object(object);
2795      while (index--) {
2796        var data = matchData[index];
2797        if ((noCustomizer && data[2])
2798              ? data[1] !== object[data[0]]
2799              : !(data[0] in object)
2800            ) {
2801          return false;
2802        }
2803      }
2804      while (++index < length) {
2805        data = matchData[index];
2806        var key = data[0],
2807            objValue = object[key],
2808            srcValue = data[1];
2809
2810        if (noCustomizer && data[2]) {
2811          if (objValue === undefined && !(key in object)) {
2812            return false;
2813          }
2814        } else {
2815          var stack = new Stack,
2816              result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2817
2818          if (!(result === undefined
2819                ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2820                : result
2821              )) {
2822            return false;
2823          }
2824        }
2825      }
2826      return true;
2827    }
2828
2829    /**
2830     * The base implementation of `_.iteratee`.
2831     *
2832     * @private
2833     * @param {*} [value=_.identity] The value to convert to an iteratee.
2834     * @returns {Function} Returns the iteratee.
2835     */
2836    function baseIteratee(value) {
2837      var type = typeof value;
2838      if (type == 'function') {
2839        return value;
2840      }
2841      if (value == null) {
2842        return identity;
2843      }
2844      if (type == 'object') {
2845        return isArray(value)
2846          ? baseMatchesProperty(value[0], value[1])
2847          : baseMatches(value);
2848      }
2849      return property(value);
2850    }
2851
2852    /**
2853     * The base implementation of `_.keys` which doesn't skip the constructor
2854     * property of prototypes or treat sparse arrays as dense.
2855     *
2856     * @private
2857     * @type Function
2858     * @param {Object} object The object to query.
2859     * @returns {Array} Returns the array of property names.
2860     */
2861    function baseKeys(object) {
2862      return nativeKeys(Object(object));
2863    }
2864
2865    /**
2866     * The base implementation of `_.keysIn` which doesn't skip the constructor
2867     * property of prototypes or treat sparse arrays as dense.
2868     *
2869     * @private
2870     * @param {Object} object The object to query.
2871     * @returns {Array} Returns the array of property names.
2872     */
2873    function baseKeysIn(object) {
2874      object = object == null ? object : Object(object);
2875
2876      var result = [];
2877      for (var key in object) {
2878        result.push(key);
2879      }
2880      return result;
2881    }
2882
2883    // Fallback for IE < 9 with es6-shim.
2884    if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
2885      baseKeysIn = function(object) {
2886        return iteratorToArray(enumerate(object));
2887      };
2888    }
2889
2890    /**
2891     * The base implementation of `_.map` without support for iteratee shorthands.
2892     *
2893     * @private
2894     * @param {Array|Object} collection The collection to iterate over.
2895     * @param {Function} iteratee The function invoked per iteration.
2896     * @returns {Array} Returns the new mapped array.
2897     */
2898    function baseMap(collection, iteratee) {
2899      var index = -1,
2900          result = isArrayLike(collection) ? Array(collection.length) : [];
2901
2902      baseEach(collection, function(value, key, collection) {
2903        result[++index] = iteratee(value, key, collection);
2904      });
2905      return result;
2906    }
2907
2908    /**
2909     * The base implementation of `_.matches` which doesn't clone `source`.
2910     *
2911     * @private
2912     * @param {Object} source The object of property values to match.
2913     * @returns {Function} Returns the new function.
2914     */
2915    function baseMatches(source) {
2916      var matchData = getMatchData(source);
2917      if (matchData.length == 1 && matchData[0][2]) {
2918        var key = matchData[0][0],
2919            value = matchData[0][1];
2920
2921        return function(object) {
2922          if (object == null) {
2923            return false;
2924          }
2925          return object[key] === value &&
2926            (value !== undefined || (key in Object(object)));
2927        };
2928      }
2929      return function(object) {
2930        return object === source || baseIsMatch(object, source, matchData);
2931      };
2932    }
2933
2934    /**
2935     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
2936     *
2937     * @private
2938     * @param {string} path The path of the property to get.
2939     * @param {*} srcValue The value to match.
2940     * @returns {Function} Returns the new function.
2941     */
2942    function baseMatchesProperty(path, srcValue) {
2943      return function(object) {
2944        var objValue = get(object, path);
2945        return (objValue === undefined && objValue === srcValue)
2946          ? hasIn(object, path)
2947          : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
2948      };
2949    }
2950
2951    /**
2952     * The base implementation of `_.merge` without support for multiple sources.
2953     *
2954     * @private
2955     * @param {Object} object The destination object.
2956     * @param {Object} source The source object.
2957     * @param {number} srcIndex The index of `source`.
2958     * @param {Function} [customizer] The function to customize merged values.
2959     * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
2960     */
2961    function baseMerge(object, source, srcIndex, customizer, stack) {
2962      if (object === source) {
2963        return;
2964      }
2965      var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
2966      arrayEach(props || source, function(srcValue, key) {
2967        if (props) {
2968          key = srcValue;
2969          srcValue = source[key];
2970        }
2971        if (isObject(srcValue)) {
2972          stack || (stack = new Stack);
2973          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
2974        }
2975        else {
2976          var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
2977          if (newValue === undefined) {
2978            newValue = srcValue;
2979          }
2980          assignMergeValue(object, key, newValue);
2981        }
2982      });
2983    }
2984
2985    /**
2986     * A specialized version of `baseMerge` for arrays and objects which performs
2987     * deep merges and tracks traversed objects enabling objects with circular
2988     * references to be merged.
2989     *
2990     * @private
2991     * @param {Object} object The destination object.
2992     * @param {Object} source The source object.
2993     * @param {string} key The key of the value to merge.
2994     * @param {number} srcIndex The index of `source`.
2995     * @param {Function} mergeFunc The function to merge values.
2996     * @param {Function} [customizer] The function to customize assigned values.
2997     * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
2998     */
2999    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3000      var objValue = object[key],
3001          srcValue = source[key],
3002          stacked = stack.get(srcValue) || stack.get(objValue);
3003
3004      if (stacked) {
3005        assignMergeValue(object, key, stacked);
3006        return;
3007      }
3008      var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
3009          isCommon = newValue === undefined;
3010
3011      if (isCommon) {
3012        newValue = srcValue;
3013        if (isArray(srcValue) || isTypedArray(srcValue)) {
3014          if (isArray(objValue)) {
3015            newValue = srcIndex ? copyArray(objValue) : objValue;
3016          }
3017          else if (isArrayLikeObject(objValue)) {
3018            newValue = copyArray(objValue);
3019          }
3020          else {
3021            newValue = baseClone(srcValue);
3022          }
3023        }
3024        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3025          if (isArguments(objValue)) {
3026            newValue = toPlainObject(objValue);
3027          }
3028          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3029            newValue = baseClone(srcValue);
3030          }
3031          else {
3032            newValue = srcIndex ? baseClone(objValue) : objValue;
3033          }
3034        }
3035        else {
3036          isCommon = false;
3037        }
3038      }
3039      stack.set(srcValue, newValue);
3040
3041      if (isCommon) {
3042        // Recursively merge objects and arrays (susceptible to call stack limits).
3043        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3044      }
3045      assignMergeValue(object, key, newValue);
3046    }
3047
3048    /**
3049     * The base implementation of `_.orderBy` without param guards.
3050     *
3051     * @private
3052     * @param {Array|Object} collection The collection to iterate over.
3053     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3054     * @param {string[]} orders The sort orders of `iteratees`.
3055     * @returns {Array} Returns the new sorted array.
3056     */
3057    function baseOrderBy(collection, iteratees, orders) {
3058      var index = -1,
3059          toIteratee = getIteratee();
3060
3061      iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3062        return toIteratee(iteratee);
3063      });
3064
3065      var result = baseMap(collection, function(value, key, collection) {
3066        var criteria = arrayMap(iteratees, function(iteratee) {
3067          return iteratee(value);
3068        });
3069        return { 'criteria': criteria, 'index': ++index, 'value': value };
3070      });
3071
3072      return baseSortBy(result, function(object, other) {
3073        return compareMultiple(object, other, orders);
3074      });
3075    }
3076
3077    /**
3078     * The base implementation of `_.pick` without support for individual
3079     * property names.
3080     *
3081     * @private
3082     * @param {Object} object The source object.
3083     * @param {string[]} props The property names to pick.
3084     * @returns {Object} Returns the new object.
3085     */
3086    function basePick(object, props) {
3087      object = Object(object);
3088      return arrayReduce(props, function(result, key) {
3089        if (key in object) {
3090          result[key] = object[key];
3091        }
3092        return result;
3093      }, {});
3094    }
3095
3096    /**
3097     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3098     *
3099     * @private
3100     * @param {Object} object The source object.
3101     * @param {Function} predicate The function invoked per property.
3102     * @returns {Object} Returns the new object.
3103     */
3104    function basePickBy(object, predicate) {
3105      var result = {};
3106      baseForIn(object, function(value, key) {
3107        if (predicate(value, key)) {
3108          result[key] = value;
3109        }
3110      });
3111      return result;
3112    }
3113
3114    /**
3115     * The base implementation of `_.property` without support for deep paths.
3116     *
3117     * @private
3118     * @param {string} key The key of the property to get.
3119     * @returns {Function} Returns the new function.
3120     */
3121    function baseProperty(key) {
3122      return function(object) {
3123        return object == null ? undefined : object[key];
3124      };
3125    }
3126
3127    /**
3128     * A specialized version of `baseProperty` which supports deep paths.
3129     *
3130     * @private
3131     * @param {Array|string} path The path of the property to get.
3132     * @returns {Function} Returns the new function.
3133     */
3134    function basePropertyDeep(path) {
3135      return function(object) {
3136        return baseGet(object, path);
3137      };
3138    }
3139
3140    /**
3141     * The base implementation of `_.pullAll`.
3142     *
3143     * @private
3144     * @param {Array} array The array to modify.
3145     * @param {Array} values The values to remove.
3146     * @returns {Array} Returns `array`.
3147     */
3148    function basePullAll(array, values) {
3149      return basePullAllBy(array, values);
3150    }
3151
3152    /**
3153     * The base implementation of `_.pullAllBy` without support for iteratee
3154     * shorthands.
3155     *
3156     * @private
3157     * @param {Array} array The array to modify.
3158     * @param {Array} values The values to remove.
3159     * @param {Function} [iteratee] The iteratee invoked per element.
3160     * @returns {Array} Returns `array`.
3161     */
3162    function basePullAllBy(array, values, iteratee) {
3163      var index = -1,
3164          length = values.length,
3165          seen = array;
3166
3167      if (iteratee) {
3168        seen = arrayMap(array, function(value) { return iteratee(value); });
3169      }
3170      while (++index < length) {
3171        var fromIndex = 0,
3172            value = values[index],
3173            computed = iteratee ? iteratee(value) : value;
3174
3175        while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3176          if (seen !== array) {
3177            splice.call(seen, fromIndex, 1);
3178          }
3179          splice.call(array, fromIndex, 1);
3180        }
3181      }
3182      return array;
3183    }
3184
3185    /**
3186     * The base implementation of `_.pullAt` without support for individual
3187     * indexes or capturing the removed elements.
3188     *
3189     * @private
3190     * @param {Array} array The array to modify.
3191     * @param {number[]} indexes The indexes of elements to remove.
3192     * @returns {Array} Returns `array`.
3193     */
3194    function basePullAt(array, indexes) {
3195      var length = array ? indexes.length : 0,
3196          lastIndex = length - 1;
3197
3198      while (length--) {
3199        var index = indexes[length];
3200        if (lastIndex == length || index != previous) {
3201          var previous = index;
3202          if (isIndex(index)) {
3203            splice.call(array, index, 1);
3204          }
3205          else if (!isKey(index, array)) {
3206            var path = baseToPath(index),
3207                object = parent(array, path);
3208
3209            if (object != null) {
3210              delete object[last(path)];
3211            }
3212          }
3213          else {
3214            delete array[index];
3215          }
3216        }
3217      }
3218      return array;
3219    }
3220
3221    /**
3222     * The base implementation of `_.random` without support for returning
3223     * floating-point numbers.
3224     *
3225     * @private
3226     * @param {number} lower The lower bound.
3227     * @param {number} upper The upper bound.
3228     * @returns {number} Returns the random number.
3229     */
3230    function baseRandom(lower, upper) {
3231      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3232    }
3233
3234    /**
3235     * The base implementation of `_.range` and `_.rangeRight` which doesn't
3236     * coerce arguments to numbers.
3237     *
3238     * @private
3239     * @param {number} start The start of the range.
3240     * @param {number} end The end of the range.
3241     * @param {number} step The value to increment or decrement by.
3242     * @param {boolean} [fromRight] Specify iterating from right to left.
3243     * @returns {Array} Returns the new array of numbers.
3244     */
3245    function baseRange(start, end, step, fromRight) {
3246      var index = -1,
3247          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3248          result = Array(length);
3249
3250      while (length--) {
3251        result[fromRight ? length : ++index] = start;
3252        start += step;
3253      }
3254      return result;
3255    }
3256
3257    /**
3258     * The base implementation of `_.set`.
3259     *
3260     * @private
3261     * @param {Object} object The object to query.
3262     * @param {Array|string} path The path of the property to set.
3263     * @param {*} value The value to set.
3264     * @param {Function} [customizer] The function to customize path creation.
3265     * @returns {Object} Returns `object`.
3266     */
3267    function baseSet(object, path, value, customizer) {
3268      path = isKey(path, object) ? [path + ''] : baseToPath(path);
3269
3270      var index = -1,
3271          length = path.length,
3272          lastIndex = length - 1,
3273          nested = object;
3274
3275      while (nested != null && ++index < length) {
3276        var key = path[index];
3277        if (isObject(nested)) {
3278          var newValue = value;
3279          if (index != lastIndex) {
3280            var objValue = nested[key];
3281            newValue = customizer ? customizer(objValue, key, nested) : undefined;
3282            if (newValue === undefined) {
3283              newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
3284            }
3285          }
3286          assignValue(nested, key, newValue);
3287        }
3288        nested = nested[key];
3289      }
3290      return object;
3291    }
3292
3293    /**
3294     * The base implementation of `setData` without support for hot loop detection.
3295     *
3296     * @private
3297     * @param {Function} func The function to associate metadata with.
3298     * @param {*} data The metadata.
3299     * @returns {Function} Returns `func`.
3300     */
3301    var baseSetData = !metaMap ? identity : function(func, data) {
3302      metaMap.set(func, data);
3303      return func;
3304    };
3305
3306    /**
3307     * The base implementation of `_.slice` without an iteratee call guard.
3308     *
3309     * @private
3310     * @param {Array} array The array to slice.
3311     * @param {number} [start=0] The start position.
3312     * @param {number} [end=array.length] The end position.
3313     * @returns {Array} Returns the slice of `array`.
3314     */
3315    function baseSlice(array, start, end) {
3316      var index = -1,
3317          length = array.length;
3318
3319      if (start < 0) {
3320        start = -start > length ? 0 : (length + start);
3321      }
3322      end = end > length ? length : end;
3323      if (end < 0) {
3324        end += length;
3325      }
3326      length = start > end ? 0 : ((end - start) >>> 0);
3327      start >>>= 0;
3328
3329      var result = Array(length);
3330      while (++index < length) {
3331        result[index] = array[index + start];
3332      }
3333      return result;
3334    }
3335
3336    /**
3337     * The base implementation of `_.some` without support for iteratee shorthands.
3338     *
3339     * @private
3340     * @param {Array|Object} collection The collection to iterate over.
3341     * @param {Function} predicate The function invoked per iteration.
3342     * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3343     */
3344    function baseSome(collection, predicate) {
3345      var result;
3346
3347      baseEach(collection, function(value, index, collection) {
3348        result = predicate(value, index, collection);
3349        return !result;
3350      });
3351      return !!result;
3352    }
3353
3354    /**
3355     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3356     * performs a binary search of `array` to determine the index at which `value`
3357     * should be inserted into `array` in order to maintain its sort order.
3358     *
3359     * @private
3360     * @param {Array} array The sorted array to inspect.
3361     * @param {*} value The value to evaluate.
3362     * @param {boolean} [retHighest] Specify returning the highest qualified index.
3363     * @returns {number} Returns the index at which `value` should be inserted
3364     *  into `array`.
3365     */
3366    function baseSortedIndex(array, value, retHighest) {
3367      var low = 0,
3368          high = array ? array.length : low;
3369
3370      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3371        while (low < high) {
3372          var mid = (low + high) >>> 1,
3373              computed = array[mid];
3374
3375          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3376            low = mid + 1;
3377          } else {
3378            high = mid;
3379          }
3380        }
3381        return high;
3382      }
3383      return baseSortedIndexBy(array, value, identity, retHighest);
3384    }
3385
3386    /**
3387     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3388     * which invokes `iteratee` for `value` and each element of `array` to compute
3389     * their sort ranking. The iteratee is invoked with one argument; (value).
3390     *
3391     * @private
3392     * @param {Array} array The sorted array to inspect.
3393     * @param {*} value The value to evaluate.
3394     * @param {Function} iteratee The iteratee invoked per element.
3395     * @param {boolean} [retHighest] Specify returning the highest qualified index.
3396     * @returns {number} Returns the index at which `value` should be inserted into `array`.
3397     */
3398    function baseSortedIndexBy(array, value, iteratee, retHighest) {
3399      value = iteratee(value);
3400
3401      var low = 0,
3402          high = array ? array.length : 0,
3403          valIsNaN = value !== value,
3404          valIsNull = value === null,
3405          valIsUndef = value === undefined;
3406
3407      while (low < high) {
3408        var mid = nativeFloor((low + high) / 2),
3409            computed = iteratee(array[mid]),
3410            isDef = computed !== undefined,
3411            isReflexive = computed === computed;
3412
3413        if (valIsNaN) {
3414          var setLow = isReflexive || retHighest;
3415        } else if (valIsNull) {
3416          setLow = isReflexive && isDef && (retHighest || computed != null);
3417        } else if (valIsUndef) {
3418          setLow = isReflexive && (retHighest || isDef);
3419        } else if (computed == null) {
3420          setLow = false;
3421        } else {
3422          setLow = retHighest ? (computed <= value) : (computed < value);
3423        }
3424        if (setLow) {
3425          low = mid + 1;
3426        } else {
3427          high = mid;
3428        }
3429      }
3430      return nativeMin(high, MAX_ARRAY_INDEX);
3431    }
3432
3433    /**
3434     * The base implementation of `_.sortedUniq`.
3435     *
3436     * @private
3437     * @param {Array} array The array to inspect.
3438     * @returns {Array} Returns the new duplicate free array.
3439     */
3440    function baseSortedUniq(array) {
3441      return baseSortedUniqBy(array);
3442    }
3443
3444    /**
3445     * The base implementation of `_.sortedUniqBy` without support for iteratee
3446     * shorthands.
3447     *
3448     * @private
3449     * @param {Array} array The array to inspect.
3450     * @param {Function} [iteratee] The iteratee invoked per element.
3451     * @returns {Array} Returns the new duplicate free array.
3452     */
3453    function baseSortedUniqBy(array, iteratee) {
3454      var index = 0,
3455          length = array.length,
3456          value = array[0],
3457          computed = iteratee ? iteratee(value) : value,
3458          seen = computed,
3459          resIndex = 0,
3460          result = [value];
3461
3462      while (++index < length) {
3463        value = array[index],
3464        computed = iteratee ? iteratee(value) : value;
3465
3466        if (!eq(computed, seen)) {
3467          seen = computed;
3468          result[++resIndex] = value;
3469        }
3470      }
3471      return result;
3472    }
3473
3474    /**
3475     * The base implementation of `_.toPath` which only converts `value` to a
3476     * path if it's not one.
3477     *
3478     * @private
3479     * @param {*} value The value to process.
3480     * @returns {Array} Returns the property path array.
3481     */
3482    function baseToPath(value) {
3483      return isArray(value) ? value : stringToPath(value);
3484    }
3485
3486    /**
3487     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3488     *
3489     * @private
3490     * @param {Array} array The array to inspect.
3491     * @param {Function} [iteratee] The iteratee invoked per element.
3492     * @param {Function} [comparator] The comparator invoked per element.
3493     * @returns {Array} Returns the new duplicate free array.
3494     */
3495    function baseUniq(array, iteratee, comparator) {
3496      var index = -1,
3497          includes = arrayIncludes,
3498          length = array.length,
3499          isCommon = true,
3500          result = [],
3501          seen = result;
3502
3503      if (comparator) {
3504        isCommon = false;
3505        includes = arrayIncludesWith;
3506      }
3507      else if (length >= LARGE_ARRAY_SIZE) {
3508        var set = iteratee ? null : createSet(array);
3509        if (set) {
3510          return setToArray(set);
3511        }
3512        isCommon = false;
3513        includes = cacheHas;
3514        seen = new SetCache;
3515      }
3516      else {
3517        seen = iteratee ? [] : result;
3518      }
3519      outer:
3520      while (++index < length) {
3521        var value = array[index],
3522            computed = iteratee ? iteratee(value) : value;
3523
3524        if (isCommon && computed === computed) {
3525          var seenIndex = seen.length;
3526          while (seenIndex--) {
3527            if (seen[seenIndex] === computed) {
3528              continue outer;
3529            }
3530          }
3531          if (iteratee) {
3532            seen.push(computed);
3533          }
3534          result.push(value);
3535        }
3536        else if (!includes(seen, computed, comparator)) {
3537          if (seen !== result) {
3538            seen.push(computed);
3539          }
3540          result.push(value);
3541        }
3542      }
3543      return result;
3544    }
3545
3546    /**
3547     * The base implementation of `_.unset`.
3548     *
3549     * @private
3550     * @param {Object} object The object to modify.
3551     * @param {Array|string} path The path of the property to unset.
3552     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3553     */
3554    function baseUnset(object, path) {
3555      path = isKey(path, object) ? [path + ''] : baseToPath(path);
3556      object = parent(object, path);
3557      var key = last(path);
3558      return (object != null && has(object, key)) ? delete object[key] : true;
3559    }
3560
3561    /**
3562     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3563     * without support for iteratee shorthands.
3564     *
3565     * @private
3566     * @param {Array} array The array to query.
3567     * @param {Function} predicate The function invoked per iteration.
3568     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3569     * @param {boolean} [fromRight] Specify iterating from right to left.
3570     * @returns {Array} Returns the slice of `array`.
3571     */
3572    function baseWhile(array, predicate, isDrop, fromRight) {
3573      var length = array.length,
3574          index = fromRight ? length : -1;
3575
3576      while ((fromRight ? index-- : ++index < length) &&
3577        predicate(array[index], index, array)) {}
3578
3579      return isDrop
3580        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3581        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3582    }
3583
3584    /**
3585     * The base implementation of `wrapperValue` which returns the result of
3586     * performing a sequence of actions on the unwrapped `value`, where each
3587     * successive action is supplied the return value of the previous.
3588     *
3589     * @private
3590     * @param {*} value The unwrapped value.
3591     * @param {Array} actions Actions to perform to resolve the unwrapped value.
3592     * @returns {*} Returns the resolved value.
3593     */
3594    function baseWrapperValue(value, actions) {
3595      var result = value;
3596      if (result instanceof LazyWrapper) {
3597        result = result.value();
3598      }
3599      return arrayReduce(actions, function(result, action) {
3600        return action.func.apply(action.thisArg, arrayPush([result], action.args
3600));
3601      }, result);
3602    }
3603
3604    /**
3605     * The base implementation of methods like `_.xor`, without support for
3606     * iteratee shorthands, that accepts an array of arrays to inspect.
3607     *
3608     * @private
3609     * @param {Array} arrays The arrays to inspect.
3610     * @param {Function} [iteratee] The iteratee invoked per element.
3611     * @param {Function} [comparator] The comparator invoked per element.
3612     * @returns {Array} Returns the new array of values.
3613     */
3614    function baseXor(arrays, iteratee, comparator) {
3615      var index = -1,
3616          length = arrays.length;
3617
3618      while (++index < length) {
3619        var result = result
3620          ? arrayPush(
3621              baseDifference(result, arrays[index], iteratee, comparator),
3622              baseDifference(arrays[index], result, iteratee, comparator)
3623            )
3624          : arrays[index];
3625      }
3626      return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3627    }
3628
3629    /**
3630     * Creates a clone of `buffer`.
3631     *
3632     * @private
3633     * @param {ArrayBuffer} buffer The array buffer to clone.
3634     * @returns {ArrayBuffer} Returns the cloned array buffer.
3635     */
3636    function cloneBuffer(buffer) {
3637      var Ctor = buffer.constructor,
3638          result = new Ctor(buffer.byteLength),
3639          view = new Uint8Array(result);
3640
3641      view.set(new Uint8Array(buffer));
3642      return result;
3643    }
3644
3645    /**
3646     * Creates a clone of `map`.
3647     *
3648     * @private
3649     * @param {Object} map The map to clone.
3650     * @returns {Object} Returns the cloned map.
3651     */
3652    function cloneMap(map) {
3653      var Ctor = map.constructor;
3654      return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3655    }
3656
3657    /**
3658     * Creates a clone of `regexp`.
3659     *
3660     * @private
3661     * @param {Object} regexp The regexp to clone.
3662     * @returns {Object} Returns the cloned regexp.
3663     */
3664    function cloneRegExp(regexp) {
3665      var Ctor = regexp.constructor,
3666          result = new Ctor(regexp.source, reFlags.exec(regexp));
3667
3668      result.lastIndex = regexp.lastIndex;
3669      return result;
3670    }
3671
3672    /**
3673     * Creates a clone of `set`.
3674     *
3675     * @private
3676     * @param {Object} set The set to clone.
3677     * @returns {Object} Returns the cloned set.
3678     */
3679    function cloneSet(set) {
3680      var Ctor = set.constructor;
3681      return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3682    }
3683
3684    /**
3685     * Creates a clone of the `symbol` object.
3686     *
3687     * @private
3688     * @param {Object} symbol The symbol object to clone.
3689     * @returns {Object} Returns the cloned symbol object.
3690     */
3691    function cloneSymbol(symbol) {
3692      return Symbol ? Object(symbolValueOf.call(symbol)) : {};
3693    }
3694
3695    /**
3696     * Creates a clone of `typedArray`.
3697     *
3698     * @private
3699     * @param {Object} typedArray The typed array to clone.
3700     * @param {boolean} [isDeep] Specify a deep clone.
3701     * @returns {Object} Returns the cloned typed array.
3702     */
3703    function cloneTypedArray(typedArray, isDeep) {
3704      var buffer = typedArray.buffer,
3705          Ctor = typedArray.constructor;
3706
3707      return new Ctor(isDeep ? cloneBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
3708    }
3709
3710    /**
3711     * Creates an array that is the composition of partially applied arguments,
3712     * placeholders, and provided arguments into a single array of arguments.
3713     *
3714     * @private
3715     * @param {Array|Object} args The provided arguments.
3716     * @param {Array} partials The arguments to prepend to those provided.
3717     * @param {Array} holders The `partials` placeholder indexes.
3718     * @returns {Array} Returns the new array of composed arguments.
3719     */
3720    function composeArgs(args, partials, holders) {
3721      var holdersLength = holders.length,
3722          argsIndex = -1,
3723          argsLength = nativeMax(args.length - holdersLength, 0),
3724          leftIndex = -1,
3725          leftLength = partials.length,
3726          result = Array(leftLength + argsLength);
3727
3728      while (++leftIndex < leftLength) {
3729        result[leftIndex] = partials[leftIndex];
3730      }
3731      while (++argsIndex < holdersLength) {
3732        result[holders[argsIndex]] = args[argsIndex];
3733      }
3734      while (argsLength--) {
3735        result[leftIndex++] = args[argsIndex++];
3736      }
3737      return result;
3738    }
3739
3740    /**
3741     * This function is like `composeArgs` except that the arguments composition
3742     * is tailored for `_.partialRight`.
3743     *
3744     * @private
3745     * @param {Array|Object} args The provided arguments.
3746     * @param {Array} partials The arguments to append to those provided.
3747     * @param {Array} holders The `partials` placeholder indexes.
3748     * @returns {Array} Returns the new array of composed arguments.
3749     */
3750    function composeArgsRight(args, partials, holders) {
3751      var holdersIndex = -1,
3752          holdersLength = holders.length,
3753          argsIndex = -1,
3754          argsLength = nativeMax(args.length - holdersLength, 0),
3755          rightIndex = -1,
3756          rightLength = partials.length,
3757          result = Array(argsLength + rightLength);
3758
3759      while (++argsIndex < argsLength) {
3760        result[argsIndex] = args[argsIndex];
3761      }
3762      var offset = argsIndex;
3763      while (++rightIndex < rightLength) {
3764        result[offset + rightIndex] = partials[rightIndex];
3765      }
3766      while (++holdersIndex < holdersLength) {
3767        result[offset + holders[holdersIndex]] = args[argsIndex++];
3768      }
3769      return result;
3770    }
3771
3772    /**
3773     * Copies the values of `source` to `array`.
3774     *
3775     * @private
3776     * @param {Array} source The array to copy values from.
3777     * @param {Array} [array=[]] The array to copy values to.
3778     * @returns {Array} Returns `array`.
3779     */
3780    function copyArray(source, array) {
3781      var index = -1,
3782          length = source.length;
3783
3784      array || (array = Array(length));
3785      while (++index < length) {
3786        array[index] = source[index];
3787      }
3788      return array;
3789    }
3790
3791    /**
3792     * Copies properties of `source` to `object`.
3793     *
3794     * @private
3795     * @param {Object} source The object to copy properties from.
3796     * @param {Array} props The property names to copy.
3797     * @param {Object} [object={}] The object to copy properties to.
3798     * @returns {Object} Returns `object`.
3799     */
3800    function copyObject(source, props, object) {
3801      return copyObjectWith(source, props, object);
3802    }
3803
3804    /**
3805     * This function is like `copyObject` except that it accepts a function to
3806     * customize copied values.
3807     *
3808     * @private
3809     * @param {Object} source The object to copy properties from.
3810     * @param {Array} props The property names to copy.
3811     * @param {Object} [object={}] The object to copy properties to.
3812     * @param {Function} [customizer] The function to customize copied values.
3813     * @returns {Object} Returns `object`.
3814     */
3815    function copyObjectWith(source, props, object, customizer) {
3816      object || (object = {});
3817
3818      var index = -1,
3819          length = props.length;
3820
3821      while (++index < length) {
3822        var key = props[index],
3823            newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
3824
3825        assignValue(object, key, newValue);
3826      }
3827      return object;
3828    }
3829
3830    /**
3831     * Copies own symbol properties of `source` to `object`.
3832     *
3833     * @private
3834     * @param {Object} source The object to copy symbols from.
3835     * @param {Object} [object={}] The object to copy symbols to.
3836     * @returns {Object} Returns `object`.
3837     */
3838    function copySymbols(source, object) {
vendor: 4,721 bytes, lines 3839-3984
3839      return copyObject(source, getSymbols(source), object);
3840    }
3841
3842    /**
3843     * Creates a function like `_.groupBy`.
3844     *
3845     * @private
3846     * @param {Function} setter The function to set keys and values of the accumulator object.
3847     * @param {Function} [initializer] The function to initialize the accumulator object.
3848     * @returns {Function} Returns the new aggregator function.
3849     */
3850    function createAggregator(setter, initializer) {
3851      return function(collection, iteratee) {
3852        var result = initializer ? initializer() : {};
3853        iteratee = getIteratee(iteratee);
3854
3855        if (isArray(collection)) {
3856          var index = -1,
3857              length = collection.length;
3858
3859          while (++index < length) {
3860            var value = collection[index];
3861            setter(result, value, iteratee(value), collection);
3862          }
3863        } else {
3864          baseEach(collection, function(value, key, collection) {
3865            setter(result, value, iteratee(value), collection);
3866          });
3867        }
3868        return result;
3869      };
3870    }
3871
3872    /**
3873     * Creates a function like `_.assign`.
3874     *
3875     * @private
3876     * @param {Function} assigner The function to assign values.
3877     * @returns {Function} Returns the new assigner function.
3878     */
3879    function createAssigner(assigner) {
3880      return rest(function(object, sources) {
3881        var index = -1,
3882            length = sources.length,
3883            customizer = length > 1 ? sources[length - 1] : undefined,
3884            guard = length > 2 ? sources[2] : undefined;
3885
3886        customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
3887        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
3888          customizer = length < 3 ? undefined : customizer;
3889          length = 1;
3890        }
3891        object = Object(object);
3892        while (++index < length) {
3893          var source = sources[index];
3894          if (source) {
3895            assigner(object, source, index, customizer);
3896          }
3897        }
3898        return object;
3899      });
3900    }
3901
3902    /**
3903     * Creates a `baseEach` or `baseEachRight` function.
3904     *
3905     * @private
3906     * @param {Function} eachFunc The function to iterate over a collection.
3907     * @param {boolean} [fromRight] Specify iterating from right to left.
3908     * @returns {Function} Returns the new base function.
3909     */
3910    function createBaseEach(eachFunc, fromRight) {
3911      return function(collection, iteratee) {
3912        if (collection == null) {
3913          return collection;
3914        }
3915        if (!isArrayLike(collection)) {
3916          return eachFunc(collection, iteratee);
3917        }
3918        var length = collection.length,
3919            index = fromRight ? length : -1,
3920            iterable = Object(collection);
3921
3922        while ((fromRight ? index-- : ++index < length)) {
3923          if (iteratee(iterable[index], index, iterable) === false) {
3924            break;
3925          }
3926        }
3927        return collection;
3928      };
3929    }
3930
3931    /**
3932     * Creates a base function for methods like `_.forIn`.
3933     *
3934     * @private
3935     * @param {boolean} [fromRight] Specify iterating from right to left.
3936     * @returns {Function} Returns the new base function.
3937     */
3938    function createBaseFor(fromRight) {
3939      return function(object, iteratee, keysFunc) {
3940        var index = -1,
3941            iterable = Object(object),
3942            props = keysFunc(object),
3943            length = props.length;
3944
3945        while (length--) {
3946          var key = props[fromRight ? length : ++index];
3947          if (iteratee(iterable[key], key, iterable) === false) {
3948            break;
3949          }
3950        }
3951        return object;
3952      };
3953    }
3954
3955    /**
3956     * Creates a function that wraps `func` to invoke it with the optional `this`
3957     * binding of `thisArg`.
3958     *
3959     * @private
3960     * @param {Function} func The function to wrap.
3961     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
3962     * @param {*} [thisArg] The `this` binding of `func`.
3963     * @returns {Function} Returns the new wrapped function.
3964     */
3965    function createBaseWrapper(func, bitmask, thisArg) {
3966      var isBind = bitmask & BIND_FLAG,
3967          Ctor = createCtorWrapper(func);
3968
3969      function wrapper() {
3970        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
3971        return fn.apply(isBind ? thisArg : this, arguments);
3972      }
3973      return wrapper;
3974    }
3975
3976    /**
3977     * Creates a function like `_.lowerFirst`.
3978     *
3979     * @private
3980     * @param {string} methodName The name of the `String` case method to use.
3981     * @returns {Function} Returns the new function.
3982     */
3983    function createCaseFirst(methodName) {
3984      return function(string) {
3985        string = toString(string);
3986
3987        var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
3988            chr = strSymbols ? strSymbols[0] : string.charAt(0),
3989            trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
3990
3991        return chr[methodName]() + trailing;
3992      };
3993    }
3994
3995    /**
3996     * Creates a function like `_.camelCase`.
3997     *
3998     * @private
3999     * @param {Function} callback The function to combine each word.
4000     * @returns {Function} Returns the new compounder function.
4001     */
4002    function createCompounder(callback) {
4003      return function(string) {
4004        return arrayReduce(words(deburr(string)), callback, '');
4005      };
4006    }
4007
4008    /**
4009     * Creates a function that produces an instance of `Ctor` regardless of
4010     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4011     *
4012     * @private
4013     * @param {Function} Ctor The constructor to wrap.
4014     * @returns {Function} Returns the new wrapped function.
4015     */
4016    function createCtorWrapper(Ctor) {
4017      return function() {
4018        // Use a `switch` statement to work with class constructors.
4019        // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4020        // for more details.
4021        var args = arguments;
4022        switch (args.length) {
4023          case 0: return new Ctor;
4024          case 1: return new Ctor(args[0]);
4025          case 2: return new Ctor(args[0], args[1]);
4026          case 3: return new Ctor(args[0], args[1], args[2]);
4027          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4028          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4029          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4030          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4031        }
4032        var thisBinding = baseCreate(Ctor.prototype),
4033            result = Ctor.apply(thisBinding, args);
4034
4035        // Mimic the constructor's `return` behavior.
4036        // See https://es5.github.io/#x13.2.2 for more details.
4037        return isObject(result) ? result : thisBinding;
4038      };
4039    }
4040
4041    /**
4042     * Creates a function that wraps `func` to enable currying.
4043     *
4044     * @private
4045     * @param {Function} func The function to wrap.
4046     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4047     * @param {number} arity The arity of `func`.
4048     * @returns {Function} Returns the new wrapped function.
4049     */
4050    function createCurryWrapper(func, bitmask, arity) {
4051      var Ctor = createCtorWrapper(func);
4052
4053      function wrapper() {
4054        var length = arguments.length,
4055            index = length,
4056            args = Array(length),
4057            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
4058            placeholder = wrapper.placeholder;
4059
4060        while (index--) {
4061          args[index] = arguments[index];
4062        }
4063        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4064          ? []
4065          : replaceHolders(args, placeholder);
4066
4067        length -= holders.length;
4068        return length < arity
4069          ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
4070          : apply(fn, this, args);
4071      }
4072      return wrapper;
4073    }
4074
4075    /**
4076     * Creates a `_.flow` or `_.flowRight` function.
4077     *
4078     * @private
4079     * @param {boolean} [fromRight] Specify iterating from right to left.
4080     * @returns {Function} Returns the new flow function.
4081     */
4082    function createFlow(fromRight) {
4083      return rest(function(funcs) {
4084        funcs = baseFlatten(funcs);
4085
4086        var length = funcs.length,
4087            index = length,
4088            prereq = LodashWrapper.prototype.thru;
4089
4090        if (fromRight) {
4091          funcs.reverse();
4092        }
4093        while (index--) {
4094          var func = funcs[index];
4095          if (typeof func != 'function') {
4096            throw new TypeError(FUNC_ERROR_TEXT);
4097          }
4098          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4099            var wrapper = new LodashWrapper([], true);
4100          }
4101        }
4102        index = wrapper ? index : length;
4103        while (++index < length) {
4104          func = funcs[index];
4105
4106          var funcName = getFuncName(func),
4107              data = funcName == 'wrapper' ? getData(func) : undefined;
4108
4109          if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
4110            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4111          } else {
4112            wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4113          }
4114        }
4115        return function() {
4116          var args = arguments,
4117              value = args[0];
4118
4119          if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4120            return wrapper.plant(value).value();
4121          }
4122          var index = 0,
4123              result = length ? funcs[index].apply(this, args) : value;
4124
4125          while (++index < length) {
4126            result = funcs[index].call(this, result);
4127          }
4128          return result;
4129        };
4130      });
4131    }
4132
4133    /**
4134     * Creates a function that wraps `func` to invoke it with optional `this`
4135     * binding of `thisArg`, partial application, and currying.
4136     *
4137     * @private
4138     * @param {Function|string} func The function or method name to wrap.
4139     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4140     * @param {*} [thisArg] The `this` binding of `func`.
4141     * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4142     * @param {Array} [holders] The `partials` placeholder indexes.
4143     * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4144     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4145     * @param {Array} [argPos] The argument positions of the new function.
4146     * @param {number} [ary] The arity cap of `func`.
4147     * @param {number} [arity] The arity of `func`.
4148     * @returns {Function} Returns the new wrapped function.
4149     */
4150    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4151      var isAry = bitmask & ARY_FLAG,
4152          isBind = bitmask & BIND_FLAG,
4153          isBindKey = bitmask & BIND_KEY_FLAG,
4154          isCurry = bitmask & CURRY_FLAG,
4155          isCurryRight = bitmask & CURRY_RIGHT_FLAG,
4156          isFlip = bitmask & FLIP_FLAG,
4157          Ctor = isBindKey ? undefined : createCtorWrapper(func);
4158
4159      function wrapper() {
4160        var length = arguments.length,
4161            index = length,
4162            args = Array(length);
4163
4164        while (index--) {
4165          args[index] = arguments[index];
4166        }
4167        if (partials) {
4168          args = composeArgs(args, partials, holders);
4169        }
4170        if (partialsRight) {
4171          args = composeArgsRight(args, partialsRight, holdersRight);
4172        }
4173        if (isCurry || isCurryRight) {
4174          var placeholder = wrapper.placeholder,
4175              argsHolders = replaceHolders(args, placeholder);
4176
4177          length -= argsHolders.length;
4178          if (length < arity) {
4179            return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
4180          }
4181        }
4182        var thisBinding = isBind ? thisArg : this,
4183            fn = isBindKey ? thisBinding[func] : func;
4184
4185        if (argPos) {
4186          args = reorder(args, argPos);
4187        } else if (isFlip && args.length > 1) {
4188          args.reverse();
4189        }
4190        if (isAry && ary < args.length) {
4191          args.length = ary;
4192        }
4193        if (this && this !== root && this instanceof wrapper) {
4194          fn = Ctor || createCtorWrapper(fn);
4195        }
4196        return fn.apply(thisBinding, args);
4197      }
4198      return wrapper;
4199    }
4200
4201    /**
4202     * Creates a function like `_.over`.
4203     *
4204     * @private
4205     * @param {Function} arrayFunc The function to iterate over iteratees.
4206     * @returns {Function} Returns the new invoker function.
4207     */
4208    function createOver(arrayFunc) {
4209      return rest(function(iteratees) {
4210        iteratees = arrayMap(baseFlatten(iteratees), getIteratee());
4211        return rest(function(args) {
4212          var thisArg = this;
4213          return arrayFunc(iteratees, function(iteratee) {
4214            return apply(iteratee, thisArg, args);
4215          });
4216        });
4217      });
4218    }
4219
4220    /**
4221     * Creates the padding for `string` based on `length`. The `chars` string
4222     * is truncated if the number of characters exceeds `length`.
4223     *
4224     * @private
4225     * @param {string} string The string to create padding for.
4226     * @param {number} [length=0] The padding length.
4227     * @param {string} [chars=' '] The string used as padding.
4228     * @returns {string} Returns the padding for `string`.
4229     */
4230    function createPadding(string, length, chars) {
4231      length = toInteger(length);
4232
4233      var strLength = stringSize(string);
4234      if (!length || strLength >= length) {
4235        return '';
4236      }
4237      var padLength = length - strLength;
4238      chars = chars === undefined ? ' ' : (chars + '');
4239
4240      var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4241      return reHasComplexSymbol.test(chars)
4242        ? stringToArray(result).slice(0, padLength).join('')
4243        : result.slice(0, padLength);
4244    }
4245
4246    /**
4247     * Creates a function that wraps `func` to invoke it with the optional `this`
4248     * binding of `thisArg` and the `partials` prepended to those provided to
4249     * the wrapper.
4250     *
4251     * @private
4252     * @param {Function} func The function to wrap.
4253     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4254     * @param {*} thisArg The `this` binding of `func`.
4255     * @param {Array} partials The arguments to prepend to those provided to the new function.
4256     * @returns {Function} Returns the new wrapped function.
4257     */
4258    function createPartialWrapper(func, bitmask, thisArg, partials) {
4259      var isBind = bitmask & BIND_FLAG,
4260          Ctor = createCtorWrapper(func);
4261
4262      function wrapper() {
4263        var argsIndex = -1,
4264            argsLength = arguments.length,
4265            leftIndex = -1,
4266            leftLength = partials.length,
4267            args = Array(leftLength + argsLength),
4268            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4269
4270        while (++leftIndex < leftLength) {
4271          args[leftIndex] = partials[leftIndex];
4272        }
4273        while (argsLength--) {
4274          args[leftIndex++] = arguments[++argsIndex];
4275        }
4276        return apply(fn, isBind ? thisArg : this, args);
4277      }
4278      return wrapper;
4279    }
4280
4281    /**
4282     * Creates a `_.range` or `_.rangeRight` function.
4283     *
4284     * @private
4285     * @param {boolean} [fromRight] Specify iterating from right to left.
4286     * @returns {Function} Returns the new range function.
4287     */
4288    function createRange(fromRight) {
4289      return function(start, end, step) {
4290        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4291          end = step = undefined;
4292        }
4293        // Ensure the sign of `-0` is preserved.
4294        start = toNumber(start);
4295        start = start === start ? start : 0;
4296        if (end === undefined) {
4297          end = start;
4298          start = 0;
4299        } else {
4300          end = toNumber(end) || 0;
4301        }
4302        step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4303        return baseRange(start, end, step, fromRight);
4304      };
4305    }
4306
4307    /**
4308     * Creates a function that wraps `func` to continue currying.
4309     *
4310     * @private
4311     * @param {Function} func The function to wrap.
4312     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4313     * @param {Function} wrapFunc The function to create the `func` wrapper.
4314     * @param {*} placeholder The placeholder to replace.
4315     * @param {*} [thisArg] The `this` binding of `func`.
4316     * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4317     * @param {Array} [holders] The `partials` placeholder indexes.
4318     * @param {Array} [argPos] The argument positions of the new function.
4319     * @param {number} [ary] The arity cap of `func`.
4320     * @param {number} [arity] The arity of `func`.
4321     * @returns {Function} Returns the new wrapped function.
4322     */
4323    function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4324      var isCurry = bitmask & CURRY_FLAG,
4325          newArgPos = argPos ? copyArray(argPos) : undefined,
4326          newsHolders = isCurry ? holders : undefined,
4327          newHoldersRight = isCurry ? undefined : holders,
4328          newPartials = isCurry ? partials : undefined,
4329          newPartialsRight = isCurry ? undefined : partials;
4330
4331      bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4332      bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4333
4334      if (!(bitmask & CURRY_BOUND_FLAG)) {
4335        bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4336      }
4337      var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
4338          result = wrapFunc.apply(undefined, newData);
4339
4340      if (isLaziable(func)) {
4341        setData(result, newData);
4342      }
4343      result.placeholder = placeholder;
4344      return result;
4345    }
4346
4347    /**
4348     * Creates a function like `_.round`.
4349     *
4350     * @private
4351     * @param {string} methodName The name of the `Math` method to use when rounding.
4352     * @returns {Function} Returns the new round function.
4353     */
4354    function createRound(methodName) {
4355      var func = Math[methodName];
4356      return function(number, precision) {
4357        number = toNumber(number);
4358        precision = toInteger(precision);
4359        if (precision) {
4360          // Shift with exponential notation to avoid floating-point issues.
4361          // See [MDN](https://mdn.io/round#Examples) for more details.
4362          var pair = (toString(number) + 'e').split('e'),
4363              value = func(pair[0] + 'e' + (+pair[1] + precision));
4364
4365          pair = (toString(value) + 'e').split('e');
4366          return +(pair[0] + 'e' + (+pair[1] - precision));
4367        }
4368        return func(number);
4369      };
4370    }
4371
4372    /**
4373     * Creates a set of `values`.
4374     *
4375     * @private
4376     * @param {Array} values The values to add to the set.
4377     * @returns {Object} Returns the new set.
4378     */
4379    var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4380      return new Set(values);
4381    };
4382
4383    /**
4384     * Creates a function that either curries or invokes `func` with optional
4385     * `this` binding and partially applied arguments.
4386     *
4387     * @private
4388     * @param {Function|string}
4388 func The function or method name to wrap.
4389     * @param {number} bitmask The bitmask of wrapper flags.
4390     *  The bitmask may be composed of the following flags:
4391     *     1 - `_.bind`
4392     *     2 - `_.bindKey`
4393     *     4 - `_.curry` or `_.curryRight` of a bound function
4394     *     8 - `_.curry`
4395     *    16 - `_.curryRight`
4396     *    32 - `_.partial`
4397     *    64 - `_.partialRight`
4398     *   128 - `_.rearg`
4399     *   256 - `_.ary`
4400     * @param {*} [thisArg] The `this` binding of `func`.
4401     * @param {Array} [partials] The arguments to be partially applied.
4402     * @param {Array} [holders] The `partials` placeholder indexes.
4403     * @param {Array} [argPos] The argument positions of the new function.
4404     * @param {number} [ary] The arity cap of `func`.
4405     * @param {number} [arity] The arity of `func`.
4406     * @returns {Function} Returns the new wrapped function.
4407     */
4408    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4409      var isBindKey = bitmask & BIND_KEY_FLAG;
4410      if (!isBindKey && typeof func != 'function') {
4411        throw new TypeError(FUNC_ERROR_TEXT);
4412      }
4413      var length = partials ? partials.length : 0;
4414      if (!length) {
4415        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4416        partials = holders = undefined;
4417      }
4418      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4419      arity = arity === undefined ? arity : toInteger(arity);
4420      length -= holders ? holders.length : 0;
4421
4422      if (bitmask & PARTIAL_RIGHT_FLAG) {
4423        var partialsRight = partials,
4424            holdersRight = holders;
4425
4426        partials = holders = undefined;
4427      }
4428      var data = isBindKey ? undefined : getData(func),
4429          newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
4430
4431      if (data) {
4432        mergeData(newData, data);
4433      }
4434      func = newData[0];
4435      bitmask = newData[1];
4436      thisArg = newData[2];
4437      partials = newData[3];
4438      holders = newData[4];
4439      arity = newData[9] = newData[9] == null
4440        ? (isBindKey ? 0 : func.length)
4441        : nativeMax(newData[9] - length, 0);
4442
4443      if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4444        bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4445      }
4446      if (!bitmask || bitmask == BIND_FLAG) {
4447        var result = createBaseWrapper(func, bitmask, thisArg);
4448      } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4449        result = createCurryWrapper(func, bitmask, arity);
4450      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4451        result = createPartialWrapper(func, bitmask, thisArg, partials);
4452      } else {
4453        result = createHybridWrapper.apply(undefined, newData);
4454      }
4455      var setter = data ? baseSetData : setData;
4456      return setter(result, newData);
4457    }
4458
4459    /**
4460     * A specialized version of `baseIsEqualDeep` for arrays with support for
4461     * partial deep comparisons.
4462     *
4463     * @private
4464     * @param {Array} array The array to compare.
4465     * @param {Array} other The other array to compare.
4466     * @param {Function} equalFunc The function to determine equivalents of values.
4467     * @param {Function} [customizer] The function to customize comparisons.
4468     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4469     * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4470     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4471     */
4472    function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4473      var index = -1,
4474          isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4475          isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4476          arrLength = array.length,
4477          othLength = other.length;
4478
4479      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4480        return false;
4481      }
4482      // Assume cyclic values are equal.
4483      var stacked = stack.get(array);
4484      if (stacked) {
4485        return stacked == other;
4486      }
4487      var result = true;
4488      stack.set(array, other);
4489
4490      // Ignore non-index properties.
4491      while (++index < arrLength) {
4492        var arrValue = array[index],
4493            othValue = other[index];
4494
4495        if (customizer) {
4496          var compared = isPartial
4497            ? customizer(othValue, arrValue, index, other, array, stack)
4498            : customizer(arrValue, othValue, index, array, other, stack);
4499        }
4500        if (compared !== undefined) {
4501          if (compared) {
4502            continue;
4503          }
4504          result = false;
4505          break;
4506        }
4507        // Recursively compare arrays (susceptible to call stack limits).
4508        if (isUnordered) {
4509          if (!arraySome(other, function(othValue) {
4510                return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4511              })) {
4512            result = false;
4513            break;
4514          }
4515        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4516          result = false;
4517          break;
4518        }
4519      }
4520      stack['delete'](array);
4521      return result;
4522    }
4523
4524    /**
4525     * A specialized version of `baseIsEqualDeep` for comparing objects of
4526     * the same `toStringTag`.
4527     *
4528     * **Note:** This function only supports comparing values with tags of
4529     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4530     *
4531     * @private
4532     * @param {Object} object The object to compare.
4533     * @param {Object} other The other object to compare.
4534     * @param {string} tag The `toStringTag` of the objects to compare.
4535     * @param {Function} equalFunc The function to determine equivalents of values.
4536     * @param {Function} [customizer] The function to customize comparisons.
4537     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4538     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4539     */
4540    function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4541      switch (tag) {
4542        case arrayBufferTag:
4543          if ((object.byteLength != other.byteLength) ||
4544              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4545            return false;
4546          }
4547          return true;
4548
4549        case boolTag:
4550        case dateTag:
4551          // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4552          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4553          return +object == +other;
4554
4555        case errorTag:
4556          return object.name == other.name && object.message == other.message;
4557
4558        case numberTag:
4559          // Treat `NaN` vs. `NaN` as equal.
4560          return (object != +object) ? other != +other : object == +other;
4561
4562        case regexpTag:
4563        case stringTag:
4564          // Coerce regexes to strings and treat strings primitives and string
4565          // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4566          return object == (other + '');
4567
4568        case mapTag:
4569          var convert = mapToArray;
4570
4571        case setTag:
4572          var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4573          convert || (convert = setToArray);
4574
4575          // Recursively compare objects (susceptible to call stack limits).
4576          return (isPartial || object.size == other.size) &&
4577            equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4578
4579        case symbolTag:
4580          return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4581      }
4582      return false;
4583    }
4584
4585    /**
4586     * A specialized version of `baseIsEqualDeep` for objects with support for
4587     * partial deep comparisons.
4588     *
4589     * @private
4590     * @param {Object} object The object to compare.
4591     * @param {Object} other The other object to compare.
4592     * @param {Function} equalFunc The function to determine equivalents of values.
4593     * @param {Function} [customizer] The function to customize comparisons.
4594     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4595     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4596     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4597     */
4598    function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4599      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4600          objProps = keys(object),
4601          objLength = objProps.length,
4602          othProps = keys(other),
4603          othLength = othProps.length;
4604
4605      if (objLength != othLength && !isPartial) {
4606        return false;
vendor: 1,071 bytes, lines 4607-4639
4607      }
4608      var index = objLength;
4609      while (index--) {
4610        var key = objProps[index];
4611        if (!(isPartial ? key in other : baseHas(other, key))) {
4612          return false;
4613        }
4614      }
4615      // Assume cyclic values are equal.
4616      var stacked = stack.get(object);
4617      if (stacked) {
4618        return stacked == other;
4619      }
4620      var result = true;
4621      stack.set(object, other);
4622
4623      var skipCtor = isPartial;
4624      while (++index < objLength) {
4625        key = objProps[index];
4626        var objValue = object[key],
4627            othValue = other[key];
4628
4629        if (customizer) {
4630          var compared = isPartial
4631            ? customizer(othValue, objValue, key, other, object, stack)
4632            : customizer(objValue, othValue, key, object, other, stack);
4633        }
4634        // Recursively compare objects (susceptible to call stack limits).
4635        if (!(compared === undefined
4636              ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4637              : compared
4638            )) {
4639          result = false;
4640          break;
4641        }
4642        skipCtor || (skipCtor = key == 'constructor');
4643      }
4644      if (result && !skipCtor) {
4645        var objCtor = object.constructor,
4646            othCtor = other.constructor;
4647
4648        // Non `Object` object instances with different constructors are not equal.
4649        if (objCtor != othCtor &&
4650            ('constructor' in object && 'constructor' in other) &&
4651            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4652              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4653          result = false;
4654        }
4655      }
4656      stack['delete'](object);
4657      return result;
4658    }
4659
4660    /**
4661     * Gets metadata for `func`.
4662     *
4663     * @private
4664     * @param {Function} func The function to query.
4665     * @returns {*} Returns the metadata for `func`.
4666     */
4667    var getData = !metaMap ? noop : function(func) {
4668      return metaMap.get(func);
4669    };
4670
4671    /**
4672     * Gets the name of `func`.
4673     *
4674     * @private
4675     * @param {Function} func The function to query.
4676     * @returns {string} Returns the function name.
4677     */
4678    function getFuncName(func) {
4679      var result = (func.name + ''),
4680          array = realNames[result],
4681          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
4682
4683      while (length--) {
4684        var data = array[length],
4685            otherFunc = data.func;
4686        if (otherFunc == null || otherFunc == func) {
4687          return data.name;
4688        }
4689      }
4690      return result;
4691    }
4692
4693    /**
4694     * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4695     * customized this function returns the custom method, otherwise it returns
4696     * `baseIteratee`. If arguments are provided the chosen function is invoked
4697     * with them and its result is returned.
4698     *
4699     * @private
4700     * @param {*} [value] The value to convert to an iteratee.
4701     * @param {number} [arity] The arity of the created iteratee.
4702     * @returns {Function} Returns the chosen function or its result.
4703     */
4704    function getIteratee() {
4705      var result = lodash.iteratee || iteratee;
4706      result = result === iteratee ? baseIteratee : result;
4707      return arguments.length ? result(arguments[0], arguments[1]) : result;
4708    }
4709
4710    /**
4711     * Gets the "length" property value of `object`.
4712     *
4713     * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4714     * that affects Safari on at least iOS 8.1-8.3 ARM64.
4715     *
4716     * @private
4717     * @param {Object} object The object to query.
4718     * @returns {*} Returns the "length" value.
4719     */
4720    var getLength = baseProperty('length');
4721
4722    /**
4723     * Gets the property names, values, and compare flags of `object`.
4724     *
4725     * @private
4726     * @param {Object} object The object to query.
4727     * @returns {Array} Returns the match data of `object`.
4728     */
4729    function getMatchData(object) {
4730      var result = toPairs(object),
4731          length = result.length;
4732
4733      while (length--) {
4734        result[length][2] = isStrictComparable(result[length][1]);
4735      }
4736      return result;
4737    }
4738
4739    /**
4740     * Gets the native function at `key` of `object`.
4741     *
4742     * @private
4743     * @param {Object} object The object to query.
4744     * @param {string} key The key of the method to get.
4745     * @returns {*} Returns the function if it's native, else `undefined`.
4746     */
4747    function getNative(object, key) {
4748      var value = object == null ? undefined : object[key];
4749      return isNative(value) ? value : undefined;
4750    }
4751
4752    /**
4753     * Creates an array of the own symbol properties of `object`.
4754     *
4755     * @private
4756     * @param {Object} object The object to query.
4757     * @returns {Array} Returns the array of symbols.
4758     */
4759    var getSymbols = getOwnPropertySymbols || function() {
4760      return [];
4761    };
4762
4763    /**
4764     * Gets the `toStringTag` of `value`.
4765     *
4766     * @private
4767     * @param {*} value The value to query.
4768     * @returns {string} Returns the `toStringTag`.
4769     */
4770    function getTag(value) {
4771      return objectToString.call(value);
4772    }
4773
4774    // Fallback for IE 11 providing `toStringTag` values for maps and sets.
4775    if ((Map && getTag(new Map) != mapTag) || (Set && getTag(new Set) != setTag)) {
4776      getTag = function(value) {
4777        var result = objectToString.call(value),
4778            Ctor = result == objectTag ? value.constructor : null,
4779            ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
4780
4781        if (ctorString) {
4782          if (ctorString == mapCtorString) {
4783            return mapTag;
4784          }
4785          if (ctorString == setCtorString) {
4786            return setTag;
4787          }
4788        }
4789        return result;
4790      };
4791    }
4792
4793    /**
4794     * Gets the view, applying any `transforms` to the `start` and `end` positions.
4795     *
4796     * @private
4797     * @param {number} start The start of the view.
4798     * @param {number} end The end of the view.
4799     * @param {Array} transforms The transformations to apply to the view.
4800     * @returns {Object} Returns an object containing the `start` and `end`
4801     *  positions of the view.
4802     */
4803    function getView(start, end, transforms) {
4804      var index = -1,
4805          length = transforms.length;
4806
4807      while (++index < length) {
4808        var data = transforms[index],
4809            size = data.size;
4810
4811        switch (data.type) {
4812          case 'drop':      start += size; break;
4813          case 'dropRight': end -= size; break;
4814          case 'take':      end = nativeMin(end, start + size); break;
4815          case 'takeRight': start = nativeMax(start, end - size); break;
4816        }
4817      }
4818      return { 'start': start, 'end': end };
4819    }
4820
4821    /**
4822     * Checks if `path` exists on `object`.
4823     *
4824     * @private
4825     * @param {Object} object The object to query.
4826     * @param {Array|string} path The path to check.
4827     * @param {Function} hasFunc The function to check properties.
4828     * @returns {boolean} Returns `true` if `path` exists, else `false`.
4829     */
4830    function hasPath(object, path, hasFunc) {
4831      if (object == null) {
4832        return false;
4833      }
4834      var result = hasFunc(object, path);
4835      if (!result && !isKey(path)) {
4836        path = baseToPath(path);
4837        object = parent(object, path);
4838        if (object != null) {
4839          path = last(path);
4840          result = hasFunc(object, path);
4841        }
4842      }
4843      return result || (isLength(object && object.length) && isIndex(path, object.length) &&
4844        (isArray(object) || isString(object) || isArguments(object)));
4845    }
4846
4847    /**
4848     * Initializes an array clone.
4849     *
4850     * @private
4851     * @param {Array} array The array to clone.
4852     * @returns {Array} Returns the initialized clone.
4853     */
4854    function initCloneArray(array) {
4855      var length = array.length,
4856          result = array.constructor(length);
4857
4858      // Add properties assigned by `RegExp#exec`.
4859      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
4860        result.index = array.index;
4861        result.input = array.input;
4862      }
4863      return result;
4864    }
4865
4866    /**
4867     * Initializes an object clone.
4868     *
4869     * @private
4870     * @param {Object} object The object to clone.
4871     * @returns {Object} Returns the initialized clone.
4872     */
4873    function initCloneObject(object) {
4874      var Ctor = object.constructor;
4875      return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
4876    }
4877
4878    /**
4879     * Initializes an object clone based on its `toStringTag`.
4880     *
4881     * **Note:** This function only supports cloning values with tags of
4882     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4883     *
4884     * @private
4885     * @param {Object} object The object to clone.
4886     * @param {string} tag The `toStringTag` of the object to clone.
4887     * @param {boolean} [isDeep] Specify a deep clone.
4888     * @returns {Object} Returns the initialized clone.
4889     */
4890    function initCloneByTag(object, tag, isDeep) {
4891      var Ctor = object.constructor;
4892      switch (tag) {
4893        case arrayBufferTag:
4894          return cloneBuffer(object);
4895
4896        case boolTag:
4897        case dateTag:
4898          return new Ctor(+object);
4899
4900        case float32Tag: case float64Tag:
4901        case int8Tag: case int16Tag: case int32Tag:
4902        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
4903          return cloneTypedArray(object, isDeep);
4904
4905        case mapTag:
4906          return cloneMap(object);
4907
4908        case numberTag:
4909        case stringTag:
4910          return new Ctor(object);
4911
4912        case regexpTag:
4913          return cloneRegExp(object);
4914
4915        case setTag:
4916          return cloneSet(object);
4917
4918        case symbolTag:
4919          return cloneSymbol(object);
4920      }
4921    }
4922
4923    /**
4924     * Creates an array of index keys for `object` values of arrays,
4925     * `arguments` objects, and strings, otherwise `null` is returned.
4926     *
4927     * @private
4928     * @param {Object} object The object to query.
4929     * @returns {Array|null} Returns index keys, else `null`.
4930     */
4931    function indexKeys(object) {
4932      var length = object ? object.length : undefined;
4933      return (isLength(length) && (isArray(object) || isString(object) || isArguments(object)))
4934        ? baseTimes(length, String)
4935        : null;
4936    }
4937
4938    /**
4939     * Checks if the provided arguments are from an iteratee call.
4940     *
4941     * @private
4942     * @param {*} value The potential iteratee value argument.
4943     * @param {*} index The potential iteratee index or key argument.
4944     * @param {*} object The potential iteratee object argument.
4945     * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
4946     */
4947    function isIterateeCall(value, index, object) {
4948      if (!isObject(object)) {
4949        return false;
4950      }
4951      var type = typeof index;
4952      if (type == 'number'
4953          ? (isArrayLike(object) && isIndex(index, object.length))
4954          : (type == 'string' && index in object)) {
4955        return eq(object[index], value);
4956      }
4957      return false;
4958    }
4959
4960    /**
4961     * Checks if `value` is a property name and not a property path.
4962     *
4963     * @private
4964     * @param {*} value The value to check.
4965     * @param {Object} [object] The object to query keys on.
4966     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
4967     */
4968    function isKey(value, object) {
4969      if (typeof value == 'number') {
4970        return true;
4971      }
4972      return !isArray(value) &&
4973        (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
4974          (object != null && value in Object(object)));
4975    }
4976
4977    /**
4978     * Checks if `value` is suitable for use as unique object key.
4979     *
4980     * @private
4981     * @param {*} value The value to check.
4982     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
4983     */
4984    function isKeyable(value) {
4985      var type = typeof value;
4986      return type == 'number' || type == 'boolean' ||
4987        (type == 'string' && value !== '__proto__') || value == null;
4988    }
4989
4990    /**
4991     * Checks if `func` has a lazy counterpart.
4992     *
4993     * @private
4994     * @param {Function} func The function to check.
4995     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
4996     */
4997    function isLaziable(func) {
4998      var funcName = getFuncName(func),
4999          other = lodash[funcName];
5000
5001      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5002        return false;
5003      }
5004      if (func === other) {
5005        return true;
5006      }
5007      var data = getData(other);
5008      return !!data && func === data[0];
5009    }
5010
5011    /**
5012     * Checks if `value` is likely a prototype object.
5013     *
5014     * @private
5015     * @param {*} value The value to check.
5016     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5017     */
5018    function isPrototype(value) {
5019      var Ctor = value && value.constructor,
5020          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5021
5022      return value === proto;
5023    }
5024
5025    /**
5026     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5027     *
5028     * @private
5029     * @param {*} value The value to check.
5030     * @returns {boolean} Returns `true` if `value` if suitable for strict
5031     *  equality comparisons, else `false`.
5032     */
5033    function isStrictComparable(value) {
5034      return value === value && !isObject(value);
5035    }
5036
5037    /**
5038     * Merges the function metadata of `source` into `data`.
5039     *
5040     * Merging metadata reduces the number of wrappers used to invoke a function.
5041     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5042     * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5043     * modify function arguments, making the order in which they are executed important,
5044     * preventing the merging of metadata. However, we make an exception for a safe
5045     * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5046     *
5047     * @private
5048     * @param {Array} data The destination metadata.
5049     * @param {Array} source The source metadata.
5050     * @returns {Array} Returns `data`.
5051     */
5052    function mergeData(data, source) {
5053      var bitmask = data[1],
5054          srcBitmask = source[1],
5055          newBitmask = bitmask | srcBitmask,
5056          isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5057
5058      var isCombo =
5059        (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
5060        (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5061        (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5062
5063      // Exit early if metadata can't be merged.
5064      if (!(isCommon || isCombo)) {
5065        return data;
5066      }
5067      // Use source `thisArg` if available.
5068      if (srcBitmask & BIND_FLAG) {
5069        data[2] = source[2];
5070        // Set when currying a bound function.
5071        newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
5072      }
5073      // Compose partial arguments.
5074      var value = source[3];
5075      if (value) {
5076        var partials = data[3];
5077        data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5078        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5079      }
5080      // Compose partial right arguments.
5081      value = source[5];
5082      if (value) {
5083        partials = data[5];
5084        data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5085        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5086      }
5087      // Use source `argPos` if available.
5088      value = source[7];
5089      if (value) {
5090        data[7] = copyArray(value);
5091      }
5092      // Use source `ary` if it's smaller.
5093      if (srcBitmask & ARY_FLAG) {
5094        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5095      }
5096      // Use source `arity` if one is not provided.
5097      if (data[9] == null) {
5098        data[9] = source[9];
5099      }
5100      // Use source `func` and merge bitmasks.
5101      data[0] = source[0];
5102      data[1] = newBitmask;
5103
5104      return data;
5105    }
5106
5107    /**
5108     * Used by `_.defaultsDeep` to customize its `_.merge` use.
5109     *
5110     * @private
5111     * @param {*} objValue The destination value.
5112     * @param {*} srcValue The source value.
5113     * @param {string} key The key of the property to merge.
5114     * @param {Object} object The parent object of `objValue`.
5115     * @param {Object} source The parent object of `srcValue`.
5116     * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5117     * @returns {*} Returns the value to assign.
5118     */
5119    function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5120      if (isObject(objValue) && isObject(srcValue)) {
5121        stack.set(srcValue, objValue);
5122        baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
5123      }
5124      return objValue;
5125    }
5126
5127    /**
5128     * Gets the parent value at `path` of `object`.
5129     *
5130     * @private
5131     * @param {Object} object The object to query.
5132     * @param {Array} path The path to get the parent value of.
5133     * @returns {*} Returns the parent value.
5134     */
5135    function parent(object, path) {
5136      return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5137    }
5138
5139    /**
5140     * Reorder `array` according to the specified indexes where the element at
5141     * the first index is assigned as the first element, the element at
5142     * the second index is assigned as the second element, and so on.
5143     *
5144     * @private
5145     * @param {Array} array The array to reorder.
5146     * @param {Array} indexes The arranged array indexes.
5147     * @returns {Array} Returns `array`.
5148     */
5149    function reorder(array, indexes) {
5150      var arrLength = array.length,
5151          length = nativeMin(indexes.length, arrLength),
5152          oldArray = copyArray(array);
5153
5154      while (length--) {
5155        var index = indexes[length];
5156        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5157      }
5158      return array;
5159    }
5160
5161    /**
5162     * Sets metadata for `func`.
5163     *
5164     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5165     * period of time, it will trip its breaker and transition to an identity function
5166     * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5167     * for more details.
5168     *
5169     * @private
5170     * @param {Function} func The function to associate metadata with.
5171     * @param {*} data The metadata.
5172     * @returns {Function} Returns `func`.
5173     */
5174    var setData = (function() {
5175      var count = 0,
5176          lastCalled = 0;
5177
5178      return function(key, value) {
5179        var stamp = now(),
5180            remaining = HOT_SPAN - (stamp - lastCalled);
5181
5182        lastCalled = stamp;
5183        if (remaining > 0) {
5184          if (++count >= HOT_COUNT) {
5185            return key;
5186          }
5187        } else {
5188          count = 0;
5189        }
5190        return baseSetData(key, value);
5191      };
5192    }());
5193
5194    /**
5195     * Converts `string` to a property path array.
5196     *
5197     * @private
5198     * @param {string} string The string to convert.
5199     * @returns {Array} Returns the property path array.
5200     */
5201    function stringToPath(string) {
5202      var result = [];
5203      toString(string).replace(rePropName, function(match, number, quote, string) {
5204        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5205      });
5206      return result;
5207    }
5208
5209    /**
5210     * Converts `value` to an array-like object if it's not one.
5211     *
5212     * @private
5213     * @param {*} value The value to process.
5214     * @returns {Array} Returns the array-like object.
5215     */
5216    function toArrayLikeObject(value) {
5217      return isArrayLikeObject(value) ? value : [];
5218    }
5219
5220    /**
5221     * Converts `value` to a function if it's not one.
5222     *
5223     * @private
5224     * @param {*} value The value to process.
5225     * @returns {Function} Returns the function.
5226     */
5227    function toFunction(value) {
5228      return typeof value == 'function' ? value : identity;
5229    }
5230
5231    /**
5232     * Creates a clone of `wrapper`.
5233     *
5234     * @private
5235     * @param {Object} wrapper The wrapper to clone.
5236     * @returns {Object} Returns the cloned wrapper.
5237     */
5238    function wrapperClone(wrapper) {
5239      if (wrapper instanceof LazyWrapper) {
5240        return wrapper.clone();
5241      }
5242      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5243      result.__actions__ = copyArray(wrapper.__actions__);
5244      result.__index__  = wrapper.__index__;
5245      result.__values__ = wrapper.__values__;
5246      return result;
5247    }
5248
5249    /*------------------------------------------------------------------------*/
5250
5251    /**
5252     * Creates an array of elements split into groups the length of `size`.
5253     * If `array` can't be split evenly, the final chunk will be the remaining
5254     * elements.
5255     *
5256     * @static
5257     * @memberOf _
5258     * @category Array
5259     * @param {Array} array The array to process.
5260     * @param {number} [size=0] The length of each chunk.
5261     * @returns {Array} Returns the new array containing chunks.
5262     * @example
5263     *
5264     * _.chunk(['a', 'b', 'c', 'd'], 2);
5265     * // => [['a', 'b'], ['c', 'd']]
5266     *
5267     * _.chunk(['a', 'b', 'c', 'd'], 3);
5268     * // => [['a', 'b', 'c'], ['d']]
5269     */
5270    function chunk(array, size) {
5271      size = nativeMax(toInteger(size), 0);
5272
5273      var length = array ? array.length : 0;
5274      if (!length || size < 1) {
5275        return [];
5276      }
5277      var index = 0,
5278          resIndex = -1,
5279          result = Array(nativeCeil(length / size));
5280
5281      while (index < length) {
5282        result[++resIndex] = baseSlice(array, index, (index += size));
5283      }
5284      return result;
5285    }
5286
5287    /**
5288     * Creates an array with all falsey values removed. The values `false`, `null`,
5289     * `0`, `""`, `undefined`, and `NaN` are falsey.
5290     *
5291     * @static
5292     * @memberOf _
5293     * @category Array
5294     * @param {Array} array The array to compact.
5295     * @returns {Array} Returns the new array of filtered values.
5296     * @example
5297     *
5298     * _.compact([0, 1, false, 2, '', 3]);
5299     * // => [1, 2, 3]
5300     */
5301    function compact(array) {
5302      var index = -1,
5303          length = array ? array.length : 0,
5304          resIndex = -1,
5305          result = [];
5306
5307      while (++index < length) {
5308        var value = array[index];
5309        if (value) {
5310          result[++resIndex] = value;
5311        }
5312      }
5313      return result;
5314    }
5315
5316    /**
5317     * Creates a new array concatenating `array` with any additional arrays
5318     * and/or values.
5319     *
5320     * @static
5321     * @memberOf _
5322     * @category Array
5323     * @param {Array} array The array to concatenate.
5324     * @param {...*} [values] The values to concatenate.
5325     * @returns {Array} Returns the new concatenated array.
5326     * @example
5327     *
5328     * var array = [1];
5329     * var other = _.concat(array, 2, [3], [[4]]);
5330     *
5331     * console.log(other);
5332     * // => [1, 2, 3, [4]]
5333     *
5334     * console.log(array);
5335     * // => [1]
5336     */
5337    var concat = rest(function(array, values) {
5338      if (!isArray(array)) {
5339        array = array == null ? [] : [Object(array)];
5340      }
5341      values = baseFlatten(values);
5342      return arrayConcat(array, values);
5343    });
5344
5345    /**
5346     * Creates an array of unique `array` values not included in the other
5347     * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5348     * for equality comparisons.
5349     *
5350     * @static
5351     * @memberOf _
5352     * @category Array
5353     * @param {Array} array The array to inspect.
5354     * @param {...Array} [values] The values to exclude.
5355     * @returns {Array} Returns the new array of filtered values.
5356     * @example
5357     *
5358     * _.difference([3, 2, 1], [4, 2]);
5359     * // => [3, 1]
5360     */
5361    var difference = rest(function(array, values) {
5362      return isArrayLikeObject(array)
5363        ? baseDifference(array, baseFlatten(values, false, true))
5364        : [];
5365    });
5366
5367    /**
5368     * This method is like `_.difference` except that it accepts `iteratee` which
5369     * is invoked for each element of `array` and `values` to generate the criterion
5370     * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5371     *
5372     * @static
5373     * @memberOf _
5374     * @category Array
5375     * @param {Array} array The array to inspect.
5376     * @param {...Array} [values] The values to exclude.
5377     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5378     * @returns {Array} Returns the new array of filtered values.
5379     * @example
5380     *
5381     * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5382     * // => [3.1, 1.3]
5383     *
5384     * // using the `_.property` iteratee shorthand
5385     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5386     * // => [{ 'x': 2 }]
5387     */
5388    var differenceBy = rest(function(array, values) {
5389      var iteratee = last(values);
5390      if (isArrayLikeObject(iteratee)) {
5391        iteratee = undefined;
5392      }
5393      return isArrayLikeObject(array)
5394        ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
5395        : [];
5396    });
5397
5398    /**
5399     * This method is like `_.difference` except that it accepts `comparator`
5400     * which is invoked to compare elements of `array` to `values`. The comparator
5401     * is invoked with two arguments: (arrVal, othVal).
5402     *
5403     * @static
5404     * @memberOf _
5405     * @category Array
5406     * @param {Array} array The array to inspect.
5407     * @param {...Array} [values] The values to exclude.
5408     * @param {Function} [comparator] The comparator invoked per element.
5409     * @returns {Array} Returns the new array of filtered values.
5410     * @example
5411     *
5412     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5413     *
5414     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5415     * // => [{ 'x': 2, 'y': 1 }]
5416     */
5417    var differenceWith = rest(function(array, values) {
5418      var comparator = last(values);
5419      if (isArrayLikeObject(comparator)) {
5420        comparator = undefined;
5421      }
5422      return isArrayLikeObject(array)
5423        ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
5424        : [];
5425    });
5426
5427    /**
5428     * Creates a slice of `array` with `n` elements dropped from the beginning.
5429     *
5430     * @static
5431     * @memberOf _
5432     * @category Array
5433     * @param {Array} array The array to query.
5434     * @param {number} [n=1] The number of elements to drop.
5435     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5436     * @returns {Array} Returns the slice of `array`.
5437     * @example
5438     *
5439     * _.drop([1, 2, 3]);
5440     * // => [2, 3]
5441     *
5442     * _.drop([1, 2, 3], 2);
5443     * // => [3]
5444     *
5445     * _.drop([1, 2, 3], 5);
5446     * // => []
5447     *
5448     * _.drop([1, 2, 3], 0);
5449     * // => [1, 2, 3]
5450     */
5451    function drop(array, n, guard) {
5452      var length = array ? array.length : 0;
5453      if (!length) {
5454        return [];
5455      }
5456      n = (guard || n === undefined) ? 1 : toInteger(n);
5457      return baseSlice(array, n < 0 ? 0 : n, length);
5458    }
5459
5460    /**
5461     * Creates a slice of `array` with `n` elements dropped from the end.
5462     *
5463     * @static
5464     * @memberOf _
5465     * @category Array
5466     * @param {Array} array The array to query.
5467     * @param {number} [n=1] The number of elements to drop.
5468     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5469     * @returns {Array} Returns the slice of `array`.
5470     * @example
5471     *
5472     * _.dropRight([1, 2, 3]);
5473     * // => [1, 2]
5474     *
5475     * _.dropRight([1, 2, 3], 2);
5476     * // => [1]
5477     *
5478     * _.dropRight([1, 2, 3], 5);
5479     * // => []
5480     *
5481     * _.dropRight([1, 2, 3], 0);
5482     * // => [1, 2, 3]
5483     */
5484    function dropRight(array, n, guard) {
5485      var length = array ? array.length : 0;
5486      if (!length) {
5487        return [];
5488      }
5489      n = (guard || n === undefined) ? 1 : toInteger(n);
5490      n = length - n;
5491      return baseSlice(array, 0, n < 0 ? 0 : n);
5492    }
5493
5494    /**
5495     * Creates a slice of `array` excluding elements dropped from the end.
5496     * Elements are dropped until `predicate` returns falsey. The predicate is
5497     * invoked with three arguments: (value, index, array).
5498     *
5499     * @static
5500     * @memberOf _
5501     * @category Array
5502     * @param {Array} array The array to query.
5503     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5504     * @returns {Array} Returns the slice of `array`.
5505     * @example
5506     *
5507     * var users = [
5508     *   { 'user': 'barney',  'active': true },
5509     *   { 'user': 'fred',    'active': false },
5510     *   { 'user': 'pebbles', 'active': false }
5511     * ];
5512     *
5513     * _.dropRightWhile(users, function(o) { return !o.active; });
5514     * // => objects for ['barney']
5515     *
5516     * // using the `_.matches` iteratee shorthand
5517     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5518     * // => objects for ['barney', 'fred']
5519     *
5520     * // using the `_.matchesProperty` iteratee shorthand
5521     * _.dropRightWhile(users, ['active', false]);
5522     * // => objects for ['barney']
5523     *
5524     * // using the `_.property` iteratee shorthand
5525     * _.dropRightWhile(users, 'active');
5526     * // => objects for ['barney', 'fred', 'pebbles']
5527     */
5528    function dropRightWhile(array, predicate) {
5529      return (array && array.length)
5530        ? baseWhile(array, getIteratee(predicate, 3), true, true)
5531        : [];
5532    }
5533
5534    /**
5535     * Creates a slice of `array` excluding elements dropped from the beginning.
5536     * Elements are dropped until `predicate` returns falsey. The predicate is
5537     * invoked with three arguments: (value, index, array).
5538     *
5539     * @static
5540     * @memberOf _
5541     * @category Array
5542     * @param {Array} array The array to query.
5543     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5544     * @returns {Array} Returns the slice of `array`.
5545     * @example
5546     *
5547     * var users = [
5548     *   { 'user': 'barney',  'active': false },
5549     *   { 'user': 'fred',    'active': false },
5550     *   { 'user': 'pebbles', 'active': true }
5551     * ];
5552     *
5553     * _.dropWhile(users, function(o) { return !o.active; });
5554     * // => objects for ['pebbles']
5555     *
5556     * // using the `_.matches` iteratee shorthand
5557     * _.dropWhile(users, { 'user': 'barney', 'active': false });
5558     * // => objects for ['fred', 'pebbles']
5559     *
5560     * // using the `_.matchesProperty` iteratee shorthand
5561     * _.dropWhile(users, ['active', false]);
5562     * // => objects for ['pebbles']
5563     *
5564     * // using the `_.property` iteratee shorthand
5565     * _.dropWhile(users, 'active');
5566     * // => objects for ['barney', 'fred', 'pebbles']
5567     */
5568    function dropWhile(array, predicate) {
5569      return (array && array.length)
5570        ? baseWhile(array, getIteratee(predicate, 3), true)
5571        : [];
5572    }
5573
5574    /**
5575     * Fills elements of `array` with `value` from `start` up to, but not
5576     * including, `end`.
5577     *
5578     * **Note:** This method mutates `array`.
5579     *
5580     * @static
5581     * @memberOf _
5582     * @category Array
5583     * @param {Array} array The array to fill.
5584     * @param {*} value The value to fill `array` with.
5585     * @param {number} [start=0] The start position.
5586     * @param {number} [end=array.length] The end position.
5587     * @returns {Array} Returns `array`.
5588     * @example
5589     *
5590     * var array = [1, 2, 3];
5591     *
5592     * _.fill(array, 'a');
5593     * console.log(array);
5594     * // => ['a', 'a', 'a']
5595     *
5596     * _.fill(Array(3), 2);
5597     * // => [2, 2, 2]
5598     *
5599     * _.fill([4, 6, 8, 10], '*', 1, 3);
5600     * // => [4, '*', '*', 10]
5601     */
5602    function fill(array, value, start, end) {
5603      var length = array ? array.length : 0;
5604      if (!length) {
5605        return [];
5606      }
5607      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5608        start = 0;
5609        end = length;
5610      }
5611      return baseFill(array, value, start, end);
5612    }
5613
5614    /**
5615     * This method is like `_.find` except that it returns the index of the first
5616     * element `predicate` returns truthy for instead of the element itself.
5617     *
5618     * @static
5619     * @memberOf _
5620     * @category Array
5621     * @param {Array} array The array to search.
5622     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5623     * @returns {number} Returns the index of the found element, else `-1`.
5624     * @example
5625     *
5626     * var users = [
5627     *   { 'user': 'barney',  'active': false },
5628     *   { 'user': 'fred',    'active': false },
5629     *   { 'user': 'pebbles', 'active': true }
5630     * ];
5631     *
5632     * _.findIndex(users, function(o) { return o.user == 'barney'; });
5633     * // => 0
5634     *
5635     * // using the `_.matches` iteratee shorthand
5636     * _.findIndex(users, { 'user': 'fred', 'active': false });
5637     * // => 1
5638     *
5639     * // using the `_.matchesProperty` iteratee shorthand
5640     * _.findIndex(users, ['active', false]);
5641     * // => 0
5642     *
5643     * // using the `_.property` iteratee shorthand
5644     * _.findIndex(users, 'active');
5645     * // => 2
5646     */
5647    function findIndex(array, predicate) {
5648      return (array && array.length)
5649        ? baseFindIndex(array, getIteratee(predicate, 3))
5650        : -1;
5651    }
5652
5653    /**
5654     * This method is like `_.findIndex` except that it iterates over elements
5655     * of `collection` from right to left.
5656     *
5657     * @static
5658     * @memberOf _
5659     * @category Array
5660     * @param {Array} array The array to search.
5661     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5662     * @returns {number} Returns the index of the found element, else `-1`.
5663     * @example
5664     *
5665     * var users = [
5666     *   { 'user': 'barney',  'active': true },
5667     *   { 'user': 'fred',    'active': false },
5668     *   { 'user': 'pebbles', 'active': false }
5669     * ];
5670     *
5671     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5672     * // => 2
5673     *
5674     * // using the `_.matches` iteratee shorthand
5675     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5676     * // => 0
5677     *
5678     * // using the `_.matchesProperty` iteratee shorthand
5679     * _.findLastIndex(users, ['active', false]);
5680     * // => 2
5681     *
5682     * // using the `_.property` iteratee shorthand
5683     * _.findLastIndex(users, 'active');
5684     * // => 0
5685     */
5686    function findLastIndex(array, predicate) {
5687      return (array && array.length)
5688        ? baseFindIndex(array, getIteratee(predicate, 3), true)
5689        : -1;
5690    }
5691
5692    /**
5693     * Creates an array of flattened values by running each element in `array`
5694     * through `iteratee` and concating its result to the other mapped values.
5695     * The iteratee is invoked with three arguments: (value, index|key, array).
5696     *
5697     * @static
5698     * @memberOf _
5699     * @category Array
5700     * @param {Array} array The array to iterate over.
5701     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
5702     * @returns {Array} Returns the new array.
5703     * @example
5704     *
5705     * function duplicate(n) {
5706     *   return [n, n];
5707     * }
5708     *
5709     * _.flatMap([1, 2], duplicate);
5710     * // => [1, 1, 2, 2]
5711     */
5712    function flatMap(array, iteratee) {
5713      var length = array ? array.length : 0;
5714      return length ? baseFlatten(arrayMap(array, getIteratee(iteratee, 3))) : [];
5715    }
5716
5717    /**
5718     * Flattens `array` a single level.
5719     *
5720     * @static
5721     * @memberOf _
5722     * @category Array
5723     * @param {Array} array The array to flatten.
5724     * @returns {Array} Returns the new flattened array.
5725     * @example
5726     *
5727     * _.flatten([1, [2, 3, [4]]]);
5728     * // => [1, 2, 3, [4]]
5729     */
5730    function flatten(array) {
5731      var length = array ? array.length : 0;
5732      return length ? baseFlatten(array) : [];
5733    }
5734
5735    /**
5736     * This method is like `_.flatten` except that it recursively flattens `array`.
5737     *
5738     * @static
5739     * @memberOf _
5740     * @category Array
5741     * @param {Array} array The array to recursively flatten.
5742     * @returns {Array} Returns the new flattened array.
5743     * @example
5744     *
5745     * _.flattenDeep([1, [2, 3, [4]]]);
5746     * // => [1, 2, 3, 4]
5747     */
5748    function flattenDeep(array) {
5749      var length = array ? array.length : 0;
5750      return length ? baseFlatten(array, true) : [];
5751    }
5752
5753    /**
5754     * The inverse of `_.toPairs`; this method returns an object composed
5755     * from key-value `pairs`.
5756     *
5757     * @static
5758     * @memberOf _
5759     * @category Array
5760     * @param {Array} pairs The key-value pairs.
5761     * @returns {Object} Returns the new object.
5762     * @example
5763     *
5764     * _.fromPairs([['fred', 30], ['barney', 40]]);
5765     * // => { 'fred': 30, 'barney': 40 }
5766     */
5767    function fromPairs(pairs) {
5768      var index = -1,
5769          length = pairs ? pairs.length : 0,
5770          result = {};
5771
5772      while (++index < length) {
5773        var pair = pairs[index];
5774        result[pair[0]] = pair[1];
5775      }
5776      return result;
5777    }
5778
5779    /**
5780     * Gets the first element of `array`.
5781     *
5782     * @static
5783     * @memberOf _
5784     * @alias first
5785     * @category Array
5786     * @param {Array} array The array to query.
5787     * @returns {*} Returns the first element of `array`.
5788     * @example
5789     *
5790     * _.head([1, 2, 3]);
5791     * // => 1
5792     *
5793     * _.head([]);
5794     * // => undefined
5795     */
5796    function head(array) {
5797      return array ? array[0] : undefined;
5798    }
5799
5800    /**
5801     * Gets the index at which the first occurrence of `value` is found in `array`
5802     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5803     * for equality comparisons. If `fromIndex` is negative, it's used as the offset
5804     * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
5805     * performs a faster binary search.
5806     *
5807     * @static
5808     * @memberOf _
5809     * @category Array
5810     * @param {Array} array The array to search.
5811     * @param {*} value The value to search for.
5812     * @param {number} [fromIndex=0] The index to search from.
5813     * @returns {number} Returns the index of the matched value, else `-1`.
5814     * @example
5815     *
5816     * _.indexOf([1, 2, 1, 2], 2);
5817     * // => 1
5818     *
5819     * // using `fromIndex`
5820     * _.indexOf([1, 2, 1, 2], 2, 2);
5821     * // => 3
5822     */
5823    function indexOf(array, value, fromIndex) {
5824      var length = array ? array.length : 0;
5825      if (!length) {
5826        return -1;
5827      }
5828      fromIndex = toInteger(fromIndex);
5829      if (fromIndex < 0) {
5830        fromIndex = nativeMax(length + fromIndex, 0);
5831      }
5832      return baseIndexOf(array, value, fromIndex);
5833    }
5834
5835    /**
5836     * Gets all but the last element of `array`.
5837     *
5838     * @static
5839     * @memberOf _
5840     * @category Array
5841     * @param {Array} array The array to query.
5842     * @returns {Array} Returns the slice of `array`.
5843     * @example
5844     *
5845     * _.initial([1, 2, 3]);
5846     * // => [1, 2]
5847     */
5848    function initial(array) {
5849      return dropRight(array, 1);
5850    }
5851
5852    /**
5853     * Creates an array of unique values that are included in all of the provided
5854     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5855     * for equality comparisons.
5856     *
5857     * @static
5858     * @memberOf _
5859     * @category Array
5860     * @param {...Array} [arrays] The arrays to inspect.
5861     * @returns {Array} Returns the new array of shared values.
5862     * @example
5863     *
5864     * _.intersection([2, 1], [4, 2], [1, 2]);
5865     * // => [2]
5866     */
5867    var intersection = rest(function(arrays) {
5868      var mapped = arrayMap(arrays, toArrayLikeObject);
5869      return (mapped.length && mapped[0] === arrays[0])
5870        ? baseIntersection(mapped)
5871        : [];
5872    });
5873
5874    /**
5875     * This method is like `_.intersection` except that it accepts `iteratee`
5876     * which is invoked for each element of each `arrays` to generate the criterion
5877     * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5878     *
5879     * @static
5880     * @memberOf _
5881     * @category Array
5882     * @param {...Array} [arrays] The arrays to inspect.
5883     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5884     * @returns {Array} Returns the new array of shared values.
5885     * @example
5886     *
5887     * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
5888     * // => [2.1]
5889     *
5890     * // using the `_.property` iteratee shorthand
5891     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
5892     * // => [{ 'x': 1 }]
5893     */
5894    var intersectionBy = rest(function(arrays) {
5895      var iteratee = last(arrays),
5896          mapped = arrayMap(arrays, toArrayLikeObject);
5897
5898      if (iteratee === last(mapped)) {
5899        iteratee = undefined;
5900      } else {
5901        mapped.pop();
5902      }
5903      return (mapped.length && mapped[0] === arrays[0])
5904        ? baseIntersection(mapped, getIteratee(iteratee))
5905        : [];
5906    });
5907
5908    /**
5909     * This method is like `_.intersection` except that it accepts `comparator`
5910     * which is invoked to compare elements of `arrays`. The comparator is invoked
5911     * with two arguments: (arrVal, othVal).
5912     *
5913     * @static
5914     * @memberOf _
5915     * @category Array
5916     * @param {...Array} [arrays] The arrays to inspect.
5917     * @param {Function} [comparator] The comparator invoked per element.
5918     * @returns {Array} Returns the new array of shared values.
5919     * @example
5920     *
5921     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5922     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
5923     *
5924     * _.intersectionWith(objects, others, _.isEqual);
5925     * // => [{ 'x': 1, 'y': 2 }]
5926     */
5927    var intersectionWith = rest(function(arrays) {
5928      var comparator = last(arrays),
5929          mapped = arrayMap(arrays, toArrayLikeObject);
5930
5931      if (comparator === last(mapped)) {
5932        comparator = undefined;
5933      } else {
5934        mapped.pop();
5935      }
5936      return (mapped.length && mapped[0] === arrays[0])
vendor: 16,384 bytes, lines 5937-6491
5937        ? baseIntersection(mapped, undefined, comparator)
5938        : [];
5939    });
5940
5941    /**
5942     * Converts all elements in `array` into a string separated by `separator`.
5943     *
5944     * @static
5945     * @memberOf _
5946     * @category Array
5947     * @param {Array} array The array to convert.
5948     * @param {string} [separator=','] The element separator.
5949     * @returns {string} Returns the joined string.
5950     * @example
5951     *
5952     * _.join(['a', 'b', 'c'], '~');
5953     * // => 'a~b~c'
5954     */
5955    function join(array, separator) {
5956      return array ? nativeJoin.call(array, separator) : '';
5957    }
5958
5959    /**
5960     * Gets the last element of `array`.
5961     *
5962     * @static
5963     * @memberOf _
5964     * @category Array
5965     * @param {Array} array The array to query.
5966     * @returns {*} Returns the last element of `array`.
5967     * @example
5968     *
5969     * _.last([1, 2, 3]);
5970     * // => 3
5971     */
5972    function last(array) {
5973      var length = array ? array.length : 0;
5974      return length ? array[length - 1] : undefined;
5975    }
5976
5977    /**
5978     * This method is like `_.indexOf` except that it iterates over elements of
5979     * `array` from right to left.
5980     *
5981     * @static
5982     * @memberOf _
5983     * @category Array
5984     * @param {Array} array The array to search.
5985     * @param {*} value The value to search for.
5986     * @param {number} [fromIndex=array.length-1] The index to search from.
5987     * @returns {number} Returns the index of the matched value, else `-1`.
5988     * @example
5989     *
5990     * _.lastIndexOf([1, 2, 1, 2], 2);
5991     * // => 3
5992     *
5993     * // using `fromIndex`
5994     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
5995     * // => 1
5996     */
5997    function lastIndexOf(array, value, fromIndex) {
5998      var length = array ? array.length : 0;
5999      if (!length) {
6000        return -1;
6001      }
6002      var index = length;
6003      if (fromIndex !== undefined) {
6004        index = toInteger(fromIndex);
6005        index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
6006      }
6007      if (value !== value) {
6008        return indexOfNaN(array, index, true);
6009      }
6010      while (index--) {
6011        if (array[index] === value) {
6012          return index;
6013        }
6014      }
6015      return -1;
6016    }
6017
6018    /**
6019     * Removes all provided values from `array` using
6020     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6021     * for equality comparisons.
6022     *
6023     * **Note:** Unlike `_.without`, this method mutates `array`.
6024     *
6025     * @static
6026     * @memberOf _
6027     * @category Array
6028     * @param {Array} array The array to modify.
6029     * @param {...*} [values] The values to remove.
6030     * @returns {Array} Returns `array`.
6031     * @example
6032     *
6033     * var array = [1, 2, 3, 1, 2, 3];
6034     *
6035     * _.pull(array, 2, 3);
6036     * console.log(array);
6037     * // => [1, 1]
6038     */
6039    var pull = rest(pullAll);
6040
6041    /**
6042     * This method is like `_.pull` except that it accepts an array of values to remove.
6043     *
6044     * **Note:** Unlike `_.difference`, this method mutates `array`.
6045     *
6046     * @static
6047     * @memberOf _
6048     * @category Array
6049     * @param {Array} array The array to modify.
6050     * @param {Array} values The values to remove.
6051     * @returns {Array} Returns `array`.
6052     * @example
6053     *
6054     * var array = [1, 2, 3, 1, 2, 3];
6055     *
6056     * _.pullAll(array, [2, 3]);
6057     * console.log(array);
6058     * // => [1, 1]
6059     */
6060    function pullAll(array, values) {
6061      return (array && array.length && values && values.length)
6062        ? basePullAll(array, values)
6063        : array;
6064    }
6065
6066    /**
6067     * This method is like `_.pullAll` except that it accepts `iteratee` which is
6068     * invoked for each element of `array` and `values` to to generate the criterion
6069     * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6070     *
6071     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6072     *
6073     * @static
6074     * @memberOf _
6075     * @category Array
6076     * @param {Array} array The array to modify.
6077     * @param {Array} values The values to remove.
6078     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6079     * @returns {Array} Returns `array`.
6080     * @example
6081     *
6082     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6083     *
6084     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6085     * console.log(array);
6086     * // => [{ 'x': 2 }]
6087     */
6088    function pullAllBy(array, values, iteratee) {
6089      return (array && array.length && values && values.length)
6090        ? basePullAllBy(array, values, getIteratee(iteratee))
6091        : array;
6092    }
6093
6094    /**
6095     * Removes elements from `array` corresponding to `indexes` and returns an
6096     * array of removed elements.
6097     *
6098     * **Note:** Unlike `_.at`, this method mutates `array`.
6099     *
6100     * @static
6101     * @memberOf _
6102     * @category Array
6103     * @param {Array} array The array to modify.
6104     * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6105     *  specified individually or in arrays.
6106     * @returns {Array} Returns the new array of removed elements.
6107     * @example
6108     *
6109     * var array = [5, 10, 15, 20];
6110     * var evens = _.pullAt(array, 1, 3);
6111     *
6112     * console.log(array);
6113     * // => [5, 15]
6114     *
6115     * console.log(evens);
6116     * // => [10, 20]
6117     */
6118    var pullAt = rest(function(array, indexes) {
6119      indexes = arrayMap(baseFlatten(indexes), String);
6120
6121      var result = baseAt(array, indexes);
6122      basePullAt(array, indexes.sort(compareAscending));
6123      return result;
6124    });
6125
6126    /**
6127     * Removes all elements from `array` that `predicate` returns truthy for
6128     * and returns an array of the removed elements. The predicate is invoked with
6129     * three arguments: (value, index, array).
6130     *
6131     * **Note:** Unlike `_.filter`, this method mutates `array`.
6132     *
6133     * @static
6134     * @memberOf _
6135     * @category Array
6136     * @param {Array} array The array to modify.
6137     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6138     * @returns {Array} Returns the new array of removed elements.
6139     * @example
6140     *
6141     * var array = [1, 2, 3, 4];
6142     * var evens = _.remove(array, function(n) {
6143     *   return n % 2 == 0;
6144     * });
6145     *
6146     * console.log(array);
6147     * // => [1, 3]
6148     *
6149     * console.log(evens);
6150     * // => [2, 4]
6151     */
6152    function remove(array, predicate) {
6153      var result = [];
6154      if (!(array && array.length)) {
6155        return result;
6156      }
6157      var index = -1,
6158          indexes = [],
6159          length = array.length;
6160
6161      predicate = getIteratee(predicate, 3);
6162      while (++index < length) {
6163        var value = array[index];
6164        if (predicate(value, index, array)) {
6165          result.push(value);
6166          indexes.push(index);
6167        }
6168      }
6169      basePullAt(array, indexes);
6170      return result;
6171    }
6172
6173    /**
6174     * Reverses `array` so that the first element becomes the last, the second
6175     * element becomes the second to last, and so on.
6176     *
6177     * **Note:** This method mutates `array` and is based on
6178     * [`Array#reverse`](https://mdn.io/Array/reverse).
6179     *
6180     * @static
6181     * @memberOf _
6182     * @category Array
6183     * @returns {Array} Returns `array`.
6184     * @example
6185     *
6186     * var array = [1, 2, 3];
6187     *
6188     * _.reverse(array);
6189     * // => [3, 2, 1]
6190     *
6191     * console.log(array);
6192     * // => [3, 2, 1]
6193     */
6194    function reverse(array) {
6195      return array ? nativeReverse.call(array) : array;
6196    }
6197
6198    /**
6199     * Creates a slice of `array` from `start` up to, but not including, `end`.
6200     *
6201     * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6202     * to ensure dense arrays are returned.
6203     *
6204     * @static
6205     * @memberOf _
6206     * @category Array
6207     * @param {Array} array The array to slice.
6208     * @param {number} [start=0] The start position.
6209     * @param {number} [end=array.length] The end position.
6210     * @returns {Array} Returns the slice of `array`.
6211     */
6212    function slice(array, start, end) {
6213      var length = array ? array.length : 0;
6214      if (!length) {
6215        return [];
6216      }
6217      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6218        start = 0;
6219        end = length;
6220      }
6221      else {
6222        start = start == null ? 0 : toInteger(start);
6223        end = end === undefined ? length : toInteger(end);
6224      }
6225      return baseSlice(array, start, end);
6226    }
6227
6228    /**
6229     * Uses a binary search to determine the lowest index at which `value` should
6230     * be inserted into `array` in order to maintain its sort order.
6231     *
6232     * @static
6233     * @memberOf _
6234     * @category Array
6235     * @param {Array} array The sorted array to inspect.
6236     * @param {*} value The value to evaluate.
6237     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6238     * @example
6239     *
6240     * _.sortedIndex([30, 50], 40);
6241     * // => 1
6242     *
6243     * _.sortedIndex([4, 5], 4);
6244     * // => 0
6245     */
6246    function sortedIndex(array, value) {
6247      return baseSortedIndex(array, value);
6248    }
6249
6250    /**
6251     * This method is like `_.sortedIndex` except that it accepts `iteratee`
6252     * which is invoked for `value` and each element of `array` to compute their
6253     * sort ranking. The iteratee is invoked with one argument: (value).
6254     *
6255     * @static
6256     * @memberOf _
6257     * @category Array
6258     * @param {Array} array The sorted array to inspect.
6259     * @param {*} value The value to evaluate.
6260     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6261     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6262     * @example
6263     *
6264     * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6265     *
6266     * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6267     * // => 1
6268     *
6269     * // using the `_.property` iteratee shorthand
6270     * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6271     * // => 0
6272     */
6273    function sortedIndexBy(array, value, iteratee) {
6274      return baseSortedIndexBy(array, value, getIteratee(iteratee));
6275    }
6276
6277    /**
6278     * This method is like `_.indexOf` except that it performs a binary
6279     * search on a sorted `array`.
6280     *
6281     * @static
6282     * @memberOf _
6283     * @category Array
6284     * @param {Array} array The array to search.
6285     * @param {*} value The value to search for.
6286     * @returns {number} Returns the index of the matched value, else `-1`.
6287     * @example
6288     *
6289     * _.sortedIndexOf([1, 1, 2, 2], 2);
6290     * // => 2
6291     */
6292    function sortedIndexOf(array, value) {
6293      var length = array ? array.length : 0;
6294      if (length) {
6295        var index = baseSortedIndex(array, value);
6296        if (index < length && eq(array[index], value)) {
6297          return index;
6298        }
6299      }
6300      return -1;
6301    }
6302
6303    /**
6304     * This method is like `_.sortedIndex` except that it returns the highest
6305     * index at which `value` should be inserted into `array` in order to
6306     * maintain its sort order.
6307     *
6308     * @static
6309     * @memberOf _
6310     * @category Array
6311     * @param {Array} array The sorted array to inspect.
6312     * @param {*} value The value to evaluate.
6313     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6314     * @example
6315     *
6316     * _.sortedLastIndex([4, 5], 4);
6317     * // => 1
6318     */
6319    function sortedLastIndex(array, value) {
6320      return baseSortedIndex(array, value, true);
6321    }
6322
6323    /**
6324     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6325     * which is invoked for `value` and each element of `array` to compute their
6326     * sort ranking. The iteratee is invoked with one argument: (value).
6327     *
6328     * @static
6329     * @memberOf _
6330     * @category Array
6331     * @param {Array} array The sorted array to inspect.
6332     * @param {*} value The value to evaluate.
6333     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6334     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6335     * @example
6336     *
6337     * // using the `_.property` iteratee shorthand
6338     * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6339     * // => 1
6340     */
6341    function sortedLastIndexBy(array, value, iteratee) {
6342      return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6343    }
6344
6345    /**
6346     * This method is like `_.lastIndexOf` except that it performs a binary
6347     * search on a sorted `array`.
6348     *
6349     * @static
6350     * @memberOf _
6351     * @category Array
6352     * @param {Array} array The array to search.
6353     * @param {*} value The value to search for.
6354     * @returns {number} Returns the index of the matched value, else `-1`.
6355     * @example
6356     *
6357     * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6358     * // => 3
6359     */
6360    function sortedLastIndexOf(array, value) {
6361      var length = array ? array.length : 0;
6362      if (length) {
6363        var index = baseSortedIndex(array, value, true) - 1;
6364        if (eq(array[index], value)) {
6365          return index;
6366        }
6367      }
6368      return -1;
6369    }
6370
6371    /**
6372     * This method is like `_.uniq` except that it's designed and optimized
6373     * for sorted arrays.
6374     *
6375     * @static
6376     * @memberOf _
6377     * @category Array
6378     * @param {Array} array The array to inspect.
6379     * @returns {Array} Returns the new duplicate free array.
6380     * @example
6381     *
6382     * _.sortedUniq([1, 1, 2]);
6383     * // => [1, 2]
6384     */
6385    function sortedUniq(array) {
6386      return (array && array.length)
6387        ? baseSortedUniq(array)
6388        : [];
6389    }
6390
6391    /**
6392     * This method is like `_.uniqBy` except that it's designed and optimized
6393     * for sorted arrays.
6394     *
6395     * @static
6396     * @memberOf _
6397     * @category Array
6398     * @param {Array} array The array to inspect.
6399     * @param {Function} [iteratee] The iteratee invoked per element.
6400     * @returns {Array} Returns the new duplicate free array.
6401     * @example
6402     *
6403     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6404     * // => [1.1, 2.2]
6405     */
6406    function sortedUniqBy(array, iteratee) {
6407      return (array && array.length)
6408        ? baseSortedUniqBy(array, getIteratee(iteratee))
6409        : [];
6410    }
6411
6412    /**
6413     * Gets all but the first element of `array`.
6414     *
6415     * @static
6416     * @memberOf _
6417     * @category Array
6418     * @param {Array} array The array to query.
6419     * @returns {Array} Returns the slice of `array`.
6420     * @example
6421     *
6422     * _.tail([1, 2, 3]);
6423     * // => [2, 3]
6424     */
6425    function tail(array) {
6426      return drop(array, 1);
6427    }
6428
6429    /**
6430     * Creates a slice of `array` with `n` elements taken from the beginning.
6431     *
6432     * @static
6433     * @memberOf _
6434     * @category Array
6435     * @param {Array} array The array to query.
6436     * @param {number} [n=1] The number of elements to take.
6437     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6438     * @returns {Array} Returns the slice of `array`.
6439     * @example
6440     *
6441     * _.take([1, 2, 3]);
6442     * // => [1]
6443     *
6444     * _.take([1, 2, 3], 2);
6445     * // => [1, 2]
6446     *
6447     * _.take([1, 2, 3], 5);
6448     * // => [1, 2, 3]
6449     *
6450     * _.take([1, 2, 3], 0);
6451     * // => []
6452     */
6453    function take(array, n, guard) {
6454      if (!(array && array.length)) {
6455        return [];
6456      }
6457      n = (guard || n === undefined) ? 1 : toInteger(n);
6458      return baseSlice(array, 0, n < 0 ? 0 : n);
6459    }
6460
6461    /**
6462     * Creates a slice of `array` with `n` elements taken from the end.
6463     *
6464     * @static
6465     * @memberOf _
6466     * @category Array
6467     * @param {Array} array The array to query.
6468     * @param {number} [n=1] The number of elements to take.
6469     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6470     * @returns {Array} Returns the slice of `array`.
6471     * @example
6472     *
6473     * _.takeRight([1, 2, 3]);
6474     * // => [3]
6475     *
6476     * _.takeRight([1, 2, 3], 2);
6477     * // => [2, 3]
6478     *
6479     * _.takeRight([1, 2, 3], 5);
6480     * // => [1, 2, 3]
6481     *
6482     * _.takeRight([1, 2, 3], 0);
6483     * // => []
6484     */
6485    function takeRight(array, n, guard) {
6486      var length = array ? array.length : 0;
6487      if (!length) {
6488        return [];
6489      }
6490      n = (guard || n === undefined) ? 1 : toInteger(n);
6491      n = length
6491 - n;
6492      return baseSlice(array, n < 0 ? 0 : n, length);
6493    }
6494
6495    /**
6496     * Creates a slice of `array` with elements taken from the end. Elements are
6497     * taken until `predicate` returns falsey. The predicate is invoked with three
6498     * arguments: (value, index, array).
6499     *
6500     * @static
6501     * @memberOf _
6502     * @category Array
6503     * @param {Array} array The array to query.
6504     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6505     * @returns {Array} Returns the slice of `array`.
6506     * @example
6507     *
6508     * var users = [
6509     *   { 'user': 'barney',  'active': true },
6510     *   { 'user': 'fred',    'active': false },
6511     *   { 'user': 'pebbles', 'active': false }
6512     * ];
6513     *
6514     * _.takeRightWhile(users, function(o) { return !o.active; });
6515     * // => objects for ['fred', 'pebbles']
6516     *
6517     * // using the `_.matches` iteratee shorthand
6518     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6519     * // => objects for ['pebbles']
6520     *
6521     * // using the `_.matchesProperty` iteratee shorthand
6522     * _.takeRightWhile(users, ['active', false]);
6523     * // => objects for ['fred', 'pebbles']
6524     *
6525     * // using the `_.property` iteratee shorthand
6526     * _.takeRightWhile(users, 'active');
6527     * // => []
6528     */
6529    function takeRightWhile(array, predicate) {
6530      return (array && array.length)
6531        ? baseWhile(array, getIteratee(predicate, 3), false, true)
6532        : [];
6533    }
6534
6535    /**
6536     * Creates a slice of `array` with elements taken from the beginning. Elements
6537     * are taken until `predicate` returns falsey. The predicate is invoked with
6538     * three arguments: (value, index, array).
6539     *
6540     * @static
6541     * @memberOf _
6542     * @category Array
6543     * @param {Array} array The array to query.
6544     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6545     * @returns {Array} Returns the slice of `array`.
6546     * @example
6547     *
6548     * var users = [
6549     *   { 'user': 'barney',  'active': false },
6550     *   { 'user': 'fred',    'active': false},
6551     *   { 'user': 'pebbles', 'active': true }
6552     * ];
6553     *
6554     * _.takeWhile(users, function(o) { return !o.active; });
6555     * // => objects for ['barney', 'fred']
6556     *
6557     * // using the `_.matches` iteratee shorthand
6558     * _.takeWhile(users, { 'user': 'barney', 'active': false });
6559     * // => objects for ['barney']
6560     *
6561     * // using the `_.matchesProperty` iteratee shorthand
6562     * _.takeWhile(users, ['active', false]);
6563     * // => objects for ['barney', 'fred']
6564     *
6565     * // using the `_.property` iteratee shorthand
6566     * _.takeWhile(users, 'active');
6567     * // => []
6568     */
6569    function takeWhile(array, predicate) {
6570      return (array && array.length)
6571        ? baseWhile(array, getIteratee(predicate, 3))
6572        : [];
6573    }
6574
6575    /**
6576     * Creates an array of unique values, in order, from all of the provided arrays
6577     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6578     * for equality comparisons.
6579     *
6580     * @static
6581     * @memberOf _
6582     * @category Array
6583     * @param {...Array} [arrays] The arrays to inspect.
6584     * @returns {Array} Returns the new array of combined values.
6585     * @example
6586     *
6587     * _.union([2, 1], [4, 2], [1, 2]);
6588     * // => [2, 1, 4]
6589     */
6590    var union = rest(function(arrays) {
6591      return baseUniq(baseFlatten(arrays, false, true));
6592    });
6593
6594    /**
6595     * This method is like `_.union` except that it accepts `iteratee` which is
6596     * invoked for each element of each `arrays` to generate the criterion by which
6597     * uniqueness is computed. The iteratee is invoked with one argument: (value).
6598     *
6599     * @static
6600     * @memberOf _
6601     * @category Array
6602     * @param {...Array} [arrays] The arrays to inspect.
6603     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6604     * @returns {Array} Returns the new array of combined values.
6605     * @example
6606     *
6607     * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6608     * // => [2.1, 1.2, 4.3]
6609     *
6610     * // using the `_.property` iteratee shorthand
6611     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6612     * // => [{ 'x': 1 }, { 'x': 2 }]
6613     */
6614    var unionBy = rest(function(arrays) {
6615      var iteratee = last(arrays);
6616      if (isArrayLikeObject(iteratee)) {
6617        iteratee = undefined;
6618      }
6619      return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
6620    });
6621
6622    /**
6623     * This method is like `_.union` except that it accepts `comparator` which
6624     * is invoked to compare elements of `arrays`. The comparator is invoked
6625     * with two arguments: (arrVal, othVal).
6626     *
6627     * @static
6628     * @memberOf _
6629     * @category Array
6630     * @param {...Array} [arrays] The arrays to inspect.
6631     * @param {Function} [comparator] The comparator invoked per element.
6632     * @returns {Array} Returns the new array of combined values.
6633     * @example
6634     *
6635     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6636     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6637     *
6638     * _.unionWith(objects, others, _.isEqual);
6639     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6640     */
6641    var unionWith = rest(function(arrays) {
6642      var comparator = last(arrays);
6643      if (isArrayLikeObject(comparator)) {
6644        comparator = undefined;
6645      }
6646      return baseUniq(baseFlatten(arrays, false, true), undefined, c
vendor: 7,640 bytes, lines 6646-6879
6646omparator);
6647    });
6648
6649    /**
6650     * Creates a duplicate-free version of an array, using
6651     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6652     * for equality comparisons, in which only the first occurrence of each element
6653     * is kept.
6654     *
6655     * @static
6656     * @memberOf _
6657     * @category Array
6658     * @param {Array} array The array to inspect.
6659     * @returns {Array} Returns the new duplicate free array.
6660     * @example
6661     *
6662     * _.uniq([2, 1, 2]);
6663     * // => [2, 1]
6664     */
6665    function uniq(array) {
6666      return (array && array.length)
6667        ? baseUniq(array)
6668        : [];
6669    }
6670
6671    /**
6672     * This method is like `_.uniq` except that it accepts `iteratee` which is
6673     * invoked for each element in `array` to generate the criterion by which
6674     * uniqueness is computed. The iteratee is invoked with one argument: (value).
6675     *
6676     * @static
6677     * @memberOf _
6678     * @category Array
6679     * @param {Array} array The array to inspect.
6680     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6681     * @returns {Array} Returns the new duplicate free array.
6682     * @example
6683     *
6684     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6685     * // => [2.1, 1.2]
6686     *
6687     * // using the `_.property` iteratee shorthand
6688     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6689     * // => [{ 'x': 1 }, { 'x': 2 }]
6690     */
6691    function uniqBy(array, iteratee) {
6692      return (array && array.length)
6693        ? baseUniq(array, getIteratee(iteratee))
6694        : [];
6695    }
6696
6697    /**
6698     * This method is like `_.uniq` except that it accepts `comparator` which
6699     * is invoked to compare elements of `array`. The comparator is invoked with
6700     * two arguments: (arrVal, othVal).
6701     *
6702     * @static
6703     * @memberOf _
6704     * @category Array
6705     * @param {Array} array The array to inspect.
6706     * @param {Function} [comparator] The comparator invoked per element.
6707     * @returns {Array} Returns the new duplicate free array.
6708     * @example
6709     *
6710     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6711     *
6712     * _.uniqWith(objects, _.isEqual);
6713     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6714     */
6715    function uniqWith(array, comparator) {
6716      return (array && array.length)
6717        ? baseUniq(array, undefined, comparator)
6718        : [];
6719    }
6720
6721    /**
6722     * This method is like `_.zip` except that it accepts an array of grouped
6723     * elements and creates an array regrouping the elements to their pre-zip
6724     * configuration.
6725     *
6726     * @static
6727     * @memberOf _
6728     * @category Array
6729     * @param {Array} array The array of grouped elements to process.
6730     * @returns {Array} Returns the new array of regrouped elements.
6731     * @example
6732     *
6733     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6734     * // => [['fred', 30, true], ['barney', 40, false]]
6735     *
6736     * _.unzip(zipped);
6737     * // => [['fred', 'barney'], [30, 40], [true, false]]
6738     */
6739    function unzip(array) {
6740      if (!(array && array.length)) {
6741        return [];
6742      }
6743      var length = 0;
6744      array = arrayFilter(array, function(group) {
6745        if (isArrayLikeObject(group)) {
6746          length = nativeMax(group.length, length);
6747          return true;
6748        }
6749      });
6750      return baseTimes(length, function(index) {
6751        return arrayMap(array, baseProperty(index));
6752      });
6753    }
6754
6755    /**
6756     * This method is like `_.unzip` except that it accepts `iteratee` to specify
6757     * how regrouped values should be combined. The iteratee is invoked with the
6758     * elements of each group: (...group).
6759     *
6760     * @static
6761     * @memberOf _
6762     * @category Array
6763     * @param {Array} array The array of grouped elements to process.
6764     * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6765     * @returns {Array} Returns the new array of regrouped elements.
6766     * @example
6767     *
6768     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6769     * // => [[1, 10, 100], [2, 20, 200]]
6770     *
6771     * _.unzipWith(zipped, _.add);
6772     * // => [3, 30, 300]
6773     */
6774    function unzipWith(array, iteratee) {
6775      if (!(array && array.length)) {
6776        return [];
6777      }
6778      var result = unzip(array);
6779      if (iteratee == null) {
6780        return result;
6781      }
6782      return arrayMap(result, function(group) {
6783        return apply(iteratee, undefined, group);
6784      });
6785    }
6786
6787    /**
6788     * Creates an array excluding all provided values using
6789     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6790     * for equality comparisons.
6791     *
6792     * @static
6793     * @memberOf _
6794     * @category Array
6795     * @param {Array} array The array to filter.
6796     * @param {...*} [values] The values to exclude.
6797     * @returns {Array} Returns the new array of filtered values.
6798     * @example
6799     *
6800     * _.without([1, 2, 1, 3], 1, 2);
6801     * // => [3]
6802     */
6803    var without = rest(function(array, values) {
6804      return isArrayLikeObject(array)
6805        ? baseDifference(array, values)
6806        : [];
6807    });
6808
6809    /**
6810     * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
6811     * of the provided arrays.
6812     *
6813     * @static
6814     * @memberOf _
6815     * @category Array
6816     * @param {...Array} [arrays] The arrays to inspect.
6817     * @returns {Array} Returns the new array of values.
6818     * @example
6819     *
6820     * _.xor([2, 1], [4, 2]);
6821     * // => [1, 4]
6822     */
6823    var xor = rest(function(arrays) {
6824      return baseXor(arrayFilter(arrays, isArrayLikeObject));
6825    });
6826
6827    /**
6828     * This method is like `_.xor` except that it accepts `iteratee` which is
6829     * invoked for each element of each `arrays` to generate the criterion by which
6830     * uniqueness is computed. The iteratee is invoked with one argument: (value).
6831     *
6832     * @static
6833     * @memberOf _
6834     * @category Array
6835     * @param {...Array} [arrays] The arrays to inspect.
6836     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6837     * @returns {Array} Returns the new array of values.
6838     * @example
6839     *
6840     * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6841     * // => [1.2, 4.3]
6842     *
6843     * // using the `_.property` iteratee shorthand
6844     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6845     * // => [{ 'x': 2 }]
6846     */
6847    var xorBy = rest(function(arrays) {
6848      var iteratee = last(arrays);
6849      if (isArrayLikeObject(iteratee)) {
6850        iteratee = undefined;
6851      }
6852      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
6853    });
6854
6855    /**
6856     * This method is like `_.xor` except that it accepts `comparator` which is
6857     * invoked to compare elements of `arrays`. The comparator is invoked with
6858     * two arguments: (arrVal, othVal).
6859     *
6860     * @static
6861     * @memberOf _
6862     * @category Array
6863     * @param {...Array} [arrays] The arrays to inspect.
6864     * @param {Function} [comparator] The comparator invoked per element.
6865     * @returns {Array} Returns the new array of values.
6866     * @example
6867     *
6868     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6869     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6870     *
6871     * _.xorWith(objects, others, _.isEqual);
6872     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6873     */
6874    var xorWith = rest(function(arrays) {
6875      var comparator = last(arrays);
6876      if (isArrayLikeObject(comparator)) {
6877        comparator = undefined;
6878      }
6879      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, c
6879omparator);
6880    });
6881
6882    /**
6883     * Creates an array of grouped elements, the first of which contains the first
6884     * elements of the given arrays, the second of which contains the second elements
6885     * of the given arrays, and so on.
6886     *
6887     * @static
6888     * @memberOf _
6889     * @category Array
6890     * @param {...Array} [arrays] The arrays to process.
6891     * @returns {Array} Returns the new array of grouped elements.
6892     * @example
6893     *
6894     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
6895     * // => [['fred', 30, true], ['barney', 40, false]]
6896     */
6897    var zip = rest(unzip);
6898
6899    /**
6900     * This method is like `_.fromPairs` except that it accepts two arrays,
6901     * one of property names and one of corresponding values.
6902     *
6903     * @static
6904     * @memberOf _
6905     * @category Array
6906     * @param {Array} [props=[]] The property names.
6907     * @param {Array} [values=[]] The property values.
6908     * @returns {Object} Returns the new object.
6909     * @example
6910     *
6911     * _.zipObject(['fred', 'barney'], [30, 40]);
6912     * // => { 'fred': 30, 'barney': 40 }
6913     */
6914    function zipObject(props, values) {
6915      var index = -1,
6916          length = props ? props.length : 0,
6917          valsLength = values ? values.length : 0,
6918          result = {};
6919
6920      while (++index < length) {
6921        baseSet(result, props[index], index < valsLength ? values[index] : undefined);
6922      }
6923      return result;
6924    }
6925
6926    /**
6927     * This method is like `_.zip` except that it accepts `iteratee` to specify
6928     * how grouped values should be combined. The iteratee is invoked with the
6929     * elements of each group: (...group).
6930     *
6931     * @static
6932     * @memberOf _
6933     * @category Array
6934     * @param {...Array} [arrays] The arrays to process.
6935     * @param {Function} [iteratee=_.identity] The function to combine grouped values.
6936     * @returns {Array} Returns the new array of grouped elements.
6937     * @example
6938     *
6939     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
6940     *   return a + b + c;
6941     * });
6942     * // => [111, 222]
6943     */
6944    var zipWith = rest(function(arrays) {
6945      var length = arrays.length,
6946          iteratee = length > 1 ? arrays[length - 1] : undefined;
6947
6948      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
6949      return unzipWith(arrays, iteratee);
6950    });
6951
6952    /*------------------------------------------------------------------------*/
6953
6954    /**
6955     * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
6956     * The result of such method chaining must be unwrapped with `_#value`.
6957     *
6958     * @static
6959     * @memberOf _
6960     * @category Seq
6961     * @param {*} value The value to wrap.
6962     * @returns {Object} Returns the new `lodash` wrapper instance.
6963     * @example
6964     *
6965     * var users = [
6966     *   { 'user': 'barney',  'age': 36 },
6967     *   { 'user': 'fred',    'age': 40 },
6968     *   { 'user': 'pebbles', 'age': 1 }
6969     * ];
6970     *
6971     * var youngest = _
6972     *   .chain(users)
6973     *   .sortBy('age')
6974     *   .map(function(o) {
6975     *     return o.user + ' is ' + o.age;
6976     *   })
6977     *   .head()
6978     *   .value();
6979     * // => 'pebbles is 1'
6980     */
6981    function chain(value) {
6982      var result = lodash(value);
6983      result.__chain__ = true;
6984      return result;
6985    }
6986
6987    /**
6988     * This method invokes `interceptor` and returns `value`. The interceptor is
6989     * invoked with one argument; (value). The purpose of this method is to "tap into"
6990     * a method chain in order to perform operations on intermediate results within
6991     * the chain.
6992     *
6993     * @static
6994     * @memberOf _
6995     * @category Seq
6996     * @param {*} value The value to provide to `interceptor`.
6997     * @param {Function} interceptor The function to invoke.
6998     * @returns {*} Returns `value`.
6999     * @example
7000     *
7001     * _([1, 2, 3])
7002     *  .tap(function(array) {
7003     *    array.pop();
7004     *  })
7005     *  .reverse()
7006     *  .value();
7007     * // => [2, 1]
7008     */
7009    function tap(value, interceptor) {
7010      interceptor(value);
7011      return value;
7012    }
7013
7014    /**
7015     * This method is like `_.tap` except that it returns the result of `interceptor`.
7016     *
7017     * @static
7018     * @memberOf _
7019     * @category Seq
7020     * @param {*} value The value to provide to `interceptor`.
7021     * @param {Function} interceptor The function to invoke.
7022     * @returns {*} Returns the result of `interceptor`.
7023     * @example
7024     *
7025     * _('  abc  ')
7026     *  .chain()
7027     *  .trim()
7028     *  .thru(function(value) {
7029     *    return [value];
7030     *  })
7031     *  .value();
7032     * // => ['abc']
7033     */
7034    function thru(value, interceptor) {
7035      return interceptor(value);
7036    }
7037
7038    /**
7039     * This method is the wrapper version of `_.at`.
7040     *
7041     * @name at
7042     * @memberOf _
7043     * @category Seq
7044     * @param {...(string|string[])} [paths] The property paths of elements to pick,
7045     *  specified individually or in arrays.
7046     * @returns {Object} Returns the new `lodash` wrapper instance.
7047     * @example
7048     *
7049     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7050     *
vendor: 5,308 bytes, lines 7051-7255
7051     * _(object).at(['a[0].b.c', 'a[1]']).value();
7052     * // => [3, 4]
7053     *
7054     * _(['a', 'b', 'c']).at(0, 2).value();
7055     * // => ['a', 'c']
7056     */
7057    var wrapperAt = rest(function(paths) {
7058      paths = baseFlatten(paths);
7059      var length = paths.length,
7060          start = length ? paths[0] : 0,
7061          value = this.__wrapped__,
7062          interceptor = function(object) { return baseAt(object, paths); };
7063
7064      if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
7065        return this.thru(interceptor);
7066      }
7067      value = value.slice(start, +start + (length ? 1 : 0));
7068      value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
7069      return new LodashWrapper(value, this.__chain__).thru(function(array) {
7070        if (length && !array.length) {
7071          array.push(undefined);
7072        }
7073        return array;
7074      });
7075    });
7076
7077    /**
7078     * Enables explicit method chaining on the wrapper object.
7079     *
7080     * @name chain
7081     * @memberOf _
7082     * @category Seq
7083     * @returns {Object} Returns the new `lodash` wrapper instance.
7084     * @example
7085     *
7086     * var users = [
7087     *   { 'user': 'barney', 'age': 36 },
7088     *   { 'user': 'fred',   'age': 40 }
7089     * ];
7090     *
7091     * // without explicit chaining
7092     * _(users).head();
7093     * // => { 'user': 'barney', 'age': 36 }
7094     *
7095     * // with explicit chaining
7096     * _(users)
7097     *   .chain()
7098     *   .head()
7099     *   .pick('user')
7100     *   .value();
7101     * // => { 'user': 'barney' }
7102     */
7103    function wrapperChain() {
7104      return chain(this);
7105    }
7106
7107    /**
7108     * Executes the chained sequence and returns the wrapped result.
7109     *
7110     * @name commit
7111     * @memberOf _
7112     * @category Seq
7113     * @returns {Object} Returns the new `lodash` wrapper instance.
7114     * @example
7115     *
7116     * var array = [1, 2];
7117     * var wrapped = _(array).push(3);
7118     *
7119     * console.log(array);
7120     * // => [1, 2]
7121     *
7122     * wrapped = wrapped.commit();
7123     * console.log(array);
7124     * // => [1, 2, 3]
7125     *
7126     * wrapped.last();
7127     * // => 3
7128     *
7129     * console.log(array);
7130     * // => [1, 2, 3]
7131     */
7132    function wrapperCommit() {
7133      return new LodashWrapper(this.value(), this.__chain__);
7134    }
7135
7136    /**
7137     * This method is the wrapper version of `_.flatMap`.
7138     *
7139     * @name flatMap
7140     * @memberOf _
7141     * @category Seq
7142     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7143     * @returns {Object} Returns the new `lodash` wrapper instance.
7144     * @example
7145     *
7146     * function duplicate(n) {
7147     *   return [n, n];
7148     * }
7149     *
7150     * _([1, 2]).flatMap(duplicate).value();
7151     * // => [1, 1, 2, 2]
7152     */
7153    function wrapperFlatMap(iteratee) {
7154      return this.map(iteratee).flatten();
7155    }
7156
7157    /**
7158     * Gets the next value on a wrapped object following the
7159     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7160     *
7161     * @name next
7162     * @memberOf _
7163     * @category Seq
7164     * @returns {Object} Returns the next iterator value.
7165     * @example
7166     *
7167     * var wrapped = _([1, 2]);
7168     *
7169     * wrapped.next();
7170     * // => { 'done': false, 'value': 1 }
7171     *
7172     * wrapped.next();
7173     * // => { 'done': false, 'value': 2 }
7174     *
7175     * wrapped.next();
7176     * // => { 'done': true, 'value': undefined }
7177     */
7178    function wrapperNext() {
7179      if (this.__values__ === undefined) {
7180        this.__values__ = toArray(this.value());
7181      }
7182      var done = this.__index__ >= this.__values__.length,
7183          value = done ? undefined : this.__values__[this.__index__++];
7184
7185      return { 'done': done, 'value': value };
7186    }
7187
7188    /**
7189     * Enables the wrapper to be iterable.
7190     *
7191     * @name Symbol.iterator
7192     * @memberOf _
7193     * @category Seq
7194     * @returns {Object} Returns the wrapper object.
7195     * @example
7196     *
7197     * var wrapped = _([1, 2]);
7198     *
7199     * wrapped[Symbol.iterator]() === wrapped;
7200     * // => true
7201     *
7202     * Array.from(wrapped);
7203     * // => [1, 2]
7204     */
7205    function wrapperToIterator() {
7206      return this;
7207    }
7208
7209    /**
7210     * Creates a clone of the chained sequence planting `value` as the wrapped value.
7211     *
7212     * @name plant
7213     * @memberOf _
7214     * @category Seq
7215     * @param {*} value The value to plant.
7216     * @returns {Object} Returns the new `lodash` wrapper instance.
7217     * @example
7218     *
7219     * function square(n) {
7220     *   return n * n;
7221     * }
7222     *
7223     * var wrapped = _([1, 2]).map(square);
7224     * var other = wrapped.plant([3, 4]);
7225     *
7226     * other.value();
7227     * // => [9, 16]
7228     *
7229     * wrapped.value();
7230     * // => [1, 4]
7231     */
7232    function wrapperPlant(value) {
7233      var result,
7234          parent = this;
7235
7236      while (parent instanceof baseLodash) {
7237        var clone = wrapperClone(parent);
7238        clone.__index__ = 0;
7239        clone.__values__ = undefined;
7240        if (result) {
7241          previous.__wrapped__ = clone;
7242        } else {
7243          result = clone;
7244        }
7245        var previous = clone;
7246        parent = parent.__wrapped__;
7247      }
7248      previous.__wrapped__ = value;
7249      return result;
7250    }
7251
7252    /**
7253     * This method is the wrapper version of `_.reverse`.
7254     *
7255     * **Note:** This method mutates the wrapped array.
7256     *
7257     * @name reverse
7258     * @memberOf _
7259     * @category Seq
7260     * @returns {Object} Returns the new `lodash` wrapper instance.
7261     * @example
7262     *
7263     * var array = [1, 2, 3];
7264     *
7265     * _(array).reverse().value()
7266     * // => [3, 2, 1]
7267     *
7268     * console.log(array);
7269     * // => [3, 2, 1]
7270     */
7271    function wrapperReverse() {
7272      var value = this.__wrapped__;
7273      if (value instanceof LazyWrapper) {
7274        var wrapped = value;
7275        if (this.__actions__.length) {
7276          wrapped = new LazyWrapper(this);
7277        }
7278        wrapped = wrapped.reverse();
7279        wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
7280        return new LodashWrapper(wrapped, this.__chain__);
7281      }
7282      return this.thru(reverse);
7283    }
7284
7285    /**
7286     * Executes the chained sequence to extract the unwrapped value.
7287     *
7288     * @name value
7289     * @memberOf _
7290     * @alias toJSON, valueOf
7291     * @category Seq
7292     * @returns {*} Returns the resolved unwrapped value.
7293     * @example
7294     *
7295     * _([1, 2, 3]).value();
7296     * // => [1, 2, 3]
7297     */
7298    function wrapperValue() {
7299      return baseWrapperValue(this.__wrapped__, this.__actions__);
7300    }
7301
7302    /*------------------------------------------------------------------------*/
7303
7304    /**
7305     * Creates an object composed of keys generated from the results of running
7306     * each element of `collection` through `iteratee`. The corresponding value
7307     * of each key is the number of times the key was returned by `iteratee`.
7308     * The iteratee is invoked with one argument: (value).
7309     *
7310     * @static
7311     * @memberOf _
7312     * @category Collection
7313     * @param {Array|Object} collection The collection to iterate over.
7314     * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7315     * @returns {Object} Returns the composed aggregate object.
7316     * @example
7317     *
7318     * _.countBy([6.1, 4.2, 6.3], Math.floor);
7319     * // => { '4': 1, '6': 2 }
7320     *
7321     * _.countBy(['one', 'two', 'three'], 'length');
7322     * // => { '3': 2, '5': 1 }
7323     */
7324    var countBy = createAggregator(function(result, value, key) {
7325      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7326    });
7327
7328    /**
7329     * Checks if `predicate` returns truthy for **all** elements of `collection`.
7330     * Iteration is stopped once `predicate` returns falsey. The predicate is
7331     * invoked with three arguments: (value, index|key, collection).
7332     *
7333     * @static
7334     * @memberOf _
7335     * @category Collection
7336     * @param {Array|Object} collection The collection to iterate over.
7337     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7338     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7339     * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7340     * @example
7341     *
7342     * _.every([true, 1, null, 'yes'], Boolean);
7343     * // => false
7344     *
7345     * var users = [
7346     *   { 'user': 'barney', 'active': false },
7347     *   { 'user': 'fred',   'active': false }
7348     * ];
7349     *
7350     * // using the `_.matches` iteratee shorthand
7351     * _.every(users, { 'user': 'barney', 'active': false });
7352     * // => false
7353     *
7354     * // using the `_.matchesProperty` iteratee shorthand
7355     * _.every(users, ['active', false]);
7356     * // => true
7357     *
7358     * // using the `_.property` iteratee shorthand
7359     * _.every(users, 'active');
7360     * // => false
7361     */
7362    function every(collection, predicate, guard) {
7363      var func = isArray(collection) ? arrayEvery : baseEvery;
7364      if (guard && isIterateeCall(collection, predicate, guard)) {
7365        predicate = undefined;
7366      }
7367      return func(collection, getIteratee(predicate, 3));
7368    }
7369
7370    /**
7371     * Iterates over elements of `collection`, returning an array of all elements
7372     * `predicate` returns truthy for. The predicate is invoked with three arguments:
7373     * (value, index|key, collection).
7374     *
7375     * @static
7376     * @memberOf _
7377     * @category Collection
7378     * @param {Array|Object} collection The collection to iterate over.
7379     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7380     * @returns {Array} Returns the new filtered array.
7381     * @example
7382     *
7383     * var users = [
7384     *   { 'user': 'barney', 'age': 36, 'active': true },
7385     *   { 'user': 'fred',   'age': 40, 'active': false }
7386     * ];
7387     *
7388     * _.filter(users, function(o) { return !o.active; });
7389     * // => objects for ['fred']
7390     *
7391     * // using the `_.matches` iteratee shorthand
7392     * _.filter(users, { 'age': 36, 'active': true });
7393     * // => objects for ['barney']
7394     *
7395     * // using the `_.matchesProperty` iteratee shorthand
7396     * _.filter(users, ['active', false]);
7397     * // => objects for ['fred']
7398     *
7399     * // using the `_.property` iteratee shorthand
7400     * _.filter(users, 'active');
7401     * // => objects for ['barney']
7402     */
7403    function filter(collection, predicate) {
7404      var func = isArray(collection) ? arrayFilter : baseFilter;
7405      return func(collection, getIteratee(predicate, 3));
7406    }
7407
7408    /**
7409     * Iterates over elements of `collection`, returning the first element
7410     * `predicate` returns truthy for. The predicate is invoked with three arguments:
7411     * (value, index|key, collection).
7412     *
7413     * @static
7414     * @memberOf _
7415     * @category Collection
7416     * @param {Array|Object} collection The collection to search.
7417     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7418     * @returns {*} Returns the matched element, else `undefined`.
7419     * @example
7420     *
7421     * var users = [
7422     *   { 'user': 'barney',  'age': 36, 'active': true },
7423     *   { 'user': 'fred',    'age': 40, 'active': false },
7424     *   { 'user': 'pebbles', 'age': 1,  'active': true }
7425     * ];
7426     *
7427     * _.find(users, function(o) { return o.age < 40; });
7428     * // => object for 'barney'
7429     *
7430     * // using the `_.matches` iteratee shorthand
7431     * _.find(users, { 'age': 1, 'active': true });
7432     * // => object for 'pebbles'
7433     *
7434     * // using the `_.matchesProperty` iteratee shorthand
7435     * _.find(users, ['active', false]);
7436     * // => object for 'fred'
7437     *
7438     * // using the `_.property` iteratee shorthand
7439     * _.find(users, 'active');
7440     * // => object for 'barney'
7441     */
7442    function find(collection, predicate) {
7443      predicate = getIteratee(predicate, 3);
7444      if (isArray(collection)) {
7445        var index = baseFindIndex(collection, predicate);
7446        return index > -1 ? collection[index] : undefined;
7447      }
7448      return baseFind(collection, predicate, baseEach);
7449    }
7450
7451    /**
7452     * This method is like `_.find` except that it iterates over elements of
7453     * `collection` from right to left.
7454     *
7455     * @static
7456     * @memberOf _
7457     * @category Collection
7458     * @param {Array|Object} collection The collection to search.
7459     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7460     * @returns {*} Returns the matched element, else `undefined`.
7461     * @example
7462     *
7463     * _.findLast([1, 2, 3, 4], function(n) {
7464     *   return n % 2 == 1;
7465     * });
7466     * // => 3
7467     */
7468    function findLast(collection, predicate) {
7469      predicate = getIteratee(predicate, 3);
7470      if (isArray(collection)) {
7471        var index = baseFindIndex(collection, predicate, true);
7472        return index > -1 ? collection[index] : undefined;
7473      }
7474      return baseFind(collection, predicate, baseEachRight);
7475    }
7476
7477    /**
7478     * Iterates over elements of `collection` invoking `iteratee` for each element.
7479     * The iteratee is invoked with three arguments: (value, index|key, collection).
7480     * Iteratee functions may exit iteration early by explicitly returning `false`.
7481     *
7482     * **Note:** As with other "Collections" methods, objects with a "length" property
7483     * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7484     * for object iteration.
7485     *
7486     * @static
7487     * @memberOf _
7488     * @alias each
7489     * @category Collection
7490     * @param {Array|Object} collection The collection to iterate over.
7491     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7492     * @returns {Array|Object} Returns `collection`.
7493     * @example
7494     *
7495     * _([1, 2]).forEach(function(value) {
7496     *   console.log(value);
7497     * });
7498     * // => logs `1` then `2`
7499     *
7500     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7501     *   console.log(key);
7502     * });
7503     * // => logs 'a' then 'b' (iteration order is not guaranteed)
7504     */
7505    function forEach(collection, iteratee) {
7506      return (typeof iteratee == 'function' && isArray(collection))
7507        ? arrayEach(collection, iteratee)
7508        : baseEach(collection, toFunction(iteratee));
7509    }
7510
7511    /**
7512     * This method is like `_.forEach` except that it iterates over elements of
7513     * `collection` from right to left.
7514     *
7515     * @static
7516     * @memberOf _
7517     * @alias eachRight
7518     * @category Collection
7519     * @param {Array|Object} collection The collection to iterate over.
7520     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7521     * @returns {Array|Object} Returns `collection`.
7522     * @example
7523     *
7524     * _.forEachRight([1, 2], function(value) {
7525     *   console.log(value);
7526     * });
7527     * // => logs `2` then `1`
7528     */
7529    function forEachRight(collection, iteratee) {
7530      return (typeof iteratee == 'function' && isArray(collection))
7531        ? arrayEachRight(collection, iteratee)
7532        : baseEachRight(collection, toFunction(iteratee));
7533    }
7534
7535    /**
7536     * Creates an object composed of keys generated from the results of running
7537     * each element of `collection` through `iteratee`. The corresponding value
7538     * of each key is an array of elements responsible for generating the key.
7539     * The iteratee is invoked with one argument: (value).
7540     *
7541     * @static
7542     * @memberOf _
7543     * @category Collection
7544     * @param {Array|Object} collection The collection to iterate over.
7545     * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7546     * @returns {Object} Returns the composed aggregate object.
7547     * @example
7548     *
7549     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7550     * // => { '4': [4.2], '6': [6.1, 6.3] }
7551     *
7552     * // using the `_.property` iteratee shorthand
7553     * _.groupBy(['one', 'two', 'three'], 'length');
7554     * // => { '3': ['one', 'two'], '5': ['three'] }
7555     */
7556    var groupBy = createAggregator(function(result, value, key) {
7557      if (hasOwnProperty.call(result, key)) {
7558        result[key].push(value);
7559      } else {
7560        result[key] = [value];
7561      }
7562    });
7563
7564    /**
7565     * Checks if `value` is in `collection`. If `collection` is a string it's checked
7566     * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7567     * is used for equality comparisons. If `fromIndex` is negative, it's used as
7568     * the offset from the end of `collection`.
7569     *
7570     * @static
7571     * @memberOf _
7572     * @category Collection
7573     * @param {Array|Object|string} collection The collection to search.
7574     * @param {*} value The value to search for.
7575     * @param {number} [fromIndex=0] The index to search from.
7576     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7577     * @returns {boolean} Returns `true` if `value` is found, else `false`.
7578     * @example
7579     *
7580     * _.includes([1, 2, 3], 1);
7581     * // => true
7582     *
7583     * _.includes([1, 2, 3], 1, 2);
7584     * // => false
7585     *
7586     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7587     * // => true
7588     *
7589     * _.includes('pebbles', 'eb');
7590     * // => true
7591     */
7592    function includes(collection, value, fromIndex, guard) {
7593      collection = isArrayLike(collection) ? collection : values(collection);
7594      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7595
7596      var length = collection.length;
7597      if (fromIndex < 0) {
7598        fromIndex = nativeMax(length + fromIndex, 0);
7599      }
7600      return isString(collection)
7601        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7602        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7603    }
7604
7605    /**
7606     * Invokes the method at `path` of each element in `collection`, returning
7607     * an array of the results of each invoked method. Any additional arguments
7608     * are provided to each invoked method. If `methodName` is a function it's
7609     * invoked for, and `this` bound to, each element in `collection`.
7610     *
7611     * @static
7612     * @memberOf _
7613     * @category Collection
7614     * @param {Array|Object} collection The collection to iterate over.
7615     * @param {Array|Function|string} path The path of the method to invoke or
7616     *  the function invoked per iteration.
7617     * @param {...*} [args] The arguments to invoke each method with.
7618     * @returns {Array} Returns the array of results.
7619     * @example
7620     *
7621     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7622     * // => [[1, 5, 7], [1, 2, 3]]
7623     *
7624     * _.invokeMap([123, 456], String.prototype.split, '');
7625     * // => [['1', '2', '3'], ['4', '5', '6']]
7626     */
7627    var invokeMap = rest(function(collection, path, args) {
7628      var index = -1,
7629          isFunc = typeof path == 'function',
7630          isProp = isKey(path),
7631          result = isArrayLike(collection) ? Array(collection.length) : [];
7632
7633      baseEach(collection, function(value) {
7634        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7635        result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7636      });
7637      return result;
7638    });
7639
7640    /**
7641     * Creates an object composed of keys generated from the results of running
7642     * each element of `collection` through `iteratee`. The corresponding value
7643     * of each key is the last element responsible for generating the key. The
7644     * iteratee is invoked with one argument: (value).
7645     *
7646     * @static
7647     * @memberOf _
7648     * @category Collection
7649     * @param {Array|Object} collection The collection to iterate over.
7650     * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7651     * @returns {Object} Returns the composed aggregate object.
7652     * @example
7653     *
7654     * var keyData = [
7655     *   { 'dir': 'left', 'code': 97 },
7656     *   { 'dir': 'right', 'code': 100 }
7657     * ];
7658     *
7659     * _.keyBy(keyData, function(o) {
7660     *   return String.fromCharCode(o.code);
7661     * });
7662     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7663     *
7664     * _.keyBy(keyData, 'dir');
7665     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7666     */
7667    var keyBy = createAggregator(function(result, value, key) {
7668      result[key] = value;
7669    });
7670
7671    /**
7672     * Creates an array of values by running each element in `collection` through
7673     * `iteratee`. The iteratee is invoked with three arguments:
7674     * (value, index|key, collection).
7675     *
7676     * Many lodash methods are guarded to work as iteratees for methods like
7677     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7678     *
7679     * The guarded methods are:
7680     * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7681     * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7682     * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7683     * and `words`
7684     *
7685     * @static
7686     * @memberOf _
7687     * @category Collection
7688     * @param {Array|Object} collection The collection to iterate over.
7689     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7690     * @returns {Array} Returns the new mapped array.
7691     * @example
7692     *
7693     * function square(n) {
7694     *   return n * n;
7695     * }
7696     *
7697     * _.map([4, 8], square);
7698     * // => [16, 64]
7699     *
7700     * _.map({ 'a': 4, 'b': 8 }, square);
7701     * // => [16, 64] (iteration order is not guaranteed)
7702     *
7703     * var users = [
7704     *   { 'user': 'barney' },
7705     *   { 'user': 'fred' }
7706     * ];
7707     *
7708     * // using the `_.property` iteratee shorthand
7709     * _.map(users, 'user');
7710     * // => ['barney', 'fred']
7711     */
7712    function map(collection, iteratee) {
7713      var func = isArray(collection) ? arrayMap : baseMap;
7714      return func(collection, getIteratee(iteratee, 3));
7715    }
7716
7717    /**
7718     * This method is like `_.sortBy` except that it allows specifying the sort
7719     * orders of the iteratees to sort by. If `orders` is unspecified, all values
7720     * are sorted in ascending order. Otherwise, specify an order of "desc" for
7721     * descending or "asc" for ascending sort order of corresponding values.
7722     *
7723     * @static
7724     * @memberOf _
7725     * @category Collection
7726     * @param {Array|Object} collection The collection to iterate over.
7727     * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7728     * @param {string[]} [orders] The sort orders of `iteratees`.
7729     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7730     * @returns {Array} Returns the new sorted array.
7731     * @example
7732     *
7733     * var users = [
7734     *   { 'user': 'fred',   'age': 48 },
7735     *   { 'user': 'barney', 'age': 34 },
7736     *   { 'user': 'fred',   'age': 42 },
7737     *   { 'user': 'barney', 'age': 36 }
7738     * ];
7739     *
7740     * // sort by `user` in ascending order and by `age` in descending order
7741     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
7742     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
7743     */
7744    function orderBy(collection, iteratees, orders, guard) {
7745      if (collection == null) {
7746        return [];
7747      }
7748      if (!isArray(iteratees)) {
7749        iteratees = iteratees == null ? [] : [iteratees];
7750      }
7751      orders = guard ? undefined : orders;
7752      if (!isArray(orders)) {
7753        orders = orders == null ? [] : [orders];
7754      }
7755      return baseOrderBy(collection, iteratees, orders);
7756    }
7757
7758    /**
7759     * Creates an array of elements split into two groups, the first of which
7760     * contains elements `predicate` returns truthy for, the second of which
7761     * contains elements `predicate` returns falsey for. The predicate is
7762     * invoked with one argument: (value).
7763     *
7764     * @static
7765     * @memberOf _
7766     * @category Collection
7767     * @param {Array|Object} collection The collection to iterate over.
7768     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7769     * @returns {Array} Returns the array of grouped elements.
7770     * @example
7771     *
7772     * var users = [
7773     *   { 'user': 'barney',  'age': 36, 'active': false },
7774     *   { 'user': 'fred',    'age': 40, 'active': true },
7775     *   { 'user': 'pebbles', 'age': 1,  'active': false }
7776     * ];
7777     *
7778     * _.partition(users, function(o) { return o.active; });
7779     * // => objects for [['fred'], ['barney', 'pebbles']]
7780     *
7781     * // using the `_.matches` iteratee shorthand
7782     * _.partition(users, { 'age': 1, 'active': false });
7783     * // => objects for [['pebbles'], ['barney', 'fred']]
7784     *
7785     * // using the `_.matchesProperty` iteratee shorthand
7786     * _.partition(users, ['active', false]);
7787     * // => objects for [['barney', 'pebbles'], ['fred']]
7788     *
7789     * // using the `_.property` iteratee shorthand
7790     * _.partition(users, 'active');
7791     * // => objects for [['fred'], ['barney', 'pebbles']]
7792     */
7793    var partition = createAggregator(function(result, value, key) {
7794      result[key ? 0 : 1].push(value);
7795    }, function() { return [[], []]; });
7796
7797    /**
7798     * Reduces `collection` to a value which is the accumulated result of running
7799     * each element in `collection` through `iteratee`, where each successive
7800     * invocation is supplied the return value of the previous. If `accumulator`
7801     * is not provided the first element of `collection` is used as the initial
7802     * value. The iteratee is invoked with four arguments:
7803     * (accumulator, value, index|key, collection).
7804     *
7805     * Many lodash methods are guarded to work as iteratees for methods like
7806     * `_.reduce`, `_.reduceRight`, and `_.transform`.
7807     *
7808     * The guarded methods are:
7809     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
7810     * and `sortBy`
7811     *
7812     * @static
7813     * @memberOf _
7814     * @category Collection
7815     * @param {Array|Object} collection The collection to iterate over.
7816     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7817     * @param {*} [accumulator] The initial value.
7818     * @returns {*} Returns the accumulated value.
7819     * @example
7820     *
7821     * _.reduce([1, 2], function(sum, n) {
7822     *   return sum + n;
7823     * });
7824     * // => 3
7825     *
7826     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
7827     *   (result[value] || (result[value] = [])).push(key);
7828     *   return result;
7829     * }, {});
7830     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
7831     */
7832    function reduce(collection, iteratee, accumulator) {
7833      var func = isArray(collection) ? arrayReduce : baseReduce,
7834          initAccum = arguments.length < 3;
7835
7836      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
7837    }
7838
7839    /**
7840     * This method is like `_.reduce` except that it iterates over elements of
7841     * `collection` from right to left.
7842     *
7843     * @static
7844     * @memberOf _
7845     * @category Collection
7846     * @param {Array|Object} collection The collection to iterate over.
7847     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7848     * @param {*} [accumulator] The initial value.
7849     * @returns {*} Returns the accumulated value.
7850     * @example
7851     *
7852     * var array = [[0, 1], [2, 3], [4, 5]];
7853     *
7854     * _.reduceRight(array, function(flattened, other) {
7855     *   return flattened.concat(other);
7856     * }, []);
7857     * // => [4, 5, 2, 3, 0, 1]
7858     */
7859    function reduceRight(collection, iteratee, accumulator) {
7860      var func = isArray(collection) ? arrayReduceRight : baseReduce,
7861          initAccum = arguments.length < 3;
7862
7863      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
7864    }
7865
7866    /**
7867     * The opposite of `_.filter`; this method returns the elements of `collection`
7868     * that `predicate` does **not** return truthy for.
7869     *
7870     * @static
7871     * @memberOf _
7872     * @category Collection
7873     * @param {Array|Object} collection The collection to iterate over.
7874     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7875     * @returns {Array} Returns the new filtered array.
7876     * @example
7877     *
7878     * var users = [
7879     *   { 'user': 'barney', 'age': 36, 'active': false },
7880     *   { 'user': 'fred',   'age': 40, 'active': true }
7881     * ];
7882     *
7883     * _.reject(users, function(o) { return !o.active; });
7884     * // => objects for ['fred']
7885     *
7886     * // using the `_.matches` iteratee shorthand
7887     * _.reject(users, { 'age': 40, 'active': true });
7888     * // => objects for ['barney']
7889     *
7890     * // using the `_.matchesProperty` iteratee shorthand
7891     * _.reject(users, ['active', false]);
7892     * // => objects for ['fred']
7893     *
7894     * // using the `_.property` iteratee shorthand
7895     * _.reject(users, 'active');
7896     * // => objects for ['barney']
7897     */
7898    function reject(collection, predicate) {
7899      var func = isArray(collection) ? arrayFilter : baseFilter;
7900      predicate = getIteratee(predicate, 3);
7901      return func(collection, function(value, index, collection) {
7902        return !predicate(value, index, collection);
7903      });
7904    }
7905
7906    /**
7907     * Gets a random element from `collection`.
7908     *
7909     * @static
7910     * @memberOf _
7911     * @category Collection
7912     * @param {Array|Object} collection The collection to sample.
7913     * @returns {*} Returns the random element.
7914     * @example
7915     *
7916     * _.sample([1, 2, 3, 4]);
7917     * // => 2
7918     */
7919    function sample(collection) {
7920      var array = isArrayLike(collection) ? collection : values(collection),
7921          length = array.length;
7922
7923      return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
7924    }
7925
7926    /**
7927     * Gets `n` random elements at unique keys from `collection` up to the
7928     * size of `collection`.
7929     *
7930     * @static
7931     * @memberOf _
7932     * @category Collection
7933     * @param {Array|Object} collection The collection to sample.
7934     * @param {number} [n=0] The number of elements to sample.
7935     * @returns {Array} Returns the random elements.
7936     * @example
7937     *
7938     * _.sampleSize([1, 2, 3], 2);
7939     * // => [3, 1]
7940     *
7941     * _.sampleSize([1, 2, 3], 4);
7942     * // => [2, 3, 1]
7943     */
7944    function sampleSize(collection, n) {
7945      var index = -1,
7946          result = toArray(collection),
7947          length = result.length,
7948          lastIndex = length - 1;
7949
7950      n = baseClamp(toInteger(n), 0, length);
7951      while (++index < n) {
7952        var rand = baseRandom(index, lastIndex),
7953            value = result[rand];
7954
7955        result[rand] = result[index];
7956        result[index] = value;
7957      }
7958      result.length = n;
7959      return result;
7960    }
7961
7962    /**
7963     * Creates an array of shuffled values, using a version of the
7964     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
7965     *
7966     * @static
7967     * @memberOf _
7968     * @category Collection
7969     * @param {Array|Object} collection The collection to shuffle.
7970     * @returns {Array} Returns the new shuffled array.
7971     * @example
7972     *
7973     * _.shuffle([1, 2, 3, 4]);
7974     * // => [4, 1, 3, 2]
7975     */
7976    function shuffle(collection) {
7977      return sampleSize(collection, MAX_ARRAY_LENGTH);
7978    }
7979
7980    /**
7981     * Gets the size of `collection` by returning its length for array-like
7982     * values or the number of own enumerable properties for objects.
7983     *
7984     * @static
7985     * @memberOf _
7986     * @category Collection
7987     * @param {Array|Object} collection The collection to inspect.
7988     * @returns {number} Returns the collection size.
7989     * @example
7990     *
7991     * _.size([1, 2, 3]);
7992     * // => 3
7993     *
7994     * _.size({ 'a': 1, 'b': 2 });
7995     * // => 2
7996     *
7997     * _.size('pebbles');
7998     * // => 7
7999     */
8000    function size(collection) {
8001      if (collection == null) {
8002        return 0;
8003      }
8004      if (isArrayLike(collection)) {
8005        var result = collection.length;
8006        return (result && isString(collection)) ? stringSize(collection) : result;
8007      }
8008      return keys(collection).length;
8009    }
8010
8011    /**
8012     * Checks if `predicate` returns truthy for **any** element of `collection`.
8013     * Iteration is stopped once `predicate` returns truthy. The predicate is
8014     * invoked with three arguments: (value, index|key, collection).
8015     *
8016     * @static
8017     * @memberOf _
8018     * @category Collection
8019     * @param {Array|Object} collection The collection to iterate over.
8020     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8021     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8022     * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
8023     * @example
8024     *
8025     * _.some([null, 0, 'yes', false], Boolean);
8026     * // => true
8027     *
8028     * var users = [
8029     *   { 'user': 'barney', 'active': true },
8030     *   { 'user': 'fred',   'active': false }
8031     * ];
8032     *
8033     * // using the `_.matches` iteratee shorthand
8034     * _.some(users, { 'user': 'barney', 'active': false });
8035     * // => false
8036     *
8037     * // using the `_.matchesProperty` iteratee shorthand
8038     * _.some(users, ['active', false]);
8039     * // => true
8040     *
8041     * // using the `_.property` iteratee shorthand
8042     * _.some(users, 'active');
8043     * // => true
8044     */
8045    function some(collection, predicate, guard) {
8046      var func = isArray(collection) ? arraySome : baseSome;
8047      if (guard && isIterateeCall(collection, predicate, guard)) {
8048        predicate = undefined;
8049      }
8050      return func(collection, getIteratee(predicate, 3));
8051    }
8052
8053    /**
8054     * Creates an array of elements, sorted in ascending order by the results of
8055     * running each element in a collection through each iteratee. This method
8056     * performs a stable sort, that is, it preserves the original sort order of
8057     * equal elements. The iteratees are invoked with one argument: (value).
8058     *
8059     * @static
8060     * @memberOf _
8061     * @category Collection
8062     * @param {Array|Object} collection The collection to iterate over.
8063     * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8064     *  The iteratees to sort by, specified individually or in arrays.
8065     * @returns {Array} Returns the new sorted array.
8066     * @example
8067     *
8068     * var users = [
8069     *   { 'user': 'fred',   'age': 48 },
8070     *   { 'user': 'barney', 'age': 36 },
8071     *   { 'user': 'fred',   'age': 42 },
8072     *   { 'user': 'barney', 'age': 34 }
8073     * ];
8074     *
8075     * _.sortBy(users, function(o) { return o.user; });
8076     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8077     *
8078     * _.sortBy(users, ['user', 'age']);
8079     * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8080     *
8081     * _.sortBy(users, 'user', function(o) {
8082     *   return Math.floor(o.age / 10);
8083     * });
8084     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8085     */
8086    var sortBy = rest(function(collection, iteratees) {
8087      if (collection == null) {
8088        return [];
8089      }
8090      var length = iteratees.length;
8091      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8092        iteratees = [];
8093      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8094        iteratees.length = 1;
8095      }
8096      return baseOrderBy(collection, baseFlatten(iteratees), []);
8097    });
8098
8099    /*------------------------------------------------------------------------*/
8100
8101    /**
8102     * Gets the timestamp of the number of milliseconds that have elapsed since
8103     * the Unix epoch (1 January 1970 00:00:00 UTC).
8104     *
8105     * @static
8106     * @memberOf _
8107     * @type Function
8108     * @category Date
8109     * @returns {number} Returns the timestamp.
8110     * @example
8111     *
8112     * _.defer(function(stamp) {
8113     *   console.log(_.now() - stamp);
8114     * }, _.now());
8115     * // => logs the number of milliseconds it took for the deferred function to be invoked
8116     */
8117    var now = Date.now;
8118
8119    /*------------------------------------------------------------------------*/
8120
8121    /**
8122     * The opposite of `_.before`; this method creates a function that invokes
8123     * `func` once it's called `n` or more times.
8124     *
8125     * @static
8126     * @memberOf _
8127     * @category Function
8128     * @param {number} n The number of calls before `func` is invoked.
8129     * @param {Function} func The function to restrict.
8130     * @returns {Function} Returns the new restricted function.
8131     * @example
8132     *
8133     * var saves = ['profile', 'settings'];
8134     *
8135     * var done = _.after(saves.length, function() {
8136     *   console.log('done saving!');
8137     * });
8138     *
8139     * _.forEach(saves, function(type) {
8140     *   asyncSave({ 'type': type, 'complete': done });
8141     * });
8142     * // => logs 'done saving!' after the two async saves have completed
8143     */
8144    function after(n, func) {
8145      if (typeof func != 'function') {
8146        throw new TypeError(FUNC_ERROR_TEXT);
8147      }
8148      n = toInteger(n);
8149      return function() {
8150        if (--n < 1) {
8151          return func.apply(this, arguments);
8152        }
8153      };
8154    }
8155
8156    /**
8157     * Creates a function that accepts up to `n` arguments, ignoring any
8158     * additional arguments.
8159     *
8160     * @static
8161     * @memberOf _
8162     * @category Function
8163     * @param {Function} func The function to cap arguments for.
8164     * @param {number} [n=func.length] The arity cap.
8165     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8166     * @returns {Function} Returns the new function.
8167     * @example
8168     *
8169     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8170     * // => [6, 8, 10]
8171     */
8172    function ary(func, n, guard) {
8173      n = guard ? undefined : n;
8174      n = (func && n == null) ? func.length : n;
8175      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8176    }
8177
8178    /**
8179     * Creates a function that invokes `func`, with the `this` binding and arguments
8180     * of the created function, while it's called less than `n` times. Subsequent
8181     * calls to the created function return the result of the last `func` invocation.
8182     *
8183     * @static
8184     * @memberOf _
8185     * @category Function
8186     * @param {number} n The number of calls at which `func` is no longer invoked.
8187     * @param {Function} func The function to restrict.
8188     * @returns {Function} Returns the new restricted function.
8189     * @example
8190     *
8191     * jQuery(element).on('click', _.before(5, addContactToList));
8192     * // => allows adding up to 4 contacts to the list
8193     */
8194    function before(n, func) {
8195      var result;
8196      if (typeof func != 'function') {
8197        throw new TypeError(FUNC_ERROR_TEXT);
8198      }
8199      n = toInteger(n);
8200      return function() {
8201        if (--n > 0) {
8202          result = func.apply(this, arguments);
8203        }
8204        if (n <= 1) {
8205          func = undefined;
8206        }
8207        return result;
8208      };
8209    }
8210
8211    /**
8212     * Creates a function that invokes `func` with the `this` binding of `thisArg`
8213     * and prepends any additional `_.bind` arguments to those provided to the
8214     * bound function.
8215     *
8216     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8217     * may be used as a placeholder for partially applied arguments.
8218     *
8219     * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8220     * property of bound functions.
8221     *
8222     * @static
8223     * @memberOf _
8224     * @category Function
8225     * @param {Function} func The function to bind.
8226     * @param {*} thisArg The `this` binding of `func`.
8227     * @param {...*} [partials] The arguments to be partially applied.
8228     * @returns {Function} Returns the new bound function.
8229     * @example
8230     *
8231     * var greet = function(greeting, punctuation) {
8232     *   return greeting + ' ' + this.user + punctuation;
8233     * };
8234     *
8235     * var object = { 'user': 'fred' };
8236     *
8237     * var bound = _.bind(greet, object, 'hi');
8238     * bound('!');
8239     * // => 'hi fred!'
8240     *
8241     * // using placeholders
8242     * var bound = _.bind(greet, object, _, '!');
8243     * bound('hi');
8244     * // => 'hi fred!'
8245     */
8246    var bind = rest(function(func, thisArg, partials) {
8247      var bitmask = BIND_FLAG;
8248      if (partials.length) {
8249        var holders = replaceHolders(partials, bind.placeholder);
8250        bitmask |= PARTIAL_FLAG;
8251      }
8252      return createWrapper(func, bitmask, thisArg, partials, holders);
8253    });
8254
8255    /**
8256     * Creates a function that invokes the method at `object[key]` and prepends
8257     * any additional `_.bindKey` arguments to those provided to the bound function.
8258     *
8259     * This method differs from `_.bind` by allowing bound functions to reference
8260     * methods that may be redefined or don't yet exist.
8261     * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8262     * for more details.
8263     *
8264     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8265     * builds, may be used as a placeholder for partially applied arguments.
8266     *
8267     * @static
8268     * @memberOf _
8269     * @category Function
8270     * @param {Object} object The object to invoke the method on.
8271     * @param {string} key The key of the method.
8272     * @param {...*} [partials] The arguments to be partially applied.
8273     * @returns {Function} Returns the new bound function.
8274     * @example
8275     *
8276     * var object = {
8277     *   'user': 'fred',
8278     *   'greet': function(greeting, punctuation) {
8279     *     return greeting + ' ' + this.user + punctuation;
8280     *   }
8281     * };
8282     *
8283     * var bound = _.bindKey(object, 'greet', 'hi');
8284     * bound('!');
8285     * // => 'hi fred!'
8286     *
8287     * object.greet = function(greeting, punctuation) {
8288     *   return greeting + 'ya ' + this.user + punctuation;
8289     * };
8290     *
8291     * bound('!');
8292     * // => 'hiya fred!'
8293     *
8294     * // using placeholders
8295     * var bound = _.bindKey(object, 'greet', _, '!');
8296     * bound('hi');
8297     * // => 'hiya fred!'
8298     */
8299    var bindKey = rest(function(object, key, partials) {
8300      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8301      if (partials.length) {
8302        var holders = replaceHolders(partials, bindKey.placeholder);
8303        bitmask |= PARTIAL_FLAG;
8304      }
8305      return createWrapper(key, bitmask, object, partials, holders);
8306    });
8307
8308    /**
8309     * Creates a function that accepts arguments of `func` and either invokes
8310     * `func` returning its result, if at least `arity` number of arguments have
8311     * been provided, or returns a function that accepts the remaining `func`
8312     * arguments, and so on. The arity of `func` may be specified if `func.length`
8313     * is not sufficient.
8314     *
8315     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8316     * may be used as a placeholder for provided arguments.
8317     *
8318     * **Note:** This method doesn't set the "length" property of curried functions.
8319     *
8320     * @static
8321     * @memberOf _
8322     * @category Function
8323     * @param {Function} func The function to curry.
8324     * @param {number} [arity=func.length] The arity of `func`.
8325     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8326     * @returns {Function} Returns the new curried function.
8327     * @example
8328     *
8329     * var abc = function(a, b, c) {
8330     *   return [a, b, c];
8331     * };
8332     *
8333     * var curried = _.curry(abc);
8334     *
8335     * curried(1)(2)(3);
8336     * // => [1, 2, 3]
8337     *
8338     * curried(1, 2)(3);
8339     * // => [1, 2, 3]
8340     *
8341     * curried(1, 2, 3);
8342     * // => [1, 2, 3]
8343     *
8344     * // using placeholders
8345     * curried(1)(_, 3)(2);
8346     * // => [1, 2, 3]
8347     */
8348    function curry(func, arity, guard) {
8349      arity = guard ? undefined : arity;
8350      var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8351      result.placeholder = curry.placeholder;
8352      return result;
8353    }
8354
8355    /**
8356     * This method is like `_.curry` except that arguments are applied to `func`
8357     * in the manner of `_.partialRight` instead of `_.partial`.
8358     *
8359     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8360     * builds, may be used as a placeholder for provided arguments.
8361     *
8362     * **Note:** This method doesn't set the "length" property of curried functions.
8363     *
8364     * @static
8365     * @memberOf _
8366     * @category Function
8367     * @param {Function} func The function to curry.
8368     * @param {number} [arity=func.length] The arity of `func`.
8369     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8370     * @returns {Function} Returns the new curried function.
8371     * @example
8372     *
8373     * var abc = function(a, b, c) {
8374     *   return [a, b, c];
8375     * };
8376     *
8377     * var curried = _.curryRight(abc);
8378     *
8379     * curried(3)(2)(1);
8380     * // => [1, 2, 3]
8381     *
8382     * curried(2, 3)(1);
8383     * // => [1, 2, 3]
8384     *
8385     * curried(1, 2, 3);
8386     * // => [1, 2, 3]
8387     *
8388     * // using placeholders
8389     * curried(3)(1, _)(2);
8390     * // => [1, 2, 3]
8391     */
8392    function curryRight(func, arity, guard) {
8393      arity = guard ? undefined : arity;
8394      var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8395      result.placeholder = curryRight.placeholder;
8396      return result;
8397    }
8398
8399    /**
8400     * Creates a debounced function that delays invoking `func` until after `wait`
8401     * milliseconds have elapsed since the last time the debounced function was
8402     * invoked. The debounced function comes with a `cancel` method to cancel
8403     * delayed `func` invocations and a `flush` method to immediately invoke them.
8404     * Provide an options object to indicate whether `func` should be invoked on
8405     * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8406     * with the last arguments provided to the debounced function. Subsequent calls
8407     * to the debounced function return the result of the last `func` invocation.
8408     *
8409     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8410     * on the trailing edge of the timeout only if the the debounced function is
8411     * invoked more than once during the `wait` timeout.
8412     *
8413     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8414     * for details over the differences between `_.debounce` and `_.throttle`.
8415     *
8416     * @static
8417     * @memberOf _
8418     * @category Function
8419     * @param {Function} func The function to debounce.
8420     * @param {number} [wait=0] The number of milliseconds to delay.
8421     * @param {Object} [options] The options object.
8422     * @param {boolean} [options.leading=false] Specify invoking on the leading
8423     *  edge of the timeout.
8424     * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8425     *  delayed before it's invoked.
8426     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8427     *  edge of the timeout.
8428     * @returns {Function} Returns the new debounced function.
8429     * @example
8430     *
8431     * // avoid costly calculations while the window size is in flux
8432     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8433     *
8434     * // invoke `sendMail` when clicked, debouncing subsequent calls
8435     * jQuery(element).on('click', _.debounce(sendMail, 300, {
8436     *   'leading': true,
8437     *   'trailing': false
8438     * }));
8439     *
8440     * // ensure `batchLog` is invoked once after 1 second of debounced calls
8441     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8442     * var source = new EventSource('/stream');
8443     * jQuery(source).on('message', debounced);
8444     *
8445     * // cancel a trailing debounced invocation
8446     * jQuery(window).on('popstate', debounced.cancel);
8447     */
8448    function debounce(func, wait, options) {
8449      var args,
8450          maxTimeoutId,
8451          result,
8452          stamp,
8453          thisArg,
8454          timeoutId,
8455          trailingCall,
8456          lastCalled = 0,
8457          leading = false,
8458          maxWait = false,
8459          trailing = true;
8460
8461      if (typeof func != 'function') {
8462        throw new TypeError(FUNC_ERROR_TEXT);
8463      }
8464      wait = toNumber(wait) || 0;
8465      if (isObject(options)) {
8466        leading = !!options.leading;
8467        maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8468        trailing = 'trailing' in options ? !!options.trailing : trailing;
8469      }
8470
8471      function cancel() {
8472        if (timeoutId) {
8473          clearTimeout(timeoutId);
8474        }
8475        if (maxTimeoutId) {
8476          clearTimeout(maxTimeoutId);
8477        }
8478        lastCalled = 0;
8479        args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8480      }
8481
8482      function complete(isCalled, id) {
8483        if (id) {
8484          clearTimeout(id);
8485        }
8486        maxTimeoutId = timeoutId = trailingCall = undefined;
8487        if (isCalled) {
8488          lastCalled = now();
8489          result = func.apply(thisArg, args);
8490          if (!timeoutId && !maxTimeoutId) {
8491            args = thisArg = undefined;
8492          }
8493        }
8494      }
8495
8496      function delayed() {
8497        var remaining = wait - (now() - stamp);
8498        if (remaining <= 0 || remaining > wait) {
8499          complete(trailingCall, maxTimeoutId);
8500        } else {
8501          timeoutId = setTimeout(delayed, remaining);
8502        }
8503      }
8504
8505      function flush() {
8506        if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8507          result = func.apply(thisArg, args);
8508        }
8509        cancel();
8510        return result;
8511      }
8512
8513      function maxDelayed() {
8514        complete(trailing, timeoutId);
8515      }
8516
8517      function debounced() {
8518        args = arguments;
8519        stamp = now();
8520        thisArg = this;
8521        trailingCall = trailing && (timeoutId || !leading);
8522
8523        if (maxWait === false) {
8524          var leadingCall = leading && !timeoutId;
8525        } else {
8526          if (!maxTimeoutId && !leading) {
8527            lastCalled = stamp;
8528          }
8529          var remaining = maxWait - (stamp - lastCalled),
8530              isCalled = remaining <= 0 || remaining > maxWait;
8531
8532          if (isCalled) {
8533            if (maxTimeoutId) {
8534              maxTimeoutId = clearTimeout(maxTimeoutId);
8535            }
8536            lastCalled = stamp;
8537            result = func.apply(thisArg, args);
8538          }
8539          else if (!maxTimeoutId) {
8540            maxTimeoutId = setTimeout(maxDelayed, remaining);
8541          }
8542        }
8543        if (isCalled && timeoutId) {
8544          timeoutId = clearTimeout(timeoutId);
8545        }
8546        else if (!timeoutId &
8546& wait !== maxWait) {
8547          timeoutId = setTimeout(delayed, wait);
8548        }
8549        if (leadingCall) {
8550          isCalled = true;
8551          result = func.apply(thisArg, args);
8552        }
8553        if (isCalled && !timeoutId && !maxTimeoutId) {
8554          args = thisArg = undefined;
8555        }
8556        return result;
8557      }
8558      debounced.cancel = cancel;
8559      debounced.flush = flush;
8560      return debounced;
8561    }
8562
8563    /**
8564     * Defers invoking the `func` until the current call stack has cleared. Any
8565     * additional arguments are provided to `func` when it's invoked.
8566     *
8567     * @static
8568     * @memberOf _
8569     * @category Function
8570     * @param {Function} func The function to defer.
8571     * @param {...*} [args] The arguments to invoke `func` with.
8572     * @returns {number} Returns the timer id.
8573     * @example
8574     *
8575     * _.defer(function(text) {
8576     *   console.log(text);
8577     * }, 'deferred');
8578     * // logs 'deferred' after one or more milliseconds
8579     */
8580    var defer = rest(function(func, args) {
8581      return baseDelay(func, 1, args);
8582    });
8583
8584    /**
8585     * Invokes `func` after `wait` milliseconds. Any additional arguments are
8586     * provided to `func` when it's invoked.
8587     *
8588     * @static
8589     * @memberOf _
8590     * @category Function
8591     * @param {Function} func The function to delay.
8592     * @param {number} wait The number of milliseconds to delay invocation.
8593     * @param {...*} [args] The arguments to invoke `func` with.
8594     * @returns {number} Returns the timer id.
8595     * @example
8596     *
8597     * _.delay(function(text) {
8598     *   console.log(text);
8599     * }, 1000, 'later');
8600     * // => logs 'later' after one second
8601     */
vendor: 9,360 bytes, lines 8602-8885
8602    var delay = rest(function(func, wait, args) {
8603      return baseDelay(func, toNumber(wait) || 0, args);
8604    });
8605
8606    /**
8607     * Creates a function that invokes `func` with arguments reversed.
8608     *
8609     * @static
8610     * @memberOf _
8611     * @category Function
8612     * @param {Function} func The function to flip arguments for.
8613     * @returns {Function} Returns the new function.
8614     * @example
8615     *
8616     * var flipped = _.flip(function() {
8617     *   return _.toArray(arguments);
8618     * });
8619     *
8620     * flipped('a', 'b', 'c', 'd');
8621     * // => ['d', 'c', 'b', 'a']
8622     */
8623    function flip(func) {
8624      return createWrapper(func, FLIP_FLAG);
8625    }
8626
8627    /**
8628     * Creates a function that memoizes the result of `func`. If `resolver` is
8629     * provided it determines the cache key for storing the result based on the
8630     * arguments provided to the memoized function. By default, the first argument
8631     * provided to the memoized function is used as the map cache key. The `func`
8632     * is invoked with the `this` binding of the memoized function.
8633     *
8634     * **Note:** The cache is exposed as the `cache` property on the memoized
8635     * function. Its creation may be customized by replacing the `_.memoize.Cache`
8636     * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8637     * method interface of `delete`, `get`, `has`, and `set`.
8638     *
8639     * @static
8640     * @memberOf _
8641     * @category Function
8642     * @param {Function} func The function to have its output memoized.
8643     * @param {Function} [resolver] The function to resolve the cache key.
8644     * @returns {Function} Returns the new memoizing function.
8645     * @example
8646     *
8647     * var object = { 'a': 1, 'b': 2 };
8648     * var other = { 'c': 3, 'd': 4 };
8649     *
8650     * var values = _.memoize(_.values);
8651     * values(object);
8652     * // => [1, 2]
8653     *
8654     * values(other);
8655     * // => [3, 4]
8656     *
8657     * object.a = 2;
8658     * values(object);
8659     * // => [1, 2]
8660     *
8661     * // modifying the result cache
8662     * values.cache.set(object, ['a', 'b']);
8663     * values(object);
8664     * // => ['a', 'b']
8665     *
8666     * // replacing `_.memoize.Cache`
8667     * _.memoize.Cache = WeakMap;
8668     */
8669    function memoize(func, resolver) {
8670      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8671        throw new TypeError(FUNC_ERROR_TEXT);
8672      }
8673      var memoized = function() {
8674        var args = arguments,
8675            key = resolver ? resolver.apply(this, args) : args[0],
8676            cache = memoized.cache;
8677
8678        if (cache.has(key)) {
8679          return cache.get(key);
8680        }
8681        var result = func.apply(this, args);
8682        memoized.cache = cache.set(key, result);
8683        return result;
8684      };
8685      memoized.cache = new memoize.Cache;
8686      return memoized;
8687    }
8688
8689    /**
8690     * Creates a function that negates the result of the predicate `func`. The
8691     * `func` predicate is invoked with the `this` binding and arguments of the
8692     * created function.
8693     *
8694     * @static
8695     * @memberOf _
8696     * @category Function
8697     * @param {Function} predicate The predicate to negate.
8698     * @returns {Function} Returns the new function.
8699     * @example
8700     *
8701     * function isEven(n) {
8702     *   return n % 2 == 0;
8703     * }
8704     *
8705     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8706     * // => [1, 3, 5]
8707     */
8708    function negate(predicate) {
8709      if (typeof predicate != 'function') {
8710        throw new TypeError(FUNC_ERROR_TEXT);
8711      }
8712      return function() {
8713        return !predicate.apply(this, arguments);
8714      };
8715    }
8716
8717    /**
8718     * Creates a function that is restricted to invoking `func` once. Repeat calls
8719     * to the function return the value of the first invocation. The `func` is
8720     * invoked with the `this` binding and arguments of the created function.
8721     *
8722     * @static
8723     * @memberOf _
8724     * @category Function
8725     * @param {Function} func The function to restrict.
8726     * @returns {Function} Returns the new restricted function.
8727     * @example
8728     *
8729     * var initialize = _.once(createApplication);
8730     * initialize();
8731     * initialize();
8732     * // `initialize` invokes `createApplication` once
8733     */
8734    function once(func) {
8735      return before(2, func);
8736    }
8737
8738    /**
8739     * Creates a function that invokes `func` with arguments transformed by
8740     * corresponding `transforms`.
8741     *
8742     * @static
8743     * @memberOf _
8744     * @category Function
8745     * @param {Function} func The function to wrap.
8746     * @param {...(Function|Function[])} [transforms] The functions to transform
8747     * arguments, specified individually or in arrays.
8748     * @returns {Function} Returns the new function.
8749     * @example
8750     *
8751     * function doubled(n) {
8752     *   return n * 2;
8753     * }
8754     *
8755     * function square(n) {
8756     *   return n * n;
8757     * }
8758     *
8759     * var func = _.overArgs(function(x, y) {
8760     *   return [x, y];
8761     * }, square, doubled);
8762     *
8763     * func(9, 3);
8764     * // => [81, 6]
8765     *
8766     * func(10, 5);
8767     * // => [100, 10]
8768     */
8769    var overArgs = rest(function(func, transforms) {
8770      transforms = arrayMap(baseFlatten(transforms), getIteratee());
8771
8772      var funcsLength = transforms.length;
8773      return rest(function(args) {
8774        var index = -1,
8775            length = nativeMin(args.length, funcsLength);
8776
8777        while (++index < length) {
8778          args[index] = transforms[index].call(this, args[index]);
8779        }
8780        return apply(func, this, args);
8781      });
8782    });
8783
8784    /**
8785     * Creates a function that invokes `func` with `partial` arguments prepended
8786     * to those provided to the new function. This method is like `_.bind` except
8787     * it does **not** alter the `this` binding.
8788     *
8789     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
8790     * builds, may be used as a placeholder for partially applied arguments.
8791     *
8792     * **Note:** This method doesn't set the "length" property of partially
8793     * applied functions.
8794     *
8795     * @static
8796     * @memberOf _
8797     * @category Function
8798     * @param {Function} func The function to partially apply arguments to.
8799     * @param {...*} [partials] The arguments to be partially applied.
8800     * @returns {Function} Returns the new partially applied function.
8801     * @example
8802     *
8803     * var greet = function(greeting, name) {
8804     *   return greeting + ' ' + name;
8805     * };
8806     *
8807     * var sayHelloTo = _.partial(greet, 'hello');
8808     * sayHelloTo('fred');
8809     * // => 'hello fred'
8810     *
8811     * // using placeholders
8812     * var greetFred = _.partial(greet, _, 'fred');
8813     * greetFred('hi');
8814     * // => 'hi fred'
8815     */
8816    var partial = rest(function(func, partials) {
8817      var holders = replaceHolders(partials, partial.placeholder);
8818      return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
8819    });
8820
8821    /**
8822     * This method is like `_.partial` except that partially applied arguments
8823     * are appended to those provided to the new function.
8824     *
8825     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
8826     * builds, may be used as a placeholder for partially applied arguments.
8827     *
8828     * **Note:** This method doesn't set the "length" property of partially
8829     * applied functions.
8830     *
8831     * @static
8832     * @memberOf _
8833     * @category Function
8834     * @param {Function} func The function to partially apply arguments to.
8835     * @param {...*} [partials] The arguments to be partially applied.
8836     * @returns {Function} Returns the new partially applied function.
8837     * @example
8838     *
8839     * var greet = function(greeting, name) {
8840     *   return greeting + ' ' + name;
8841     * };
8842     *
8843     * var greetFred = _.partialRight(greet, 'fred');
8844     * greetFred('hi');
8845     * // => 'hi fred'
8846     *
8847     * // using placeholders
8848     * var sayHelloTo = _.partialRight(greet, 'hello', _);
8849     * sayHelloTo('fred');
8850     * // => 'hello fred'
8851     */
8852    var partialRight = rest(function(func, partials) {
8853      var holders = replaceHolders(partials, partialRight.placeholder);
8854      return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
8855    });
8856
8857    /**
8858     * Creates a function that invokes `func` with arguments arranged according
8859     * to the specified indexes where the argument value at the first index is
8860     * provided as the first argument, the argument value at the second index is
8861     * provided as the second argument, and so on.
8862     *
8863     * @static
8864     * @memberOf _
8865     * @category Function
8866     * @param {Function} func The function to rearrange arguments for.
8867     * @param {...(number|number[])} indexes The arranged argument indexes,
8868     *  specified individually or in arrays.
8869     * @returns {Function} Returns the new function.
8870     * @example
8871     *
8872     * var rearged = _.rearg(function(a, b, c) {
8873     *   return [a, b, c];
8874     * }, 2, 0, 1);
8875     *
8876     * rearged('b', 'c', 'a')
8877     * // => ['a', 'b', 'c']
8878     */
8879    var rearg = rest(function(func, indexes) {
8880      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
8881    });
8882
8883    /**
8884     * Creates a function that invokes `func` with the `this` binding of the
8885     * created function and arguments from `start` and beyond provided as an array.
8886     *
8887     * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
8888     *
8889     * @static
8890     * @memberOf _
8891     * @category Function
8892     * @param {Function} func The function to apply a rest parameter to.
8893     * @param {number} [start=func.length-1] The start position of the rest parameter.
8894     * @returns {Function} Returns the new function.
8895     * @example
8896     *
8897     * var say = _.rest(function(what, names) {
8898     *   return what + ' ' + _.initial(names).join(', ') +
8899     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
8900     * });
8901     *
8902     * say('hello', 'fred', 'barney', 'pebbles');
8903     * // => 'hello fred, barney, & pebbles'
8904     */
8905    function rest(func, start) {
8906      if (typeof func != 'function') {
8907        throw new TypeError(FUNC_ERROR_TEXT);
8908      }
8909      start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
8910      return function() {
8911        var args = arguments,
8912            index = -1,
8913            length = nativeMax(args.length - start, 0),
8914            array = Array(length);
8915
8916        while (++index < length) {
8917          array[index] = args[start + index];
8918        }
8919        switch (start) {
8920          case 0: return func.call(this, array);
8921          case 1: return func.call(this, args[0], array);
8922          case 2: return func.call(this, args[0], args[1], array);
8923        }
8924        var otherArgs = Array(start + 1);
8925        index = -1;
8926        while (++index < start) {
8927          otherArgs[index] = args[index];
8928        }
8929        otherArgs[start] = array;
8930        return apply(func, this, otherArgs);
8931      };
8932    }
8933
8934    /**
8935     * Creates a function that invokes `func` with the `this` binding of the created
8936     * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
8937     *
8938     * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
8939     *
8940     * @static
8941     * @memberOf _
8942     * @category Function
8943     * @param {Function} func The function to spread arguments over.
8944     * @returns {Function} Returns the new function.
8945     * @example
8946     *
8947     * var say = _.spread(function(who, what) {
8948     *   return who + ' says ' + what;
8949     * });
8950     *
8951     * say(['fred', 'hello']);
8952     * // => 'fred says hello'
8953     *
8954     * // with a Promise
8955     * var numbers = Promise.all([
8956     *   Promise.resolve(40),
8957     *   Promise.resolve(36)
8958     * ]);
8959     *
8960     * numbers.then(_.spread(function(x, y) {
8961     *   return x + y;
8962     * }));
8963     * // => a Promise of 76
8964     */
8965    function spread(func) {
8966      if (typeof func != 'function') {
8967        throw new TypeError(FUNC_ERROR_TEXT);
8968      }
8969      return function(array) {
8970        return apply(func, this, array);
8971      };
8972    }
8973
8974    /**
8975     * Creates a throttled function that only invokes `func` at most once per
8976     * every `wait` milliseconds. The throttled function comes with a `cancel`
8977     * method to cancel delayed `func` invocations and a `flush` method to
8978     * immediately invoke them. Provide an options object to indicate whether
8979     * `func` should be invoked on the leading and/or trailing edge of the `wait`
8980     * timeout. The `func` is invoked with the last arguments provided to the
8981     * throttled function. Subsequent calls to the throttled function return the
8982     * result of the last `func` invocation.
8983     *
8984     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8985     * on the trailing edge of the timeout only if the the throttled function is
8986     * invoked more than once during the `wait` timeout.
8987     *
8988     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8989     * for details over the differences between `_.throttle` and `_.debounce`.
8990     *
8991     * @static
8992     * @memberOf _
8993     * @category Function
8994     * @param {Function} func The function to throttle.
8995     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
8996     * @param {Object} [options] The options object.
8997     * @param {boolean} [options.leading=true] Specify invoking on the leading
8998     *  edge of the timeout.
8999     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
9000     *  edge of the timeout.
9001     * @returns {Function} Returns the new throttled function.
9002     * @example
9003     *
9004     * // avoid excessively updating the position while scrolling
9005     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
9006     *
9007     * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
9008     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
9009     * jQuery(element).on('click', throttled);
9010     *
9011     * // cancel a trailing throttled invocation
9012     * jQuery(window).on('popstate', throttled.cancel);
9013     */
9014    function throttle(func, wait, options) {
9015      var leading = true,
9016          trailing = true;
9017
9018      if (typeof func != 'function') {
9019        throw new TypeError(FUNC_ERROR_TEXT);
9020      }
9021      if (isObject(options)) {
9022        leading = 'leading' in options ? !!options.leading : leading;
9023        trailing = 'trailing' in options ? !!options.trailing : trailing;
9024      }
9025      return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
9026    }
9027
9028    /**
9029     * Creates a function that accepts up to one argument, ignoring any
9030     * additional arguments.
9031     *
9032     * @static
9033     * @memberOf _
9034     * @category Function
9035     * @param {Function} func The function to cap arguments for.
9036     * @returns {Function} Returns the new function.
9037     * @example
9038     *
9039     * _.map(['6', '8', '10'], _.unary(parseInt));
9040     * // => [6, 8, 10]
9041     */
9042    function unary(func) {
9043      return ary(func, 1);
9044    }
9045
9046    /**
9047     * Creates a function that provides `value` to the wrapper function as its
9048     * first argument. Any additional arguments provided to the function are
9049     * appended to those provided to the wrapper function. The wrapper is invoked
9050     * with the `this` binding of the created function.
9051     *
9052     * @static
9053     * @memberOf _
9054     * @category Function
9055     * @param {*} value The value to wrap.
9056     * @param {Function} wrapper The wrapper function.
9057     * @returns {Function} Returns the new function.
9058     * @example
9059     *
9060     * var p = _.wrap(_.escape, function(func, text) {
9061     *   return '<p>' + func(text) + '</p>';
9062     * });
9063     *
9064     * p('fred, barney, & pebbles');
9065     * // => '<p>fred, barney, &amp; pebbles</p>'
9066     */
9067    function wrap(value, wrapper) {
9068      wrapper = wrapper == null ? identity : wrapper;
9069      return partial(wrapper, value);
9070    }
9071
9072    /*------------------------------------------------------------------------*/
9073
9074    /**
9075     * Creates a shallow clone of `value`.
9076     *
9077     * **Note:** This method is loosely based on the
9078     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9079     * and supports cloning arrays, array buffers, booleans, date objects, maps,
9080     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9081     * arrays. The own enumerable properties of `arguments` objects are cloned
9082     * as plain objects. An empty object is returned for uncloneable values such
9083     * as error objects, functions, DOM nodes, and WeakMaps.
9084     *
9085     * @static
9086     * @memberOf _
9087     * @category Lang
9088     * @param {*} value The value to clone.
9089     * @returns {*} Returns the cloned value.
9090     * @example
9091     *
9092     * var objects = [{ 'a': 1 }, { 'b': 2 }];
9093     *
9094     * var shallow = _.clone(objects);
9095     * console.log(shallow[0] === objects[0]);
9096     * // => true
9097     */
9098    function clone(value) {
9099      return baseClone(value);
9100    }
9101
9102    /**
9103     * This method is like `_.clone` except that it accepts `customizer` which
9104     * is invoked to produce the cloned value. If `customizer` returns `undefined`
9105     * cloning is handled by the method instead. The `customizer` is invoked with
9106     * up to four arguments; (value [, index|key, object, stack]).
9107     *
9108     * @static
9109     * @memberOf _
9110     * @category Lang
9111     * @param {*} value The value to clone.
9112     * @param {Function} [customizer] The function to customize cloning.
9113     * @returns {*} Returns the cloned value.
9114     * @example
9115     *
9116     * function customizer(value) {
9117     *   if (_.isElement(value)) {
9118     *     return value.cloneNode(false);
9119     *   }
9120     * }
9121     *
9122     * var el = _.cloneWith(document.body, customizer);
9123     *
9124     * console.log(el === document.body);
9125     * // => false
9126     * console.log(el.nodeName);
9127     * // => 'BODY'
9128     * console.log(el.childNodes.length);
9129     * // => 0
9130     */
9131    function cloneWith(value, customizer) {
9132      return baseClone(value, false, customizer);
9133    }
9134
9135    /**
9136     * This method is like `_.clone` except that it recursively clones `value`.
9137     *
9138     * @static
9139     * @memberOf _
9140     * @category Lang
9141     * @param {*} value The value to recursively clone.
9142     * @returns {*} Returns the deep cloned value.
9143     * @example
9144     *
9145     * var objects = [{ 'a': 1 }, { 'b': 2 }];
9146     *
9147     * var deep = _.cloneDeep(objects);
9148     * console.log(deep[0] === objects[0]);
9149     * // => false
9150     */
9151    function cloneDeep(value) {
9152      return baseClone(value, true);
9153    }
9154
9155    /**
9156     * This method is like `_.cloneWith` except that it recursively clones `value`.
9157     *
9158     * @static
9159     * @memberOf _
9160     * @category Lang
9161     * @param {*} value The value to recursively clone.
9162     * @param {Function} [customizer] The function to customize cloning.
9163     * @returns {*} Returns the deep cloned value.
9164     * @example
9165     *
9166     * function customizer(value) {
9167     *   if (_.isElement(value)) {
9168     *     return value.cloneNode(true);
9169     *   }
9170     * }
9171     *
9172     * var el = _.cloneDeepWith(document.body, customizer);
9173     *
9174     * console.log(el === document.body);
9175     * // => false
9176     * console.log(el.nodeName);
9177     * // => 'BODY'
9178     * console.log(el.childNodes.length);
9179     * // => 20
9180     */
9181    function cloneDeepWith(value, customizer) {
9182      return baseClone(value, true, customizer);
9183    }
9184
9185    /**
9186     * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9187     * comparison between two values to determine if they are equivalent.
9188     *
9189     * @static
9190     * @memberOf _
9191     * @category Lang
9192     * @param {*} value The value to compare.
9193     * @param {*} other The other value to compare.
9194     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9195     * @example
9196     *
9197     * var object = { 'user': 'fred' };
9198     * var other = { 'user': 'fred' };
9199     *
9200     * _.eq(object, object);
9201     * // => true
9202     *
9203     * _.eq(object, other);
9204     * // => false
9205     *
9206     * _.eq('a', 'a');
9207     * // => true
9208     *
9209     * _.eq('a', Object('a'));
9210     * // => false
9211     *
9212     * _.eq(NaN, NaN);
9213     * // => true
9214     */
9215    function eq(value, other) {
9216      return value === other || (value !== value && other !== other);
9217    }
9218
9219    /**
9220     * Checks if `value` is greater than `other`.
9221     *
9222     * @static
9223     * @memberOf _
9224     * @category Lang
9225     * @param {*} value The value to compare.
9226     * @param {*} other The other value to compare.
9227     * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9228     * @example
9229     *
9230     * _.gt(3, 1);
9231     * // => true
9232     *
9233     * _.gt(3, 3);
9234     * // => false
9235     *
9236     * _.gt(1, 3);
9237     * // => false
9238     */
9239    function gt(value, other) {
9240      return value > other;
9241    }
9242
9243    /**
9244     * Checks if `value` is greater than or equal to `other`.
9245     *
9246     * @static
9247     * @memberOf _
9248     * @category Lang
9249     * @param {*} value The value to compare.
9250     * @param {*} other The other value to compare.
9251     * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9252     * @example
9253     *
9254     * _.gte(3, 1);
9255     * // => true
9256     *
9257     * _.gte(3, 3);
9258     * // => true
9259     *
9260     * _.gte(1, 3);
9261     * // => false
9262     */
9263    function gte(value, other) {
9264      return value >= other;
9265    }
9266
9267    /**
9268     * Checks if `value` is likely an `arguments` object.
9269     *
9270     * @static
9271     * @memberOf _
9272     * @category Lang
9273     * @param {*} value The value to check.
9274     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9275     * @example
9276     *
9277     * _.isArguments(function() { return arguments; }());
9278     * // => true
9279     *
9280     * _.isArguments([1, 2, 3]);
9281     * // => false
9282     */
9283    function isArguments(value) {
9284      // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9285      return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9286        (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9287    }
9288
9289    /**
9290     * Checks if `value` is classified as an `Array` object.
9291     *
9292     * @static
9293     * @memberOf _
9294     * @type Function
9295     * @category Lang
9296     * @param {*} value The value to check.
9297     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9298     * @example
9299     *
9300     * _.isArray([1, 2, 3]);
9301     * // => true
9302     *
9303     * _.isArray(document.body.children);
9304     * // => false
9305     *
9306     * _.isArray('abc');
9307     * // => false
9308     *
9309     * _.isArray(_.noop);
9310     * // => false
9311     */
9312    var isArray = Array.isArray;
9313
9314    /**
9315     * Checks if `value` is array-like. A value is considered array-like if it's
9316     * not a function and has a `value.length` that's an integer greater than or
9317     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9318     *
9319     * @static
9320     * @memberOf _
9321     * @type Function
9322     * @category Lang
9323     * @param {*} value The value to check.
9324     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9325     * @example
9326     *
9327     * _.isArrayLike([1, 2, 3]);
9328     * // => true
9329     *
9330     * _.isArrayLike(document.body.children);
9331     * // => true
9332     *
9333     * _.isArrayLike('abc');
9334     * // => true
9335     *
9336     * _.isArrayLike(_.noop);
9337     * // => false
9338     */
9339    function isArrayLike(value) {
9340      return value != null &&
9341        !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9342    }
9343
9344    /**
9345     * This method is like `_.isArrayLike` except that it also checks if `value`
9346     * is an object.
9347     *
9348     * @static
9349     * @memberOf _
9350     * @type Function
9351     * @category Lang
9352     * @param {*} value The value to check.
9353     * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9354     * @example
9355     *
9356     * _.isArrayLikeObject([1, 2, 3]);
9357     * // => true
9358     *
9359     * _.isArrayLikeObject(document.body.children);
9360     * // => true
9361     *
9362     * _.isArrayLikeObject('abc');
9363     * // => false
9364     *
9365     * _.isArrayLikeObject(_.noop);
9366     * // => false
9367     */
9368    function isArrayLikeObject(value) {
9369      return isObjectLike(value) && isArrayLike(value);
9370    }
9371
9372    /**
9373     * Checks if `value` is classified as a boolean primitive or object.
9374     *
9375     * @static
9376     * @memberOf _
9377     * @category Lang
9378     * @param {*} value The value to check.
9379     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9380     * @example
9381     *
9382     * _.isBoolean(false);
9383     * // => true
9384     *
9385     * _.isBoolean(null);
9386     * // => false
9387     */
9388    function isBoolean(value) {
9389      return value === true || value === false ||
9390        (isObjectLike(value) && objectToString.call(value) == boolTag);
9391    }
9392
9393    /**
9394     * Checks if `value` is classified as a `Date` object.
9395     *
9396     * @static
9397     * @memberOf _
9398     * @category Lang
9399     * @param {*} value The value to check.
9400     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9401     * @example
9402     *
9403     * _.isDate(new Date);
9404     * // => true
9405     *
9406     * _.isDate('Mon April 23 2012');
9407     * // => false
9408     */
9409    function isDate(value) {
9410      return isObjectLike(value) && objectToString.call(value) == dateTag;
9411    }
9412
9413    /**
9414     * Checks if `value` is likely a DOM element.
9415     *
9416     * @static
9417     * @memberOf _
9418     * @category Lang
9419     * @param {*} value The value to check.
9420     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9421     * @example
9422     *
9423     * _.isElement(document.body);
9424     * // => true
9425     *
9426     * _.isElement('<body>');
9427     * // => false
9428     */
9429    function isElement(value) {
9430      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9431    }
9432
9433    /**
9434     * Checks if `value` is empty. A value is considered empty unless it's an
9435     * `arguments` object, array, string, or jQuery-like collection with a length
9436     * greater than `0` or an object with own enumerable properties.
9437     *
9438     * @static
9439     * @memberOf _
9440     * @category Lang
9441     * @param {Array|Object|string} value The value to inspect.
9442     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9443     * @example
9444     *
9445     * _.isEmpty(null);
9446     * // => true
9447     *
9448     * _.isEmpty(true);
9449     * // => true
9450     *
9451     * _.isEmpty(1);
9452     * // => true
9453     *
9454     * _.isEmpty([1, 2, 3]);
9455     * // => false
9456     *
9457     * _.isEmpty({ 'a': 1 });
9458     * // => false
9459     */
9460    function isEmpty(value) {
9461      return (!isObjectLike(value) || isFunction(value.splice))
9462        ? !size(value)
9463        : !keys(value).length;
9464    }
9465
9466    /**
9467     * Performs a deep comparison between two values to determine if they are
9468     * equivalent.
9469     *
9470     * **Note:** This method supports comparing arrays, array buffers, booleans,
9471     * date objects, error objects, maps, numbers, `Object` objects, regexes,
9472     * sets, strings, symbols, and typed arrays. `Object` objects are compared
9473     * by their own, not inherited, enumerable properties. Functions and DOM
9474     * nodes are **not** supported.
9475     *
9476     * @static
9477     * @memberOf _
9478     * @category Lang
9479     * @param {*} value The value to compare.
9480     * @param {*} other The other value to compare.
9481     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9482     * @example
9483     *
9484     * var object = { 'user': 'fred' };
9485     * var other = { 'user': 'fred' };
9486     *
9487     * _.isEqual(object, other);
9488     * // => true
9489     *
9490     * object === other;
9491     * // => false
9492     */
9493    function isEqual(value, other) {
9494      return baseIsEqual(value, other);
9495    }
9496
9497    /**
9498     * This method is like `_.isEqual` except that it accepts `customizer` which is
9499     * invoked to compare values. If `customizer` returns `undefined` comparisons are
9500     * handled by the method instead. The `customizer` is invoked with up to six arguments:
9501     * (objValue, othValue [, index|key, object, other, stack]).
9502     *
9503     * @static
9504     * @memberOf _
9505     * @category Lang
9506     * @param {*} value The value to compare.
9507     * @param {*} other The other value to compare.
9508     * @param {Function} [customizer] The function to customize comparisons.
9509     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9510     * @example
9511     *
9512     * function isGreeting(value) {
9513     *   return /^h(?:i|ello)$/.test(value);
9514     * }
9515     *
9516     * function customizer(objValue, othValue) {
9517     *   if (isGreeting(objValue) && isGreeting(othValue)) {
9518     *     return true;
9519     *   }
9520     * }
9521     *
9522     * var array = ['hello', 'goodbye'];
9523     * var other = ['hi', 'goodbye'];
9524     *
9525     * _.isEqualWith(array, other, customizer);
9526     * // => true
9527     */
9528    function isEqualWith(value, other, customizer) {
9529      customizer = typeof customizer == 'function' ? customizer : undefined;
9530      var result = customizer ? customizer(value, other) : undefined;
9531      return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9532    }
9533
9534    /**
9535     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9536     * `SyntaxError`, `TypeError`, or `URIError` object.
9537     *
9538     * @static
9539     * @memberOf _
9540     * @category Lang
9541     * @param {*} value The value to check.
9542     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9543     * @example
9544     *
9545     * _.isError(new Error);
9546     * // => true
9547     *
9548     * _.isError(Error);
9549     * // => false
9550     */
9551    function isError(value) {
9552      return isObjectLike(value) &&
9553        typeof value.message == 'string' && objectToString.call(value) == errorTag;
9554    }
9555
9556    /**
9557     * Checks if `value` is a finite primitive number.
9558     *
9559     * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9560     *
9561     * @static
9562     * @memberOf _
9563     * @category Lang
9564     * @param {*} value The value to check.
9565     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9566     * @example
9567     *
9568     * _.isFinite(3);
9569     * // => true
9570     *
9571     * _.isFinite(Number.MAX_VALUE);
9572     * // => true
9573     *
9574     * _.isFinite(3.14);
9575     * // => true
9576     *
9577     * _.isFinite(Infinity);
9578     * // => false
9579     */
9580    function isFinite(value) {
9581      return typeof value == 'number' && nativeIsFinite(value);
9582    }
9583
9584    /**
9585     * Checks if `value` is classified as a `Function` object.
9586     *
9587     * @static
9588     * @memberOf _
9589     * @category Lang
9590     * @param {*} value The value to check.
9591     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9592     * @example
9593     *
9594     * _.isFunction(_);
9595     * // => true
9596     *
9597     * _.isFunction(/abc/);
9598     * // => false
9599     */
9600    function isFunction(value) {
vendor: 4,491 bytes, lines 9601-9751
9601      // The use of `Object#toString` avoids issues with the `typeof` operator
9602      // in Safari 8 which returns 'object' for typed array constructors, and
9603      // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9604      var tag = isObject(value) ? objectToString.call(value) : '';
9605      return tag == funcTag || tag == genTag;
9606    }
9607
9608    /**
9609     * Checks if `value` is an integer.
9610     *
9611     * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9612     *
9613     * @static
9614     * @memberOf _
9615     * @category Lang
9616     * @param {*} value The value to check.
9617     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9618     * @example
9619     *
9620     * _.isInteger(3);
9621     * // => true
9622     *
9623     * _.isInteger(Number.MIN_VALUE);
9624     * // => false
9625     *
9626     * _.isInteger(Infinity);
9627     * // => false
9628     *
9629     * _.isInteger('3');
9630     * // => false
9631     */
9632    function isInteger(value) {
9633      return typeof value == 'number' && value == toInteger(value);
9634    }
9635
9636    /**
9637     * Checks if `value` is a valid array-like length.
9638     *
9639     * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
9640     *
9641     * @static
9642     * @memberOf _
9643     * @category Lang
9644     * @param {*} value The value to check.
9645     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
9646     * @example
9647     *
9648     * _.isLength(3);
9649     * // => true
9650     *
9651     * _.isLength(Number.MIN_VALUE);
9652     * // => false
9653     *
9654     * _.isLength(Infinity);
9655     * // => false
9656     *
9657     * _.isLength('3');
9658     * // => false
9659     */
9660    function isLength(value) {
9661      return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
9662    }
9663
9664    /**
9665     * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
9666     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
9667     *
9668     * @static
9669     * @memberOf _
9670     * @category Lang
9671     * @param {*} value The value to check.
9672     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
9673     * @example
9674     *
9675     * _.isObject({});
9676     * // => true
9677     *
9678     * _.isObject([1, 2, 3]);
9679     * // => true
9680     *
9681     * _.isObject(_.noop);
9682     * // => true
9683     *
9684     * _.isObject(null);
9685     * // => false
9686     */
9687    function isObject(value) {
9688      // Avoid a V8 JIT bug in Chrome 19-20.
9689      // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
9690      var type = typeof value;
9691      return !!value && (type == 'object' || type == 'function');
9692    }
9693
9694    /**
9695     * Checks if `value` is object-like. A value is object-like if it's not `null`
9696     * and has a `typeof` result of "object".
9697     *
9698     * @static
9699     * @memberOf _
9700     * @category Lang
9701     * @param {*} value The value to check.
9702     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
9703     * @example
9704     *
9705     * _.isObjectLike({});
9706     * // => true
9707     *
9708     * _.isObjectLike([1, 2, 3]);
9709     * // => true
9710     *
9711     * _.isObjectLike(_.noop);
9712     * // => false
9713     *
9714     * _.isObjectLike(null);
9715     * // => false
9716     */
9717    function isObjectLike(value) {
9718      return !!value && typeof value == 'object';
9719    }
9720
9721    /**
9722     * Performs a deep comparison between `object` and `source` to determine if
9723     * `object` contains equivalent property values.
9724     *
9725     * **Note:** This method supports comparing the same values as `_.isEqual`.
9726     *
9727     * @static
9728     * @memberOf _
9729     * @category Lang
9730     * @param {Object} object The object to inspect.
9731     * @param {Object} source The object of property values to match.
9732     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9733     * @example
9734     *
9735     * var object = { 'user': 'fred', 'age': 40 };
9736     *
9737     * _.isMatch(object, { 'age': 40 });
9738     * // => true
9739     *
9740     * _.isMatch(object, { 'age': 36 });
9741     * // => false
9742     */
9743    function isMatch(object, source) {
9744      return object === source || baseIsMatch(object, source, getMatchData(source));
9745    }
9746
9747    /**
9748     * This method is like `_.isMatch` except that it accepts `customizer` which
9749     * is invoked to compare values. If `customizer` returns `undefined` comparisons
9750     * are handled by the method instead. The `customizer` is invoked with five
9751     * arguments: (objValue, srcValue, index|key, object, source).
9752     *
9753     * @static
9754     * @memberOf _
9755     * @category Lang
9756     * @param {Object} object The object to inspect.
9757     * @param {Object} source The object of property values to match.
9758     * @param {Function} [customizer] The function to customize comparisons.
9759     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9760     * @example
9761     *
9762     * function isGreeting(value) {
9763     *   return /^h(?:i|ello)$/.test(value);
9764     * }
9765     *
9766     * function customizer(objValue, srcValue) {
9767     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
9768     *     return true;
9769     *   }
9770     * }
9771     *
9772     * var object = { 'greeting': 'hello' };
9773     * var source = { 'greeting': 'hi' };
9774     *
9775     * _.isMatchWith(object, source, customizer);
9776     * // => true
9777     */
9778    function isMatchWith(object, source, customizer) {
9779      customizer = typeof customizer == 'function' ? customizer : undefined;
9780      return baseIsMatch(object, source, getMatchData(source), customizer);
9781    }
9782
9783    /**
9784     * Checks if `value` is `NaN`.
9785     *
9786     * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
9787     * which returns `true` for `undefined` and other non-numeric values.
9788     *
9789     * @static
9790     * @memberOf _
9791     * @category Lang
9792     * @param {*} value The value to check.
9793     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
9794     * @example
9795     *
9796     * _.isNaN(NaN);
9797     * // => true
9798     *
9799     * _.isNaN(new Number(NaN));
9800     * // => true
9801     *
9802     * isNaN(undefined);
9803     * // => true
9804     *
9805     * _.isNaN(undefined);
9806     * // => false
9807     */
9808    function isNaN(value) {
9809      // An `NaN` primitive is the only value that is not equal to itself.
9810      // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
9811      return isNumber(value) && value != +value;
9812    }
9813
9814    /**
9815     * Checks if `value` is a native function.
9816     *
9817     * @static
9818     * @memberOf _
9819     * @category Lang
9820     * @param {*} value The value to check.
9821     * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
9822     * @example
9823     *
9824     * _.isNative(Array.prototype.push);
9825     * // => true
9826     *
9827     * _.isNative(_);
9828     * // => false
9829     */
9830    function isNative(value) {
9831      if (value == null) {
9832        return false;
9833      }
9834      if (isFunction(value)) {
9835        return reIsNative.test(funcToString.call(value));
9836      }
9837      return isObjectLike(value) &&
9838        (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
9839    }
9840
9841    /**
9842     * Checks if `value` is `null`.
9843     *
9844     * @static
9845     * @memberOf _
9846     * @category Lang
9847     * @param {*} value The value to check.
9848     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
9849     * @example
9850     *
9851     * _.isNull(null);
9852     * // => true
9853     *
9854     * _.isNull(void 0);
9855     * // => false
9856     */
9857    function isNull(value) {
9858      return value === null;
9859    }
9860
9861    /**
9862     * Checks if `value` is `null` or `undefined`.
9863     *
9864     * @static
9865     * @memberOf _
9866     * @category Lang
9867     * @param {*} value The value to check.
9868     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
9869     * @example
9870     *
9871     * _.isNil(null);
9872     * // => true
9873     *
9874     * _.isNil(void 0);
9875     * // => true
9876     *
9877     * _.isNil(NaN);
9878     * // => false
9879     */
9880    function isNil(value) {
9881      return value == null;
9882    }
9883
9884    /**
9885     * Checks if `value` is classified as a `Number` primitive or object.
9886     *
9887     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
9888     * as numbers, use the `_.isFinite` method.
9889     *
9890     * @static
9891     * @memberOf _
9892     * @category Lang
9893     * @param {*} value The value to check.
9894     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9895     * @example
9896     *
9897     * _.isNumber(3);
9898     * // => true
9899     *
9900     * _.isNumber(Number.MIN_VALUE);
9901     * // => true
9902     *
9903     * _.isNumber(Infinity);
9904     * // => true
9905     *
9906     * _.isNumber('3');
9907     * // => false
9908     */
9909    function isNumber(value) {
9910      return typeof value == 'number' ||
9911        (isObjectLike(value) && objectToString.call(value) == numberTag);
9912    }
9913
9914    /**
9915     * Checks if `value` is a plain object, that is, an object created by the
9916     * `Object` constructor or one with a `[[Prototype]]` of `null`.
9917     *
9918     * @static
9919     * @memberOf _
9920     * @category Lang
9921     * @param {*} value The value to check.
9922     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
9923     * @example
9924     *
9925     * function Foo() {
9926     *   this.a = 1;
9927     * }
9928     *
9929     * _.isPlainObject(new Foo);
9930     * // => false
9931     *
9932     * _.isPlainObject([1, 2, 3]);
9933     * // => false
9934     *
9935     * _.isPlainObject({ 'x': 0, 'y': 0 });
9936     * // => true
9937     *
9938     * _.isPlainObject(Object.create(null));
9939     * // => true
9940     */
9941    function isPlainObject(value) {
9942      if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
9943        return false;
9944      }
9945      var proto = objectProto;
9946      if (typeof value.constructor == 'function') {
9947        proto = getPrototypeOf(value);
9948      }
9949      if (proto === null) {
9950        return true;
9951      }
9952      var Ctor = proto.constructor;
9953      return (typeof Ctor == 'function' &&
9954        Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
9955    }
9956
9957    /**
9958     * Checks if `value` is classified as a `RegExp` object.
9959     *
9960     * @static
9961     * @memberOf _
9962     * @category Lang
9963     * @param {*} value The value to check.
9964     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9965     * @example
9966     *
9967     * _.isRegExp(/abc/);
9968     * // => true
9969     *
9970     * _.isRegExp('/abc/');
9971     * // => false
9972     */
9973    function isRegExp(value) {
9974      return isObject(value) && objectToString.call(value) == regexpTag;
9975    }
9976
9977    /**
9978     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
9979     * double precision number which isn't the result of a rounded unsafe integer.
9980     *
9981     * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
9982     *
9983     * @static
9984     * @memberOf _
9985     * @category Lang
9986     * @param {*} value The value to check.
9987     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
9988     * @example
9989     *
9990     * _.isSafeInteger(3);
9991     * // => true
9992     *
9993     * _.isSafeInteger(Number.MIN_VALUE);
9994     * // => false
9995     *
9996     * _.isSafeInteger(Infinity);
9997     * // => false
9998     *
9999     * _.isSafeInteger('3');
10000     * // => false
10001     */
10002    function isSafeInteger(value) {
10003      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10004    }
10005
10006    /**
10007     * Checks if `value` is classified as a `String` primitive or object.
10008     *
10009     * @static
10010     * @memberOf _
10011     * @category Lang
10012     * @param {*} value The value to check.
10013     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10014     * @example
10015     *
10016     * _.isString('abc');
10017     * // => true
10018     *
10019     * _.isString(1);
10020     * // => false
10021     */
10022    function isString(value) {
10023      return typeof value == 'string' ||
10024        (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
10025    }
10026
10027    /**
10028     * Checks if `value` is classified as a `Symbol` primitive or object.
10029     *
10030     * @static
10031     * @memberOf _
10032     * @category Lang
10033     * @param {*} value The value to check.
10034     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10035     * @example
10036     *
10037     * _.isSymbol(Symbol.iterator);
10038     * // => true
10039     *
10040     * _.isSymbol('abc');
10041     * // => false
10042     */
10043    function isSymbol(value) {
10044      return typeof value == 'symbol' ||
10045        (isObjectLike(value) && objectToString.call(value) == symbolTag);
10046    }
10047
10048    /**
10049     * Checks if `value` is classified as a typed array.
10050     *
10051     * @static
10052     * @memberOf _
10053     * @category Lang
10054     * @param {*} value The value to check.
10055     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10056     * @example
10057     *
10058     * _.isTypedArray(new Uint8Array);
10059     * // => true
10060     *
10061     * _.isTypedArray([]);
10062     * // => false
10063     */
10064    function isTypedArray(value) {
10065      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10066    }
10067
10068    /**
10069     * Checks if `value` is `undefined`.
10070     *
10071     * @static
10072     * @memberOf _
10073     * @category Lang
10074     * @param {*} value The value to check.
10075     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10076     * @example
10077     *
10078     * _.isUndefined(void 0);
10079     * // => true
10080     *
10081     * _.isUndefined(null);
10082     * // => false
10083     */
10084    function isUndefined(value) {
10085      return value === undefined;
10086    }
10087
10088    /**
10089     * Checks if `value` is less than `other`.
10090     *
10091     * @static
10092     * @memberOf _
10093     * @category Lang
10094     * @param {*} value The value to compare.
10095     * @param {*} other The other value to compare.
10096     * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10097     * @example
10098     *
10099     * _.lt(1, 3);
10100     * // => true
10101     *
10102     * _.lt(3, 3);
10103     * // => false
10104     *
10105     * _.lt(3, 1);
10106     * // => false
10107     */
10108    function lt(value, other) {
10109      return value < other;
10110    }
10111
10112    /**
10113     * Checks if `value` is less than or equal to `other`.
10114     *
10115     * @static
10116     * @memberOf _
10117     * @category Lang
10118     * @param {*} value The value to compare.
10119     * @param {*} other The other value to compare.
10120     * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10121     * @example
10122     *
10123     * _.lte(1, 3);
10124     * // => true
10125     *
10126     * _.lte(3, 3);
10127     * // => true
10128     *
10129     * _.lte(3, 1);
10130     * // => false
10131     */
10132    function lte(value, other) {
10133      return value <= other;
10134    }
10135
10136    /**
10137     * Converts `value` to an array.
10138     *
10139     * @static
10140     * @memberOf _
10141     * @category Lang
10142     * @param {*} value The value to convert.
10143     * @returns {Array} Returns the converted array.
10144     * @example
10145     *
10146     * _.toArray({ 'a': 1, 'b': 2 });
10147     * // => [1, 2]
10148     *
10149     * _.toArray('abc');
10150     * // => ['a', 'b', 'c']
10151     *
10152     * _.toArray(1);
10153     * // => []
10154     *
10155     * _.toArray(null);
10156     * // => []
10157     */
10158    function toArray(value) {
10159      if (!value) {
10160        return [];
10161      }
10162      if (isArrayLike(value)) {
10163        return isString(value) ? stringToArray(value) : copyArray(value);
10164      }
10165      if (iteratorSymbol && value[iteratorSymbol]) {
10166        return iteratorToArray(value[iteratorSymbol]());
10167      }
10168      var tag = getTag(value),
10169          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10170
10171      return func(value);
10172    }
10173
10174    /**
10175     * Converts `value` to an integer.
10176     *
10177     * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10178     *
10179     * @static
10180     * @memberOf _
10181     * @category Lang
10182     * @param {*} value The value to convert.
10183     * @returns {number} Returns the converted integer.
10184     * @example
10185     *
10186     * _.toInteger(3);
10187     * // => 3
10188     *
10189     * _.toInteger(Number.MIN_VALUE);
10190     * // => 0
10191     *
10192     * _.toInteger(Infinity);
10193     * // => 1.7976931348623157e+308
10194     *
10195     * _.toInteger('3');
10196     * // => 3
10197     */
10198    function toInteger(value) {
10199      if (!value) {
10200        return value === 0 ? value : 0;
10201      }
10202      value = toNumber(value);
10203      if (value === INFINITY || value === -INFINITY) {
10204        var sign = (value < 0 ? -1 : 1);
10205        return sign * MAX_INTEGER;
10206      }
10207      var remainder = value % 1;
10208      return value === value ? (remainder ? value - remainder : value) : 0;
10209    }
10210
10211    /**
10212     * Converts `value` to an integer suitable for use as the length of an
10213     * array-like object.
10214     *
10215     * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10216     *
10217     * @static
10218     * @memberOf _
10219     * @category Lang
10220     * @param {*} value The value to convert.
10221     * @returns {number} Returns the converted integer.
10222     * @example
10223     *
10224     * _.toLength(3);
10225     * // => 3
10226     *
10227     * _.toLength(Number.MIN_VALUE);
10228     * // => 0
10229     *
10230     * _.toLength(Infinity);
10231     * // => 4294967295
10232     *
10233     * _.toLength('3');
10234     * // => 3
10235     */
10236    function toLength(value) {
10237      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10238    }
10239
10240    /**
10241     * Converts `value` to a number.
10242     *
10243     * @static
10244     * @memberOf _
10245     * @category Lang
10246     * @param {*} value The value to process.
10247     * @returns {number} Returns the number.
10248     * @example
10249     *
10250     * _.toNumber(3);
10251     * // => 3
10252     *
10253     * _.toNumber(Number.MIN_VALUE);
10254     * // => 5e-324
10255     *
10256     * _.toNumber(Infinity);
10257     * // => Infinity
10258     *
10259     * _.toNumber('3');
10260     * // => 3
10261     */
10262    function toNumber(value) {
10263      if (isObject(value)) {
10264        var other = isFunction(value.valueOf) ? value.valueOf() : value;
10265        value = isObject(other) ? (other + '') : other;
10266      }
10267      if (typeof value != 'string') {
10268        return value === 0 ? value : +value;
10269      }
10270      value = value.replace(reTrim, '');
10271      var isBinary = reIsBinary.test(value);
10272      return (isBinary || reIsOctal.test(value))
10273        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10274        : (reIsBadHex.test(value) ? NAN : +value);
10275    }
10276
10277    /**
10278     * Converts `value` to a plain object flattening inherited enumerable
10279     * properties of `value` to own properties of the plain object.
10280     *
10281     * @static
10282     * @memberOf _
10283     * @category Lang
10284     * @param {*} value The value to convert.
10285     * @returns {Object} Returns the converted plain object.
10286     * @example
10287     *
10288     * function Foo() {
10289     *   this.b = 2;
10290     * }
10291     *
10292     * Foo.prototype.c = 3;
10293     *
10294     * _.assign({ 'a': 1 }, new Foo);
10295     * // => { 'a': 1, 'b': 2 }
10296     *
10297     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10298     * // => { 'a': 1, 'b': 2, 'c': 3 }
10299     */
10300    function toPlainObject(value) {
10301      return copyObject(value, keysIn(value));
10302    }
10303
10304    /**
10305     * Converts `value` to a safe integer. A safe integer can be compared and
10306     * represented correctly.
10307     *
10308     * @static
10309     * @memberOf _
10310     * @category Lang
10311     * @param {*} value The value to convert.
10312     * @returns {number} Returns the converted integer.
10313     * @example
10314     *
10315     * _.toSafeInteger(3);
10316     * // => 3
10317     *
10318     * _.toSafeInteger(Number.MIN_VALUE);
10319     * // => 0
10320     *
10321     * _.toSafeInteger(Infinity);
10322     * // => 9007199254740991
10323     *
10324     * _.toSafeInteger('3');
10325     * // => 3
10326     */
10327    function toSafeInteger(value) {
10328      return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10329    }
10330
10331    /**
10332     * Converts `value` to a string if it's not one. An empty string is returned
10333     * for `null` and `undefined` values. The sign of `-0` is preserved.
10334     *
10335     * @static
10336     * @memberOf _
10337     * @category Lang
10338     * @param {*} value The value to process.
10339     * @returns {string} Returns the string.
10340     * @example
10341     *
10342     * _.toString(null);
10343     * // => ''
10344     *
10345     * _.toString(-0);
10346     * // => '-0'
10347     *
10348     * _.toString([1, 2, 3]);
10349     * // => '1,2,3'
10350     */
10351    function toString(value) {
10352      // Exit early for strings to avoid a performance hit in some environments.
10353      if (typeof value == 'string') {
10354        return value;
10355      }
10356      if (value == null) {
10357        return '';
10358      }
10359      if (isSymbol(value)) {
10360        return Symbol ? symbolToString.call(value) : '';
10361      }
10362      var result = (value + '');
10363      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10364    }
10365
10366    /*------------------------------------------------------------------------*/
10367
10368    /**
10369     * Assigns own enumerable properties of source objects to the destination
10370     * object. Source objects are applied from left to right. Subsequent sources
10371     * overwrite property assignments of previous sources.
10372     *
10373     * **Note:** This method mutates `object` and is loosely based on
10374     * [`Object.assign`](https://mdn.io/Object/assign).
10375     *
10376     * @static
10377     * @memberOf _
10378     * @category Object
10379     * @param {Object} object The destination object.
10380     * @param {...Object} [sources] The source objects.
10381     * @returns {Object} Returns `object`.
10382     * @example
10383     *
10384     * function Foo() {
10385     *   this.c = 3;
10386     * }
10387     *
10388     * function Bar() {
10389     *   this.e = 5;
10390     * }
10391     *
10392     * Foo.prototype.d = 4;
10393     * Bar.prototype.f = 6;
10394     *
10395     * _.assign({ 'a': 1 }, new Foo, new Bar);
10396     * // => { 'a': 1, 'c': 3, 'e': 5 }
10397     */
10398    var assign = createAssigner(function(object, source) {
10399      copyObject(source, keys(source), object);
10400    });
10401
10402    /**
10403     * This method is like `_.assign` except that it iterates over own and
10404     * inherited source properties.
10405     *
10406     * **Note:** This method mutates `object`.
10407     *
10408     * @static
10409     * @memberOf _
10410     * @alias extend
10411     * @category Object
10412     * @param {Object} object The destination object.
10413     * @param {...Object} [sources] The source objects.
10414     * @returns {Object} Returns `object`.
10415     * @example
10416     *
10417     * function Foo() {
10418     *   this.b = 2;
10419     * }
10420     *
10421     * function Bar() {
10422     *   this.d = 4;
10423     * }
10424     *
10425     * Foo.prototype.c = 3;
10426     * Bar.prototype.e = 5;
10427     *
10428     * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10429     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10430     */
10431    var assignIn = createAssigner(function(object, source) {
10432      copyObject(source, keysIn(source), object);
10433    });
10434
10435    /**
10436     * This method is like `_.assignIn` except that it accepts `customizer` which
10437     * is invoked to produce the assigned values. If `customizer` returns `undefined`
10438     * assignment is handled by the method instead. The `customizer` is invoked
10439     * with five arguments: (objValue, srcValue, key, object, source).
10440     *
10441     * **Note:** This method mutates `object`.
10442     *
10443     * @static
10444     * @memberOf _
10445     * @alias extendWith
10446     * @category Object
10447     * @param {Object} object The destination object.
10448     * @param {...Object} sources The source objects.
10449     * @param {Function} [customizer] The function to customize assigned values.
10450     * @returns {Object} Returns `object`.
10451     * @example
10452     *
10453     * function customizer(objValue, srcValue) {
10454     *   return _.isUndefined(objValue) ? srcValue : objValue;
10455     * }
10456     *
10457     * var defaults = _.partialRight(_.assignInWith, customizer);
10458     *
10459     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10460     * // => { 'a': 1, 'b': 2 }
10461     */
10462    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
10463      copyObjectWith(source, keysIn(source), object, customizer);
10464    });
10465
10466    /**
10467     * This method is like `_.assign` except that it accepts `customizer` which
10468     * is invoked to produce the assigned values. If `customizer` returns `undefined`
10469     * assignment is handled by the method instead. The `customizer` is invoked
10470     * with five arguments: (objValue, srcValue, key, object, source).
10471     *
10472     * **Note:** This method mutates `object`.
10473     *
10474     * @static
10475     * @memberOf _
10476     * @category Object
10477     * @param {Object} object The destination object.
10478     * @param {...Object} sources The source objects.
10479     * @param {Function} [customizer] The function to customize assigned values.
10480     * @returns {Object} Returns `object`.
10481     * @example
10482     *
10483     * function customizer(objValue, srcValue) {
10484     *   return _.isUndefined(objValue) ? srcValue : objValue;
10485     * }
10486     *
10487     * var defaults = _.partialRight(_.assignWith, customizer);
10488     *
10489     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10490     * // => { 'a': 1, 'b': 2 }
10491     */
10492    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
10493      copyObjectWith(source, keys(source), object, customizer);
10494    });
10495
10496    /**
10497     * Creates an array of values corresponding to `paths` of `object`.
10498     *
10499     * @static
10500     * @memberOf _
10501     * @category Object
10502     * @param {Object} object The object to iterate over.
10503     * @param {...(string|string[])} [paths] The property paths of elements to pick,
10504     *  specified individually or in arrays.
10505     * @returns {Array} Returns the new array of picked elements.
10506     * @example
10507     *
10508     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10509     *
10510     * _.at(object, ['a[0].b.c', 'a[1]']);
10511     * // => [3, 4]
10512     *
10513     * _.at(['a', 'b', 'c'], 0, 2);
10514     * // => ['a', 'c']
10515     */
10516    var at = rest(function(object, paths) {
10517      return baseAt(object, baseFlatten(paths));
10518    });
10519
10520    /**
10521     * Creates an object that inherits from the `prototype` object. If a `properties`
10522     * object is provided its own enumerable properties are assigned to the created object.
10523     *
10524     * @static
10525     * @memberOf _
10526     * @category Object
10527     * @param {Object} prototype The object to inherit from.
10528     * @param {Object} [properties] The properties to assign to the object.
10529     * @returns {Object} Returns the new object.
10530     * @example
10531     *
10532     * function Shape() {
10533     *   this.x = 0;
10534     *   this.y = 0;
10535     * }
10536     *
10537     * function Circle() {
10538     *   Shape.call(this);
10539     * }
10540     *
10541     * Circle.prototype = _.create(Shape.prototype, {
10542     *   'constructor': Circle
10543     * });
10544     *
10545     * var circle = new Circle;
10546     * circle instanceof Circle;
10547     * // => true
10548     *
10549     * circle instanceof Shape;
10550     * // => true
10551     */
10552    function create(prototype, properties) {
10553      var result = baseCreate(prototype);
10554      return properties ? baseAssign(result, properties) : result;
10555    }
10556
10557    /**
10558     * Assigns own and inherited enumerable properties of source objects to the
10559     * destination object for all destination properties that resolve to `undefined`.
10560     * Source objects are applied from left to right. Once a property is set,
10561     * additional values of the same property are ignored.
10562     *
10563     * **Note:** This method mutates `object`.
10564     *
10565     * @static
10566     * @memberOf _
10567     * @category Object
10568     * @param {Object} object The destination object.
10569     * @param {...Object} [sources] The source objects.
10570     * @returns {Object} Returns `object`.
10571     * @example
10572     *
10573     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
10574     * // => { 'user': 'barney', 'age': 36 }
10575     */
10576    var defaults = rest(function(args) {
10577      args.push(undefined, assignInDefaults);
10578      return apply(assignInWith, undefined, args);
10579    });
10580
10581    /**
10582     * This method is like `_.defaults` except that it recursively assigns
10583     * default properties.
10584     *
10585     * **Note:** This method mutates `object`.
10586     *
10587     * @static
10588     * @memberOf _
10589     * @category Object
10590     * @param {Object} object The destination object.
10591     * @param {...Object} [sources] The source objects.
10592     * @returns {Object} Returns `object`.
10593     * @example
10594     *
10595     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
10596     * // => { 'user': { 'name': 'barney', 'age': 36 } }
10597     *
10598     */
10599    var defaultsDeep = rest(function(args) {
10600      args.push(undefined, mergeDefaults);
10601      return apply(mergeWith, undefined, args);
10602    });
10603
10604    /**
10605     * This method is like `_.find` except that it returns the key of the first
10606     * element `predicate` returns truthy for instead of the element itself.
10607     *
10608     * @static
10609     * @memberOf _
10610     * @category Object
10611     * @param {Object} object The object to search.
10612     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10613     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10614     * @example
10615     *
10616     * var users = {
10617     *   'barney':  { 'age': 36, 'active': true },
10618     *   'fred':    { 'age': 40, 'active': false },
10619     *   'pebbles': { 'age': 1,  'active': true }
10620     * };
10621     *
10622     * _.findKey(users, function(o) { return o.age < 40; });
10623     * // => 'barney' (iteration order is not guaranteed)
10624     *
10625     * // using the `_.matches` iteratee shorthand
10626     * _.findKey(users, { 'age': 1, 'active': true });
10627     * // => 'pebbles'
10628     *
10629     * // using the `_.matchesProperty` iteratee shorthand
10630     * _.findKey(users, ['active', false]);
10631     * // => 'fred'
10632     *
10633     * // using the `_.property` iteratee shorthand
10634     * _.findKey(users, 'active');
10635     * // => 'barney'
10636     */
10637    function findKey(object, predicate) {
10638      return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
10639    }
10640
10641    /**
10642     * This method is like `_.findKey` except that it iterates over elements of
10643     * a collection in the opposite order.
10644     *
10645     * @static
10646     * @memberOf _
10647     * @category Object
10648     * @param {Object} object The object to search.
10649     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10650     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10651     * @example
10652     *
10653     * var users = {
10654     *   'barney':  { 'age': 36, 'active': true },
10655     *   'fred':    { 'age': 40, 'active': false },
10656     *   'pebbles': { 'age': 1,  'active': true }
10657     * };
10658     *
10659     * _.findLastKey(users, function(o) { return o.age < 40; });
10660     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
10661     *
10662     * // using the `_.matches` iteratee shorthand
10663     * _.findLastKey(users, { 'age': 36, 'active': true });
10664     * // => 'barney'
10665     *
10666     * // using the `_.matchesProperty` iteratee shorthand
10667     * _.findLastKey(users, ['active', false]);
10668     * // => 'fred'
10669     *
10670     * // using the `_.property` iteratee shorthand
10671     * _.findLastKey(users, 'active');
10672     * // => 'pebbles'
10673     */
10674    function findLastKey(object, predicate) {
10675      return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
10676    }
10677
10678    /**
10679     * Iterates over own and inherited enumerable properties of an object invoking
10680     * `iteratee` for each property. The iteratee is invoked with three arguments:
10681     * (value, key, object). Iteratee functions may exit iteration early by explicitly
10682     * returning `false`.
10683     *
10684     * @static
10685     * @memberOf _
10686     * @category Object
10687     * @param {Object} object The object to iterate over.
10688     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10689     * @returns {Object} Returns `object`.
10690     * @example
10691     *
10692     * function Foo() {
10693     *   this.a = 1;
10694     *   this.b = 2;
10695     * }
10696     *
10697     * Foo.prototype.c = 3;
10698     *
10699     * _.forIn(new Foo, function(value, key) {
10700     *   console.log(key);
10701     * });
10702     * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
10703     */
10704    function forIn(object, iteratee) {
10705      return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
10706    }
10707
10708    /**
10709     * This method is like `_.forIn` except that it iterates over properties of
10710     * `object` in the opposite order.
10711     *
10712     * @static
10713     * @memberOf _
10714     * @category Object
10715     * @param {Object} object The object to iterate over.
10716     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10717     * @returns {Object} Returns `object`.
10718     * @example
10719     *
10720     * function Foo() {
10721     *   this.a = 1;
10722     *   this.b = 2;
10723     * }
10724     *
10725     * Foo.prototype.c = 3;
10726     *
10727     * _.forInRight(new Foo, function(value, key) {
10728     *   console.log(key);
10729     * });
10730     * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
10731     */
10732    function forInRight(object, iteratee) {
10733      return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
10734    }
10735
10736    /**
10737     * Iterates over own enumerable properties of an object invoking `iteratee`
10738     * for each property. The iteratee is invoked with three arguments:
10739     * (value, key, object). Iteratee functions may exit iteration early by
10740     * explicitly returning `false`.
10741     *
10742     * @static
10743     * @memberOf _
10744     * @category Object
10745     * @param {Object} object The object to iterate over.
10746     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10747     * @returns {Object} Returns `object`.
10748     * @example
10749     *
10750     * function Foo() {
10751     *   this.a = 1;
10752     *   this.b = 2;
10753     * }
10754     *
10755     * Foo.prototype.c = 3;
10756     *
10757     * _.forOwn(new Foo, function(value, key) {
10758     *   console.log(key);
10759     * });
10760     * // => logs 'a' then 'b' (iteration order is not guaranteed)
10761     */
10762    function forOwn(object, iteratee) {
10763      return object && baseForOwn(object, toFunction(iteratee));
10764    }
10765
10766    /**
10767     * This method is like `_.forOwn` except that it iterates over properties of
10768     * `object` in the opposite order.
10769     *
10770     * @static
10771     * @memberOf _
10772     * @category Object
10773     * @param {Object} object The object to iterate over.
10774     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10775     * @returns {Object} Returns `object`.
10776     * @example
10777     *
10778     * function Foo() {
10779     *   this.a = 1;
10780     *   this.b = 2;
10781     * }
10782     *
10783     * Foo.prototype.c = 3;
10784     *
10785     * _.forOwnRight(new Foo, function(value, key) {
10786     *   console.log(key);
10787     * });
10788     * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
10789     */
10790    function forOwnRight(object, iteratee) {
10791      return object && baseForOwnRight(object, toFunction(iteratee));
10792    }
10793
10794    /**
10795     * Creates an array of function property names from own enumerable properties
10796     * of `object`.
10797     *
10798     * @static
10799     * @memberOf _
10800     * @category Object
10801     * @param {Object} object The object to inspect.
10802     * @returns {Array} Returns the new array of property names.
10803     * @example
10804     *
10805     * function Foo() {
10806     *   this.a = _.constant('a');
10807     *   this.b = _.constant('b');
10808     * }
10809     *
10810     * Foo.prototype.c = _.constant('c');
10811     *
10812     * _.functions(new Foo);
10813     * // => ['a', 'b']
10814     */
10815    function functions(object) {
10816      return object == null ? [] : baseFunctions(object, keys(object));
10817    }
10818
10819    /**
10820     * Creates an array of function property names from own and inherited
10821     * enumerable properties of `object`.
10822     *
10823     * @static
10824     * @memberOf _
10825     * @category Object
10826     * @param {Object} object The object to inspect.
10827     * @returns {Array} Returns the new array of property names.
10828     * @example
10829     *
10830     * function Foo() {
10831     *   this.a = _.constant('a');
10832     *   this.b = _.constant('b');
10833     * }
10834     *
10835     * Foo.prototype.c = _.constant('c');
10836     *
10837     * _.functionsIn(new Foo);
10838     * // => ['a', 'b', 'c']
10839     */
10840    function functionsIn(object) {
10841      return object == null ? [] : baseFunctions(object, keysIn(object));
10842    }
10843
10844    /**
10845     * Gets the value at `path` of `object`. If the resolved value is
10846     * `undefined` the `defaultValue` is used in its place.
10847     *
10848     * @static
10849     * @memberOf _
10850     * @category Object
10851     * @param {Object} object The object to query.
10852     * @param {Array|string} path The path of the property to get.
10853     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
10854     * @returns {*} Returns the resolved value.
10855     * @example
10856     *
10857     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
10858     *
10859     * _.get(object, 'a[0].b.c');
10860     * // => 3
10861     *
10862     * _.get(object, ['a', '0', 'b', 'c']);
10863     * // => 3
10864     *
10865     * _.get(object, 'a.b.c', 'default');
10866     * // => 'default'
10867     */
10868    function get(object, path, defaultValue) {
10869      var result = object == null ? undefined : baseGet(object, path);
10870      return result === undefined ? defaultValue : result;
10871    }
10872
10873    /**
10874     * Checks if `path` is a direct property of `object`.
10875     *
10876     * @static
10877     * @memberOf _
10878     * @category Object
10879     * @param {Object} object The object to query.
10880     * @param {Array|string} path The path to check.
10881     * @returns {boolean} Returns `true` if `path` exists, else `false`.
10882     * @example
10883     *
10884     * var object = { 'a': { 'b': { 'c': 3 } } };
10885     * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
10886     *
10887     * _.has(object, 'a');
10888     * // => true
10889     *
10890     * _.has(object, 'a.b.c');
10891     * // => true
10892     *
10893     * _.has(object, ['a', 'b', 'c']);
10894     * // => true
10895     *
10896     * _.has(other, 'a');
10897     * // => false
10898     */
10899    function has(object, path) {
10900      return hasPath(object, path, baseHas);
10901    }
10902
10903    /**
10904     * Checks if `path` is a direct or inherited property of `object`.
10905     *
10906     * @static
10907     * @memberOf _
10908     * @category Object
10909     * @param {Object} object The object to query.
10910     * @param {Array|string} path The path to check.
10911     * @returns {boolean} Returns `true` if `path` exists, else `false`.
10912     * @example
10913     *
10914     * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
10915     *
10916     * _.hasIn(object, 'a');
10917     * // => true
10918     *
10919     * _.hasIn(object, 'a.b.c');
10920     * // => true
10921     *
10922     * _.hasIn(object, ['a', 'b', 'c']);
10923     * // => true
10924     *
10925     * _.hasIn(object, 'b');
10926     * // => false
10927     */
10928    function hasIn(object, path) {
10929      return hasPath(object, path, baseHasIn);
10930    }
10931
10932    /**
10933     * Creates an object composed of the inverted keys and values of `object`.
10934     * If `object` contains duplicate values, subsequent values overwrite property
10935     * assignments of previous values unless `multiVal` is `true`.
10936     *
10937     * @static
10938     * @memberOf _
10939     * @category Object
10940     * @param {Object} object The object to invert.
10941     * @param {boolean} [multiVal] Allow multiple values per key.
10942     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
10943     * @returns {Object} Returns the new inverted object.
10944     * @example
10945     *
10946     * var object = { 'a': 1, 'b': 2, 'c': 1 };
10947     *
10948     * _.invert(object);
10949     * // => { '1': 'c', '2': 'b' }
10950     *
10951     * // with `multiVal`
10952     * _.invert(object, true);
10953     * // => { '1': ['a', 'c'], '2': ['b'] }
10954     */
10955    function invert(object, multiVal, guard) {
10956      return arrayReduce(keys(object), function(result, key) {
10957        var value = object[key];
10958        if (multiVal && !guard) {
10959          if (hasOwnProperty.call(result, value)) {
10960            result[value].push(key);
10961          } else {
10962            result[value] = [key];
10963          }
10964        }
10965        else {
10966          result[value] = key;
10967        }
10968        return result;
10969      }, {});
10970    }
10971
10972    /**
10973     * Invokes the method at `path` of `object`.
10974     *
10975     * @static
10976     * @memberOf _
10977     * @category Object
10978     * @param {Object} object The object to query.
10979     * @param {Array|string} path The path of the method to invoke.
10980     * @param {...*} [args] The arguments to invoke the method with.
10981     * @returns {*} Returns the result of the invoked method.
10982     * @example
10983     *
10984     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
10985     *
10986     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
10987     * // => [2, 3]
10988     */
10989    var invoke = rest(baseInvoke);
10990
10991    /**
10992     * Creates an array of the own enumerable property names of `object`.
10993     *
10994     * **Note:** Non-object values are coerced to objects. See the
10995     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
10996     * for more details.
10997     *
10998     * @static
10999     * @memberOf _
11000     * @category Object
11001     * @param {Object} object The object to query.
11002     * @returns {Array} Returns the array of property names.
11003     * @example
11004     *
11005     * function Foo() {
11006     *   this.a = 1;
11007     *   this.b = 2;
11008     * }
11009     *
11010     * Foo.prototype.c = 3;
11011     *
11012     * _.keys(new Foo);
11013     * // => ['a', 'b'] (iteration order is not guaranteed)
11014     *
11015     * _.keys('hi');
11016     * // => ['0', '1']
11017     */
11018    function keys(object) {
11019      var isProto = isPrototype(object);
11020      if (!(isProto || isArrayLike(object))) {
11021        return baseKeys(object);
11022      }
11023      var indexes = indexKeys(object),
11024          skipIndexes = !!indexes,
11025          result = indexes || [],
11026          length = result.length;
11027
11028      for (var key in object) {
11029        if (baseHas(object, key) &&
11030            !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11031            !(isProto && key == 'constructor')) {
11032          result.push(key);
11033        }
11034      }
11035      return result;
11036    }
11037
11038    /**
11039     * Creates an array of the own and inherited enumerable property names of `object`.
11040     *
11041     * **Note:** Non-object values are coerced to objects.
11042     *
11043     * @static
11044     * @memberOf _
11045     * @category Object
11046     * @param {Object} object The object to query.
11047     * @returns {Array} Returns the array of property names.
11048     * @example
11049     *
11050     * function Foo() {
11051     *   this.a = 1;
11052     *   this.b = 2;
11053     * }
11054     *
11055     * Foo.prototype.c = 3;
11056     *
11057     * _.keysIn(new Foo);
11058     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11059     */
11060    function keysIn(object) {
11061      var index = -1,
11062          isProto = isPrototype(object),
11063          props = baseKeysIn(object),
11064          propsLength = props.length,
11065          indexes = indexKeys(object),
11066          skipIndexes = !!indexes,
11067          result = indexes || [],
11068          length = result.length;
11069
11070      while (++index < propsLength) {
11071        var key = props[index];
11072        if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11073            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11074          result.push(key);
11075        }
11076      }
11077      return result;
11078    }
11079
11080    /**
11081     * The opposite of `_.mapValues`; this method creates an object with the
11082     * same values as `object` and keys generated by running each own enumerable
11083     * property of `object` through `iteratee`.
11084     *
11085     * @static
11086     * @memberOf _
11087     * @category Object
11088     * @param {Object} object The object to iterate over.
11089     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11090     * @returns {Object} Returns the new mapped object.
11091     * @example
11092     *
11093     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11094     *   return key + value;
11095     * });
11096     * // => { 'a1': 1, 'b2': 2 }
11097     */
11098    function mapKeys(object, iteratee) {
11099      var result = {};
11100      iteratee = getIteratee(iteratee, 3);
11101
11102      baseForOwn(object, function(value, key, object) {
11103        result[iteratee(value, key, object)] = value;
11104      });
11105      return result;
11106    }
11107
11108    /**
11109     * Creates an object with the same keys as `object` and values generated by
11110     * running each own enumerable property of `object` through `iteratee`. The
11111     * iteratee function is invoked with three arguments: (value, key, object).
11112     *
11113     * @static
11114     * @memberOf _
11115     * @category Object
11116     * @param {Object} object The object to iterate over.
11117     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11118     * @returns {Object} Returns the new mapped object.
11119     * @example
11120     *
11121     * var users = {
11122     *   'fred':    { 'user': 'fred',    'age': 40 },
11123     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11124     * };
11125     *
11126     * _.mapValues(users, function(o) { return o.age; });
11127     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11128     *
11129     * // using the `_.property` iteratee shorthand
11130     * _.mapValues(users, 'age');
11131     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11132     */
11133    function mapValues(object, iteratee) {
11134      var result = {};
11135      iteratee = getIteratee(iteratee, 3);
11136
11137      baseForOwn(object, function(value, key, object) {
11138        result[key] = iteratee(value, key, object);
11139      });
11140      return result;
11141    }
11142
11143    /**
11144     * Recursively merges own and inherited enumerable properties of source
11145     * objects into the destination object, skipping source properties that resolve
11146     * to `undefined`. Array and plain object properties are merged recursively.
11147     * Other objects and value types are overridden by assignment. Source objects
11148     * are applied from left to right. Subsequent sources overwrite property
11149     * assignments of previous sources.
11150     *
11151     * **Note:** This method mutates `object`.
11152     *
11153     * @static
11154     * @memberOf _
11155     * @category Object
11156     * @param {Object} object The destination object.
11157     * @param {...Object} [sources] The source objects.
11158     * @returns {Object} Returns `object`.
11159     * @example
11160     *
11161     * var users = {
11162     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11163     * };
11164     *
11165     * var ages = {
11166     *   'data': [{ 'age': 36 }, { 'age': 40 }]
11167     * };
11168     *
11169     * _.merge(users, ages);
11170     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11171     */
11172    var merge = createAssigner(function(object, source, srcIndex) {
11173      baseMerge(object, source, srcIndex);
11174    });
11175
11176    /**
11177     * This method is like `_.merge` except that it accepts `customizer` which
11178     * is invoked to produce the merged values of the destination and source
11179     * properties. If `customizer` returns `undefined` merging is handled by the
11180     * method instead. The `customizer` is invoked with seven arguments:
11181     * (objValue, srcValue, key, object, source, stack).
11182     *
11183     * @static
11184     * @memberOf _
11185     * @category Object
11186     * @param {Object} object The destination object.
11187     * @param {...Object} sources The source objects.
11188     * @param {Function} customizer The function to customize assigned values.
11189     * @returns {Object} Returns `object`.
11190     * @example
11191     *
11192     * function customizer(objValue, srcValue) {
11193     *   if (_.isArray(objValue)) {
11194     *     return objValue.concat(srcValue);
11195     *   }
11196     * }
11197     *
11198     * var object = {
11199     *   'fruits': ['apple'],
11200     *   'vegetables': ['beet']
11201     * };
11202     *
11203     * var other = {
11204     *   'fruits': ['banana'],
11205     *   'vegetables': ['carrot']
11206     * };
11207     *
11208     * _.mergeWith(object, other, customizer);
11209     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11210     */
11211    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11212      baseMerge(object, source, srcIndex, customizer);
11213    });
11214
11215    /**
11216     * The opposite of `_.pick`;
11216 this method creates an object composed of the
11217     * own and inherited enumerable properties of `object` that are not omitted.
11218     *
11219     * @static
11220     * @memberOf _
11221     * @category Object
11222     * @param {Object} object The source object.
11223     * @param {...(string|string[])} [props] The property names to omit, specified
11224     *  individually or in arrays..
11225     * @returns {Object} Returns the new object.
11226     * @example
11227     *
11228     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11229     *
11230     * _.omit(object, ['a', 'c']);
11231     * // => { 'b': '2' }
11232     */
11233    var omit = rest(function(object, props) {
11234      if (object == null) {
11235        return {};
11236      }
11237      props = arrayMap(baseFlatten(props), String);
11238      return basePick(object, baseDifference(keysIn(object), props));
11239    });
11240
11241    /**
11242     * The opposite of `_.pickBy`; this method creates an object composed of the
11243     * own and inherited enumerable properties of `object` that `predicate`
11244     * doesn't return truthy for.
11245     *
11246     * @static
11247     * @memberOf _
11248     * @category Object
11249     * @param {Object} object The source object.
11250     * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11251     * @returns {Object} Returns the new object.
11252     * @example
11253     *
11254     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11255     *
11256     * _.omitBy(object, _.isNumber);
11257     * // => { 'b': '2' }
11258     */
11259    function omitBy(object, predicate) {
11260      predicate = getIteratee(predicate, 2);
11261      return basePickBy(object, function(value, key) {
11262        return !predicate(value, key);
11263      });
11264    }
11265
11266    /**
11267     * Creates an object composed of the picked `object` properties.
11268     *
11269     * @static
11270     * @memberOf _
11271     * @category Object
11272     * @param {Object} object The source object.
11273     * @param {...(string|string[])} [props] The property names to pick, specified
11274     *  individually or in arrays.
11275     * @returns {Object} Returns the new object.
11276     * @example
11277     *
11278     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11279     *
11280     * _.pick(object, ['a', 'c']);
11281     * // => { 'a': 1, 'c': 3 }
11282     */
11283    var pick = rest(function(object, props) {
11284      return object == null ? {} : basePick(object, baseFlatten(props));
11285    });
11286
11287    /**
11288     * Creates an object composed of the `object` properties `predicate` returns
11289     * truthy for. The predicate is invoked with one argument: (value).
11290     *
11291     * @static
11292     * @memberOf _
11293     * @category Object
11294     * @param {Object} object The source object.
11295     * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11296     * @returns {Object} Returns the new object.
11297     * @example
11298     *
11299     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11300     *
11301     * _.pickBy(object, _.isNumber);
11302     * // => { 'a': 1, 'c': 3 }
11303     */
11304    function pickBy(object, predicate) {
11305      return object == null ? {} : basePickBy(object, getIteratee(predicate, 2));
11306    }
11307
11308    /**
11309     * This method is like `_.get` except that if the resolved value is a function
11310     * it's invoked with the `this` binding of its parent object and its result
11311     * is returned.
11312     *
11313     * @static
11314     * @memberOf _
11315     * @category Object
11316     * @param {Object} object The object to query.
11317     * @param {Array|string} path The path of the property to resolve.
11318     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11319     * @returns {*} Returns the resolved value.
11320     * @example
11321     *
11322     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11323     *
11324     * _.result(object, 'a[0].b.c1');
11325     * // => 3
11326     *
11327     * _.result(object, 'a[0].b.c2');
11328     * // => 4
11329     *
11330     * _.result(object, 'a[0].b.c3', 'default');
11331     * // => 'default'
11332     *
11333     * _.result(object, 'a[0].b.c3', _.constant('default'));
11334     * // => 'default'
11335     */
11336    function result(object, path, defaultValue) {
11337      if (!isKey(path, object)) {
11338        path = baseToPath(path);
11339        var result = get(object, path);
11340        object = parent(object, path);
11341      } else {
11342        result = object == null ? undefined : object[path];
11343      }
11344      if (result === undefined) {
11345        result = defaultValue;
11346      }
11347      return isFunction(result) ? result.call(object) : result;
11348    }
11349
11350    /**
11351     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11352     * it's created. Arrays are created for missing index properties while objects
11353     * are created for all other missing properties. Use `_.setWith` to customize
11354     * `path` creation.
11355     *
11356     * @static
11357     * @memberOf _
11358     * @category Object
11359     * @param {Object} object The object to modify.
11360     * @param {Array|string} path The path of the property to set.
11361     * @param {*} value The value to set.
11362     * @returns {Object} Returns `object`.
11363     * @example
11364     *
11365     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11366     *
11367     * _.set(object, 'a[0].b.c', 4);
11368     * console.log(object.a[0].b.c);
11369     * // => 4
11370     *
11371     * _.set(object, 'x[0].y.z', 5);
11372     * console.log(object.x[0].y.z);
11373     * // => 5
11374     */
11375    function set(object, path, value) {
11376      return object == null ? object : baseSet(object, path, value);
11377    }
11378
11379    /**
11380     * This method is like `_.set` except that it accepts `customizer` which is
11381     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11382     * path creation is handled by the method instead. The `customizer` is invoked
11383     * with three arguments: (nsValue, key, nsObject).
11384     *
11385     * @static
11386     * @memberOf _
11387     * @category Object
11388     * @param {Object} object The object to modify.
11389     * @param {Array|string} path The path of the property to set.
11390     * @param {*} value The value to set.
11391     * @param {Function} [customizer] The function to customize assigned values.
11392     * @returns {Object} Returns `object`.
11393     * @example
11394     *
11395     * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11396     * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11397     */
11398    function setWith(object, path, value, customizer) {
11399      customizer = typeof customizer == 'function' ? customizer : undefined;
11400      return object == null ? object : baseSet(object, path, value, customizer);
11401    }
11402
11403    /**
11404     * Creates an array of own enumerable key-value pairs for `object`.
11405     *
11406     * @static
11407     * @memberOf _
11408     * @category Object
11409     * @param {Object} object The object to query.
11410     * @returns {Array} Returns the new array of key-value pairs.
11411     * @example
11412     *
11413     * function Foo() {
11414     *   this.a = 1;
11415     *   this.b = 2;
11416     * }
11417     *
11418     * Foo.prototype.c = 3;
11419     *
11420     * _.toPairs(new Foo);
11421     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11422     */
11423    function toPairs(object) {
11424      return baseToPairs(object, keys(object));
11425    }
11426
11427    /**
11428     * Creates an array of own and inherited enumerable key-value pairs for `object`.
11429     *
11430     * @static
11431     * @memberOf _
11432     * @category Object
11433     * @param {Object} object The object to query.
11434     * @returns {Array} Returns the new array of key-value pairs.
11435     * @example
11436     *
11437     * function Foo() {
11438     *   this.a = 1;
11439     *   this.b = 2;
11440     * }
11441     *
11442     * Foo.prototype.c = 3;
11443     *
11444     * _.toPairsIn(new Foo);
11445     * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11446     */
11447    function toPairsIn(object) {
11448      return baseToPairs(object, keysIn(object));
11449    }
11450
11451    /**
11452     * An alternative to `_.reduce`; this method transforms `object` to a new
11453     * `accumulator` object which is the result of running each of its own enumerable
11454     * properties through `iteratee`, with each invocation potentially mutating
11455     * the `accumulator` object. The iteratee is invoked with four arguments:
11456     * (accumulator, value, key, object). Iteratee functions may exit iteration
11457     * early by explicitly returning `false`.
11458     *
11459     * @static
11460     * @memberOf _
11461     * @category Object
11462     * @param {Array|Object} object The object to iterate over.
11463     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11464     * @param {*} [accumulator] The custom accumulator value.
11465     * @returns {*} Returns the accumulated value.
11466     * @example
11467     *
11468     * _.transform([2, 3, 4], function(result, n) {
11469     *   result.push(n *= n);
11470     *   return n % 2 == 0;
11471     * });
11472     * // => [4, 9]
11473     *
11474     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11475     *   (result[value] || (result[value] = [])).push(key);
11476     * });
11477     * // => { '1': ['a', 'c'], '2': ['b'] }
11478     */
11479    function transform(object, iteratee, accumulator) {
11480      var isArr = isArray(object) || isTypedArray(object);
11481      iteratee = getIteratee(iteratee, 4);
11482
11483      if (accumulator == null) {
11484        if (isArr || isObject(object)) {
11485          var Ctor = object.constructor;
11486          if (isArr) {
11487            accumulator = isArray(object) ? new Ctor : [];
11488          } else {
11489            accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
11490          }
11491        } else {
11492          accumulator = {};
11493        }
11494      }
11495      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11496        return iteratee(accumulator, value, index, object);
11497      });
11498      return accumulator;
11499    }
11500
11501    /**
11502     * Removes the property at `path` of `object`.
11503     *
11504     * @static
11505     * @memberOf _
11506     * @category Object
11507     * @param {Object} object The object to modify.
11508     * @param {Array|string} path The path of the property to unset.
11509     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11510     * @example
11511     *
11512     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11513     * _.unset(object, 'a[0].b.c');
11514     * // => true
11515     *
11516     * console.log(object);
11517     * // => { 'a': [{ 'b': {} }] };
11518     *
11519     * _.unset(object, 'a[0].b.c');
11520     * // => true
11521     *
11522     * console.log(object);
11523     * // => { 'a': [{ 'b': {} }] };
11524     */
11525    function unset(object, path) {
11526      return object == null ? true : baseUnset(object, path);
11527    }
11528
11529    /**
11530     * Creates an array of the own enumerable property values of `object`.
11531     *
11532     * **Note:** Non-object values are coerced to objects.
11533     *
11534     * @static
11535     * @memberOf _
11536     * @category Object
11537     * @param {Object} object The object to query.
11538     * @returns {Array} Returns the array of property values.
11539     * @example
11540     *
11541     * function Foo() {
11542     *   this.a = 1;
11543     *   this.b = 2;
11544     * }
11545     *
11546     * Foo.prototype.c = 3;
11547     *
11548     * _.values(new Foo);
11549     * // => [1, 2] (iteration order is not guaranteed)
11550     *
11551     * _.values('hi');
11552     * // => ['h', 'i']
11553     */
11554    function values(object) {
11555      return object ? baseValues(object, keys(object)) : [];
11556    }
11557
11558    /**
11559     * Creates an array of the own and inherited enumerable property values of `object`.
11560     *
11561     * **Note:** Non-object values are coerced to objects.
11562     *
11563     * @static
11564     * @memberOf _
11565     * @category Object
11566     * @param {Object} object The object to query.
11567     * @returns {Array} Returns the array of property values.
11568     * @example
11569     *
11570     * function Foo() {
11571     *   this.a = 1;
11572     *   this.b = 2;
11573     * }
11574     *
11575     * Foo.prototype.c = 3;
11576     *
11577     * _.valuesIn(new Foo);
11578     * // => [1, 2, 3] (iteration order is not guaranteed)
11579     */
11580    function valuesIn(object) {
11581      return object == null ? baseValues(object, keysIn(object)) : [];
11582    }
11583
11584    /*------------------------------------------------------------------------*/
11585
11586    /**
11587     * Clamps `number` within the inclusive `lower` and `upper` bounds.
11588     *
11589     * @static
11590     * @memberOf _
11591     * @category Number
11592     * @param {number} number The number to clamp.
11593     * @param {number} [lower] The lower bound.
11594     * @param {number} upper The upper bound.
11595     * @returns {number} Returns the clamped number.
11596     * @example
11597     *
11598     * _.clamp(-10, -5, 5);
11599     * // => -5
11600     *
11601     * _.clamp(10, -5, 5);
11602     * // => 5
11603     */
11604    function clamp(number, lower, upper) {
11605      if (upper === undefined) {
11606        upper = lower;
11607        lower = undefined;
11608      }
11609      if (upper !== undefined) {
11610        upper = toNumber(upper);
11611        upper = upper === upper ? upper : 0;
11612      }
11613      if (lower !== undefined) {
11614        lower = toNumber(lower);
11615        lower = lower === lower ? lower : 0;
11616      }
11617      return baseClamp(toNumber(number), lower, upper);
11618    }
11619
11620    /**
11621     * Checks if `n` is between `start` and up to but not including, `end`. If
11622     * `end` is not specified it's set to `start` with `start` then set to `0`.
11623     * If `start` is greater than `end` the params are swapped to support
11624     * negative ranges.
11625     *
11626     * @static
11627     * @memberOf _
11628     * @category Number
11629     * @param {number} number The number to check.
11630     * @param {number} [start=0] The start of the range.
11631     * @param {number} end The end of the range.
11632     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
11633     * @example
11634     *
11635     * _.inRange(3, 2, 4);
11636     * // => true
11637     *
11638     * _.inRange(4, 8);
11639     * // => true
11640     *
11641     * _.inRange(4, 2);
11642     * // => false
11643     *
11644     * _.inRange(2, 2);
11645     * // => false
11646     *
11647     * _.inRange(1.2, 2);
11648     * // => true
11649     *
11650     * _.inRange(5.2, 4);
11651     * // => false
11652     *
11653     * _.inRange(-3, -2, -6);
11654     * // => true
11655     */
11656    function inRange(number, start, end) {
11657      start = toNumber(start) || 0;
11658      if (end === undefined) {
11659        end = start;
11660        start = 0;
11661      } else {
11662        end = toNumber(end) || 0;
11663      }
11664      number = toNumber(number);
11665      return baseInRange(number, start, end);
11666    }
11667
11668    /**
11669     * Produces a random number between the inclusive `lower` and `upper` bounds.
11670     * If only one argument is provided a number between `0` and the given number
11671     * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
11672     * a floating-point number is returned instead of an integer.
11673     *
11674     * **Note:** JavaScript follows the IEEE-754 standard for resolving
11675     * floating-point values which can produce unexpected results.
11676     *
11677     * @static
11678     * @memberOf _
11679     * @category Number
11680     * @param {number} [lower=0] The lower bound.
11681     * @param {number} [upper=1] The upper bound.
11682     * @param {boolean} [floating] Specify returning a floating-point number.
11683     * @returns {number} Returns the random number.
11684     * @example
11685     *
11686     * _.random(0, 5);
11687     * // => an integer between 0 and 5
11688     *
11689     * _.random(5);
11690     * // => also an integer between 0 and 5
11691     *
11692     * _.random(5, true);
11693     * // => a floating-point number between 0 and 5
11694     *
11695     * _.random(1.2, 5.2);
11696     * // => a floating-point number between 1.2 and 5.2
11697     */
11698    function random(lower, upper, floating) {
11699      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
11700        upper = floating = undefined;
11701      }
11702      if (floating === undefined) {
11703        if (typeof upper == 'boolean') {
11704          floating = upper;
11705          upper = undefined;
11706        }
11707        else if (typeof lower == 'boolean') {
11708          floating = lower;
11709          lower = undefined;
11710        }
11711      }
11712      if (lower === undefined && upper === undefined) {
11713        lower = 0;
11714        upper = 1;
11715      }
11716      else {
11717        lower = toNumber(lower) || 0;
11718        if (upper === undefined) {
11719          upper = lower;
11720          lower = 0;
11721        } else {
11722          upper = toNumber(upper) || 0;
11723        }
11724      }
11725      if (lower > upper) {
11726        var temp = lower;
11727        lower = upper;
11728        upper = temp;
11729      }
11730      if (floating || lower % 1 || upper % 1) {
11731        var rand = nativeRandom();
11732        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
11733      }
11734      return baseRandom(lower, upper);
11735    }
11736
11737    /*------------------------------------------------------------------------*/
11738
11739    /**
11740     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
11741     *
11742     * @static
11743     * @memberOf _
11744     * @category String
11745     * @param {string} [string=''] The string to convert.
11746     * @returns {string} Returns the camel cased string.
11747     * @example
11748     *
11749     * _.camelCase('Foo Bar');
11750     * // => 'fooBar'
11751     *
11752     * _.camelCase('--foo-bar');
11753     * // => 'fooBar'
11754     *
11755     * _.camelCase('__foo_bar__');
11756     * // => 'fooBar'
11757     */
vendor: 4,524 bytes, lines 11758-11887
11758    var camelCase = createCompounder(function(result, word, index) {
11759      word = word.toLowerCase();
11760      return result + (index ? capitalize(word) : word);
11761    });
11762
11763    /**
11764     * Converts the first character of `string` to upper case and the remaining
11765     * to lower case.
11766     *
11767     * @static
11768     * @memberOf _
11769     * @category String
11770     * @param {string} [string=''] The string to capitalize.
11771     * @returns {string} Returns the capitalized string.
11772     * @example
11773     *
11774     * _.capitalize('FRED');
11775     * // => 'Fred'
11776     */
11777    function capitalize(string) {
11778      return upperFirst(toString(string).toLowerCase());
11779    }
11780
11781    /**
11782     * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
11783     * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
11784     *
11785     * @static
11786     * @memberOf _
11787     * @category String
11788     * @param {string} [string=''] The string to deburr.
11789     * @returns {string} Returns the deburred string.
11790     * @example
11791     *
11792     * _.deburr('déjà vu');
11793     * // => 'deja vu'
11794     */
11795    function deburr(string) {
11796      string = toString(string);
11797      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
11798    }
11799
11800    /**
11801     * Checks if `string` ends with the given target string.
11802     *
11803     * @static
11804     * @memberOf _
11805     * @category String
11806     * @param {string} [string=''] The string to search.
11807     * @param {string} [target] The string to search for.
11808     * @param {number} [position=string.length] The position to search from.
11809     * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
11810     * @example
11811     *
11812     * _.endsWith('abc', 'c');
11813     * // => true
11814     *
11815     * _.endsWith('abc', 'b');
11816     * // => false
11817     *
11818     * _.endsWith('abc', 'b', 2);
11819     * // => true
11820     */
11821    function endsWith(string, target, position) {
11822      string = toString(string);
11823      target = typeof target == 'string' ? target : (target + '');
11824
11825      var length = string.length;
11826      position = position === undefined
11827        ? length
11828        : baseClamp(toInteger(position), 0, length);
11829
11830      position -= target.length;
11831      return position >= 0 && string.indexOf(target, position) == position;
11832    }
11833
11834    /**
11835     * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
11836     * their corresponding HTML entities.
11837     *
11838     * **Note:** No other characters are escaped. To escape additional
11839     * characters use a third-party library like [_he_](https://mths.be/he).
11840     *
11841     * Though the ">" character is escaped for symmetry, characters like
11842     * ">" and "/" don't need escaping in HTML and have no special meaning
11843     * unless they're part of a tag or unquoted attribute value.
11844     * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
11845     * (under "semi-related fun fact") for more details.
11846     *
11847     * Backticks are escaped because in IE < 9, they can break out of
11848     * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
11849     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
11850     * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
11851     * for more details.
11852     *
11853     * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
11854     * to reduce XSS vectors.
11855     *
11856     * @static
11857     * @memberOf _
11858     * @category String
11859     * @param {string} [string=''] The string to escape.
11860     * @returns {string} Returns the escaped string.
11861     * @example
11862     *
11863     * _.escape('fred, barney, & pebbles');
11864     * // => 'fred, barney, &amp; pebbles'
11865     */
11866    function escape(string) {
11867      string = toString(string);
11868      return (string && reHasUnescapedHtml.test(string))
11869        ? string.replace(reUnescapedHtml, escapeHtmlChar)
11870        : string;
11871    }
11872
11873    /**
11874     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
11875     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
11876     *
11877     * @static
11878     * @memberOf _
11879     * @category String
11880     * @param {string} [string=''] The string to escape.
11881     * @returns {string} Returns the escaped string.
11882     * @example
11883     *
11884     * _.escapeRegExp('[lodash](https://lodash.com/)');
11885     * // => '\[lodash\]\(https://lodash\.com/\)'
11886     */
11887    function escapeRegExp(string) {
11888      string = toString(string);
11889      return (string && reHasRegExpChar.test(string))
11890        ? string.replace(reRegExpChar, '\\$&')
11891        : string;
11892    }
11893
11894    /**
11895     * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
11896     *
11897     * @static
11898     * @memberOf _
11899     * @category String
11900     * @param {string} [string=''] The string to convert.
11901     * @returns {string} Returns the kebab cased string.
11902     * @example
11903     *
11904     * _.kebabCase('Foo Bar');
11905     * // => 'foo-bar'
11906     *
11907     * _.kebabCase('fooBar');
11908     * // => 'foo-bar'
11909     *
11910     * _.kebabCase('__foo_bar__');
11911     * // => 'foo-bar'
11912     */
11913    var kebabCase = createCompounder(function(result, word, index) {
11914      return result + (index ? '-' : '') + word.toLowerCase();
11915    });
11916
11917    /**
11918     * Converts `string`, as space separated words, to lower case.
11919     *
11920     * @static
11921     * @memberOf _
11922     * @category String
11923     * @param {string} [string=''] The string to convert.
11924     * @returns {string} Returns the lower cased string.
11925     * @example
11926     *
11927     * _.lowerCase('--Foo-Bar');
11928     * // => 'foo bar'
11929     *
11930     * _.lowerCase('fooBar');
11931     * // => 'foo bar'
11932     *
11933     * _.lowerCase('__FOO_BAR__');
11934     * // => 'foo bar'
11935     */
11936    var lowerCase = createCompounder(function(result, word, index) {
11937      return result + (index ? ' ' : '') + word.toLowerCase();
11938    });
11939
11940    /**
11941     * Converts the first character of `string` to lower case.
11942     *
11943     * @static
11944     * @memberOf _
11945     * @category String
11946     * @param {string} [string=''] The string to convert.
11947     * @returns {string} Returns the converted string.
11948     * @example
11949     *
11950     * _.lowerFirst('Fred');
11951     * // => 'fred'
11952     *
11953     * _.lowerFirst('FRED');
11954     * // => 'fRED'
11955     */
11956    var lowerFirst = createCaseFirst('toLowerCase');
11957
11958    /**
11959     * Converts the first character of `string` to upper case.
11960     *
11961     * @static
11962     * @memberOf _
11963     * @category String
11964     * @param {string} [string=''] The string to convert.
11965     * @returns {string} Returns the converted string.
11966     * @example
11967     *
11968     * _.upperFirst('fred');
11969     * // => 'Fred'
11970     *
11971     * _.upperFirst('FRED');
11972     * // => 'FRED'
11973     */
11974    var upperFirst = createCaseFirst('toUpperCase');
11975
11976    /**
11977     * Pads `string` on the left and right sides if it's shorter than `length`.
11978     * Padding characters are truncated if they can't be evenly divided by `length`.
11979     *
11980     * @static
11981     * @memberOf _
11982     * @category String
11983     * @param {string} [string=''] The string to pad.
11984     * @param {number} [length=0] The padding length.
11985     * @param {string} [chars=' '] The string used as padding.
11986     * @returns {string} Returns the padded string.
11987     * @example
11988     *
11989     * _.pad('abc', 8);
11990     * // => '  abc   '
11991     *
11992     * _.pad('abc', 8, '_-');
11993     * // => '_-abc_-_'
11994     *
11995     * _.pad('abc', 3);
11996     * // => 'abc'
11997     */
11998    function pad(string, length, chars) {
11999      string = toString(string);
12000      length = toInteger(length);
12001
12002      var strLength = stringSize(string);
12003      if (!length || strLength >= length) {
12004        return string;
12005      }
12006      var mid = (length - strLength) / 2,
12007          leftLength = nativeFloor(mid),
12008          rightLength = nativeCeil(mid);
12009
12010      return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
12011    }
12012
12013    /**
12014     * Pads `string` on the right side if it's shorter than `length`. Padding
12015     * characters are truncated if they exceed `length`.
12016     *
12017     * @static
12018     * @memberOf _
12019     * @category String
12020     * @param {string} [string=''] The string to pad.
12021     * @param {number} [length=0] The padding length.
12022     * @param {string} [chars=' '] The string used as padding.
12023     * @returns {string} Returns the padded string.
12024     * @example
12025     *
12026     * _.padEnd('abc', 6);
12027     * // => 'abc   '
12028     *
12029     * _.padEnd('abc', 6, '_-');
12030     * // => 'abc_-_'
12031     *
12032     * _.padEnd('abc', 3);
12033     * // => 'abc'
12034     */
12035    function padEnd(string, length, chars) {
12036      string = toString(string);
12037      return string + createPadding(string, length, chars);
12038    }
12039
12040    /**
12041     * Pads `string` on the left side if it's shorter than `length`. Padding
12042     * characters are truncated if they exceed `length`.
12043     *
12044     * @static
12045     * @memberOf _
12046     * @category String
12047     * @param {string} [string=''] The string to pad.
12048     * @param {number} [length=0] The padding length.
12049     * @param {string} [chars=' '] The string used as padding.
12050     * @returns {string} Returns the padded string.
12051     * @example
12052     *
12053     * _.padStart('abc', 6);
12054     * // => '   abc'
12055     *
12056     * _.padStart('abc', 6, '_-');
12057     * // => '_-_abc'
12058     *
12059     * _.padStart('abc', 3);
12060     * // => 'abc'
12061     */
12062    function padStart(string, length, chars) {
12063      string = toString(string);
12064      return createPadding(string, length, chars) + string;
12065    }
12066
12067    /**
12068     * Converts `string` to an integer of the specified radix. If `radix` is
12069     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12070     * in which case a `radix` of `16` is used.
12071     *
12072     * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
12073     * of `parseInt`.
12074     *
12075     * @static
12076     * @memberOf _
12077     * @category String
12078     * @param {string} string The string to convert.
12079     * @param {number} [radix] The radix to interpret `value` by.
12080     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12081     * @returns {number} Returns the converted integer.
12082     * @example
12083     *
12084     * _.parseInt('08');
12085     * // => 8
12086     *
12087     * _.map(['6', '08', '10'], _.parseInt);
12088     * // => [6, 8, 10]
12089     */
12090    function parseInt(string, radix, guard) {
12091      // Chrome fails to trim leading <BOM> whitespace characters.
12092      // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12093      if (guard || radix == null) {
12094        radix = 0;
12095      } else if (radix) {
12096        radix = +radix;
12097      }
12098      string = toString(string).replace(reTrim, '');
12099      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12100    }
12101
12102    /**
12103     * Repeats the given string `n` times.
12104     *
12105     * @static
12106     * @memberOf _
12107     * @category String
12108     * @param {string} [string=''] The string to repeat.
12109     * @param {number} [n=0] The number of times to repeat the string.
12110     * @returns {string} Returns the repeated string.
12111     * @example
12112     *
12113     * _.repeat('*', 3);
12114     * // => '***'
12115     *
12116     * _.repeat('abc', 2);
12117     * // => 'abcabc'
12118     *
12119     * _.repeat('abc', 0);
12120     * // => ''
12121     */
12122    function repeat(string, n) {
12123      string = toString(string);
12124      n = toInteger(n);
12125
12126      var result = '';
12127      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12128        return result;
12129      }
12130      // Leverage the exponentiation by squaring algorithm for a faster repeat.
12131      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12132      do {
12133        if (n % 2) {
12134          result += string;
12135        }
12136        n = nativeFloor(n / 2);
12137        string += string;
12138      } while (n);
12139
12140      return result;
12141    }
12142
12143    /**
12144     * Replaces matches for `pattern` in `string` with `replacement`.
12145     *
12146     * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12147     *
12148     * @static
12149     * @memberOf _
12150     * @category String
12151     * @param {string} [string=''] The string to modify.
12152     * @param {RegExp|string} pattern The pattern to replace.
12153     * @param {Function|string} replacement The match replacement.
12154     * @returns {string} Returns the modified string.
12155     * @example
12156     *
12157     * _.replace('Hi Fred', 'Fred', 'Barney');
12158     * // =>
12158 'Hi Barney'
12159     */
12160    function replace() {
12161      var args = arguments,
12162          string = toString(args[0]);
12163
12164      return args.length < 3 ? string : string.replace(args[1], args[2]);
12165    }
12166
12167    /**
12168     * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12169     *
12170     * @static
12171     * @memberOf _
12172     * @category String
12173     * @param {string} [string=''] The string to convert.
12174     * @returns {string} Returns the snake cased string.
12175     * @example
12176     *
12177     * _.snakeCase('Foo Bar');
12178     * // => 'foo_bar'
12179     *
12180     * _.snakeCase('fooBar');
12181     * // => 'foo_bar'
12182     *
12183     * _.snakeCase('--foo-bar');
12184     * // => 'foo_bar'
12185     */
12186    var snakeCase = createCompounder(function(result, word, index) {
12187      return result + (index ? '_' : '') + word.toLowerCase();
12188    });
12189
12190    /**
12191     * Splits `string` by `separator`.
12192     *
12193     * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12194     *
12195     * @static
12196     * @memberOf _
12197     * @category String
12198     * @param {string} [string=''] The string to split.
12199     * @param {RegExp|string} separator The separator pattern to split by.
12200     * @param {number} [limit] The length to truncate results to.
12201     * @returns {Array} Returns the new array of string segments.
12202     * @example
12203     *
12204     * _.split('a-b-c', '-', 2);
12205     * // => ['a', 'b']
12206     */
12207    function split(string, separator, limit) {
12208      return toString(string).split(separator, limit);
12209    }
12210
12211    /**
12212     * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12213     *
12214     * @static
12215     * @memberOf _
12216     * @category String
12217     * @param {string} [string=''] The string to convert.
12218     * @returns {string} Returns the start cased string.
12219     * @example
12220     *
12221     * _.startCase('--foo-bar');
12222     * // => 'Foo Bar'
12223     *
12224     * _.startCase('fooBar');
12225     * // => 'Foo Bar'
12226     *
12227     * _.startCase('__foo_bar__');
12228     * // => 'Foo Bar'
12229     */
12230    var startCase = createCompounder(function(result, word, index) {
12231      return result + (index ? ' ' : '') + capitalize(word);
12232    });
12233
12234    /**
12235     * Checks if `string` starts with the given target string.
12236     *
12237     * @static
12238     * @memberOf _
12239     * @category String
12240     * @param {string} [string=''] The string to search.
12241     * @param {string} [target] The string to search for.
12242     * @param {number} [position=0] The position to search from.
12243     * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12244     * @example
12245     *
12246     * _.startsWith('abc', 'a');
12247     * // => true
12248     *
12249     * _.startsWith('abc', 'b');
12250     * // => false
12251     *
12252     * _.startsWith('abc', 'b', 1);
12253     * // => true
12254     */
12255    function startsWith(string, target, position) {
12256      string = toString(string);
12257      position = baseClamp(toInteger(position), 0, string.length);
12258      return string.lastIndexOf(target, position) == position;
12259    }
12260
12261    /**
12262     * Creates a compiled template function that can interpolate data properties
12263     * in "interpolate" delimiters, HTML-escape interpolated data properties in
12264     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12265     * properties may be accessed as free variables in the template. If a setting
12266     * object is provided it takes precedence over `_.templateSettings` values.
12267     *
12268     * **Note:** In the development build `_.template` utilizes
12269     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12270     * for easier debugging.
12271     *
12272     * For more information on precompiling templates see
12273     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12274     *
12275     * For more information on Chrome extension sandboxes see
12276     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12277     *
12278     * @static
12279     * @memberOf _
12280     * @category String
12281     * @param {string} [string=''] The template string.
12282     * @param {Object} [options] The options object.
12283     * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12284     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12285     * @param {Object} [options.imports] An object to import into the template as free variables.
12286     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12287     * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12288     * @param {string} [options.variable] The data object variable name.
12289     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12290     * @returns {Function} Returns the compiled template function.
12291     * @example
12292     *
12293     * // using the "interpolate" delimiter to create a compiled template
12294     * var compiled = _.template('hello <%= user %>!');
12295     * compiled({ 'user': 'fred' });
12296     * // => 'hello fred!'
12297     *
12298     * // using the HTML "escape" delimiter to escape data property values
12299     * var compiled = _.template('<b><%- value %></b>');
12300     * compiled({ 'value': '<script>' });
12301     * // => '<b>&lt;script&gt;</b>'
12302     *
12303     * // using the "evaluate" delimiter to execute JavaScript and generate HTML
12304     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12305     * compiled({ 'users': ['fred', 'barney'] });
12306     * // => '<li>fred</li><li>barney</li>'
12307     *
12308     * // using the internal `print` function in "evaluate" delimiters
12309     * var compiled = _.template('<% print("hello " + user); %>!');
12310     * compiled({ 'user': 'barney' });
12311     * // => 'hello barney!'
12312     *
12313     * // using the ES delimiter as an alternative to the default "interpolate" delimiter
12314     * var compiled = _.template('hello ${ user }!');
12315     * compiled({ 'user': 'pebbles' });
12316     * // => 'hello pebbles!'
12317     *
12318     * // using custom template delimiters
12319     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12320     * var compiled = _.template('hello {{ user }}!');
12321     * compiled({ 'user': 'mustache' });
12322     * // => 'hello mustache!'
12323     *
12324     * // using backslashes to treat delimiters as plain text
12325     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12326     * compiled({ 'value': 'ignored' });
12327     * // => '<%- value %>'
12328     *
12329     * // using the `imports` option to import `jQuery` as `jq`
12330     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12331     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12332     * compiled({ 'users': ['fred', 'barney'] });
12333     * // => '<li>fred</li><li>barney</li>'
12334     *
12335     * // using the `sourceURL` option to specify a custom sourceURL for the template
12336     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12337     * compiled(data);
12338     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12339     *
12340     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
12341     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12342     * compiled.source;
12343     * // => function(data) {
12344     * //   var __t, __p = '';
12345     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12346     * //   return __p;
12347     * // }
12348     *
12349     * // using the `source` property to inline compiled templates for meaningful
12350     * // line numbers in error messages and a stack trace
12351     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12352     *   var JST = {\
12353     *     "main": ' + _.template(mainText).source + '\
12354     *   };\
12355     * ');
12356     */
12357    function template(string, options, guard) {
12358      // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12359      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12360      var settings = lodash.templateSettings;
12361
12362      if (guard && isIterateeCall(string, options, guard)) {
12363        options = undefined;
12364      }
12365      string = toString(string);
12366      options = assignInWith({}, options, settings, assignInDefaults);
12367
12368      var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12369          importsKeys = keys(imports),
12370          importsValues = baseValues(imports, importsKeys);
12371
12372      var isEscaping,
12373          isEvaluating,
12374          index = 0,
12375          interpolate = options.interpolate || reNoMatch,
12376          source = "__p += '";
12377
12378      // Compile the regexp to match each delimiter.
12379      var reDelimiters = RegExp(
12380        (options.escape || reNoMatch).source + '|' +
12381        interpolate.source + '|' +
12382        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12383        (options.evaluate || reNoMatch).source + '|$'
12384      , 'g');
12385
12386      // Use a sourceURL for easier debugging.
12387      var sourceURL = '//# sourceURL=' +
12388        ('sourceURL' in options
12389          ? options.sourceURL
12390          : ('lodash.templateSources[' + (++templateCounter) + ']')
12391        ) + '\n';
12392
12393      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12394        interpolateValue || (interpolateValue = esTemplateValue);
12395
12396        // Escape characters that can't be included in string literals.
12397        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12398
12399        // Replace delimiters with snippets.
12400        if (escapeValue) {
12401          isEscaping = true;
12402          source += "' +\n__e(" + escapeValue + ") +\n'";
12403        }
12404        if (evaluateValue) {
12405          isEvaluating = true;
12406          source += "';\n" + evaluateValue + ";\n__p += '";
12407        }
12408        if (interpolateValue) {
12409          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12410        }
12411        index = offset + match.length;
12412
12413        // The JS engine embedded in Adobe products needs `match` returned in
12414        // order to produce the correct `offset` value.
12415        return match;
12416      });
12417
12418      source += "';\n";
12419
12420      // If `variable` is not specified wrap a with-statement around the generated
12421      // code to add the data object to the top of the scope chain.
12422      var variable = options.variable;
12423      if (!variable) {
12424        source = 'with (obj) {\n' + source + '\n}\n';
12425      }
12426      // Cleanup code by stripping empty strings.
12427      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12428        .replace(reEmptyStringMiddle, '$1')
12429        .replace(reEmptyStringTrailing, '$1;');
12430
12431      // Frame code as the function body.
12432      source = 'function(' + (variable || 'obj') + ') {\n' +
12433        (variable
12434          ? ''
12435          : 'obj || (obj = {});\n'
12436        ) +
12437        "var __t, __p = ''" +
12438        (isEscaping
12439           ? ', __e = _.escape'
12440           : ''
12441        ) +
12442        (isEvaluating
12443          ? ', __j = Array.prototype.join;\n' +
12444            "function print() { __p += __j.call(arguments, '') }\n"
12445          : ';\n'
12446        ) +
12447        source +
12448        'return __p\n}';
12449
12450      var result = attempt(function() {
12451        return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
12452      });
12453
12454      // Provide the compiled function's source by its `toString` method or
12455      // the `source` property as a convenience for inlining compiled templates.
12456      result.source = source;
12457      if (isError(result)) {
12458        throw result;
12459      }
12460      return result;
12461    }
12462
12463    /**
12464     * Converts `string`, as a whole, to lower case.
12465     *
12466     * @static
12467     * @memberOf _
12468     * @category String
12469     * @param {string} [string=''] The string to convert.
12470     * @returns {string} Returns the lower cased string.
12471     * @example
12472     *
12473     * _.toLower('--Foo-Bar');
12474     * // => '--foo-bar'
12475     *
12476     * _.toLower('fooBar');
12477     * // => 'foobar'
12478     *
12479     * _.toLower('__FOO_BAR__');
12480     * // => '__foo_bar__'
12481     */
12482    function toLower(value) {
12483      return toString(value).toLowerCase();
12484    }
12485
12486    /**
12487     * Converts `string`, as a whole, to upper case.
12488     *
12489     * @static
12490     * @memberOf _
12491     * @category String
12492     * @param {string} [string=''] The string to convert.
12493     * @returns {string} Returns the upper cased string.
12494     * @example
12495     *
12496     * _.toUpper('--foo-bar');
12497     * // => '--FOO-BAR'
12498     *
12499     * _.toUpper('fooBar');
12500     * // => 'FOOBAR'
12501     *
12502     * _.toUpper('__foo_bar__');
12503     * // => '__FOO_BAR__'
12504     */
12505    function toUpper(value) {
12506      return toString(value).toUpperCase();
12507    }
12508
12509    /**
12510     * Removes leading and trailing whitespace or specified characters from `string`.
12511     *
12512     * @static
12513     * @memberOf _
12514     * @category String
12515     * @param {string} [string=''] The string to trim.
12516     * @param {string} [chars=whitespace] The characters to trim.
12517     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12518     * @returns {string} Returns the trimmed string.
12519     * @example
12520     *
12521     * _.trim('  abc  ');
12522     * // => 'abc'
12523     *
12524     * _.trim('-_-abc-_-', '_-');
12525     * // => 'abc'
12526     *
12527     * _.map(['  foo  ', '  bar  '], _.trim);
12528     * // => ['foo', 'bar']
12529     */
12530    function trim(string, chars, guard) {
12531      string = toString(string);
12532      if (!string) {
12533        return string;
12534      }
12535      if (guard || chars === undefined) {
12536        return string.replace(reTrim, '');
12537      }
12538      chars = (chars + '');
12539      if (!chars) {
12540        return string;
12541      }
12542      var strSymbols = stringToArray(string),
12543          chrSymbols = stringToArray(chars);
12544
12545      return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
12546    }
12547
12548    /**
12549     * Removes trailing whitespace or specified characters from `string`.
12550     *
12551     * @static
12552     * @memberOf _
12553     * @category String
12554     * @param {string} [string=''] The string to trim.
12555     * @param {string} [chars=whitespace] The characters to trim.
12556     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12557     * @returns {string} Returns the trimmed string.
12558     * @example
12559     *
12560     * _.trimEnd('  abc  ');
12561     * // => '  abc'
12562     *
12563     * _.trimEnd('-_-abc-_-', '_-');
12564     * // => '-_-abc'
12565     */
12566    function trimEnd(string, chars, guard) {
12567      string = toString(string);
12568      if (!string) {
12569        return string;
12570      }
12571      if (guard || chars === undefined) {
12572        return string.replace(reTrimEnd, '');
12573      }
12574      chars = (chars + '');
12575      if (!chars) {
12576        return string;
12577      }
12578      var strSymbols = stringToArray(string);
12579      return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
12580    }
12581
12582    /**
12583     * Removes leading whitespace or specified characters from `string`.
12584     *
12585     * @static
12586     * @memberOf _
12587     * @category String
12588     * @param {string} [string=''] The string to trim.
12589     * @param {string} [chars=whitespace] The characters to trim.
12590     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12591     * @returns {string} Returns the trimmed string.
12592     * @example
12593     *
12594     * _.trimStart('  abc  ');
12595     * // => 'abc  '
12596     *
12597     * _.trimStart('-_-abc-_-', '_-');
12598     * // => 'abc-_-'
12599     */
12600    function trimStart(string, chars, guard) {
12601      string = toString(string);
12602      if (!string) {
12603        return string;
12604      }
12605      if (guard || chars === undefined) {
12606        return string.replace(reTrimStart, '');
12607      }
12608      chars = (chars + '');
12609      if (!chars) {
12610        return string;
12611      }
12612      var strSymbols = stringToArray(string);
12613      return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
12614    }
12615
12616    /**
12617     * Truncates `string` if it's longer than the given maximum string length.
12618     * The last characters of the truncated string are replaced with the omission
12619     * string which defaults to "...".
12620     *
12621     * @static
12622     * @memberOf _
12623     * @category String
12624     * @param {string} [string=''] The string to truncate.
12625     * @param {Object} [options] The options object.
12626     * @param {number} [options.length=30] The maximum string length.
12627     * @param {string} [options.omission='...'] The string to indicate text is omitted.
12628     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
12629     * @returns {string} Returns the truncated string.
12630     * @example
12631     *
12632     * _.truncate('hi-diddly-ho there, neighborino');
12633     * // => 'hi-diddly-ho there, neighbo...'
12634     *
12635     * _.truncate('hi-diddly-ho there, neighborino', {
12636     *   'length': 24,
12637     *   'separator': ' '
12638     * });
12639     * // => 'hi-diddly-ho there,...'
12640     *
12641     * _.truncate('hi-diddly-ho there, neighborino', {
12642     *   'length': 24,
12643     *   'separator': /,? +/
12644     * });
12645     * // => 'hi-diddly-ho there...'
12646     *
12647     * _.truncate('hi-diddly-ho there, neighborino', {
12648     *   'omission': ' [...]'
12649     * });
12650     * // => 'hi-diddly-ho there, neig [...]'
12651     */
12652    function truncate(string, options) {
12653      var length = DEFAULT_TRUNC_LENGTH,
12654          omission = DEFAULT_TRUNC_OMISSION;
12655
12656      if (isObject(options)) {
12657        var separator = 'separator' in options ? options.separator : separator;
12658        length = 'length' in options ? toInteger(options.length) : length;
12659        omission = 'omission' in options ? toString(options.omission) : omission;
12660      }
12661      string = toString(string);
12662
12663      var strLength = string.length;
12664      if (reHasComplexSymbol.test(string)) {
12665        var strSymbols = stringToArray(string);
12666        strLength = strSymbols.length;
12667      }
12668      if (length >= strLength) {
12669        return string;
12670      }
12671      var end = length - stringSize(omission);
12672      if (end < 1) {
12673        return omission;
12674      }
12675      var result = strSymbols
12676        ? strSymbols.slice(0, end).join('')
12677        : string.slice(0, end);
12678
12679      if (separator === undefined) {
12680        return result + omission;
12681      }
12682      if (strSymbols) {
12683        end += (result.length - end);
12684      }
12685      if (isRegExp(separator)) {
12686        if (string.slice(end).search(separator)) {
12687          var match,
12688              substring = result;
12689
12690          if (!separator.global) {
12691            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
12692          }
12693          separator.lastIndex = 0;
12694          while ((match = separator.exec(substring))) {
12695            var newEnd = match.index;
12696          }
12697          result = result.slice(0, newEnd === undefined ? end : newEnd);
12698        }
12699      } else if (string.indexOf(separator, end) != end) {
12700        var index = result.lastIndexOf(separator);
12701        if (index > -1) {
12702          result = result.slice(0, index);
12703        }
12704      }
12705      return result + omission;
12706    }
12707
12708    /**
12709     * The inverse of `_.escape`; this method converts the HTML entities
12710     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
12711     * corresponding characters.
12712     *
12713     * **Note:** No other HTML entities are unescaped. To unescape additional HTML
12714     * entities use a third-party library like [_he_](https://mths.be/he).
12715     *
12716     * @static
12717     * @memberOf _
12718     * @category String
12719     * @param {string} [string=''] The string to unescape.
12720     * @returns {string} Returns the unescaped string.
12721     * @example
12722     *
12723     * _.unescape('fred, barney, &amp; pebbles');
12724     * // => 'fred, barney, & pebbles'
12725     */
12726    function unescape(string) {
vendor: 4,996 bytes, lines 12727-12889
12727      string = toString(string);
12728      return (string && reHasEscapedHtml.test(string))
12729        ? string.replace(reEscapedHtml, unescapeHtmlChar)
12730        : string;
12731    }
12732
12733    /**
12734     * Converts `string`, as space separated words, to upper case.
12735     *
12736     * @static
12737     * @memberOf _
12738     * @category String
12739     * @param {string} [string=''] The string to convert.
12740     * @returns {string} Returns the upper cased string.
12741     * @example
12742     *
12743     * _.upperCase('--foo-bar');
12744     * // => 'FOO BAR'
12745     *
12746     * _.upperCase('fooBar');
12747     * // => 'FOO BAR'
12748     *
12749     * _.upperCase('__foo_bar__');
12750     * // => 'FOO BAR'
12751     */
12752    var upperCase = createCompounder(function(result, word, index) {
12753      return result + (index ? ' ' : '') + word.toUpperCase();
12754    });
12755
12756    /**
12757     * Splits `string` into an array of its words.
12758     *
12759     * @static
12760     * @memberOf _
12761     * @category String
12762     * @param {string} [string=''] The string to inspect.
12763     * @param {RegExp|string} [pattern] The pattern to match words.
12764     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12765     * @returns {Array} Returns the words of `string`.
12766     * @example
12767     *
12768     * _.words('fred, barney, & pebbles');
12769     * // => ['fred', 'barney', 'pebbles']
12770     *
12771     * _.words('fred, barney, & pebbles', /[^, ]+/g);
12772     * // => ['fred', 'barney', '&', 'pebbles']
12773     */
12774    function words(string, pattern, guard) {
12775      string = toString(string);
12776      pattern = guard ? undefined : pattern;
12777
12778      if (pattern === undefined) {
12779        pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
12780      }
12781      return string.match(pattern) || [];
12782    }
12783
12784    /*------------------------------------------------------------------------*/
12785
12786    /**
12787     * Attempts to invoke `func`, returning either the result or the caught error
12788     * object. Any additional arguments are provided to `func` when it's invoked.
12789     *
12790     * @static
12791     * @memberOf _
12792     * @category Util
12793     * @param {Function} func The function to attempt.
12794     * @returns {*} Returns the `func` result or error object.
12795     * @example
12796     *
12797     * // avoid throwing errors for invalid selectors
12798     * var elements = _.attempt(function(selector) {
12799     *   return document.querySelectorAll(selector);
12800     * }, '>_>');
12801     *
12802     * if (_.isError(elements)) {
12803     *   elements = [];
12804     * }
12805     */
12806    var attempt = rest(function(func, args) {
12807      try {
12808        return apply(func, undefined, args);
12809      } catch (e) {
12810        return isError(e) ? e : new Error(e);
12811      }
12812    });
12813
12814    /**
12815     * Binds methods of an object to the object itself, overwriting the existing
12816     * method.
12817     *
12818     * **Note:** This method doesn't set the "length" property of bound functions.
12819     *
12820     * @static
12821     * @memberOf _
12822     * @category Util
12823     * @param {Object} object The object to bind and assign the bound methods to.
12824     * @param {...(string|string[])} methodNames The object method names to bind,
12825     *  specified individually or in arrays.
12826     * @returns {Object} Returns `object`.
12827     * @example
12828     *
12829     * var view = {
12830     *   'label': 'docs',
12831     *   'onClick': function() {
12832     *     console.log('clicked ' + this.label);
12833     *   }
12834     * };
12835     *
12836     * _.bindAll(view, 'onClick');
12837     * jQuery(element).on('click', view.onClick);
12838     * // => logs 'clicked docs' when clicked
12839     */
12840    var bindAll = rest(function(object, methodNames) {
12841      arrayEach(baseFlatten(methodNames), function(key) {
12842        object[key] = bind(object[key], object);
12843      });
12844      return object;
12845    });
12846
12847    /**
12848     * Creates a function that iterates over `pairs` invoking the corresponding
12849     * function of the first predicate to return truthy. The predicate-function
12850     * pairs are invoked with the `this` binding and arguments of the created
12851     * function.
12852     *
12853     * @static
12854     * @memberOf _
12855     * @category Util
12856     * @param {Array} pairs The predicate-function pairs.
12857     * @returns {Function} Returns the new function.
12858     * @example
12859     *
12860     * var func = _.cond([
12861     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
12862     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
12863     *   [_.constant(true),                _.constant('no match')]
12864     * ]);
12865     *
12866     * func({ 'a': 1, 'b': 2 });
12867     * // => 'matches A'
12868     *
12869     * func({ 'a': 0, 'b': 1 });
12870     * // => 'matches B'
12871     *
12872     * func({ 'a': '1', 'b': '2' });
12873     * // => 'no match'
12874     */
12875    function cond(pairs) {
12876      var length = pairs ? pairs.length : 0,
12877          toIteratee = getIteratee();
12878
12879      pairs = !length ? [] : arrayMap(pairs, function(pair) {
12880        if (typeof pair[1] != 'function') {
12881          throw new TypeError(FUNC_ERROR_TEXT);
12882        }
12883        return [toIteratee(pair[0]), pair[1]];
12884      });
12885
12886      return rest(function(args) {
12887        var index = -1;
12888        while (++index < length) {
12889          var pair = pairs[index];
12890          if (apply(pair[0], this, args)) {
12891            return apply(pair[1], this, args);
12892          }
12893        }
12894      });
12895    }
12896
12897    /**
12898     * Creates a function that invokes the predicate properties of `source` with
12899     * the corresponding property values of a given object, returning `true` if
12900     * all predicates return truthy, else `false`.
12901     *
12902     * @static
12903     * @memberOf _
12904     * @category Util
12905     * @param {Object} source The object of property predicates to conform to.
12906     * @returns {Function} Returns the new function.
12907     * @example
12908     *
12909     * var users = [
12910     *   { 'user': 'barney', 'age': 36 },
12911     *   { 'user': 'fred',   'age': 40 }
12912     * ];
12913     *
12914     * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
12915     * // => [{ 'user': 'fred', 'age': 40 }]
12916     */
12917    function conforms(source) {
12918      return baseConforms(baseClone(source, true));
12919    }
12920
12921    /**
12922     * Creates a function that returns `value`.
12923     *
12924     * @static
12925     * @memberOf _
12926     * @category Util
12927     * @param {*} value The value to return from the new function.
12928     * @returns {Function} Returns the new function.
12929     * @example
12930     *
12931     * var object = { 'user': 'fred' };
12932     * var getter = _.constant(object);
12933     *
12934     * getter() === object;
12935     * // => true
12936     */
12937    function constant(value) {
12938      return function() {
12939        return value;
12940      };
12941    }
12942
12943    /**
12944     * Creates a function that returns the result of invoking the provided
12945     * functions with the `this` binding of the created function, where each
12946     * successive invocation is supplied the return value of the previous.
12947     *
12948     * @static
12949     * @memberOf _
12950     * @category Util
12951     * @param {...(Function|Function[])} [funcs] Functions to invoke.
12952     * @returns {Function} Returns the new function.
12953     * @example
12954     *
12955     * function square(n) {
12956     *   return n * n;
12957     * }
12958     *
12959     * var addSquare = _.flow(_.add, square);
12960     * addSquare(1, 2);
12961     * // => 9
12962     */
12963    var flow = createFlow();
12964
12965    /**
12966     * This method is like `_.flow` except that it creates a function that
12967     * invokes the provided functions from right to left.
12968     *
12969     * @static
12970     * @memberOf _
12971     * @category Util
12972     * @param {...(Function|Function[])} [funcs] Functions to invoke.
12973     * @returns {Function} Returns the new function.
12974     * @example
12975     *
12976     * function square(n) {
12977     *   return n * n;
12978     * }
12979     *
12980     * var addSquare = _.flowRight(square, _.add);
12981     * addSquare(1, 2);
12982     * // => 9
12983     */
12984    var flowRight = createFlow(true);
12985
12986    /**
12987     * This method returns the first argument provided to it.
12988     *
12989     * @static
12990     * @memberOf _
12991     * @category Util
12992     * @param {*} value Any value.
12993     * @returns {*} Returns `value`.
12994     * @example
12995     *
12996     * var object = { 'user': 'fred' };
12997     *
12998     * _.identity(object) === object;
12999     * // => true
13000     */
13001    function identity(value) {
13002      return value;
13003    }
13004
13005    /**
13006     * Creates a function that invokes `func` with the arguments of the created
13007     * function. If `func` is a property name the created callback returns the
13008     * property value for a given element. If `func` is an object the created
13009     * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
13010     *
13011     * @static
13012     * @memberOf _
13013     * @category Util
13014     * @param {*} [func=_.identity] The value to convert to a callback.
13015     * @returns {Function} Returns the callback.
13016     * @example
13017     *
13018     * var users = [
13019     *   { 'user': 'barney', 'age': 36 },
13020     *   { 'user': 'fred',   'age': 40 }
13021     * ];
13022     *
13023     * // create custom iteratee shorthands
13024     * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
13025     *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
13026     *   return !p ? callback(func) : function(object) {
13027     *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
13028     *   };
13029     * });
13030     *
13031     * _.filter(users, 'age > 36');
13032     * // => [{ 'user': 'fred', 'age': 40 }]
13033     */
13034    function iteratee(func) {
13035      return (isObjectLike(func) && !isArray(func))
13036        ? matches(func)
13037        : baseIteratee(func);
13038    }
13039
13040    /**
13041     * Creates a function that performs a deep partial comparison between a given
13042     * object and `source`, returning `true` if the given object has equivalent
13043     * property values, else `false`.
13044     *
13045     * **Note:** This method supports comparing the same values as `_.isEqual`.
13046     *
13047     * @static
13048     * @memberOf _
13049     * @category Util
13050     * @param {Object} source The object of property values to match.
13051     * @returns {Function} Returns the new function.
13052     * @example
13053     *
13054     * var users = [
13055     *   { 'user': 'barney', 'age': 36, 'active': true },
13056     *   { 'user': 'fred',   'age': 40, 'active': false }
13057     * ];
13058     *
13059     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13060     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13061     */
13062    function matches(source) {
13063      return baseMatches(baseClone(source, true));
13064    }
13065
13066    /**
13067     * Creates a function that performs a deep partial comparison between the
13068     * value at `path` of a given object to `srcValue`, returning `true` if the
13069     * object value is equivalent, else `false`.
13070     *
13071     * **Note:** This method supports comparing the same values as `_.isEqual`.
13072     *
13073     * @static
13074     * @memberOf _
13075     * @category Util
13076     * @param {Array|string} path The path of the property to get.
13077     * @param {*} srcValue The value to match.
13078     * @returns {Function} Returns the new function.
13079     * @example
13080     *
13081     * var users = [
13082     *   { 'user': 'barney' },
13083     *   { 'user': 'fred' }
13084     * ];
13085     *
13086     * _.find(users, _.matchesProperty('user', 'fred'));
13087     * // => { 'user': 'fred' }
13088     */
13089    function matchesProperty(path, srcValue) {
13090      return baseMatchesProperty(path, baseClone(srcValue, true));
13091    }
13092
13093    /**
13094     * Creates a function that invokes the method at `path` of a given object.
13095     * Any additional arguments are provided to the invoked method.
13096     *
13097     * @static
13098     * @memberOf _
13099     * @category Util
13100     * @param {Array|string} path The path of the method to invoke.
13101     * @param {...*} [args] The arguments to invoke the method with.
13102     * @returns {Function} Returns the new function.
13103     * @example
13104     *
13105     * var objects = [
13106     *   { 'a': { 'b': { 'c': _.constant(2) } } },
13107     *   { 'a': { 'b': { 'c': _.constant(1) } } }
13108     * ];
13109     *
13110     * _.map(objects, _.method('a.b.c'));
13111     * // => [2, 1]
13112     *
13113     * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13114     * // => [1, 2]
13115     */
13116    var method = rest(function(path, args) {
13117      return function(object) {
13118        return baseInvoke(object, path, args);
13119      };
13120    });
13121
13122    /**
13123     * The opposite of `_.method`; this method creates a function that invokes
13124     * the method at a given path of `object`. Any additional arguments are
13125     * provided to the invoked method.
13126     *
13127     * @static
13128     * @memberOf _
13129     * @category Util
13130     * @param {Object} object The object to query.
13131     * @param {...*} [args] The arguments to invoke the method with.
13132     * @returns {Function} Returns the new function.
13133     * @example
13134     *
13135     * var array = _.times(3, _.constant),
13136     *     object = { 'a': array, 'b': array, 'c': array };
13137     *
13138     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13139     * // => [2, 0]
13140     *
13141     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13142     * // => [2, 0]
13143     */
13144    var methodOf = rest(function(object, args) {
13145      return function(path) {
13146        return baseInvoke(object, path, args);
13147      };
13148    });
13149
13150    /**
13151     * Adds all own enumerable function properties of a source object to the
13152     * destination object. If `object` is a function then methods are added to
13153     * its prototype as well.
13154     *
13155     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13156     * avoid conflicts caused by modifying the original.
13157     *
13158     * @static
13159     * @memberOf _
13160     * @category Util
13161     * @param {Function|Object} [object=lodash] The destination object.
13162     * @param {Object} source The object of functions to add.
13163     * @param {Object} [options] The options object.
13164     * @param {boolean} [options.chain=true] Specify whether the functions added
13165     *  are chainable.
13166     * @returns {Function|Object} Returns `object`.
13167     * @example
13168     *
13169     * function vowels(string) {
13170     *   return _.filter(string, function(v) {
13171     *     return /[aeiou]/i.test(v);
13172     *   });
13173     * }
13174     *
13175     * _.mixin({ 'vowels': vowels });
13176     * _.vowels('fred');
13177     * // => ['e']
13178     *
vendor: 9,000 bytes, lines 13179-13512
13179     * _('fred').vowels().value();
13180     * // => ['e']
13181     *
13182     * _.mixin({ 'vowels': vowels }, { 'chain': false });
13183     * _('fred').vowels();
13184     * // => ['e']
13185     */
13186    function mixin(object, source, options) {
13187      var props = keys(source),
13188          methodNames = baseFunctions(source, props);
13189
13190      if (options == null &&
13191          !(isObject(source) && (methodNames.length || !props.length))) {
13192        options = source;
13193        source = object;
13194        object = this;
13195        methodNames = baseFunctions(source, keys(source));
13196      }
13197      var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13198          isFunc = isFunction(object);
13199
13200      arrayEach(methodNames, function(methodName) {
13201        var func = source[methodName];
13202        object[methodName] = func;
13203        if (isFunc) {
13204          object.prototype[methodName] = function() {
13205            var chainAll = this.__chain__;
13206            if (chain || chainAll) {
13207              var result = object(this.__wrapped__),
13208                  actions = result.__actions__ = copyArray(this.__actions__);
13209
13210              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13211              result.__chain__ = chainAll;
13212              return result;
13213            }
13214            return func.apply(object, arrayPush([this.value()], arguments));
13215          };
13216        }
13217      });
13218
13219      return object;
13220    }
13221
13222    /**
13223     * Reverts the `_` variable to its previous value and returns a reference to
13224     * the `lodash` function.
13225     *
13226     * @static
13227     * @memberOf _
13228     * @category Util
13229     * @returns {Function} Returns the `lodash` function.
13230     * @example
13231     *
13232     * var lodash = _.noConflict();
13233     */
13234    function noConflict() {
13235      if (root._ === this) {
13236        root._ = oldDash;
13237      }
13238      return this;
13239    }
13240
13241    /**
13242     * A no-operation function that returns `undefined` regardless of the
13243     * arguments it receives.
13244     *
13245     * @static
13246     * @memberOf _
13247     * @category Util
13248     * @example
13249     *
13250     * var object = { 'user': 'fred' };
13251     *
13252     * _.noop(object) === undefined;
13253     * // => true
13254     */
13255    function noop() {
13256      // No operation performed.
13257    }
13258
13259    /**
13260     * Creates a function that returns its nth argument.
13261     *
13262     * @static
13263     * @memberOf _
13264     * @category Util
13265     * @param {number} [n=0] The index of the argument to return.
13266     * @returns {Function} Returns the new function.
13267     * @example
13268     *
13269     * var func = _.nthArg(1);
13270     *
13271     * func('a', 'b', 'c');
13272     * // => 'b'
13273     */
13274    function nthArg(n) {
13275      n = toInteger(n);
13276      return function() {
13277        return arguments[n];
13278      };
13279    }
13280
13281    /**
13282     * Creates a function that invokes `iteratees` with the arguments provided
13283     * to the created function and returns their results.
13284     *
13285     * @static
13286     * @memberOf _
13287     * @category Util
13288     * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13289     * @returns {Function} Returns the new function.
13290     * @example
13291     *
13292     * var func = _.over(Math.max, Math.min);
13293     *
13294     * func(1, 2, 3, 4);
13295     * // => [4, 1]
13296     */
13297    var over = createOver(arrayMap);
13298
13299    /**
13300     * Creates a function that checks if **all** of the `predicates` return
13301     * truthy when invoked with the arguments provided to the created function.
13302     *
13303     * @static
13304     * @memberOf _
13305     * @category Util
13306     * @param {...(Function|Function[])} predicates The predicates to check.
13307     * @returns {Function} Returns the new function.
13308     * @example
13309     *
13310     * var func = _.overEvery(Boolean, isFinite);
13311     *
13312     * func('1');
13313     * // => true
13314     *
13315     * func(null);
13316     * // => false
13317     *
13318     * func(NaN);
13319     * // => false
13320     */
13321    var overEvery = createOver(arrayEvery);
13322
13323    /**
13324     * Creates a function that checks if **any** of the `predicates` return
13325     * truthy when invoked with the arguments provided to the created function.
13326     *
13327     * @static
13328     * @memberOf _
13329     * @category Util
13330     * @param {...(Function|Function[])} predicates The predicates to check.
13331     * @returns {Function} Returns the new function.
13332     * @example
13333     *
13334     * var func = _.overSome(Boolean, isFinite);
13335     *
13336     * func('1');
13337     * // => true
13338     *
13339     * func(null);
13340     * // => true
13341     *
13342     * func(NaN);
13343     * // => false
13344     */
13345    var overSome = createOver(arraySome);
13346
13347    /**
13348     * Creates a function that returns the value at `path` of a given object.
13349     *
13350     * @static
13351     * @memberOf _
13352     * @category Util
13353     * @param {Array|string} path The path of the property to get.
13354     * @returns {Function} Returns the new function.
13355     * @example
13356     *
13357     * var objects = [
13358     *   { 'a': { 'b': { 'c': 2 } } },
13359     *   { 'a': { 'b': { 'c': 1 } } }
13360     * ];
13361     *
13362     * _.map(objects, _.property('a.b.c'));
13363     * // => [2, 1]
13364     *
13365     * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13366     * // => [1, 2]
13367     */
13368    function property(path) {
13369      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13370    }
13371
13372    /**
13373     * The opposite of `_.property`; this method creates a function that returns
13374     * the value at a given path of `object`.
13375     *
13376     * @static
13377     * @memberOf _
13378     * @category Util
13379     * @param {Object} object The object to query.
13380     * @returns {Function} Returns the new function.
13381     * @example
13382     *
13383     * var array = [0, 1, 2],
13384     *     object = { 'a': array, 'b': array, 'c': array };
13385     *
13386     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13387     * // => [2, 0]
13388     *
13389     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13390     * // => [2, 0]
13391     */
13392    function propertyOf(object) {
13393      return function(path) {
13394        return object == null ? undefined : baseGet(object, path);
13395      };
13396    }
13397
13398    /**
13399     * Creates an array of numbers (positive and/or negative) progressing from
13400     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13401     * `start` is specified without an `end` or `step`. If `end` is not specified
13402     * it's set to `start` with `start` then set to `0`.
13403     *
13404     * **Note:** JavaScript follows the IEEE-754 standard for resolving
13405     * floating-point values which can produce unexpected results.
13406     *
13407     * @static
13408     * @memberOf _
13409     * @category Util
13410     * @param {number} [start=0] The start of the range.
13411     * @param {number} end The end of the range.
13412     * @param {number} [step=1] The value to increment or decrement by.
13413     * @returns {Array} Returns the new array of numbers.
13414     * @example
13415     *
13416     * _.range(4);
13417     * // => [0, 1, 2, 3]
13418     *
13419     * _.range(-4);
13420     * // => [0, -1, -2, -3]
13421     *
13422     * _.range(1, 5);
13423     * // => [1, 2, 3, 4]
13424     *
13425     * _.range(0, 20, 5);
13426     * // => [0, 5, 10, 15]
13427     *
13428     * _.range(0, -4, -1);
13429     * // => [0, -1, -2, -3]
13430     *
13431     * _.range(1, 4, 0);
13432     * // => [1, 1, 1]
13433     *
13434     * _.range(0);
13435     * // => []
13436     */
13437    var range = createRange();
13438
13439    /**
13440     * This method is like `_.range` except that it populates values in
13441     * descending order.
13442     *
13443     * @static
13444     * @memberOf _
13445     * @category Util
13446     * @param {number} [start=0] The start of the range.
13447     * @param {number} end The end of the range.
13448     * @param {number} [step=1] The value to increment or decrement by.
13449     * @returns {Array} Returns the new array of numbers.
13450     * @example
13451     *
13452     * _.rangeRight(4);
13453     * // => [3, 2, 1, 0]
13454     *
13455     * _.rangeRight(-4);
13456     * // => [-3, -2, -1, 0]
13457     *
13458     * _.rangeRight(1, 5);
13459     * // => [4, 3, 2, 1]
13460     *
13461     * _.rangeRight(0, 20, 5);
13462     * // => [15, 10, 5, 0]
13463     *
13464     * _.rangeRight(0, -4, -1);
13465     * // => [-3, -2, -1, 0]
13466     *
13467     * _.rangeRight(1, 4, 0);
13468     * // => [1, 1, 1]
13469     *
13470     * _.rangeRight(0);
13471     * // => []
13472     */
13473    var rangeRight = createRange(true);
13474
13475    /**
13476     * Invokes the iteratee function `n` times, returning an array of the results
13477     * of each invocation. The iteratee is invoked with one argument; (index).
13478     *
13479     * @static
13480     * @memberOf _
13481     * @category Util
13482     * @param {number} n The number of times to invoke `iteratee`.
13483     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13484     * @returns {Array} Returns the array of results.
13485     * @example
13486     *
13487     * _.times(3, String);
13488     * // => ['0', '1', '2']
13489     *
13490     *  _.times(4, _.constant(true));
13491     * // => [true, true, true, true]
13492     */
13493    function times(n, iteratee) {
13494      n = toInteger(n);
13495      if (n < 1 || n > MAX_SAFE_INTEGER) {
13496        return [];
13497      }
13498      var index = MAX_ARRAY_LENGTH,
13499          length = nativeMin(n, MAX_ARRAY_LENGTH);
13500
13501      iteratee = toFunction(iteratee);
13502      n -= MAX_ARRAY_LENGTH;
13503
13504      var result = baseTimes(length, iteratee);
13505      while (++index < n) {
13506        iteratee(index);
13507      }
13508      return result;
13509    }
13510
13511    /**
13512     * Converts `value` to a property path array.
13513     *
13514     * @static
13515     * @memberOf _
13516     * @category Util
13517     * @param {*} value The value to convert.
13518     * @returns {Array} Returns the new property path array.
13519     * @example
13520     *
13521     * _.toPath('a.b.c');
13522     * // => ['a', 'b', 'c']
13523     *
13524     * _.toPath('a[0].b.c');
13525     * // => ['a', '0', 'b', 'c']
13526     *
13527     * var path = ['a', 'b', 'c'],
13528     *     newPath = _.toPath(path);
13529     *
13530     * console.log(newPath);
13531     * // => ['a', 'b', 'c']
13532     *
13533     * console.log(path === newPath);
13534     * // => false
13535     */
13536    function toPath(value) {
13537      return isArray(value) ? arrayMap(value, String) : stringToPath(value);
13538    }
13539
13540    /**
13541     * Generates a unique ID. If `prefix` is provided the ID is appended to it.
13542     *
13543     * @static
13544     * @memberOf _
13545     * @category Util
13546     * @param {string} [prefix] The value to prefix the ID with.
13547     * @returns {string} Returns the unique ID.
13548     * @example
13549     *
13550     * _.uniqueId('contact_');
13551     * // => 'contact_104'
13552     *
13553     * _.uniqueId();
13554     * // => '105'
13555     */
13556    function uniqueId(prefix) {
13557      var id = ++idCounter;
13558      return toString(prefix) + id;
13559    }
13560
13561    /*------------------------------------------------------------------------*/
13562
13563    /**
13564     * Adds two numbers.
13565     *
13566     * @static
13567     * @memberOf _
13568     * @category Math
13569     * @param {number} augend The first number in an addition.
13570     * @param {number} addend The second number in an addition.
13571     * @returns {number} Returns the total.
13572     * @example
13573     *
13574     * _.add(6, 4);
13575     * // => 10
13576     */
13577    function add(augend, addend) {
13578      var result;
13579      if (augend !== undefined) {
13580        result = augend;
13581      }
13582      if (addend !== undefined) {
13583        result = result === undefined ? addend : (result + addend);
13584      }
13585      return result;
13586    }
13587
13588    /**
13589     * Computes `number` rounded up to `precision`.
13590     *
13591     * @static
13592     * @memberOf _
13593     * @category Math
13594     * @param {number} number The number to round up.
13595     * @param {number} [precision=0] The precision to round up to.
13596     * @returns {number} Returns the rounded up number.
13597     * @example
13598     *
13599     * _.ceil(4.006);
13600     * // => 5
13601     *
13602     * _.ceil(6.004, 2);
13603     * // => 6.01
13604     *
13605     * _.ceil(6040, -2);
13606     * // => 6100
13607     */
13608    var ceil = createRound('ceil');
13609
13610    /**
13611     * Computes `number` rounded down to `precision`.
13612     *
13613     * @static
13614     * @memberOf _
13615     * @category Math
13616     * @param {number} number The number to round down.
13617     * @param {number} [precision=0] The precision to round down to.
13618     * @returns {number} Returns the rounded down number.
13619     * @example
13620     *
13621     * _.floor(4.006);
13622     * // => 4
13623     *
13624     * _.floor(0.046, 2);
13625     * // => 0.04
13626     *
13627     * _.floor(4060, -2);
13628     * // => 4000
13629     */
13630    var floor = createRound('floor');
13631
13632    /**
13633     * Computes the maximum value of `array`. If `array` is empty or falsey
13634     * `undefined` is returned.
13635     *
13636     * @static
13637     * @memberOf _
13638     * @category Math
13639     * @param {Array} array The array to iterate over.
13640     * @returns {*} Returns the maximum value.
13641     * @example
13642     *
13643     * _.max([4, 2, 8, 6]);
13644     * // => 8
13645     *
13646     * _.max([]);
13647     * // => undefined
13648     */
13649    function max(array) {
13650      return (array && array.length)
13651        ? baseExtremum(array, identity, gt)
13652        : undefined;
13653    }
13654
13655    /**
13656     * This method is like `_.max` except that it accepts `iteratee` which is
13657     * invoked for each element in `array` to generate the criterion by which
13658     * the value is ranked. The iteratee is invoked with one argument: (value).
13659     *
13660     * @static
13661     * @memberOf _
13662     * @category Math
13663     * @param {Array} array The array to iterate over.
13664     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13665     * @returns {*} Returns the maximum value.
13666     * @example
13667     *
13668     * var objects = [{ 'n': 1 }, { 'n': 2 }];
13669     *
13670     * _.maxBy(objects, function(o) { return o.n; });
13671     * // => { 'n': 2 }
13672     *
13673     * // using the `_.property` iteratee shorthand
13674     * _.maxBy(objects, 'n');
13675     * // => { 'n': 2 }
13676     */
13677    function maxBy(array, iteratee) {
13678      return (array && array.length)
13679        ? baseExtremum(array, getIteratee(iteratee), gt)
13680        : undefined;
13681    }
13682
13683    /**
13684     * Computes the mean of the values in `array`.
13685     *
13686     * @static
13687     * @memberOf _
13688     * @category Math
13689     * @param {Array} array The array to iterate over.
13690     * @returns {number} Returns the mean.
13691     * @example
13692     *
13693     * _.mean([4, 2, 8, 6]);
13694     * // => 5
13695     */
13696    function mean(array) {
13697      return sum(array) / (array ? array.length : 0);
13698    }
13699
13700    /**
13701     * Computes the minimum value of `array`. If `array` is empty or falsey
13702     * `undefined` is returned.
13703     *
13704     * @static
13705     * @memberOf _
13706     * @category Math
13707     * @param {Array} array The array to iterate over.
13708     * @returns {*} Returns the minimum value.
13709     * @example
13710     *
13711     * _.min([4, 2, 8, 6]);
13712     * // => 2
13713     *
13714     * _.min([]);
13715     * // => undefined
13716     */
13717    function min(array) {
13718      return (array && array.length)
13719        ? baseExtremum(array, identity, lt)
13720        : undefined;
13721    }
13722
13723    /**
13724     * This method is like `_.min` except that it accepts `iteratee` which is
13725     * invoked for each element in `array` to generate the criterion by which
13726     * the value is ranked. The iteratee is invoked with one argument: (value).
13727     *
13728     * @static
13729     * @memberOf _
13730     * @category Math
13731     * @param {Array} array The array to iterate over.
13732     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13733     * @returns {*} Returns the minimum value.
13734     * @example
13735     *
13736     * var objects = [{ 'n': 1 }, { 'n': 2 }];
13737     *
13738     * _.minBy(objects, function(o) { return o.n; });
13739     * // => { 'n': 1 }
13740     *
13741     * // using the `_.property` iteratee shorthand
13742     * _.minBy(objects, 'n');
13743     * // => { 'n': 1 }
13744     */
13745    function minBy(array, iteratee) {
13746      return (array && array.length)
13747        ? baseExtremum(array, getIteratee(iteratee), lt)
13748        : undefined;
13749    }
13750
13751    /**
13752     * Computes `number` rounded to `precision`.
13753     *
13754     * @static
13755     * @memberOf _
13756     * @category Math
13757     * @param {number} number The number to round.
13758     * @param {number} [precision=0] The precision to round to.
13759     * @returns {number} Returns the rounded number.
13760     * @example
13761     *
13762     * _.round(4.006);
13763     * // => 4
13764     *
13765     * _.round(4.006, 2);
13766     * // => 4.01
13767     *
13768     * _.round(4060, -2);
13769     * // => 4100
13770     */
13771    var round = createRound('round');
13772
13773    /**
13774     * Subtract two numbers.
13775     *
13776     * @static
13777     * @memberOf _
13778     * @category Math
13779     * @param {number} minuend The first number in a subtraction.
13780     * @param {number} subtrahend The second number in a subtraction.
13781     * @returns {number} Returns the difference.
13782     * @example
13783     *
13784     * _.subtract(6, 4);
13785     * // => 2
13786     */
13787    function subtract(minuend, subtrahend) {
13788      var result;
13789      if (minuend !== undefined) {
13790        result = minuend;
13791      }
13792      if (subtrahend !== undefined) {
13793        result = result === undefined ? subtrahend : (result - subtrahend);
13794      }
13795      return result;
13796    }
13797
13798    /**
13799     * Computes the sum of the values in `array`.
13800     *
13801     * @static
13802     * @memberOf _
13803     * @category Math
13804     * @param {Array} array The array to iterate over.
13805     * @returns {number} Returns the sum.
13806     * @example
13807     *
13808     * _.sum([4, 2, 8, 6]);
13809     * // => 20
13810     */
13811    function sum(array) {
13812      return (array && array.length)
13813        ? baseSum(array, identity)
13814        : undefined;
13815    }
13816
13817    /**
13818     * This method is like `_.sum` except that it accepts `iteratee` which is
13819     * invoked for each element in `array` to generate the value to be summed.
13820     * The iteratee is invoked with one argument: (value).
13821     *
13822     * @static
13823     * @memberOf _
13824     * @category Math
13825     * @param {Array} array The array to iterate over.
13826     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13827     * @returns {number} Returns the sum.
13828     * @example
13829     *
13830     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
13831     *
13832     * _.sumBy(objects, function(o) { return o.n; });
13833     * // => 20
13834     *
13835     * // using the `_.property` iteratee shorthand
13836     * _.sumBy(objects, 'n');
13837     * // => 20
13838     */
13839    function sumBy(array, iteratee) {
13840      return (array && array.length)
13841        ? baseSum(array, getIteratee(iteratee))
13842        : undefined;
13843    }
13844
13845    /*------------------------------------------------------------------------*/
13846
13847    // Ensure wrappers are instances of `baseLodash`.
13848    lodash.prototype = baseLodash.prototype;
13849
13850    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
13851    LodashWrapper.prototype.constructor = LodashWrapper;
13852
13853    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
13854    LazyWrapper.prototype.constructor = LazyWrapper;
13855
13856    // Avoid inheriting from `Object.prototype` when possible.
13857    Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
13858
13859    // Add functions to the `MapCache`.
13860    MapCache.prototype.clear = mapClear;
13861    MapCache.prototype['delete'] = mapDelete;
13862    MapCache.prototype.get = mapGet;
13863    MapCache.prototype.has = mapHas;
13864    MapCache.prototype.set = mapSet;
13865
13866    // Add functions to the `SetCache`.
13867    SetCache.prototype.push = cachePush;
13868
13869    // Add functions to the `Stack` cache.
13870    Stack.prototype.clear = stackClear;
13871    Stack.prototype['delete'] = stackDelete;
13872    Stack.prototype.get = stackGet;
13873    Stack.prototype.has = stackHas;
13874    Stack.prototype.set = stackSet;
13875
13876    // Assign cache to `_.memoize`.
13877    memoize.Cache = MapCache;
13878
13879    // Add functions that return wrapped values when chaining.
13880    lodash.after = after;
13881    lodash.ary = ary;
13882    lodash.assign = assign;
13883    lodash.assignIn = assignIn;
13884    lodash.assignInWith = assignInWith;
13885    lodash.assignWith = assignWith;
13886    lodash.at = at;
13887    lodash.before = before;
13888    lodash.bind = bind;
13889    lodash.bindAll = bindAll;
13890    lodash.bindKey = bindKey;
13891    lodash.chain = chain;
13892    lodash.chunk = chunk;
13893    lodash.compact = compact;
13894    lodash.concat = concat;
13895    lodash.cond = cond;
13896    lodash.conforms = conforms;
13897    lodash.constant = constant;
13898    lodash.countBy = countBy;
13899    lodash.create = create;
13900    lodash.curry = curry;
13901    lodash.curryRight = curryRight;
13902    lodash.debounce = debounce;
13903    lodash.defaults = defaults;
13904    lodash.defaultsDeep = defaultsDeep;
13905    lodash.defer = defer;
13906    lodash.delay = delay;
13907    lodash.difference = difference;
13908    lodash.differenceBy = differenceBy;
13909    lodash.differenceWith = differenceWith;
13910    lodash.drop = drop;
13911    lodash.dropRight = dropRight;
13912    lodash.dropRightWhile = dropRightWhile;
13913    lodash.dropWhile = dropWhile;
13914    lodash.fill = fill;
13915    lodash.filter = filter;
13916    lodash.flatMap = flatMap;
13917    lodash.flatten = flatten;
13918    lodash.flattenDeep = flattenDeep;
13919    lodash.flip = flip;
13920    lodash.flow = flow;
13921    lodash.flowRight = flowRight;
13922    lodash.fromPairs = fromPairs;
13923    lodash.functions = functions;
13924    lodash.functionsIn = functionsIn;
13925    lodash.groupBy = groupBy;
13926    lodash.initial = initial;
13927    lodash.intersection = intersection;
13928    lodash.intersectionBy = intersectionBy;
13929    lodash.intersectionWith = intersectionWith;
13930    lodash.invert = invert;
13931    lodash.invokeMap = invokeMap;
13932    lodash.iteratee = iteratee;
13933    lodash.keyBy = keyBy;
13934    lodash.keys = keys;
13935    lodash.keysIn = keysIn;
13936    lodash.map = map;
13937    lodash.mapKeys = mapKeys;
13938    lodash.mapValues = mapValues;
13939    lodash.matches = matches;
13940    lodash.matchesProperty = matchesProperty;
13941    lodash.memoize = memoize;
13942    lodash.merge = merge;
13943    lodash.mergeWith = mergeWith;
13944    lodash.method = method;
13945    lodash.methodOf = methodOf;
13946    lodash.mixin = mixin;
13947    lodash.negate = negate;
13948    lodash.nthArg = nthArg;
13949    lodash.omit = omit;
13950    lodash.omitBy = omitBy;
13951    lodash.once = once;
13952    lodash.orderBy = orderBy;
13953    lodash.over = over;
13954    lodash.overArgs = overArgs;
13955    lodash.overEvery = overEvery;
13956    lodash.overSome = overSome;
13957    lodash.partial = partial;
13958    lodash.partialRight = partialRight;
13959    lodash.partition = partition;
13960    lodash.pick = pick;
13961    lodash.pickBy = pickBy;
13962    lodash.property = property;
13963    lodash.propertyOf = propertyOf;
13964    lodash.pull = pull;
13965    lodash.pullAll = pullAll;
13966    lodash.pullAllBy = pullAllBy;
13967    lodash.pullAt = pullAt;
13968    lodash.range = range;
13969    lodash.rangeRight = rangeRight;
13970    lodash.rearg = rearg;
13971    lodash.reject = reject;
13972    lodash.remove = remove;
13973    lodash.rest = rest;
13974    lodash.reverse = reverse;
13975    lodash.sampleSize = sampleSize;
13976    lodash.set = set;
13977    lodash.setWith = setWith;
13978    lodash.shuffle = shuffle;
13979    lodash.slice = slice;
13980    lodash.sortBy = sortBy;
13981    lodash.sortedUniq = sortedUniq;
13982    lodash.sortedUniqBy = sortedUniqBy;
13983    lodash.split = split;
13984    lodash.spread = spread;
13985    lodash.tail = tail;
13986    lodash.take = take;
13987    lodash.takeRight = takeRight;
13988    lodash.takeRightWhile = takeRightWhile;
13989    lodash.takeWhile = takeWhile;
13990    lodash.tap = tap;
13991    lodash.throttle = throttle;
13992    lodash.thru = thru;
13993    lodash.toArray = toArray;
13994    lodash.toPairs = toPairs;
13995    lodash.toPairsIn = toPairsIn;
13996    lodash.toPath = toPath;
13997    lodash.toPlainObject = toPlainObject;
13998    lodash.transform = transform;
13999    lodash.unary = unary;
14000    lodash.union = union;
14001    lodash.unionBy = unionBy;
14002    lodash.unionWith = unionWith;
14003    lodash.uniq = uniq;
14004    lodash.uniqBy = uniqBy;
14005    lodash.uniqWith = uniqWith;
14006    lodash.unset = unset;
14007    lodash.unzip = unzip;
14008    lodash.unzipWith = unzipWith;
14009    lodash.values = values;
14010    lodash.valuesIn = valuesIn;
14011    lodash.without = without;
14012    lodash.words = words;
14013    lodash.wrap = wrap;
14014    lodash.xor = xor;
14015    lodash.xorBy = xorBy;
14016    lodash.xorWith = xorWith;
14017    lodash.zip = zip;
14018    lodash.zipObject = zipObject;
14019    lodash.zipWith = zipWith;
14020
14021    // Add aliases.
14022    lodash.extend = assignIn;
14023    lodash.extendWith = assignInWith;
14024
14025    // Add functions to `lodash.prototype`.
14026    mixin(lodash, lodash);
14027
14028    /*------------------------------------------------------------------------*/
14029
14030    // Add functions that return unwrapped values when chaining.
14031    lodash.add = add;
14032    lodash.attempt = attempt;
14033    lodash.camelCase = camelCase;
14034    lodash.capitalize = capitalize;
14035    lodash.ceil = ceil;
14036    lodash.clamp = clamp;
14037    lodash.clone = clone;
14038    lodash.cloneDeep = cloneDeep;
14039    lodash.cloneDeepWith = cloneDeepWith;
14040    lodash.cloneWith = cloneWith;
14041    lodash.deburr = deburr;
14042    lodash.endsWith = endsWith;
14043    lodash.eq = eq;
14044    lodash.escape = escape;
14045    lodash.escapeRegExp = escapeRegExp;
14046    lodash.every = every;
14047    lodash.find = find;
14048    lodash.findIndex = findIndex;
14049    lodash.findKey = findKey;
14050    lodash.findLast = findLast;
14051    lodash.findLastIndex = findLastIndex;
14052    lodash.findLastKey = findLastKey;
14053    lodash.floor = floor;
vendor: 8,916 bytes, lines 14054-14327
14054    lodash.forEach = forEach;
14055    lodash.forEachRight = forEachRight;
14056    lodash.forIn = forIn;
14057    lodash.forInRight = forInRight;
14058    lodash.forOwn = forOwn;
14059    lodash.forOwnRight = forOwnRight;
14060    lodash.get = get;
14061    lodash.gt = gt;
14062    lodash.gte = gte;
14063    lodash.has = has;
14064    lodash.hasIn = hasIn;
14065    lodash.head = head;
14066    lodash.identity = identity;
14067    lodash.includes = includes;
14068    lodash.indexOf = indexOf;
14069    lodash.inRange = inRange;
14070    lodash.invoke = invoke;
14071    lodash.isArguments = isArguments;
14072    lodash.isArray = isArray;
14073    lodash.isArrayLike = isArrayLike;
14074    lodash.isArrayLikeObject = isArrayLikeObject;
14075    lodash.isBoolean = isBoolean;
14076    lodash.isDate = isDate;
14077    lodash.isElement = isElement;
14078    lodash.isEmpty = isEmpty;
14079    lodash.isEqual = isEqual;
14080    lodash.isEqualWith = isEqualWith;
14081    lodash.isError = isError;
14082    lodash.isFinite = isFinite;
14083    lodash.isFunction = isFunction;
14084    lodash.isInteger = isInteger;
14085    lodash.isLength = isLength;
14086    lodash.isMatch = isMatch;
14087    lodash.isMatchWith = isMatchWith;
14088    lodash.isNaN = isNaN;
14089    lodash.isNative = isNative;
14090    lodash.isNil = isNil;
14091    lodash.isNull = isNull;
14092    lodash.isNumber = isNumber;
14093    lodash.isObject = isObject;
14094    lodash.isObjectLike = isObjectLike;
14095    lodash.isPlainObject = isPlainObject;
14096    lodash.isRegExp = isRegExp;
14097    lodash.isSafeInteger = isSafeInteger;
14098    lodash.isString = isString;
14099    lodash.isSymbol = isSymbol;
14100    lodash.isTypedArray = isTypedArray;
14101    lodash.isUndefined = isUndefined;
14102    lodash.join = join;
14103    lodash.kebabCase = kebabCase;
14104    lodash.last = last;
14105    lodash.lastIndexOf = lastIndexOf;
14106    lodash.lowerCase = lowerCase;
14107    lodash.lowerFirst = lowerFirst;
14108    lodash.lt = lt;
14109    lodash.lte = lte;
14110    lodash.max = max;
14111    lodash.maxBy = maxBy;
14112    lodash.mean = mean;
14113    lodash.min = min;
14114    lodash.minBy = minBy;
14115    lodash.noConflict = noConflict;
14116    lodash.noop = noop;
14117    lodash.now = now;
14118    lodash.pad = pad;
14119    lodash.padEnd = padEnd;
14120    lodash.padStart = padStart;
14121    lodash.parseInt = parseInt;
14122    lodash.random = random;
14123    lodash.reduce = reduce;
14124    lodash.reduceRight = reduceRight;
14125    lodash.repeat = repeat;
14126    lodash.replace = replace;
14127    lodash.result = result;
14128    lodash.round = round;
14129    lodash.runInContext = runInContext;
14130    lodash.sample = sample;
14131    lodash.size = size;
14132    lodash.snakeCase = snakeCase;
14133    lodash.some = some;
14134    lodash.sortedIndex = sortedIndex;
14135    lodash.sortedIndexBy = sortedIndexBy;
14136    lodash.sortedIndexOf = sortedIndexOf;
14137    lodash.sortedLastIndex = sortedLastIndex;
14138    lodash.sortedLastIndexBy = sortedLastIndexBy;
14139    lodash.sortedLastIndexOf = sortedLastIndexOf;
14140    lodash.startCase = startCase;
14141    lodash.startsWith = startsWith;
14142    lodash.subtract = subtract;
14143    lodash.sum = sum;
14144    lodash.sumBy = sumBy;
14145    lodash.template = template;
14146    lodash.times = times;
14147    lodash.toInteger = toInteger;
14148    lodash.toLength = toLength;
14149    lodash.toLower = toLower;
14150    lodash.toNumber = toNumber;
14151    lodash.toSafeInteger = toSafeInteger;
14152    lodash.toString = toString;
14153    lodash.toUpper = toUpper;
14154    lodash.trim = trim;
14155    lodash.trimEnd = trimEnd;
14156    lodash.trimStart = trimStart;
14157    lodash.truncate = truncate;
14158    lodash.unescape = unescape;
14159    lodash.uniqueId = uniqueId;
14160    lodash.upperCase = upperCase;
14161    lodash.upperFirst = upperFirst;
14162
14163    // Add aliases.
14164    lodash.each = forEach;
14165    lodash.eachRight = forEachRight;
14166    lodash.first = head;
14167
14168    mixin(lodash, (function() {
14169      var source = {};
14170      baseForOwn(lodash, function(func, methodName) {
14171        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14172          source[methodName] = func;
14173        }
14174      });
14175      return source;
14176    }()), { 'chain': false });
14177
14178    /*------------------------------------------------------------------------*/
14179
14180    /**
14181     * The semantic version number.
14182     *
14183     * @static
14184     * @memberOf _
14185     * @type string
14186     */
14187    lodash.VERSION = VERSION;
14188
14189    // Assign default placeholders.
14190    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14191      lodash[methodName].placeholder = lodash;
14192    });
14193
14194    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14195    arrayEach(['drop', 'take'], function(methodName, index) {
14196      LazyWrapper.prototype[methodName] = function(n) {
14197        var filtered = this.__filtered__;
14198        if (filtered && !index) {
14199          return new LazyWrapper(this);
14200        }
14201        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14202
14203        var result = this.clone();
14204        if (filtered) {
14205          result.__takeCount__ = nativeMin(n, result.__takeCount__);
14206        } else {
14207          result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
14208        }
14209        return result;
14210      };
14211
14212      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14213        return this.reverse()[methodName](n).reverse();
14214      };
14215    });
14216
14217    // Add `LazyWrapper` methods that accept an `iteratee` value.
14218    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14219      var type = index + 1,
14220          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14221
14222      LazyWrapper.prototype[methodName] = function(iteratee) {
14223        var result = this.clone();
14224        result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type });
14225        result.__filtered__ = result.__filtered__ || isFilter;
14226        return result;
14227      };
14228    });
14229
14230    // Add `LazyWrapper` methods for `_.head` and `_.last`.
14231    arrayEach(['head', 'last'], function(methodName, index) {
14232      var takeName = 'take' + (index ? 'Right' : '');
14233
14234      LazyWrapper.prototype[methodName] = function() {
14235        return this[takeName](1).value()[0];
14236      };
14237    });
14238
14239    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14240    arrayEach(['initial', 'tail'], function(methodName, index) {
14241      var dropName = 'drop' + (index ? '' : 'Right');
14242
14243      LazyWrapper.prototype[methodName] = function() {
14244        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14245      };
14246    });
14247
14248    LazyWrapper.prototype.compact = function() {
14249      return this.filter(identity);
14250    };
14251
14252    LazyWrapper.prototype.find = function(predicate) {
14253      return this.filter(predicate).head();
14254    };
14255
14256    LazyWrapper.prototype.findLast = function(predicate) {
14257      return this.reverse().find(predicate);
14258    };
14259
14260    LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14261      if (typeof path == 'function') {
14262        return new LazyWrapper(this);
14263      }
14264      return this.map(function(value) {
14265        return baseInvoke(value, path, args);
14266      });
14267    });
14268
14269    LazyWrapper.prototype.reject = function(predicate) {
14270      predicate = getIteratee(predicate, 3);
14271      return this.filter(function(value) {
14272        return !predicate(value);
14273      });
14274    };
14275
14276    LazyWrapper.prototype.slice = function(start, end) {
14277      start = toInteger(start);
14278
14279      var result = this;
14280      if (result.__filtered__ && (start > 0 || end < 0)) {
14281        return new LazyWrapper(result);
14282      }
14283      if (start < 0) {
14284        result = result.takeRight(-start);
14285      } else if (start) {
14286        result = result.drop(start);
14287      }
14288      if (end !== undefined) {
14289        end = toInteger(end);
14290        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14291      }
14292      return result;
14293    };
14294
14295    LazyWrapper.prototype.takeRightWhile = function(predicate) {
14296      return this.reverse().takeWhile(predicate).reverse();
14297    };
14298
14299    LazyWrapper.prototype.toArray = function() {
14300      return this.take(MAX_ARRAY_LENGTH);
14301    };
14302
14303    // Add `LazyWrapper` methods to `lodash.prototype`.
14304    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14305      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14306          isTaker = /^(?:head|last)$/.test(methodName),
14307          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14308          retUnwrapped = isTaker || /^find/.test(methodName);
14309
14310      if (!lodashFunc) {
14311        return;
14312      }
14313      lodash.prototype[methodName] = function() {
14314        var value = this.__wrapped__,
14315            args = isTaker ? [1] : arguments,
14316            isLazy = value instanceof LazyWrapper,
14317            iteratee = args[0],
14318            useLazy = isLazy || isArray(value);
14319
14320        var interceptor = function(value) {
14321          var result = lodashFunc.apply(lodash, arrayPush([value], args));
14322          return (isTaker && chainAll) ? result[0] : result;
14323        };
14324
14325        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14326          // Avoid lazy use if the iteratee has a "length" value other than `1`.
14327          isLazy = useLazy = false;
vendor: 3,058 bytes, lines 14328-14408
14328        }
14329        var chainAll = this.__chain__,
14330            isHybrid = !!this.__actions__.length,
14331            isUnwrapped = retUnwrapped && !chainAll,
14332            onlyLazy = isLazy && !isHybrid;
14333
14334        if (!retUnwrapped && useLazy) {
14335          value = onlyLazy ? value : new LazyWrapper(this);
14336          var result = func.apply(value, args);
14337          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14338          return new LodashWrapper(result, chainAll);
14339        }
14340        if (isUnwrapped && onlyLazy) {
14341          return func.apply(this, args);
14342        }
14343        result = this.thru(interceptor);
14344        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14345      };
14346    });
14347
14348    // Add `Array` and `String` methods to `lodash.prototype`.
14349    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14350      var func = arrayProto[methodName],
14351          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14352          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14353
14354      lodash.prototype[methodName] = function() {
14355        var args = arguments;
14356        if (retUnwrapped && !this.__chain__) {
14357          return func.apply(this.value(), args);
14358        }
14359        return this[chainName](function(value) {
14360          return func.apply(value, args);
14361        });
14362      };
14363    });
14364
14365    // Map minified function names to their real names.
14366    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14367      var lodashFunc = lodash[methodName];
14368      if (lodashFunc) {
14369        var key = (lodashFunc.name + ''),
14370            names = realNames[key] || (realNames[key] = []);
14371
14372        names.push({ 'name': methodName, 'func': lodashFunc });
14373      }
14374    });
14375
14376    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
14377
14378    // Add functions to the lazy wrapper.
14379    LazyWrapper.prototype.clone = lazyClone;
14380    LazyWrapper.prototype.reverse = lazyReverse;
14381    LazyWrapper.prototype.value = lazyValue;
14382
14383    // Add chaining functions to the `lodash` wrapper.
14384    lodash.prototype.at = wrapperAt;
14385    lodash.prototype.chain = wrapperChain;
14386    lodash.prototype.commit = wrapperCommit;
14387    lodash.prototype.flatMap = wrapperFlatMap;
14388    lodash.prototype.next = wrapperNext;
14389    lodash.prototype.plant = wrapperPlant;
14390    lodash.prototype.reverse = wrapperReverse;
14391    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14392
14393    if (iteratorSymbol) {
14394      lodash.prototype[iteratorSymbol] = wrapperToIterator;
14395    }
14396    return lodash;
14397  }
14398
14399  /*--------------------------------------------------------------------------*/
14400
14401  // Export lodash.
14402  var _ = runInContext();
14403
14404  // Expose lodash on the free variable `window` or `self` when available. This
14405  // prevents errors in cases where lodash is loaded by a script tag in the presence
14406  // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14407  (freeWindow || freeSelf || {})._ = _;
14408
14409  // Some AMD build optimizers like r.js check for condition patterns like the following:
14410  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14411    // Define as an anonymous module so, through path mapping, it can be
14412    // referenced as the "underscore" module.
14413    define(function() {
14414      return _;
14415    });
14416  }
14417  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14418  else if (freeExports && freeModule) {
14419    // Export for Node.js.
14420    if (moduleExports) {
14421      (freeModule.exports = _)._ = _;
14422    }
14423    // Export for CommonJS support.
14424    freeExports._ = _;
14425  }
14426  else {
14427    // Export to the global object.
14428    root._ = _;
14429  }
14430}.call(this));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.