PageSourceSearch

https://kamloopsairport.com/wp-content/plugins/penguinpress-react/js/vendor/lodash-4.5.0.js?ver=4.5.0

js kamloopsairport.com collected 2026-10-02 10:01:57 UTC 469,224 bytes, 14,731 lines download raw bytes

1/**
2 * @license
3 * lodash 4.3.0 (Custom Build) <https://lodash.com/>
4 * Build: `lodash -o ./dist/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.3.0';
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      weakSetTag = '[object WeakSet]';
87
88  var arrayBufferTag = '[object ArrayBuffer]',
89      float32Tag = '[object Float32Array]',
90      float64Tag = '[object Float64Array]',
91      int8Tag = '[object Int8Array]',
92      int16Tag = '[object Int16Array]',
93      int32Tag = '[object Int32Array]',
94      uint8Tag = '[object Uint8Array]',
95      uint8ClampedTag = '[object Uint8ClampedArray]',
96      uint16Tag = '[object Uint16Array]',
97      uint32Tag = '[object Uint32Array]';
98
99  /** Used to match empty string literals in compiled template source. */
100  var reEmptyStringLeading = /\b__p \+= '';/g,
101      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
102      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
103
104  /** Used to match HTML entities and HTML characters. */
105  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g,
106      reUnescapedHtml = /[&<>"'`]/g,
107      reHasEscapedHtml = RegExp(reEscapedHtml.source),
108      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
109
110  /** Used to match template delimiters. */
111  var reEscape = /<%-([\s\S]+?)%>/g,
112      reEvaluate = /<%([\s\S]+?)%>/g,
113      reInterpolate = /<%=([\s\S]+?)%>/g;
114
115  /** Used to match property names within property paths. */
116  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
117      reIsPlainProp = /^\w*$/,
118      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
119
120  /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */
121  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
122      reHasRegExpChar = RegExp(reRegExpChar.source);
123
124  /** Used to match leading and trailing whitespace. */
125  var reTrim = /^\s+|\s+$/g,
126      reTrimStart = /^\s+/,
127      reTrimEnd = /\s+$/;
128
129  /** Used to match backslashes in property paths. */
130  var reEscapeChar = /\\(\\)?/g;
131
132  /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
133  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
134
135  /** Used to match `RegExp` flags from their coerced string values. */
136  var reFlags = /\w*$/;
137
138  /** Used to detect hexadecimal string values. */
139  var reHasHexPrefix = /^0x/i;
140
141  /** Used to detect bad signed hexadecimal string values. */
142  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
143
144  /** Used to detect binary string values. */
vendor: 5,540 bytes, lines 145-258
145  var reIsBinary = /^0b[01]+$/i;
146
147  /** Used to detect host constructors (Safari > 5). */
148  var reIsHostCtor = /^\[object .+?Constructor\]$/;
149
150  /** Used to detect octal string values. */
151  var reIsOctal = /^0o[0-7]+$/i;
152
153  /** Used to detect unsigned integer values. */
154  var reIsUint = /^(?:0|[1-9]\d*)$/;
155
156  /** Used to match latin-1 supplementary letters (excluding mathematical operators). */
157  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
158
159  /** Used to ensure capturing order of template delimiters. */
160  var reNoMatch = /($^)/;
161
162  /** Used to match unescaped characters in compiled string literals. */
163  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
164
165  /** Used to compose unicode character classes. */
166  var rsAstralRange = '\\ud800-\\udfff',
167      rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
168      rsComboSymbolsRange = '\\u20d0-\\u20f0',
169      rsDingbatRange = '\\u2700-\\u27bf',
170      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
171      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
172      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
173      rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
174      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',
175      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
176      rsVarRange = '\\ufe0e\\ufe0f',
177      rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
178
179  /** Used to compose unicode capture groups. */
180  var rsAstral = '[' + rsAstralRange + ']',
181      rsBreak = '[' + rsBreakRange + ']',
182      rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
183      rsDigits = '\\d+',
184      rsDingbat = '[' + rsDingbatRange + ']',
185      rsLower = '[' + rsLowerRange + ']',
186      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
187      rsFitz = '\\ud83c[\\udffb-\\udfff]',
188      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
189      rsNonAstral = '[^' + rsAstralRange + ']',
190      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
191      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
192      rsUpper = '[' + rsUpperRange + ']',
193      rsZWJ = '\\u200d';
194
195  /** Used to compose unicode regexes. */
196  var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
197      rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
198      reOptMod = rsModifier + '?',
199      rsOptVar = '[' + rsVarRange + ']?',
200      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
201      rsSeq = rsOptVar + reOptMod + rsOptJoin,
202      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
203      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
204
205  /**
206   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
207   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
208   */
209  var reComboMark = RegExp(rsCombo, 'g');
210
211  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
212  var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
213
214  /** 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/). */
215  var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
216
217  /** Used to match non-compound words composed of alphanumeric characters. */
218  var reBasicWord = /[a-zA-Z0-9]+/g;
219
220  /** Used to match complex or compound words. */
221  var reComplexWord = RegExp([
222    rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
223    rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
224    rsUpper + '?' + rsLowerMisc + '+',
225    rsUpper + '+',
226    rsDigits,
227    rsEmoji
228  ].join('|'), 'g');
229
230  /** Used to detect strings that need a more robust regexp to match words. */
231  var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
232
233  /** Used to assign default `context` object properties. */
234  var contextProps = [
235    'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array',
236    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
237    'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
238    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_',
239    'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
240  ];
241
242  /** Used to make template sourceURLs easier to identify. */
243  var templateCounter = -1;
244
245  /** Used to identify `toStringTag` values of typed arrays. */
246  var typedArrayTags = {};
247  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
248  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
249  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
250  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
251  typedArrayTags[uint32Tag] = true;
252  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
253  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
254  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
255  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
256  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
257  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
258  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
259
260  /** Used to identify `toStringTag` values supported by `_.clone`. */
261  var cloneableTags = {};
262  cloneableTags[argsTag] = cloneableTags[arrayTag] =
263  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
264  cloneableTags[dateTag] = cloneableTags[float32Tag] =
265  cloneableTags[float64Tag] = cloneableTags[int8Tag] =
266  cloneableTags[int16Tag] = cloneableTags[int32Tag] =
267  cloneableTags[mapTag] = cloneableTags[numberTag] =
268  cloneableTags[objectTag] = cloneableTags[regexpTag] =
269  cloneableTags[setTag] = cloneableTags[stringTag] =
270  cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
271  cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
272  cloneableTags[uint32Tag] = true;
273  cloneableTags[errorTag] = cloneableTags[funcTag] =
274  cloneableTags[weakMapTag] = false;
275
276  /** Used to map latin-1 supplementary letters to basic latin letters. */
277  var deburredLetters = {
278    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
279    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
280    '\xc7': 'C',  '\xe7': 'c',
281    '\xd0': 'D',  '\xf0': 'd',
282    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
283    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
284    '\xcC': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
285    '\xeC': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
286    '\xd1': 'N',  '\xf1': 'n',
287    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
288    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
289    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
290    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
291    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
292    '\xc6': 'Ae', '\xe6': 'ae',
293    '\xde': 'Th', '\xfe': 'th',
294    '\xdf': 'ss'
295  };
296
297  /** Used to map characters to HTML entities. */
298  var htmlEscapes = {
299    '&': '&amp;',
300    '<': '&lt;',
301    '>': '&gt;',
302    '"': '&quot;',
303    "'": '&#39;',
304    '`': '&#96;'
305  };
306
307  /** Used to map HTML entities to characters. */
308  var htmlUnescapes = {
309    '&amp;': '&',
310    '&lt;': '<',
311    '&gt;': '>',
312    '&quot;': '"',
313    '&#39;': "'",
314    '&#96;': '`'
315  };
316
317  /** Used to determine if values are of the language type `Object`. */
318  var objectTypes = {
319    'function': true,
320    'object': true
321  };
322
323  /** Used to escape characters for inclusion in compiled string literals. */
324  var stringEscapes = {
325    '\\': '\\',
326    "'": "'",
327    '\n': 'n',
328    '\r': 'r',
329    '\u2028': 'u2028',
330    '\u2029': 'u2029'
331  };
332
333  /** Built-in method references without a dependency on `root`. */
334  var freeParseFloat = parseFloat,
335      freeParseInt = parseInt;
336
337  /** Detect free variable `exports`. */
338  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
339
340  /** Detect free variable `module`. */
341  var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
342
343  /** Detect free variable `global` from Node.js. */
344  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
345
346  /** Detect free variable `self`. */
347  var freeSelf = checkGlobal(objectTypes[typeof self] && self);
348
349  /** Detect free variable `window`. */
350  var freeWindow = checkGlobal(objectTypes[typeof window] && window);
351
352  /** Detect the popular CommonJS extension `module.exports`. */
353  var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
354
355  /** Detect `this` as the global object. */
356  var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
357
358  /**
359   * Used as a reference to the global object.
360   *
361   * The `this` value is used if it's the global object to avoid Greasemonkey's
362   * restricted `window` object, otherwise the `window` object is used.
363   */
364  var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
365
366  /*--------------------------------------------------------------------------*/
367
368  /**
369   * Adds the key-value `pair` to `map`.
370   *
371   * @private
372   * @param {Object} map The map to modify.
373   * @param {Array} pair The key-value pair to add.
374   * @returns {Object} Returns `map`.
375   */
376  function addMapEntry(map, pair) {
377    map.set(pair[0], pair[1]);
378    return map;
379  }
380
381  /**
382   * Adds `value` to `set`.
383   *
384   * @private
385   * @param {Object} set The set to modify.
386   * @param {*} value The value to add.
387   * @returns {Object} Returns `set`.
388   */
389  function addSetEntry(set, value) {
390    set.add(value);
391    return set;
392  }
393
394  /**
395   * A faster alternative to `Function#apply`, this function invokes `func`
396   * with the `this` binding of `thisArg` and the arguments of `args`.
397   *
398   * @private
399   * @param {Function} func The function to invoke.
400   * @param {*} thisArg The `this` binding of `func`.
401   * @param {...*} args The arguments to invoke `func` with.
402   * @returns {*} Returns the result of `func`.
403   */
404  function apply(func, thisArg, args) {
405    var length = args.length;
406    switch (length) {
407      case 0: return func.call(thisArg);
408      case 1: return func.call(thisArg, args[0]);
409      case 2: return func.call(thisArg, args[0], args[1]);
410      case 3: return func.call(thisArg, args[0], args[1], args[2]);
411    }
412    return func.apply(thisArg, args);
413  }
414
415  /**
416   * A specialized version of `baseAggregator` for arrays.
417   *
418   * @private
419   * @param {Array} array The array to iterate over.
420   * @param {Function} setter The function to set `accumulator` values.
421   * @param {Function} iteratee The iteratee to transform keys.
422   * @param {Object} accumulator The initial aggregated object.
423   * @returns {Function} Returns `accumulator`.
424   */
425  function arrayAggregator(array, setter, iteratee, accumulator) {
426    var index = -1,
427        length = array.length;
428
429    while (++index < length) {
430      var value = array[index];
431      setter(accumulator, value, iteratee(value), array);
432    }
433    return accumulator;
434  }
435
436  /**
437   * Creates a new array concatenating `array` with `other`.
438   *
439   * @private
440   * @param {Array} array The first array to concatenate.
441   * @param {Array} other The second array to concatenate.
442   * @returns {Array} Returns the new concatenated array.
vendor: 6,769 bytes, lines 443-684
443   */
444  function arrayConcat(array, other) {
445    var index = -1,
446        length = array.length,
447        othIndex = -1,
448        othLength = other.length,
449        result = Array(length + othLength);
450
451    while (++index < length) {
452      result[index] = array[index];
453    }
454    while (++othIndex < othLength) {
455      result[index++] = other[othIndex];
456    }
457    return result;
458  }
459
460  /**
461   * A specialized version of `_.forEach` for arrays without support for
462   * iteratee shorthands.
463   *
464   * @private
465   * @param {Array} array The array to iterate over.
466   * @param {Function} iteratee The function invoked per iteration.
467   * @returns {Array} Returns `array`.
468   */
469  function arrayEach(array, iteratee) {
470    var index = -1,
471        length = array.length;
472
473    while (++index < length) {
474      if (iteratee(array[index], index, array) === false) {
475        break;
476      }
477    }
478    return array;
479  }
480
481  /**
482   * A specialized version of `_.forEachRight` for arrays without support for
483   * iteratee shorthands.
484   *
485   * @private
486   * @param {Array} array The array to iterate over.
487   * @param {Function} iteratee The function invoked per iteration.
488   * @returns {Array} Returns `array`.
489   */
490  function arrayEachRight(array, iteratee) {
491    var length = array.length;
492
493    while (length--) {
494      if (iteratee(array[length], length, array) === false) {
495        break;
496      }
497    }
498    return array;
499  }
500
501  /**
502   * A specialized version of `_.every` for arrays without support for
503   * iteratee shorthands.
504   *
505   * @private
506   * @param {Array} array The array to iterate over.
507   * @param {Function} predicate The function invoked per iteration.
508   * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
509   */
510  function arrayEvery(array, predicate) {
511    var index = -1,
512        length = array.length;
513
514    while (++index < length) {
515      if (!predicate(array[index], index, array)) {
516        return false;
517      }
518    }
519    return true;
520  }
521
522  /**
523   * A specialized version of `_.filter` for arrays without support for
524   * iteratee shorthands.
525   *
526   * @private
527   * @param {Array} array The array to iterate over.
528   * @param {Function} predicate The function invoked per iteration.
529   * @returns {Array} Returns the new filtered array.
530   */
531  function arrayFilter(array, predicate) {
532    var index = -1,
533        length = array.length,
534        resIndex = -1,
535        result = [];
536
537    while (++index < length) {
538      var value = array[index];
539      if (predicate(value, index, array)) {
540        result[++resIndex] = value;
541      }
542    }
543    return result;
544  }
545
546  /**
547   * A specialized version of `_.includes` for arrays without support for
548   * specifying an index to search from.
549   *
550   * @private
551   * @param {Array} array The array to search.
552   * @param {*} target The value to search for.
553   * @returns {boolean} Returns `true` if `target` is found, else `false`.
554   */
555  function arrayIncludes(array, value) {
556    return !!array.length && baseIndexOf(array, value, 0) > -1;
557  }
558
559  /**
560   * A specialized version of `_.includesWith` for arrays without support for
561   * specifying an index to search from.
562   *
563   * @private
564   * @param {Array} array The array to search.
565   * @param {*} target The value to search for.
566   * @param {Function} comparator The comparator invoked per element.
567   * @returns {boolean} Returns `true` if `target` is found, else `false`.
568   */
569  function arrayIncludesWith(array, value, comparator) {
570    var index = -1,
571        length = array.length;
572
573    while (++index < length) {
574      if (comparator(value, array[index])) {
575        return true;
576      }
577    }
578    return false;
579  }
580
581  /**
582   * A specialized version of `_.map` for arrays without support for iteratee
583   * shorthands.
584   *
585   * @private
586   * @param {Array} array The array to iterate over.
587   * @param {Function} iteratee The function invoked per iteration.
588   * @returns {Array} Returns the new mapped array.
589   */
590  function arrayMap(array, iteratee) {
591    var index = -1,
592        length = array.length,
593        result = Array(length);
594
595    while (++index < length) {
596      result[index] = iteratee(array[index], index, array);
597    }
598    return result;
599  }
600
601  /**
602   * Appends the elements of `values` to `array`.
603   *
604   * @private
605   * @param {Array} array The array to modify.
606   * @param {Array} values The values to append.
607   * @returns {Array} Returns `array`.
608   */
609  function arrayPush(array, values) {
610    var index = -1,
611        length = values.length,
612        offset = array.length;
613
614    while (++index < length) {
615      array[offset + index] = values[index];
616    }
617    return array;
618  }
619
620  /**
621   * A specialized version of `_.reduce` for arrays without support for
622   * iteratee shorthands.
623   *
624   * @private
625   * @param {Array} array The array to iterate over.
626   * @param {Function} iteratee The function invoked per iteration.
627   * @param {*} [accumulator] The initial value.
628   * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
629   * @returns {*} Returns the accumulated value.
630   */
631  function arrayReduce(array, iteratee, accumulator, initAccum) {
632    var index = -1,
633        length = array.length;
634
635    if (initAccum && length) {
636      accumulator = array[++index];
637    }
638    while (++index < length) {
639      accumulator = iteratee(accumulator, array[index], index, array);
640    }
641    return accumulator;
642  }
643
644  /**
645   * A specialized version of `_.reduceRight` for arrays without support for
646   * iteratee shorthands.
647   *
648   * @private
649   * @param {Array} array The array to iterate over.
650   * @param {Function} iteratee The function invoked per iteration.
651   * @param {*} [accumulator] The initial value.
652   * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
653   * @returns {*} Returns the accumulated value.
654   */
655  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
656    var length = array.length;
657    if (initAccum && length) {
658      accumulator = array[--length];
659    }
660    while (length--) {
661      accumulator = iteratee(accumulator, array[length], length, array);
662    }
663    return accumulator;
664  }
665
666  /**
667   * A specialized version of `_.some` for arrays without support for iteratee
668   * shorthands.
669   *
670   * @private
671   * @param {Array} array The array to iterate over.
672   * @param {Function} predicate The function invoked per iteration.
673   * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
674   */
675  function arraySome(array, predicate) {
676    var index = -1,
677        length = array.length;
678
679    while (++index < length) {
680      if (predicate(array[index], index, array)) {
681        return true;
682      }
683    }
684    return false;
vendor: 5,156 bytes, lines 685-848
685  }
686
687  /**
688   * The base implementation of methods like `_.max` and `_.min` which accepts a
689   * `comparator` to determine the extremum value.
690   *
691   * @private
692   * @param {Array} array The array to iterate over.
693   * @param {Function} iteratee The iteratee invoked per iteration.
694   * @param {Function} comparator The comparator used to compare values.
695   * @returns {*} Returns the extremum value.
696   */
697  function baseExtremum(array, iteratee, comparator) {
698    var index = -1,
699        length = array.length;
700
701    while (++index < length) {
702      var value = array[index],
703          current = iteratee(value);
704
705      if (current != null && (computed === undefined
706            ? current === current
707            : comparator(current, computed)
708          )) {
709        var computed = current,
710            result = value;
711      }
712    }
713    return result;
714  }
715
716  /**
717   * The base implementation of methods like `_.find` and `_.findKey`, without
718   * support for iteratee shorthands, which iterates over `collection` using
719   * `eachFunc`.
720   *
721   * @private
722   * @param {Array|Object} collection The collection to search.
723   * @param {Function} predicate The function invoked per iteration.
724   * @param {Function} eachFunc The function to iterate over `collection`.
725   * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
726   * @returns {*} Returns the found element or its key, else `undefined`.
727   */
728  function baseFind(collection, predicate, eachFunc, retKey) {
729    var result;
730    eachFunc(collection, function(value, key, collection) {
731      if (predicate(value, key, collection)) {
732        result = retKey ? key : value;
733        return false;
734      }
735    });
736    return result;
737  }
738
739  /**
740   * The base implementation of `_.findIndex` and `_.findLastIndex` without
741   * support for iteratee shorthands.
742   *
743   * @private
744   * @param {Array} array The array to search.
745   * @param {Function} predicate The function invoked per iteration.
746   * @param {boolean} [fromRight] Specify iterating from right to left.
747   * @returns {number} Returns the index of the matched value, else `-1`.
748   */
749  function baseFindIndex(array, predicate, fromRight) {
750    var length = array.length,
751        index = fromRight ? length : -1;
752
753    while ((fromRight ? index-- : ++index < length)) {
754      if (predicate(array[index], index, array)) {
755        return index;
756      }
757    }
758    return -1;
759  }
760
761  /**
762   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
763   *
764   * @private
765   * @param {Array} array The array to search.
766   * @param {*} value The value to search for.
767   * @param {number} fromIndex The index to search from.
768   * @returns {number} Returns the index of the matched value, else `-1`.
769   */
770  function baseIndexOf(array, value, fromIndex) {
771    if (value !== value) {
772      return indexOfNaN(array, fromIndex);
773    }
774    var index = fromIndex - 1,
775        length = array.length;
776
777    while (++index < length) {
778      if (array[index] === value) {
779        return index;
780      }
781    }
782    return -1;
783  }
784
785  /**
786   * The base implementation of `_.reduce` and `_.reduceRight`, without support
787   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
788   *
789   * @private
790   * @param {Array|Object} collection The collection to iterate over.
791   * @param {Function} iteratee The function invoked per iteration.
792   * @param {*} accumulator The initial value.
793   * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
794   * @param {Function} eachFunc The function to iterate over `collection`.
795   * @returns {*} Returns the accumulated value.
796   */
797  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
798    eachFunc(collection, function(value, index, collection) {
799      accumulator = initAccum
800        ? (initAccum = false, value)
801        : iteratee(accumulator, value, index, collection);
802    });
803    return accumulator;
804  }
805
806  /**
807   * The base implementation of `_.sortBy` which uses `comparer` to define
808   * the sort order of `array` and replaces criteria objects with their
809   * corresponding values.
810   *
811   * @private
812   * @param {Array} array The array to sort.
813   * @param {Function} comparer The function to define sort order.
814   * @returns {Array} Returns `array`.
815   */
816  function baseSortBy(array, comparer) {
817    var length = array.length;
818
819    array.sort(comparer);
820    while (length--) {
821      array[length] = array[length].value;
822    }
823    return array;
824  }
825
826  /**
827   * The base implementation of `_.sum` without support for iteratee shorthands.
828   *
829   * @private
830   * @param {Array} array The array to iterate over.
831   * @param {Function} iteratee The function invoked per iteration.
832   * @returns {number} Returns the sum.
833   */
834  function baseSum(array, iteratee) {
835    var result,
836        index = -1,
837        length = array.length;
838
839    while (++index < length) {
840      var current = iteratee(array[index]);
841      if (current !== undefined) {
842        result = result === undefined ? current : (result + current);
843      }
844    }
845    return result;
846  }
847
848  /**
849   * The base implementation of `_.times` without support for iteratee shorthands
850   * or max array length checks.
851   *
852   * @private
853   * @param {number} n The number of times to invoke `iteratee`.
854   * @param {Function} iteratee The function invoked per iteration.
855   * @returns {Array} Returns the array of results.
856   */
857  function baseTimes(n, iteratee) {
858    var index = -1,
859        result = Array(n);
860
861    while (++index < n) {
862      result[index] = iteratee(index);
863    }
864    return result;
865  }
866
867  /**
868   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
869   * of key-value pairs for `object` corresponding to the property names of `props`.
870   *
871   * @private
872   * @param {Object} object The object to query.
873   * @param {Array} props The property names to get values for.
874   * @returns {Object} Returns the new array of key-value pairs.
875   */
876  function baseToPairs(object, props) {
877    return arrayMap(props, function(key) {
878      return [key, object[key]];
879    });
880  }
881
882  /**
883   * The base implementation of `_.unary` without support for storing wrapper metadata.
884   *
885   * @private
886   * @param {Function} func The function to cap arguments for.
887   * @returns {Function} Returns the new function.
888   */
889  function baseUnary(func) {
890    return function(value) {
891      return func(value);
892    };
893  }
894
895  /**
896   * The base implementation of `_.values` and `_.valuesIn` which creates an
897   * array of `object` property values corresponding to the property names
898   * of `props`.
899   *
900   * @private
901   * @param {Object} object The object to query.
902   * @param {Array} props The property names to get values for.
903   * @returns {Object} Returns the array of property values.
904   */
905  function baseValues(object, props) {
906    return arrayMap(props, function(key) {
907      return object[key];
908    });
909  }
910
911  /**
912   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
913   * that is not found in the character symbols.
914   *
915   * @private
916   * @param {Array} strSymbols The string symbols to inspect.
917   * @param {Array} chrSymbols The character symbols to find.
918   * @returns {number} Returns the index of the first unmatched string symbol.
919   */
920  function charsStartIndex(strSymbols, chrSymbols) {
921    var index = -1,
922        length = strSymbols.length;
923
924    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
925    return index;
926  }
927
928  /**
929   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
930   * that is not found in the character symbols.
931   *
932   * @private
933   * @param {Array} strSymbols The string symbols to inspect.
934   * @param {Array} chrSymbols The character symbols to find.
935   * @returns {number} Returns the index of the last unmatched string symbol.
936   */
937  function charsEndIndex(strSymbols, chrSymbols) {
938    var index = strSymbols.length;
939
940    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
941    return index;
942  }
943
944  /**
945   * Checks if `value` is a global object.
946   *
947   * @private
948   * @param {*} value The value to check.
949   * @returns {null|Object} Returns `value` if it's a global object, else `null`.
950   */
951  function checkGlobal(value) {
952    return (value && value.Object === Object) ? value : null;
953  }
954
955  /**
956   * Compares values to sort them in ascending order.
957   *
958   * @private
959   * @param {*} value The value to compare.
960   * @param {*} other The other value to compare.
961   * @returns {number} Returns the sort order indicator for `value`.
962   */
963  function compareAscending(value, other) {
964    if (value !== other) {
965      var valIsNull = value === null,
966          valIsUndef = value === undefined,
967          valIsReflexive = value === value;
968
969      var othIsNull = other === null,
970          othIsUndef = other === undefined,
971          othIsReflexive = other === other;
972
973      if ((value > other && !othIsNull) || !valIsReflexive ||
974          (valIsNull && !othIsUndef && othIsReflexive) ||
975          (valIsUndef && othIsReflexive)) {
976        return 1;
977      }
978      if ((value < other && !valIsNull) || !othIsReflexive ||
979          (othIsNull && !valIsUndef && valIsReflexive) ||
980          (othIsUndef && valIsReflexive)) {
981        return -1;
982      }
983    }
984    return 0;
985  }
986
987  /**
988   * Used by `_.orderBy` to compare multiple properties of a value to another
989   * and stable sort them.
990   *
991   * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
992   * specify an order of "desc" for descending or "asc" for ascending sort order
993   * of corresponding values.
994   *
995   * @private
996   * @param {Object} object The object to compare.
997   * @param {Object} other The other object to compare.
998   * @param {boolean[]|string[]} orders The order to sort by for each property.
999   * @returns {number} Returns the sort order indicator for `object`.
1000   */
1001  function compareMultiple(object, other, orders) {
1002    var index = -1,
1003        objCriteria = object.criteria,
1004        othCriteria = other.criteria,
1005        length = objCriteria.length,
1006        ordersLength = orders.length;
1007
1008    while (++index < length) {
1009      var result = compareAscending(objCriteria[index], othCriteria[index]);
1010      if (result) {
1011        if (index >= ordersLength) {
1012          return result;
1013        }
1014        var order = orders[index];
1015        return result * (order == 'desc' ? -1 : 1);
1016      }
1017    }
1018    // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
1019    // that causes it, under certain circumstances, to provide the same value for
1020    // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
1021    // for more details.
1022    //
1023    // This also ensures a stable sort in V8 and other engines.
1024    // See https://code.google.com/p/v8/issues/detail?id=90 for more details.
1025    return object.index - other.index;
1026  }
1027
1028  /**
1029   * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
1030   *
1031   * @private
1032   * @param {string} letter The matched letter to deburr.
1033   * @returns {string} Returns the deburred letter.
1034   */
1035  function deburrLetter(letter) {
1036    return deburredLetters[letter];
1037  }
1038
1039  /**
1040   * Used by `_.escape` to convert characters to HTML entities.
1041   *
1042   * @private
1043   * @param {string} chr The matched character to escape.
1044   * @returns {string} Returns the escaped character.
1045   */
1046  function escapeHtmlChar(chr) {
1047    return htmlEscapes[chr];
1048  }
1049
1050  /**
1051   * Used by `_.template` to escape characters for inclusion in compiled string literals.
1052   *
1053   * @private
1054   * @param {string} chr The matched character to escape.
1055   * @returns {string} Returns the escaped character.
1056   */
1057  function escapeStringChar(chr) {
1058    return '\\' + stringEscapes[chr];
1059  }
1060
1061  /**
1062   * Gets the index at which the first occurrence of `NaN` is found in `array`.
1063   *
1064   * @private
1065   * @param {Array} array The array to search.
1066   * @param {number} fromIndex The index to search from.
1067   * @param {boolean} [fromRight] Specify iterating from right to left.
1068   * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1069   */
1070  function indexOfNaN(array, fromIndex, fromRight) {
1071    var length = array.length,
1072        index = fromIndex + (fromRight ? 0 : -1);
1073
1074    while ((fromRight ? index-- : ++index < length)) {
1075      var other = array[index];
1076      if (other !== other) {
1077        return index;
1078      }
1079    }
1080    return -1;
1081  }
1082
1083  /**
1084   * Checks if `value` is a host object in IE < 9.
1085   *
1086   * @private
1087   * @param {*} value The value to check.
1088   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1089   */
1090  function isHostObject(value) {
1091    // Many host objects are `Object` objects that can coerce to strings
1092    // despite having improperly defined `toString` methods.
1093    var result = false;
1094    if (value != null && typeof value.toString != 'function') {
1095      try {
1096        result = !!(value + '');
1097      } catch (e) {}
1098    }
1099    return result;
1100  }
1101
1102  /**
1103   * Checks if `value` is a valid array-like index.
1104   *
1105   * @private
1106   * @param {*} value The value to check.
1107   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1108   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1109   */
1110  function isIndex(value, length) {
1111    value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
1112    length = length == null ? MAX_SAFE_INTEGER : length;
1113    return value > -1 && value % 1 == 0 && value < length;
1114  }
1115
1116  /**
1117   * Converts `iterator` to an array.
1118   *
1119   * @private
1120   * @param {Object} iterator The iterator to convert.
1121   * @returns {Array} Returns the converted array.
1122   */
1123  function iteratorToArray(iterator) {
1124    var data,
1125        result = [];
1126
1127    while (!(data = iterator.next()).done) {
1128      result.push(data.value);
1129    }
1130    return result;
1131  }
1132
1133  /**
1134   * Converts `map` to an array.
1135   *
1136   * @private
1137   * @param {Object} map The map to convert.
1138   * @returns {Array} Returns the converted array.
1139   */
1140  function mapToArray(map) {
1141    var index = -1,
1142        result = Array(map.size);
1143
1144    map.forEach(function(value, key) {
1145      result[++index] = [key, value];
1146    });
1147    return result;
1148  }
1149
1150  /**
1151   * Replaces all `placeholder` elements in `array` with an internal placeholder
1152   * and returns an array of their indexes.
1153   *
1154   * @private
1155   * @param {Array} array The array to modify.
1156   * @param {*} placeholder The placeholder to replace.
1157   * @returns {Array} Returns the new array of placeholder indexes.
1158   */
1159  function replaceHolders(array, placeholder) {
1160    var index = -1,
1161        length = array.length,
1162        resIndex = -1,
1163        result = [];
1164
1165    while (++index < length) {
1166      if (array[index] === placeholder) {
1167        array[index] = PLACEHOLDER;
1168        result[++resIndex] = index;
1169      }
1170    }
1171    return result;
1172  }
1173
1174  /**
1175   * Converts `set` to an array.
1176   *
1177   * @private
1178   * @param {Object} set The set to convert.
1179   * @returns {Array} Returns the converted array.
1180   */
1181  function setToArray(set) {
1182    var index = -1,
1183        result = Array(set.size);
1184
1185    set.forEach(function(value) {
1186      result[++index] = value;
1187    });
1188    return result;
1189  }
1190
1191  /**
1192   * Gets the number of symbols in `string`.
1193   *
1194   * @private
1195   * @param {string} string The string to inspect.
1196   * @returns {number} Returns the string size.
1197   */
1198  function stringSize(string) {
1199    if (!(string && reHasComplexSymbol.test(string))) {
1200      return string.length;
1201    }
1202    var result = reComplexSymbol.lastIndex = 0;
1203    while (reComplexSymbol.test(string)) {
1204      result++;
1205    }
1206    return result;
1207  }
1208
1209  /**
1210   * Converts `string` to an array.
1211   *
1212   * @private
1213   * @param {string} string The string to convert.
1214   * @returns {Array} Returns the converted array.
1215   */
1216  function stringToArray(string) {
1217    return string.match(reComplexSymbol);
1218  }
1219
1220  /**
1221   * Used by `_.unescape` to convert HTML entities to characters.
1222   *
1223   * @private
1224   * @param {string} chr The matched character to unescape.
1225   * @returns {string} Returns the unescaped character.
1226   */
1227  function unescapeHtmlChar(chr) {
1228    return htmlUnescapes[chr];
1229  }
1230
1231  /*--------------------------------------------------------------------------*/
1232
1233  /**
1234   * Create a new pristine `lodash` function using the `context` object.
1235   *
1236   * @static
1237   * @memberOf _
1238   * @category Util
1239   * @param {Object} [context=root] The context object.
1240   * @returns {Function} Returns a new `lodash` function.
1241   * @example
1242   *
1243   * _.mixin({ 'foo': _.constant('foo') });
1244   *
1245   * var lodash = _.runInContext();
1246   * lodash.mixin({ 'bar': lodash.constant('bar') });
1247   *
1248   * _.isFunction(_.foo);
1249   * // => true
1250   * _.isFunction(_.bar);
1251   * // => false
1252   *
1253   * lodash.isFunction(lodash.foo);
1254   * // => false
1255   * lodash.isFunction(lodash.bar);
1256   * // => true
1257   *
1258   * // Use `context` to mock `Date#getTime` use in `_.now`.
1259   * var mock = _.runInContext({
1260   *   'Date': function() {
1261   *     return { 'getTime': getTimeMock };
1262   *   }
1263   * });
1264   *
1265   * // Create a suped-up `defer` in Node.js.
1266   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1267   */
1268  function runInContext(context) {
1269    context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1270
1271    /** Built-in constructor references. */
1272    var Date = context.Date,
1273        Error = context.Error,
1274        Math = context.Math,
1275        RegExp = context.RegExp,
1276        TypeError = context.TypeError;
1277
1278    /** Used for built-in method references. */
1279    var arrayProto = context.Array.prototype,
1280        objectProto = context.Object.prototype;
1281
1282    /** Used to resolve the decompiled source of functions. */
1283    var funcToString = context.Function.prototype.toString;
1284
1285    /** Used to check objects for own properties. */
1286    var hasOwnProperty = objectProto.hasOwnProperty;
1287
1288    /** Used to generate unique IDs. */
1289    var idCounter = 0;
1290
1291    /** Used to infer the `Object` constructor. */
1292    var objectCtorString = funcToString.call(Object);
1293
1294    /**
1295     * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1296     * of values.
1297     */
1298    var objectToString = objectProto.toString;
1299
1300    /** Used to restore the original `_` reference in `_.noConflict`. */
1301    var oldDash = root._;
1302
1303    /** Used to detect if a method is native. */
1304    var reIsNative = RegExp('^' +
1305      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1306      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1307    );
1308
1309    /** Built-in value references. */
1310    var Buffer = moduleExports ? context.Buffer : undefined,
1311        Reflect = context.Reflect,
1312        Symbol = context.Symbol,
1313        Uint8Array = context.Uint8Array,
1314        clearTimeout = context.clearTimeout,
1315        enumerate = Reflect ? Reflect.enumerate : undefined,
1316        getPrototypeOf = Object.getPrototypeOf,
1317        getOwnPropertySymbols = Object.getOwnPropertySymbols,
1318        iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1319        propertyIsEnumerable = objectProto.propertyIsEnumerable,
1320        setTimeout = context.setTimeout,
1321        splice = arrayProto.splice;
1322
1323    /* Built-in method references for those with the same name as other `lodash` methods. */
1324    var nativeCeil = Math.ceil,
1325        nativeFloor = Math.floor,
1326        nativeIsFinite = context.isFinite,
1327        nativeJoin = arrayProto.join,
1328        nativeKeys = Object.keys,
1329        nativeMax = Math.max,
1330        nativeMin = Math.min,
1331        nativeParseInt = context.parseInt,
1332        nativeRandom = Math.random,
1333        nativeReverse = arrayProto.reverse;
1334
1335    /* Built-in method references that are verified to be native. */
1336    var Map = getNative(context, 'Map'),
1337        Set = getNative(context, 'Set'),
1338        WeakMap = getNative(context, 'WeakMap'),
1339        nativeCreate = getNative(Object, 'create');
1340
1341    /** Used to store function metadata. */
1342    var metaMap = WeakMap && new WeakMap;
1343
1344    /** Used to detect maps, sets, and weakmaps. */
1345    var mapCtorString = Map ? funcToString.call(Map) : '',
1346        setCtorString = Set ? funcToString.call(Set) : '',
1347        weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : '';
1348
1349    /** Used to convert symbols to primitives and strings. */
1350    var symbolProto = Symbol ? Symbol.prototype : undefined,
1351        symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
1352        symbolToString = Symbol ? symbolProto.toString : undefined;
1353
1354    /** Used to lookup unminified function names. */
1355    var realNames = {};
1356
1357    /*------------------------------------------------------------------------*/
1358
1359    /**
1360     * Creates a `lodash` object which wraps `value` to enable implicit method
1361     * chaining. Methods that operate on and return arrays, collections, and
1362     * functions can be chained together. Methods that retrieve a single value or
1363     * may return a primitive value will automatically end the chain sequence and
1364     * return the unwrapped value. Otherwise, the value must be unwrapped with
1365     * `_#value`.
1366     *
1367     * Explicit chaining, which must be unwrapped with `_#value` in all cases,
1368     * may be enabled using `_.chain`.
1369     *
1370     * The execution of chained methods is lazy, that is, it's deferred until
1371     * `_#value` is implicitly or explicitly called.
1372     *
1373     * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
1374     * fusion is an optimization to merge iteratee calls; this avoids the creation
1375     * of intermediate arrays and can greatly reduce the number of iteratee executions.
1376     * Sections of a chain sequence qualify for shortcut fusion if the section is
1377     * applied to an array of at least two hundred elements and any iteratees
1378     * accept only one argument. The heuristic for whether a section qualifies
1379     * for shortcut fusion is subject to change.
1380     *
1381     * Chaining is supported in custom builds as long as the `_#value` method is
1382     * directly or indirectly included in the build.
1383     *
1384     * In addition to lodash methods, wrappers have `Array` and `String` methods.
1385     *
1386     * The wrapper `Array` methods are:
1387     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1388     *
1389     * The wrapper `String` methods are:
1390     * `replace` and `split`
1391     *
1392     * The wrapper methods that support shortcut fusion are:
1393     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1394     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1395     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1396     *
1397     * The chainable wrapper methods are:
1398     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
1399     * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
1400     * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
1401     * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
1402     * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
1403     * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
1404     * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
1405     * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`,
1406     * `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`,
1407     * `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`,
1408     * `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`,
1409     * `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`,
1410     * `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`,
1411     * `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`,
1412     * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`,
1413     * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`,
1414     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
1415     * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`,
1416     * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`,
1417     * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`,
1418     * `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`,
1419     * `zipObjectDeep`, and `zipWith`
1420     *
1421     * The wrapper methods that are **not** chainable by default are:
1422     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1423     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
1424     * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
1425     * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
1426     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1427     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1428     * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1429     * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
1430     * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
1431     * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
1432     * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
1433     * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
1434     * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
1435     * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
1436     * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
1437     * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
1438     * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
1439     * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
1440     * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
1441     * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
1442     * `upperCase`, `upperFirst`, `value`, and `words`
1443     *
1444     * @name _
1445     * @constructor
1446     * @category Seq
1447     * @param {*} value The value to wrap in a `lodash` instance.
1448     * @returns {Object} Returns the new `lodash` wrapper instance.
1449     * @example
1450     *
1451     * function square(n) {
1452     *   return n * n;
1453     * }
1454     *
1455     * var wrapped = _([1, 2, 3]);
1456     *
1457     * // Returns an unwrapped value.
1458     * wrapped.reduce(_.add);
1459     * // => 6
1460     *
1461     * // Returns a wrapped value.
1462     * var squares = wrapped.map(square);
1463     *
1464     * _.isArray(squares);
1465     * // => false
1466     *
1467     * _.isArray(squares.value());
1468     * // => true
1469     */
1470    function lodash(value) {
1471      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1472        if (value instanceof LodashWrapper) {
1473          return value;
1474        }
1475        if (hasOwnProperty.call(value, '__wrapped__')) {
1476          return wrapperClone(value);
1477        }
1478      }
1479      return new LodashWrapper(value);
1480    }
1481
1482    /**
1483     * The function whose prototype all chaining wrappers inherit from.
1484     *
1485     * @private
1486     */
1487    function baseLodash() {
1488      // No operation performed.
1489    }
1490
1491    /**
1492     * The base constructor for creating `lodash` wrapper objects.
1493     *
1494     * @private
1495     * @param {*} value The value to wrap.
1496     * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
1497     */
1498    function LodashWrapper(value, chainAll) {
1499      this.__wrapped__ = value;
1500      this.__actions__ = [];
1501      this.__chain__ = !!chainAll;
1502      this.__index__ = 0;
1503      this.__values__ = undefined;
1504    }
1505
1506    /**
1507     * By default, the template delimiters used by lodash are like those in
1508     * embedded Ruby (ERB). Change the following template settings to use
1509     * alternative delimiters.
1510     *
1511     * @static
1512     * @memberOf _
1513     * @type Object
1514     */
1515    lodash.templateSettings = {
1516
1517      /**
1518       * Used to detect `data` property values to be HTML-escaped.
1519       *
1520       * @memberOf _.templateSettings
1521       * @type RegExp
1522       */
1523      'escape': reEscape,
1524
1525      /**
1526       * Used to detect code to be evaluated.
1527       *
1528       * @memberOf _.templateSettings
1529       * @type RegExp
1530       */
1531      'evaluate': reEvaluate,
1532
1533      /**
1534       * Used to detect `data` property values to inject.
1535       *
1536       * @memberOf _.templateSettings
1537       * @type RegExp
1538       */
1539      'interpolate': reInterpolate,
1540
1541      /**
1542       * Used to reference the data object in the template text.
1543       *
1544       * @memberOf _.templateSettings
1545       * @type string
1546       */
1547      'variable': '',
1548
1549      /**
1550       * Used to import variables into the compiled template.
1551       *
1552       * @memberOf _.templateSettings
1553       * @type Object
1554       */
1555      'imports': {
1556
1557        /**
1558         * A reference to the `lodash` function.
1559         *
1560         * @memberOf _.templateSettings.imports
1561         * @type Function
1562         */
1563        '_': lodash
1564      }
1565    };
1566
1567    /*------------------------------------------------------------------------*/
1568
1569    /**
1570     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1571     *
1572     * @private
1573     * @param {*} value The value to wrap.
1574     */
1575    function LazyWrapper(value) {
1576      this.__wrapped__ = value;
1577      this.__actions__ = [];
1578      this.__dir__ = 1;
1579      this.__filtered__ = false;
vendor: 5,751 bytes, lines 1580-1783
1580      this.__iteratees__ = [];
1581      this.__takeCount__ = MAX_ARRAY_LENGTH;
1582      this.__views__ = [];
1583    }
1584
1585    /**
1586     * Creates a clone of the lazy wrapper object.
1587     *
1588     * @private
1589     * @name clone
1590     * @memberOf LazyWrapper
1591     * @returns {Object} Returns the cloned `LazyWrapper` object.
1592     */
1593    function lazyClone() {
1594      var result = new LazyWrapper(this.__wrapped__);
1595      result.__actions__ = copyArray(this.__actions__);
1596      result.__dir__ = this.__dir__;
1597      result.__filtered__ = this.__filtered__;
1598      result.__iteratees__ = copyArray(this.__iteratees__);
1599      result.__takeCount__ = this.__takeCount__;
1600      result.__views__ = copyArray(this.__views__);
1601      return result;
1602    }
1603
1604    /**
1605     * Reverses the direction of lazy iteration.
1606     *
1607     * @private
1608     * @name reverse
1609     * @memberOf LazyWrapper
1610     * @returns {Object} Returns the new reversed `LazyWrapper` object.
1611     */
1612    function lazyReverse() {
1613      if (this.__filtered__) {
1614        var result = new LazyWrapper(this);
1615        result.__dir__ = -1;
1616        result.__filtered__ = true;
1617      } else {
1618        result = this.clone();
1619        result.__dir__ *= -1;
1620      }
1621      return result;
1622    }
1623
1624    /**
1625     * Extracts the unwrapped value from its lazy wrapper.
1626     *
1627     * @private
1628     * @name value
1629     * @memberOf LazyWrapper
1630     * @returns {*} Returns the unwrapped value.
1631     */
1632    function lazyValue() {
1633      var array = this.__wrapped__.value(),
1634          dir = this.__dir__,
1635          isArr = isArray(array),
1636          isRight = dir < 0,
1637          arrLength = isArr ? array.length : 0,
1638          view = getView(0, arrLength, this.__views__),
1639          start = view.start,
1640          end = view.end,
1641          length = end - start,
1642          index = isRight ? end : (start - 1),
1643          iteratees = this.__iteratees__,
1644          iterLength = iteratees.length,
1645          resIndex = 0,
1646          takeCount = nativeMin(length, this.__takeCount__);
1647
1648      if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) {
1649        return baseWrapperValue(array, this.__actions__);
1650      }
1651      var result = [];
1652
1653      outer:
1654      while (length-- && resIndex < takeCount) {
1655        index += dir;
1656
1657        var iterIndex = -1,
1658            value = array[index];
1659
1660        while (++iterIndex < iterLength) {
1661          var data = iteratees[iterIndex],
1662              iteratee = data.iteratee,
1663              type = data.type,
1664              computed = iteratee(value);
1665
1666          if (type == LAZY_MAP_FLAG) {
1667            value = computed;
1668          } else if (!computed) {
1669            if (type == LAZY_FILTER_FLAG) {
1670              continue outer;
1671            } else {
1672              break outer;
1673            }
1674          }
1675        }
1676        result[resIndex++] = value;
1677      }
1678      return result;
1679    }
1680
1681    /*------------------------------------------------------------------------*/
1682
1683    /**
1684     * Creates an hash object.
1685     *
1686     * @private
1687     * @returns {Object} Returns the new hash object.
1688     */
1689    function Hash() {}
1690
1691    /**
1692     * Removes `key` and its value from the hash.
1693     *
1694     * @private
1695     * @param {Object} hash The hash to modify.
1696     * @param {string} key The key of the value to remove.
1697     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1698     */
1699    function hashDelete(hash, key) {
1700      return hashHas(hash, key) && delete hash[key];
1701    }
1702
1703    /**
1704     * Gets the hash value for `key`.
1705     *
1706     * @private
1707     * @param {Object} hash The hash to query.
1708     * @param {string} key The key of the value to get.
1709     * @returns {*} Returns the entry value.
1710     */
1711    function hashGet(hash, key) {
1712      if (nativeCreate) {
1713        var result = hash[key];
1714        return result === HASH_UNDEFINED ? undefined : result;
1715      }
1716      return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
1717    }
1718
1719    /**
1720     * Checks if a hash value for `key` exists.
1721     *
1722     * @private
1723     * @param {Object} hash The hash to query.
1724     * @param {string} key The key of the entry to check.
1725     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1726     */
1727    function hashHas(hash, key) {
1728      return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
1729    }
1730
1731    /**
1732     * Sets the hash `key` to `value`.
1733     *
1734     * @private
1735     * @param {Object} hash The hash to modify.
1736     * @param {string} key The key of the value to set.
1737     * @param {*} value The value to set.
1738     */
1739    function hashSet(hash, key, value) {
1740      hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1741    }
1742
1743    /*------------------------------------------------------------------------*/
1744
1745    /**
1746     * Creates a map cache object to store key-value pairs.
1747     *
1748     * @private
1749     * @param {Array} [values] The values to cache.
1750     */
1751    function MapCache(values) {
1752      var index = -1,
1753          length = values ? values.length : 0;
1754
1755      this.clear();
1756      while (++index < length) {
1757        var entry = values[index];
1758        this.set(entry[0], entry[1]);
1759      }
1760    }
1761
1762    /**
1763     * Removes all key-value entries from the map.
1764     *
1765     * @private
1766     * @name clear
1767     * @memberOf MapCache
1768     */
1769    function mapClear() {
1770      this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash };
1771    }
1772
1773    /**
1774     * Removes `key` and its value from the map.
1775     *
1776     * @private
1777     * @name delete
1778     * @memberOf MapCache
1779     * @param {string} key The key of the value to remove.
1780     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1781     */
1782    function mapDelete(key) {
1783      var data = this.__data__;
1784      if (isKeyable(key)) {
1785        return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
1786      }
1787      return Map ? data.map['delete'](key) : assocDelete(data.map, key);
1788    }
1789
1790    /**
1791     * Gets the map value for `key`.
1792     *
1793     * @private
1794     * @name get
1795     * @memberOf MapCache
1796     * @param {string} key The key of the value to get.
1797     * @returns {*} Returns the entry value.
1798     */
1799    function mapGet(key) {
1800      var data = this.__data__;
1801      if (isKeyable(key)) {
1802        return hashGet(typeof key == 'string' ? data.string : data.hash, key);
1803      }
1804      return Map ? data.map.get(key) : assocGet(data.map, key);
1805    }
1806
1807    /**
1808     * Checks if a map value for `key` exists.
1809     *
1810     * @private
1811     * @name has
1812     * @memberOf MapCache
1813     * @param {string} key The key of the entry to check.
1814     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1815     */
1816    function mapHas(key) {
1817      var data = this.__data__;
1818      if (isKeyable(key)) {
1819        return hashHas(typeof key == 'string' ? data.string : data.hash, key);
1820      }
1821      return Map ? data.map.has(key) : assocHas(data.map, key);
1822    }
1823
1824    /**
1825     * Sets the map `key` to `value`.
1826     *
1827     * @private
1828     * @name set
1829     * @memberOf MapCache
1830     * @param {string} key The key of the value to set.
1831     * @param {*} value The value to set.
1832     * @returns {Object} Returns the map cache object.
1833     */
1834    function mapSet(key, value) {
1835      var data = this.__data__;
1836      if (isKeyable(key)) {
1837        hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
1838      } else if (Map) {
1839        data.map.set(key, value);
1840      } else {
1841        assocSet(data.map, key, value);
1842      }
1843      return this;
1844    }
1845
1846    /*------------------------------------------------------------------------*/
1847
1848    /**
1849     *
1850     * Creates a set cache object to store unique values.
1851     *
1852     * @private
1853     * @param {Array} [values] The values to cache.
1854     */
1855    function SetCache(values) {
1856      var index = -1,
1857          length = values ? values.length : 0;
1858
1859      this.__data__ = new MapCache;
1860      while (++index < length) {
1861        this.push(values[index]);
1862      }
1863    }
1864
1865    /**
1866     * Checks if `value` is in `cache`.
1867     *
1868     * @private
1869     * @param {Object} cache The set cache to search.
1870     * @param {*} value The value to search for.
1871     * @returns {number} Returns `true` if `value` is found, else `false`.
1872     */
1873    function cacheHas(cache, value) {
1874      var map = cache.__data__;
1875      if (isKeyable(value)) {
1876        var data = map.__data__,
1877            hash = typeof value == 'string' ? data.string : data.hash;
1878
1879        return hash[value] === HASH_UNDEFINED;
1880      }
1881      return map.has(value);
1882    }
1883
1884    /**
1885     * Adds `value` to the set cache.
1886     *
1887     * @private
1888     * @name push
1889     * @memberOf SetCache
1890     * @param {*} value The value to cache.
1891     */
1892    function cachePush(value) {
1893      var map = this.__data__;
1894      if (isKeyable(value)) {
1895        var data = map.__data__,
1896            hash = typeof value == 'string' ? data.string : data.hash;
1897
1898        hash[value] = HASH_UNDEFINED;
1899      }
1900      else {
1901        map.set(value, HASH_UNDEFINED);
1902      }
1903    }
1904
1905    /*------------------------------------------------------------------------*/
1906
1907    /**
1908     * Creates a stack cache object to store key-value pairs.
1909     *
1910     * @private
1911     * @param {Array} [values] The values to cache.
1912     */
1913    function Stack(values) {
1914      var index = -1,
1915          length = values ? values.length : 0;
1916
1917      this.clear();
1918      while (++index < length) {
1919        var entry = values[index];
1920        this.set(entry[0], entry[1]);
1921      }
1922    }
1923
1924    /**
1925     * Removes all key-value entries from the stack.
1926     *
1927     * @private
1928     * @name clear
1929     * @memberOf Stack
1930     */
1931    function stackClear() {
1932      this.__data__ = { 'array': [], 'map': null };
1933    }
1934
1935    /**
1936     * Removes `key` and its value from the stack.
1937     *
1938     * @private
1939     * @name delete
1940     * @memberOf Stack
1941     * @param {string} key The key of the value to remove.
1942     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1943     */
1944    function stackDelete(key) {
1945      var data = this.__data__,
1946          array = data.array;
1947
1948      return array ? assocDelete(array, key) : data.map['delete'](key);
1949    }
1950
1951    /**
1952     * Gets the stack value for `key`.
1953     *
1954     * @private
1955     * @name get
1956     * @memberOf Stack
1957     * @param {string} key The key of the value to get.
1958     * @returns {*} Returns the entry value.
1959     */
1960    function stackGet(key) {
1961      var data = this.__data__,
1962          array = data.array;
1963
1964      return array ? assocGet(array, key) : data.map.get(key);
1965    }
1966
1967    /**
1968     * Checks if a stack value for `key` exists.
1969     *
1970     * @private
1971     * @name has
1972     * @memberOf Stack
1973     * @param {string} key The key of the entry to check.
1974     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1975     */
1976    function stackHas(key) {
1977      var data = this.__data__,
1978          array = data.array;
1979
1980      return array ? assocHas(array, key) : data.map.has(key);
1981    }
1982
1983    /**
1984     * Sets the stack `key` to `value`.
1985     *
1986     * @private
1987     * @name set
1988     * @memberOf Stack
1989     * @param {string} key The key of the value to set.
1990     * @param {*} value The value to set.
1991     * @returns {Object} Returns the stack cache object.
1992     */
1993    function stackSet(key, value) {
1994      var data = this.__data__,
1995          array = data.array;
1996
1997      if (array) {
1998        if (array.length < (LARGE_ARRAY_SIZE - 1)) {
1999          assocSet(array, key, value);
2000        } else {
2001          data.array = null;
2002          data.map = new MapCache(array);
2003        }
2004      }
2005      var map = data.map;
2006      if (map) {
2007        map.set(key, value);
2008      }
2009      return this;
2010    }
2011
2012    /*------------------------------------------------------------------------*/
2013
2014    /**
2015     * Removes `key` and its value from the associative array.
2016     *
2017     * @private
2018     * @param {Array} array The array to query.
2019     * @param {string} key The key of the value to remove.
2020     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2021     */
2022    function assocDelete(array, key) {
2023      var index = assocIndexOf(array, key);
2024      if (index < 0) {
2025        return false;
vendor: 7,577 bytes, lines 2026-2260
2026      }
2027      var lastIndex = array.length - 1;
2028      if (index == lastIndex) {
2029        array.pop();
2030      } else {
2031        splice.call(array, index, 1);
2032      }
2033      return true;
2034    }
2035
2036    /**
2037     * Gets the associative array value for `key`.
2038     *
2039     * @private
2040     * @param {Array} array The array to query.
2041     * @param {string} key The key of the value to get.
2042     * @returns {*} Returns the entry value.
2043     */
2044    function assocGet(array, key) {
2045      var index = assocIndexOf(array, key);
2046      return index < 0 ? undefined : array[index][1];
2047    }
2048
2049    /**
2050     * Checks if an associative array value for `key` exists.
2051     *
2052     * @private
2053     * @param {Array} array The array to query.
2054     * @param {string} key The key of the entry to check.
2055     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2056     */
2057    function assocHas(array, key) {
2058      return assocIndexOf(array, key) > -1;
2059    }
2060
2061    /**
2062     * Gets the index at which the first occurrence of `key` is found in `array`
2063     * of key-value pairs.
2064     *
2065     * @private
2066     * @param {Array} array The array to search.
2067     * @param {*} key The key to search for.
2068     * @returns {number} Returns the index of the matched value, else `-1`.
2069     */
2070    function assocIndexOf(array, key) {
2071      var length = array.length;
2072      while (length--) {
2073        if (eq(array[length][0], key)) {
2074          return length;
2075        }
2076      }
2077      return -1;
2078    }
2079
2080    /**
2081     * Sets the associative array `key` to `value`.
2082     *
2083     * @private
2084     * @param {Array} array The array to modify.
2085     * @param {string} key The key of the value to set.
2086     * @param {*} value The value to set.
2087     */
2088    function assocSet(array, key, value) {
2089      var index = assocIndexOf(array, key);
2090      if (index < 0) {
2091        array.push([key, value]);
2092      } else {
2093        array[index][1] = value;
2094      }
2095    }
2096
2097    /*------------------------------------------------------------------------*/
2098
2099    /**
2100     * Used by `_.defaults` to customize its `_.assignIn` use.
2101     *
2102     * @private
2103     * @param {*} objValue The destination value.
2104     * @param {*} srcValue The source value.
2105     * @param {string} key The key of the property to assign.
2106     * @param {Object} object The parent object of `objValue`.
2107     * @returns {*} Returns the value to assign.
2108     */
2109    function assignInDefaults(objValue, srcValue, key, object) {
2110      if (objValue === undefined ||
2111          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2112        return srcValue;
2113      }
2114      return objValue;
2115    }
2116
2117    /**
2118     * This function is like `assignValue` except that it doesn't assign `undefined` values.
2119     *
2120     * @private
2121     * @param {Object} object The object to modify.
2122     * @param {string} key The key of the property to assign.
2123     * @param {*} value The value to assign.
2124     */
2125    function assignMergeValue(object, key, value) {
2126      if ((value !== undefined && !eq(object[key], value)) ||
2127          (typeof key == 'number' && value === undefined && !(key in object))) {
2128        object[key] = value;
2129      }
2130    }
2131
2132    /**
2133     * Assigns `value` to `key` of `object` if the existing value is not equivalent
2134     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2135     * for equality comparisons.
2136     *
2137     * @private
2138     * @param {Object} object The object to modify.
2139     * @param {string} key The key of the property to assign.
2140     * @param {*} value The value to assign.
2141     */
2142    function assignValue(object, key, value) {
2143      var objValue = object[key];
2144      if ((!eq(objValue, value) ||
2145            (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
2146          (value === undefined && !(key in object))) {
2147        object[key] = value;
2148      }
2149    }
2150
2151    /**
2152     * Aggregates elements of `collection` on `accumulator` with keys transformed
2153     * by `iteratee` and values set by `setter`.
2154     *
2155     * @private
2156     * @param {Array|Object} collection The collection to iterate over.
2157     * @param {Function} setter The function to set `accumulator` values.
2158     * @param {Function} iteratee The iteratee to transform keys.
2159     * @param {Object} accumulator The initial aggregated object.
2160     * @returns {Function} Returns `accumulator`.
2161     */
2162    function baseAggregator(collection, setter, iteratee, accumulator) {
2163      baseEach(collection, function(value, key, collection) {
2164        setter(accumulator, value, iteratee(value), collection);
2165      });
2166      return accumulator;
2167    }
2168
2169    /**
2170     * The base implementation of `_.assign` without support for multiple sources
2171     * or `customizer` functions.
2172     *
2173     * @private
2174     * @param {Object} object The destination object.
2175     * @param {Object} source The source object.
2176     * @returns {Object} Returns `object`.
2177     */
2178    function baseAssign(object, source) {
2179      return object && copyObject(source, keys(source), object);
2180    }
2181
2182    /**
2183     * The base implementation of `_.at` without support for individual paths.
2184     *
2185     * @private
2186     * @param {Object} object The object to iterate over.
2187     * @param {string[]} paths The property paths of elements to pick.
2188     * @returns {Array} Returns the new array of picked elements.
2189     */
2190    function baseAt(object, paths) {
2191      var index = -1,
2192          isNil = object == null,
2193          length = paths.length,
2194          result = Array(length);
2195
2196      while (++index < length) {
2197        result[index] = isNil ? undefined : get(object, paths[index]);
2198      }
2199      return result;
2200    }
2201
2202    /**
2203     * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2204     *
2205     * @private
2206     * @param {number} number The number to clamp.
2207     * @param {number} [lower] The lower bound.
2208     * @param {number} upper The upper bound.
2209     * @returns {number} Returns the clamped number.
2210     */
2211    function baseClamp(number, lower, upper) {
2212      if (number === number) {
2213        if (upper !== undefined) {
2214          number = number <= upper ? number : upper;
2215        }
2216        if (lower !== undefined) {
2217          number = number >= lower ? number : lower;
2218        }
2219      }
2220      return number;
2221    }
2222
2223    /**
2224     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2225     * traversed objects.
2226     *
2227     * @private
2228     * @param {*} value The value to clone.
2229     * @param {boolean} [isDeep] Specify a deep clone.
2230     * @param {Function} [customizer] The function to customize cloning.
2231     * @param {string} [key] The key of `value`.
2232     * @param {Object} [object] The parent object of `value`.
2233     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2234     * @returns {*} Returns the cloned value.
2235     */
2236    function baseClone(value, isDeep, customizer, key, object, stack) {
2237      var result;
2238      if (customizer) {
2239        result = object ? customizer(value, key, object, stack) : customizer(value);
2240      }
2241      if (result !== undefined) {
2242        return result;
2243      }
2244      if (!isObject(value)) {
2245        return value;
2246      }
2247      var isArr = isArray(value);
2248      if (isArr) {
2249        result = initCloneArray(value);
2250        if (!isDeep) {
2251          return copyArray(value, result);
2252        }
2253      } else {
2254        var tag = getTag(value),
2255            isFunc = tag == funcTag || tag == genTag;
2256
2257        if (isBuffer(value)) {
2258          return cloneBuffer(value, isDeep);
2259        }
2260        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2261          if (isHostObject(value)) {
2262            return object ? value : {};
2263          }
2264          result = initCloneObject(isFunc ? {} : value);
2265          if (!isDeep) {
2266            return copySymbols(value, baseAssign(result, value));
2267          }
2268        } else {
2269          return cloneableTags[tag]
2270            ? initCloneByTag(value, tag, isDeep)
2271            : (object ? value : {});
2272        }
2273      }
2274      // Check for circular references and return its corresponding clone.
2275      stack || (stack = new Stack);
2276      var stacked = stack.get(value);
2277      if (stacked) {
2278        return stacked;
2279      }
2280      stack.set(value, result);
2281
2282      // Recursively populate clone (susceptible to call stack limits).
2283      (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2284        assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
2285      });
2286      return isArr ? result : copySymbols(value, result);
2287    }
2288
2289    /**
2290     * The base implementation of `_.conforms` which doesn't clone `source`.
2291     *
2292     * @private
2293     * @param {Object} source The object of property predicates to conform to.
2294     * @returns {Function} Returns the new function.
2295     */
2296    function baseConforms(source) {
2297      var props = keys(source),
2298          length = props.length;
2299
2300      return function(object) {
2301        if (object == null) {
2302          return !length;
2303        }
2304        var index = length;
2305        while (index--) {
2306          var key = props[index],
2307              predicate = source[key],
2308              value = object[key];
2309
2310          if ((value === undefined && !(key in Object(object))) || !predicate(value)) {
2311            return false;
2312          }
2313        }
2314        return true;
2315      };
2316    }
2317
2318    /**
2319     * The base implementation of `_.create` without support for assigning
2320     * properties to the created object.
2321     *
2322     * @private
2323     * @param {Object} prototype The object to inherit from.
2324     * @returns {Object} Returns the new object.
2325     */
2326    var baseCreate = (function() {
2327      function object() {}
2328      return function(prototype) {
2329        if (isObject(prototype)) {
2330          object.prototype = prototype;
2331          var result = new object;
2332          object.prototype = undefined;
2333        }
2334        return result || {};
2335      };
2336    }());
2337
2338    /**
2339     * The base implementation of `_.delay` and `_.defer` which accepts an array
2340     * of `func` arguments.
2341     *
2342     * @private
2343     * @param {Function} func The function to delay.
2344     * @param {number} wait The number of milliseconds to delay invocation.
2345     * @param {Object} args The arguments to provide to `func`.
2346     * @returns {number} Returns the timer id.
2347     */
vendor: 4,428 bytes, lines 2348-2481
2348    function baseDelay(func, wait, args) {
2349      if (typeof func != 'function') {
2350        throw new TypeError(FUNC_ERROR_TEXT);
2351      }
2352      return setTimeout(function() { func.apply(undefined, args); }, wait);
2353    }
2354
2355    /**
2356     * The base implementation of methods like `_.difference` without support for
2357     * excluding multiple arrays or iteratee shorthands.
2358     *
2359     * @private
2360     * @param {Array} array The array to inspect.
2361     * @param {Array} values The values to exclude.
2362     * @param {Function} [iteratee] The iteratee invoked per element.
2363     * @param {Function} [comparator] The comparator invoked per element.
2364     * @returns {Array} Returns the new array of filtered values.
2365     */
2366    function baseDifference(array, values, iteratee, comparator) {
2367      var index = -1,
2368          includes = arrayIncludes,
2369          isCommon = true,
2370          length = array.length,
2371          result = [],
2372          valuesLength = values.length;
2373
2374      if (!length) {
2375        return result;
2376      }
2377      if (iteratee) {
2378        values = arrayMap(values, baseUnary(iteratee));
2379      }
2380      if (comparator) {
2381        includes = arrayIncludesWith;
2382        isCommon = false;
2383      }
2384      else if (values.length >= LARGE_ARRAY_SIZE) {
2385        includes = cacheHas;
2386        isCommon = false;
2387        values = new SetCache(values);
2388      }
2389      outer:
2390      while (++index < length) {
2391        var value = array[index],
2392            computed = iteratee ? iteratee(value) : value;
2393
2394        if (isCommon && computed === computed) {
2395          var valuesIndex = valuesLength;
2396          while (valuesIndex--) {
2397            if (values[valuesIndex] === computed) {
2398              continue outer;
2399            }
2400          }
2401          result.push(value);
2402        }
2403        else if (!includes(values, computed, comparator)) {
2404          result.push(value);
2405        }
2406      }
2407      return result;
2408    }
2409
2410    /**
2411     * The base implementation of `_.forEach` without support for iteratee shorthands.
2412     *
2413     * @private
2414     * @param {Array|Object} collection The collection to iterate over.
2415     * @param {Function} iteratee The function invoked per iteration.
2416     * @returns {Array|Object} Returns `collection`.
2417     */
2418    var baseEach = createBaseEach(baseForOwn);
2419
2420    /**
2421     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2422     *
2423     * @private
2424     * @param {Array|Object} collection The collection to iterate over.
2425     * @param {Function} iteratee The function invoked per iteration.
2426     * @returns {Array|Object} Returns `collection`.
2427     */
2428    var baseEachRight = createBaseEach(baseForOwnRight, true);
2429
2430    /**
2431     * The base implementation of `_.every` without support for iteratee shorthands.
2432     *
2433     * @private
2434     * @param {Array|Object} collection The collection to iterate over.
2435     * @param {Function} predicate The function invoked per iteration.
2436     * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
2437     */
2438    function baseEvery(collection, predicate) {
2439      var result = true;
2440      baseEach(collection, function(value, index, collection) {
2441        result = !!predicate(value, index, collection);
2442        return result;
2443      });
2444      return result;
2445    }
2446
2447    /**
2448     * The base implementation of `_.fill` without an iteratee call guard.
2449     *
2450     * @private
2451     * @param {Array} array The array to fill.
2452     * @param {*} value The value to fill `array` with.
2453     * @param {number} [start=0] The start position.
2454     * @param {number} [end=array.length] The end position.
2455     * @returns {Array} Returns `array`.
2456     */
2457    function baseFill(array, value, start, end) {
2458      var length = array.length;
2459
2460      start = toInteger(start);
2461      if (start < 0) {
2462        start = -start > length ? 0 : (length + start);
2463      }
2464      end = (end === undefined || end > length) ? length : toInteger(end);
2465      if (end < 0) {
2466        end += length;
2467      }
2468      end = start > end ? 0 : toLength(end);
2469      while (start < end) {
2470        array[start++] = value;
2471      }
2472      return array;
2473    }
2474
2475    /**
2476     * The base implementation of `_.filter` without support for iteratee shorthands.
2477     *
2478     * @private
2479     * @param {Array|Object} collection The collection to iterate over.
2480     * @param {Function} predicate The function invoked per iteration.
2481     * @returns {Array} Returns the new filtered array.
2482     */
2483    function baseFilter(collection, predicate) {
2484      var result = [];
2485      baseEach(collection, function(value, index, collection) {
2486        if (predicate(value, index, collection)) {
2487          result.push(value);
2488        }
2489      });
2490      return result;
2491    }
2492
2493    /**
2494     * The base implementation of `_.flatten` with support for restricting flattening.
2495     *
2496     * @private
2497     * @param {Array} array The array to flatten.
2498     * @param {boolean} [isDeep] Specify a deep flatten.
2499     * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
2500     * @param {Array} [result=[]] The initial result value.
2501     * @returns {Array} Returns the new flattened array.
2502     */
2503    function baseFlatten(array, isDeep, isStrict, result) {
2504      result || (result = []);
2505
2506      var index = -1,
2507          length = array.length;
2508
2509      while (++index < length) {
2510        var value = array[index];
2511        if (isArrayLikeObject(value) &&
2512            (isStrict || isArray(value) || isArguments(value))) {
2513          if (isDeep) {
2514            // Recursively flatten arrays (susceptible to call stack limits).
2515            baseFlatten(value, isDeep, isStrict, result);
2516          } else {
2517            arrayPush(result, value);
2518          }
2519        } else if (!isStrict) {
2520          result[result.length] = value;
2521        }
2522      }
2523      return result;
2524    }
2525
2526    /**
2527     * The base implementation of `baseForIn` and `baseForOwn` which iterates
2528     * over `object` properties returned by `keysFunc` invoking `iteratee` for
2529     * each property. Iteratee functions may exit iteration early by explicitly
2530     * returning `false`.
2531     *
2532     * @private
2533     * @param {Object} object The object to iterate over.
2534     * @param {Function} iteratee The function invoked per iteration.
2535     * @param {Function} keysFunc The function to get the keys of `object`.
2536     * @returns {Object} Returns `object`.
2537     */
2538    var baseFor = createBaseFor();
2539
2540    /**
2541     * This function is like `baseFor` except that it iterates over properties
2542     * in the opposite order.
2543     *
2544     * @private
2545     * @param {Object} object The object to iterate over.
2546     * @param {Function} iteratee The function invoked per iteration.
2547     * @param {Function} keysFunc The function to get the keys of `object`.
2548     * @returns {Object} Returns `object`.
2549     */
2550    var baseForRight = createBaseFor(true);
2551
2552    /**
2553     * The base implementation of `_.forIn` without support for iteratee shorthands.
2554     *
2555     * @private
2556     * @param {Object} object The object to iterate over.
2557     * @param {Function} iteratee The function invoked per iteration.
2558     * @returns {Object} Returns `object`.
2559     */
2560    function baseForIn(object, iteratee) {
2561      return object == null ? object : baseFor(object, iteratee, keysIn);
2562    }
2563
2564    /**
2565     * The base implementation of `_.forOwn` without support for iteratee shorthands.
2566     *
2567     * @private
2568     * @param {Object} object The object to iterate over.
2569     * @param {Function} iteratee The function invoked per iteration.
2570     * @returns {Object} Returns `object`.
2571     */
2572    function baseForOwn(object, iteratee) {
2573      return object && baseFor(object, iteratee, keys);
2574    }
2575
2576    /**
2577     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2578     *
2579     * @private
2580     * @param {Object} object The object to iterate over.
2581     * @param {Function} iteratee The function invoked per iteration.
2582     * @returns {Object} Returns `object`.
2583     */
2584    function baseForOwnRight(object, iteratee) {
2585      return object && baseForRight(object, iteratee, keys);
2586    }
2587
2588    /**
2589     * The base implementation of `_.functions` which creates an array of
2590     * `object` function property names filtered from `props`.
2591     *
2592     * @private
2593     * @param {Object} object The object to inspect.
2594     * @param {Array} props The property names to filter.
2595     * @returns {Array} Returns the new array of filtered property names.
2596     */
2597    function baseFunctions(object, props) {
2598      return arrayFilter(props, function(key) {
2599        return isFunction(object[key]);
2600      });
2601    }
2602
2603    /**
2604     * The base implementation of `_.get` without support for default values.
2605     *
2606     * @private
2607     * @param {Object} object The object to query.
2608     * @param {Array|string} path The path of the property to get.
2609     * @returns {*} Returns the resolved value.
2610     */
2611    function baseGet(object, path) {
2612      path = isKey(path, object) ? [path + ''] : baseToPath(path);
2613
2614      var index = 0,
2615          length = path.length;
2616
2617      while (object != null && index < length) {
2618        object = object[path[index++]];
2619      }
2620      return (index && index == length) ? object : undefined;
2621    }
2622
2623    /**
2624     * The base implementation of `_.has` without support for deep paths.
2625     *
2626     * @private
2627     * @param {Object} object The object to query.
2628     * @param {Array|string} key The key to check.
2629     * @returns {boolean} Returns `true` if `key` exists, else `false`.
2630     */
2631    function baseHas(object, key) {
2632      // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2633      // that are composed entirely of index properties, return `false` for
2634      // `hasOwnProperty` checks of them.
2635      return hasOwnProperty.call(object, key) ||
2636        (typeof object == 'object' && key in object && getPrototypeOf(object) === null);
2637    }
2638
2639    /**
2640     * The base implementation of `_.hasIn` without support for deep paths.
2641     *
2642     * @private
2643     * @param {Object} object The object to query.
2644     * @param {Array|string} key The key to check.
2645     * @returns {boolean} Returns `true` if `key` exists, else `false`.
2646     */
2647    function baseHasIn(object, key) {
2648      return key in Object(object);
2649    }
2650
2651    /**
2652     * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2653     *
2654     * @private
2655     * @param {number} number The number to check.
2656     * @param {number} start The start of the range.
2657     * @param {number} end The end of the range.
2658     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2659     */
2660    function baseInRange(number, start, end) {
2661      return number >= nativeMin(start, end) && number < nativeMax(start, end);
2662    }
2663
2664    /**
2665     * The base implementation of methods like `_.intersection`, without support
2666     * for iteratee shorthands, that accepts an array of arrays to inspect.
2667     *
2668     * @private
2669     * @param {Array} arrays The arrays to inspect.
2670     * @param {Function} [iteratee] The iteratee invoked per element.
2671     * @param {Function} [comparator] The comparator invoked per element.
2672     * @returns {Array} Returns the new array of shared values.
2673     */
2674    function baseIntersection(arrays, iteratee, comparator) {
2675      var includes = comparator ? arrayIncludesWith : arrayIncludes,
2676          othLength = arrays.length,
2677          othIndex = othLength,
2678          caches = Array(othLength),
2679          result = [];
2680
2681      while (othIndex--) {
2682        var array = arrays[othIndex];
2683        if (othIndex && iteratee) {
2684          array = arrayMap(array, baseUnary(iteratee));
2685        }
2686        caches[othIndex] = !comparator && (iteratee || array.length >= 120)
2687          ? new SetCache(othIndex && array)
2688          : undefined;
2689      }
2690      array = arrays[0];
2691
2692      var index = -1,
2693          length = array.length,
2694          seen = caches[0];
2695
2696      outer:
2697      while (++index < length) {
2698        var value = array[index],
2699            computed = iteratee ? iteratee(value) : value;
2700
2701        if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) {
2702          var othIndex = othLength;
2703          while (--othIndex) {
2704            var cache = caches[othIndex];
2705            if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) {
2706              continue outer;
2707            }
2708          }
2709          if (seen) {
2710            seen.push(computed);
2711          }
2712          result.push(value);
2713        }
2714      }
2715      return result;
2716    }
2717
2718    /**
2719     * The base implementation of `_.invert` and `_.invertBy` which inverts
2720     * `object` with values transformed by `iteratee` and set by `setter`.
2721     *
2722     * @private
2723     * @param {Object} object The object to iterate over.
2724     * @param {Function} setter The function to set `accumulator` values.
2725     * @param {Function} iteratee The iteratee to transform values.
2726     * @param {Object} accumulator The initial inverted object.
2727     * @returns {Function} Returns `accumulator`.
2728     */
2729    function baseInverter(object, setter, iteratee, accumulator) {
2730      baseForOwn(object, function(value, key, object) {
2731        setter(accumulator, iteratee(value), key, object);
2732      });
2733      return accumulator;
2734    }
2735
2736    /**
2737     * The base implementation of `_.invoke` without support for individual
2738     * method arguments.
2739     *
2740     * @private
2741     * @param {Object} object The object to query.
2742     * @param {Array|string} path The path of the method to invoke.
2743     * @param {Array} args The arguments to invoke the method with.
2744     * @returns {*} Returns the result of the invoked method.
2745     */
2746    function baseInvoke(object, path, args) {
2747      if (!isKey(path, object)) {
2748        path = baseToPath(path);
2749        object = parent(object, path);
2750        path = last(path);
2751      }
2752      var func = object == null ? object : object[path];
2753      return func == null ? undefined : apply(func, object, args);
2754    }
2755
2756    /**
2757     * The base implementation of `_.isEqual` which supports partial comparisons
2758     * and tracks traversed objects.
2759     *
2760     * @private
2761     * @param {*} value The value to compare.
2762     * @param {*} other The other value to compare.
2763     * @param {Function} [customizer] The function to customize comparisons.
2764     * @param {boolean} [bitmask] The bitmask of comparison flags.
2765     *  The bitmask may be composed of the following flags:
2766     *     1 - Unordered comparison
2767     *     2 - Partial comparison
2768     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2769     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2770     */
2771    function baseIsEqual(value, other, customizer, bitmask, stack) {
2772      if (value === other) {
2773        return true;
2774      }
2775      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2776        return value !== value && other !== other;
2777      }
2778      return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2779    }
2780
2781    /**
2782     * A specialized version of `baseIsEqual` for arrays and objects which performs
2783     * deep comparisons and tracks traversed objects enabling objects with circular
2784     * references to be compared.
2785     *
2786     * @private
2787     * @param {Object} object The object to compare.
2788     * @param {Object} other The other object to compare.
2789     * @param {Function} equalFunc The function to determine equivalents of values.
2790     * @param {Function} [customizer] The function to customize comparisons.
2791     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
2792     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2793     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2794     */
2795    function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2796      var objIsArr = isArray(object),
2797          othIsArr = isArray(other),
2798          objTag = arrayTag,
2799          othTag = arrayTag;
2800
2801      if (!objIsArr) {
2802        objTag = getTag(object);
2803        if (objTag == argsTag) {
2804          objTag = objectTag;
2805        } else if (objTag != objectTag) {
2806          objIsArr = isTypedArray(object);
2807        }
2808      }
2809      if (!othIsArr) {
2810        othTag = getTag(other);
2811        if (othTag == argsTag) {
2812          othTag = objectTag;
2813        } else if (othTag != objectTag) {
2814          othIsArr = isTypedArray(other);
2815        }
2816      }
2817      var objIsObj = objTag == objectTag && !isHostObject(object),
2818          othIsObj = othTag == objectTag && !isHostObject(other),
2819          isSameTag = objTag == othTag;
2820
2821      if (isSameTag && !(objIsArr || objIsObj)) {
2822        return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
2823      }
2824      var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
2825      if (!isPartial) {
2826        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2827            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2828
2829        if (objIsWrapped || othIsWrapped) {
2830          return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
2831        }
2832      }
2833      if (!isSameTag) {
2834        return false;
2835      }
2836      stack || (stack = new Stack);
2837      return (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
2838    }
2839
2840    /**
2841     * The base implementation of `_.isMatch` without support for iteratee shorthands.
2842     *
2843     * @private
2844     * @param {Object} object The object to inspect.
2845     * @param {Object} source The object of property values to match.
2846     * @param {Array} matchData The property names, values, and compare flags to match.
2847     * @param {Function} [customizer] The function to customize comparisons.
2848     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2849     */
2850    function baseIsMatch(object, source, matchData, customizer) {
2851      var index = matchData.length,
2852          length = index,
2853          noCustomizer = !customizer;
2854
2855      if (object == null) {
2856        return !length;
2857      }
2858      object = Object(object);
2859      while (index--) {
2860        var data = matchData[index];
2861        if ((noCustomizer && data[2])
2862              ? data[1] !== object[data[0]]
2863              : !(data[0] in object)
2864            ) {
2865          return false;
2866        }
2867      }
2868      while (++index < length) {
2869        data = matchData[index];
2870        var key = data[0],
2871            objValue = object[key],
2872            srcValue = data[1];
2873
2874        if (noCustomizer && data[2]) {
2875          if (objValue === undefined && !(key in object)) {
2876            return false;
2877          }
2878        } else {
2879          var stack = new Stack,
2880              result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
2881
2882          if (!(result === undefined
2883                ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
2884                : result
2885              )) {
2886            return false;
2887          }
2888        }
2889      }
2890      return true;
2891    }
2892
2893    /**
2894     * The base implementation of `_.iteratee`.
2895     *
2896     * @private
2897     * @param {*} [value=_.identity] The value to convert to an iteratee.
2898     * @returns {Function} Returns the iteratee.
2899     */
2900    function baseIteratee(value) {
2901      var type = typeof value;
2902      if (type == 'function') {
2903        return value;
2904      }
2905      if (value == null) {
2906        return identity;
2907      }
2908      if (type == 'object') {
2909        return isArray(value)
2910          ? baseMatchesProperty(value[0], value[1])
2911          : baseMatches(value);
2912      }
2913      return property(value);
2914    }
2915
2916    /**
2917     * The base implementation of `_.keys` which doesn't skip the constructor
2918     * property of prototypes or treat sparse arrays as dense.
2919     *
2920     * @private
2921     * @type Function
2922     * @param {Object} object The object to query.
2923     * @returns {Array} Returns the array of property names.
2924     */
2925    function baseKeys(object) {
2926      return nativeKeys(Object(object));
2927    }
2928
2929    /**
2930     * The base implementation of `_.keysIn` which doesn't skip the constructor
2931     * property of prototypes or treat sparse arrays as dense.
2932     *
2933     * @private
2934     * @param {Object} object The object to query.
2935     * @returns {Array} Returns the array of property names.
2936     */
2937    function baseKeysIn(object) {
2938      object = object == null ? object : Object(object);
2939
2940      var result = [];
2941      for (var key in object) {
2942        result.push(key);
2943      }
2944      return result;
2945    }
2946
2947    // Fallback for IE < 9 with es6-shim.
2948    if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
2949      baseKeysIn = function(object) {
2950        return iteratorToArray(enumerate(object));
2951      };
2952    }
2953
2954    /**
2955     * The base implementation of `_.map` without support for iteratee shorthands.
2956     *
2957     * @private
2958     * @param {Array|Object} collection The collection to iterate over.
2959     * @param {Function} iteratee The function invoked per iteration.
2960     * @returns {Array} Returns the new mapped array.
2961     */
2962    function baseMap(collection, iteratee) {
2963      var index = -1,
2964          result = isArrayLike(collection) ? Array(collection.length) : [];
2965
2966      baseEach(collection, function(value, key, collection) {
2967        result[++index] = iteratee(value, key, collection);
2968      });
2969      return result;
2970    }
2971
2972    /**
2973     * The base implementation of `_.matches` which doesn't clone `source`.
2974     *
2975     * @private
2976     * @param {Object} source The object of property values to match.
2977     * @returns {Function} Returns the new function.
2978     */
2979    function baseMatches(source) {
2980      var matchData = getMatchData(source);
2981      if (matchData.length == 1 && matchData[0][2]) {
2982        var key = matchData[0][0],
2983            value = matchData[0][1];
2984
2985        return function(object) {
2986          if (object == null) {
2987            return false;
2988          }
2989          return object[key] === value &&
2990            (value !== undefined || (key in Object(object)));
2991        };
2992      }
2993      return function(object) {
2994        return object === source || baseIsMatch(object, source, matchData);
2995      };
2996    }
2997
2998    /**
2999     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3000     *
3001     * @private
3002     * @param {string} path The path of the property to get.
3003     * @param {*} srcValue The value to match.
3004     * @returns {Function} Returns the new function.
3005     */
3006    function baseMatchesProperty(path, srcValue) {
3007      return function(object) {
3008        var objValue = get(object, path);
3009        return (objValue === undefined && objValue === srcValue)
3010          ? hasIn(object, path)
3011          : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
3012      };
3013    }
3014
3015    /**
3016     * The base implementation of `_.merge` without support for multiple sources.
3017     *
3018     * @private
3019     * @param {Object} object The destination object.
3020     * @param {Object} source The source object.
3021     * @param {number} srcIndex The index of `source`.
3022     * @param {Function} [customizer] The function to customize merged values.
3023     * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3024     */
3025    function baseMerge(object, source, srcIndex, customizer, stack) {
3026      if (object === source) {
3027        return;
3028      }
3029      var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source);
3030      arrayEach(props || source, function(srcValue, key) {
3031        if (props) {
3032          key = srcValue;
3033          srcValue = source[key];
3034        }
3035        if (isObject(srcValue)) {
3036          stack || (stack = new Stack);
3037          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3038        }
3039        else {
3040          var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
3041          if (newValue === undefined) {
3042            newValue = srcValue;
3043          }
3044          assignMergeValue(object, key, newValue);
3045        }
3046      });
3047    }
3048
3049    /**
3050     * A specialized version of `baseMerge` for arrays and objects which performs
3051     * deep merges and tracks traversed objects enabling objects with circular
3052     * references to be merged.
3053     *
3054     * @private
3055     * @param {Object} object The destination object.
3056     * @param {Object} source The source object.
3057     * @param {string} key The key of the value to merge.
3058     * @param {number} srcIndex The index of `source`.
3059     * @param {Function} mergeFunc The function to merge values.
3060     * @param {Function} [customizer] The function to customize assigned values.
3061     * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
3062     */
3063    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3064      var objValue = object[key],
3065          srcValue = source[key],
3066          stacked = stack.get(srcValue);
3067
3068      if (stacked) {
3069        assignMergeValue(object, key, stacked);
3070        return;
3071      }
3072      var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined,
3073          isCommon = newValue === undefined;
3074
3075      if (isCommon) {
3076        newValue = srcValue;
3077        if (isArray(srcValue) || isTypedArray(srcValue)) {
3078          if (isArray(objValue)) {
3079            newValue = srcIndex ? copyArray(objValue) : objValue;
3080          }
3081          else if (isArrayLikeObject(objValue)) {
3082            newValue = copyArray(objValue);
3083          }
3084          else {
3085            isCommon = false;
3086            newValue = baseClone(srcValue);
3087          }
3088        }
3089        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3090          if (isArguments(objValue)) {
3091            newValue = toPlainObject(objValue);
3092          }
3093          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3094            isCommon = false;
3095            newValue = baseClone(srcValue);
3096          }
3097          else {
3098            newValue = srcIndex ? baseClone(objValue) : objValue;
3099          }
3100        }
3101        else {
3102          isCommon = false;
3103        }
3104      }
3105      stack.set(srcValue, newValue);
3106
3107      if (isCommon) {
3108        // Recursively merge objects and arrays (susceptible to call stack limits).
3109        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3110      }
3111      assignMergeValue(object, key, newValue);
3112    }
3113
3114    /**
3115     * The base implementation of `_.orderBy` without param guards.
3116     *
3117     * @private
3118     * @param {Array|Object} collection The collection to iterate over.
3119     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3120     * @param {string[]} orders The sort orders of `iteratees`.
3121     * @returns {Array} Returns the new sorted array.
3122     */
3123    function baseOrderBy(collection, iteratees, orders) {
3124      var index = -1,
3125          toIteratee = getIteratee();
3126
3127      iteratees = arrayMap(iteratees.length ? iteratees : Array(1), function(iteratee) {
3128        return toIteratee(iteratee);
3129      });
3130
3131      var result = baseMap(collection, function(value, key, collection) {
3132        var criteria = arrayMap(iteratees, function(iteratee) {
3133          return iteratee(value);
3134        });
3135        return { 'criteria': criteria, 'index': ++index, 'value': value };
3136      });
3137
3138      return baseSortBy(result, function(object, other) {
3139        return compareMultiple(object, other, orders);
3140      });
3141    }
3142
3143    /**
3144     * The base implementation of `_.pick` without support for individual
3145     * property names.
3146     *
3147     * @private
3148     * @param {Object} object The source object.
3149     * @param {string[]} props The property names to pick.
3150     * @returns {Object} Returns the new object.
3151     */
3152    function basePick(object, props) {
3153      object = Object(object);
3154      return arrayReduce(props, function(result, key) {
3155        if (key in object) {
3156          result[key] = object[key];
3157        }
3158        return result;
3159      }, {});
3160    }
3161
3162    /**
3163     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3164     *
3165     * @private
3166     * @param {Object} object The source object.
3167     * @param {Function} predicate The function invoked per property.
3168     * @returns {Object} Returns the new object.
3169     */
3170    function basePickBy(object, predicate) {
3171      var result = {};
3172      baseForIn(object, function(value, key) {
3173        if (predicate(value, key)) {
3174          result[key] = value;
3175        }
3176      });
3177      return result;
3178    }
3179
3180    /**
3181     * The base implementation of `_.property` without support for deep paths.
3182     *
3183     * @private
3184     * @param {string} key The key of the property to get.
3185     * @returns {Function} Returns the new function.
3186     */
3187    function baseProperty(key) {
3188      return function(object) {
3189        return object == null ? undefined : object[key];
3190      };
3191    }
3192
3193    /**
3194     * A specialized version of `baseProperty` which supports deep paths.
3195     *
3196     * @private
3197     * @param {Array|string} path The path of the property to get.
3198     * @returns {Function} Returns the new function.
3199     */
3200    function basePropertyDeep(path) {
3201      return function(object) {
3202        return baseGet(object, path);
3203      };
3204    }
3205
3206    /**
3207     * The base implementation of `_.pullAll`.
3208     *
3209     * @private
3210     * @param {Array} array The array to modify.
3211     * @param {Array} values The values to remove.
3212     * @returns {Array} Returns `array`.
3213     */
3214    function basePullAll(array, values) {
3215      return basePullAllBy(array, values);
3216    }
3217
3218    /**
3219     * The base implementation of `_.pullAllBy` without support for iteratee
3220     * shorthands.
3221     *
3222     * @private
3223     * @param {Array} array The array to modify.
3224     * @param {Array} values The values to remove.
3225     * @param {Function} [iteratee] The iteratee invoked per element.
3226     * @returns {Array} Returns `array`.
3227     */
3228    function basePullAllBy(array, values, iteratee) {
3229      var index = -1,
3230          length = values.length,
3231          seen = array;
3232
3233      if (iteratee) {
3234        seen = arrayMap(array, function(value) { return iteratee(value); });
3235      }
3236      while (++index < length) {
3237        var fromIndex = 0,
3238            value = values[index],
3239            computed = iteratee ? iteratee(value) : value;
3240
3241        while ((fromIndex = baseIndexOf(seen, computed, fromIndex)) > -1) {
3242          if (seen !== array) {
3243            splice.call(seen, fromIndex, 1);
3244          }
3245          splice.call(array, fromIndex, 1);
3246        }
3247      }
3248      return array;
3249    }
3250
3251    /**
3252     * The base implementation of `_.pullAt` without support for individual
3253     * indexes or capturing the removed elements.
3254     *
3255     * @private
3256     * @param {Array} array The array to modify.
3257     * @param {number[]} indexes The indexes of elements to remove.
3258     * @returns {Array} Returns `array`.
3259     */
3260    function basePullAt(array, indexes) {
3261      var length = array ? indexes.length : 0,
3262          lastIndex = length - 1;
3263
3264      while (length--) {
3265        var index = indexes[length];
3266        if (lastIndex == length || index != previous) {
3267          var previous = index;
3268          if (isIndex(index)) {
3269            splice.call(array, index, 1);
3270          }
3271          else if (!isKey(index, array)) {
3272            var path = baseToPath(index),
3273                object = parent(array, path);
3274
3275            if (object != null) {
3276              delete object[last(path)];
3277            }
3278          }
3279          else {
3280            delete array[index];
3281          }
3282        }
3283      }
3284      return array;
3285    }
3286
3287    /**
3288     * The base implementation of `_.random` without support for returning
3289     * floating-point numbers.
3290     *
3291     * @private
3292     * @param {number} lower The lower bound.
3293     * @param {number} upper The upper bound.
3294     * @returns {number} Returns the random number.
3295     */
3296    function baseRandom(lower, upper) {
3297      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3298    }
3299
3300    /**
3301     * The base implementation of `_.range` and `_.rangeRight` which doesn't
3302     * coerce arguments to numbers.
3303     *
3304     * @private
3305     * @param {number} start The start of the range.
3306     * @param {number} end The end of the range.
3307     * @param {number} step The value to increment or decrement by.
3308     * @param {boolean} [fromRight] Specify iterating from right to left.
3309     * @returns {Array} Returns the new array of numbers.
3310     */
3311    function baseRange(start, end, step, fromRight) {
3312      var index = -1,
3313          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3314          result = Array(length);
3315
3316      while (length--) {
3317        result[fromRight ? length : ++index] = start;
3318        start += step;
3319      }
3320      return result;
3321    }
3322
3323    /**
3324     * The base implementation of `_.set`.
3325     *
3326     * @private
3327     * @param {Object} object The object to query.
3328     * @param {Array|string} path The path of the property to set.
3329     * @param {*} value The value to set.
3330     * @param {Function} [customizer] The function to customize path creation.
3331     * @returns {Object} Returns `object`.
3332     */
3333    function baseSet(object, path, value, customizer) {
3334      path = isKey(path, object) ? [path + ''] : baseToPath(path);
3335
3336      var index = -1,
3337          length = path.length,
3338          lastIndex = length - 1,
3339          nested = object;
3340
3341      while (nested != null && ++index < length) {
3342        var key = path[index];
3343        if (isObject(nested)) {
3344          var newValue = value;
3345          if (index != lastIndex) {
3346            var objValue = nested[key];
3347            newValue = customizer ? customizer(objValue, key, nested) : undefined;
3348            if (newValue === undefined) {
3349              newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue;
3350            }
3351          }
3352          assignValue(nested, key, newValue);
3353        }
3354        nested = nested[key];
3355      }
3356      return object;
3357    }
3358
3359    /**
3360     * The base implementation of `setData` without support for hot loop detection.
3361     *
3362     * @private
3363     * @param {Function} func The function to associate metadata with.
3364     * @param {*} data The metadata.
3365     * @returns {Function} Returns `func`.
3366     */
3367    var baseSetData = !metaMap ? identity : function(func, data) {
3368      metaMap.set(func, data);
3369      return func;
3370    };
3371
3372    /**
3373     * The base implementation of `_.slice` without an iteratee call guard.
3374     *
3375     * @private
3376     * @param {Array} array The array to slice.
3377     * @param {number} [start=0] The start position.
3378     * @param {number} [end=array.length] The end position.
3379     * @returns {Array} Returns the slice of `array`.
3380     */
3381    function baseSlice(array, start, end) {
3382      var index = -1,
3383          length = array.length;
3384
3385      if (start < 0) {
3386        start = -start > length ? 0 : (length + start);
3387      }
3388      end = end > length ? length : end;
3389      if (end < 0) {
3390        end += length;
3391      }
3392      length = start > end ? 0 : ((end - start) >>> 0);
3393      start >>>= 0;
3394
3395      var result = Array(length);
3396      while (++index < length) {
3397        result[index] = array[index + start];
3398      }
3399      return result;
3400    }
3401
3402    /**
3403     * The base implementation of `_.some` without support for iteratee shorthands.
3404     *
3405     * @private
3406     * @param {Array|Object} collection The collection to iterate over.
3407     * @param {Function} predicate The function invoked per iteration.
3408     * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
3409     */
3410    function baseSome(collection, predicate) {
3411      var result;
3412
3413      baseEach(collection, function(value, index, collection) {
3414        result = predicate(value, index, collection);
3415        return !result;
3416      });
3417      return !!result;
3418    }
3419
3420    /**
3421     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3422     * performs a binary search of `array` to determine the index at which `value`
3423     * should be inserted into `array` in order to maintain its sort order.
3424     *
3425     * @private
3426     * @param {Array} array The sorted array to inspect.
3427     * @param {*} value The value to evaluate.
3428     * @param {boolean} [retHighest] Specify returning the highest qualified index.
3429     * @returns {number} Returns the index at which `value` should be inserted
3430     *  into `array`.
3431     */
3432    function baseSortedIndex(array, value, retHighest) {
3433      var low = 0,
3434          high = array ? array.length : low;
3435
3436      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3437        while (low < high) {
3438          var mid = (low + high) >>> 1,
3439              computed = array[mid];
3440
3441          if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
3442            low = mid + 1;
3443          } else {
3444            high = mid;
3445          }
3446        }
3447        return high;
3448      }
3449      return baseSortedIndexBy(array, value, identity, retHighest);
3450    }
3451
3452    /**
3453     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3454     * which invokes `iteratee` for `value` and each element of `array` to compute
3455     * their sort ranking. The iteratee is invoked with one argument; (value).
3456     *
3457     * @private
3458     * @param {Array} array The sorted array to inspect.
3459     * @param {*} value The value to evaluate.
3460     * @param {Function} iteratee The iteratee invoked per element.
3461     * @param {boolean} [retHighest] Specify returning the highest qualified index.
3462     * @returns {number} Returns the index at which `value` should be inserted into `array`.
3463     */
3464    function baseSortedIndexBy(array, value, iteratee, retHighest) {
3465      value = iteratee(value);
3466
3467      var low = 0,
3468          high = array ? array.length : 0,
3469          valIsNaN = value !== value,
3470          valIsNull = value === null,
3471          valIsUndef = value === undefined;
3472
3473      while (low < high) {
3474        var mid = nativeFloor((low + high) / 2),
3475            computed = iteratee(array[mid]),
3476            isDef = computed !== undefined,
3477            isReflexive = computed === computed;
3478
3479        if (valIsNaN) {
3480          var setLow = isReflexive || retHighest;
3481        } else if (valIsNull) {
3482          setLow = isReflexive && isDef && (retHighest || computed != null);
3483        } else if (valIsUndef) {
3484          setLow = isReflexive && (retHighest || isDef);
3485        } else if (computed == null) {
3486          setLow = false;
3487        } else {
3488          setLow = retHighest ? (computed <= value) : (computed < value);
3489        }
3490        if (setLow) {
3491          low = mid + 1;
3492        } else {
3493          high = mid;
3494        }
3495      }
3496      return nativeMin(high, MAX_ARRAY_INDEX);
3497    }
3498
3499    /**
3500     * The base implementation of `_.sortedUniq`.
3501     *
3502     * @private
3503     * @param {Array} array The array to inspect.
3504     * @returns {Array} Returns the new duplicate free array.
3505     */
3506    function baseSortedUniq(array) {
3507      return baseSortedUniqBy(array);
3508    }
3509
3510    /**
3511     * The base implementation of `_.sortedUniqBy` without support for iteratee
3512     * shorthands.
3513     *
3514     * @private
3515     * @param {Array} array The array to inspect.
3516     * @param {Function} [iteratee] The iteratee invoked per element.
3517     * @returns {Array} Returns the new duplicate free array.
3518     */
3519    function baseSortedUniqBy(array, iteratee) {
3520      var index = 0,
3521          length = array.length,
3522          value = array[0],
3523          computed = iteratee ? iteratee(value) : value,
3524          seen = computed,
3525          resIndex = 0,
3526          result = [value];
3527
3528      while (++index < length) {
3529        value = array[index],
3530        computed = iteratee ? iteratee(value) : value;
3531
3532        if (!eq(computed, seen)) {
3533          seen = computed;
3534          result[++resIndex] = value;
3535        }
3536      }
3537      return result;
3538    }
3539
3540    /**
3541     * The base implementation of `_.toPath` which only converts `value` to a
3542     * path if it's not one.
3543     *
3544     * @private
3545     * @param {*} value The value to process.
3546     * @returns {Array} Returns the property path array.
3547     */
3548    function baseToPath(value) {
3549      return isArray(value) ? value : stringToPath(value);
3550    }
3551
3552    /**
3553     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3554     *
3555     * @private
3556     * @param {Array} array The array to inspect.
3557     * @param {Function} [iteratee] The iteratee invoked per element.
3558     * @param {Function} [comparator] The comparator invoked per element.
3559     * @returns {Array} Returns the new duplicate free array.
3560     */
3561    function baseUniq(array, iteratee, comparator) {
3562      var index = -1,
3563          includes = arrayIncludes,
3564          length = array.length,
3565          isCommon = true,
3566          result = [],
3567          seen = result;
3568
3569      if (comparator) {
3570        isCommon = false;
3571        includes = arrayIncludesWith;
3572      }
3573      else if (length >= LARGE_ARRAY_SIZE) {
3574        var set = iteratee ? null : createSet(array);
3575        if (set) {
3576          return setToArray(set);
3577        }
3578        isCommon = false;
3579        includes = cacheHas;
3580        seen = new SetCache;
3581      }
3582      else {
3583        seen = iteratee ? [] : result;
3584      }
3585      outer:
3586      while (++index < length) {
3587        var value = array[index],
3588            computed = iteratee ? iteratee(value) : value;
3589
3590        if (isCommon && computed === computed) {
3591          var seenIndex = seen.length;
3592          while (seenIndex--) {
3593            if (seen[seenIndex] === computed) {
3594              continue outer;
3595            }
3596          }
3597          if (iteratee) {
3598            seen.push(computed);
3599          }
3600          result.push(value);
3601        }
3602        else if (!includes(seen, computed, comparator)) {
3603          if (seen !== result) {
3604            seen.push(computed);
3605          }
3606          result.push(value);
3607        }
3608      }
3609      return result;
3610    }
3611
3612    /**
3613     * The base implementation of `_.unset`.
3614     *
3615     * @private
3616     * @param {Object} object The object to modify.
3617     * @param {Array|string} path The path of the property to unset.
3618     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3619     */
3620    function baseUnset(object, path) {
3621      path = isKey(path, object) ? [path + ''] : baseToPath(path);
3622      object = parent(object, path);
3623      var key = last(path);
3624      return (object != null && has(object, key)) ? delete object[key] : true;
3625    }
3626
3627    /**
3628     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3629     * without support for iteratee shorthands.
3630     *
3631     * @private
3632     * @param {Array} array The array to query.
3633     * @param {Function} predicate The function invoked per iteration.
3634     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3635     * @param {boolean} [fromRight] Specify iterating from right to left.
3636     * @returns {Array} Returns the slice of `array`.
3637     */
3638    function baseWhile(array, predicate, isDrop, fromRight) {
3639      var length = array.length,
3640          index = fromRight ? length : -1;
3641
3642      while ((fromRight ? index-- : ++index < length) &&
3643        predicate(array[index], index, array)) {}
3644
3645      return isDrop
3646        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3647        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3648    }
3649
3650    /**
3651     * The base implementation of `wrapperValue` which returns the result of
3652     * performing a sequence of actions on the unwrapped `value`, where each
3653     * successive action is supplied the return value of the previous.
3654     *
3655     * @private
3656     * @param {*} value The unwrapped value.
3657     * @param {Array} actions Actions to perform to resolve the unwrapped value.
3658     * @returns {*} Returns the resolved value.
3659     */
3660    function baseWrapperValue(value, actions) {
3661      var result = value;
3662      if (result instanceof LazyWrapper) {
3663        result = result.value();
3664      }
3665      return arrayReduce(actions, function(result, action) {
3666        return action.func.apply(action.thisArg, arrayPush([result], action.args
3666));
3667      }, result);
3668    }
3669
3670    /**
3671     * The base implementation of methods like `_.xor`, without support for
3672     * iteratee shorthands, that accepts an array of arrays to inspect.
3673     *
3674     * @private
3675     * @param {Array} arrays The arrays to inspect.
3676     * @param {Function} [iteratee] The iteratee invoked per element.
3677     * @param {Function} [comparator] The comparator invoked per element.
3678     * @returns {Array} Returns the new array of values.
3679     */
3680    function baseXor(arrays, iteratee, comparator) {
3681      var index = -1,
3682          length = arrays.length;
3683
3684      while (++index < length) {
3685        var result = result
3686          ? arrayPush(
3687              baseDifference(result, arrays[index], iteratee, comparator),
3688              baseDifference(arrays[index], result, iteratee, comparator)
3689            )
3690          : arrays[index];
3691      }
3692      return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3693    }
3694
3695    /**
3696     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
3697     *
3698     * @private
3699     * @param {Array} props The property names.
3700     * @param {Array} values The property values.
3701     * @param {Function} assignFunc The function to assign values.
3702     * @returns {Object} Returns the new object.
3703     */
3704    function baseZipObject(props, values, assignFunc) {
3705      var index = -1,
3706          length = props.length,
3707          valsLength = values.length,
3708          result = {};
3709
3710      while (++index < length) {
3711        assignFunc(result, props[index], index < valsLength ? values[index] : undefined);
3712      }
3713      return result;
3714    }
3715
3716    /**
3717     * Creates a clone of  `buffer`.
3718     *
3719     * @private
3720     * @param {Buffer} buffer The buffer to clone.
3721     * @param {boolean} [isDeep] Specify a deep clone.
3722     * @returns {Buffer} Returns the cloned buffer.
3723     */
3724    function cloneBuffer(buffer, isDeep) {
3725      if (isDeep) {
3726        return buffer.slice();
3727      }
3728      var Ctor = buffer.constructor,
3729          result = new Ctor(buffer.length);
3730
3731      buffer.copy(result);
3732      return result;
3733    }
3734
3735    /**
3736     * Creates a clone of `arrayBuffer`.
3737     *
3738     * @private
3739     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
3740     * @returns {ArrayBuffer} Returns the cloned array buffer.
3741     */
3742    function cloneArrayBuffer(arrayBuffer) {
3743      var Ctor = arrayBuffer.constructor,
3744          result = new Ctor(arrayBuffer.byteLength),
3745          view = new Uint8Array(result);
3746
3747      view.set(new Uint8Array(arrayBuffer));
3748      return result;
3749    }
3750
3751    /**
3752     * Creates a clone of `map`.
3753     *
3754     * @private
3755     * @param {Object} map The map to clone.
3756     * @returns {Object} Returns the cloned map.
3757     */
3758    function cloneMap(map) {
3759      var Ctor = map.constructor;
3760      return arrayReduce(mapToArray(map), addMapEntry, new Ctor);
3761    }
3762
3763    /**
3764     * Creates a clone of `regexp`.
3765     *
3766     * @private
3767     * @param {Object} regexp The regexp to clone.
3768     * @returns {Object} Returns the cloned regexp.
3769     */
3770    function cloneRegExp(regexp) {
3771      var Ctor = regexp.constructor,
3772          result = new Ctor(regexp.source, reFlags.exec(regexp));
3773
3774      result.lastIndex = regexp.lastIndex;
3775      return result;
3776    }
3777
3778    /**
3779     * Creates a clone of `set`.
3780     *
3781     * @private
3782     * @param {Object} set The set to clone.
3783     * @returns {Object} Returns the cloned set.
3784     */
3785    function cloneSet(set) {
3786      var Ctor = set.constructor;
3787      return arrayReduce(setToArray(set), addSetEntry, new Ctor);
3788    }
3789
3790    /**
3791     * Creates a clone of the `symbol` object.
3792     *
3793     * @private
3794     * @param {Object} symbol The symbol object to clone.
3795     * @returns {Object} Returns the cloned symbol object.
3796     */
3797    function cloneSymbol(symbol) {
3798      return Symbol ? Object(symbolValueOf.call(symbol)) : {};
3799    }
3800
3801    /**
3802     * Creates a clone of `typedArray`.
3803     *
3804     * @private
3805     * @param {Object} typedArray The typed array to clone.
3806     * @param {boolean} [isDeep] Specify a deep clone.
3807     * @returns {Object} Returns the cloned typed array.
vendor: 4,608 bytes, lines 3808-3944
3808     */
3809    function cloneTypedArray(typedArray, isDeep) {
3810      var buffer = typedArray.buffer,
3811          Ctor = typedArray.constructor;
3812
3813      return new Ctor(isDeep ? cloneArrayBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length);
3814    }
3815
3816    /**
3817     * Creates an array that is the composition of partially applied arguments,
3818     * placeholders, and provided arguments into a single array of arguments.
3819     *
3820     * @private
3821     * @param {Array|Object} args The provided arguments.
3822     * @param {Array} partials The arguments to prepend to those provided.
3823     * @param {Array} holders The `partials` placeholder indexes.
3824     * @returns {Array} Returns the new array of composed arguments.
3825     */
3826    function composeArgs(args, partials, holders) {
3827      var holdersLength = holders.length,
3828          argsIndex = -1,
3829          argsLength = nativeMax(args.length - holdersLength, 0),
3830          leftIndex = -1,
3831          leftLength = partials.length,
3832          result = Array(leftLength + argsLength);
3833
3834      while (++leftIndex < leftLength) {
3835        result[leftIndex] = partials[leftIndex];
3836      }
3837      while (++argsIndex < holdersLength) {
3838        result[holders[argsIndex]] = args[argsIndex];
3839      }
3840      while (argsLength--) {
3841        result[leftIndex++] = args[argsIndex++];
3842      }
3843      return result;
3844    }
3845
3846    /**
3847     * This function is like `composeArgs` except that the arguments composition
3848     * is tailored for `_.partialRight`.
3849     *
3850     * @private
3851     * @param {Array|Object} args The provided arguments.
3852     * @param {Array} partials The arguments to append to those provided.
3853     * @param {Array} holders The `partials` placeholder indexes.
3854     * @returns {Array} Returns the new array of composed arguments.
3855     */
3856    function composeArgsRight(args, partials, holders) {
3857      var holdersIndex = -1,
3858          holdersLength = holders.length,
3859          argsIndex = -1,
3860          argsLength = nativeMax(args.length - holdersLength, 0),
3861          rightIndex = -1,
3862          rightLength = partials.length,
3863          result = Array(argsLength + rightLength);
3864
3865      while (++argsIndex < argsLength) {
3866        result[argsIndex] = args[argsIndex];
3867      }
3868      var offset = argsIndex;
3869      while (++rightIndex < rightLength) {
3870        result[offset + rightIndex] = partials[rightIndex];
3871      }
3872      while (++holdersIndex < holdersLength) {
3873        result[offset + holders[holdersIndex]] = args[argsIndex++];
3874      }
3875      return result;
3876    }
3877
3878    /**
3879     * Copies the values of `source` to `array`.
3880     *
3881     * @private
3882     * @param {Array} source The array to copy values from.
3883     * @param {Array} [array=[]] The array to copy values to.
3884     * @returns {Array} Returns `array`.
3885     */
3886    function copyArray(source, array) {
3887      var index = -1,
3888          length = source.length;
3889
3890      array || (array = Array(length));
3891      while (++index < length) {
3892        array[index] = source[index];
3893      }
3894      return array;
3895    }
3896
3897    /**
3898     * Copies properties of `source` to `object`.
3899     *
3900     * @private
3901     * @param {Object} source The object to copy properties from.
3902     * @param {Array} props The property names to copy.
3903     * @param {Object} [object={}] The object to copy properties to.
3904     * @returns {Object} Returns `object`.
3905     */
3906    function copyObject(source, props, object) {
3907      return copyObjectWith(source, props, object);
3908    }
3909
3910    /**
3911     * This function is like `copyObject` except that it accepts a function to
3912     * customize copied values.
3913     *
3914     * @private
3915     * @param {Object} source The object to copy properties from.
3916     * @param {Array} props The property names to copy.
3917     * @param {Object} [object={}] The object to copy properties to.
3918     * @param {Function} [customizer] The function to customize copied values.
3919     * @returns {Object} Returns `object`.
3920     */
3921    function copyObjectWith(source, props, object, customizer) {
3922      object || (object = {});
3923
3924      var index = -1,
3925          length = props.length;
3926
3927      while (++index < length) {
3928        var key = props[index],
3929            newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
3930
3931        assignValue(object, key, newValue);
3932      }
3933      return object;
3934    }
3935
3936    /**
3937     * Copies own symbol properties of `source` to `object`.
3938     *
3939     * @private
3940     * @param {Object} source The object to copy symbols from.
3941     * @param {Object} [object={}] The object to copy symbols to.
3942     * @returns {Object} Returns `object`.
3943     */
3944    function copySymbols(source, object) {
vendor: 4,344 bytes, lines 3945-4077
3945      return copyObject(source, getSymbols(source), object);
3946    }
3947
3948    /**
3949     * Creates a function like `_.groupBy`.
3950     *
3951     * @private
3952     * @param {Function} setter The function to set accumulator values.
3953     * @param {Function} [initializer] The accumulator object initializer.
3954     * @returns {Function} Returns the new aggregator function.
3955     */
3956    function createAggregator(setter, initializer) {
3957      return function(collection, iteratee) {
3958        var func = isArray(collection) ? arrayAggregator : baseAggregator,
3959            accumulator = initializer ? initializer() : {};
3960
3961        return func(collection, setter, getIteratee(iteratee), accumulator);
3962      };
3963    }
3964
3965    /**
3966     * Creates a function like `_.assign`.
3967     *
3968     * @private
3969     * @param {Function} assigner The function to assign values.
3970     * @returns {Function} Returns the new assigner function.
3971     */
3972    function createAssigner(assigner) {
3973      return rest(function(object, sources) {
3974        var index = -1,
3975            length = sources.length,
3976            customizer = length > 1 ? sources[length - 1] : undefined,
3977            guard = length > 2 ? sources[2] : undefined;
3978
3979        customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
3980        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
3981          customizer = length < 3 ? undefined : customizer;
3982          length = 1;
3983        }
3984        object = Object(object);
3985        while (++index < length) {
3986          var source = sources[index];
3987          if (source) {
3988            assigner(object, source, index, customizer);
3989          }
3990        }
3991        return object;
3992      });
3993    }
3994
3995    /**
3996     * Creates a `baseEach` or `baseEachRight` function.
3997     *
3998     * @private
3999     * @param {Function} eachFunc The function to iterate over a collection.
4000     * @param {boolean} [fromRight] Specify iterating from right to left.
4001     * @returns {Function} Returns the new base function.
4002     */
4003    function createBaseEach(eachFunc, fromRight) {
4004      return function(collection, iteratee) {
4005        if (collection == null) {
4006          return collection;
4007        }
4008        if (!isArrayLike(collection)) {
4009          return eachFunc(collection, iteratee);
4010        }
4011        var length = collection.length,
4012            index = fromRight ? length : -1,
4013            iterable = Object(collection);
4014
4015        while ((fromRight ? index-- : ++index < length)) {
4016          if (iteratee(iterable[index], index, iterable) === false) {
4017            break;
4018          }
4019        }
4020        return collection;
4021      };
4022    }
4023
4024    /**
4025     * Creates a base function for methods like `_.forIn`.
4026     *
4027     * @private
4028     * @param {boolean} [fromRight] Specify iterating from right to left.
4029     * @returns {Function} Returns the new base function.
4030     */
4031    function createBaseFor(fromRight) {
4032      return function(object, iteratee, keysFunc) {
4033        var index = -1,
4034            iterable = Object(object),
4035            props = keysFunc(object),
4036            length = props.length;
4037
4038        while (length--) {
4039          var key = props[fromRight ? length : ++index];
4040          if (iteratee(iterable[key], key, iterable) === false) {
4041            break;
4042          }
4043        }
4044        return object;
4045      };
4046    }
4047
4048    /**
4049     * Creates a function that wraps `func` to invoke it with the optional `this`
4050     * binding of `thisArg`.
4051     *
4052     * @private
4053     * @param {Function} func The function to wrap.
4054     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4055     * @param {*} [thisArg] The `this` binding of `func`.
4056     * @returns {Function} Returns the new wrapped function.
4057     */
4058    function createBaseWrapper(func, bitmask, thisArg) {
4059      var isBind = bitmask & BIND_FLAG,
4060          Ctor = createCtorWrapper(func);
4061
4062      function wrapper() {
4063        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4064        return fn.apply(isBind ? thisArg : this, arguments);
4065      }
4066      return wrapper;
4067    }
4068
4069    /**
4070     * Creates a function like `_.lowerFirst`.
4071     *
4072     * @private
4073     * @param {string} methodName The name of the `String` case method to use.
4074     * @returns {Function} Returns the new function.
4075     */
4076    function createCaseFirst(methodName) {
4077      return function(string) {
4078        string = toString(string);
4079
4080        var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined,
4081            chr = strSymbols ? strSymbols[0] : string.charAt(0),
4082            trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1);
4083
4084        return chr[methodName]() + trailing;
4085      };
4086    }
4087
4088    /**
4089     * Creates a function like `_.camelCase`.
4090     *
4091     * @private
4092     * @param {Function} callback The function to combine each word.
4093     * @returns {Function} Returns the new compounder function.
4094     */
4095    function createCompounder(callback) {
4096      return function(string) {
4097        return arrayReduce(words(deburr(string)), callback, '');
4098      };
4099    }
4100
4101    /**
4102     * Creates a function that produces an instance of `Ctor` regardless of
4103     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4104     *
4105     * @private
4106     * @param {Function} Ctor The constructor to wrap.
4107     * @returns {Function} Returns the new wrapped function.
4108     */
4109    function createCtorWrapper(Ctor) {
4110      return function() {
4111        // Use a `switch` statement to work with class constructors.
4112        // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4113        // for more details.
4114        var args = arguments;
4115        switch (args.length) {
4116          case 0: return new Ctor;
4117          case 1: return new Ctor(args[0]);
4118          case 2: return new Ctor(args[0], args[1]);
4119          case 3: return new Ctor(args[0], args[1], args[2]);
4120          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4121          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4122          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4123          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4124        }
4125        var thisBinding = baseCreate(Ctor.prototype),
4126            result = Ctor.apply(thisBinding, args);
4127
4128        // Mimic the constructor's `return` behavior.
4129        // See https://es5.github.io/#x13.2.2 for more details.
4130        return isObject(result) ? result : thisBinding;
4131      };
4132    }
4133
4134    /**
4135     * Creates a function that wraps `func` to enable currying.
4136     *
4137     * @private
4138     * @param {Function} func The function to wrap.
4139     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4140     * @param {number} arity The arity of `func`.
4141     * @returns {Function} Returns the new wrapped function.
4142     */
4143    function createCurryWrapper(func, bitmask, arity) {
4144      var Ctor = createCtorWrapper(func);
4145
4146      function wrapper() {
4147        var length = arguments.length,
4148            index = length,
4149            args = Array(length),
4150            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
4151            placeholder = lodash.placeholder || wrapper.placeholder;
4152
4153        while (index--) {
4154          args[index] = arguments[index];
4155        }
4156        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4157          ? []
4158          : replaceHolders(args, placeholder);
4159
4160        length -= holders.length;
4161        return length < arity
4162          ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
4163          : apply(fn, this, args);
4164      }
4165      return wrapper;
4166    }
4167
4168    /**
4169     * Creates a `_.flow` or `_.flowRight` function.
4170     *
4171     * @private
4172     * @param {boolean} [fromRight] Specify iterating from right to left.
4173     * @returns {Function} Returns the new flow function.
4174     */
4175    function createFlow(fromRight) {
4176      return rest(function(funcs) {
4177        funcs = baseFlatten(funcs);
4178
4179        var length = funcs.length,
4180            index = length,
4181            prereq = LodashWrapper.prototype.thru;
4182
4183        if (fromRight) {
4184          funcs.reverse();
4185        }
4186        while (index--) {
4187          var func = funcs[index];
4188          if (typeof func != 'function') {
4189            throw new TypeError(FUNC_ERROR_TEXT);
4190          }
4191          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4192            var wrapper = new LodashWrapper([], true);
4193          }
4194        }
4195        index = wrapper ? index : length;
4196        while (++index < length) {
4197          func = funcs[index];
4198
4199          var funcName = getFuncName(func),
4200              data = funcName == 'wrapper' ? getData(func) : undefined;
4201
4202          if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) {
4203            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4204          } else {
4205            wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func);
4206          }
4207        }
4208        return function() {
4209          var args = arguments,
4210              value = args[0];
4211
4212          if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4213            return wrapper.plant(value).value();
4214          }
4215          var index = 0,
4216              result = length ? funcs[index].apply(this, args) : value;
4217
4218          while (++index < length) {
4219            result = funcs[index].call(this, result);
4220          }
4221          return result;
4222        };
4223      });
4224    }
4225
4226    /**
4227     * Creates a function that wraps `func` to invoke it with optional `this`
4228     * binding of `thisArg`, partial application, and currying.
4229     *
4230     * @private
4231     * @param {Function|string} func The function or method name to wrap.
4232     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4233     * @param {*} [thisArg] The `this` binding of `func`.
4234     * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4235     * @param {Array} [holders] The `partials` placeholder indexes.
4236     * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
4237     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4238     * @param {Array} [argPos] The argument positions of the new function.
4239     * @param {number} [ary] The arity cap of `func`.
4240     * @param {number} [arity] The arity of `func`.
4241     * @returns {Function} Returns the new wrapped function.
4242     */
4243    function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4244      var isAry = bitmask & ARY_FLAG,
4245          isBind = bitmask & BIND_FLAG,
4246          isBindKey = bitmask & BIND_KEY_FLAG,
4247          isCurry = bitmask & CURRY_FLAG,
4248          isCurryRight = bitmask & CURRY_RIGHT_FLAG,
4249          isFlip = bitmask & FLIP_FLAG,
4250          Ctor = isBindKey ? undefined : createCtorWrapper(func);
4251
4252      function wrapper() {
4253        var length = arguments.length,
4254            index = length,
4255            args = Array(length);
4256
4257        while (index--) {
4258          args[index] = arguments[index];
4259        }
4260        if (partials) {
4261          args = composeArgs(args, partials, holders);
4262        }
4263        if (partialsRight) {
4264          args = composeArgsRight(args, partialsRight, holdersRight);
4265        }
4266        if (isCurry || isCurryRight) {
4267          var placeholder = lodash.placeholder || wrapper.placeholder,
4268              argsHolders = replaceHolders(args, placeholder);
4269
4270          length -= argsHolders.length;
4271          if (length < arity) {
4272            return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
4273          }
4274        }
4275        var thisBinding = isBind ? thisArg : this,
4276            fn = isBindKey ? thisBinding[func] : func;
4277
4278        if (argPos) {
4279          args = reorder(args, argPos);
4280        } else if (isFlip && args.length > 1) {
4281          args.reverse();
4282        }
4283        if (isAry && ary < args.length) {
4284          args.length = ary;
4285        }
4286        if (this && this !== root && this instanceof wrapper) {
4287          fn = Ctor || createCtorWrapper(fn);
4288        }
4289        return fn.apply(thisBinding, args);
4290      }
4291      return wrapper;
4292    }
4293
4294    /**
4295     * Creates a function like `_.invertBy`.
4296     *
4297     * @private
4298     * @param {Function} setter The function to set accumulator values.
4299     * @param {Function} toIteratee The function to resolve iteratees.
4300     * @returns {Function} Returns the new inverter function.
4301     */
4302    function createInverter(setter, toIteratee) {
4303      return function(object, iteratee) {
4304        return baseInverter(object, setter, toIteratee(iteratee), {});
4305      };
4306    }
4307
4308    /**
4309     * Creates a function like `_.over`.
4310     *
4311     * @private
4312     * @param {Function} arrayFunc The function to iterate over iteratees.
4313     * @returns {Function} Returns the new invoker function.
4314     */
4315    function createOver(arrayFunc) {
4316      return rest(function(iteratees) {
4317        iteratees = arrayMap(baseFlatten(iteratees), getIteratee());
4318        return rest(function(args) {
4319          var thisArg = this;
4320          return arrayFunc(iteratees, function(iteratee) {
4321            return apply(iteratee, thisArg, args);
4322          });
4323        });
4324      });
4325    }
4326
4327    /**
4328     * Creates the padding for `string` based on `length`. The `chars` string
4329     * is truncated if the number of characters exceeds `length`.
4330     *
4331     * @private
4332     * @param {string} string The string to create padding for.
4333     * @param {number} [length=0] The padding length.
4334     * @param {string} [chars=' '] The string used as padding.
4335     * @returns {string} Returns the padding for `string`.
4336     */
4337    function createPadding(string, length, chars) {
4338      length = toInteger(length);
4339
4340      var strLength = stringSize(string);
4341      if (!length || strLength >= length) {
4342        return '';
4343      }
4344      var padLength = length - strLength;
4345      chars = chars === undefined ? ' ' : (chars + '');
4346
4347      var result = repeat(chars, nativeCeil(padLength / stringSize(chars)));
4348      return reHasComplexSymbol.test(chars)
4349        ? stringToArray(result).slice(0, padLength).join('')
4350        : result.slice(0, padLength);
4351    }
4352
4353    /**
4354     * Creates a function that wraps `func` to invoke it with the optional `this`
4355     * binding of `thisArg` and the `partials` prepended to those provided to
4356     * the wrapper.
4357     *
4358     * @private
4359     * @param {Function} func The function to wrap.
4360     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4361     * @param {*} thisArg The `this` binding of `func`.
4362     * @param {Array} partials The arguments to prepend to those provided to the new function.
4363     * @returns {Function} Returns the new wrapped function.
4364     */
4365    function createPartialWrapper(func, bitmask, thisArg, partials) {
4366      var isBind = bitmask & BIND_FLAG,
4367          Ctor = createCtorWrapper(func);
4368
4369      function wrapper() {
4370        var argsIndex = -1,
4371            argsLength = arguments.length,
4372            leftIndex = -1,
4373            leftLength = partials.length,
4374            args = Array(leftLength + argsLength),
4375            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4376
4377        while (++leftIndex < leftLength) {
4378          args[leftIndex] = partials[leftIndex];
4379        }
4380        while (argsLength--) {
4381          args[leftIndex++] = arguments[++argsIndex];
4382        }
4383        return apply(fn, isBind ? thisArg : this, args);
4384      }
4385      return wrapper;
4386    }
4387
4388    /**
4389     * Creates a `_.range` or `_.rangeRight` function.
4390     *
4391     * @private
4392     * @param {boolean} [fromRight] Specify iterating from right to left.
4393     * @returns {Function} Returns the new range function.
4394     */
4395    function createRange(fromRight) {
4396      return function(start, end, step) {
4397        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4398          end = step = undefined;
4399        }
4400        // Ensure the sign of `-0` is preserved.
4401        start = toNumber(start);
4402        start = start === start ? start : 0;
4403        if (end === undefined) {
4404          end = start;
4405          start = 0;
4406        } else {
4407          end = toNumber(end) || 0;
4408        }
4409        step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4410        return baseRange(start, end, step, fromRight);
4411      };
4412    }
4413
4414    /**
4415     * Creates a function that wraps `func` to continue currying.
4416     *
4417     * @private
4418     * @param {Function} func The function to wrap.
4419     * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
4420     * @param {Function} wrapFunc The function to create the `func` wrapper.
4421     * @param {*} placeholder The placeholder to replace.
4422     * @param {*} [thisArg] The `this` binding of `func`.
4423     * @param {Array} [partials] The arguments to prepend to those provided to the new function.
4424     * @param {Array} [holders] The `partials` placeholder indexes.
4425     * @param {Array} [argPos] The argument positions of the new function.
4426     * @param {number} [ary] The arity cap of `func`.
4427     * @param {number} [arity] The arity of `func`.
4428     * @returns {Function} Returns the new wrapped function.
4429     */
4430    function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4431      var isCurry = bitmask & CURRY_FLAG,
4432          newArgPos = argPos ? copyArray(argPos) : undefined,
4433          newsHolders = isCurry ? holders : undefined,
4434          newHoldersRight = isCurry ? undefined : holders,
4435          newPartials = isCurry ? partials : undefined,
4436          newPartialsRight = isCurry ? undefined : partials;
4437
4438      bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4439      bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4440
4441      if (!(bitmask & CURRY_BOUND_FLAG)) {
4442        bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4443      }
4444      var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity],
4445          result = wrapFunc.apply(undefined, newData);
4446
4447      if (isLaziable(func)) {
4448        setData(result, newData);
4449      }
4450      result.placeholder = placeholder;
4451      return result;
4452    }
4453
4454    /**
4455     * Creates a function like `_.round`.
4456     *
4457     * @private
4458     * @param {string} methodName The name of the `Math` method to use when rounding.
4459     * @returns {Function} Returns the new round function.
4460     */
4461    function createRound(methodName) {
4462      var func = Math[methodName];
4463      return function(number, precision) {
4464        number = toNumber(number);
4465        precision = toInteger(precision);
4466        if (precision) {
4467          // Shift with exponential notation to avoid floating-point issues.
4468          // See [MDN](https://mdn.io/round#Examples) for more details.
4469          var pair = (toString(number) + 'e').split('e'),
4470              value = func(pair[0] + 'e' + (+pair[1] + precision));
4471
4472          pair = (toString(value) + 'e').split('e');
4473          return +(pair[0] + 'e' + (+pair[1] - precision));
4474        }
4475        return func(number);
4476      };
4477    }
4478
4479    /**
4480     * Creates a set of `values`.
4481     *
4482     * @private
4483     * @param {Array} values The values to add to the set.
4484     * @returns {Object} Returns the new set.
4485     */
4486    var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) {
4487      return new Set(values);
4488    };
4489
4490    /**
4491     * Creates a function that either curries or invokes `func` with optional
4492     * `this` binding and partially applied arguments.
4493     *
4494     * @private
4495     * @param {Function|string}
4495 func The function or method name to wrap.
4496     * @param {number} bitmask The bitmask of wrapper flags.
4497     *  The bitmask may be composed of the following flags:
4498     *     1 - `_.bind`
4499     *     2 - `_.bindKey`
4500     *     4 - `_.curry` or `_.curryRight` of a bound function
4501     *     8 - `_.curry`
4502     *    16 - `_.curryRight`
4503     *    32 - `_.partial`
4504     *    64 - `_.partialRight`
4505     *   128 - `_.rearg`
4506     *   256 - `_.ary`
4507     * @param {*} [thisArg] The `this` binding of `func`.
4508     * @param {Array} [partials] The arguments to be partially applied.
4509     * @param {Array} [holders] The `partials` placeholder indexes.
4510     * @param {Array} [argPos] The argument positions of the new function.
4511     * @param {number} [ary] The arity cap of `func`.
4512     * @param {number} [arity] The arity of `func`.
4513     * @returns {Function} Returns the new wrapped function.
4514     */
4515    function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
4516      var isBindKey = bitmask & BIND_KEY_FLAG;
4517      if (!isBindKey && typeof func != 'function') {
4518        throw new TypeError(FUNC_ERROR_TEXT);
4519      }
4520      var length = partials ? partials.length : 0;
4521      if (!length) {
4522        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
4523        partials = holders = undefined;
4524      }
4525      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
4526      arity = arity === undefined ? arity : toInteger(arity);
4527      length -= holders ? holders.length : 0;
4528
4529      if (bitmask & PARTIAL_RIGHT_FLAG) {
4530        var partialsRight = partials,
4531            holdersRight = holders;
4532
4533        partials = holders = undefined;
4534      }
4535      var data = isBindKey ? undefined : getData(func),
4536          newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
4537
4538      if (data) {
4539        mergeData(newData, data);
4540      }
4541      func = newData[0];
4542      bitmask = newData[1];
4543      thisArg = newData[2];
4544      partials = newData[3];
4545      holders = newData[4];
4546      arity = newData[9] = newData[9] == null
4547        ? (isBindKey ? 0 : func.length)
4548        : nativeMax(newData[9] - length, 0);
4549
4550      if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
4551        bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
4552      }
4553      if (!bitmask || bitmask == BIND_FLAG) {
4554        var result = createBaseWrapper(func, bitmask, thisArg);
4555      } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
4556        result = createCurryWrapper(func, bitmask, arity);
4557      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
4558        result = createPartialWrapper(func, bitmask, thisArg, partials);
4559      } else {
4560        result = createHybridWrapper.apply(undefined, newData);
4561      }
4562      var setter = data ? baseSetData : setData;
4563      return setter(result, newData);
4564    }
4565
4566    /**
4567     * A specialized version of `baseIsEqualDeep` for arrays with support for
4568     * partial deep comparisons.
4569     *
4570     * @private
4571     * @param {Array} array The array to compare.
4572     * @param {Array} other The other array to compare.
4573     * @param {Function} equalFunc The function to determine equivalents of values.
4574     * @param {Function} [customizer] The function to customize comparisons.
4575     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4576     * @param {Object} [stack] Tracks traversed `array` and `other` objects.
4577     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
4578     */
4579    function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
4580      var index = -1,
4581          isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4582          isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
4583          arrLength = array.length,
4584          othLength = other.length;
4585
4586      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
4587        return false;
4588      }
4589      // Assume cyclic values are equal.
4590      var stacked = stack.get(array);
4591      if (stacked) {
4592        return stacked == other;
4593      }
4594      var result = true;
4595      stack.set(array, other);
4596
4597      // Ignore non-index properties.
4598      while (++index < arrLength) {
4599        var arrValue = array[index],
4600            othValue = other[index];
4601
4602        if (customizer) {
4603          var compared = isPartial
4604            ? customizer(othValue, arrValue, index, other, array, stack)
4605            : customizer(arrValue, othValue, index, array, other, stack);
4606        }
4607        if (compared !== undefined) {
4608          if (compared) {
4609            continue;
4610          }
4611          result = false;
4612          break;
4613        }
4614        // Recursively compare arrays (susceptible to call stack limits).
4615        if (isUnordered) {
4616          if (!arraySome(other, function(othValue) {
4617                return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
4618              })) {
4619            result = false;
4620            break;
4621          }
4622        } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
4623          result = false;
4624          break;
4625        }
4626      }
4627      stack['delete'](array);
4628      return result;
4629    }
4630
4631    /**
4632     * A specialized version of `baseIsEqualDeep` for comparing objects of
4633     * the same `toStringTag`.
4634     *
4635     * **Note:** This function only supports comparing values with tags of
4636     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4637     *
4638     * @private
4639     * @param {Object} object The object to compare.
4640     * @param {Object} other The other object to compare.
4641     * @param {string} tag The `toStringTag` of the objects to compare.
4642     * @param {Function} equalFunc The function to determine equivalents of values.
4643     * @param {Function} [customizer] The function to customize comparisons.
4644     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4645     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4646     */
4647    function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
4648      switch (tag) {
4649        case arrayBufferTag:
4650          if ((object.byteLength != other.byteLength) ||
4651              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
4652            return false;
4653          }
4654          return true;
4655
4656        case boolTag:
4657        case dateTag:
4658          // Coerce dates and booleans to numbers, dates to milliseconds and booleans
4659          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
4660          return +object == +other;
4661
4662        case errorTag:
4663          return object.name == other.name && object.message == other.message;
4664
4665        case numberTag:
4666          // Treat `NaN` vs. `NaN` as equal.
4667          return (object != +object) ? other != +other : object == +other;
4668
4669        case regexpTag:
4670        case stringTag:
4671          // Coerce regexes to strings and treat strings primitives and string
4672          // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
4673          return object == (other + '');
4674
4675        case mapTag:
4676          var convert = mapToArray;
4677
4678        case setTag:
4679          var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
4680          convert || (convert = setToArray);
4681
4682          // Recursively compare objects (susceptible to call stack limits).
4683          return (isPartial || object.size == other.size) &&
4684            equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
4685
4686        case symbolTag:
4687          return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
4688      }
4689      return false;
4690    }
4691
4692    /**
4693     * A specialized version of `baseIsEqualDeep` for objects with support for
4694     * partial deep comparisons.
4695     *
4696     * @private
4697     * @param {Object} object The object to compare.
4698     * @param {Object} other The other object to compare.
4699     * @param {Function} equalFunc The function to determine equivalents of values.
4700     * @param {Function} [customizer] The function to customize comparisons.
4701     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
4702     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4703     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4704     */
4705    function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
4706      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
4707          objProps = keys(object),
4708          objLength = objProps.length,
4709          othProps = keys(other),
4710          othLength = othProps.length;
4711
4712      if (objLength != othLength && !isPartial) {
4713        return false;
4714      }
4715      var index = objLength;
4716      while (index--) {
4717        var key = objProps[index];
4718        if (!(isPartial ? key in other : baseHas(other, key))) {
4719          return false;
4720        }
4721      }
4722      // Assume cyclic values are equal.
4723      var stacked = stack.get(object);
4724      if (stacked) {
4725        return stacked == other;
4726      }
4727      var result = true;
4728      stack.set(object, other);
4729
4730      var skipCtor = isPartial;
4731      while (++index < objLength) {
4732        key = objProps[index];
4733        var objValue = object[key],
4734            othValue = other[key];
4735
4736        if (customizer) {
4737          var compared = isPartial
4738            ? customizer(othValue, objValue, key, other, object, stack)
4739            : customizer(objValue, othValue, key, object, other, stack);
4740        }
4741        // Recursively compare objects (susceptible to call stack limits).
4742        if (!(compared === undefined
4743              ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
4744              : compared
4745            )) {
4746          result = false;
4747          break;
4748        }
4749        skipCtor || (skipCtor = key == 'constructor');
4750      }
4751      if (result && !skipCtor) {
4752        var objCtor = object.constructor,
4753            othCtor = other.constructor;
4754
4755        // Non `Object` object instances with different constructors are not equal.
4756        if (objCtor != othCtor &&
4757            ('constructor' in object && 'constructor' in other) &&
4758            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
4759              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
4760          result = false;
4761        }
4762      }
4763      stack['delete'](object);
4764      return result;
4765    }
4766
4767    /**
4768     * Gets metadata for `func`.
4769     *
4770     * @private
4771     * @param {Function} func The function to query.
4772     * @returns {*} Returns the metadata for `func`.
4773     */
4774    var getData = !metaMap ? noop : function(func) {
4775      return metaMap.get(func);
4776    };
4777
4778    /**
4779     * Gets the name of `func`.
4780     *
4781     * @private
4782     * @param {Function} func The function to query.
4783     * @returns {string} Returns the function name.
4784     */
4785    function getFuncName(func) {
4786      var result = (func.name + ''),
4787          array = realNames[result],
4788          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
4789
4790      while (length--) {
4791        var data = array[length],
4792            otherFunc = data.func;
4793        if (otherFunc == null || otherFunc == func) {
4794          return data.name;
4795        }
4796      }
4797      return result;
4798    }
4799
4800    /**
4801     * Gets the appropriate "iteratee" function. If the `_.iteratee` method is
4802     * customized this function returns the custom method, otherwise it returns
4803     * `baseIteratee`. If arguments are provided the chosen function is invoked
4804     * with them and its result is returned.
4805     *
4806     * @private
4807     * @param {*} [value] The value to convert to an iteratee.
4808     * @param {number} [arity] The arity of the created iteratee.
4809     * @returns {Function} Returns the chosen function or its result.
4810     */
4811    function getIteratee() {
4812      var result = lodash.iteratee || iteratee;
4813      result = result === iteratee ? baseIteratee : result;
4814      return arguments.length ? result(arguments[0], arguments[1]) : result;
4815    }
4816
4817    /**
4818     * Gets the "length" property value of `object`.
4819     *
4820     * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4821     * that affects Safari on at least iOS 8.1-8.3 ARM64.
4822     *
4823     * @private
4824     * @param {Object} object The object to query.
4825     * @returns {*} Returns the "length" value.
4826     */
4827    var getLength = baseProperty('length');
4828
4829    /**
4830     * Gets the property names, values, and compare flags of `object`.
4831     *
4832     * @private
4833     * @param {Object} object The object to query.
4834     * @returns {Array} Returns the match data of `object`.
4835     */
4836    function getMatchData(object) {
4837      var result = toPairs(object),
4838          length = result.length;
4839
4840      while (length--) {
4841        result[length][2] = isStrictComparable(result[length][1]);
4842      }
4843      return result;
4844    }
4845
4846    /**
4847     * Gets the native function at `key` of `object`.
4848     *
4849     * @private
4850     * @param {Object} object The object to query.
4851     * @param {string} key The key of the method to get.
4852     * @returns {*} Returns the function if it's native, else `undefined`.
4853     */
4854    function getNative(object, key) {
4855      var value = object == null ? undefined : object[key];
4856      return isNative(value) ? value : undefined;
4857    }
4858
4859    /**
4860     * Creates an array of the own symbol properties of `object`.
4861     *
4862     * @private
4863     * @param {Object} object The object to query.
4864     * @returns {Array} Returns the array of symbols.
4865     */
4866    var getSymbols = getOwnPropertySymbols || function() {
4867      return [];
4868    };
4869
4870    /**
4871     * Gets the `toStringTag` of `value`.
4872     *
4873     * @private
4874     * @param {*} value The value to query.
4875     * @returns {string} Returns the `toStringTag`.
4876     */
4877    function getTag(value) {
4878      return objectToString.call(value);
4879    }
4880
4881    // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps.
4882    if ((Map && getTag(new Map) != mapTag) ||
4883        (Set && getTag(new Set) != setTag) ||
4884        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
4885      getTag = function(value) {
4886        var result = objectToString.call(value),
4887            Ctor = result == objectTag ? value.constructor : null,
4888            ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : '';
4889
4890        if (ctorString) {
4891          switch (ctorString) {
4892            case mapCtorString: return mapTag;
4893            case setCtorString: return setTag;
4894            case weakMapCtorString: return weakMapTag;
4895          }
4896        }
4897        return result;
4898      };
4899    }
4900
4901    /**
4902     * Gets the view, applying any `transforms` to the `start` and `end` positions.
4903     *
4904     * @private
4905     * @param {number} start The start of the view.
4906     * @param {number} end The end of the view.
4907     * @param {Array} transforms The transformations to apply to the view.
4908     * @returns {Object} Returns an object containing the `start` and `end`
4909     *  positions of the view.
4910     */
4911    function getView(start, end, transforms) {
4912      var index = -1,
4913          length = transforms.length;
4914
4915      while (++index < length) {
4916        var data = transforms[index],
4917            size = data.size;
4918
4919        switch (data.type) {
4920          case 'drop':      start += size; break;
4921          case 'dropRight': end -= size; break;
4922          case 'take':      end = nativeMin(end, start + size); break;
4923          case 'takeRight': start = nativeMax(start, end - size); break;
4924        }
4925      }
4926      return { 'start': start, 'end': end };
4927    }
4928
4929    /**
4930     * Checks if `path` exists on `object`.
4931     *
4932     * @private
4933     * @param {Object} object The object to query.
4934     * @param {Array|string} path The path to check.
4935     * @param {Function} hasFunc The function to check properties.
4936     * @returns {boolean} Returns `true` if `path` exists, else `false`.
4937     */
4938    function hasPath(object, path, hasFunc) {
4939      if (object == null) {
4940        return false;
4941      }
4942      var result = hasFunc(object, path);
4943      if (!result && !isKey(path)) {
4944        path = baseToPath(path);
4945        object = parent(object, path);
4946        if (object != null) {
4947          path = last(path);
4948          result = hasFunc(object, path);
4949        }
4950      }
4951      var length = object ? object.length : undefined;
4952      return result || (
4953        !!length && isLength(length) && isIndex(path, length) &&
4954        (isArray(object) || isString(object) || isArguments(object))
4955      );
4956    }
4957
4958    /**
4959     * Initializes an array clone.
4960     *
4961     * @private
4962     * @param {Array} array The array to clone.
4963     * @returns {Array} Returns the initialized clone.
4964     */
4965    function initCloneArray(array) {
4966      var length = array.length,
4967          result = array.constructor(length);
4968
4969      // Add properties assigned by `RegExp#exec`.
4970      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
4971        result.index = array.index;
4972        result.input = array.input;
4973      }
4974      return result;
4975    }
4976
4977    /**
4978     * Initializes an object clone.
4979     *
4980     * @private
4981     * @param {Object} object The object to clone.
4982     * @returns {Object} Returns the initialized clone.
4983     */
4984    function initCloneObject(object) {
4985      if (isPrototype(object)) {
4986        return {};
4987      }
4988      var Ctor = object.constructor;
4989      return baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
4990    }
4991
4992    /**
4993     * Initializes an object clone based on its `toStringTag`.
4994     *
4995     * **Note:** This function only supports cloning values with tags of
4996     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
4997     *
4998     * @private
4999     * @param {Object} object The object to clone.
5000     * @param {string} tag The `toStringTag` of the object to clone.
5001     * @param {boolean} [isDeep] Specify a deep clone.
5002     * @returns {Object} Returns the initialized clone.
5003     */
5004    function initCloneByTag(object, tag, isDeep) {
5005      var Ctor = object.constructor;
5006      switch (tag) {
5007        case arrayBufferTag:
5008          return cloneArrayBuffer(object);
5009
5010        case boolTag:
5011        case dateTag:
5012          return new Ctor(+object);
5013
5014        case float32Tag: case float64Tag:
5015        case int8Tag: case int16Tag: case int32Tag:
5016        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
5017          return cloneTypedArray(object, isDeep);
5018
5019        case mapTag:
5020          return cloneMap(object);
5021
5022        case numberTag:
5023        case stringTag:
5024          return new Ctor(object);
5025
5026        case regexpTag:
5027          return cloneRegExp(object);
5028
5029        case setTag:
5030          return cloneSet(object);
5031
5032        case symbolTag:
5033          return cloneSymbol(object);
5034      }
5035    }
5036
5037    /**
5038     * Creates an array of index keys for `object` values of arrays,
5039     * `arguments` objects, and strings, otherwise `null` is returned.
5040     *
5041     * @private
5042     * @param {Object} object The object to query.
5043     * @returns {Array|null} Returns index keys, else `null`.
5044     */
5045    function indexKeys(object) {
5046      var length = object ? object.length : undefined;
5047      if (isLength(length) &&
5048          (isArray(object) || isString(object) || isArguments(object))) {
5049        return baseTimes(length, String);
5050      }
5051      return null;
5052    }
5053
5054    /**
5055     * Checks if the given arguments are from an iteratee call.
5056     *
5057     * @private
5058     * @param {*} value The potential iteratee value argument.
5059     * @param {*} index The potential iteratee index or key argument.
5060     * @param {*} object The potential iteratee object argument.
5061     * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
5062     */
5063    function isIterateeCall(value, index, object) {
5064      if (!isObject(object)) {
5065        return false;
5066      }
5067      var type = typeof index;
5068      if (type == 'number'
5069          ? (isArrayLike(object) && isIndex(index, object.length))
5070          : (type == 'string' && index in object)) {
5071        return eq(object[index], value);
5072      }
5073      return false;
5074    }
5075
5076    /**
5077     * Checks if `value` is a property name and not a property path.
5078     *
5079     * @private
5080     * @param {*} value The value to check.
5081     * @param {Object} [object] The object to query keys on.
5082     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
5083     */
5084    function isKey(value, object) {
5085      if (typeof value == 'number') {
5086        return true;
5087      }
5088      return !isArray(value) &&
5089        (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
5090          (object != null && value in Object(object)));
5091    }
5092
5093    /**
5094     * Checks if `value` is suitable for use as unique object key.
5095     *
5096     * @private
5097     * @param {*} value The value to check.
5098     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
5099     */
5100    function isKeyable(value) {
5101      var type = typeof value;
5102      return type == 'number' || type == 'boolean' ||
5103        (type == 'string' && value !== '__proto__') || value == null;
5104    }
5105
5106    /**
5107     * Checks if `func` has a lazy counterpart.
5108     *
5109     * @private
5110     * @param {Function} func The function to check.
5111     * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
5112     */
5113    function isLaziable(func) {
5114      var funcName = getFuncName(func),
5115          other = lodash[funcName];
5116
5117      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5118        return false;
5119      }
5120      if (func === other) {
5121        return true;
5122      }
5123      var data = getData(other);
5124      return !!data && func === data[0];
5125    }
5126
5127    /**
5128     * Checks if `value` is likely a prototype object.
5129     *
5130     * @private
5131     * @param {*} value The value to check.
5132     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5133     */
5134    function isPrototype(value) {
5135      var Ctor = value && value.constructor,
5136          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5137
5138      return value === proto;
5139    }
5140
5141    /**
5142     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5143     *
5144     * @private
5145     * @param {*} value The value to check.
5146     * @returns {boolean} Returns `true` if `value` if suitable for strict
5147     *  equality comparisons, else `false`.
5148     */
5149    function isStrictComparable(value) {
5150      return value === value && !isObject(value);
5151    }
5152
5153    /**
5154     * Merges the function metadata of `source` into `data`.
5155     *
5156     * Merging metadata reduces the number of wrappers used to invoke a function.
5157     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5158     * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
5159     * modify function arguments, making the order in which they are executed important,
5160     * preventing the merging of metadata. However, we make an exception for a safe
5161     * combined case where curried functions have `_.ary` and or `_.rearg` applied.
5162     *
5163     * @private
5164     * @param {Array} data The destination metadata.
5165     * @param {Array} source The source metadata.
5166     * @returns {Array} Returns `data`.
5167     */
5168    function mergeData(data, source) {
5169      var bitmask = data[1],
5170          srcBitmask = source[1],
5171          newBitmask = bitmask | srcBitmask,
5172          isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5173
5174      var isCombo =
5175        (srcBitmask == ARY_FLAG && (bitmask == CURRY_FLAG)) ||
5176        (srcBitmask == ARY_FLAG && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5177        (srcBitmask == (ARY_FLAG | REARG_FLAG) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5178
5179      // Exit early if metadata can't be merged.
5180      if (!(isCommon || isCombo)) {
5181        return data;
5182      }
5183      // Use source `thisArg` if available.
5184      if (srcBitmask & BIND_FLAG) {
5185        data[2] = source[2];
5186        // Set when currying a bound function.
5187        newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
5188      }
5189      // Compose partial arguments.
5190      var value = source[3];
5191      if (value) {
5192        var partials = data[3];
5193        data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value);
5194        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]);
5195      }
5196      // Compose partial right arguments.
5197      value = source[5];
5198      if (value) {
5199        partials = data[5];
5200        data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value);
5201        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]);
5202      }
5203      // Use source `argPos` if available.
5204      value = source[7];
5205      if (value) {
5206        data[7] = copyArray(value);
5207      }
5208      // Use source `ary` if it's smaller.
5209      if (srcBitmask & ARY_FLAG) {
5210        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5211      }
5212      // Use source `arity` if one is not provided.
5213      if (data[9] == null) {
5214        data[9] = source[9];
5215      }
5216      // Use source `func` and merge bitmasks.
5217      data[0] = source[0];
5218      data[1] = newBitmask;
5219
5220      return data;
5221    }
5222
5223    /**
5224     * Used by `_.defaultsDeep` to customize its `_.merge` use.
5225     *
5226     * @private
5227     * @param {*} objValue The destination value.
5228     * @param {*} srcValue The source value.
5229     * @param {string} key The key of the property to merge.
5230     * @param {Object} object The parent object of `objValue`.
5231     * @param {Object} source The parent object of `srcValue`.
5232     * @param {Object} [stack] Tracks traversed source values and their merged counterparts.
5233     * @returns {*} Returns the value to assign.
5234     */
5235    function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5236      if (isObject(objValue) && isObject(srcValue)) {
5237        stack.set(srcValue, objValue);
5238        baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
5239      }
5240      return objValue;
5241    }
5242
5243    /**
5244     * Gets the parent value at `path` of `object`.
5245     *
5246     * @private
5247     * @param {Object} object The object to query.
5248     * @param {Array} path The path to get the parent value of.
5249     * @returns {*} Returns the parent value.
5250     */
5251    function parent(object, path) {
5252      return path.length == 1 ? object : get(object, baseSlice(path, 0, -1));
5253    }
5254
5255    /**
5256     * Reorder `array` according to the specified indexes where the element at
5257     * the first index is assigned as the first element, the element at
5258     * the second index is assigned as the second element, and so on.
5259     *
5260     * @private
5261     * @param {Array} array The array to reorder.
5262     * @param {Array} indexes The arranged array indexes.
5263     * @returns {Array} Returns `array`.
5264     */
5265    function reorder(array, indexes) {
5266      var arrLength = array.length,
5267          length = nativeMin(indexes.length, arrLength),
5268          oldArray = copyArray(array);
5269
5270      while (length--) {
5271        var index = indexes[length];
5272        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5273      }
5274      return array;
5275    }
5276
5277    /**
5278     * Sets metadata for `func`.
5279     *
5280     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5281     * period of time, it will trip its breaker and transition to an identity function
5282     * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
5283     * for more details.
5284     *
5285     * @private
5286     * @param {Function} func The function to associate metadata with.
5287     * @param {*} data The metadata.
5288     * @returns {Function} Returns `func`.
5289     */
5290    var setData = (function() {
5291      var count = 0,
5292          lastCalled = 0;
5293
5294      return function(key, value) {
5295        var stamp = now(),
5296            remaining = HOT_SPAN - (stamp - lastCalled);
5297
5298        lastCalled = stamp;
5299        if (remaining > 0) {
5300          if (++count >= HOT_COUNT) {
5301            return key;
5302          }
5303        } else {
5304          count = 0;
5305        }
5306        return baseSetData(key, value);
5307      };
5308    }());
5309
5310    /**
5311     * Converts `string` to a property path array.
5312     *
5313     * @private
5314     * @param {string} string The string to convert.
5315     * @returns {Array} Returns the property path array.
5316     */
5317    function stringToPath(string) {
5318      var result = [];
5319      toString(string).replace(rePropName, function(match, number, quote, string) {
5320        result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5321      });
5322      return result;
5323    }
5324
5325    /**
5326     * Converts `value` to an array-like object if it's not one.
5327     *
5328     * @private
5329     * @param {*} value The value to process.
5330     * @returns {Array} Returns the array-like object.
5331     */
5332    function toArrayLikeObject(value) {
5333      return isArrayLikeObject(value) ? value : [];
5334    }
5335
5336    /**
5337     * Converts `value` to a function if it's not one.
5338     *
5339     * @private
5340     * @param {*} value The value to process.
5341     * @returns {Function} Returns the function.
5342     */
5343    function toFunction(value) {
5344      return typeof value == 'function' ? value : identity;
5345    }
5346
5347    /**
5348     * Creates a clone of `wrapper`.
5349     *
5350     * @private
5351     * @param {Object} wrapper The wrapper to clone.
5352     * @returns {Object} Returns the cloned wrapper.
5353     */
5354    function wrapperClone(wrapper) {
5355      if (wrapper instanceof LazyWrapper) {
5356        return wrapper.clone();
5357      }
5358      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
5359      result.__actions__ = copyArray(wrapper.__actions__);
5360      result.__index__  = wrapper.__index__;
5361      result.__values__ = wrapper.__values__;
5362      return result;
5363    }
5364
5365    /*------------------------------------------------------------------------*/
5366
5367    /**
5368     * Creates an array of elements split into groups the length of `size`.
5369     * If `array` can't be split evenly, the final chunk will be the remaining
5370     * elements.
5371     *
5372     * @static
5373     * @memberOf _
5374     * @category Array
5375     * @param {Array} array The array to process.
5376     * @param {number} [size=0] The length of each chunk.
5377     * @returns {Array} Returns the new array containing chunks.
5378     * @example
5379     *
5380     * _.chunk(['a', 'b', 'c', 'd'], 2);
5381     * // => [['a', 'b'], ['c', 'd']]
5382     *
5383     * _.chunk(['a', 'b', 'c', 'd'], 3);
5384     * // => [['a', 'b', 'c'], ['d']]
5385     */
5386    function chunk(array, size) {
5387      size = nativeMax(toInteger(size), 0);
5388
5389      var length = array ? array.length : 0;
5390      if (!length || size < 1) {
5391        return [];
5392      }
5393      var index = 0,
5394          resIndex = -1,
5395          result = Array(nativeCeil(length / size));
5396
5397      while (index < length) {
5398        result[++resIndex] = baseSlice(array, index, (index += size));
5399      }
5400      return result;
5401    }
5402
5403    /**
5404     * Creates an array with all falsey values removed. The values `false`, `null`,
5405     * `0`, `""`, `undefined`, and `NaN` are falsey.
5406     *
5407     * @static
5408     * @memberOf _
5409     * @category Array
5410     * @param {Array} array The array to compact.
5411     * @returns {Array} Returns the new array of filtered values.
5412     * @example
5413     *
5414     * _.compact([0, 1, false, 2, '', 3]);
5415     * // => [1, 2, 3]
5416     */
5417    function compact(array) {
5418      var index = -1,
5419          length = array ? array.length : 0,
5420          resIndex = -1,
5421          result = [];
5422
5423      while (++index < length) {
5424        var value = array[index];
5425        if (value) {
5426          result[++resIndex] = value;
5427        }
5428      }
5429      return result;
5430    }
5431
5432    /**
5433     * Creates a new array concatenating `array` with any additional arrays
5434     * and/or values.
5435     *
5436     * @static
5437     * @memberOf _
5438     * @category Array
5439     * @param {Array} array The array to concatenate.
5440     * @param {...*} [values] The values to concatenate.
5441     * @returns {Array} Returns the new concatenated array.
5442     * @example
5443     *
5444     * var array = [1];
5445     * var other = _.concat(array, 2, [3], [[4]]);
5446     *
5447     * console.log(other);
5448     * // => [1, 2, 3, [4]]
5449     *
5450     * console.log(array);
5451     * // => [1]
5452     */
5453    var concat = rest(function(array, values) {
5454      if (!isArray(array)) {
5455        array = array == null ? [] : [Object(array)];
5456      }
5457      values = baseFlatten(values);
5458      return arrayConcat(array, values);
5459    });
5460
5461    /**
5462     * Creates an array of unique `array` values not included in the other
5463     * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5464     * for equality comparisons.
5465     *
5466     * @static
5467     * @memberOf _
5468     * @category Array
5469     * @param {Array} array The array to inspect.
5470     * @param {...Array} [values] The values to exclude.
5471     * @returns {Array} Returns the new array of filtered values.
5472     * @example
5473     *
5474     * _.difference([3, 2, 1], [4, 2]);
5475     * // => [3, 1]
5476     */
5477    var difference = rest(function(array, values) {
5478      return isArrayLikeObject(array)
5479        ? baseDifference(array, baseFlatten(values, false, true))
5480        : [];
5481    });
5482
5483    /**
5484     * This method is like `_.difference` except that it accepts `iteratee` which
5485     * is invoked for each element of `array` and `values` to generate the criterion
5486     * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5487     *
5488     * @static
5489     * @memberOf _
5490     * @category Array
5491     * @param {Array} array The array to inspect.
5492     * @param {...Array} [values] The values to exclude.
5493     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5494     * @returns {Array} Returns the new array of filtered values.
5495     * @example
5496     *
5497     * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
5498     * // => [3.1, 1.3]
5499     *
5500     * // The `_.property` iteratee shorthand.
5501     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
5502     * // => [{ 'x': 2 }]
5503     */
5504    var differenceBy = rest(function(array, values) {
5505      var iteratee = last(values);
5506      if (isArrayLikeObject(iteratee)) {
5507        iteratee = undefined;
5508      }
5509      return isArrayLikeObject(array)
5510        ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee))
5511        : [];
5512    });
5513
5514    /**
5515     * This method is like `_.difference` except that it accepts `comparator`
5516     * which is invoked to compare elements of `array` to `values`. The comparator
5517     * is invoked with two arguments: (arrVal, othVal).
5518     *
5519     * @static
5520     * @memberOf _
5521     * @category Array
5522     * @param {Array} array The array to inspect.
5523     * @param {...Array} [values] The values to exclude.
5524     * @param {Function} [comparator] The comparator invoked per element.
5525     * @returns {Array} Returns the new array of filtered values.
5526     * @example
5527     *
5528     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
5529     *
5530     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
5531     * // => [{ 'x': 2, 'y': 1 }]
5532     */
5533    var differenceWith = rest(function(array, values) {
5534      var comparator = last(values);
5535      if (isArrayLikeObject(comparator)) {
5536        comparator = undefined;
5537      }
5538      return isArrayLikeObject(array)
5539        ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator)
5540        : [];
5541    });
5542
5543    /**
5544     * Creates a slice of `array` with `n` elements dropped from the beginning.
5545     *
5546     * @static
5547     * @memberOf _
5548     * @category Array
5549     * @param {Array} array The array to query.
5550     * @param {number} [n=1] The number of elements to drop.
5551     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5552     * @returns {Array} Returns the slice of `array`.
5553     * @example
5554     *
5555     * _.drop([1, 2, 3]);
5556     * // => [2, 3]
5557     *
5558     * _.drop([1, 2, 3], 2);
5559     * // => [3]
5560     *
5561     * _.drop([1, 2, 3], 5);
5562     * // => []
5563     *
5564     * _.drop([1, 2, 3], 0);
5565     * // => [1, 2, 3]
5566     */
5567    function drop(array, n, guard) {
5568      var length = array ? array.length : 0;
5569      if (!length) {
5570        return [];
5571      }
5572      n = (guard || n === undefined) ? 1 : toInteger(n);
5573      return baseSlice(array, n < 0 ? 0 : n, length);
5574    }
5575
5576    /**
5577     * Creates a slice of `array` with `n` elements dropped from the end.
5578     *
5579     * @static
5580     * @memberOf _
5581     * @category Array
5582     * @param {Array} array The array to query.
5583     * @param {number} [n=1] The number of elements to drop.
5584     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
5585     * @returns {Array} Returns the slice of `array`.
5586     * @example
5587     *
5588     * _.dropRight([1, 2, 3]);
5589     * // => [1, 2]
5590     *
5591     * _.dropRight([1, 2, 3], 2);
5592     * // => [1]
5593     *
5594     * _.dropRight([1, 2, 3], 5);
5595     * // => []
5596     *
5597     * _.dropRight([1, 2, 3], 0);
5598     * // => [1, 2, 3]
5599     */
5600    function dropRight(array, n, guard) {
5601      var length = array ? array.length : 0;
5602      if (!length) {
5603        return [];
5604      }
5605      n = (guard || n === undefined) ? 1 : toInteger(n);
5606      n = length - n;
5607      return baseSlice(array, 0, n < 0 ? 0 : n);
5608    }
5609
5610    /**
5611     * Creates a slice of `array` excluding elements dropped from the end.
5612     * Elements are dropped until `predicate` returns falsey. The predicate is
5613     * invoked with three arguments: (value, index, array).
5614     *
5615     * @static
5616     * @memberOf _
5617     * @category Array
5618     * @param {Array} array The array to query.
5619     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5620     * @returns {Array} Returns the slice of `array`.
5621     * @example
5622     *
5623     * var users = [
5624     *   { 'user': 'barney',  'active': true },
5625     *   { 'user': 'fred',    'active': false },
5626     *   { 'user': 'pebbles', 'active': false }
5627     * ];
5628     *
5629     * _.dropRightWhile(users, function(o) { return !o.active; });
5630     * // => objects for ['barney']
5631     *
5632     * // The `_.matches` iteratee shorthand.
5633     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
5634     * // => objects for ['barney', 'fred']
5635     *
5636     * // The `_.matchesProperty` iteratee shorthand.
5637     * _.dropRightWhile(users, ['active', false]);
5638     * // => objects for ['barney']
5639     *
5640     * // The `_.property` iteratee shorthand.
5641     * _.dropRightWhile(users, 'active');
5642     * // => objects for ['barney', 'fred', 'pebbles']
5643     */
5644    function dropRightWhile(array, predicate) {
5645      return (array && array.length)
5646        ? baseWhile(array, getIteratee(predicate, 3), true, true)
5647        : [];
5648    }
5649
5650    /**
5651     * Creates a slice of `array` excluding elements dropped from the beginning.
5652     * Elements are dropped until `predicate` returns falsey. The predicate is
5653     * invoked with three arguments: (value, index, array).
5654     *
5655     * @static
5656     * @memberOf _
5657     * @category Array
5658     * @param {Array} array The array to query.
5659     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5660     * @returns {Array} Returns the slice of `array`.
5661     * @example
5662     *
5663     * var users = [
5664     *   { 'user': 'barney',  'active': false },
5665     *   { 'user': 'fred',    'active': false },
5666     *   { 'user': 'pebbles', 'active': true }
5667     * ];
5668     *
5669     * _.dropWhile(users, function(o) { return !o.active; });
5670     * // => objects for ['pebbles']
5671     *
5672     * // The `_.matches` iteratee shorthand.
5673     * _.dropWhile(users, { 'user': 'barney', 'active': false });
5674     * // => objects for ['fred', 'pebbles']
5675     *
5676     * // The `_.matchesProperty` iteratee shorthand.
5677     * _.dropWhile(users, ['active', false]);
5678     * // => objects for ['pebbles']
5679     *
5680     * // The `_.property` iteratee shorthand.
5681     * _.dropWhile(users, 'active');
5682     * // => objects for ['barney', 'fred', 'pebbles']
5683     */
5684    function dropWhile(array, predicate) {
5685      return (array && array.length)
5686        ? baseWhile(array, getIteratee(predicate, 3), true)
5687        : [];
5688    }
5689
5690    /**
5691     * Fills elements of `array` with `value` from `start` up to, but not
5692     * including, `end`.
5693     *
5694     * **Note:** This method mutates `array`.
5695     *
5696     * @static
5697     * @memberOf _
5698     * @category Array
5699     * @param {Array} array The array to fill.
5700     * @param {*} value The value to fill `array` with.
5701     * @param {number} [start=0] The start position.
5702     * @param {number} [end=array.length] The end position.
5703     * @returns {Array} Returns `array`.
5704     * @example
5705     *
5706     * var array = [1, 2, 3];
5707     *
5708     * _.fill(array, 'a');
5709     * console.log(array);
5710     * // => ['a', 'a', 'a']
5711     *
5712     * _.fill(Array(3), 2);
5713     * // => [2, 2, 2]
5714     *
5715     * _.fill([4, 6, 8, 10], '*', 1, 3);
5716     * // => [4, '*', '*', 10]
5717     */
5718    function fill(array, value, start, end) {
5719      var length = array ? array.length : 0;
5720      if (!length) {
5721        return [];
5722      }
5723      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
5724        start = 0;
5725        end = length;
5726      }
5727      return baseFill(array, value, start, end);
5728    }
5729
5730    /**
5731     * This method is like `_.find` except that it returns the index of the first
5732     * element `predicate` returns truthy for instead of the element itself.
5733     *
5734     * @static
5735     * @memberOf _
5736     * @category Array
5737     * @param {Array} array The array to search.
5738     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5739     * @returns {number} Returns the index of the found element, else `-1`.
5740     * @example
5741     *
5742     * var users = [
5743     *   { 'user': 'barney',  'active': false },
5744     *   { 'user': 'fred',    'active': false },
5745     *   { 'user': 'pebbles', 'active': true }
5746     * ];
5747     *
5748     * _.findIndex(users, function(o) { return o.user == 'barney'; });
5749     * // => 0
5750     *
5751     * // The `_.matches` iteratee shorthand.
5752     * _.findIndex(users, { 'user': 'fred', 'active': false });
5753     * // => 1
5754     *
5755     * // The `_.matchesProperty` iteratee shorthand.
5756     * _.findIndex(users, ['active', false]);
5757     * // => 0
5758     *
5759     * // The `_.property` iteratee shorthand.
5760     * _.findIndex(users, 'active');
5761     * // => 2
5762     */
5763    function findIndex(array, predicate) {
5764      return (array && array.length)
5765        ? baseFindIndex(array, getIteratee(predicate, 3))
5766        : -1;
5767    }
5768
5769    /**
5770     * This method is like `_.findIndex` except that it iterates over elements
5771     * of `collection` from right to left.
5772     *
5773     * @static
5774     * @memberOf _
5775     * @category Array
5776     * @param {Array} array The array to search.
5777     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
5778     * @returns {number} Returns the index of the found element, else `-1`.
5779     * @example
5780     *
5781     * var users = [
5782     *   { 'user': 'barney',  'active': true },
5783     *   { 'user': 'fred',    'active': false },
5784     *   { 'user': 'pebbles', 'active': false }
5785     * ];
5786     *
5787     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
5788     * // => 2
5789     *
5790     * // The `_.matches` iteratee shorthand.
5791     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
5792     * // => 0
5793     *
5794     * // The `_.matchesProperty` iteratee shorthand.
5795     * _.findLastIndex(users, ['active', false]);
5796     * // => 2
5797     *
5798     * // The `_.property` iteratee shorthand.
5799     * _.findLastIndex(users, 'active');
5800     * // => 0
5801     */
5802    function findLastIndex(array, predicate) {
5803      return (array && array.length)
5804        ? baseFindIndex(array, getIteratee(predicate, 3), true)
5805        : -1;
5806    }
5807
5808    /**
5809     * Flattens `array` a single level.
5810     *
5811     * @static
5812     * @memberOf _
5813     * @category Array
5814     * @param {Array} array The array to flatten.
5815     * @returns {Array} Returns the new flattened array.
5816     * @example
5817     *
5818     * _.flatten([1, [2, 3, [4]]]);
5819     * // => [1, 2, 3, [4]]
5820     */
5821    function flatten(array) {
5822      var length = array ? array.length : 0;
5823      return length ? baseFlatten(array) : [];
5824    }
5825
5826    /**
5827     * This method is like `_.flatten` except that it recursively flattens `array`.
5828     *
5829     * @static
5830     * @memberOf _
5831     * @category Array
5832     * @param {Array} array The array to recursively flatten.
5833     * @returns {Array} Returns the new flattened array.
5834     * @example
5835     *
5836     * _.flattenDeep([1, [2, 3, [4]]]);
5837     * // => [1, 2, 3, 4]
5838     */
5839    function flattenDeep(array) {
5840      var length = array ? array.length : 0;
5841      return length ? baseFlatten(array, true) : [];
5842    }
5843
5844    /**
5845     * The inverse of `_.toPairs`; this method returns an object composed
5846     * from key-value `pairs`.
5847     *
5848     * @static
5849     * @memberOf _
5850     * @category Array
5851     * @param {Array} pairs The key-value pairs.
5852     * @returns {Object} Returns the new object.
5853     * @example
5854     *
5855     * _.fromPairs([['fred', 30], ['barney', 40]]);
5856     * // => { 'fred': 30, 'barney': 40 }
5857     */
5858    function fromPairs(pairs) {
5859      var index = -1,
5860          length = pairs ? pairs.length : 0,
5861          result = {};
5862
5863      while (++index < length) {
5864        var pair = pairs[index];
5865        result[pair[0]] = pair[1];
5866      }
5867      return result;
5868    }
5869
5870    /**
5871     * Gets the first element of `array`.
5872     *
5873     * @static
5874     * @memberOf _
5875     * @alias first
5876     * @category Array
5877     * @param {Array} array The array to query.
5878     * @returns {*} Returns the first element of `array`.
5879     * @example
5880     *
5881     * _.head([1, 2, 3]);
5882     * // => 1
5883     *
5884     * _.head([]);
5885     * // => undefined
5886     */
5887    function head(array) {
5888      return array ? array[0] : undefined;
5889    }
5890
5891    /**
5892     * Gets the index at which the first occurrence of `value` is found in `array`
5893     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5894     * for equality comparisons. If `fromIndex` is negative, it's used as the offset
5895     * from the end of `array`.
5896     *
5897     * @static
5898     * @memberOf _
5899     * @category Array
5900     * @param {Array} array The array to search.
5901     * @param {*} value The value to search for.
5902     * @param {number} [fromIndex=0] The index to search from.
5903     * @returns {number} Returns the index of the matched value, else `-1`.
5904     * @example
5905     *
5906     * _.indexOf([1, 2, 1, 2], 2);
5907     * // => 1
5908     *
5909     * // Search from the `fromIndex`.
5910     * _.indexOf([1, 2, 1, 2], 2, 2);
5911     * // => 3
5912     */
5913    function indexOf(array, value, fromIndex) {
5914      var length = array ? array.length : 0;
5915      if (!length) {
5916        return -1;
5917      }
5918      fromIndex = toInteger(fromIndex);
5919      if (fromIndex < 0) {
5920        fromIndex = nativeMax(length + fromIndex, 0);
5921      }
5922      return baseIndexOf(array, value, fromIndex);
5923    }
5924
5925    /**
5926     * Gets all but the last element of `array`.
5927     *
5928     * @static
5929     * @memberOf _
5930     * @category Array
5931     * @param {Array} array The array to query.
5932     * @returns {Array} Returns the slice of `array`.
5933     * @example
5934     *
5935     * _.initial([1, 2, 3]);
5936     * // => [1, 2]
5937     */
5938    function initial(array) {
5939      return dropRight(array, 1);
5940    }
5941
5942    /**
5943     * Creates an array of unique values that are included in all given arrays
5944     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
5945     * for equality comparisons.
5946     *
5947     * @static
5948     * @memberOf _
5949     * @category Array
5950     * @param {...Array} [arrays] The arrays to inspect.
5951     * @returns {Array} Returns the new array of shared values.
5952     * @example
5953     *
5954     * _.intersection([2, 1], [4, 2], [1, 2]);
5955     * // => [2]
5956     */
5957    var intersection = rest(function(arrays) {
5958      var mapped = arrayMap(arrays, toArrayLikeObject);
5959      return (mapped.length && mapped[0] === arrays[0])
5960        ? baseIntersection(mapped)
5961        : [];
5962    });
5963
5964    /**
5965     * This method is like `_.intersection` except that it accepts `iteratee`
5966     * which is invoked for each element of each `arrays` to generate the criterion
5967     * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
5968     *
5969     * @static
5970     * @memberOf _
5971     * @category Array
5972     * @param {...Array} [arrays] The arrays to inspect.
5973     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
5974     * @returns {Array} Returns the new array of shared values.
5975     * @example
5976     *
5977     * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
5978     * // => [2.1]
5979     *
5980     * // The `_.property` iteratee shorthand.
5981     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
5982     * // => [{ 'x': 1 }]
5983     */
5984    var intersectionBy = rest(function(arrays) {
5985      var iteratee = last(arrays),
5986          mapped = arrayMap(arrays, toArrayLikeObject);
5987
5988      if (iteratee === last(mapped)) {
5989        iteratee = undefined;
5990      } else {
5991        mapped.pop();
5992      }
5993      return (mapped.length && mapped[0] === arrays[0])
5994        ? baseIntersection(mapped, getIteratee(iteratee))
5995        : [];
5996    });
5997
5998    /**
5999     * This method is like `_.intersection` except that it accepts `comparator`
6000     * which is invoked to compare elements of `arrays`. The comparator is invoked
6001     * with two arguments: (arrVal, othVal).
6002     *
6003     * @static
6004     * @memberOf _
6005     * @category Array
6006     * @param {...Array} [arrays] The arrays to inspect.
6007     * @param {Function} [comparator] The comparator invoked per element.
6008     * @returns {Array} Returns the new array of shared values.
6009     * @example
6010     *
6011     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6012     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6013     *
6014     * _.intersectionWith(objects, others, _.isEqual);
6015     * // => [{ 'x': 1, 'y': 2 }]
6016     */
6017    var intersectionWith = rest(function(arrays) {
6018      var comparator = last(arrays),
6019          mapped = arrayMap(arrays, toArrayLikeObject);
6020
6021      if (comparator === last(mapped)) {
6022        comparator = undefined;
6023      } else {
6024        mapped.pop();
6025      }
6026      return (mapped.length && mapped[0] === arrays[0])
vendor: 16,384 bytes, lines 6027-6581
6027        ? baseIntersection(mapped, undefined, comparator)
6028        : [];
6029    });
6030
6031    /**
6032     * Converts all elements in `array` into a string separated by `separator`.
6033     *
6034     * @static
6035     * @memberOf _
6036     * @category Array
6037     * @param {Array} array The array to convert.
6038     * @param {string} [separator=','] The element separator.
6039     * @returns {string} Returns the joined string.
6040     * @example
6041     *
6042     * _.join(['a', 'b', 'c'], '~');
6043     * // => 'a~b~c'
6044     */
6045    function join(array, separator) {
6046      return array ? nativeJoin.call(array, separator) : '';
6047    }
6048
6049    /**
6050     * Gets the last element of `array`.
6051     *
6052     * @static
6053     * @memberOf _
6054     * @category Array
6055     * @param {Array} array The array to query.
6056     * @returns {*} Returns the last element of `array`.
6057     * @example
6058     *
6059     * _.last([1, 2, 3]);
6060     * // => 3
6061     */
6062    function last(array) {
6063      var length = array ? array.length : 0;
6064      return length ? array[length - 1] : undefined;
6065    }
6066
6067    /**
6068     * This method is like `_.indexOf` except that it iterates over elements of
6069     * `array` from right to left.
6070     *
6071     * @static
6072     * @memberOf _
6073     * @category Array
6074     * @param {Array} array The array to search.
6075     * @param {*} value The value to search for.
6076     * @param {number} [fromIndex=array.length-1] The index to search from.
6077     * @returns {number} Returns the index of the matched value, else `-1`.
6078     * @example
6079     *
6080     * _.lastIndexOf([1, 2, 1, 2], 2);
6081     * // => 3
6082     *
6083     * // Search from the `fromIndex`.
6084     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
6085     * // => 1
6086     */
6087    function lastIndexOf(array, value, fromIndex) {
6088      var length = array ? array.length : 0;
6089      if (!length) {
6090        return -1;
6091      }
6092      var index = length;
6093      if (fromIndex !== undefined) {
6094        index = toInteger(fromIndex);
6095        index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1;
6096      }
6097      if (value !== value) {
6098        return indexOfNaN(array, index, true);
6099      }
6100      while (index--) {
6101        if (array[index] === value) {
6102          return index;
6103        }
6104      }
6105      return -1;
6106    }
6107
6108    /**
6109     * Removes all given values from `array` using
6110     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6111     * for equality comparisons.
6112     *
6113     * **Note:** Unlike `_.without`, this method mutates `array`.
6114     *
6115     * @static
6116     * @memberOf _
6117     * @category Array
6118     * @param {Array} array The array to modify.
6119     * @param {...*} [values] The values to remove.
6120     * @returns {Array} Returns `array`.
6121     * @example
6122     *
6123     * var array = [1, 2, 3, 1, 2, 3];
6124     *
6125     * _.pull(array, 2, 3);
6126     * console.log(array);
6127     * // => [1, 1]
6128     */
6129    var pull = rest(pullAll);
6130
6131    /**
6132     * This method is like `_.pull` except that it accepts an array of values to remove.
6133     *
6134     * **Note:** Unlike `_.difference`, this method mutates `array`.
6135     *
6136     * @static
6137     * @memberOf _
6138     * @category Array
6139     * @param {Array} array The array to modify.
6140     * @param {Array} values The values to remove.
6141     * @returns {Array} Returns `array`.
6142     * @example
6143     *
6144     * var array = [1, 2, 3, 1, 2, 3];
6145     *
6146     * _.pullAll(array, [2, 3]);
6147     * console.log(array);
6148     * // => [1, 1]
6149     */
6150    function pullAll(array, values) {
6151      return (array && array.length && values && values.length)
6152        ? basePullAll(array, values)
6153        : array;
6154    }
6155
6156    /**
6157     * This method is like `_.pullAll` except that it accepts `iteratee` which is
6158     * invoked for each element of `array` and `values` to generate the criterion
6159     * by which uniqueness is computed. The iteratee is invoked with one argument: (value).
6160     *
6161     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
6162     *
6163     * @static
6164     * @memberOf _
6165     * @category Array
6166     * @param {Array} array The array to modify.
6167     * @param {Array} values The values to remove.
6168     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6169     * @returns {Array} Returns `array`.
6170     * @example
6171     *
6172     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
6173     *
6174     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
6175     * console.log(array);
6176     * // => [{ 'x': 2 }]
6177     */
6178    function pullAllBy(array, values, iteratee) {
6179      return (array && array.length && values && values.length)
6180        ? basePullAllBy(array, values, getIteratee(iteratee))
6181        : array;
6182    }
6183
6184    /**
6185     * Removes elements from `array` corresponding to `indexes` and returns an
6186     * array of removed elements.
6187     *
6188     * **Note:** Unlike `_.at`, this method mutates `array`.
6189     *
6190     * @static
6191     * @memberOf _
6192     * @category Array
6193     * @param {Array} array The array to modify.
6194     * @param {...(number|number[])} [indexes] The indexes of elements to remove,
6195     *  specified individually or in arrays.
6196     * @returns {Array} Returns the new array of removed elements.
6197     * @example
6198     *
6199     * var array = [5, 10, 15, 20];
6200     * var evens = _.pullAt(array, 1, 3);
6201     *
6202     * console.log(array);
6203     * // => [5, 15]
6204     *
6205     * console.log(evens);
6206     * // => [10, 20]
6207     */
6208    var pullAt = rest(function(array, indexes) {
6209      indexes = arrayMap(baseFlatten(indexes), String);
6210
6211      var result = baseAt(array, indexes);
6212      basePullAt(array, indexes.sort(compareAscending));
6213      return result;
6214    });
6215
6216    /**
6217     * Removes all elements from `array` that `predicate` returns truthy for
6218     * and returns an array of the removed elements. The predicate is invoked with
6219     * three arguments: (value, index, array).
6220     *
6221     * **Note:** Unlike `_.filter`, this method mutates `array`.
6222     *
6223     * @static
6224     * @memberOf _
6225     * @category Array
6226     * @param {Array} array The array to modify.
6227     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6228     * @returns {Array} Returns the new array of removed elements.
6229     * @example
6230     *
6231     * var array = [1, 2, 3, 4];
6232     * var evens = _.remove(array, function(n) {
6233     *   return n % 2 == 0;
6234     * });
6235     *
6236     * console.log(array);
6237     * // => [1, 3]
6238     *
6239     * console.log(evens);
6240     * // => [2, 4]
6241     */
6242    function remove(array, predicate) {
6243      var result = [];
6244      if (!(array && array.length)) {
6245        return result;
6246      }
6247      var index = -1,
6248          indexes = [],
6249          length = array.length;
6250
6251      predicate = getIteratee(predicate, 3);
6252      while (++index < length) {
6253        var value = array[index];
6254        if (predicate(value, index, array)) {
6255          result.push(value);
6256          indexes.push(index);
6257        }
6258      }
6259      basePullAt(array, indexes);
6260      return result;
6261    }
6262
6263    /**
6264     * Reverses `array` so that the first element becomes the last, the second
6265     * element becomes the second to last, and so on.
6266     *
6267     * **Note:** This method mutates `array` and is based on
6268     * [`Array#reverse`](https://mdn.io/Array/reverse).
6269     *
6270     * @static
6271     * @memberOf _
6272     * @category Array
6273     * @returns {Array} Returns `array`.
6274     * @example
6275     *
6276     * var array = [1, 2, 3];
6277     *
6278     * _.reverse(array);
6279     * // => [3, 2, 1]
6280     *
6281     * console.log(array);
6282     * // => [3, 2, 1]
6283     */
6284    function reverse(array) {
6285      return array ? nativeReverse.call(array) : array;
6286    }
6287
6288    /**
6289     * Creates a slice of `array` from `start` up to, but not including, `end`.
6290     *
6291     * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
6292     * to ensure dense arrays are returned.
6293     *
6294     * @static
6295     * @memberOf _
6296     * @category Array
6297     * @param {Array} array The array to slice.
6298     * @param {number} [start=0] The start position.
6299     * @param {number} [end=array.length] The end position.
6300     * @returns {Array} Returns the slice of `array`.
6301     */
6302    function slice(array, start, end) {
6303      var length = array ? array.length : 0;
6304      if (!length) {
6305        return [];
6306      }
6307      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
6308        start = 0;
6309        end = length;
6310      }
6311      else {
6312        start = start == null ? 0 : toInteger(start);
6313        end = end === undefined ? length : toInteger(end);
6314      }
6315      return baseSlice(array, start, end);
6316    }
6317
6318    /**
6319     * Uses a binary search to determine the lowest index at which `value` should
6320     * be inserted into `array` in order to maintain its sort order.
6321     *
6322     * @static
6323     * @memberOf _
6324     * @category Array
6325     * @param {Array} array The sorted array to inspect.
6326     * @param {*} value The value to evaluate.
6327     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6328     * @example
6329     *
6330     * _.sortedIndex([30, 50], 40);
6331     * // => 1
6332     *
6333     * _.sortedIndex([4, 5], 4);
6334     * // => 0
6335     */
6336    function sortedIndex(array, value) {
6337      return baseSortedIndex(array, value);
6338    }
6339
6340    /**
6341     * This method is like `_.sortedIndex` except that it accepts `iteratee`
6342     * which is invoked for `value` and each element of `array` to compute their
6343     * sort ranking. The iteratee is invoked with one argument: (value).
6344     *
6345     * @static
6346     * @memberOf _
6347     * @category Array
6348     * @param {Array} array The sorted array to inspect.
6349     * @param {*} value The value to evaluate.
6350     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6351     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6352     * @example
6353     *
6354     * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
6355     *
6356     * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
6357     * // => 1
6358     *
6359     * // The `_.property` iteratee shorthand.
6360     * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6361     * // => 0
6362     */
6363    function sortedIndexBy(array, value, iteratee) {
6364      return baseSortedIndexBy(array, value, getIteratee(iteratee));
6365    }
6366
6367    /**
6368     * This method is like `_.indexOf` except that it performs a binary
6369     * search on a sorted `array`.
6370     *
6371     * @static
6372     * @memberOf _
6373     * @category Array
6374     * @param {Array} array The array to search.
6375     * @param {*} value The value to search for.
6376     * @returns {number} Returns the index of the matched value, else `-1`.
6377     * @example
6378     *
6379     * _.sortedIndexOf([1, 1, 2, 2], 2);
6380     * // => 2
6381     */
6382    function sortedIndexOf(array, value) {
6383      var length = array ? array.length : 0;
6384      if (length) {
6385        var index = baseSortedIndex(array, value);
6386        if (index < length && eq(array[index], value)) {
6387          return index;
6388        }
6389      }
6390      return -1;
6391    }
6392
6393    /**
6394     * This method is like `_.sortedIndex` except that it returns the highest
6395     * index at which `value` should be inserted into `array` in order to
6396     * maintain its sort order.
6397     *
6398     * @static
6399     * @memberOf _
6400     * @category Array
6401     * @param {Array} array The sorted array to inspect.
6402     * @param {*} value The value to evaluate.
6403     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6404     * @example
6405     *
6406     * _.sortedLastIndex([4, 5], 4);
6407     * // => 1
6408     */
6409    function sortedLastIndex(array, value) {
6410      return baseSortedIndex(array, value, true);
6411    }
6412
6413    /**
6414     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
6415     * which is invoked for `value` and each element of `array` to compute their
6416     * sort ranking. The iteratee is invoked with one argument: (value).
6417     *
6418     * @static
6419     * @memberOf _
6420     * @category Array
6421     * @param {Array} array The sorted array to inspect.
6422     * @param {*} value The value to evaluate.
6423     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6424     * @returns {number} Returns the index at which `value` should be inserted into `array`.
6425     * @example
6426     *
6427     * // The `_.property` iteratee shorthand.
6428     * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
6429     * // => 1
6430     */
6431    function sortedLastIndexBy(array, value, iteratee) {
6432      return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
6433    }
6434
6435    /**
6436     * This method is like `_.lastIndexOf` except that it performs a binary
6437     * search on a sorted `array`.
6438     *
6439     * @static
6440     * @memberOf _
6441     * @category Array
6442     * @param {Array} array The array to search.
6443     * @param {*} value The value to search for.
6444     * @returns {number} Returns the index of the matched value, else `-1`.
6445     * @example
6446     *
6447     * _.sortedLastIndexOf([1, 1, 2, 2], 2);
6448     * // => 3
6449     */
6450    function sortedLastIndexOf(array, value) {
6451      var length = array ? array.length : 0;
6452      if (length) {
6453        var index = baseSortedIndex(array, value, true) - 1;
6454        if (eq(array[index], value)) {
6455          return index;
6456        }
6457      }
6458      return -1;
6459    }
6460
6461    /**
6462     * This method is like `_.uniq` except that it's designed and optimized
6463     * for sorted arrays.
6464     *
6465     * @static
6466     * @memberOf _
6467     * @category Array
6468     * @param {Array} array The array to inspect.
6469     * @returns {Array} Returns the new duplicate free array.
6470     * @example
6471     *
6472     * _.sortedUniq([1, 1, 2]);
6473     * // => [1, 2]
6474     */
6475    function sortedUniq(array) {
6476      return (array && array.length)
6477        ? baseSortedUniq(array)
6478        : [];
6479    }
6480
6481    /**
6482     * This method is like `_.uniqBy` except that it's designed and optimized
6483     * for sorted arrays.
6484     *
6485     * @static
6486     * @memberOf _
6487     * @category Array
6488     * @param {Array} array The array to inspect.
6489     * @param {Function} [iteratee] The iteratee invoked per element.
6490     * @returns {Array} Returns the new duplicate free array.
6491     * @example
6492     *
6493     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
6494     * // => [1.1, 2.3]
6495     */
6496    function sortedUniqBy(array, iteratee) {
6497      return (array && array.length)
6498        ? baseSortedUniqBy(array, getIteratee(iteratee))
6499        : [];
6500    }
6501
6502    /**
6503     * Gets all but the first element of `array`.
6504     *
6505     * @static
6506     * @memberOf _
6507     * @category Array
6508     * @param {Array} array The array to query.
6509     * @returns {Array} Returns the slice of `array`.
6510     * @example
6511     *
6512     * _.tail([1, 2, 3]);
6513     * // => [2, 3]
6514     */
6515    function tail(array) {
6516      return drop(array, 1);
6517    }
6518
6519    /**
6520     * Creates a slice of `array` with `n` elements taken from the beginning.
6521     *
6522     * @static
6523     * @memberOf _
6524     * @category Array
6525     * @param {Array} array The array to query.
6526     * @param {number} [n=1] The number of elements to take.
6527     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6528     * @returns {Array} Returns the slice of `array`.
6529     * @example
6530     *
6531     * _.take([1, 2, 3]);
6532     * // => [1]
6533     *
6534     * _.take([1, 2, 3], 2);
6535     * // => [1, 2]
6536     *
6537     * _.take([1, 2, 3], 5);
6538     * // => [1, 2, 3]
6539     *
6540     * _.take([1, 2, 3], 0);
6541     * // => []
6542     */
6543    function take(array, n, guard) {
6544      if (!(array && array.length)) {
6545        return [];
6546      }
6547      n = (guard || n === undefined) ? 1 : toInteger(n);
6548      return baseSlice(array, 0, n < 0 ? 0 : n);
6549    }
6550
6551    /**
6552     * Creates a slice of `array` with `n` elements taken from the end.
6553     *
6554     * @static
6555     * @memberOf _
6556     * @category Array
6557     * @param {Array} array The array to query.
6558     * @param {number} [n=1] The number of elements to take.
6559     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
6560     * @returns {Array} Returns the slice of `array`.
6561     * @example
6562     *
6563     * _.takeRight([1, 2, 3]);
6564     * // => [3]
6565     *
6566     * _.takeRight([1, 2, 3], 2);
6567     * // => [2, 3]
6568     *
6569     * _.takeRight([1, 2, 3], 5);
6570     * // => [1, 2, 3]
6571     *
6572     * _.takeRight([1, 2, 3], 0);
6573     * // => []
6574     */
6575    function takeRight(array, n, guard) {
6576      var length = array ? array.length : 0;
6577      if (!length) {
6578        return [];
6579      }
6580      n = (guard || n === undefined) ? 1 : toInteger(n);
6581      n = length - n;
6581
6582      return baseSlice(array, n < 0 ? 0 : n, length);
6583    }
6584
6585    /**
6586     * Creates a slice of `array` with elements taken from the end. Elements are
6587     * taken until `predicate` returns falsey. The predicate is invoked with three
6588     * arguments: (value, index, array).
6589     *
6590     * @static
6591     * @memberOf _
6592     * @category Array
6593     * @param {Array} array The array to query.
6594     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6595     * @returns {Array} Returns the slice of `array`.
6596     * @example
6597     *
6598     * var users = [
6599     *   { 'user': 'barney',  'active': true },
6600     *   { 'user': 'fred',    'active': false },
6601     *   { 'user': 'pebbles', 'active': false }
6602     * ];
6603     *
6604     * _.takeRightWhile(users, function(o) { return !o.active; });
6605     * // => objects for ['fred', 'pebbles']
6606     *
6607     * // The `_.matches` iteratee shorthand.
6608     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
6609     * // => objects for ['pebbles']
6610     *
6611     * // The `_.matchesProperty` iteratee shorthand.
6612     * _.takeRightWhile(users, ['active', false]);
6613     * // => objects for ['fred', 'pebbles']
6614     *
6615     * // The `_.property` iteratee shorthand.
6616     * _.takeRightWhile(users, 'active');
6617     * // => []
6618     */
6619    function takeRightWhile(array, predicate) {
6620      return (array && array.length)
6621        ? baseWhile(array, getIteratee(predicate, 3), false, true)
6622        : [];
6623    }
6624
6625    /**
6626     * Creates a slice of `array` with elements taken from the beginning. Elements
6627     * are taken until `predicate` returns falsey. The predicate is invoked with
6628     * three arguments: (value, index, array).
6629     *
6630     * @static
6631     * @memberOf _
6632     * @category Array
6633     * @param {Array} array The array to query.
6634     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
6635     * @returns {Array} Returns the slice of `array`.
6636     * @example
6637     *
6638     * var users = [
6639     *   { 'user': 'barney',  'active': false },
6640     *   { 'user': 'fred',    'active': false},
6641     *   { 'user': 'pebbles', 'active': true }
6642     * ];
6643     *
6644     * _.takeWhile(users, function(o) { return !o.active; });
6645     * // => objects for ['barney', 'fred']
6646     *
6647     * // The `_.matches` iteratee shorthand.
6648     * _.takeWhile(users, { 'user': 'barney', 'active': false });
6649     * // => objects for ['barney']
6650     *
6651     * // The `_.matchesProperty` iteratee shorthand.
6652     * _.takeWhile(users, ['active', false]);
6653     * // => objects for ['barney', 'fred']
6654     *
6655     * // The `_.property` iteratee shorthand.
6656     * _.takeWhile(users, 'active');
6657     * // => []
6658     */
6659    function takeWhile(array, predicate) {
6660      return (array && array.length)
6661        ? baseWhile(array, getIteratee(predicate, 3))
6662        : [];
6663    }
6664
6665    /**
6666     * Creates an array of unique values, in order, from all given arrays using
6667     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6668     * for equality comparisons.
6669     *
6670     * @static
6671     * @memberOf _
6672     * @category Array
6673     * @param {...Array} [arrays] The arrays to inspect.
6674     * @returns {Array} Returns the new array of combined values.
6675     * @example
6676     *
6677     * _.union([2, 1], [4, 2], [1, 2]);
6678     * // => [2, 1, 4]
6679     */
6680    var union = rest(function(arrays) {
6681      return baseUniq(baseFlatten(arrays, false, true));
6682    });
6683
6684    /**
6685     * This method is like `_.union` except that it accepts `iteratee` which is
6686     * invoked for each element of each `arrays` to generate the criterion by which
6687     * uniqueness is computed. The iteratee is invoked with one argument: (value).
6688     *
6689     * @static
6690     * @memberOf _
6691     * @category Array
6692     * @param {...Array} [arrays] The arrays to inspect.
6693     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6694     * @returns {Array} Returns the new array of combined values.
6695     * @example
6696     *
6697     * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6698     * // => [2.1, 1.2, 4.3]
6699     *
6700     * // The `_.property` iteratee shorthand.
6701     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6702     * // => [{ 'x': 1 }, { 'x': 2 }]
6703     */
6704    var unionBy = rest(function(arrays) {
6705      var iteratee = last(arrays);
6706      if (isArrayLikeObject(iteratee)) {
6707        iteratee = undefined;
6708      }
6709      return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee));
6710    });
6711
6712    /**
6713     * This method is like `_.union` except that it accepts `comparator` which
6714     * is invoked to compare elements of `arrays`. The comparator is invoked
6715     * with two arguments: (arrVal, othVal).
6716     *
6717     * @static
6718     * @memberOf _
6719     * @category Array
6720     * @param {...Array} [arrays] The arrays to inspect.
6721     * @param {Function} [comparator] The comparator invoked per element.
6722     * @returns {Array} Returns the new array of combined values.
6723     * @example
6724     *
6725     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6726     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6727     *
6728     * _.unionWith(objects, others, _.isEqual);
6729     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6730     */
6731    var unionWith = rest(function(arrays) {
6732      var comparator = last(arrays);
6733      if (isArrayLikeObject(comparator)) {
6734        comparator = undefined;
6735      }
6736      return baseUniq(baseFlatten(arrays, false, true), undefined, c
vendor: 7,624 bytes, lines 6736-6969
6736omparator);
6737    });
6738
6739    /**
6740     * Creates a duplicate-free version of an array, using
6741     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6742     * for equality comparisons, in which only the first occurrence of each element
6743     * is kept.
6744     *
6745     * @static
6746     * @memberOf _
6747     * @category Array
6748     * @param {Array} array The array to inspect.
6749     * @returns {Array} Returns the new duplicate free array.
6750     * @example
6751     *
6752     * _.uniq([2, 1, 2]);
6753     * // => [2, 1]
6754     */
6755    function uniq(array) {
6756      return (array && array.length)
6757        ? baseUniq(array)
6758        : [];
6759    }
6760
6761    /**
6762     * This method is like `_.uniq` except that it accepts `iteratee` which is
6763     * invoked for each element in `array` to generate the criterion by which
6764     * uniqueness is computed. The iteratee is invoked with one argument: (value).
6765     *
6766     * @static
6767     * @memberOf _
6768     * @category Array
6769     * @param {Array} array The array to inspect.
6770     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6771     * @returns {Array} Returns the new duplicate free array.
6772     * @example
6773     *
6774     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
6775     * // => [2.1, 1.2]
6776     *
6777     * // The `_.property` iteratee shorthand.
6778     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
6779     * // => [{ 'x': 1 }, { 'x': 2 }]
6780     */
6781    function uniqBy(array, iteratee) {
6782      return (array && array.length)
6783        ? baseUniq(array, getIteratee(iteratee))
6784        : [];
6785    }
6786
6787    /**
6788     * This method is like `_.uniq` except that it accepts `comparator` which
6789     * is invoked to compare elements of `array`. The comparator is invoked with
6790     * two arguments: (arrVal, othVal).
6791     *
6792     * @static
6793     * @memberOf _
6794     * @category Array
6795     * @param {Array} array The array to inspect.
6796     * @param {Function} [comparator] The comparator invoked per element.
6797     * @returns {Array} Returns the new duplicate free array.
6798     * @example
6799     *
6800     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }];
6801     *
6802     * _.uniqWith(objects, _.isEqual);
6803     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
6804     */
6805    function uniqWith(array, comparator) {
6806      return (array && array.length)
6807        ? baseUniq(array, undefined, comparator)
6808        : [];
6809    }
6810
6811    /**
6812     * This method is like `_.zip` except that it accepts an array of grouped
6813     * elements and creates an array regrouping the elements to their pre-zip
6814     * configuration.
6815     *
6816     * @static
6817     * @memberOf _
6818     * @category Array
6819     * @param {Array} array The array of grouped elements to process.
6820     * @returns {Array} Returns the new array of regrouped elements.
6821     * @example
6822     *
6823     * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
6824     * // => [['fred', 30, true], ['barney', 40, false]]
6825     *
6826     * _.unzip(zipped);
6827     * // => [['fred', 'barney'], [30, 40], [true, false]]
6828     */
6829    function unzip(array) {
6830      if (!(array && array.length)) {
6831        return [];
6832      }
6833      var length = 0;
6834      array = arrayFilter(array, function(group) {
6835        if (isArrayLikeObject(group)) {
6836          length = nativeMax(group.length, length);
6837          return true;
6838        }
6839      });
6840      return baseTimes(length, function(index) {
6841        return arrayMap(array, baseProperty(index));
6842      });
6843    }
6844
6845    /**
6846     * This method is like `_.unzip` except that it accepts `iteratee` to specify
6847     * how regrouped values should be combined. The iteratee is invoked with the
6848     * elements of each group: (...group).
6849     *
6850     * @static
6851     * @memberOf _
6852     * @category Array
6853     * @param {Array} array The array of grouped elements to process.
6854     * @param {Function} [iteratee=_.identity] The function to combine regrouped values.
6855     * @returns {Array} Returns the new array of regrouped elements.
6856     * @example
6857     *
6858     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
6859     * // => [[1, 10, 100], [2, 20, 200]]
6860     *
6861     * _.unzipWith(zipped, _.add);
6862     * // => [3, 30, 300]
6863     */
6864    function unzipWith(array, iteratee) {
6865      if (!(array && array.length)) {
6866        return [];
6867      }
6868      var result = unzip(array);
6869      if (iteratee == null) {
6870        return result;
6871      }
6872      return arrayMap(result, function(group) {
6873        return apply(iteratee, undefined, group);
6874      });
6875    }
6876
6877    /**
6878     * Creates an array excluding all given values using
6879     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6880     * for equality comparisons.
6881     *
6882     * @static
6883     * @memberOf _
6884     * @category Array
6885     * @param {Array} array The array to filter.
6886     * @param {...*} [values] The values to exclude.
6887     * @returns {Array} Returns the new array of filtered values.
6888     * @example
6889     *
6890     * _.without([1, 2, 1, 3], 1, 2);
6891     * // => [3]
6892     */
6893    var without = rest(function(array, values) {
6894      return isArrayLikeObject(array)
6895        ? baseDifference(array, values)
6896        : [];
6897    });
6898
6899    /**
6900     * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
6901     * of the given arrays.
6902     *
6903     * @static
6904     * @memberOf _
6905     * @category Array
6906     * @param {...Array} [arrays] The arrays to inspect.
6907     * @returns {Array} Returns the new array of values.
6908     * @example
6909     *
6910     * _.xor([2, 1], [4, 2]);
6911     * // => [1, 4]
6912     */
6913    var xor = rest(function(arrays) {
6914      return baseXor(arrayFilter(arrays, isArrayLikeObject));
6915    });
6916
6917    /**
6918     * This method is like `_.xor` except that it accepts `iteratee` which is
6919     * invoked for each element of each `arrays` to generate the criterion by which
6920     * uniqueness is computed. The iteratee is invoked with one argument: (value).
6921     *
6922     * @static
6923     * @memberOf _
6924     * @category Array
6925     * @param {...Array} [arrays] The arrays to inspect.
6926     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
6927     * @returns {Array} Returns the new array of values.
6928     * @example
6929     *
6930     * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
6931     * // => [1.2, 4.3]
6932     *
6933     * // The `_.property` iteratee shorthand.
6934     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6935     * // => [{ 'x': 2 }]
6936     */
6937    var xorBy = rest(function(arrays) {
6938      var iteratee = last(arrays);
6939      if (isArrayLikeObject(iteratee)) {
6940        iteratee = undefined;
6941      }
6942      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
6943    });
6944
6945    /**
6946     * This method is like `_.xor` except that it accepts `comparator` which is
6947     * invoked to compare elements of `arrays`. The comparator is invoked with
6948     * two arguments: (arrVal, othVal).
6949     *
6950     * @static
6951     * @memberOf _
6952     * @category Array
6953     * @param {...Array} [arrays] The arrays to inspect.
6954     * @param {Function} [comparator] The comparator invoked per element.
6955     * @returns {Array} Returns the new array of values.
6956     * @example
6957     *
6958     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6959     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6960     *
6961     * _.xorWith(objects, others, _.isEqual);
6962     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
6963     */
6964    var xorWith = rest(function(arrays) {
6965      var comparator = last(arrays);
6966      if (isArrayLikeObject(comparator)) {
6967        comparator = undefined;
6968      }
6969      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, c
vendor: 10,871 bytes, lines 6969-7357
6969omparator);
6970    });
6971
6972    /**
6973     * Creates an array of grouped elements, the first of which contains the first
6974     * elements of the given arrays, the second of which contains the second elements
6975     * of the given arrays, and so on.
6976     *
6977     * @static
6978     * @memberOf _
6979     * @category Array
6980     * @param {...Array} [arrays] The arrays to process.
6981     * @returns {Array} Returns the new array of grouped elements.
6982     * @example
6983     *
6984     * _.zip(['fred', 'barney'], [30, 40], [true, false]);
6985     * // => [['fred', 30, true], ['barney', 40, false]]
6986     */
6987    var zip = rest(unzip);
6988
6989    /**
6990     * This method is like `_.fromPairs` except that it accepts two arrays,
6991     * one of property names and one of corresponding values.
6992     *
6993     * @static
6994     * @memberOf _
6995     * @category Array
6996     * @param {Array} [props=[]] The property names.
6997     * @param {Array} [values=[]] The property values.
6998     * @returns {Object} Returns the new object.
6999     * @example
7000     *
7001     * _.zipObject(['a', 'b'], [1, 2]);
7002     * // => { 'a': 1, 'b': 2 }
7003     */
7004    function zipObject(props, values) {
7005      return baseZipObject(props || [], values || [], assignValue);
7006    }
7007
7008    /**
7009     * This method is like `_.zipObject` except that it supports property paths.
7010     *
7011     * @static
7012     * @memberOf _
7013     * @category Array
7014     * @param {Array} [props=[]] The property names.
7015     * @param {Array} [values=[]] The property values.
7016     * @returns {Object} Returns the new object.
7017     * @example
7018     *
7019     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
7020     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
7021     */
7022    function zipObjectDeep(props, values) {
7023      return baseZipObject(props || [], values || [], baseSet);
7024    }
7025
7026    /**
7027     * This method is like `_.zip` except that it accepts `iteratee` to specify
7028     * how grouped values should be combined. The iteratee is invoked with the
7029     * elements of each group: (...group).
7030     *
7031     * @static
7032     * @memberOf _
7033     * @category Array
7034     * @param {...Array} [arrays] The arrays to process.
7035     * @param {Function} [iteratee=_.identity] The function to combine grouped values.
7036     * @returns {Array} Returns the new array of grouped elements.
7037     * @example
7038     *
7039     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
7040     *   return a + b + c;
7041     * });
7042     * // => [111, 222]
7043     */
7044    var zipWith = rest(function(arrays) {
7045      var length = arrays.length,
7046          iteratee = length > 1 ? arrays[length - 1] : undefined;
7047
7048      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
7049      return unzipWith(arrays, iteratee);
7050    });
7051
7052    /*------------------------------------------------------------------------*/
7053
7054    /**
7055     * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
7056     * The result of such method chaining must be unwrapped with `_#value`.
7057     *
7058     * @static
7059     * @memberOf _
7060     * @category Seq
7061     * @param {*} value The value to wrap.
7062     * @returns {Object} Returns the new `lodash` wrapper instance.
7063     * @example
7064     *
7065     * var users = [
7066     *   { 'user': 'barney',  'age': 36 },
7067     *   { 'user': 'fred',    'age': 40 },
7068     *   { 'user': 'pebbles', 'age': 1 }
7069     * ];
7070     *
7071     * var youngest = _
7072     *   .chain(users)
7073     *   .sortBy('age')
7074     *   .map(function(o) {
7075     *     return o.user + ' is ' + o.age;
7076     *   })
7077     *   .head()
7078     *   .value();
7079     * // => 'pebbles is 1'
7080     */
7081    function chain(value) {
7082      var result = lodash(value);
7083      result.__chain__ = true;
7084      return result;
7085    }
7086
7087    /**
7088     * This method invokes `interceptor` and returns `value`. The interceptor
7089     * is invoked with one argument; (value). The purpose of this method is to
7090     * "tap into" a method chain in order to modify intermediate results.
7091     *
7092     * @static
7093     * @memberOf _
7094     * @category Seq
7095     * @param {*} value The value to provide to `interceptor`.
7096     * @param {Function} interceptor The function to invoke.
7097     * @returns {*} Returns `value`.
7098     * @example
7099     *
7100     * _([1, 2, 3])
7101     *  .tap(function(array) {
7102     *    // Mutate input array.
7103     *    array.pop();
7104     *  })
7105     *  .reverse()
7106     *  .value();
7107     * // => [2, 1]
7108     */
7109    function tap(value, interceptor) {
7110      interceptor(value);
7111      return value;
7112    }
7113
7114    /**
7115     * This method is like `_.tap` except that it returns the result of `interceptor`.
7116     * The purpose of this method is to "pass thru" values replacing intermediate
7117     * results in a method chain.
7118     *
7119     * @static
7120     * @memberOf _
7121     * @category Seq
7122     * @param {*} value The value to provide to `interceptor`.
7123     * @param {Function} interceptor The function to invoke.
7124     * @returns {*} Returns the result of `interceptor`.
7125     * @example
7126     *
7127     * _('  abc  ')
7128     *  .chain()
7129     *  .trim()
7130     *  .thru(function(value) {
7131     *    return [value];
7132     *  })
7133     *  .value();
7134     * // => ['abc']
7135     */
7136    function thru(value, interceptor) {
7137      return interceptor(value);
7138    }
7139
7140    /**
7141     * This method is the wrapper version of `_.at`.
7142     *
7143     * @name at
7144     * @memberOf _
7145     * @category Seq
7146     * @param {...(string|string[])} [paths] The property paths of elements to pick,
7147     *  specified individually or in arrays.
7148     * @returns {Object} Returns the new `lodash` wrapper instance.
7149     * @example
7150     *
7151     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
7152     *
7153     * _(object).at(['a[0].b.c', 'a[1]']).value();
7154     * // => [3, 4]
7155     *
7156     * _(['a', 'b', 'c']).at(0, 2).value();
7157     * // => ['a', 'c']
7158     */
7159    var wrapperAt = rest(function(paths) {
7160      paths = baseFlatten(paths);
7161      var length = paths.length,
7162          start = length ? paths[0] : 0,
7163          value = this.__wrapped__,
7164          interceptor = function(object) { return baseAt(object, paths); };
7165
7166      if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) {
7167        return this.thru(interceptor);
7168      }
7169      value = value.slice(start, +start + (length ? 1 : 0));
7170      value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
7171      return new LodashWrapper(value, this.__chain__).thru(function(array) {
7172        if (length && !array.length) {
7173          array.push(undefined);
7174        }
7175        return array;
7176      });
7177    });
7178
7179    /**
7180     * Enables explicit method chaining on the wrapper object.
7181     *
7182     * @name chain
7183     * @memberOf _
7184     * @category Seq
7185     * @returns {Object} Returns the new `lodash` wrapper instance.
7186     * @example
7187     *
7188     * var users = [
7189     *   { 'user': 'barney', 'age': 36 },
7190     *   { 'user': 'fred',   'age': 40 }
7191     * ];
7192     *
7193     * // A sequence without explicit chaining.
7194     * _(users).head();
7195     * // => { 'user': 'barney', 'age': 36 }
7196     *
7197     * // A sequence with explicit chaining.
7198     * _(users)
7199     *   .chain()
7200     *   .head()
7201     *   .pick('user')
7202     *   .value();
7203     * // => { 'user': 'barney' }
7204     */
7205    function wrapperChain() {
7206      return chain(this);
7207    }
7208
7209    /**
7210     * Executes the chained sequence and returns the wrapped result.
7211     *
7212     * @name commit
7213     * @memberOf _
7214     * @category Seq
7215     * @returns {Object} Returns the new `lodash` wrapper instance.
7216     * @example
7217     *
7218     * var array = [1, 2];
7219     * var wrapped = _(array).push(3);
7220     *
7221     * console.log(array);
7222     * // => [1, 2]
7223     *
7224     * wrapped = wrapped.commit();
7225     * console.log(array);
7226     * // => [1, 2, 3]
7227     *
7228     * wrapped.last();
7229     * // => 3
7230     *
7231     * console.log(array);
7232     * // => [1, 2, 3]
7233     */
7234    function wrapperCommit() {
7235      return new LodashWrapper(this.value(), this.__chain__);
7236    }
7237
7238    /**
7239     * This method is the wrapper version of `_.flatMap`.
7240     *
7241     * @name flatMap
7242     * @memberOf _
7243     * @category Seq
7244     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7245     * @returns {Object} Returns the new `lodash` wrapper instance.
7246     * @example
7247     *
7248     * function duplicate(n) {
7249     *   return [n, n];
7250     * }
7251     *
7252     * _([1, 2]).flatMap(duplicate).value();
7253     * // => [1, 1, 2, 2]
7254     */
7255    function wrapperFlatMap(iteratee) {
7256      return this.map(iteratee).flatten();
7257    }
7258
7259    /**
7260     * Gets the next value on a wrapped object following the
7261     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
7262     *
7263     * @name next
7264     * @memberOf _
7265     * @category Seq
7266     * @returns {Object} Returns the next iterator value.
7267     * @example
7268     *
7269     * var wrapped = _([1, 2]);
7270     *
7271     * wrapped.next();
7272     * // => { 'done': false, 'value': 1 }
7273     *
7274     * wrapped.next();
7275     * // => { 'done': false, 'value': 2 }
7276     *
7277     * wrapped.next();
7278     * // => { 'done': true, 'value': undefined }
7279     */
7280    function wrapperNext() {
7281      if (this.__values__ === undefined) {
7282        this.__values__ = toArray(this.value());
7283      }
7284      var done = this.__index__ >= this.__values__.length,
7285          value = done ? undefined : this.__values__[this.__index__++];
7286
7287      return { 'done': done, 'value': value };
7288    }
7289
7290    /**
7291     * Enables the wrapper to be iterable.
7292     *
7293     * @name Symbol.iterator
7294     * @memberOf _
7295     * @category Seq
7296     * @returns {Object} Returns the wrapper object.
7297     * @example
7298     *
7299     * var wrapped = _([1, 2]);
7300     *
7301     * wrapped[Symbol.iterator]() === wrapped;
7302     * // => true
7303     *
7304     * Array.from(wrapped);
7305     * // => [1, 2]
7306     */
7307    function wrapperToIterator() {
7308      return this;
7309    }
7310
7311    /**
7312     * Creates a clone of the chained sequence planting `value` as the wrapped value.
7313     *
7314     * @name plant
7315     * @memberOf _
7316     * @category Seq
7317     * @param {*} value The value to plant.
7318     * @returns {Object} Returns the new `lodash` wrapper instance.
7319     * @example
7320     *
7321     * function square(n) {
7322     *   return n * n;
7323     * }
7324     *
7325     * var wrapped = _([1, 2]).map(square);
7326     * var other = wrapped.plant([3, 4]);
7327     *
7328     * other.value();
7329     * // => [9, 16]
7330     *
7331     * wrapped.value();
7332     * // => [1, 4]
7333     */
7334    function wrapperPlant(value) {
7335      var result,
7336          parent = this;
7337
7338      while (parent instanceof baseLodash) {
7339        var clone = wrapperClone(parent);
7340        clone.__index__ = 0;
7341        clone.__values__ = undefined;
7342        if (result) {
7343          previous.__wrapped__ = clone;
7344        } else {
7345          result = clone;
7346        }
7347        var previous = clone;
7348        parent = parent.__wrapped__;
7349      }
7350      previous.__wrapped__ = value;
7351      return result;
7352    }
7353
7354    /**
7355     * This method is the wrapper version of `_.reverse`.
7356     *
7357     * **Note:** This method mutates the wrapped array.
7358     *
7359     * @name reverse
7360     * @memberOf _
7361     * @category Seq
7362     * @returns {Object} Returns the new `lodash` wrapper instance.
7363     * @example
7364     *
7365     * var array = [1, 2, 3];
7366     *
7367     * _(array).reverse().value()
7368     * // => [3, 2, 1]
7369     *
7370     * console.log(array);
7371     * // => [3, 2, 1]
7372     */
7373    function wrapperReverse() {
7374      var value = this.__wrapped__;
7375      if (value instanceof LazyWrapper) {
7376        var wrapped = value;
7377        if (this.__actions__.length) {
7378          wrapped = new LazyWrapper(this);
7379        }
7380        wrapped = wrapped.reverse();
7381        wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined });
7382        return new LodashWrapper(wrapped, this.__chain__);
7383      }
7384      return this.thru(reverse);
7385    }
7386
7387    /**
7388     * Executes the chained sequence to extract the unwrapped value.
7389     *
7390     * @name value
7391     * @memberOf _
7392     * @alias toJSON, valueOf
7393     * @category Seq
7394     * @returns {*} Returns the resolved unwrapped value.
7395     * @example
7396     *
7397     * _([1, 2, 3]).value();
7398     * // => [1, 2, 3]
7399     */
7400    function wrapperValue() {
7401      return baseWrapperValue(this.__wrapped__, this.__actions__);
7402    }
7403
7404    /*------------------------------------------------------------------------*/
7405
7406    /**
7407     * Creates an object composed of keys generated from the results of running
7408     * each element of `collection` through `iteratee`. The corresponding value
7409     * of each key is the number of times the key was returned by `iteratee`.
7410     * The iteratee is invoked with one argument: (value).
7411     *
7412     * @static
7413     * @memberOf _
7414     * @category Collection
7415     * @param {Array|Object} collection The collection to iterate over.
7416     * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7417     * @returns {Object} Returns the composed aggregate object.
7418     * @example
7419     *
7420     * _.countBy([6.1, 4.2, 6.3], Math.floor);
7421     * // => { '4': 1, '6': 2 }
7422     *
7423     * _.countBy(['one', 'two', 'three'], 'length');
7424     * // => { '3': 2, '5': 1 }
7425     */
7426    var countBy = createAggregator(function(result, value, key) {
7427      hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
7428    });
7429
7430    /**
7431     * Checks if `predicate` returns truthy for **all** elements of `collection`.
7432     * Iteration is stopped once `predicate` returns falsey. The predicate is
7433     * invoked with three arguments: (value, index|key, collection).
7434     *
7435     * @static
7436     * @memberOf _
7437     * @category Collection
7438     * @param {Array|Object} collection The collection to iterate over.
7439     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7440     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
7441     * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
7442     * @example
7443     *
7444     * _.every([true, 1, null, 'yes'], Boolean);
7445     * // => false
7446     *
7447     * var users = [
7448     *   { 'user': 'barney', 'active': false },
7449     *   { 'user': 'fred',   'active': false }
7450     * ];
7451     *
7452     * // The `_.matches` iteratee shorthand.
7453     * _.every(users, { 'user': 'barney', 'active': false });
7454     * // => false
7455     *
7456     * // The `_.matchesProperty` iteratee shorthand.
7457     * _.every(users, ['active', false]);
7458     * // => true
7459     *
7460     * // The `_.property` iteratee shorthand.
7461     * _.every(users, 'active');
7462     * // => false
7463     */
7464    function every(collection, predicate, guard) {
7465      var func = isArray(collection) ? arrayEvery : baseEvery;
7466      if (guard && isIterateeCall(collection, predicate, guard)) {
7467        predicate = undefined;
7468      }
7469      return func(collection, getIteratee(predicate, 3));
7470    }
7471
7472    /**
7473     * Iterates over elements of `collection`, returning an array of all elements
7474     * `predicate` returns truthy for. The predicate is invoked with three arguments:
7475     * (value, index|key, collection).
7476     *
7477     * @static
7478     * @memberOf _
7479     * @category Collection
7480     * @param {Array|Object} collection The collection to iterate over.
7481     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7482     * @returns {Array} Returns the new filtered array.
7483     * @example
7484     *
7485     * var users = [
7486     *   { 'user': 'barney', 'age': 36, 'active': true },
7487     *   { 'user': 'fred',   'age': 40, 'active': false }
7488     * ];
7489     *
7490     * _.filter(users, function(o) { return !o.active; });
7491     * // => objects for ['fred']
7492     *
7493     * // The `_.matches` iteratee shorthand.
7494     * _.filter(users, { 'age': 36, 'active': true });
7495     * // => objects for ['barney']
7496     *
7497     * // The `_.matchesProperty` iteratee shorthand.
7498     * _.filter(users, ['active', false]);
7499     * // => objects for ['fred']
7500     *
7501     * // The `_.property` iteratee shorthand.
7502     * _.filter(users, 'active');
7503     * // => objects for ['barney']
7504     */
7505    function filter(collection, predicate) {
7506      var func = isArray(collection) ? arrayFilter : baseFilter;
7507      return func(collection, getIteratee(predicate, 3));
7508    }
7509
7510    /**
7511     * Iterates over elements of `collection`, returning the first element
7512     * `predicate` returns truthy for. The predicate is invoked with three arguments:
7513     * (value, index|key, collection).
7514     *
7515     * @static
7516     * @memberOf _
7517     * @category Collection
7518     * @param {Array|Object} collection The collection to search.
7519     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7520     * @returns {*} Returns the matched element, else `undefined`.
7521     * @example
7522     *
7523     * var users = [
7524     *   { 'user': 'barney',  'age': 36, 'active': true },
7525     *   { 'user': 'fred',    'age': 40, 'active': false },
7526     *   { 'user': 'pebbles', 'age': 1,  'active': true }
7527     * ];
7528     *
7529     * _.find(users, function(o) { return o.age < 40; });
7530     * // => object for 'barney'
7531     *
7532     * // The `_.matches` iteratee shorthand.
7533     * _.find(users, { 'age': 1, 'active': true });
7534     * // => object for 'pebbles'
7535     *
7536     * // The `_.matchesProperty` iteratee shorthand.
7537     * _.find(users, ['active', false]);
7538     * // => object for 'fred'
7539     *
7540     * // The `_.property` iteratee shorthand.
7541     * _.find(users, 'active');
7542     * // => object for 'barney'
7543     */
7544    function find(collection, predicate) {
7545      predicate = getIteratee(predicate, 3);
7546      if (isArray(collection)) {
7547        var index = baseFindIndex(collection, predicate);
7548        return index > -1 ? collection[index] : undefined;
7549      }
7550      return baseFind(collection, predicate, baseEach);
7551    }
7552
7553    /**
7554     * This method is like `_.find` except that it iterates over elements of
7555     * `collection` from right to left.
7556     *
7557     * @static
7558     * @memberOf _
7559     * @category Collection
7560     * @param {Array|Object} collection The collection to search.
7561     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7562     * @returns {*} Returns the matched element, else `undefined`.
7563     * @example
7564     *
7565     * _.findLast([1, 2, 3, 4], function(n) {
7566     *   return n % 2 == 1;
7567     * });
7568     * // => 3
7569     */
7570    function findLast(collection, predicate) {
7571      predicate = getIteratee(predicate, 3);
7572      if (isArray(collection)) {
7573        var index = baseFindIndex(collection, predicate, true);
7574        return index > -1 ? collection[index] : undefined;
7575      }
7576      return baseFind(collection, predicate, baseEachRight);
7577    }
7578
7579    /**
7580     * Creates an array of flattened values by running each element in `collection`
7581     * through `iteratee` and concating its result to the other mapped values.
7582     * The iteratee is invoked with three arguments: (value, index|key, collection).
7583     *
7584     * @static
7585     * @memberOf _
7586     * @category Collection
7587     * @param {Array|Object} collection The collection to iterate over.
7588     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7589     * @returns {Array} Returns the new flattened array.
7590     * @example
7591     *
7592     * function duplicate(n) {
7593     *   return [n, n];
7594     * }
7595     *
7596     * _.flatMap([1, 2], duplicate);
7597     * // => [1, 1, 2, 2]
7598     */
7599    function flatMap(collection, iteratee) {
7600      return baseFlatten(map(collection, iteratee));
7601    }
7602
7603    /**
7604     * Iterates over elements of `collection` invoking `iteratee` for each element.
7605     * The iteratee is invoked with three arguments: (value, index|key, collection).
7606     * Iteratee functions may exit iteration early by explicitly returning `false`.
7607     *
7608     * **Note:** As with other "Collections" methods, objects with a "length" property
7609     * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
7610     * for object iteration.
7611     *
7612     * @static
7613     * @memberOf _
7614     * @alias each
7615     * @category Collection
7616     * @param {Array|Object} collection The collection to iterate over.
7617     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7618     * @returns {Array|Object} Returns `collection`.
7619     * @example
7620     *
7621     * _([1, 2]).forEach(function(value) {
7622     *   console.log(value);
7623     * });
7624     * // => logs `1` then `2`
7625     *
7626     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
7627     *   console.log(key);
7628     * });
7629     * // => logs 'a' then 'b' (iteration order is not guaranteed)
7630     */
7631    function forEach(collection, iteratee) {
7632      return (typeof iteratee == 'function' && isArray(collection))
7633        ? arrayEach(collection, iteratee)
7634        : baseEach(collection, toFunction(iteratee));
7635    }
7636
7637    /**
7638     * This method is like `_.forEach` except that it iterates over elements of
7639     * `collection` from right to left.
7640     *
7641     * @static
7642     * @memberOf _
7643     * @alias eachRight
7644     * @category Collection
7645     * @param {Array|Object} collection The collection to iterate over.
7646     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7647     * @returns {Array|Object} Returns `collection`.
7648     * @example
7649     *
7650     * _.forEachRight([1, 2], function(value) {
7651     *   console.log(value);
7652     * });
7653     * // => logs `2` then `1`
7654     */
7655    function forEachRight(collection, iteratee) {
7656      return (typeof iteratee == 'function' && isArray(collection))
7657        ? arrayEachRight(collection, iteratee)
7658        : baseEachRight(collection, toFunction(iteratee));
7659    }
7660
7661    /**
7662     * Creates an object composed of keys generated from the results of running
7663     * each element of `collection` through `iteratee`. The corresponding value
7664     * of each key is an array of elements responsible for generating the key.
7665     * The iteratee is invoked with one argument: (value).
7666     *
7667     * @static
7668     * @memberOf _
7669     * @category Collection
7670     * @param {Array|Object} collection The collection to iterate over.
7671     * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7672     * @returns {Object} Returns the composed aggregate object.
7673     * @example
7674     *
7675     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
7676     * // => { '4': [4.2], '6': [6.1, 6.3] }
7677     *
7678     * // The `_.property` iteratee shorthand.
7679     * _.groupBy(['one', 'two', 'three'], 'length');
7680     * // => { '3': ['one', 'two'], '5': ['three'] }
7681     */
7682    var groupBy = createAggregator(function(result, value, key) {
7683      if (hasOwnProperty.call(result, key)) {
7684        result[key].push(value);
7685      } else {
7686        result[key] = [value];
7687      }
7688    });
7689
7690    /**
7691     * Checks if `value` is in `collection`. If `collection` is a string it's checked
7692     * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7693     * is used for equality comparisons. If `fromIndex` is negative, it's used as
7694     * the offset from the end of `collection`.
7695     *
7696     * @static
7697     * @memberOf _
7698     * @category Collection
7699     * @param {Array|Object|string} collection The collection to search.
7700     * @param {*} value The value to search for.
7701     * @param {number} [fromIndex=0] The index to search from.
7702     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7703     * @returns {boolean} Returns `true` if `value` is found, else `false`.
7704     * @example
7705     *
7706     * _.includes([1, 2, 3], 1);
7707     * // => true
7708     *
7709     * _.includes([1, 2, 3], 1, 2);
7710     * // => false
7711     *
7712     * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
7713     * // => true
7714     *
7715     * _.includes('pebbles', 'eb');
7716     * // => true
7717     */
7718    function includes(collection, value, fromIndex, guard) {
7719      collection = isArrayLike(collection) ? collection : values(collection);
7720      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
7721
7722      var length = collection.length;
7723      if (fromIndex < 0) {
7724        fromIndex = nativeMax(length + fromIndex, 0);
7725      }
7726      return isString(collection)
7727        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
7728        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
7729    }
7730
7731    /**
7732     * Invokes the method at `path` of each element in `collection`, returning
7733     * an array of the results of each invoked method. Any additional arguments
7734     * are provided to each invoked method. If `methodName` is a function it's
7735     * invoked for, and `this` bound to, each element in `collection`.
7736     *
7737     * @static
7738     * @memberOf _
7739     * @category Collection
7740     * @param {Array|Object} collection The collection to iterate over.
7741     * @param {Array|Function|string} path The path of the method to invoke or
7742     *  the function invoked per iteration.
7743     * @param {...*} [args] The arguments to invoke each method with.
7744     * @returns {Array} Returns the array of results.
7745     * @example
7746     *
7747     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
7748     * // => [[1, 5, 7], [1, 2, 3]]
7749     *
7750     * _.invokeMap([123, 456], String.prototype.split, '');
7751     * // => [['1', '2', '3'], ['4', '5', '6']]
7752     */
7753    var invokeMap = rest(function(collection, path, args) {
7754      var index = -1,
7755          isFunc = typeof path == 'function',
7756          isProp = isKey(path),
7757          result = isArrayLike(collection) ? Array(collection.length) : [];
7758
7759      baseEach(collection, function(value) {
7760        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
7761        result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
7762      });
7763      return result;
7764    });
7765
7766    /**
7767     * Creates an object composed of keys generated from the results of running
7768     * each element of `collection` through `iteratee`. The corresponding value
7769     * of each key is the last element responsible for generating the key. The
7770     * iteratee is invoked with one argument: (value).
7771     *
7772     * @static
7773     * @memberOf _
7774     * @category Collection
7775     * @param {Array|Object} collection The collection to iterate over.
7776     * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
7777     * @returns {Object} Returns the composed aggregate object.
7778     * @example
7779     *
7780     * var array = [
7781     *   { 'dir': 'left', 'code': 97 },
7782     *   { 'dir': 'right', 'code': 100 }
7783     * ];
7784     *
7785     * _.keyBy(array, function(o) {
7786     *   return String.fromCharCode(o.code);
7787     * });
7788     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
7789     *
7790     * _.keyBy(array, 'dir');
7791     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
7792     */
7793    var keyBy = createAggregator(function(result, value, key) {
7794      result[key] = value;
7795    });
7796
7797    /**
7798     * Creates an array of values by running each element in `collection` through
7799     * `iteratee`. The iteratee is invoked with three arguments:
7800     * (value, index|key, collection).
7801     *
7802     * Many lodash methods are guarded to work as iteratees for methods like
7803     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
7804     *
7805     * The guarded methods are:
7806     * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
7807     * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
7808     * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
7809     * and `words`
7810     *
7811     * @static
7812     * @memberOf _
7813     * @category Collection
7814     * @param {Array|Object} collection The collection to iterate over.
7815     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
7816     * @returns {Array} Returns the new mapped array.
7817     * @example
7818     *
7819     * function square(n) {
7820     *   return n * n;
7821     * }
7822     *
7823     * _.map([4, 8], square);
7824     * // => [16, 64]
7825     *
7826     * _.map({ 'a': 4, 'b': 8 }, square);
7827     * // => [16, 64] (iteration order is not guaranteed)
7828     *
7829     * var users = [
7830     *   { 'user': 'barney' },
7831     *   { 'user': 'fred' }
7832     * ];
7833     *
7834     * // The `_.property` iteratee shorthand.
7835     * _.map(users, 'user');
7836     * // => ['barney', 'fred']
7837     */
7838    function map(collection, iteratee) {
7839      var func = isArray(collection) ? arrayMap : baseMap;
7840      return func(collection, getIteratee(iteratee, 3));
7841    }
7842
7843    /**
7844     * This method is like `_.sortBy` except that it allows specifying the sort
7845     * orders of the iteratees to sort by. If `orders` is unspecified, all values
7846     * are sorted in ascending order. Otherwise, specify an order of "desc" for
7847     * descending or "asc" for ascending sort order of corresponding values.
7848     *
7849     * @static
7850     * @memberOf _
7851     * @category Collection
7852     * @param {Array|Object} collection The collection to iterate over.
7853     * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by.
7854     * @param {string[]} [orders] The sort orders of `iteratees`.
7855     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`.
7856     * @returns {Array} Returns the new sorted array.
7857     * @example
7858     *
7859     * var users = [
7860     *   { 'user': 'fred',   'age': 48 },
7861     *   { 'user': 'barney', 'age': 34 },
7862     *   { 'user': 'fred',   'age': 42 },
7863     *   { 'user': 'barney', 'age': 36 }
7864     * ];
7865     *
7866     * // Sort by `user` in ascending order and by `age` in descending order.
7867     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
7868     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
7869     */
7870    function orderBy(collection, iteratees, orders, guard) {
7871      if (collection == null) {
7872        return [];
7873      }
7874      if (!isArray(iteratees)) {
7875        iteratees = iteratees == null ? [] : [iteratees];
7876      }
7877      orders = guard ? undefined : orders;
7878      if (!isArray(orders)) {
7879        orders = orders == null ? [] : [orders];
7880      }
7881      return baseOrderBy(collection, iteratees, orders);
7882    }
7883
7884    /**
7885     * Creates an array of elements split into two groups, the first of which
7886     * contains elements `predicate` returns truthy for, the second of which
7887     * contains elements `predicate` returns falsey for. The predicate is
7888     * invoked with one argument: (value).
7889     *
7890     * @static
7891     * @memberOf _
7892     * @category Collection
7893     * @param {Array|Object} collection The collection to iterate over.
7894     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
7895     * @returns {Array} Returns the array of grouped elements.
7896     * @example
7897     *
7898     * var users = [
7899     *   { 'user': 'barney',  'age': 36, 'active': false },
7900     *   { 'user': 'fred',    'age': 40, 'active': true },
7901     *   { 'user': 'pebbles', 'age': 1,  'active': false }
7902     * ];
7903     *
7904     * _.partition(users, function(o) { return o.active; });
7905     * // => objects for [['fred'], ['barney', 'pebbles']]
7906     *
7907     * // The `_.matches` iteratee shorthand.
7908     * _.partition(users, { 'age': 1, 'active': false });
7909     * // => objects for [['pebbles'], ['barney', 'fred']]
7910     *
7911     * // The `_.matchesProperty` iteratee shorthand.
7912     * _.partition(users, ['active', false]);
7913     * // => objects for [['barney', 'pebbles'], ['fred']]
7914     *
7915     * // The `_.property` iteratee shorthand.
7916     * _.partition(users, 'active');
7917     * // => objects for [['fred'], ['barney', 'pebbles']]
7918     */
7919    var partition = createAggregator(function(result, value, key) {
7920      result[key ? 0 : 1].push(value);
7921    }, function() { return [[], []]; });
7922
7923    /**
7924     * Reduces `collection` to a value which is the accumulated result of running
7925     * each element in `collection` through `iteratee`, where each successive
7926     * invocation is supplied the return value of the previous. If `accumulator`
7927     * is not given the first element of `collection` is used as the initial
7928     * value. The iteratee is invoked with four arguments:
7929     * (accumulator, value, index|key, collection).
7930     *
7931     * Many lodash methods are guarded to work as iteratees for methods like
7932     * `_.reduce`, `_.reduceRight`, and `_.transform`.
7933     *
7934     * The guarded methods are:
7935     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
7936     * and `sortBy`
7937     *
7938     * @static
7939     * @memberOf _
7940     * @category Collection
7941     * @param {Array|Object} collection The collection to iterate over.
7942     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7943     * @param {*} [accumulator] The initial value.
7944     * @returns {*} Returns the accumulated value.
7945     * @example
7946     *
7947     * _.reduce([1, 2], function(sum, n) {
7948     *   return sum + n;
7949     * }, 0);
7950     * // => 3
7951     *
7952     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
7953     *   (result[value] || (result[value] = [])).push(key);
7954     *   return result;
7955     * }, {});
7956     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
7957     */
7958    function reduce(collection, iteratee, accumulator) {
7959      var func = isArray(collection) ? arrayReduce : baseReduce,
7960          initAccum = arguments.length < 3;
7961
7962      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
7963    }
7964
7965    /**
7966     * This method is like `_.reduce` except that it iterates over elements of
7967     * `collection` from right to left.
7968     *
7969     * @static
7970     * @memberOf _
7971     * @category Collection
7972     * @param {Array|Object} collection The collection to iterate over.
7973     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
7974     * @param {*} [accumulator] The initial value.
7975     * @returns {*} Returns the accumulated value.
7976     * @example
7977     *
7978     * var array = [[0, 1], [2, 3], [4, 5]];
7979     *
7980     * _.reduceRight(array, function(flattened, other) {
7981     *   return flattened.concat(other);
7982     * }, []);
7983     * // => [4, 5, 2, 3, 0, 1]
7984     */
7985    function reduceRight(collection, iteratee, accumulator) {
7986      var func = isArray(collection) ? arrayReduceRight : baseReduce,
7987          initAccum = arguments.length < 3;
7988
7989      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
7990    }
7991
7992    /**
7993     * The opposite of `_.filter`; this method returns the elements of `collection`
7994     * that `predicate` does **not** return truthy for.
7995     *
7996     * @static
7997     * @memberOf _
7998     * @category Collection
7999     * @param {Array|Object} collection The collection to iterate over.
8000     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8001     * @returns {Array} Returns the new filtered array.
8002     * @example
8003     *
8004     * var users = [
8005     *   { 'user': 'barney', 'age': 36, 'active': false },
8006     *   { 'user': 'fred',   'age': 40, 'active': true }
8007     * ];
8008     *
8009     * _.reject(users, function(o) { return !o.active; });
8010     * // => objects for ['fred']
8011     *
8012     * // The `_.matches` iteratee shorthand.
8013     * _.reject(users, { 'age': 40, 'active': true });
8014     * // => objects for ['barney']
8015     *
8016     * // The `_.matchesProperty` iteratee shorthand.
8017     * _.reject(users, ['active', false]);
8018     * // => objects for ['fred']
8019     *
8020     * // The `_.property` iteratee shorthand.
8021     * _.reject(users, 'active');
8022     * // => objects for ['barney']
8023     */
8024    function reject(collection, predicate) {
8025      var func = isArray(collection) ? arrayFilter : baseFilter;
8026      predicate = getIteratee(predicate, 3);
8027      return func(collection, function(value, index, collection) {
8028        return !predicate(value, index, collection);
8029      });
8030    }
8031
8032    /**
8033     * Gets a random element from `collection`.
8034     *
8035     * @static
8036     * @memberOf _
8037     * @category Collection
8038     * @param {Array|Object} collection The collection to sample.
8039     * @returns {*} Returns the random element.
8040     * @example
8041     *
8042     * _.sample([1, 2, 3, 4]);
8043     * // => 2
8044     */
8045    function sample(collection) {
8046      var array = isArrayLike(collection) ? collection : values(collection),
8047          length = array.length;
8048
8049      return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
8050    }
8051
8052    /**
8053     * Gets `n` random elements at unique keys from `collection` up to the
8054     * size of `collection`.
8055     *
8056     * @static
8057     * @memberOf _
8058     * @category Collection
8059     * @param {Array|Object} collection The collection to sample.
8060     * @param {number} [n=0] The number of elements to sample.
8061     * @returns {Array} Returns the random elements.
8062     * @example
8063     *
8064     * _.sampleSize([1, 2, 3], 2);
8065     * // => [3, 1]
8066     *
8067     * _.sampleSize([1, 2, 3], 4);
8068     * // => [2, 3, 1]
8069     */
8070    function sampleSize(collection, n) {
8071      var index = -1,
8072          result = toArray(collection),
8073          length = result.length,
8074          lastIndex = length - 1;
8075
8076      n = baseClamp(toInteger(n), 0, length);
8077      while (++index < n) {
8078        var rand = baseRandom(index, lastIndex),
8079            value = result[rand];
8080
8081        result[rand] = result[index];
8082        result[index] = value;
8083      }
8084      result.length = n;
8085      return result;
8086    }
8087
8088    /**
8089     * Creates an array of shuffled values, using a version of the
8090     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
8091     *
8092     * @static
8093     * @memberOf _
8094     * @category Collection
8095     * @param {Array|Object} collection The collection to shuffle.
8096     * @returns {Array} Returns the new shuffled array.
8097     * @example
8098     *
8099     * _.shuffle([1, 2, 3, 4]);
8100     * // => [4, 1, 3, 2]
8101     */
8102    function shuffle(collection) {
8103      return sampleSize(collection, MAX_ARRAY_LENGTH);
8104    }
8105
8106    /**
8107     * Gets the size of `collection` by returning its length for array-like
8108     * values or the number of own enumerable properties for objects.
8109     *
8110     * @static
8111     * @memberOf _
8112     * @category Collection
8113     * @param {Array|Object} collection The collection to inspect.
8114     * @returns {number} Returns the collection size.
8115     * @example
8116     *
8117     * _.size([1, 2, 3]);
8118     * // => 3
8119     *
8120     * _.size({ 'a': 1, 'b': 2 });
8121     * // => 2
8122     *
8123     * _.size('pebbles');
8124     * // => 7
8125     */
8126    function size(collection) {
8127      if (collection == null) {
8128        return 0;
8129      }
8130      if (isArrayLike(collection)) {
8131        var result = collection.length;
8132        return (result && isString(collection)) ? stringSize(collection) : result;
8133      }
8134      return keys(collection).length;
8135    }
8136
8137    /**
8138     * Checks if `predicate` returns truthy for **any** element of `collection`.
8139     * Iteration is stopped once `predicate` returns truthy. The predicate is
8140     * invoked with three arguments: (value, index|key, collection).
8141     *
8142     * @static
8143     * @memberOf _
8144     * @category Collection
8145     * @param {Array|Object} collection The collection to iterate over.
8146     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
8147     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8148     * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
8149     * @example
8150     *
8151     * _.some([null, 0, 'yes', false], Boolean);
8152     * // => true
8153     *
8154     * var users = [
8155     *   { 'user': 'barney', 'active': true },
8156     *   { 'user': 'fred',   'active': false }
8157     * ];
8158     *
8159     * // The `_.matches` iteratee shorthand.
8160     * _.some(users, { 'user': 'barney', 'active': false });
8161     * // => false
8162     *
8163     * // The `_.matchesProperty` iteratee shorthand.
8164     * _.some(users, ['active', false]);
8165     * // => true
8166     *
8167     * // The `_.property` iteratee shorthand.
8168     * _.some(users, 'active');
8169     * // => true
8170     */
8171    function some(collection, predicate, guard) {
8172      var func = isArray(collection) ? arraySome : baseSome;
8173      if (guard && isIterateeCall(collection, predicate, guard)) {
8174        predicate = undefined;
8175      }
8176      return func(collection, getIteratee(predicate, 3));
8177    }
8178
8179    /**
8180     * Creates an array of elements, sorted in ascending order by the results of
8181     * running each element in a collection through each iteratee. This method
8182     * performs a stable sort, that is, it preserves the original sort order of
8183     * equal elements. The iteratees are invoked with one argument: (value).
8184     *
8185     * @static
8186     * @memberOf _
8187     * @category Collection
8188     * @param {Array|Object} collection The collection to iterate over.
8189     * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
8190     *  The iteratees to sort by, specified individually or in arrays.
8191     * @returns {Array} Returns the new sorted array.
8192     * @example
8193     *
8194     * var users = [
8195     *   { 'user': 'fred',   'age': 48 },
8196     *   { 'user': 'barney', 'age': 36 },
8197     *   { 'user': 'fred',   'age': 42 },
8198     *   { 'user': 'barney', 'age': 34 }
8199     * ];
8200     *
8201     * _.sortBy(users, function(o) { return o.user; });
8202     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8203     *
8204     * _.sortBy(users, ['user', 'age']);
8205     * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
8206     *
8207     * _.sortBy(users, 'user', function(o) {
8208     *   return Math.floor(o.age / 10);
8209     * });
8210     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
8211     */
8212    var sortBy = rest(function(collection, iteratees) {
8213      if (collection == null) {
8214        return [];
8215      }
8216      var length = iteratees.length;
8217      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
8218        iteratees = [];
8219      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
8220        iteratees.length = 1;
8221      }
8222      return baseOrderBy(collection, baseFlatten(iteratees), []);
8223    });
8224
8225    /*------------------------------------------------------------------------*/
8226
8227    /**
8228     * Gets the timestamp of the number of milliseconds that have elapsed since
8229     * the Unix epoch (1 January 1970 00:00:00 UTC).
8230     *
8231     * @static
8232     * @memberOf _
8233     * @type Function
8234     * @category Date
8235     * @returns {number} Returns the timestamp.
8236     * @example
8237     *
8238     * _.defer(function(stamp) {
8239     *   console.log(_.now() - stamp);
8240     * }, _.now());
8241     * // => logs the number of milliseconds it took for the deferred function to be invoked
8242     */
8243    var now = Date.now;
8244
8245    /*------------------------------------------------------------------------*/
8246
8247    /**
8248     * The opposite of `_.before`; this method creates a function that invokes
8249     * `func` once it's called `n` or more times.
8250     *
8251     * @static
8252     * @memberOf _
8253     * @category Function
8254     * @param {number} n The number of calls before `func` is invoked.
8255     * @param {Function} func The function to restrict.
8256     * @returns {Function} Returns the new restricted function.
8257     * @example
8258     *
8259     * var saves = ['profile', 'settings'];
8260     *
8261     * var done = _.after(saves.length, function() {
8262     *   console.log('done saving!');
8263     * });
8264     *
8265     * _.forEach(saves, function(type) {
8266     *   asyncSave({ 'type': type, 'complete': done });
8267     * });
8268     * // => logs 'done saving!' after the two async saves have completed
8269     */
8270    function after(n, func) {
8271      if (typeof func != 'function') {
8272        throw new TypeError(FUNC_ERROR_TEXT);
8273      }
8274      n = toInteger(n);
8275      return function() {
8276        if (--n < 1) {
8277          return func.apply(this, arguments);
8278        }
8279      };
8280    }
8281
8282    /**
8283     * Creates a function that accepts up to `n` arguments, ignoring any
8284     * additional arguments.
8285     *
8286     * @static
8287     * @memberOf _
8288     * @category Function
8289     * @param {Function} func The function to cap arguments for.
8290     * @param {number} [n=func.length] The arity cap.
8291     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8292     * @returns {Function} Returns the new function.
8293     * @example
8294     *
8295     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
8296     * // => [6, 8, 10]
8297     */
8298    function ary(func, n, guard) {
8299      n = guard ? undefined : n;
8300      n = (func && n == null) ? func.length : n;
8301      return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
8302    }
8303
8304    /**
8305     * Creates a function that invokes `func`, with the `this` binding and arguments
8306     * of the created function, while it's called less than `n` times. Subsequent
8307     * calls to the created function return the result of the last `func` invocation.
8308     *
8309     * @static
8310     * @memberOf _
8311     * @category Function
8312     * @param {number} n The number of calls at which `func` is no longer invoked.
8313     * @param {Function} func The function to restrict.
8314     * @returns {Function} Returns the new restricted function.
8315     * @example
8316     *
8317     * jQuery(element).on('click', _.before(5, addContactToList));
8318     * // => allows adding up to 4 contacts to the list
8319     */
8320    function before(n, func) {
8321      var result;
8322      if (typeof func != 'function') {
8323        throw new TypeError(FUNC_ERROR_TEXT);
8324      }
8325      n = toInteger(n);
8326      return function() {
8327        if (--n > 0) {
8328          result = func.apply(this, arguments);
8329        }
8330        if (n <= 1) {
8331          func = undefined;
8332        }
8333        return result;
8334      };
8335    }
8336
8337    /**
8338     * Creates a function that invokes `func` with the `this` binding of `thisArg`
8339     * and prepends any additional `_.bind` arguments to those provided to the
8340     * bound function.
8341     *
8342     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
8343     * may be used as a placeholder for partially applied arguments.
8344     *
8345     * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
8346     * property of bound functions.
8347     *
8348     * @static
8349     * @memberOf _
8350     * @category Function
8351     * @param {Function} func The function to bind.
8352     * @param {*} thisArg The `this` binding of `func`.
8353     * @param {...*} [partials] The arguments to be partially applied.
8354     * @returns {Function} Returns the new bound function.
8355     * @example
8356     *
8357     * var greet = function(greeting, punctuation) {
8358     *   return greeting + ' ' + this.user + punctuation;
8359     * };
8360     *
8361     * var object = { 'user': 'fred' };
8362     *
8363     * var bound = _.bind(greet, object, 'hi');
8364     * bound('!');
8365     * // => 'hi fred!'
8366     *
8367     * // Bound with placeholders.
8368     * var bound = _.bind(greet, object, _, '!');
8369     * bound('hi');
8370     * // => 'hi fred!'
8371     */
8372    var bind = rest(function(func, thisArg, partials) {
8373      var bitmask = BIND_FLAG;
8374      if (partials.length) {
8375        var placeholder = lodash.placeholder || bind.placeholder,
8376            holders = replaceHolders(partials, placeholder);
8377
8378        bitmask |= PARTIAL_FLAG;
8379      }
8380      return createWrapper(func, bitmask, thisArg, partials, holders);
8381    });
8382
8383    /**
8384     * Creates a function that invokes the method at `object[key]` and prepends
8385     * any additional `_.bindKey` arguments to those provided to the bound function.
8386     *
8387     * This method differs from `_.bind` by allowing bound functions to reference
8388     * methods that may be redefined or don't yet exist.
8389     * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
8390     * for more details.
8391     *
8392     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
8393     * builds, may be used as a placeholder for partially applied arguments.
8394     *
8395     * @static
8396     * @memberOf _
8397     * @category Function
8398     * @param {Object} object The object to invoke the method on.
8399     * @param {string} key The key of the method.
8400     * @param {...*} [partials] The arguments to be partially applied.
8401     * @returns {Function} Returns the new bound function.
8402     * @example
8403     *
8404     * var object = {
8405     *   'user': 'fred',
8406     *   'greet': function(greeting, punctuation) {
8407     *     return greeting + ' ' + this.user + punctuation;
8408     *   }
8409     * };
8410     *
8411     * var bound = _.bindKey(object, 'greet', 'hi');
8412     * bound('!');
8413     * // => 'hi fred!'
8414     *
8415     * object.greet = function(greeting, punctuation) {
8416     *   return greeting + 'ya ' + this.user + punctuation;
8417     * };
8418     *
8419     * bound('!');
8420     * // => 'hiya fred!'
8421     *
8422     * // Bound with placeholders.
8423     * var bound = _.bindKey(object, 'greet', _, '!');
8424     * bound('hi');
8425     * // => 'hiya fred!'
8426     */
8427    var bindKey = rest(function(object, key, partials) {
8428      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
8429      if (partials.length) {
8430        var placeholder = lodash.placeholder || bindKey.placeholder,
8431            holders = replaceHolders(partials, placeholder);
8432
8433        bitmask |= PARTIAL_FLAG;
8434      }
8435      return createWrapper(key, bitmask, object, partials, holders);
8436    });
8437
8438    /**
8439     * Creates a function that accepts arguments of `func` and either invokes
8440     * `func` returning its result, if at least `arity` number of arguments have
8441     * been provided, or returns a function that accepts the remaining `func`
8442     * arguments, and so on. The arity of `func` may be specified if `func.length`
8443     * is not sufficient.
8444     *
8445     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
8446     * may be used as a placeholder for provided arguments.
8447     *
8448     * **Note:** This method doesn't set the "length" property of curried functions.
8449     *
8450     * @static
8451     * @memberOf _
8452     * @category Function
8453     * @param {Function} func The function to curry.
8454     * @param {number} [arity=func.length] The arity of `func`.
8455     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8456     * @returns {Function} Returns the new curried function.
8457     * @example
8458     *
8459     * var abc = function(a, b, c) {
8460     *   return [a, b, c];
8461     * };
8462     *
8463     * var curried = _.curry(abc);
8464     *
8465     * curried(1)(2)(3);
8466     * // => [1, 2, 3]
8467     *
8468     * curried(1, 2)(3);
8469     * // => [1, 2, 3]
8470     *
8471     * curried(1, 2, 3);
8472     * // => [1, 2, 3]
8473     *
8474     * // Curried with placeholders.
8475     * curried(1)(_, 3)(2);
8476     * // => [1, 2, 3]
8477     */
8478    function curry(func, arity, guard) {
8479      arity = guard ? undefined : arity;
8480      var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8481      result.placeholder = lodash.placeholder || curry.placeholder;
8482      return result;
8483    }
8484
8485    /**
8486     * This method is like `_.curry` except that arguments are applied to `func`
8487     * in the manner of `_.partialRight` instead of `_.partial`.
8488     *
8489     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
8490     * builds, may be used as a placeholder for provided arguments.
8491     *
8492     * **Note:** This method doesn't set the "length" property of curried functions.
8493     *
8494     * @static
8495     * @memberOf _
8496     * @category Function
8497     * @param {Function} func The function to curry.
8498     * @param {number} [arity=func.length] The arity of `func`.
8499     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
8500     * @returns {Function} Returns the new curried function.
8501     * @example
8502     *
8503     * var abc = function(a, b, c) {
8504     *   return [a, b, c];
8505     * };
8506     *
8507     * var curried = _.curryRight(abc);
8508     *
8509     * curried(3)(2)(1);
8510     * // => [1, 2, 3]
8511     *
8512     * curried(2, 3)(1);
8513     * // => [1, 2, 3]
8514     *
8515     * curried(1, 2, 3);
8516     * // => [1, 2, 3]
8517     *
8518     * // Curried with placeholders.
8519     * curried(3)(1, _)(2);
8520     * // => [1, 2, 3]
8521     */
8522    function curryRight(func, arity, guard) {
8523      arity = guard ? undefined : arity;
8524      var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
8525      result.placeholder = lodash.placeholder || curryRight.placeholder;
8526      return result;
8527    }
8528
8529    /**
8530     * Creates a debounced function that delays invoking `func` until after `wait`
8531     * milliseconds have elapsed since the last time the debounced function was
8532     * invoked. The debounced function comes with a `cancel` method to cancel
8533     * delayed `func` invocations and a `flush` method to immediately invoke them.
8534     * Provide an options object to indicate whether `func` should be invoked on
8535     * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
8536     * with the last arguments provided to the debounced function. Subsequent calls
8537     * to the debounced function return the result of the last `func` invocation.
8538     *
8539     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
8540     * on the trailing edge of the timeout only if the debounced function is
8541     * invoked more than once during the `wait` timeout.
8542     *
8543     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
8544     * for details over the differences between `_.debounce` and `_.throttle`.
8545     *
8546     * @static
8547     * @memberOf _
8548     * @category Function
8549     * @param {Function} func The function to debounce.
8550     * @param {number} [wait=0] The number of milliseconds to delay.
8551     * @param {Object} [options] The options object.
8552     * @param {boolean} [options.leading=false] Specify invoking on the leading
8553     *  edge of the timeout.
8554     * @param {number} [options.maxWait] The maximum time `func` is allowed to be
8555     *  delayed before it's invoked.
8556     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
8557     *  edge of the timeout.
8558     * @returns {Function} Returns the new debounced function.
8559     * @example
8560     *
8561     * // Avoid costly calculations while the window size is in flux.
8562     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
8563     *
8564     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
8565     * jQuery(element).on('click', _.debounce(sendMail, 300, {
8566     *   'leading': true,
8567     *   'trailing': false
8568     * }));
8569     *
8570     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
8571     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
8572     * var source = new EventSource('/stream');
8573     * jQuery(source).on('message', debounced);
8574     *
8575     * // Cancel the trailing debounced invocation.
8576     * jQuery(window).on('popstate', debounced.cancel);
8577     */
8578    function debounce(func, wait, options) {
8579      var args,
8580          maxTimeoutId,
8581          result,
8582          stamp,
8583          thisArg,
8584          timeoutId,
8585          trailingCall,
8586          lastCalled = 0,
8587          leading = false,
8588          maxWait = false,
8589          trailing = true;
8590
8591      if (typeof func != 'function') {
8592        throw new TypeError(FUNC_ERROR_TEXT);
8593      }
8594      wait = toNumber(wait) || 0;
8595      if (isObject(options)) {
8596        leading = !!options.leading;
8597        maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
8598        trailing = 'trailing' in options ? !!options.trailing : trailing;
8599      }
8600
8601      function cancel() {
8602        if (timeoutId) {
8603          clearTimeout(timeoutId);
8604        }
8605        if (maxTimeoutId) {
8606          clearTimeout(maxTimeoutId);
8607        }
8608        lastCalled = 0;
8609        args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
8610      }
8611
8612      function complete(isCalled, id) {
8613        if (id) {
8614          clearTimeout(id);
8615        }
8616        maxTimeoutId = timeoutId = trailingCall = undefined;
8617        if (isCalled) {
8618          lastCalled = now();
8619          result = func.apply(thisArg, args);
8620          if (!timeoutId && !maxTimeoutId) {
8621            args = thisArg = undefined;
8622          }
8623        }
8624      }
8625
8626      function delayed() {
8627        var remaining = wait - (now() - stamp);
8628        if (remaining <= 0 || remaining > wait) {
8629          complete(trailingCall, maxTimeoutId);
8630        } else {
8631          timeoutId = setTimeout(delayed, remaining);
8632        }
8633      }
8634
8635      function flush() {
8636        if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
8637          result = func.apply(thisArg, args);
8638        }
8639        cancel();
8640        return result;
8641      }
8642
8643      function maxDelayed() {
8644        complete(trailing, timeoutId);
8645      }
8646
8647      function debounced() {
8648        args = arguments;
8649        stamp = now();
8650        thisArg = this;
8651        trailingCall = trailing && (timeoutId || !leading);
8652
8653        if (maxWait === false) {
8654          var leadingCall = leading && !timeoutId;
8655        } else {
8656          if (!lastCalled && !maxTimeoutId && !leading) {
8657            lastCalled = stamp;
8658          }
8659          var remaining = maxWait - (stamp - lastCalled),
8660              isCalled = remaining <= 0 || remaining > maxWait;
8661
8662          if (isCalled) {
8663            if (maxTimeoutId) {
8664              maxTimeoutId = clearTimeout(maxTimeoutId);
8665            }
8666            lastCalled = stamp;
8667            result = func.apply(thisArg, args);
8668          }
8669          else if (!maxTimeout
vendor: 1,888 bytes, lines 8669-8731
8669Id) {
8670            maxTimeoutId = setTimeout(maxDelayed, remaining);
8671          }
8672        }
8673        if (isCalled && timeoutId) {
8674          timeoutId = clearTimeout(timeoutId);
8675        }
8676        else if (!timeoutId && wait !== maxWait) {
8677          timeoutId = setTimeout(delayed, wait);
8678        }
8679        if (leadingCall) {
8680          isCalled = true;
8681          result = func.apply(thisArg, args);
8682        }
8683        if (isCalled && !timeoutId && !maxTimeoutId) {
8684          args = thisArg = undefined;
8685        }
8686        return result;
8687      }
8688      debounced.cancel = cancel;
8689      debounced.flush = flush;
8690      return debounced;
8691    }
8692
8693    /**
8694     * Defers invoking the `func` until the current call stack has cleared. Any
8695     * additional arguments are provided to `func` when it's invoked.
8696     *
8697     * @static
8698     * @memberOf _
8699     * @category Function
8700     * @param {Function} func The function to defer.
8701     * @param {...*} [args] The arguments to invoke `func` with.
8702     * @returns {number} Returns the timer id.
8703     * @example
8704     *
8705     * _.defer(function(text) {
8706     *   console.log(text);
8707     * }, 'deferred');
8708     * // => logs 'deferred' after one or more milliseconds
8709     */
8710    var defer = rest(function(func, args) {
8711      return baseDelay(func, 1, args);
8712    });
8713
8714    /**
8715     * Invokes `func` after `wait` milliseconds. Any additional arguments are
8716     * provided to `func` when it's invoked.
8717     *
8718     * @static
8719     * @memberOf _
8720     * @category Function
8721     * @param {Function} func The function to delay.
8722     * @param {number} wait The number of milliseconds to delay invocation.
8723     * @param {...*} [args] The arguments to invoke `func` with.
8724     * @returns {number} Returns the timer id.
8725     * @example
8726     *
8727     * _.delay(function(text) {
8728     *   console.log(text);
8729     * }, 1000, 'later');
8730     * // => logs 'later' after one second
8731     */
vendor: 9,513 bytes, lines 8732-9019
8732    var delay = rest(function(func, wait, args) {
8733      return baseDelay(func, toNumber(wait) || 0, args);
8734    });
8735
8736    /**
8737     * Creates a function that invokes `func` with arguments reversed.
8738     *
8739     * @static
8740     * @memberOf _
8741     * @category Function
8742     * @param {Function} func The function to flip arguments for.
8743     * @returns {Function} Returns the new function.
8744     * @example
8745     *
8746     * var flipped = _.flip(function() {
8747     *   return _.toArray(arguments);
8748     * });
8749     *
8750     * flipped('a', 'b', 'c', 'd');
8751     * // => ['d', 'c', 'b', 'a']
8752     */
8753    function flip(func) {
8754      return createWrapper(func, FLIP_FLAG);
8755    }
8756
8757    /**
8758     * Creates a function that memoizes the result of `func`. If `resolver` is
8759     * provided it determines the cache key for storing the result based on the
8760     * arguments provided to the memoized function. By default, the first argument
8761     * provided to the memoized function is used as the map cache key. The `func`
8762     * is invoked with the `this` binding of the memoized function.
8763     *
8764     * **Note:** The cache is exposed as the `cache` property on the memoized
8765     * function. Its creation may be customized by replacing the `_.memoize.Cache`
8766     * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
8767     * method interface of `delete`, `get`, `has`, and `set`.
8768     *
8769     * @static
8770     * @memberOf _
8771     * @category Function
8772     * @param {Function} func The function to have its output memoized.
8773     * @param {Function} [resolver] The function to resolve the cache key.
8774     * @returns {Function} Returns the new memoizing function.
8775     * @example
8776     *
8777     * var object = { 'a': 1, 'b': 2 };
8778     * var other = { 'c': 3, 'd': 4 };
8779     *
8780     * var values = _.memoize(_.values);
8781     * values(object);
8782     * // => [1, 2]
8783     *
8784     * values(other);
8785     * // => [3, 4]
8786     *
8787     * object.a = 2;
8788     * values(object);
8789     * // => [1, 2]
8790     *
8791     * // Modify the result cache.
8792     * values.cache.set(object, ['a', 'b']);
8793     * values(object);
8794     * // => ['a', 'b']
8795     *
8796     * // Replace `_.memoize.Cache`.
8797     * _.memoize.Cache = WeakMap;
8798     */
8799    function memoize(func, resolver) {
8800      if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
8801        throw new TypeError(FUNC_ERROR_TEXT);
8802      }
8803      var memoized = function() {
8804        var args = arguments,
8805            key = resolver ? resolver.apply(this, args) : args[0],
8806            cache = memoized.cache;
8807
8808        if (cache.has(key)) {
8809          return cache.get(key);
8810        }
8811        var result = func.apply(this, args);
8812        memoized.cache = cache.set(key, result);
8813        return result;
8814      };
8815      memoized.cache = new memoize.Cache;
8816      return memoized;
8817    }
8818
8819    /**
8820     * Creates a function that negates the result of the predicate `func`. The
8821     * `func` predicate is invoked with the `this` binding and arguments of the
8822     * created function.
8823     *
8824     * @static
8825     * @memberOf _
8826     * @category Function
8827     * @param {Function} predicate The predicate to negate.
8828     * @returns {Function} Returns the new function.
8829     * @example
8830     *
8831     * function isEven(n) {
8832     *   return n % 2 == 0;
8833     * }
8834     *
8835     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
8836     * // => [1, 3, 5]
8837     */
8838    function negate(predicate) {
8839      if (typeof predicate != 'function') {
8840        throw new TypeError(FUNC_ERROR_TEXT);
8841      }
8842      return function() {
8843        return !predicate.apply(this, arguments);
8844      };
8845    }
8846
8847    /**
8848     * Creates a function that is restricted to invoking `func` once. Repeat calls
8849     * to the function return the value of the first invocation. The `func` is
8850     * invoked with the `this` binding and arguments of the created function.
8851     *
8852     * @static
8853     * @memberOf _
8854     * @category Function
8855     * @param {Function} func The function to restrict.
8856     * @returns {Function} Returns the new restricted function.
8857     * @example
8858     *
8859     * var initialize = _.once(createApplication);
8860     * initialize();
8861     * initialize();
8862     * // `initialize` invokes `createApplication` once
8863     */
8864    function once(func) {
8865      return before(2, func);
8866    }
8867
8868    /**
8869     * Creates a function that invokes `func` with arguments transformed by
8870     * corresponding `transforms`.
8871     *
8872     * @static
8873     * @memberOf _
8874     * @category Function
8875     * @param {Function} func The function to wrap.
8876     * @param {...(Function|Function[])} [transforms] The functions to transform
8877     * arguments, specified individually or in arrays.
8878     * @returns {Function} Returns the new function.
8879     * @example
8880     *
8881     * function doubled(n) {
8882     *   return n * 2;
8883     * }
8884     *
8885     * function square(n) {
8886     *   return n * n;
8887     * }
8888     *
8889     * var func = _.overArgs(function(x, y) {
8890     *   return [x, y];
8891     * }, square, doubled);
8892     *
8893     * func(9, 3);
8894     * // => [81, 6]
8895     *
8896     * func(10, 5);
8897     * // => [100, 10]
8898     */
8899    var overArgs = rest(function(func, transforms) {
8900      transforms = arrayMap(baseFlatten(transforms), getIteratee());
8901
8902      var funcsLength = transforms.length;
8903      return rest(function(args) {
8904        var index = -1,
8905            length = nativeMin(args.length, funcsLength);
8906
8907        while (++index < length) {
8908          args[index] = transforms[index].call(this, args[index]);
8909        }
8910        return apply(func, this, args);
8911      });
8912    });
8913
8914    /**
8915     * Creates a function that invokes `func` with `partial` arguments prepended
8916     * to those provided to the new function. This method is like `_.bind` except
8917     * it does **not** alter the `this` binding.
8918     *
8919     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
8920     * builds, may be used as a placeholder for partially applied arguments.
8921     *
8922     * **Note:** This method doesn't set the "length" property of partially
8923     * applied functions.
8924     *
8925     * @static
8926     * @memberOf _
8927     * @category Function
8928     * @param {Function} func The function to partially apply arguments to.
8929     * @param {...*} [partials] The arguments to be partially applied.
8930     * @returns {Function} Returns the new partially applied function.
8931     * @example
8932     *
8933     * var greet = function(greeting, name) {
8934     *   return greeting + ' ' + name;
8935     * };
8936     *
8937     * var sayHelloTo = _.partial(greet, 'hello');
8938     * sayHelloTo('fred');
8939     * // => 'hello fred'
8940     *
8941     * // Partially applied with placeholders.
8942     * var greetFred = _.partial(greet, _, 'fred');
8943     * greetFred('hi');
8944     * // => 'hi fred'
8945     */
8946    var partial = rest(function(func, partials) {
8947      var placeholder = lodash.placeholder || partial.placeholder,
8948          holders = replaceHolders(partials, placeholder);
8949
8950      return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
8951    });
8952
8953    /**
8954     * This method is like `_.partial` except that partially applied arguments
8955     * are appended to those provided to the new function.
8956     *
8957     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
8958     * builds, may be used as a placeholder for partially applied arguments.
8959     *
8960     * **Note:** This method doesn't set the "length" property of partially
8961     * applied functions.
8962     *
8963     * @static
8964     * @memberOf _
8965     * @category Function
8966     * @param {Function} func The function to partially apply arguments to.
8967     * @param {...*} [partials] The arguments to be partially applied.
8968     * @returns {Function} Returns the new partially applied function.
8969     * @example
8970     *
8971     * var greet = function(greeting, name) {
8972     *   return greeting + ' ' + name;
8973     * };
8974     *
8975     * var greetFred = _.partialRight(greet, 'fred');
8976     * greetFred('hi');
8977     * // => 'hi fred'
8978     *
8979     * // Partially applied with placeholders.
8980     * var sayHelloTo = _.partialRight(greet, 'hello', _);
8981     * sayHelloTo('fred');
8982     * // => 'hello fred'
8983     */
8984    var partialRight = rest(function(func, partials) {
8985      var placeholder = lodash.placeholder || partialRight.placeholder,
8986          holders = replaceHolders(partials, placeholder);
8987
8988      return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
8989    });
8990
8991    /**
8992     * Creates a function that invokes `func` with arguments arranged according
8993     * to the specified indexes where the argument value at the first index is
8994     * provided as the first argument, the argument value at the second index is
8995     * provided as the second argument, and so on.
8996     *
8997     * @static
8998     * @memberOf _
8999     * @category Function
9000     * @param {Function} func The function to rearrange arguments for.
9001     * @param {...(number|number[])} indexes The arranged argument indexes,
9002     *  specified individually or in arrays.
9003     * @returns {Function} Returns the new function.
9004     * @example
9005     *
9006     * var rearged = _.rearg(function(a, b, c) {
9007     *   return [a, b, c];
9008     * }, 2, 0, 1);
9009     *
9010     * rearged('b', 'c', 'a')
9011     * // => ['a', 'b', 'c']
9012     */
9013    var rearg = rest(function(func, indexes) {
9014      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes));
9015    });
9016
9017    /**
9018     * Creates a function that invokes `func` with the `this` binding of the
9019     * created function and arguments from `start` and beyond provided as an array.
9020     *
9021     * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
9022     *
9023     * @static
9024     * @memberOf _
9025     * @category Function
9026     * @param {Function} func The function to apply a rest parameter to.
9027     * @param {number} [start=func.length-1] The start position of the rest parameter.
9028     * @returns {Function} Returns the new function.
9029     * @example
9030     *
9031     * var say = _.rest(function(what, names) {
9032     *   return what + ' ' + _.initial(names).join(', ') +
9033     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
9034     * });
9035     *
9036     * say('hello', 'fred', 'barney', 'pebbles');
9037     * // => 'hello fred, barney, & pebbles'
9038     */
9039    function rest(func, start) {
9040      if (typeof func != 'function') {
9041        throw new TypeError(FUNC_ERROR_TEXT);
9042      }
9043      start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
9044      return function() {
9045        var args = arguments,
9046            index = -1,
9047            length = nativeMax(args.length - start, 0),
9048            array = Array(length);
9049
9050        while (++index < length) {
9051          array[index] = args[start + index];
9052        }
9053        switch (start) {
9054          case 0: return func.call(this, array);
9055          case 1: return func.call(this, args[0], array);
9056          case 2: return func.call(this, args[0], args[1], array);
9057        }
9058        var otherArgs = Array(start + 1);
9059        index = -1;
9060        while (++index < start) {
9061          otherArgs[index] = args[index];
9062        }
9063        otherArgs[start] = array;
9064        return apply(func, this, otherArgs);
9065      };
9066    }
9067
9068    /**
9069     * Creates a function that invokes `func` with the `this` binding of the created
9070     * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3).
9071     *
9072     * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator).
9073     *
9074     * @static
9075     * @memberOf _
9076     * @category Function
9077     * @param {Function} func The function to spread arguments over.
9078     * @param {number} [start=0] The start position of the spread.
9079     * @returns {Function} Returns the new function.
9080     * @example
9081     *
9082     * var say = _.spread(function(who, what) {
9083     *   return who + ' says ' + what;
9084     * });
9085     *
9086     * say(['fred', 'hello']);
9087     * // => 'fred says hello'
9088     *
9089     * var numbers = Promise.all([
9090     *   Promise.resolve(40),
9091     *   Promise.resolve(36)
9092     * ]);
9093     *
9094     * numbers.then(_.spread(function(x, y) {
9095     *   return x + y;
9096     * }));
9097     * // => a Promise of 76
9098     */
9099    function spread(func, start) {
9100      if (typeof func != 'function') {
9101        throw new TypeError(FUNC_ERROR_TEXT);
9102      }
9103      start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
9104      return rest(function(args) {
9105        var array = args[start],
9106            otherArgs = args.slice(0, start);
9107
9108        if (array) {
9109          arrayPush(otherArgs, array);
9110        }
9111        return apply(func, this, otherArgs);
9112      });
9113    }
9114
9115    /**
9116     * Creates a throttled function that only invokes `func` at most once per
9117     * every `wait` milliseconds. The throttled function comes with a `cancel`
9118     * method to cancel delayed `func` invocations and a `flush` method to
9119     * immediately invoke them. Provide an options object to indicate whether
9120     * `func` should be invoked on the leading and/or trailing edge of the `wait`
9121     * timeout. The `func` is invoked with the last arguments provided to the
9122     * throttled function. Subsequent calls to the throttled function return the
9123     * result of the last `func` invocation.
9124     *
9125     * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
9126     * on the trailing edge of the timeout only if the throttled function is
9127     * invoked more than once during the `wait` timeout.
9128     *
9129     * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
9130     * for details over the differences between `_.throttle` and `_.debounce`.
9131     *
9132     * @static
9133     * @memberOf _
9134     * @category Function
9135     * @param {Function} func The function to throttle.
9136     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
9137     * @param {Object} [options] The options object.
9138     * @param {boolean} [options.leading=true] Specify invoking on the leading
9139     *  edge of the timeout.
9140     * @param {boolean} [options.trailing=true] Specify invoking on the trailing
9141     *  edge of the timeout.
9142     * @returns {Function} Returns the new throttled function.
9143     * @example
9144     *
9145     * // Avoid excessively updating the position while scrolling.
9146     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
9147     *
9148     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
9149     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
9150     * jQuery(element).on('click', throttled);
9151     *
9152     * // Cancel the trailing throttled invocation.
9153     * jQuery(window).on('popstate', throttled.cancel);
9154     */
9155    function throttle(func, wait, options) {
9156      var leading = true,
9157          trailing = true;
9158
9159      if (typeof func != 'function') {
9160        throw new TypeError(FUNC_ERROR_TEXT);
9161      }
9162      if (isObject(options)) {
9163        leading = 'leading' in options ? !!options.leading : leading;
9164        trailing = 'trailing' in options ? !!options.trailing : trailing;
9165      }
9166      return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
9167    }
9168
9169    /**
9170     * Creates a function that accepts up to one argument, ignoring any
9171     * additional arguments.
9172     *
9173     * @static
9174     * @memberOf _
9175     * @category Function
9176     * @param {Function} func The function to cap arguments for.
9177     * @returns {Function} Returns the new function.
9178     * @example
9179     *
9180     * _.map(['6', '8', '10'], _.unary(parseInt));
9181     * // => [6, 8, 10]
9182     */
9183    function unary(func) {
9184      return ary(func, 1);
9185    }
9186
9187    /**
9188     * Creates a function that provides `value` to the wrapper function as its
9189     * first argument. Any additional arguments provided to the function are
9190     * appended to those provided to the wrapper function. The wrapper is invoked
9191     * with the `this` binding of the created function.
9192     *
9193     * @static
9194     * @memberOf _
9195     * @category Function
9196     * @param {*} value The value to wrap.
9197     * @param {Function} wrapper The wrapper function.
9198     * @returns {Function} Returns the new function.
9199     * @example
9200     *
9201     * var p = _.wrap(_.escape, function(func, text) {
9202     *   return '<p>' + func(text) + '</p>';
9203     * });
9204     *
9205     * p('fred, barney, & pebbles');
9206     * // => '<p>fred, barney, &amp; pebbles</p>'
9207     */
9208    function wrap(value, wrapper) {
9209      wrapper = wrapper == null ? identity : wrapper;
9210      return partial(wrapper, value);
9211    }
9212
9213    /*------------------------------------------------------------------------*/
9214
9215    /**
9216     * Creates a shallow clone of `value`.
9217     *
9218     * **Note:** This method is loosely based on the
9219     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
9220     * and supports cloning arrays, array buffers, booleans, date objects, maps,
9221     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
9222     * arrays. The own enumerable properties of `arguments` objects are cloned
9223     * as plain objects. An empty object is returned for uncloneable values such
9224     * as error objects, functions, DOM nodes, and WeakMaps.
9225     *
9226     * @static
9227     * @memberOf _
9228     * @category Lang
9229     * @param {*} value The value to clone.
9230     * @returns {*} Returns the cloned value.
9231     * @example
9232     *
9233     * var objects = [{ 'a': 1 }, { 'b': 2 }];
9234     *
9235     * var shallow = _.clone(objects);
9236     * console.log(shallow[0] === objects[0]);
9237     * // => true
9238     */
9239    function clone(value) {
9240      return baseClone(value);
9241    }
9242
9243    /**
9244     * This method is like `_.clone` except that it accepts `customizer` which
9245     * is invoked to produce the cloned value. If `customizer` returns `undefined`
9246     * cloning is handled by the method instead. The `customizer` is invoked with
9247     * up to four arguments; (value [, index|key, object, stack]).
9248     *
9249     * @static
9250     * @memberOf _
9251     * @category Lang
9252     * @param {*} value The value to clone.
9253     * @param {Function} [customizer] The function to customize cloning.
9254     * @returns {*} Returns the cloned value.
9255     * @example
9256     *
9257     * function customizer(value) {
9258     *   if (_.isElement(value)) {
9259     *     return value.cloneNode(false);
9260     *   }
9261     * }
9262     *
9263     * var el = _.cloneWith(document.body, customizer);
9264     *
9265     * console.log(el === document.body);
9266     * // => false
9267     * console.log(el.nodeName);
9268     * // => 'BODY'
9269     * console.log(el.childNodes.length);
9270     * // => 0
9271     */
9272    function cloneWith(value, customizer) {
9273      return baseClone(value, false, customizer);
9274    }
9275
9276    /**
9277     * This method is like `_.clone` except that it recursively clones `value`.
9278     *
9279     * @static
9280     * @memberOf _
9281     * @category Lang
9282     * @param {*} value The value to recursively clone.
9283     * @returns {*} Returns the deep cloned value.
9284     * @example
9285     *
9286     * var objects = [{ 'a': 1 }, { 'b': 2 }];
9287     *
9288     * var deep = _.cloneDeep(objects);
9289     * console.log(deep[0] === objects[0]);
9290     * // => false
9291     */
9292    function cloneDeep(value) {
9293      return baseClone(value, true);
9294    }
9295
9296    /**
9297     * This method is like `_.cloneWith` except that it recursively clones `value`.
9298     *
9299     * @static
9300     * @memberOf _
9301     * @category Lang
9302     * @param {*} value The value to recursively clone.
9303     * @param {Function} [customizer] The function to customize cloning.
9304     * @returns {*} Returns the deep cloned value.
9305     * @example
9306     *
9307     * function customizer(value) {
9308     *   if (_.isElement(value)) {
9309     *     return value.cloneNode(true);
9310     *   }
9311     * }
9312     *
9313     * var el = _.cloneDeepWith(document.body, customizer);
9314     *
9315     * console.log(el === document.body);
9316     * // => false
9317     * console.log(el.nodeName);
9318     * // => 'BODY'
9319     * console.log(el.childNodes.length);
9320     * // => 20
9321     */
9322    function cloneDeepWith(value, customizer) {
9323      return baseClone(value, true, customizer);
9324    }
9325
9326    /**
9327     * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
9328     * comparison between two values to determine if they are equivalent.
9329     *
9330     * @static
9331     * @memberOf _
9332     * @category Lang
9333     * @param {*} value The value to compare.
9334     * @param {*} other The other value to compare.
9335     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9336     * @example
9337     *
9338     * var object = { 'user': 'fred' };
9339     * var other = { 'user': 'fred' };
9340     *
9341     * _.eq(object, object);
9342     * // => true
9343     *
9344     * _.eq(object, other);
9345     * // => false
9346     *
9347     * _.eq('a', 'a');
9348     * // => true
9349     *
9350     * _.eq('a', Object('a'));
9351     * // => false
9352     *
9353     * _.eq(NaN, NaN);
9354     * // => true
9355     */
9356    function eq(value, other) {
9357      return value === other || (value !== value && other !== other);
9358    }
9359
9360    /**
9361     * Checks if `value` is greater than `other`.
9362     *
9363     * @static
9364     * @memberOf _
9365     * @category Lang
9366     * @param {*} value The value to compare.
9367     * @param {*} other The other value to compare.
9368     * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
9369     * @example
9370     *
9371     * _.gt(3, 1);
9372     * // => true
9373     *
9374     * _.gt(3, 3);
9375     * // => false
9376     *
9377     * _.gt(1, 3);
9378     * // => false
9379     */
9380    function gt(value, other) {
9381      return value > other;
9382    }
9383
9384    /**
9385     * Checks if `value` is greater than or equal to `other`.
9386     *
9387     * @static
9388     * @memberOf _
9389     * @category Lang
9390     * @param {*} value The value to compare.
9391     * @param {*} other The other value to compare.
9392     * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
9393     * @example
9394     *
9395     * _.gte(3, 1);
9396     * // => true
9397     *
9398     * _.gte(3, 3);
9399     * // => true
9400     *
9401     * _.gte(1, 3);
9402     * // => false
9403     */
9404    function gte(value, other) {
9405      return value >= other;
9406    }
9407
9408    /**
9409     * Checks if `value` is likely an `arguments` object.
9410     *
9411     * @static
9412     * @memberOf _
9413     * @category Lang
9414     * @param {*} value The value to check.
9415     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9416     * @example
9417     *
9418     * _.isArguments(function() { return arguments; }());
9419     * // => true
9420     *
9421     * _.isArguments([1, 2, 3]);
9422     * // => false
9423     */
9424    function isArguments(value) {
9425      // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
9426      return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
9427        (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
9428    }
9429
9430    /**
9431     * Checks if `value` is classified as an `Array` object.
9432     *
9433     * @static
9434     * @memberOf _
9435     * @type Function
9436     * @category Lang
9437     * @param {*} value The value to check.
9438     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9439     * @example
9440     *
9441     * _.isArray([1, 2, 3]);
9442     * // => true
9443     *
9444     * _.isArray(document.body.children);
9445     * // => false
9446     *
9447     * _.isArray('abc');
9448     * // => false
9449     *
9450     * _.isArray(_.noop);
9451     * // => false
9452     */
9453    var isArray = Array.isArray;
9454
9455    /**
9456     * Checks if `value` is classified as an `ArrayBuffer` object.
9457     *
9458     * @static
9459     * @memberOf _
9460     * @type Function
9461     * @category Lang
9462     * @param {*} value The value to check.
9463     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9464     * @example
9465     *
9466     * _.isArrayBuffer(new ArrayBuffer(2));
9467     * // => true
9468     *
9469     * _.isArrayBuffer(new Array(2));
9470     * // => false
9471     */
9472    function isArrayBuffer(value) {
9473      return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
9474    }
9475
9476    /**
9477     * Checks if `value` is array-like. A value is considered array-like if it's
9478     * not a function and has a `value.length` that's an integer greater than or
9479     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
9480     *
9481     * @static
9482     * @memberOf _
9483     * @type Function
9484     * @category Lang
9485     * @param {*} value The value to check.
9486     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
9487     * @example
9488     *
9489     * _.isArrayLike([1, 2, 3]);
9490     * // => true
9491     *
9492     * _.isArrayLike(document.body.children);
9493     * // => true
9494     *
9495     * _.isArrayLike('abc');
9496     * // => true
9497     *
9498     * _.isArrayLike(_.noop);
9499     * // => false
9500     */
9501    function isArrayLike(value) {
9502      return value != null &&
9503        !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
9504    }
9505
9506    /**
9507     * This method is like `_.isArrayLike` except that it also checks if `value`
9508     * is an object.
9509     *
9510     * @static
9511     * @memberOf _
9512     * @type Function
9513     * @category Lang
9514     * @param {*} value The value to check.
9515     * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
9516     * @example
9517     *
9518     * _.isArrayLikeObject([1, 2, 3]);
9519     * // => true
9520     *
9521     * _.isArrayLikeObject(document.body.children);
9522     * // => true
9523     *
9524     * _.isArrayLikeObject('abc');
9525     * // => false
9526     *
9527     * _.isArrayLikeObject(_.noop);
9528     * // => false
9529     */
9530    function isArrayLikeObject(value) {
9531      return isObjectLike(value) && isArrayLike(value);
9532    }
9533
9534    /**
9535     * Checks if `value` is classified as a boolean primitive or object.
9536     *
9537     * @static
9538     * @memberOf _
9539     * @category Lang
9540     * @param {*} value The value to check.
9541     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9542     * @example
9543     *
9544     * _.isBoolean(false);
9545     * // => true
9546     *
9547     * _.isBoolean(null);
9548     * // => false
9549     */
9550    function isBoolean(value) {
9551      return value === true || value === false ||
9552        (isObjectLike(value) && objectToString.call(value) == boolTag);
9553    }
9554
9555    /**
9556     * Checks if `value` is a buffer.
9557     *
9558     * @static
9559     * @memberOf _
9560     * @category Lang
9561     * @param {*} value The value to check.
9562     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
9563     * @example
9564     *
9565     * _.isBuffer(new Buffer(2));
9566     * // => true
9567     *
9568     * _.isBuffer(new Uint8Array(2));
9569     * // => false
9570     */
9571    var isBuffer = !Buffer ? constant(false) : function(value) {
9572      return value instanceof Buffer;
9573    };
9574
9575    /**
9576     * Checks if `value` is classified as a `Date` object.
9577     *
9578     * @static
9579     * @memberOf _
9580     * @category Lang
9581     * @param {*} value The value to check.
9582     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9583     * @example
9584     *
9585     * _.isDate(new Date);
9586     * // => true
9587     *
9588     * _.isDate('Mon April 23 2012');
9589     * // => false
9590     */
9591    function isDate(value) {
9592      return isObjectLike(value) && objectToString.call(value) == dateTag;
9593    }
9594
9595    /**
9596     * Checks if `value` is likely a DOM element.
9597     *
9598     * @static
9599     * @memberOf _
9600     * @category Lang
9601     * @param {*} value The value to check.
9602     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
9603     * @example
9604     *
9605     * _.isElement(document.body);
9606     * // => true
9607     *
9608     * _.isElement('<body>');
9609     * // => false
9610     */
9611    function isElement(value) {
9612      return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
9613    }
9614
9615    /**
9616     * Checks if `value` is empty. A value is considered empty unless it's an
9617     * `arguments` object, array, string, or jQuery-like collection with a length
9618     * greater than `0` or an object with own enumerable properties.
9619     *
9620     * @static
9621     * @memberOf _
9622     * @category Lang
9623     * @param {Array|Object|string} value The value to inspect.
9624     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
9625     * @example
9626     *
9627     * _.isEmpty(null);
9628     * // => true
9629     *
9630     * _.isEmpty(true);
9631     * // => true
9632     *
9633     * _.isEmpty(1);
9634     * // => true
9635     *
9636     * _.isEmpty([1, 2, 3]);
9637     * // => false
9638     *
9639     * _.isEmpty({ 'a': 1 });
9640     * // => false
9641     */
9642    function isEmpty(value) {
9643      if (isArrayLike(value) &&
9644          (isArray(value) || isString(value) || isFunction(value.splice) || isArguments(value))) {
9645        return !value.length;
9646      }
9647      for (var key in value) {
9648        if (hasOwnProperty.call(value, key)) {
9649          return false;
9650        }
9651      }
9652      return true;
9653    }
9654
9655    /**
9656     * Performs a deep comparison between two values to determine if they are
9657     * equivalent.
9658     *
9659     * **Note:** This method supports comparing arrays, array buffers, booleans,
9660     * date objects, error objects, maps, numbers, `Object` objects, regexes,
9661     * sets, strings, symbols, and typed arrays. `Object` objects are compared
9662     * by their own, not inherited, enumerable properties. Functions and DOM
9663     * nodes are **not** supported.
9664     *
9665     * @static
9666     * @memberOf _
9667     * @category Lang
9668     * @param {*} value The value to compare.
9669     * @param {*} other The other value to compare.
9670     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9671     * @example
9672     *
9673     * var object = { 'user': 'fred' };
9674     * var other = { 'user': 'fred' };
9675     *
9676     * _.isEqual(object, other);
9677     * // => true
9678     *
9679     * object === other;
9680     * // => false
9681     */
9682    function isEqual(value, other) {
9683      return baseIsEqual(value, other);
9684    }
9685
9686    /**
9687     * This method is like `_.isEqual` except that it accepts `customizer` which is
9688     * invoked to compare values. If `customizer` returns `undefined` comparisons are
9689     * handled by the method instead. The `customizer` is invoked with up to six arguments:
9690     * (objValue, othValue [, index|key, object, other, stack]).
9691     *
9692     * @static
9693     * @memberOf _
9694     * @category Lang
9695     * @param {*} value The value to compare.
9696     * @param {*} other The other value to compare.
9697     * @param {Function} [customizer] The function to customize comparisons.
9698     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
9699     * @example
9700     *
9701     * function isGreeting(value) {
9702     *   return /^h(?:i|ello)$/.test(value);
9703     * }
9704     *
9705     * function customizer(objValue, othValue) {
9706     *   if (isGreeting(objValue) && isGreeting(othValue)) {
9707     *     return true;
9708     *   }
9709     * }
9710     *
9711     * var array = ['hello', 'goodbye'];
9712     * var other = ['hi', 'goodbye'];
9713     *
9714     * _.isEqualWith(array, other, customizer);
9715     * // => true
9716     */
9717    function isEqualWith(value, other, customizer) {
9718      customizer = typeof customizer == 'function' ? customizer : undefined;
9719      var result = customizer ? customizer(value, other) : undefined;
9720      return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
9721    }
9722
9723    /**
9724     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
9725     * `SyntaxError`, `TypeError`, or `URIError` object.
9726     *
9727     * @static
9728     * @memberOf _
9729     * @category Lang
9730     * @param {*} value The value to check.
9731     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
9732     * @example
9733     *
9734     * _.isError(new Error);
9735     * // => true
9736     *
9737     * _.isError(Error);
9738     * // => false
9739     */
9740    function isError(value) {
9741      return isObjectLike(value) &&
9742        typeof value.message == 'string' && objectToString.call(value) == errorTag;
9743    }
9744
9745    /**
9746     * Checks if `value` is a finite primitive number.
9747     *
9748     * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
9749     *
9750     * @static
9751     * @memberOf _
9752     * @category Lang
9753     * @param {*} value The value to check.
9754     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
9755     * @example
9756     *
9757     * _.isFinite(3);
9758     * // => true
9759     *
9760     * _.isFinite(Number.MAX_VALUE);
9761     * // => true
9762     *
9763     * _.isFinite(3.14);
9764     * // => true
9765     *
9766     * _.isFinite(Infinity);
9767     * // => false
9768     */
9769    function isFinite(value) {
9770      return typeof value == 'number' && nativeIsFinite(value);
9771    }
9772
9773    /**
9774     * Checks if `value` is classified as a `Function` object.
9775     *
9776     * @static
9777     * @memberOf _
9778     * @category Lang
9779     * @param {*} value The value to check.
9780     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9781     * @example
9782     *
9783     * _.isFunction(_);
9784     * // => true
9785     *
9786     * _.isFunction(/abc/);
9787     * // => false
9788     */
9789    function isFunction(value) {
vendor: 4,853 bytes, lines 9790-9958
9790      // The use of `Object#toString` avoids issues with the `typeof` operator
9791      // in Safari 8 which returns 'object' for typed array constructors, and
9792      // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
9793      var tag = isObject(value) ? objectToString.call(value) : '';
9794      return tag == funcTag || tag == genTag;
9795    }
9796
9797    /**
9798     * Checks if `value` is an integer.
9799     *
9800     * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger).
9801     *
9802     * @static
9803     * @memberOf _
9804     * @category Lang
9805     * @param {*} value The value to check.
9806     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
9807     * @example
9808     *
9809     * _.isInteger(3);
9810     * // => true
9811     *
9812     * _.isInteger(Number.MIN_VALUE);
9813     * // => false
9814     *
9815     * _.isInteger(Infinity);
9816     * // => false
9817     *
9818     * _.isInteger('3');
9819     * // => false
9820     */
9821    function isInteger(value) {
9822      return typeof value == 'number' && value == toInteger(value);
9823    }
9824
9825    /**
9826     * Checks if `value` is a valid array-like length.
9827     *
9828     * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
9829     *
9830     * @static
9831     * @memberOf _
9832     * @category Lang
9833     * @param {*} value The value to check.
9834     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
9835     * @example
9836     *
9837     * _.isLength(3);
9838     * // => true
9839     *
9840     * _.isLength(Number.MIN_VALUE);
9841     * // => false
9842     *
9843     * _.isLength(Infinity);
9844     * // => false
9845     *
9846     * _.isLength('3');
9847     * // => false
9848     */
9849    function isLength(value) {
9850      return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
9851    }
9852
9853    /**
9854     * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
9855     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
9856     *
9857     * @static
9858     * @memberOf _
9859     * @category Lang
9860     * @param {*} value The value to check.
9861     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
9862     * @example
9863     *
9864     * _.isObject({});
9865     * // => true
9866     *
9867     * _.isObject([1, 2, 3]);
9868     * // => true
9869     *
9870     * _.isObject(_.noop);
9871     * // => true
9872     *
9873     * _.isObject(null);
9874     * // => false
9875     */
9876    function isObject(value) {
9877      var type = typeof value;
9878      return !!value && (type == 'object' || type == 'function');
9879    }
9880
9881    /**
9882     * Checks if `value` is object-like. A value is object-like if it's not `null`
9883     * and has a `typeof` result of "object".
9884     *
9885     * @static
9886     * @memberOf _
9887     * @category Lang
9888     * @param {*} value The value to check.
9889     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
9890     * @example
9891     *
9892     * _.isObjectLike({});
9893     * // => true
9894     *
9895     * _.isObjectLike([1, 2, 3]);
9896     * // => true
9897     *
9898     * _.isObjectLike(_.noop);
9899     * // => false
9900     *
9901     * _.isObjectLike(null);
9902     * // => false
9903     */
9904    function isObjectLike(value) {
9905      return !!value && typeof value == 'object';
9906    }
9907
9908    /**
9909     * Checks if `value` is classified as a `Map` object.
9910     *
9911     * @static
9912     * @memberOf _
9913     * @category Lang
9914     * @param {*} value The value to check.
9915     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
9916     * @example
9917     *
9918     * _.isMap(new Map);
9919     * // => true
9920     *
9921     * _.isMap(new WeakMap);
9922     * // => false
9923     */
9924    function isMap(value) {
9925      return isObjectLike(value) && getTag(value) == mapTag;
9926    }
9927
9928    /**
9929     * Performs a deep comparison between `object` and `source` to determine if
9930     * `object` contains equivalent property values.
9931     *
9932     * **Note:** This method supports comparing the same values as `_.isEqual`.
9933     *
9934     * @static
9935     * @memberOf _
9936     * @category Lang
9937     * @param {Object} object The object to inspect.
9938     * @param {Object} source The object of property values to match.
9939     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9940     * @example
9941     *
9942     * var object = { 'user': 'fred', 'age': 40 };
9943     *
9944     * _.isMatch(object, { 'age': 40 });
9945     * // => true
9946     *
9947     * _.isMatch(object, { 'age': 36 });
9948     * // => false
9949     */
9950    function isMatch(object, source) {
9951      return object === source || baseIsMatch(object, source, getMatchData(source));
9952    }
9953
9954    /**
9955     * This method is like `_.isMatch` except that it accepts `customizer` which
9956     * is invoked to compare values. If `customizer` returns `undefined` comparisons
9957     * are handled by the method instead. The `customizer` is invoked with five
9958     * arguments: (objValue, srcValue, index|key, object, source).
9959     *
9960     * @static
9961     * @memberOf _
9962     * @category Lang
9963     * @param {Object} object The object to inspect.
9964     * @param {Object} source The object of property values to match.
9965     * @param {Function} [customizer] The function to customize comparisons.
9966     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
9967     * @example
9968     *
9969     * function isGreeting(value) {
9970     *   return /^h(?:i|ello)$/.test(value);
9971     * }
9972     *
9973     * function customizer(objValue, srcValue) {
9974     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
9975     *     return true;
9976     *   }
9977     * }
9978     *
9979     * var object = { 'greeting': 'hello' };
9980     * var source = { 'greeting': 'hi' };
9981     *
9982     * _.isMatchWith(object, source, customizer);
9983     * // => true
9984     */
9985    function isMatchWith(object, source, customizer) {
9986      customizer = typeof customizer == 'function' ? customizer : undefined;
9987      return baseIsMatch(object, source, getMatchData(source), customizer);
9988    }
9989
9990    /**
9991     * Checks if `value` is `NaN`.
9992     *
9993     * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
9994     * which returns `true` for `undefined` and other non-numeric values.
9995     *
9996     * @static
9997     * @memberOf _
9998     * @category Lang
9999     * @param {*} value The value to check.
10000     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
10001     * @example
10002     *
10003     * _.isNaN(NaN);
10004     * // => true
10005     *
10006     * _.isNaN(new Number(NaN));
10007     * // => true
10008     *
10009     * isNaN(undefined);
10010     * // => true
10011     *
10012     * _.isNaN(undefined);
10013     * // => false
10014     */
10015    function isNaN(value) {
10016      // An `NaN` primitive is the only value that is not equal to itself.
10017      // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
10018      return isNumber(value) && value != +value;
10019    }
10020
10021    /**
10022     * Checks if `value` is a native function.
10023     *
10024     * @static
10025     * @memberOf _
10026     * @category Lang
10027     * @param {*} value The value to check.
10028     * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
10029     * @example
10030     *
10031     * _.isNative(Array.prototype.push);
10032     * // => true
10033     *
10034     * _.isNative(_);
10035     * // => false
10036     */
10037    function isNative(value) {
10038      if (value == null) {
10039        return false;
10040      }
10041      if (isFunction(value)) {
10042        return reIsNative.test(funcToString.call(value));
10043      }
10044      return isObjectLike(value) &&
10045        (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
10046    }
10047
10048    /**
10049     * Checks if `value` is `null`.
10050     *
10051     * @static
10052     * @memberOf _
10053     * @category Lang
10054     * @param {*} value The value to check.
10055     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
10056     * @example
10057     *
10058     * _.isNull(null);
10059     * // => true
10060     *
10061     * _.isNull(void 0);
10062     * // => false
10063     */
10064    function isNull(value) {
10065      return value === null;
10066    }
10067
10068    /**
10069     * Checks if `value` is `null` or `undefined`.
10070     *
10071     * @static
10072     * @memberOf _
10073     * @category Lang
10074     * @param {*} value The value to check.
10075     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
10076     * @example
10077     *
10078     * _.isNil(null);
10079     * // => true
10080     *
10081     * _.isNil(void 0);
10082     * // => true
10083     *
10084     * _.isNil(NaN);
10085     * // => false
10086     */
10087    function isNil(value) {
10088      return value == null;
10089    }
10090
10091    /**
10092     * Checks if `value` is classified as a `Number` primitive or object.
10093     *
10094     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
10095     * as numbers, use the `_.isFinite` method.
10096     *
10097     * @static
10098     * @memberOf _
10099     * @category Lang
10100     * @param {*} value The value to check.
10101     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10102     * @example
10103     *
10104     * _.isNumber(3);
10105     * // => true
10106     *
10107     * _.isNumber(Number.MIN_VALUE);
10108     * // => true
10109     *
10110     * _.isNumber(Infinity);
10111     * // => true
10112     *
10113     * _.isNumber('3');
10114     * // => false
10115     */
10116    function isNumber(value) {
10117      return typeof value == 'number' ||
10118        (isObjectLike(value) && objectToString.call(value) == numberTag);
10119    }
10120
10121    /**
10122     * Checks if `value` is a plain object, that is, an object created by the
10123     * `Object` constructor or one with a `[[Prototype]]` of `null`.
10124     *
10125     * @static
10126     * @memberOf _
10127     * @category Lang
10128     * @param {*} value The value to check.
10129     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
10130     * @example
10131     *
10132     * function Foo() {
10133     *   this.a = 1;
10134     * }
10135     *
10136     * _.isPlainObject(new Foo);
10137     * // => false
10138     *
10139     * _.isPlainObject([1, 2, 3]);
10140     * // => false
10141     *
10142     * _.isPlainObject({ 'x': 0, 'y': 0 });
10143     * // => true
10144     *
10145     * _.isPlainObject(Object.create(null));
10146     * // => true
10147     */
10148    function isPlainObject(value) {
10149      if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
10150        return false;
10151      }
10152      var proto = objectProto;
10153      if (typeof value.constructor == 'function') {
10154        proto = getPrototypeOf(value);
10155      }
10156      if (proto === null) {
10157        return true;
10158      }
10159      var Ctor = proto.constructor;
10160      return (typeof Ctor == 'function' &&
10161        Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
10162    }
10163
10164    /**
10165     * Checks if `value` is classified as a `RegExp` object.
10166     *
10167     * @static
10168     * @memberOf _
10169     * @category Lang
10170     * @param {*} value The value to check.
10171     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10172     * @example
10173     *
10174     * _.isRegExp(/abc/);
10175     * // => true
10176     *
10177     * _.isRegExp('/abc/');
10178     * // => false
10179     */
10180    function isRegExp(value) {
10181      return isObject(value) && objectToString.call(value) == regexpTag;
10182    }
10183
10184    /**
10185     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
10186     * double precision number which isn't the result of a rounded unsafe integer.
10187     *
10188     * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
10189     *
10190     * @static
10191     * @memberOf _
10192     * @category Lang
10193     * @param {*} value The value to check.
10194     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
10195     * @example
10196     *
10197     * _.isSafeInteger(3);
10198     * // => true
10199     *
10200     * _.isSafeInteger(Number.MIN_VALUE);
10201     * // => false
10202     *
10203     * _.isSafeInteger(Infinity);
10204     * // => false
10205     *
10206     * _.isSafeInteger('3');
10207     * // => false
10208     */
10209    function isSafeInteger(value) {
10210      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
10211    }
10212
10213    /**
10214     * Checks if `value` is classified as a `Set` object.
10215     *
10216     * @static
10217     * @memberOf _
10218     * @category Lang
10219     * @param {*} value The value to check.
10220     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10221     * @example
10222     *
10223     * _.isSet(new Set);
10224     * // => true
10225     *
10226     * _.isSet(new WeakSet);
10227     * // => false
10228     */
10229    function isSet(value) {
10230      return isObjectLike(value) && getTag(value) == setTag;
10231    }
10232
10233    /**
10234     * Checks if `value` is classified as a `String` primitive or object.
10235     *
10236     * @static
10237     * @memberOf _
10238     * @category Lang
10239     * @param {*} value The value to check.
10240     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10241     * @example
10242     *
10243     * _.isString('abc');
10244     * // => true
10245     *
10246     * _.isString(1);
10247     * // => false
10248     */
10249    function isString(value) {
10250      return typeof value == 'string' ||
10251        (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
10252    }
10253
10254    /**
10255     * Checks if `value` is classified as a `Symbol` primitive or object.
10256     *
10257     * @static
10258     * @memberOf _
10259     * @category Lang
10260     * @param {*} value The value to check.
10261     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10262     * @example
10263     *
10264     * _.isSymbol(Symbol.iterator);
10265     * // => true
10266     *
10267     * _.isSymbol('abc');
10268     * // => false
10269     */
10270    function isSymbol(value) {
10271      return typeof value == 'symbol' ||
10272        (isObjectLike(value) && objectToString.call(value) == symbolTag);
10273    }
10274
10275    /**
10276     * Checks if `value` is classified as a typed array.
10277     *
10278     * @static
10279     * @memberOf _
10280     * @category Lang
10281     * @param {*} value The value to check.
10282     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10283     * @example
10284     *
10285     * _.isTypedArray(new Uint8Array);
10286     * // => true
10287     *
10288     * _.isTypedArray([]);
10289     * // => false
10290     */
10291    function isTypedArray(value) {
10292      return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
10293    }
10294
10295    /**
10296     * Checks if `value` is `undefined`.
10297     *
10298     * @static
10299     * @memberOf _
10300     * @category Lang
10301     * @param {*} value The value to check.
10302     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
10303     * @example
10304     *
10305     * _.isUndefined(void 0);
10306     * // => true
10307     *
10308     * _.isUndefined(null);
10309     * // => false
10310     */
10311    function isUndefined(value) {
10312      return value === undefined;
10313    }
10314
10315    /**
10316     * Checks if `value` is classified as a `WeakMap` object.
10317     *
10318     * @static
10319     * @memberOf _
10320     * @category Lang
10321     * @param {*} value The value to check.
10322     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10323     * @example
10324     *
10325     * _.isWeakMap(new WeakMap);
10326     * // => true
10327     *
10328     * _.isWeakMap(new Map);
10329     * // => false
10330     */
10331    function isWeakMap(value) {
10332      return isObjectLike(value) && getTag(value) == weakMapTag;
10333    }
10334
10335    /**
10336     * Checks if `value` is classified as a `WeakSet` object.
10337     *
10338     * @static
10339     * @memberOf _
10340     * @category Lang
10341     * @param {*} value The value to check.
10342     * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
10343     * @example
10344     *
10345     * _.isWeakSet(new WeakSet);
10346     * // => true
10347     *
10348     * _.isWeakSet(new Set);
10349     * // => false
10350     */
10351    function isWeakSet(value) {
10352      return isObjectLike(value) && objectToString.call(value) == weakSetTag;
10353    }
10354
10355    /**
10356     * Checks if `value` is less than `other`.
10357     *
10358     * @static
10359     * @memberOf _
10360     * @category Lang
10361     * @param {*} value The value to compare.
10362     * @param {*} other The other value to compare.
10363     * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
10364     * @example
10365     *
10366     * _.lt(1, 3);
10367     * // => true
10368     *
10369     * _.lt(3, 3);
10370     * // => false
10371     *
10372     * _.lt(3, 1);
10373     * // => false
10374     */
10375    function lt(value, other) {
10376      return value < other;
10377    }
10378
10379    /**
10380     * Checks if `value` is less than or equal to `other`.
10381     *
10382     * @static
10383     * @memberOf _
10384     * @category Lang
10385     * @param {*} value The value to compare.
10386     * @param {*} other The other value to compare.
10387     * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
10388     * @example
10389     *
10390     * _.lte(1, 3);
10391     * // => true
10392     *
10393     * _.lte(3, 3);
10394     * // => true
10395     *
10396     * _.lte(3, 1);
10397     * // => false
10398     */
10399    function lte(value, other) {
10400      return value <= other;
10401    }
10402
10403    /**
10404     * Converts `value` to an array.
10405     *
10406     * @static
10407     * @memberOf _
10408     * @category Lang
10409     * @param {*} value The value to convert.
10410     * @returns {Array} Returns the converted array.
10411     * @example
10412     *
10413     * _.toArray({ 'a': 1, 'b': 2 });
10414     * // => [1, 2]
10415     *
10416     * _.toArray('abc');
10417     * // => ['a', 'b', 'c']
10418     *
10419     * _.toArray(1);
10420     * // => []
10421     *
10422     * _.toArray(null);
10423     * // => []
10424     */
10425    function toArray(value) {
10426      if (!value) {
10427        return [];
10428      }
10429      if (isArrayLike(value)) {
10430        return isString(value) ? stringToArray(value) : copyArray(value);
10431      }
10432      if (iteratorSymbol && value[iteratorSymbol]) {
10433        return iteratorToArray(value[iteratorSymbol]());
10434      }
10435      var tag = getTag(value),
10436          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
10437
10438      return func(value);
10439    }
10440
10441    /**
10442     * Converts `value` to an integer.
10443     *
10444     * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
10445     *
10446     * @static
10447     * @memberOf _
10448     * @category Lang
10449     * @param {*} value The value to convert.
10450     * @returns {number} Returns the converted integer.
10451     * @example
10452     *
10453     * _.toInteger(3);
10454     * // => 3
10455     *
10456     * _.toInteger(Number.MIN_VALUE);
10457     * // => 0
10458     *
10459     * _.toInteger(Infinity);
10460     * // => 1.7976931348623157e+308
10461     *
10462     * _.toInteger('3');
10463     * // => 3
10464     */
10465    function toInteger(value) {
10466      if (!value) {
10467        return value === 0 ? value : 0;
10468      }
10469      value = toNumber(value);
10470      if (value === INFINITY || value === -INFINITY) {
10471        var sign = (value < 0 ? -1 : 1);
10472        return sign * MAX_INTEGER;
10473      }
10474      var remainder = value % 1;
10475      return value === value ? (remainder ? value - remainder : value) : 0;
10476    }
10477
10478    /**
10479     * Converts `value` to an integer suitable for use as the length of an
10480     * array-like object.
10481     *
10482     * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
10483     *
10484     * @static
10485     * @memberOf _
10486     * @category Lang
10487     * @param {*} value The value to convert.
10488     * @returns {number} Returns the converted integer.
10489     * @example
10490     *
10491     * _.toLength(3);
10492     * // => 3
10493     *
10494     * _.toLength(Number.MIN_VALUE);
10495     * // => 0
10496     *
10497     * _.toLength(Infinity);
10498     * // => 4294967295
10499     *
10500     * _.toLength('3');
10501     * // => 3
10502     */
10503    function toLength(value) {
10504      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
10505    }
10506
10507    /**
10508     * Converts `value` to a number.
10509     *
10510     * @static
10511     * @memberOf _
10512     * @category Lang
10513     * @param {*} value The value to process.
10514     * @returns {number} Returns the number.
10515     * @example
10516     *
10517     * _.toNumber(3);
10518     * // => 3
10519     *
10520     * _.toNumber(Number.MIN_VALUE);
10521     * // => 5e-324
10522     *
10523     * _.toNumber(Infinity);
10524     * // => Infinity
10525     *
10526     * _.toNumber('3');
10527     * // => 3
10528     */
10529    function toNumber(value) {
10530      if (isObject(value)) {
10531        var other = isFunction(value.valueOf) ? value.valueOf() : value;
10532        value = isObject(other) ? (other + '') : other;
10533      }
10534      if (typeof value != 'string') {
10535        return value === 0 ? value : +value;
10536      }
10537      value = value.replace(reTrim, '');
10538      var isBinary = reIsBinary.test(value);
10539      return (isBinary || reIsOctal.test(value))
10540        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
10541        : (reIsBadHex.test(value) ? NAN : +value);
10542    }
10543
10544    /**
10545     * Converts `value` to a plain object flattening inherited enumerable
10546     * properties of `value` to own properties of the plain object.
10547     *
10548     * @static
10549     * @memberOf _
10550     * @category Lang
10551     * @param {*} value The value to convert.
10552     * @returns {Object} Returns the converted plain object.
10553     * @example
10554     *
10555     * function Foo() {
10556     *   this.b = 2;
10557     * }
10558     *
10559     * Foo.prototype.c = 3;
10560     *
10561     * _.assign({ 'a': 1 }, new Foo);
10562     * // => { 'a': 1, 'b': 2 }
10563     *
10564     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
10565     * // => { 'a': 1, 'b': 2, 'c': 3 }
10566     */
10567    function toPlainObject(value) {
10568      return copyObject(value, keysIn(value));
10569    }
10570
10571    /**
10572     * Converts `value` to a safe integer. A safe integer can be compared and
10573     * represented correctly.
10574     *
10575     * @static
10576     * @memberOf _
10577     * @category Lang
10578     * @param {*} value The value to convert.
10579     * @returns {number} Returns the converted integer.
10580     * @example
10581     *
10582     * _.toSafeInteger(3);
10583     * // => 3
10584     *
10585     * _.toSafeInteger(Number.MIN_VALUE);
10586     * // => 0
10587     *
10588     * _.toSafeInteger(Infinity);
10589     * // => 9007199254740991
10590     *
10591     * _.toSafeInteger('3');
10592     * // => 3
10593     */
10594    function toSafeInteger(value) {
10595      return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
10596    }
10597
10598    /**
10599     * Converts `value` to a string if it's not one. An empty string is returned
10600     * for `null` and `undefined` values. The sign of `-0` is preserved.
10601     *
10602     * @static
10603     * @memberOf _
10604     * @category Lang
10605     * @param {*} value The value to process.
10606     * @returns {string} Returns the string.
10607     * @example
10608     *
10609     * _.toString(null);
10610     * // => ''
10611     *
10612     * _.toString(-0);
10613     * // => '-0'
10614     *
10615     * _.toString([1, 2, 3]);
10616     * // => '1,2,3'
10617     */
10618    function toString(value) {
10619      // Exit early for strings to avoid a performance hit in some environments.
10620      if (typeof value == 'string') {
10621        return value;
10622      }
10623      if (value == null) {
10624        return '';
10625      }
10626      if (isSymbol(value)) {
10627        return Symbol ? symbolToString.call(value) : '';
10628      }
10629      var result = (value + '');
10630      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
10631    }
10632
10633    /*------------------------------------------------------------------------*/
10634
10635    /**
10636     * Assigns own enumerable properties of source objects to the destination
10637     * object. Source objects are applied from left to right. Subsequent sources
10638     * overwrite property assignments of previous sources.
10639     *
10640     * **Note:** This method mutates `object` and is loosely based on
10641     * [`Object.assign`](https://mdn.io/Object/assign).
10642     *
10643     * @static
10644     * @memberOf _
10645     * @category Object
10646     * @param {Object} object The destination object.
10647     * @param {...Object} [sources] The source objects.
10648     * @returns {Object} Returns `object`.
10649     * @example
10650     *
10651     * function Foo() {
10652     *   this.c = 3;
10653     * }
10654     *
10655     * function Bar() {
10656     *   this.e = 5;
10657     * }
10658     *
10659     * Foo.prototype.d = 4;
10660     * Bar.prototype.f = 6;
10661     *
10662     * _.assign({ 'a': 1 }, new Foo, new Bar);
10663     * // => { 'a': 1, 'c': 3, 'e': 5 }
10664     */
10665    var assign = createAssigner(function(object, source) {
10666      copyObject(source, keys(source), object);
10667    });
10668
10669    /**
10670     * This method is like `_.assign` except that it iterates over own and
10671     * inherited source properties.
10672     *
10673     * **Note:** This method mutates `object`.
10674     *
10675     * @static
10676     * @memberOf _
10677     * @alias extend
10678     * @category Object
10679     * @param {Object} object The destination object.
10680     * @param {...Object} [sources] The source objects.
10681     * @returns {Object} Returns `object`.
10682     * @example
10683     *
10684     * function Foo() {
10685     *   this.b = 2;
10686     * }
10687     *
10688     * function Bar() {
10689     *   this.d = 4;
10690     * }
10691     *
10692     * Foo.prototype.c = 3;
10693     * Bar.prototype.e = 5;
10694     *
10695     * _.assignIn({ 'a': 1 }, new Foo, new Bar);
10696     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
10697     */
10698    var assignIn = createAssigner(function(object, source) {
10699      copyObject(source, keysIn(source), object);
10700    });
10701
10702    /**
10703     * This method is like `_.assignIn` except that it accepts `customizer` which
10704     * is invoked to produce the assigned values. If `customizer` returns `undefined`
10705     * assignment is handled by the method instead. The `customizer` is invoked
10706     * with five arguments: (objValue, srcValue, key, object, source).
10707     *
10708     * **Note:** This method mutates `object`.
10709     *
10710     * @static
10711     * @memberOf _
10712     * @alias extendWith
10713     * @category Object
10714     * @param {Object} object The destination object.
10715     * @param {...Object} sources The source objects.
10716     * @param {Function} [customizer] The function to customize assigned values.
10717     * @returns {Object} Returns `object`.
10718     * @example
10719     *
10720     * function customizer(objValue, srcValue) {
10721     *   return _.isUndefined(objValue) ? srcValue : objValue;
10722     * }
10723     *
10724     * var defaults = _.partialRight(_.assignInWith, customizer);
10725     *
10726     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10727     * // => { 'a': 1, 'b': 2 }
10728     */
10729    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
10730      copyObjectWith(source, keysIn(source), object, customizer);
10731    });
10732
10733    /**
10734     * This method is like `_.assign` except that it accepts `customizer` which
10735     * is invoked to produce the assigned values. If `customizer` returns `undefined`
10736     * assignment is handled by the method instead. The `customizer` is invoked
10737     * with five arguments: (objValue, srcValue, key, object, source).
10738     *
10739     * **Note:** This method mutates `object`.
10740     *
10741     * @static
10742     * @memberOf _
10743     * @category Object
10744     * @param {Object} object The destination object.
10745     * @param {...Object} sources The source objects.
10746     * @param {Function} [customizer] The function to customize assigned values.
10747     * @returns {Object} Returns `object`.
10748     * @example
10749     *
10750     * function customizer(objValue, srcValue) {
10751     *   return _.isUndefined(objValue) ? srcValue : objValue;
10752     * }
10753     *
10754     * var defaults = _.partialRight(_.assignWith, customizer);
10755     *
10756     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
10757     * // => { 'a': 1, 'b': 2 }
10758     */
10759    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
10760      copyObjectWith(source, keys(source), object, customizer);
10761    });
10762
10763    /**
10764     * Creates an array of values corresponding to `paths` of `object`.
10765     *
10766     * @static
10767     * @memberOf _
10768     * @category Object
10769     * @param {Object} object The object to iterate over.
10770     * @param {...(string|string[])} [paths] The property paths of elements to pick,
10771     *  specified individually or in arrays.
10772     * @returns {Array} Returns the new array of picked elements.
10773     * @example
10774     *
10775     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
10776     *
10777     * _.at(object, ['a[0].b.c', 'a[1]']);
10778     * // => [3, 4]
10779     *
10780     * _.at(['a', 'b', 'c'], 0, 2);
10781     * // => ['a', 'c']
10782     */
10783    var at = rest(function(object, paths) {
10784      return baseAt(object, baseFlatten(paths));
10785    });
10786
10787    /**
10788     * Creates an object that inherits from the `prototype` object. If a `properties`
10789     * object is given its own enumerable properties are assigned to the created object.
10790     *
10791     * @static
10792     * @memberOf _
10793     * @category Object
10794     * @param {Object} prototype The object to inherit from.
10795     * @param {Object} [properties] The properties to assign to the object.
10796     * @returns {Object} Returns the new object.
10797     * @example
10798     *
10799     * function Shape() {
10800     *   this.x = 0;
10801     *   this.y = 0;
10802     * }
10803     *
10804     * function Circle() {
10805     *   Shape.call(this);
10806     * }
10807     *
10808     * Circle.prototype = _.create(Shape.prototype, {
10809     *   'constructor': Circle
10810     * });
10811     *
10812     * var circle = new Circle;
10813     * circle instanceof Circle;
10814     * // => true
10815     *
10816     * circle instanceof Shape;
10817     * // => true
10818     */
10819    function create(prototype, properties) {
10820      var result = baseCreate(prototype);
10821      return properties ? baseAssign(result, properties) : result;
10822    }
10823
10824    /**
10825     * Assigns own and inherited enumerable properties of source objects to the
10826     * destination object for all destination properties that resolve to `undefined`.
10827     * Source objects are applied from left to right. Once a property is set,
10828     * additional values of the same property are ignored.
10829     *
10830     * **Note:** This method mutates `object`.
10831     *
10832     * @static
10833     * @memberOf _
10834     * @category Object
10835     * @param {Object} object The destination object.
10836     * @param {...Object} [sources] The source objects.
10837     * @returns {Object} Returns `object`.
10838     * @example
10839     *
10840     * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
10841     * // => { 'user': 'barney', 'age': 36 }
10842     */
10843    var defaults = rest(function(args) {
10844      args.push(undefined, assignInDefaults);
10845      return apply(assignInWith, undefined, args);
10846    });
10847
10848    /**
10849     * This method is like `_.defaults` except that it recursively assigns
10850     * default properties.
10851     *
10852     * **Note:** This method mutates `object`.
10853     *
10854     * @static
10855     * @memberOf _
10856     * @category Object
10857     * @param {Object} object The destination object.
10858     * @param {...Object} [sources] The source objects.
10859     * @returns {Object} Returns `object`.
10860     * @example
10861     *
10862     * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
10863     * // => { 'user': { 'name': 'barney', 'age': 36 } }
10864     *
10865     */
10866    var defaultsDeep = rest(function(args) {
10867      args.push(undefined, mergeDefaults);
10868      return apply(mergeWith, undefined, args);
10869    });
10870
10871    /**
10872     * This method is like `_.find` except that it returns the key of the first
10873     * element `predicate` returns truthy for instead of the element itself.
10874     *
10875     * @static
10876     * @memberOf _
10877     * @category Object
10878     * @param {Object} object The object to search.
10879     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10880     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10881     * @example
10882     *
10883     * var users = {
10884     *   'barney':  { 'age': 36, 'active': true },
10885     *   'fred':    { 'age': 40, 'active': false },
10886     *   'pebbles': { 'age': 1,  'active': true }
10887     * };
10888     *
10889     * _.findKey(users, function(o) { return o.age < 40; });
10890     * // => 'barney' (iteration order is not guaranteed)
10891     *
10892     * // The `_.matches` iteratee shorthand.
10893     * _.findKey(users, { 'age': 1, 'active': true });
10894     * // => 'pebbles'
10895     *
10896     * // The `_.matchesProperty` iteratee shorthand.
10897     * _.findKey(users, ['active', false]);
10898     * // => 'fred'
10899     *
10900     * // The `_.property` iteratee shorthand.
10901     * _.findKey(users, 'active');
10902     * // => 'barney'
10903     */
10904    function findKey(object, predicate) {
10905      return baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
10906    }
10907
10908    /**
10909     * This method is like `_.findKey` except that it iterates over elements of
10910     * a collection in the opposite order.
10911     *
10912     * @static
10913     * @memberOf _
10914     * @category Object
10915     * @param {Object} object The object to search.
10916     * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
10917     * @returns {string|undefined} Returns the key of the matched element, else `undefined`.
10918     * @example
10919     *
10920     * var users = {
10921     *   'barney':  { 'age': 36, 'active': true },
10922     *   'fred':    { 'age': 40, 'active': false },
10923     *   'pebbles': { 'age': 1,  'active': true }
10924     * };
10925     *
10926     * _.findLastKey(users, function(o) { return o.age < 40; });
10927     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
10928     *
10929     * // The `_.matches` iteratee shorthand.
10930     * _.findLastKey(users, { 'age': 36, 'active': true });
10931     * // => 'barney'
10932     *
10933     * // The `_.matchesProperty` iteratee shorthand.
10934     * _.findLastKey(users, ['active', false]);
10935     * // => 'fred'
10936     *
10937     * // The `_.property` iteratee shorthand.
10938     * _.findLastKey(users, 'active');
10939     * // => 'pebbles'
10940     */
10941    function findLastKey(object, predicate) {
10942      return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
10943    }
10944
10945    /**
10946     * Iterates over own and inherited enumerable properties of an object invoking
10947     * `iteratee` for each property. The iteratee is invoked with three arguments:
10948     * (value, key, object). Iteratee functions may exit iteration early by explicitly
10949     * returning `false`.
10950     *
10951     * @static
10952     * @memberOf _
10953     * @category Object
10954     * @param {Object} object The object to iterate over.
10955     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10956     * @returns {Object} Returns `object`.
10957     * @example
10958     *
10959     * function Foo() {
10960     *   this.a = 1;
10961     *   this.b = 2;
10962     * }
10963     *
10964     * Foo.prototype.c = 3;
10965     *
10966     * _.forIn(new Foo, function(value, key) {
10967     *   console.log(key);
10968     * });
10969     * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed)
10970     */
10971    function forIn(object, iteratee) {
10972      return object == null ? object : baseFor(object, toFunction(iteratee), keysIn);
10973    }
10974
10975    /**
10976     * This method is like `_.forIn` except that it iterates over properties of
10977     * `object` in the opposite order.
10978     *
10979     * @static
10980     * @memberOf _
10981     * @category Object
10982     * @param {Object} object The object to iterate over.
10983     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10984     * @returns {Object} Returns `object`.
10985     * @example
10986     *
10987     * function Foo() {
10988     *   this.a = 1;
10989     *   this.b = 2;
10990     * }
10991     *
10992     * Foo.prototype.c = 3;
10993     *
10994     * _.forInRight(new Foo, function(value, key) {
10995     *   console.log(key);
10996     * });
10997     * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'
10998     */
10999    function forInRight(object, iteratee) {
11000      return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn);
11001    }
11002
11003    /**
11004     * Iterates over own enumerable properties of an object invoking `iteratee`
11005     * for each property. The iteratee is invoked with three arguments:
11006     * (value, key, object). Iteratee functions may exit iteration early by
11007     * explicitly returning `false`.
11008     *
11009     * @static
11010     * @memberOf _
11011     * @category Object
11012     * @param {Object} object The object to iterate over.
11013     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11014     * @returns {Object} Returns `object`.
11015     * @example
11016     *
11017     * function Foo() {
11018     *   this.a = 1;
11019     *   this.b = 2;
11020     * }
11021     *
11022     * Foo.prototype.c = 3;
11023     *
11024     * _.forOwn(new Foo, function(value, key) {
11025     *   console.log(key);
11026     * });
11027     * // => logs 'a' then 'b' (iteration order is not guaranteed)
11028     */
11029    function forOwn(object, iteratee) {
11030      return object && baseForOwn(object, toFunction(iteratee));
11031    }
11032
11033    /**
11034     * This method is like `_.forOwn` except that it iterates over properties of
11035     * `object` in the opposite order.
11036     *
11037     * @static
11038     * @memberOf _
11039     * @category Object
11040     * @param {Object} object The object to iterate over.
11041     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11042     * @returns {Object} Returns `object`.
11043     * @example
11044     *
11045     * function Foo() {
11046     *   this.a = 1;
11047     *   this.b = 2;
11048     * }
11049     *
11050     * Foo.prototype.c = 3;
11051     *
11052     * _.forOwnRight(new Foo, function(value, key) {
11053     *   console.log(key);
11054     * });
11055     * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'
11056     */
11057    function forOwnRight(object, iteratee) {
11058      return object && baseForOwnRight(object, toFunction(iteratee));
11059    }
11060
11061    /**
11062     * Creates an array of function property names from own enumerable properties
11063     * of `object`.
11064     *
11065     * @static
11066     * @memberOf _
11067     * @category Object
11068     * @param {Object} object The object to inspect.
11069     * @returns {Array} Returns the new array of property names.
11070     * @example
11071     *
11072     * function Foo() {
11073     *   this.a = _.constant('a');
11074     *   this.b = _.constant('b');
11075     * }
11076     *
11077     * Foo.prototype.c = _.constant('c');
11078     *
11079     * _.functions(new Foo);
11080     * // => ['a', 'b']
11081     */
11082    function functions(object) {
11083      return object == null ? [] : baseFunctions(object, keys(object));
11084    }
11085
11086    /**
11087     * Creates an array of function property names from own and inherited
11088     * enumerable properties of `object`.
11089     *
11090     * @static
11091     * @memberOf _
11092     * @category Object
11093     * @param {Object} object The object to inspect.
11094     * @returns {Array} Returns the new array of property names.
11095     * @example
11096     *
11097     * function Foo() {
11098     *   this.a = _.constant('a');
11099     *   this.b = _.constant('b');
11100     * }
11101     *
11102     * Foo.prototype.c = _.constant('c');
11103     *
11104     * _.functionsIn(new Foo);
11105     * // => ['a', 'b', 'c']
11106     */
11107    function functionsIn(object) {
11108      return object == null ? [] : baseFunctions(object, keysIn(object));
11109    }
11110
11111    /**
11112     * Gets the value at `path` of `object`. If the resolved value is
11113     * `undefined` the `defaultValue` is used in its place.
11114     *
11115     * @static
11116     * @memberOf _
11117     * @category Object
11118     * @param {Object} object The object to query.
11119     * @param {Array|string} path The path of the property to get.
11120     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11121     * @returns {*} Returns the resolved value.
11122     * @example
11123     *
11124     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11125     *
11126     * _.get(object, 'a[0].b.c');
11127     * // => 3
11128     *
11129     * _.get(object, ['a', '0', 'b', 'c']);
11130     * // => 3
11131     *
11132     * _.get(object, 'a.b.c', 'default');
11133     * // => 'default'
11134     */
11135    function get(object, path, defaultValue) {
11136      var result = object == null ? undefined : baseGet(object, path);
11137      return result === undefined ? defaultValue : result;
11138    }
11139
11140    /**
11141     * Checks if `path` is a direct property of `object`.
11142     *
11143     * @static
11144     * @memberOf _
11145     * @category Object
11146     * @param {Object} object The object to query.
11147     * @param {Array|string} path The path to check.
11148     * @returns {boolean} Returns `true` if `path` exists, else `false`.
11149     * @example
11150     *
11151     * var object = { 'a': { 'b': { 'c': 3 } } };
11152     * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11153     *
11154     * _.has(object, 'a');
11155     * // => true
11156     *
11157     * _.has(object, 'a.b.c');
11158     * // => true
11159     *
11160     * _.has(object, ['a', 'b', 'c']);
11161     * // => true
11162     *
11163     * _.has(other, 'a');
11164     * // => false
11165     */
11166    function has(object, path) {
11167      return hasPath(object, path, baseHas);
11168    }
11169
11170    /**
11171     * Checks if `path` is a direct or inherited property of `object`.
11172     *
11173     * @static
11174     * @memberOf _
11175     * @category Object
11176     * @param {Object} object The object to query.
11177     * @param {Array|string} path The path to check.
11178     * @returns {boolean} Returns `true` if `path` exists, else `false`.
11179     * @example
11180     *
11181     * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
11182     *
11183     * _.hasIn(object, 'a');
11184     * // => true
11185     *
11186     * _.hasIn(object, 'a.b.c');
11187     * // => true
11188     *
11189     * _.hasIn(object, ['a', 'b', 'c']);
11190     * // => true
11191     *
11192     * _.hasIn(object, 'b');
11193     * // => false
11194     */
11195    function hasIn(object, path) {
11196      return hasPath(object, path, baseHasIn);
11197    }
11198
11199    /**
11200     * Creates an object composed of the inverted keys and values of `object`.
11201     * If `object` contains duplicate values, subsequent values overwrite property
11202     * assignments of previous values.
11203     *
11204     * @static
11205     * @memberOf _
11206     * @category Object
11207     * @param {Object} object The object to invert.
11208     * @returns {Object} Returns the new inverted object.
11209     * @example
11210     *
11211     * var object = { 'a': 1, 'b': 2, 'c': 1 };
11212     *
11213     * _.invert(object);
11214     * // => { '1': 'c', '2': 'b' }
11215     */
11216    var invert = createInverter(function(result, value, key) {
11217      result[value] = key;
11218    }, constant(identity));
11219
11220    /**
11221     * This method is like `_.invert` except that the inverted object is generated
11222     * from the results of running each element of `object` through `iteratee`.
11223     * The corresponding inverted value of each inverted key is an array of keys
11224     * responsible for generating the inverted value. The iteratee is invoked
11225     * with one argument: (value).
11226     *
11227     * @static
11228     * @memberOf _
11229     * @category Object
11230     * @param {Object} object The object to invert.
11231     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
11232     * @returns {Object} Returns the new inverted object.
11233     * @example
11234     *
11235     * var object = { 'a': 1, 'b': 2, 'c': 1 };
11236     *
11237     * _.invertBy(object);
11238     * // => { '1': ['a', 'c'], '2': ['b'] }
11239     *
11240     * _.invertBy(object, function(value) {
11241     *   return 'group' + value;
11242     * });
11243     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
11244     */
11245    var invertBy = createInverter(function(result, value, key) {
11246      if (hasOwnProperty.call(result, value)) {
11247        result[value].push(key);
11248      } else {
11249        result[value] = [key];
11250      }
11251    }, getIteratee);
11252
11253    /**
11254     * Invokes the method at `path` of `object`.
11255     *
11256     * @static
11257     * @memberOf _
11258     * @category Object
11259     * @param {Object} object The object to query.
11260     * @param {Array|string} path The path of the method to invoke.
11261     * @param {...*} [args] The arguments to invoke the method with.
11262     * @returns {*} Returns the result of the invoked method.
11263     * @example
11264     *
11265     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
11266     *
11267     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
11268     * // => [2, 3]
11269     */
11270    var invoke = rest(baseInvoke);
11271
11272    /**
11273     * Creates an array of the own enumerable property names of `object`.
11274     *
11275     * **Note:** Non-object values are coerced to objects. See the
11276     * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
11277     * for more details.
11278     *
11279     * @static
11280     * @memberOf _
11281     * @category Object
11282     * @param {Object} object The object to query.
11283     * @returns {Array} Returns the array of property names.
11284     * @example
11285     *
11286     * function Foo() {
11287     *   this.a = 1;
11288     *   this.b = 2;
11289     * }
11290     *
11291     * Foo.prototype.c = 3;
11292     *
11293     * _.keys(new Foo);
11294     * // => ['a', 'b'] (iteration order is not guaranteed)
11295     *
11296     * _.keys('hi');
11297     * // => ['0', '1']
11298     */
11299    function keys(object) {
11300      var isProto = isPrototype(object);
11301      if (!(isProto || isArrayLike(object))) {
11302        return baseKeys(object);
11303      }
11304      var indexes = indexKeys(object),
11305          skipIndexes = !!indexes,
11306          result = indexes || [],
11307          length = result.length;
11308
11309      for (var key in object) {
11310        if (baseHas(object, key) &&
11311            !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11312            !(isProto && key == 'constructor')) {
11313          result.push(key);
11314        }
11315      }
11316      return result;
11317    }
11318
11319    /**
11320     * Creates an array of the own and inherited enumerable property names of `object`.
11321     *
11322     * **Note:** Non-object values are coerced to objects.
11323     *
11324     * @static
11325     * @memberOf _
11326     * @category Object
11327     * @param {Object} object The object to query.
11328     * @returns {Array} Returns the array of property names.
11329     * @example
11330     *
11331     * function Foo() {
11332     *   this.a = 1;
11333     *   this.b = 2;
11334     * }
11335     *
11336     * Foo.prototype.c = 3;
11337     *
11338     * _.keysIn(new Foo);
11339     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
11340     */
11341    function keysIn(object) {
11342      var index = -1,
11343          isProto = isPrototype(object),
11344          props = baseKeysIn(object),
11345          propsLength = props.length,
11346          indexes = indexKeys(object),
11347          skipIndexes = !!indexes,
11348          result = indexes || [],
11349          length = result.length;
11350
11351      while (++index < propsLength) {
11352        var key = props[index];
11353        if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
11354            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
11355          result.push(key);
11356        }
11357      }
11358      return result;
11359    }
11360
11361    /**
11362     * The opposite of `_.mapValues`; this method creates an object with the
11363     * same values as `object` and keys generated by running each own enumerable
11364     * property of `object` through `iteratee`.
11365     *
11366     * @static
11367     * @memberOf _
11368     * @category Object
11369     * @param {Object} object The object to iterate over.
11370     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11371     * @returns {Object} Returns the new mapped object.
11372     * @example
11373     *
11374     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
11375     *   return key + value;
11376     * });
11377     * // => { 'a1': 1, 'b2': 2 }
11378     */
11379    function mapKeys(object, iteratee) {
11380      var result = {};
11381      iteratee = getIteratee(iteratee, 3);
11382
11383      baseForOwn(object, function(value, key, object) {
11384        result[iteratee(value, key, object)] = value;
11385      });
11386      return result;
11387    }
11388
11389    /**
11390     * Creates an object with the same keys as `object` and values generated by
11391     * running each own enumerable property of `object` through `iteratee`. The
11392     * iteratee function is invoked with three arguments: (value, key, object).
11393     *
11394     * @static
11395     * @memberOf _
11396     * @category Object
11397     * @param {Object} object The object to iterate over.
11398     * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
11399     * @returns {Object} Returns the new mapped object.
11400     * @example
11401     *
11402     * var users = {
11403     *   'fred':    { 'user': 'fred',    'age': 40 },
11404     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
11405     * };
11406     *
11407     * _.mapValues(users, function(o) { return o.age; });
11408     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11409     *
11410     * // The `_.property` iteratee shorthand.
11411     * _.mapValues(users, 'age');
11412     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
11413     */
11414    function mapValues(object, iteratee) {
11415      var result = {};
11416      iteratee = getIteratee(iteratee, 3);
11417
11418      baseForOwn(object, function(value, key, object) {
11419        result[key] = iteratee(value, key, object);
11420      });
11421      return result;
11422    }
11423
11424    /**
11425     * Recursively merges own and inherited enumerable properties of source
11426     * objects into the destination object, skipping source properties that resolve
11427     * to `undefined`. Array and plain object properties are merged recursively.
11428     * Other objects and value types are overridden by assignment. Source objects
11429     * are applied from left to right. Subsequent sources overwrite property
11430     * assignments of previous sources.
11431     *
11432     * **Note:** This method mutates `object`.
11433     *
11434     * @static
11435     * @memberOf _
11436     * @category Object
11437     * @param {Object} object The destination object.
11438     * @param {...Object} [sources] The source objects.
11439     * @returns {Object} Returns `object`.
11440     * @example
11441     *
11442     * var users = {
11443     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
11444     * };
11445     *
11446     * var ages = {
11447     *   'data': [{ 'age': 36 }, { 'age': 40 }]
11448     * };
11449     *
11450     * _.merge(users, ages);
11451     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
11452     */
11453    var merge = createAssigner(function(object, source, srcIndex) {
11454      baseMerge(object, source, srcIndex);
11455    });
11456
11457    /**
11458     * This method is like `_.merge` except that it accepts `customizer` which
11459     * is invoked to produce the merged values of the destination and source
11460     * properties. If `customizer` returns `undefined` merging is handled by the
11461     * method instead. The `customizer` is invoked with seven arguments:
11462     * (objValue, srcValue, key, object, source, stack).
11463     *
11464     * **Note:** This method mutates `object`.
11465     *
11466     * @static
11467     * @memberOf _
11468     * @category Object
11469     * @param {Object} object The destination object.
11470     * @param {...Object} sources The source objects.
11471     * @param {Function} customizer The function to customize assigned values.
11472     * @returns {Object} Returns `object`.
11473     * @example
11474     *
11475     * function customizer(objValue, srcValue) {
11476     *   if (_.isArray(objValue)) {
11477     *     return objValue.concat(srcValue);
11478     *   }
11479     * }
11480     *
11481     * var object = {
11482     *   'fruits': ['apple'],
11483     *   'vegetables': ['beet']
11484     * };
11485     *
11486     * var other = {
11487     *   'fruits': ['banana'],
11488     *   'vegetables': ['carrot']
11489     * };
11490     *
11491     * _.mergeWith(object, other, customizer);
11492     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
11493     */
11494    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
11495      baseMerge(object, source, srcIndex, customizer);
11496    });
11497
11498    /**
11499     * The opposite of `_.pick`;
11499 this method creates an object composed of the
11500     * own and inherited enumerable properties of `object` that are not omitted.
11501     *
11502     * @static
11503     * @memberOf _
11504     * @category Object
11505     * @param {Object} object The source object.
11506     * @param {...(string|string[])} [props] The property names to omit, specified
11507     *  individually or in arrays..
11508     * @returns {Object} Returns the new object.
11509     * @example
11510     *
11511     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11512     *
11513     * _.omit(object, ['a', 'c']);
11514     * // => { 'b': '2' }
11515     */
11516    var omit = rest(function(object, props) {
11517      if (object == null) {
11518        return {};
11519      }
11520      props = arrayMap(baseFlatten(props), String);
11521      return basePick(object, baseDifference(keysIn(object), props));
11522    });
11523
11524    /**
11525     * The opposite of `_.pickBy`; this method creates an object composed of the
11526     * own and inherited enumerable properties of `object` that `predicate`
11527     * doesn't return truthy for.
11528     *
11529     * @static
11530     * @memberOf _
11531     * @category Object
11532     * @param {Object} object The source object.
11533     * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11534     * @returns {Object} Returns the new object.
11535     * @example
11536     *
11537     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11538     *
11539     * _.omitBy(object, _.isNumber);
11540     * // => { 'b': '2' }
11541     */
11542    function omitBy(object, predicate) {
11543      predicate = getIteratee(predicate, 2);
11544      return basePickBy(object, function(value, key) {
11545        return !predicate(value, key);
11546      });
11547    }
11548
11549    /**
11550     * Creates an object composed of the picked `object` properties.
11551     *
11552     * @static
11553     * @memberOf _
11554     * @category Object
11555     * @param {Object} object The source object.
11556     * @param {...(string|string[])} [props] The property names to pick, specified
11557     *  individually or in arrays.
11558     * @returns {Object} Returns the new object.
11559     * @example
11560     *
11561     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11562     *
11563     * _.pick(object, ['a', 'c']);
11564     * // => { 'a': 1, 'c': 3 }
11565     */
11566    var pick = rest(function(object, props) {
11567      return object == null ? {} : basePick(object, baseFlatten(props));
11568    });
11569
11570    /**
11571     * Creates an object composed of the `object` properties `predicate` returns
11572     * truthy for. The predicate is invoked with two arguments: (value, key).
11573     *
11574     * @static
11575     * @memberOf _
11576     * @category Object
11577     * @param {Object} object The source object.
11578     * @param {Function|Object|string} [predicate=_.identity] The function invoked per property.
11579     * @returns {Object} Returns the new object.
11580     * @example
11581     *
11582     * var object = { 'a': 1, 'b': '2', 'c': 3 };
11583     *
11584     * _.pickBy(object, _.isNumber);
11585     * // => { 'a': 1, 'c': 3 }
11586     */
11587    function pickBy(object, predicate) {
11588      return object == null ? {} : basePickBy(object, getIteratee(predicate, 2));
11589    }
11590
11591    /**
11592     * This method is like `_.get` except that if the resolved value is a function
11593     * it's invoked with the `this` binding of its parent object and its result
11594     * is returned.
11595     *
11596     * @static
11597     * @memberOf _
11598     * @category Object
11599     * @param {Object} object The object to query.
11600     * @param {Array|string} path The path of the property to resolve.
11601     * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
11602     * @returns {*} Returns the resolved value.
11603     * @example
11604     *
11605     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
11606     *
11607     * _.result(object, 'a[0].b.c1');
11608     * // => 3
11609     *
11610     * _.result(object, 'a[0].b.c2');
11611     * // => 4
11612     *
11613     * _.result(object, 'a[0].b.c3', 'default');
11614     * // => 'default'
11615     *
11616     * _.result(object, 'a[0].b.c3', _.constant('default'));
11617     * // => 'default'
11618     */
11619    function result(object, path, defaultValue) {
11620      if (!isKey(path, object)) {
11621        path = baseToPath(path);
11622        var result = get(object, path);
11623        object = parent(object, path);
11624      } else {
11625        result = object == null ? undefined : object[path];
11626      }
11627      if (result === undefined) {
11628        result = defaultValue;
11629      }
11630      return isFunction(result) ? result.call(object) : result;
11631    }
11632
11633    /**
11634     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist
11635     * it's created. Arrays are created for missing index properties while objects
11636     * are created for all other missing properties. Use `_.setWith` to customize
11637     * `path` creation.
11638     *
11639     * **Note:** This method mutates `object`.
11640     *
11641     * @static
11642     * @memberOf _
11643     * @category Object
11644     * @param {Object} object The object to modify.
11645     * @param {Array|string} path The path of the property to set.
11646     * @param {*} value The value to set.
11647     * @returns {Object} Returns `object`.
11648     * @example
11649     *
11650     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
11651     *
11652     * _.set(object, 'a[0].b.c', 4);
11653     * console.log(object.a[0].b.c);
11654     * // => 4
11655     *
11656     * _.set(object, 'x[0].y.z', 5);
11657     * console.log(object.x[0].y.z);
11658     * // => 5
11659     */
11660    function set(object, path, value) {
11661      return object == null ? object : baseSet(object, path, value);
11662    }
11663
11664    /**
11665     * This method is like `_.set` except that it accepts `customizer` which is
11666     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
11667     * path creation is handled by the method instead. The `customizer` is invoked
11668     * with three arguments: (nsValue, key, nsObject).
11669     *
11670     * **Note:** This method mutates `object`.
11671     *
11672     * @static
11673     * @memberOf _
11674     * @category Object
11675     * @param {Object} object The object to modify.
11676     * @param {Array|string} path The path of the property to set.
11677     * @param {*} value The value to set.
11678     * @param {Function} [customizer] The function to customize assigned values.
11679     * @returns {Object} Returns `object`.
11680     * @example
11681     *
11682     * _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object);
11683     * // => { '0': { '1': { '2': 3 }, 'length': 2 } }
11684     */
11685    function setWith(object, path, value, customizer) {
11686      customizer = typeof customizer == 'function' ? customizer : undefined;
11687      return object == null ? object : baseSet(object, path, value, customizer);
11688    }
11689
11690    /**
11691     * Creates an array of own enumerable key-value pairs for `object`.
11692     *
11693     * @static
11694     * @memberOf _
11695     * @category Object
11696     * @param {Object} object The object to query.
11697     * @returns {Array} Returns the new array of key-value pairs.
11698     * @example
11699     *
11700     * function Foo() {
11701     *   this.a = 1;
11702     *   this.b = 2;
11703     * }
11704     *
11705     * Foo.prototype.c = 3;
11706     *
11707     * _.toPairs(new Foo);
11708     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
11709     */
11710    function toPairs(object) {
11711      return baseToPairs(object, keys(object));
11712    }
11713
11714    /**
11715     * Creates an array of own and inherited enumerable key-value pairs for `object`.
11716     *
11717     * @static
11718     * @memberOf _
11719     * @category Object
11720     * @param {Object} object The object to query.
11721     * @returns {Array} Returns the new array of key-value pairs.
11722     * @example
11723     *
11724     * function Foo() {
11725     *   this.a = 1;
11726     *   this.b = 2;
11727     * }
11728     *
11729     * Foo.prototype.c = 3;
11730     *
11731     * _.toPairsIn(new Foo);
11732     * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
11733     */
11734    function toPairsIn(object) {
11735      return baseToPairs(object, keysIn(object));
11736    }
11737
11738    /**
11739     * An alternative to `_.reduce`; this method transforms `object` to a new
11740     * `accumulator` object which is the result of running each of its own enumerable
11741     * properties through `iteratee`, with each invocation potentially mutating
11742     * the `accumulator` object. The iteratee is invoked with four arguments:
11743     * (accumulator, value, key, object). Iteratee functions may exit iteration
11744     * early by explicitly returning `false`.
11745     *
11746     * @static
11747     * @memberOf _
11748     * @category Object
11749     * @param {Array|Object} object The object to iterate over.
11750     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
11751     * @param {*} [accumulator] The custom accumulator value.
11752     * @returns {*} Returns the accumulated value.
11753     * @example
11754     *
11755     * _.transform([2, 3, 4], function(result, n) {
11756     *   result.push(n *= n);
11757     *   return n % 2 == 0;
11758     * }, []);
11759     * // => [4, 9]
11760     *
11761     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
11762     *   (result[value] || (result[value] = [])).push(key);
11763     * }, {});
11764     * // => { '1': ['a', 'c'], '2': ['b'] }
11765     */
11766    function transform(object, iteratee, accumulator) {
11767      var isArr = isArray(object) || isTypedArray(object);
11768      iteratee = getIteratee(iteratee, 4);
11769
11770      if (accumulator == null) {
11771        if (isArr || isObject(object)) {
11772          var Ctor = object.constructor;
11773          if (isArr) {
11774            accumulator = isArray(object) ? new Ctor : [];
11775          } else {
11776            accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined);
11777          }
11778        } else {
11779          accumulator = {};
11780        }
11781      }
11782      (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
11783        return iteratee(accumulator, value, index, object);
11784      });
11785      return accumulator;
11786    }
11787
11788    /**
11789     * Removes the property at `path` of `object`.
11790     *
11791     * **Note:** This method mutates `object`.
11792     *
11793     * @static
11794     * @memberOf _
11795     * @category Object
11796     * @param {Object} object The object to modify.
11797     * @param {Array|string} path The path of the property to unset.
11798     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
11799     * @example
11800     *
11801     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
11802     * _.unset(object, 'a[0].b.c');
11803     * // => true
11804     *
11805     * console.log(object);
11806     * // => { 'a': [{ 'b': {} }] };
11807     *
11808     * _.unset(object, 'a[0].b.c');
11809     * // => true
11810     *
11811     * console.log(object);
11812     * // => { 'a': [{ 'b': {} }] };
11813     */
11814    function unset(object, path) {
11815      return object == null ? true : baseUnset(object, path);
11816    }
11817
11818    /**
11819     * Creates an array of the own enumerable property values of `object`.
11820     *
11821     * **Note:** Non-object values are coerced to objects.
11822     *
11823     * @static
11824     * @memberOf _
11825     * @category Object
11826     * @param {Object} object The object to query.
11827     * @returns {Array} Returns the array of property values.
11828     * @example
11829     *
11830     * function Foo() {
11831     *   this.a = 1;
11832     *   this.b = 2;
11833     * }
11834     *
11835     * Foo.prototype.c = 3;
11836     *
11837     * _.values(new Foo);
11838     * // => [1, 2] (iteration order is not guaranteed)
11839     *
11840     * _.values('hi');
11841     * // => ['h', 'i']
11842     */
11843    function values(object) {
11844      return object ? baseValues(object, keys(object)) : [];
11845    }
11846
11847    /**
11848     * Creates an array of the own and inherited enumerable property values of `object`.
11849     *
11850     * **Note:** Non-object values are coerced to objects.
11851     *
11852     * @static
11853     * @memberOf _
11854     * @category Object
11855     * @param {Object} object The object to query.
11856     * @returns {Array} Returns the array of property values.
11857     * @example
11858     *
11859     * function Foo() {
11860     *   this.a = 1;
11861     *   this.b = 2;
11862     * }
11863     *
11864     * Foo.prototype.c = 3;
11865     *
11866     * _.valuesIn(new Foo);
11867     * // => [1, 2, 3] (iteration order is not guaranteed)
11868     */
11869    function valuesIn(object) {
11870      return object == null ? baseValues(object, keysIn(object)) : [];
11871    }
11872
11873    /*------------------------------------------------------------------------*/
11874
11875    /**
11876     * Clamps `number` within the inclusive `lower` and `upper` bounds.
11877     *
11878     * @static
11879     * @memberOf _
11880     * @category Number
11881     * @param {number} number The number to clamp.
11882     * @param {number} [lower] The lower bound.
11883     * @param {number} upper The upper bound.
11884     * @returns {number} Returns the clamped number.
11885     * @example
11886     *
11887     * _.clamp(-10, -5, 5);
11888     * // => -5
11889     *
11890     * _.clamp(10, -5, 5);
11891     * // => 5
11892     */
11893    function clamp(number, lower, upper) {
11894      if (upper === undefined) {
11895        upper = lower;
11896        lower = undefined;
11897      }
11898      if (upper !== undefined) {
11899        upper = toNumber(upper);
11900        upper = upper === upper ? upper : 0;
11901      }
11902      if (lower !== undefined) {
11903        lower = toNumber(lower);
11904        lower = lower === lower ? lower : 0;
11905      }
11906      return baseClamp(toNumber(number), lower, upper);
11907    }
11908
11909    /**
11910     * Checks if `n` is between `start` and up to but not including, `end`. If
11911     * `end` is not specified it's set to `start` with `start` then set to `0`.
11912     * If `start` is greater than `end` the params are swapped to support
11913     * negative ranges.
11914     *
11915     * @static
11916     * @memberOf _
11917     * @category Number
11918     * @param {number} number The number to check.
11919     * @param {number} [start=0] The start of the range.
11920     * @param {number} end The end of the range.
11921     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
11922     * @example
11923     *
11924     * _.inRange(3, 2, 4);
11925     * // => true
11926     *
11927     * _.inRange(4, 8);
11928     * // => true
11929     *
11930     * _.inRange(4, 2);
11931     * // => false
11932     *
11933     * _.inRange(2, 2);
11934     * // => false
11935     *
11936     * _.inRange(1.2, 2);
11937     * // => true
11938     *
11939     * _.inRange(5.2, 4);
11940     * // => false
11941     *
11942     * _.inRange(-3, -2, -6);
11943     * // => true
11944     */
11945    function inRange(number, start, end) {
11946      start = toNumber(start) || 0;
11947      if (end === undefined) {
11948        end = start;
11949        start = 0;
11950      } else {
11951        end = toNumber(end) || 0;
11952      }
11953      number = toNumber(number);
11954      return baseInRange(number, start, end);
11955    }
11956
11957    /**
11958     * Produces a random number between the inclusive `lower` and `upper` bounds.
11959     * If only one argument is provided a number between `0` and the given number
11960     * is returned. If `floating` is `true`, or either `lower` or `upper` are floats,
11961     * a floating-point number is returned instead of an integer.
11962     *
11963     * **Note:** JavaScript follows the IEEE-754 standard for resolving
11964     * floating-point values which can produce unexpected results.
11965     *
11966     * @static
11967     * @memberOf _
11968     * @category Number
11969     * @param {number} [lower=0] The lower bound.
11970     * @param {number} [upper=1] The upper bound.
11971     * @param {boolean} [floating] Specify returning a floating-point number.
11972     * @returns {number} Returns the random number.
11973     * @example
11974     *
11975     * _.random(0, 5);
11976     * // => an integer between 0 and 5
11977     *
11978     * _.random(5);
11979     * // => also an integer between 0 and 5
11980     *
11981     * _.random(5, true);
11982     * // => a floating-point number between 0 and 5
11983     *
11984     * _.random(1.2, 5.2);
11985     * // => a floating-point number between 1.2 and 5.2
11986     */
11987    function random(lower, upper, floating) {
11988      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
11989        upper = floating = undefined;
11990      }
11991      if (floating === undefined) {
11992        if (typeof upper == 'boolean') {
11993          floating = upper;
11994          upper = undefined;
11995        }
11996        else if (typeof lower == 'boolean') {
11997          floating = lower;
11998          lower = undefined;
11999        }
12000      }
12001      if (lower === undefined && upper === undefined) {
12002        lower = 0;
12003        upper = 1;
12004      }
12005      else {
12006        lower = toNumber(lower) || 0;
12007        if (upper === undefined) {
12008          upper = lower;
12009          lower = 0;
12010        } else {
12011          upper = toNumber(upper) || 0;
12012        }
12013      }
12014      if (lower > upper) {
12015        var temp = lower;
12016        lower = upper;
12017        upper = temp;
12018      }
12019      if (floating || lower % 1 || upper % 1) {
12020        var rand = nativeRandom();
12021        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
12022      }
12023      return baseRandom(lower, upper);
12024    }
12025
12026    /*------------------------------------------------------------------------*/
12027
12028    /**
12029     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
12030     *
12031     * @static
12032     * @memberOf _
12033     * @category String
12034     * @param {string} [string=''] The string to convert.
12035     * @returns {string} Returns the camel cased string.
12036     * @example
12037     *
12038     * _.camelCase('Foo Bar');
12039     * // => 'fooBar'
12040     *
12041     * _.camelCase('--foo-bar');
12042     * // => 'fooBar'
12043     *
12044     * _.camelCase('__foo_bar__');
12045     * // => 'fooBar'
12046     */
vendor: 4,524 bytes, lines 12047-12176
12047    var camelCase = createCompounder(function(result, word, index) {
12048      word = word.toLowerCase();
12049      return result + (index ? capitalize(word) : word);
12050    });
12051
12052    /**
12053     * Converts the first character of `string` to upper case and the remaining
12054     * to lower case.
12055     *
12056     * @static
12057     * @memberOf _
12058     * @category String
12059     * @param {string} [string=''] The string to capitalize.
12060     * @returns {string} Returns the capitalized string.
12061     * @example
12062     *
12063     * _.capitalize('FRED');
12064     * // => 'Fred'
12065     */
12066    function capitalize(string) {
12067      return upperFirst(toString(string).toLowerCase());
12068    }
12069
12070    /**
12071     * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
12072     * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
12073     *
12074     * @static
12075     * @memberOf _
12076     * @category String
12077     * @param {string} [string=''] The string to deburr.
12078     * @returns {string} Returns the deburred string.
12079     * @example
12080     *
12081     * _.deburr('déjà vu');
12082     * // => 'deja vu'
12083     */
12084    function deburr(string) {
12085      string = toString(string);
12086      return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
12087    }
12088
12089    /**
12090     * Checks if `string` ends with the given target string.
12091     *
12092     * @static
12093     * @memberOf _
12094     * @category String
12095     * @param {string} [string=''] The string to search.
12096     * @param {string} [target] The string to search for.
12097     * @param {number} [position=string.length] The position to search from.
12098     * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`.
12099     * @example
12100     *
12101     * _.endsWith('abc', 'c');
12102     * // => true
12103     *
12104     * _.endsWith('abc', 'b');
12105     * // => false
12106     *
12107     * _.endsWith('abc', 'b', 2);
12108     * // => true
12109     */
12110    function endsWith(string, target, position) {
12111      string = toString(string);
12112      target = typeof target == 'string' ? target : (target + '');
12113
12114      var length = string.length;
12115      position = position === undefined
12116        ? length
12117        : baseClamp(toInteger(position), 0, length);
12118
12119      position -= target.length;
12120      return position >= 0 && string.indexOf(target, position) == position;
12121    }
12122
12123    /**
12124     * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
12125     * their corresponding HTML entities.
12126     *
12127     * **Note:** No other characters are escaped. To escape additional
12128     * characters use a third-party library like [_he_](https://mths.be/he).
12129     *
12130     * Though the ">" character is escaped for symmetry, characters like
12131     * ">" and "/" don't need escaping in HTML and have no special meaning
12132     * unless they're part of a tag or unquoted attribute value.
12133     * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
12134     * (under "semi-related fun fact") for more details.
12135     *
12136     * Backticks are escaped because in IE < 9, they can break out of
12137     * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
12138     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
12139     * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
12140     * for more details.
12141     *
12142     * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
12143     * to reduce XSS vectors.
12144     *
12145     * @static
12146     * @memberOf _
12147     * @category String
12148     * @param {string} [string=''] The string to escape.
12149     * @returns {string} Returns the escaped string.
12150     * @example
12151     *
12152     * _.escape('fred, barney, & pebbles');
12153     * // => 'fred, barney, &amp; pebbles'
12154     */
12155    function escape(string) {
12156      string = toString(string);
12157      return (string && reHasUnescapedHtml.test(string))
12158        ? string.replace(reUnescapedHtml, escapeHtmlChar)
12159        : string;
12160    }
12161
12162    /**
12163     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
12164     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
12165     *
12166     * @static
12167     * @memberOf _
12168     * @category String
12169     * @param {string} [string=''] The string to escape.
12170     * @returns {string} Returns the escaped string.
12171     * @example
12172     *
12173     * _.escapeRegExp('[lodash](https://lodash.com/)');
12174     * // => '\[lodash\]\(https://lodash\.com/\)'
12175     */
12176    function escapeRegExp(string) {
12177      string = toString(string);
12178      return (string && reHasRegExpChar.test(string))
12179        ? string.replace(reRegExpChar, '\\$&')
12180        : string;
12181    }
12182
12183    /**
12184     * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
12185     *
12186     * @static
12187     * @memberOf _
12188     * @category String
12189     * @param {string} [string=''] The string to convert.
12190     * @returns {string} Returns the kebab cased string.
12191     * @example
12192     *
12193     * _.kebabCase('Foo Bar');
12194     * // => 'foo-bar'
12195     *
12196     * _.kebabCase('fooBar');
12197     * // => 'foo-bar'
12198     *
12199     * _.kebabCase('__foo_bar__');
12200     * // => 'foo-bar'
12201     */
12202    var kebabCase = createCompounder(function(result, word, index) {
12203      return result + (index ? '-' : '') + word.toLowerCase();
12204    });
12205
12206    /**
12207     * Converts `string`, as space separated words, to lower case.
12208     *
12209     * @static
12210     * @memberOf _
12211     * @category String
12212     * @param {string} [string=''] The string to convert.
12213     * @returns {string} Returns the lower cased string.
12214     * @example
12215     *
12216     * _.lowerCase('--Foo-Bar');
12217     * // => 'foo bar'
12218     *
12219     * _.lowerCase('fooBar');
12220     * // => 'foo bar'
12221     *
12222     * _.lowerCase('__FOO_BAR__');
12223     * // => 'foo bar'
12224     */
12225    var lowerCase = createCompounder(function(result, word, index) {
12226      return result + (index ? ' ' : '') + word.toLowerCase();
12227    });
12228
12229    /**
12230     * Converts the first character of `string` to lower case.
12231     *
12232     * @static
12233     * @memberOf _
12234     * @category String
12235     * @param {string} [string=''] The string to convert.
12236     * @returns {string} Returns the converted string.
12237     * @example
12238     *
12239     * _.lowerFirst('Fred');
12240     * // => 'fred'
12241     *
12242     * _.lowerFirst('FRED');
12243     * // => 'fRED'
12244     */
12245    var lowerFirst = createCaseFirst('toLowerCase');
12246
12247    /**
12248     * Converts the first character of `string` to upper case.
12249     *
12250     * @static
12251     * @memberOf _
12252     * @category String
12253     * @param {string} [string=''] The string to convert.
12254     * @returns {string} Returns the converted string.
12255     * @example
12256     *
12257     * _.upperFirst('fred');
12258     * // => 'Fred'
12259     *
12260     * _.upperFirst('FRED');
12261     * // => 'FRED'
12262     */
12263    var upperFirst = createCaseFirst('toUpperCase');
12264
12265    /**
12266     * Pads `string` on the left and right sides if it's shorter than `length`.
12267     * Padding characters are truncated if they can't be evenly divided by `length`.
12268     *
12269     * @static
12270     * @memberOf _
12271     * @category String
12272     * @param {string} [string=''] The string to pad.
12273     * @param {number} [length=0] The padding length.
12274     * @param {string} [chars=' '] The string used as padding.
12275     * @returns {string} Returns the padded string.
12276     * @example
12277     *
12278     * _.pad('abc', 8);
12279     * // => '  abc   '
12280     *
12281     * _.pad('abc', 8, '_-');
12282     * // => '_-abc_-_'
12283     *
12284     * _.pad('abc', 3);
12285     * // => 'abc'
12286     */
12287    function pad(string, length, chars) {
12288      string = toString(string);
12289      length = toInteger(length);
12290
12291      var strLength = stringSize(string);
12292      if (!length || strLength >= length) {
12293        return string;
12294      }
12295      var mid = (length - strLength) / 2,
12296          leftLength = nativeFloor(mid),
12297          rightLength = nativeCeil(mid);
12298
12299      return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars);
12300    }
12301
12302    /**
12303     * Pads `string` on the right side if it's shorter than `length`. Padding
12304     * characters are truncated if they exceed `length`.
12305     *
12306     * @static
12307     * @memberOf _
12308     * @category String
12309     * @param {string} [string=''] The string to pad.
12310     * @param {number} [length=0] The padding length.
12311     * @param {string} [chars=' '] The string used as padding.
12312     * @returns {string} Returns the padded string.
12313     * @example
12314     *
12315     * _.padEnd('abc', 6);
12316     * // => 'abc   '
12317     *
12318     * _.padEnd('abc', 6, '_-');
12319     * // => 'abc_-_'
12320     *
12321     * _.padEnd('abc', 3);
12322     * // => 'abc'
12323     */
12324    function padEnd(string, length, chars) {
12325      string = toString(string);
12326      return string + createPadding(string, length, chars);
12327    }
12328
12329    /**
12330     * Pads `string` on the left side if it's shorter than `length`. Padding
12331     * characters are truncated if they exceed `length`.
12332     *
12333     * @static
12334     * @memberOf _
12335     * @category String
12336     * @param {string} [string=''] The string to pad.
12337     * @param {number} [length=0] The padding length.
12338     * @param {string} [chars=' '] The string used as padding.
12339     * @returns {string} Returns the padded string.
12340     * @example
12341     *
12342     * _.padStart('abc', 6);
12343     * // => '   abc'
12344     *
12345     * _.padStart('abc', 6, '_-');
12346     * // => '_-_abc'
12347     *
12348     * _.padStart('abc', 3);
12349     * // => 'abc'
12350     */
12351    function padStart(string, length, chars) {
12352      string = toString(string);
12353      return createPadding(string, length, chars) + string;
12354    }
12355
12356    /**
12357     * Converts `string` to an integer of the specified radix. If `radix` is
12358     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
12359     * in which case a `radix` of `16` is used.
12360     *
12361     * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
12362     * of `parseInt`.
12363     *
12364     * @static
12365     * @memberOf _
12366     * @category String
12367     * @param {string} string The string to convert.
12368     * @param {number} [radix] The radix to interpret `value` by.
12369     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12370     * @returns {number} Returns the converted integer.
12371     * @example
12372     *
12373     * _.parseInt('08');
12374     * // => 8
12375     *
12376     * _.map(['6', '08', '10'], _.parseInt);
12377     * // => [6, 8, 10]
12378     */
12379    function parseInt(string, radix, guard) {
12380      // Chrome fails to trim leading <BOM> whitespace characters.
12381      // See https://code.google.com/p/v8/issues/detail?id=3109 for more details.
12382      if (guard || radix == null) {
12383        radix = 0;
12384      } else if (radix) {
12385        radix = +radix;
12386      }
12387      string = toString(string).replace(reTrim, '');
12388      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
12389    }
12390
12391    /**
12392     * Repeats the given string `n` times.
12393     *
12394     * @static
12395     * @memberOf _
12396     * @category String
12397     * @param {string} [string=''] The string to repeat.
12398     * @param {number} [n=0] The number of times to repeat the string.
12399     * @returns {string} Returns the repeated string.
12400     * @example
12401     *
12402     * _.repeat('*', 3);
12403     * // => '***'
12404     *
12405     * _.repeat('abc', 2);
12406     * // => 'abcabc'
12407     *
12408     * _.repeat('abc', 0);
12409     * // => ''
12410     */
12411    function repeat(string, n) {
12412      string = toString(string);
12413      n = toInteger(n);
12414
12415      var result = '';
12416      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
12417        return result;
12418      }
12419      // Leverage the exponentiation by squaring algorithm for a faster repeat.
12420      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
12421      do {
12422        if (n % 2) {
12423          result += string;
12424        }
12425        n = nativeFloor(n / 2);
12426        string += string;
12427      } while (n);
12428
12429      return result;
12430    }
12431
12432    /**
12433     * Replaces matches for `pattern` in `string` with `replacement`.
12434     *
12435     * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace).
12436     *
12437     * @static
12438     * @memberOf _
12439     * @category String
12440     * @param {string} [string=''] The string to modify.
12441     * @param {RegExp|string} pattern The pattern to replace.
12442     * @param {Function|string} replacement The match replacement.
12443     * @returns {string} Returns the modified string.
12444     * @example
12445     *
12446     * _.replace('Hi Fred', 'Fred', 'Barney');
12447     * // =>
12447 'Hi Barney'
12448     */
12449    function replace() {
12450      var args = arguments,
12451          string = toString(args[0]);
12452
12453      return args.length < 3 ? string : string.replace(args[1], args[2]);
12454    }
12455
12456    /**
12457     * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case).
12458     *
12459     * @static
12460     * @memberOf _
12461     * @category String
12462     * @param {string} [string=''] The string to convert.
12463     * @returns {string} Returns the snake cased string.
12464     * @example
12465     *
12466     * _.snakeCase('Foo Bar');
12467     * // => 'foo_bar'
12468     *
12469     * _.snakeCase('fooBar');
12470     * // => 'foo_bar'
12471     *
12472     * _.snakeCase('--foo-bar');
12473     * // => 'foo_bar'
12474     */
12475    var snakeCase = createCompounder(function(result, word, index) {
12476      return result + (index ? '_' : '') + word.toLowerCase();
12477    });
12478
12479    /**
12480     * Splits `string` by `separator`.
12481     *
12482     * **Note:** This method is based on [`String#split`](https://mdn.io/String/split).
12483     *
12484     * @static
12485     * @memberOf _
12486     * @category String
12487     * @param {string} [string=''] The string to split.
12488     * @param {RegExp|string} separator The separator pattern to split by.
12489     * @param {number} [limit] The length to truncate results to.
12490     * @returns {Array} Returns the new array of string segments.
12491     * @example
12492     *
12493     * _.split('a-b-c', '-', 2);
12494     * // => ['a', 'b']
12495     */
12496    function split(string, separator, limit) {
12497      return toString(string).split(separator, limit);
12498    }
12499
12500    /**
12501     * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
12502     *
12503     * @static
12504     * @memberOf _
12505     * @category String
12506     * @param {string} [string=''] The string to convert.
12507     * @returns {string} Returns the start cased string.
12508     * @example
12509     *
12510     * _.startCase('--foo-bar');
12511     * // => 'Foo Bar'
12512     *
12513     * _.startCase('fooBar');
12514     * // => 'Foo Bar'
12515     *
12516     * _.startCase('__foo_bar__');
12517     * // => 'Foo Bar'
12518     */
12519    var startCase = createCompounder(function(result, word, index) {
12520      return result + (index ? ' ' : '') + capitalize(word);
12521    });
12522
12523    /**
12524     * Checks if `string` starts with the given target string.
12525     *
12526     * @static
12527     * @memberOf _
12528     * @category String
12529     * @param {string} [string=''] The string to search.
12530     * @param {string} [target] The string to search for.
12531     * @param {number} [position=0] The position to search from.
12532     * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`.
12533     * @example
12534     *
12535     * _.startsWith('abc', 'a');
12536     * // => true
12537     *
12538     * _.startsWith('abc', 'b');
12539     * // => false
12540     *
12541     * _.startsWith('abc', 'b', 1);
12542     * // => true
12543     */
12544    function startsWith(string, target, position) {
12545      string = toString(string);
12546      position = baseClamp(toInteger(position), 0, string.length);
12547      return string.lastIndexOf(target, position) == position;
12548    }
12549
12550    /**
12551     * Creates a compiled template function that can interpolate data properties
12552     * in "interpolate" delimiters, HTML-escape interpolated data properties in
12553     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
12554     * properties may be accessed as free variables in the template. If a setting
12555     * object is given it takes precedence over `_.templateSettings` values.
12556     *
12557     * **Note:** In the development build `_.template` utilizes
12558     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
12559     * for easier debugging.
12560     *
12561     * For more information on precompiling templates see
12562     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
12563     *
12564     * For more information on Chrome extension sandboxes see
12565     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
12566     *
12567     * @static
12568     * @memberOf _
12569     * @category String
12570     * @param {string} [string=''] The template string.
12571     * @param {Object} [options] The options object.
12572     * @param {RegExp} [options.escape] The HTML "escape" delimiter.
12573     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
12574     * @param {Object} [options.imports] An object to import into the template as free variables.
12575     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
12576     * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
12577     * @param {string} [options.variable] The data object variable name.
12578     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12579     * @returns {Function} Returns the compiled template function.
12580     * @example
12581     *
12582     * // Use the "interpolate" delimiter to create a compiled template.
12583     * var compiled = _.template('hello <%= user %>!');
12584     * compiled({ 'user': 'fred' });
12585     * // => 'hello fred!'
12586     *
12587     * // Use the HTML "escape" delimiter to escape data property values.
12588     * var compiled = _.template('<b><%- value %></b>');
12589     * compiled({ 'value': '<script>' });
12590     * // => '<b>&lt;script&gt;</b>'
12591     *
12592     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
12593     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
12594     * compiled({ 'users': ['fred', 'barney'] });
12595     * // => '<li>fred</li><li>barney</li>'
12596     *
12597     * // Use the internal `print` function in "evaluate" delimiters.
12598     * var compiled = _.template('<% print("hello " + user); %>!');
12599     * compiled({ 'user': 'barney' });
12600     * // => 'hello barney!'
12601     *
12602     * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
12603     * var compiled = _.template('hello ${ user }!');
12604     * compiled({ 'user': 'pebbles' });
12605     * // => 'hello pebbles!'
12606     *
12607     * // Use custom template delimiters.
12608     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
12609     * var compiled = _.template('hello {{ user }}!');
12610     * compiled({ 'user': 'mustache' });
12611     * // => 'hello mustache!'
12612     *
12613     * // Use backslashes to treat delimiters as plain text.
12614     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
12615     * compiled({ 'value': 'ignored' });
12616     * // => '<%- value %>'
12617     *
12618     * // Use the `imports` option to import `jQuery` as `jq`.
12619     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
12620     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
12621     * compiled({ 'users': ['fred', 'barney'] });
12622     * // => '<li>fred</li><li>barney</li>'
12623     *
12624     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
12625     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
12626     * compiled(data);
12627     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
12628     *
12629     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
12630     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
12631     * compiled.source;
12632     * // => function(data) {
12633     * //   var __t, __p = '';
12634     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
12635     * //   return __p;
12636     * // }
12637     *
12638     * // Use the `source` property to inline compiled templates for meaningful
12639     * // line numbers in error messages and stack traces.
12640     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
12641     *   var JST = {\
12642     *     "main": ' + _.template(mainText).source + '\
12643     *   };\
12644     * ');
12645     */
12646    function template(string, options, guard) {
12647      // Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/)
12648      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
12649      var settings = lodash.templateSettings;
12650
12651      if (guard && isIterateeCall(string, options, guard)) {
12652        options = undefined;
12653      }
12654      string = toString(string);
12655      options = assignInWith({}, options, settings, assignInDefaults);
12656
12657      var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
12658          importsKeys = keys(imports),
12659          importsValues = baseValues(imports, importsKeys);
12660
12661      var isEscaping,
12662          isEvaluating,
12663          index = 0,
12664          interpolate = options.interpolate || reNoMatch,
12665          source = "__p += '";
12666
12667      // Compile the regexp to match each delimiter.
12668      var reDelimiters = RegExp(
12669        (options.escape || reNoMatch).source + '|' +
12670        interpolate.source + '|' +
12671        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
12672        (options.evaluate || reNoMatch).source + '|$'
12673      , 'g');
12674
12675      // Use a sourceURL for easier debugging.
12676      var sourceURL = '//# sourceURL=' +
12677        ('sourceURL' in options
12678          ? options.sourceURL
12679          : ('lodash.templateSources[' + (++templateCounter) + ']')
12680        ) + '\n';
12681
12682      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
12683        interpolateValue || (interpolateValue = esTemplateValue);
12684
12685        // Escape characters that can't be included in string literals.
12686        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
12687
12688        // Replace delimiters with snippets.
12689        if (escapeValue) {
12690          isEscaping = true;
12691          source += "' +\n__e(" + escapeValue + ") +\n'";
12692        }
12693        if (evaluateValue) {
12694          isEvaluating = true;
12695          source += "';\n" + evaluateValue + ";\n__p += '";
12696        }
12697        if (interpolateValue) {
12698          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
12699        }
12700        index = offset + match.length;
12701
12702        // The JS engine embedded in Adobe products needs `match` returned in
12703        // order to produce the correct `offset` value.
12704        return match;
12705      });
12706
12707      source += "';\n";
12708
12709      // If `variable` is not specified wrap a with-statement around the generated
12710      // code to add the data object to the top of the scope chain.
12711      var variable = options.variable;
12712      if (!variable) {
12713        source = 'with (obj) {\n' + source + '\n}\n';
12714      }
12715      // Cleanup code by stripping empty strings.
12716      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
12717        .replace(reEmptyStringMiddle, '$1')
12718        .replace(reEmptyStringTrailing, '$1;');
12719
12720      // Frame code as the function body.
12721      source = 'function(' + (variable || 'obj') + ') {\n' +
12722        (variable
12723          ? ''
12724          : 'obj || (obj = {});\n'
12725        ) +
12726        "var __t, __p = ''" +
12727        (isEscaping
12728           ? ', __e = _.escape'
12729           : ''
12730        ) +
12731        (isEvaluating
12732          ? ', __j = Array.prototype.join;\n' +
12733            "function print() { __p += __j.call(arguments, '') }\n"
12734          : ';\n'
12735        ) +
12736        source +
12737        'return __p\n}';
12738
12739      var result = attempt(function() {
12740        return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues);
12741      });
12742
12743      // Provide the compiled function's source by its `toString` method or
12744      // the `source` property as a convenience for inlining compiled templates.
12745      result.source = source;
12746      if (isError(result)) {
12747        throw result;
12748      }
12749      return result;
12750    }
12751
12752    /**
12753     * Converts `string`, as a whole, to lower case.
12754     *
12755     * @static
12756     * @memberOf _
12757     * @category String
12758     * @param {string} [string=''] The string to convert.
12759     * @returns {string} Returns the lower cased string.
12760     * @example
12761     *
12762     * _.toLower('--Foo-Bar');
12763     * // => '--foo-bar'
12764     *
12765     * _.toLower('fooBar');
12766     * // => 'foobar'
12767     *
12768     * _.toLower('__FOO_BAR__');
12769     * // => '__foo_bar__'
12770     */
12771    function toLower(value) {
12772      return toString(value).toLowerCase();
12773    }
12774
12775    /**
12776     * Converts `string`, as a whole, to upper case.
12777     *
12778     * @static
12779     * @memberOf _
12780     * @category String
12781     * @param {string} [string=''] The string to convert.
12782     * @returns {string} Returns the upper cased string.
12783     * @example
12784     *
12785     * _.toUpper('--foo-bar');
12786     * // => '--FOO-BAR'
12787     *
12788     * _.toUpper('fooBar');
12789     * // => 'FOOBAR'
12790     *
12791     * _.toUpper('__foo_bar__');
12792     * // => '__FOO_BAR__'
12793     */
12794    function toUpper(value) {
12795      return toString(value).toUpperCase();
12796    }
12797
12798    /**
12799     * Removes leading and trailing whitespace or specified characters from `string`.
12800     *
12801     * @static
12802     * @memberOf _
12803     * @category String
12804     * @param {string} [string=''] The string to trim.
12805     * @param {string} [chars=whitespace] The characters to trim.
12806     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12807     * @returns {string} Returns the trimmed string.
12808     * @example
12809     *
12810     * _.trim('  abc  ');
12811     * // => 'abc'
12812     *
12813     * _.trim('-_-abc-_-', '_-');
12814     * // => 'abc'
12815     *
12816     * _.map(['  foo  ', '  bar  '], _.trim);
12817     * // => ['foo', 'bar']
12818     */
12819    function trim(string, chars, guard) {
12820      string = toString(string);
12821      if (!string) {
12822        return string;
12823      }
12824      if (guard || chars === undefined) {
12825        return string.replace(reTrim, '');
12826      }
12827      chars = (chars + '');
12828      if (!chars) {
12829        return string;
12830      }
12831      var strSymbols = stringToArray(string),
12832          chrSymbols = stringToArray(chars);
12833
12834      return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join('');
12835    }
12836
12837    /**
12838     * Removes trailing whitespace or specified characters from `string`.
12839     *
12840     * @static
12841     * @memberOf _
12842     * @category String
12843     * @param {string} [string=''] The string to trim.
12844     * @param {string} [chars=whitespace] The characters to trim.
12845     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12846     * @returns {string} Returns the trimmed string.
12847     * @example
12848     *
12849     * _.trimEnd('  abc  ');
12850     * // => '  abc'
12851     *
12852     * _.trimEnd('-_-abc-_-', '_-');
12853     * // => '-_-abc'
12854     */
12855    function trimEnd(string, chars, guard) {
12856      string = toString(string);
12857      if (!string) {
12858        return string;
12859      }
12860      if (guard || chars === undefined) {
12861        return string.replace(reTrimEnd, '');
12862      }
12863      chars = (chars + '');
12864      if (!chars) {
12865        return string;
12866      }
12867      var strSymbols = stringToArray(string);
12868      return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join('');
12869    }
12870
12871    /**
12872     * Removes leading whitespace or specified characters from `string`.
12873     *
12874     * @static
12875     * @memberOf _
12876     * @category String
12877     * @param {string} [string=''] The string to trim.
12878     * @param {string} [chars=whitespace] The characters to trim.
12879     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
12880     * @returns {string} Returns the trimmed string.
12881     * @example
12882     *
12883     * _.trimStart('  abc  ');
12884     * // => 'abc  '
12885     *
12886     * _.trimStart('-_-abc-_-', '_-');
12887     * // => 'abc-_-'
12888     */
12889    function trimStart(string, chars, guard) {
12890      string = toString(string);
12891      if (!string) {
12892        return string;
12893      }
12894      if (guard || chars === undefined) {
12895        return string.replace(reTrimStart, '');
12896      }
12897      chars = (chars + '');
12898      if (!chars) {
12899        return string;
12900      }
12901      var strSymbols = stringToArray(string);
12902      return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join('');
12903    }
12904
12905    /**
12906     * Truncates `string` if it's longer than the given maximum string length.
12907     * The last characters of the truncated string are replaced with the omission
12908     * string which defaults to "...".
12909     *
12910     * @static
12911     * @memberOf _
12912     * @category String
12913     * @param {string} [string=''] The string to truncate.
12914     * @param {Object} [options] The options object.
12915     * @param {number} [options.length=30] The maximum string length.
12916     * @param {string} [options.omission='...'] The string to indicate text is omitted.
12917     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
12918     * @returns {string} Returns the truncated string.
12919     * @example
12920     *
12921     * _.truncate('hi-diddly-ho there, neighborino');
12922     * // => 'hi-diddly-ho there, neighbo...'
12923     *
12924     * _.truncate('hi-diddly-ho there, neighborino', {
12925     *   'length': 24,
12926     *   'separator': ' '
12927     * });
12928     * // => 'hi-diddly-ho there,...'
12929     *
12930     * _.truncate('hi-diddly-ho there, neighborino', {
12931     *   'length': 24,
12932     *   'separator': /,? +/
12933     * });
12934     * // => 'hi-diddly-ho there...'
12935     *
12936     * _.truncate('hi-diddly-ho there, neighborino', {
12937     *   'omission': ' [...]'
12938     * });
12939     * // => 'hi-diddly-ho there, neig [...]'
12940     */
12941    function truncate(string, options) {
12942      var length = DEFAULT_TRUNC_LENGTH,
12943          omission = DEFAULT_TRUNC_OMISSION;
12944
12945      if (isObject(options)) {
12946        var separator = 'separator' in options ? options.separator : separator;
12947        length = 'length' in options ? toInteger(options.length) : length;
12948        omission = 'omission' in options ? toString(options.omission) : omission;
12949      }
12950      string = toString(string);
12951
12952      var strLength = string.length;
12953      if (reHasComplexSymbol.test(string)) {
12954        var strSymbols = stringToArray(string);
12955        strLength = strSymbols.length;
12956      }
12957      if (length >= strLength) {
12958        return string;
12959      }
12960      var end = length - stringSize(omission);
12961      if (end < 1) {
12962        return omission;
12963      }
12964      var result = strSymbols
12965        ? strSymbols.slice(0, end).join('')
12966        : string.slice(0, end);
12967
12968      if (separator === undefined) {
12969        return result + omission;
12970      }
12971      if (strSymbols) {
12972        end += (result.length - end);
12973      }
12974      if (isRegExp(separator)) {
12975        if (string.slice(end).search(separator)) {
12976          var match,
12977              substring = result;
12978
12979          if (!separator.global) {
12980            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
12981          }
12982          separator.lastIndex = 0;
12983          while ((match = separator.exec(substring))) {
12984            var newEnd = match.index;
12985          }
12986          result = result.slice(0, newEnd === undefined ? end : newEnd);
12987        }
12988      } else if (string.indexOf(separator, end) != end) {
12989        var index = result.lastIndexOf(separator);
12990        if (index > -1) {
12991          result = result.slice(0, index);
12992        }
12993      }
12994      return result + omission;
12995    }
12996
12997    /**
12998     * The inverse of `_.escape`; this method converts the HTML entities
12999     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to their
13000     * corresponding characters.
13001     *
13002     * **Note:** No other HTML entities are unescaped. To unescape additional HTML
13003     * entities use a third-party library like [_he_](https://mths.be/he).
13004     *
13005     * @static
13006     * @memberOf _
13007     * @category String
13008     * @param {string} [string=''] The string to unescape.
13009     * @returns {string} Returns the unescaped string.
13010     * @example
13011     *
13012     * _.unescape('fred, barney, &amp; pebbles');
13013     * // => 'fred, barney, & pebbles'
13014     */
13015    function unescape(string) {
vendor: 4,998 bytes, lines 13016-13178
13016      string = toString(string);
13017      return (string && reHasEscapedHtml.test(string))
13018        ? string.replace(reEscapedHtml, unescapeHtmlChar)
13019        : string;
13020    }
13021
13022    /**
13023     * Converts `string`, as space separated words, to upper case.
13024     *
13025     * @static
13026     * @memberOf _
13027     * @category String
13028     * @param {string} [string=''] The string to convert.
13029     * @returns {string} Returns the upper cased string.
13030     * @example
13031     *
13032     * _.upperCase('--foo-bar');
13033     * // => 'FOO BAR'
13034     *
13035     * _.upperCase('fooBar');
13036     * // => 'FOO BAR'
13037     *
13038     * _.upperCase('__foo_bar__');
13039     * // => 'FOO BAR'
13040     */
13041    var upperCase = createCompounder(function(result, word, index) {
13042      return result + (index ? ' ' : '') + word.toUpperCase();
13043    });
13044
13045    /**
13046     * Splits `string` into an array of its words.
13047     *
13048     * @static
13049     * @memberOf _
13050     * @category String
13051     * @param {string} [string=''] The string to inspect.
13052     * @param {RegExp|string} [pattern] The pattern to match words.
13053     * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
13054     * @returns {Array} Returns the words of `string`.
13055     * @example
13056     *
13057     * _.words('fred, barney, & pebbles');
13058     * // => ['fred', 'barney', 'pebbles']
13059     *
13060     * _.words('fred, barney, & pebbles', /[^, ]+/g);
13061     * // => ['fred', 'barney', '&', 'pebbles']
13062     */
13063    function words(string, pattern, guard) {
13064      string = toString(string);
13065      pattern = guard ? undefined : pattern;
13066
13067      if (pattern === undefined) {
13068        pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
13069      }
13070      return string.match(pattern) || [];
13071    }
13072
13073    /*------------------------------------------------------------------------*/
13074
13075    /**
13076     * Attempts to invoke `func`, returning either the result or the caught error
13077     * object. Any additional arguments are provided to `func` when it's invoked.
13078     *
13079     * @static
13080     * @memberOf _
13081     * @category Util
13082     * @param {Function} func The function to attempt.
13083     * @returns {*} Returns the `func` result or error object.
13084     * @example
13085     *
13086     * // Avoid throwing errors for invalid selectors.
13087     * var elements = _.attempt(function(selector) {
13088     *   return document.querySelectorAll(selector);
13089     * }, '>_>');
13090     *
13091     * if (_.isError(elements)) {
13092     *   elements = [];
13093     * }
13094     */
13095    var attempt = rest(function(func, args) {
13096      try {
13097        return apply(func, undefined, args);
13098      } catch (e) {
13099        return isObject(e) ? e : new Error(e);
13100      }
13101    });
13102
13103    /**
13104     * Binds methods of an object to the object itself, overwriting the existing
13105     * method.
13106     *
13107     * **Note:** This method doesn't set the "length" property of bound functions.
13108     *
13109     * @static
13110     * @memberOf _
13111     * @category Util
13112     * @param {Object} object The object to bind and assign the bound methods to.
13113     * @param {...(string|string[])} methodNames The object method names to bind,
13114     *  specified individually or in arrays.
13115     * @returns {Object} Returns `object`.
13116     * @example
13117     *
13118     * var view = {
13119     *   'label': 'docs',
13120     *   'onClick': function() {
13121     *     console.log('clicked ' + this.label);
13122     *   }
13123     * };
13124     *
13125     * _.bindAll(view, 'onClick');
13126     * jQuery(element).on('click', view.onClick);
13127     * // => logs 'clicked docs' when clicked
13128     */
13129    var bindAll = rest(function(object, methodNames) {
13130      arrayEach(baseFlatten(methodNames), function(key) {
13131        object[key] = bind(object[key], object);
13132      });
13133      return object;
13134    });
13135
13136    /**
13137     * Creates a function that iterates over `pairs` invoking the corresponding
13138     * function of the first predicate to return truthy. The predicate-function
13139     * pairs are invoked with the `this` binding and arguments of the created
13140     * function.
13141     *
13142     * @static
13143     * @memberOf _
13144     * @category Util
13145     * @param {Array} pairs The predicate-function pairs.
13146     * @returns {Function} Returns the new function.
13147     * @example
13148     *
13149     * var func = _.cond([
13150     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
13151     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
13152     *   [_.constant(true),                _.constant('no match')]
13153     * ]);
13154     *
13155     * func({ 'a': 1, 'b': 2 });
13156     * // => 'matches A'
13157     *
13158     * func({ 'a': 0, 'b': 1 });
13159     * // => 'matches B'
13160     *
13161     * func({ 'a': '1', 'b': '2' });
13162     * // => 'no match'
13163     */
13164    function cond(pairs) {
13165      var length = pairs ? pairs.length : 0,
13166          toIteratee = getIteratee();
13167
13168      pairs = !length ? [] : arrayMap(pairs, function(pair) {
13169        if (typeof pair[1] != 'function') {
13170          throw new TypeError(FUNC_ERROR_TEXT);
13171        }
13172        return [toIteratee(pair[0]), pair[1]];
13173      });
13174
13175      return rest(function(args) {
13176        var index = -1;
13177        while (++index < length) {
13178          var pair = pairs[index];
13179          if (apply(pair[0], this, args)) {
13180            return apply(pair[1], this, args);
13181          }
13182        }
13183      });
13184    }
13185
13186    /**
13187     * Creates a function that invokes the predicate properties of `source` with
13188     * the corresponding property values of a given object, returning `true` if
13189     * all predicates return truthy, else `false`.
13190     *
13191     * @static
13192     * @memberOf _
13193     * @category Util
13194     * @param {Object} source The object of property predicates to conform to.
13195     * @returns {Function} Returns the new function.
13196     * @example
13197     *
13198     * var users = [
13199     *   { 'user': 'barney', 'age': 36 },
13200     *   { 'user': 'fred',   'age': 40 }
13201     * ];
13202     *
13203     * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
13204     * // => [{ 'user': 'fred', 'age': 40 }]
13205     */
13206    function conforms(source) {
13207      return baseConforms(baseClone(source, true));
13208    }
13209
13210    /**
13211     * Creates a function that returns `value`.
13212     *
13213     * @static
13214     * @memberOf _
13215     * @category Util
13216     * @param {*} value The value to return from the new function.
13217     * @returns {Function} Returns the new function.
13218     * @example
13219     *
13220     * var object = { 'user': 'fred' };
13221     * var getter = _.constant(object);
13222     *
13223     * getter() === object;
13224     * // => true
13225     */
13226    function constant(value) {
13227      return function() {
13228        return value;
13229      };
13230    }
13231
13232    /**
13233     * Creates a function that returns the result of invoking the given functions
13234     * with the `this` binding of the created function, where each successive
13235     * invocation is supplied the return value of the previous.
13236     *
13237     * @static
13238     * @memberOf _
13239     * @category Util
13240     * @param {...(Function|Function[])} [funcs] Functions to invoke.
13241     * @returns {Function} Returns the new function.
13242     * @example
13243     *
13244     * function square(n) {
13245     *   return n * n;
13246     * }
13247     *
13248     * var addSquare = _.flow(_.add, square);
13249     * addSquare(1, 2);
13250     * // => 9
13251     */
13252    var flow = createFlow();
13253
13254    /**
13255     * This method is like `_.flow` except that it creates a function that
13256     * invokes the given functions from right to left.
13257     *
13258     * @static
13259     * @memberOf _
13260     * @category Util
13261     * @param {...(Function|Function[])} [funcs] Functions to invoke.
13262     * @returns {Function} Returns the new function.
13263     * @example
13264     *
13265     * function square(n) {
13266     *   return n * n;
13267     * }
13268     *
13269     * var addSquare = _.flowRight(square, _.add);
13270     * addSquare(1, 2);
13271     * // => 9
13272     */
13273    var flowRight = createFlow(true);
13274
13275    /**
13276     * This method returns the first argument given to it.
13277     *
13278     * @static
13279     * @memberOf _
13280     * @category Util
13281     * @param {*} value Any value.
13282     * @returns {*} Returns `value`.
13283     * @example
13284     *
13285     * var object = { 'user': 'fred' };
13286     *
13287     * _.identity(object) === object;
13288     * // => true
13289     */
13290    function identity(value) {
13291      return value;
13292    }
13293
13294    /**
13295     * Creates a function that invokes `func` with the arguments of the created
13296     * function. If `func` is a property name the created callback returns the
13297     * property value for a given element. If `func` is an object the created
13298     * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
13299     *
13300     * @static
13301     * @memberOf _
13302     * @category Util
13303     * @param {*} [func=_.identity] The value to convert to a callback.
13304     * @returns {Function} Returns the callback.
13305     * @example
13306     *
13307     * var users = [
13308     *   { 'user': 'barney', 'age': 36 },
13309     *   { 'user': 'fred',   'age': 40 }
13310     * ];
13311     *
13312     * // Create custom iteratee shorthands.
13313     * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
13314     *   var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
13315     *   return !p ? callback(func) : function(object) {
13316     *     return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
13317     *   };
13318     * });
13319     *
13320     * _.filter(users, 'age > 36');
13321     * // => [{ 'user': 'fred', 'age': 40 }]
13322     */
13323    function iteratee(func) {
13324      return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
13325    }
13326
13327    /**
13328     * Creates a function that performs a deep partial comparison between a given
13329     * object and `source`, returning `true` if the given object has equivalent
13330     * property values, else `false`.
13331     *
13332     * **Note:** This method supports comparing the same values as `_.isEqual`.
13333     *
13334     * @static
13335     * @memberOf _
13336     * @category Util
13337     * @param {Object} source The object of property values to match.
13338     * @returns {Function} Returns the new function.
13339     * @example
13340     *
13341     * var users = [
13342     *   { 'user': 'barney', 'age': 36, 'active': true },
13343     *   { 'user': 'fred',   'age': 40, 'active': false }
13344     * ];
13345     *
13346     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
13347     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
13348     */
13349    function matches(source) {
13350      return baseMatches(baseClone(source, true));
13351    }
13352
13353    /**
13354     * Creates a function that performs a deep partial comparison between the
13355     * value at `path` of a given object to `srcValue`, returning `true` if the
13356     * object value is equivalent, else `false`.
13357     *
13358     * **Note:** This method supports comparing the same values as `_.isEqual`.
13359     *
13360     * @static
13361     * @memberOf _
13362     * @category Util
13363     * @param {Array|string} path The path of the property to get.
13364     * @param {*} srcValue The value to match.
13365     * @returns {Function} Returns the new function.
13366     * @example
13367     *
13368     * var users = [
13369     *   { 'user': 'barney' },
13370     *   { 'user': 'fred' }
13371     * ];
13372     *
13373     * _.find(users, _.matchesProperty('user', 'fred'));
13374     * // => { 'user': 'fred' }
13375     */
13376    function matchesProperty(path, srcValue) {
13377      return baseMatchesProperty(path, baseClone(srcValue, true));
13378    }
13379
13380    /**
13381     * Creates a function that invokes the method at `path` of a given object.
13382     * Any additional arguments are provided to the invoked method.
13383     *
13384     * @static
13385     * @memberOf _
13386     * @category Util
13387     * @param {Array|string} path The path of the method to invoke.
13388     * @param {...*} [args] The arguments to invoke the method with.
13389     * @returns {Function} Returns the new function.
13390     * @example
13391     *
13392     * var objects = [
13393     *   { 'a': { 'b': { 'c': _.constant(2) } } },
13394     *   { 'a': { 'b': { 'c': _.constant(1) } } }
13395     * ];
13396     *
13397     * _.map(objects, _.method('a.b.c'));
13398     * // => [2, 1]
13399     *
13400     * _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c');
13401     * // => [1, 2]
13402     */
13403    var method = rest(function(path, args) {
13404      return function(object) {
13405        return baseInvoke(object, path, args);
13406      };
13407    });
13408
13409    /**
13410     * The opposite of `_.method`; this method creates a function that invokes
13411     * the method at a given path of `object`. Any additional arguments are
13412     * provided to the invoked method.
13413     *
13414     * @static
13415     * @memberOf _
13416     * @category Util
13417     * @param {Object} object The object to query.
13418     * @param {...*} [args] The arguments to invoke the method with.
13419     * @returns {Function} Returns the new function.
13420     * @example
13421     *
13422     * var array = _.times(3, _.constant),
13423     *     object = { 'a': array, 'b': array, 'c': array };
13424     *
13425     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
13426     * // => [2, 0]
13427     *
13428     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
13429     * // => [2, 0]
13430     */
13431    var methodOf = rest(function(object, args) {
13432      return function(path) {
13433        return baseInvoke(object, path, args);
13434      };
13435    });
13436
13437    /**
13438     * Adds all own enumerable function properties of a source object to the
13439     * destination object. If `object` is a function then methods are added to
13440     * its prototype as well.
13441     *
13442     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
13443     * avoid conflicts caused by modifying the original.
13444     *
13445     * @static
13446     * @memberOf _
13447     * @category Util
13448     * @param {Function|Object} [object=lodash] The destination object.
13449     * @param {Object} source The object of functions to add.
13450     * @param {Object} [options] The options object.
13451     * @param {boolean} [options.chain=true] Specify whether the functions added
13452     *  are chainable.
13453     * @returns {Function|Object} Returns `object`.
13454     * @example
13455     *
13456     * function vowels(string) {
13457     *   return _.filter(string, function(v) {
13458     *     return /[aeiou]/i.test(v);
13459     *   });
13460     * }
13461     *
13462     * _.mixin({ 'vowels': vowels });
13463     * _.vowels('fred');
13464     * // => ['e']
13465     *
vendor: 9,000 bytes, lines 13466-13799
13466     * _('fred').vowels().value();
13467     * // => ['e']
13468     *
13469     * _.mixin({ 'vowels': vowels }, { 'chain': false });
13470     * _('fred').vowels();
13471     * // => ['e']
13472     */
13473    function mixin(object, source, options) {
13474      var props = keys(source),
13475          methodNames = baseFunctions(source, props);
13476
13477      if (options == null &&
13478          !(isObject(source) && (methodNames.length || !props.length))) {
13479        options = source;
13480        source = object;
13481        object = this;
13482        methodNames = baseFunctions(source, keys(source));
13483      }
13484      var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
13485          isFunc = isFunction(object);
13486
13487      arrayEach(methodNames, function(methodName) {
13488        var func = source[methodName];
13489        object[methodName] = func;
13490        if (isFunc) {
13491          object.prototype[methodName] = function() {
13492            var chainAll = this.__chain__;
13493            if (chain || chainAll) {
13494              var result = object(this.__wrapped__),
13495                  actions = result.__actions__ = copyArray(this.__actions__);
13496
13497              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
13498              result.__chain__ = chainAll;
13499              return result;
13500            }
13501            return func.apply(object, arrayPush([this.value()], arguments));
13502          };
13503        }
13504      });
13505
13506      return object;
13507    }
13508
13509    /**
13510     * Reverts the `_` variable to its previous value and returns a reference to
13511     * the `lodash` function.
13512     *
13513     * @static
13514     * @memberOf _
13515     * @category Util
13516     * @returns {Function} Returns the `lodash` function.
13517     * @example
13518     *
13519     * var lodash = _.noConflict();
13520     */
13521    function noConflict() {
13522      if (root._ === this) {
13523        root._ = oldDash;
13524      }
13525      return this;
13526    }
13527
13528    /**
13529     * A no-operation function that returns `undefined` regardless of the
13530     * arguments it receives.
13531     *
13532     * @static
13533     * @memberOf _
13534     * @category Util
13535     * @example
13536     *
13537     * var object = { 'user': 'fred' };
13538     *
13539     * _.noop(object) === undefined;
13540     * // => true
13541     */
13542    function noop() {
13543      // No operation performed.
13544    }
13545
13546    /**
13547     * Creates a function that returns its nth argument.
13548     *
13549     * @static
13550     * @memberOf _
13551     * @category Util
13552     * @param {number} [n=0] The index of the argument to return.
13553     * @returns {Function} Returns the new function.
13554     * @example
13555     *
13556     * var func = _.nthArg(1);
13557     *
13558     * func('a', 'b', 'c');
13559     * // => 'b'
13560     */
13561    function nthArg(n) {
13562      n = toInteger(n);
13563      return function() {
13564        return arguments[n];
13565      };
13566    }
13567
13568    /**
13569     * Creates a function that invokes `iteratees` with the arguments provided
13570     * to the created function and returns their results.
13571     *
13572     * @static
13573     * @memberOf _
13574     * @category Util
13575     * @param {...(Function|Function[])} iteratees The iteratees to invoke.
13576     * @returns {Function} Returns the new function.
13577     * @example
13578     *
13579     * var func = _.over(Math.max, Math.min);
13580     *
13581     * func(1, 2, 3, 4);
13582     * // => [4, 1]
13583     */
13584    var over = createOver(arrayMap);
13585
13586    /**
13587     * Creates a function that checks if **all** of the `predicates` return
13588     * truthy when invoked with the arguments provided to the created function.
13589     *
13590     * @static
13591     * @memberOf _
13592     * @category Util
13593     * @param {...(Function|Function[])} predicates The predicates to check.
13594     * @returns {Function} Returns the new function.
13595     * @example
13596     *
13597     * var func = _.overEvery(Boolean, isFinite);
13598     *
13599     * func('1');
13600     * // => true
13601     *
13602     * func(null);
13603     * // => false
13604     *
13605     * func(NaN);
13606     * // => false
13607     */
13608    var overEvery = createOver(arrayEvery);
13609
13610    /**
13611     * Creates a function that checks if **any** of the `predicates` return
13612     * truthy when invoked with the arguments provided to the created function.
13613     *
13614     * @static
13615     * @memberOf _
13616     * @category Util
13617     * @param {...(Function|Function[])} predicates The predicates to check.
13618     * @returns {Function} Returns the new function.
13619     * @example
13620     *
13621     * var func = _.overSome(Boolean, isFinite);
13622     *
13623     * func('1');
13624     * // => true
13625     *
13626     * func(null);
13627     * // => true
13628     *
13629     * func(NaN);
13630     * // => false
13631     */
13632    var overSome = createOver(arraySome);
13633
13634    /**
13635     * Creates a function that returns the value at `path` of a given object.
13636     *
13637     * @static
13638     * @memberOf _
13639     * @category Util
13640     * @param {Array|string} path The path of the property to get.
13641     * @returns {Function} Returns the new function.
13642     * @example
13643     *
13644     * var objects = [
13645     *   { 'a': { 'b': { 'c': 2 } } },
13646     *   { 'a': { 'b': { 'c': 1 } } }
13647     * ];
13648     *
13649     * _.map(objects, _.property('a.b.c'));
13650     * // => [2, 1]
13651     *
13652     * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
13653     * // => [1, 2]
13654     */
13655    function property(path) {
13656      return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
13657    }
13658
13659    /**
13660     * The opposite of `_.property`; this method creates a function that returns
13661     * the value at a given path of `object`.
13662     *
13663     * @static
13664     * @memberOf _
13665     * @category Util
13666     * @param {Object} object The object to query.
13667     * @returns {Function} Returns the new function.
13668     * @example
13669     *
13670     * var array = [0, 1, 2],
13671     *     object = { 'a': array, 'b': array, 'c': array };
13672     *
13673     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
13674     * // => [2, 0]
13675     *
13676     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
13677     * // => [2, 0]
13678     */
13679    function propertyOf(object) {
13680      return function(path) {
13681        return object == null ? undefined : baseGet(object, path);
13682      };
13683    }
13684
13685    /**
13686     * Creates an array of numbers (positive and/or negative) progressing from
13687     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
13688     * `start` is specified without an `end` or `step`. If `end` is not specified
13689     * it's set to `start` with `start` then set to `0`.
13690     *
13691     * **Note:** JavaScript follows the IEEE-754 standard for resolving
13692     * floating-point values which can produce unexpected results.
13693     *
13694     * @static
13695     * @memberOf _
13696     * @category Util
13697     * @param {number} [start=0] The start of the range.
13698     * @param {number} end The end of the range.
13699     * @param {number} [step=1] The value to increment or decrement by.
13700     * @returns {Array} Returns the new array of numbers.
13701     * @example
13702     *
13703     * _.range(4);
13704     * // => [0, 1, 2, 3]
13705     *
13706     * _.range(-4);
13707     * // => [0, -1, -2, -3]
13708     *
13709     * _.range(1, 5);
13710     * // => [1, 2, 3, 4]
13711     *
13712     * _.range(0, 20, 5);
13713     * // => [0, 5, 10, 15]
13714     *
13715     * _.range(0, -4, -1);
13716     * // => [0, -1, -2, -3]
13717     *
13718     * _.range(1, 4, 0);
13719     * // => [1, 1, 1]
13720     *
13721     * _.range(0);
13722     * // => []
13723     */
13724    var range = createRange();
13725
13726    /**
13727     * This method is like `_.range` except that it populates values in
13728     * descending order.
13729     *
13730     * @static
13731     * @memberOf _
13732     * @category Util
13733     * @param {number} [start=0] The start of the range.
13734     * @param {number} end The end of the range.
13735     * @param {number} [step=1] The value to increment or decrement by.
13736     * @returns {Array} Returns the new array of numbers.
13737     * @example
13738     *
13739     * _.rangeRight(4);
13740     * // => [3, 2, 1, 0]
13741     *
13742     * _.rangeRight(-4);
13743     * // => [-3, -2, -1, 0]
13744     *
13745     * _.rangeRight(1, 5);
13746     * // => [4, 3, 2, 1]
13747     *
13748     * _.rangeRight(0, 20, 5);
13749     * // => [15, 10, 5, 0]
13750     *
13751     * _.rangeRight(0, -4, -1);
13752     * // => [-3, -2, -1, 0]
13753     *
13754     * _.rangeRight(1, 4, 0);
13755     * // => [1, 1, 1]
13756     *
13757     * _.rangeRight(0);
13758     * // => []
13759     */
13760    var rangeRight = createRange(true);
13761
13762    /**
13763     * Invokes the iteratee function `n` times, returning an array of the results
13764     * of each invocation. The iteratee is invoked with one argument; (index).
13765     *
13766     * @static
13767     * @memberOf _
13768     * @category Util
13769     * @param {number} n The number of times to invoke `iteratee`.
13770     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13771     * @returns {Array} Returns the array of results.
13772     * @example
13773     *
13774     * _.times(3, String);
13775     * // => ['0', '1', '2']
13776     *
13777     *  _.times(4, _.constant(true));
13778     * // => [true, true, true, true]
13779     */
13780    function times(n, iteratee) {
13781      n = toInteger(n);
13782      if (n < 1 || n > MAX_SAFE_INTEGER) {
13783        return [];
13784      }
13785      var index = MAX_ARRAY_LENGTH,
13786          length = nativeMin(n, MAX_ARRAY_LENGTH);
13787
13788      iteratee = toFunction(iteratee);
13789      n -= MAX_ARRAY_LENGTH;
13790
13791      var result = baseTimes(length, iteratee);
13792      while (++index < n) {
13793        iteratee(index);
13794      }
13795      return result;
13796    }
13797
13798    /**
13799     * Converts `value` to a property path array.
13800     *
13801     * @static
13802     * @memberOf _
13803     * @category Util
13804     * @param {*} value The value to convert.
13805     * @returns {Array} Returns the new property path array.
13806     * @example
13807     *
13808     * _.toPath('a.b.c');
13809     * // => ['a', 'b', 'c']
13810     *
13811     * _.toPath('a[0].b.c');
13812     * // => ['a', '0', 'b', 'c']
13813     *
13814     * var path = ['a', 'b', 'c'],
13815     *     newPath = _.toPath(path);
13816     *
13817     * console.log(newPath);
13818     * // => ['a', 'b', 'c']
13819     *
13820     * console.log(path === newPath);
13821     * // => false
13822     */
13823    function toPath(value) {
13824      return isArray(value) ? arrayMap(value, String) : stringToPath(value);
13825    }
13826
13827    /**
13828     * Generates a unique ID. If `prefix` is given the ID is appended to it.
13829     *
13830     * @static
13831     * @memberOf _
13832     * @category Util
13833     * @param {string} [prefix] The value to prefix the ID with.
13834     * @returns {string} Returns the unique ID.
13835     * @example
13836     *
13837     * _.uniqueId('contact_');
13838     * // => 'contact_104'
13839     *
13840     * _.uniqueId();
13841     * // => '105'
13842     */
13843    function uniqueId(prefix) {
13844      var id = ++idCounter;
13845      return toString(prefix) + id;
13846    }
13847
13848    /*------------------------------------------------------------------------*/
13849
13850    /**
13851     * Adds two numbers.
13852     *
13853     * @static
13854     * @memberOf _
13855     * @category Math
13856     * @param {number} augend The first number in an addition.
13857     * @param {number} addend The second number in an addition.
13858     * @returns {number} Returns the total.
13859     * @example
13860     *
13861     * _.add(6, 4);
13862     * // => 10
13863     */
13864    function add(augend, addend) {
13865      var result;
13866      if (augend === undefined && addend === undefined) {
13867        return 0;
13868      }
13869      if (augend !== undefined) {
13870        result = augend;
13871      }
13872      if (addend !== undefined) {
13873        result = result === undefined ? addend : (result + addend);
13874      }
13875      return result;
13876    }
13877
13878    /**
13879     * Computes `number` rounded up to `precision`.
13880     *
13881     * @static
13882     * @memberOf _
13883     * @category Math
13884     * @param {number} number The number to round up.
13885     * @param {number} [precision=0] The precision to round up to.
13886     * @returns {number} Returns the rounded up number.
13887     * @example
13888     *
13889     * _.ceil(4.006);
13890     * // => 5
13891     *
13892     * _.ceil(6.004, 2);
13893     * // => 6.01
13894     *
13895     * _.ceil(6040, -2);
13896     * // => 6100
13897     */
13898    var ceil = createRound('ceil');
13899
13900    /**
13901     * Computes `number` rounded down to `precision`.
13902     *
13903     * @static
13904     * @memberOf _
13905     * @category Math
13906     * @param {number} number The number to round down.
13907     * @param {number} [precision=0] The precision to round down to.
13908     * @returns {number} Returns the rounded down number.
13909     * @example
13910     *
13911     * _.floor(4.006);
13912     * // => 4
13913     *
13914     * _.floor(0.046, 2);
13915     * // => 0.04
13916     *
13917     * _.floor(4060, -2);
13918     * // => 4000
13919     */
13920    var floor = createRound('floor');
13921
13922    /**
13923     * Computes the maximum value of `array`. If `array` is empty or falsey
13924     * `undefined` is returned.
13925     *
13926     * @static
13927     * @memberOf _
13928     * @category Math
13929     * @param {Array} array The array to iterate over.
13930     * @returns {*} Returns the maximum value.
13931     * @example
13932     *
13933     * _.max([4, 2, 8, 6]);
13934     * // => 8
13935     *
13936     * _.max([]);
13937     * // => undefined
13938     */
13939    function max(array) {
13940      return (array && array.length)
13941        ? baseExtremum(array, identity, gt)
13942        : undefined;
13943    }
13944
13945    /**
13946     * This method is like `_.max` except that it accepts `iteratee` which is
13947     * invoked for each element in `array` to generate the criterion by which
13948     * the value is ranked. The iteratee is invoked with one argument: (value).
13949     *
13950     * @static
13951     * @memberOf _
13952     * @category Math
13953     * @param {Array} array The array to iterate over.
13954     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
13955     * @returns {*} Returns the maximum value.
13956     * @example
13957     *
13958     * var objects = [{ 'n': 1 }, { 'n': 2 }];
13959     *
13960     * _.maxBy(objects, function(o) { return o.n; });
13961     * // => { 'n': 2 }
13962     *
13963     * // The `_.property` iteratee shorthand.
13964     * _.maxBy(objects, 'n');
13965     * // => { 'n': 2 }
13966     */
13967    function maxBy(array, iteratee) {
13968      return (array && array.length)
13969        ? baseExtremum(array, getIteratee(iteratee), gt)
13970        : undefined;
13971    }
13972
13973    /**
13974     * Computes the mean of the values in `array`.
13975     *
13976     * @static
13977     * @memberOf _
13978     * @category Math
13979     * @param {Array} array The array to iterate over.
13980     * @returns {number} Returns the mean.
13981     * @example
13982     *
13983     * _.mean([4, 2, 8, 6]);
13984     * // => 5
13985     */
13986    function mean(array) {
13987      return sum(array) / (array ? array.length : 0);
13988    }
13989
13990    /**
13991     * Computes the minimum value of `array`. If `array` is empty or falsey
13992     * `undefined` is returned.
13993     *
13994     * @static
13995     * @memberOf _
13996     * @category Math
13997     * @param {Array} array The array to iterate over.
13998     * @returns {*} Returns the minimum value.
13999     * @example
14000     *
14001     * _.min([4, 2, 8, 6]);
14002     * // => 2
14003     *
14004     * _.min([]);
14005     * // => undefined
14006     */
14007    function min(array) {
14008      return (array && array.length)
14009        ? baseExtremum(array, identity, lt)
14010        : undefined;
14011    }
14012
14013    /**
14014     * This method is like `_.min` except that it accepts `iteratee` which is
14015     * invoked for each element in `array` to generate the criterion by which
14016     * the value is ranked. The iteratee is invoked with one argument: (value).
14017     *
14018     * @static
14019     * @memberOf _
14020     * @category Math
14021     * @param {Array} array The array to iterate over.
14022     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14023     * @returns {*} Returns the minimum value.
14024     * @example
14025     *
14026     * var objects = [{ 'n': 1 }, { 'n': 2 }];
14027     *
14028     * _.minBy(objects, function(o) { return o.n; });
14029     * // => { 'n': 1 }
14030     *
14031     * // The `_.property` iteratee shorthand.
14032     * _.minBy(objects, 'n');
14033     * // => { 'n': 1 }
14034     */
14035    function minBy(array, iteratee) {
14036      return (array && array.length)
14037        ? baseExtremum(array, getIteratee(iteratee), lt)
14038        : undefined;
14039    }
14040
14041    /**
14042     * Computes `number` rounded to `precision`.
14043     *
14044     * @static
14045     * @memberOf _
14046     * @category Math
14047     * @param {number} number The number to round.
14048     * @param {number} [precision=0] The precision to round to.
14049     * @returns {number} Returns the rounded number.
14050     * @example
14051     *
14052     * _.round(4.006);
14053     * // => 4
14054     *
14055     * _.round(4.006, 2);
14056     * // => 4.01
14057     *
14058     * _.round(4060, -2);
14059     * // => 4100
14060     */
14061    var round = createRound('round');
14062
14063    /**
14064     * Subtract two numbers.
14065     *
14066     * @static
14067     * @memberOf _
14068     * @category Math
14069     * @param {number} minuend The first number in a subtraction.
14070     * @param {number} subtrahend The second number in a subtraction.
14071     * @returns {number} Returns the difference.
14072     * @example
14073     *
14074     * _.subtract(6, 4);
14075     * // => 2
14076     */
14077    function subtract(minuend, subtrahend) {
14078      var result;
14079      if (minuend === undefined && subtrahend === undefined) {
14080        return 0;
14081      }
14082      if (minuend !== undefined) {
14083        result = minuend;
14084      }
14085      if (subtrahend !== undefined) {
14086        result = result === undefined ? subtrahend : (result - subtrahend);
14087      }
14088      return result;
14089    }
14090
14091    /**
14092     * Computes the sum of the values in `array`.
14093     *
14094     * @static
14095     * @memberOf _
14096     * @category Math
14097     * @param {Array} array The array to iterate over.
14098     * @returns {number} Returns the sum.
14099     * @example
14100     *
14101     * _.sum([4, 2, 8, 6]);
14102     * // => 20
14103     */
14104    function sum(array) {
14105      return (array && array.length)
14106        ? baseSum(array, identity)
14107        : 0;
14108    }
14109
14110    /**
14111     * This method is like `_.sum` except that it accepts `iteratee` which is
14112     * invoked for each element in `array` to generate the value to be summed.
14113     * The iteratee is invoked with one argument: (value).
14114     *
14115     * @static
14116     * @memberOf _
14117     * @category Math
14118     * @param {Array} array The array to iterate over.
14119     * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
14120     * @returns {number} Returns the sum.
14121     * @example
14122     *
14123     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
14124     *
14125     * _.sumBy(objects, function(o) { return o.n; });
14126     * // => 20
14127     *
14128     * // The `_.property` iteratee shorthand.
14129     * _.sumBy(objects, 'n');
14130     * // => 20
14131     */
14132    function sumBy(array, iteratee) {
14133      return (array && array.length)
14134        ? baseSum(array, getIteratee(iteratee))
14135        : 0;
14136    }
14137
14138    /*------------------------------------------------------------------------*/
14139
14140    // Ensure wrappers are instances of `baseLodash`.
14141    lodash.prototype = baseLodash.prototype;
14142
14143    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
14144    LodashWrapper.prototype.constructor = LodashWrapper;
14145
14146    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
14147    LazyWrapper.prototype.constructor = LazyWrapper;
14148
14149    // Avoid inheriting from `Object.prototype` when possible.
14150    Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
14151
14152    // Add functions to the `MapCache`.
14153    MapCache.prototype.clear = mapClear;
14154    MapCache.prototype['delete'] = mapDelete;
14155    MapCache.prototype.get = mapGet;
14156    MapCache.prototype.has = mapHas;
14157    MapCache.prototype.set = mapSet;
14158
14159    // Add functions to the `SetCache`.
14160    SetCache.prototype.push = cachePush;
14161
14162    // Add functions to the `Stack` cache.
14163    Stack.prototype.clear = stackClear;
14164    Stack.prototype['delete'] = stackDelete;
14165    Stack.prototype.get = stackGet;
14166    Stack.prototype.has = stackHas;
14167    Stack.prototype.set = stackSet;
14168
14169    // Assign cache to `_.memoize`.
14170    memoize.Cache = MapCache;
14171
14172    // Add functions that return wrapped values when chaining.
14173    lodash.after = after;
14174    lodash.ary = ary;
14175    lodash.assign = assign;
14176    lodash.assignIn = assignIn;
14177    lodash.assignInWith = assignInWith;
14178    lodash.assignWith = assignWith;
14179    lodash.at = at;
14180    lodash.before = before;
14181    lodash.bind = bind;
14182    lodash.bindAll = bindAll;
14183    lodash.bindKey = bindKey;
14184    lodash.chain = chain;
14185    lodash.chunk = chunk;
14186    lodash.compact = compact;
14187    lodash.concat = concat;
14188    lodash.cond = cond;
14189    lodash.conforms = conforms;
14190    lodash.constant = constant;
14191    lodash.countBy = countBy;
14192    lodash.create = create;
14193    lodash.curry = curry;
14194    lodash.curryRight = curryRight;
14195    lodash.debounce = debounce;
14196    lodash.defaults = defaults;
14197    lodash.defaultsDeep = defaultsDeep;
14198    lodash.defer = defer;
14199    lodash.delay = delay;
14200    lodash.difference = difference;
14201    lodash.differenceBy = differenceBy;
14202    lodash.differenceWith = differenceWith;
14203    lodash.drop = drop;
14204    lodash.dropRight = dropRight;
14205    lodash.dropRightWhile = dropRightWhile;
14206    lodash.dropWhile = dropWhile;
14207    lodash.fill = fill;
14208    lodash.filter = filter;
14209    lodash.flatMap = flatMap;
14210    lodash.flatten = flatten;
14211    lodash.flattenDeep = flattenDeep;
14212    lodash.flip = flip;
14213    lodash.flow = flow;
14214    lodash.flowRight = flowRight;
14215    lodash.fromPairs = fromPairs;
14216    lodash.functions = functions;
14217    lodash.functionsIn = functionsIn;
14218    lodash.groupBy = groupBy;
14219    lodash.initial = initial;
14220    lodash.intersection = intersection;
14221    lodash.intersectionBy = intersectionBy;
14222    lodash.intersectionWith = intersectionWith;
14223    lodash.invert = invert;
14224    lodash.invertBy = invertBy;
14225    lodash.invokeMap = invokeMap;
14226    lodash.iteratee = iteratee;
14227    lodash.keyBy = keyBy;
14228    lodash.keys = keys;
14229    lodash.keysIn = keysIn;
14230    lodash.map = map;
14231    lodash.mapKeys = mapKeys;
14232    lodash.mapValues = mapValues;
14233    lodash.matches = matches;
14234    lodash.matchesProperty = matchesProperty;
14235    lodash.memoize = memoize;
14236    lodash.merge = merge;
14237    lodash.mergeWith = mergeWith;
14238    lodash.method = method;
14239    lodash.methodOf = methodOf;
14240    lodash.mixin = mixin;
14241    lodash.negate = negate;
14242    lodash.nthArg = nthArg;
14243    lodash.omit = omit;
14244    lodash.omitBy = omitBy;
14245    lodash.once = once;
14246    lodash.orderBy = orderBy;
14247    lodash.over = over;
14248    lodash.overArgs = overArgs;
14249    lodash.overEvery = overEvery;
14250    lodash.overSome = overSome;
14251    lodash.partial = partial;
14252    lodash.partialRight = partialRight;
14253    lodash.partition = partition;
14254    lodash.pick = pick;
14255    lodash.pickBy = pickBy;
14256    lodash.property = property;
14257    lodash.propertyOf = propertyOf;
14258    lodash.pull = pull;
14259    lodash.pullAll = pullAll;
14260    lodash.pullAllBy = pullAllBy;
14261    lodash.pullAt = pullAt;
14262    lodash.range = range;
14263    lodash.rangeRight = rangeRight;
14264    lodash.rearg = rearg;
14265    lodash.reject = reject;
14266    lodash.remove = remove;
14267    lodash.rest = rest;
14268    lodash.reverse = reverse;
14269    lodash.sampleSize = sampleSize;
14270    lodash.set = set;
14271    lodash.setWith = setWith;
14272    lodash.shuffle = shuffle;
14273    lodash.slice = slice;
14274    lodash.sortBy = sortBy;
14275    lodash.sortedUniq = sortedUniq;
14276    lodash.sortedUniqBy = sortedUniqBy;
14277    lodash.split = split;
14278    lodash.spread = spread;
14279    lodash.tail = tail;
14280    lodash.take = take;
14281    lodash.takeRight = takeRight;
14282    lodash.takeRightWhile = takeRightWhile;
14283    lodash.takeWhile = takeWhile;
14284    lodash.tap = tap;
14285    lodash.throttle = throttle;
14286    lodash.thru = thru;
14287    lodash.toArray = toArray;
14288    lodash.toPairs = toPairs;
14289    lodash.toPairsIn = toPairsIn;
14290    lodash.toPath = toPath;
14291    lodash.toPlainObject = toPlainObject;
14292    lodash.transform = transform;
14293    lodash.unary = unary;
14294    lodash.union = union;
14295    lodash.unionBy = unionBy;
14296    lodash.unionWith = unionWith;
14297    lodash.uniq = uniq;
14298    lodash.uniqBy = uniqBy;
14299    lodash.uniqWith = uniqWith;
14300    lodash.unset = unset;
14301    lodash.unzip = unzip;
14302    lodash.unzipWith = unzipWith;
14303    lodash.values = values;
14304    lodash.valuesIn = valuesIn;
14305    lodash.without = without;
14306    lodash.words = words;
14307    lodash.wrap = wrap;
14308    lodash.xor = xor;
14309    lodash.xorBy = xorBy;
14310    lodash.xorWith = xorWith;
14311    lodash.zip = zip;
14312    lodash.zipObject = zipObject;
14313    lodash.zipObjectDeep = zipObjectDeep;
14314    lodash.zipWith = zipWith;
14315
14316    // Add aliases.
14317    lodash.extend = assignIn;
14318    lodash.extendWith = assignInWith;
14319
14320    // Add functions to `lodash.prototype`.
14321    mixin(lodash, lodash);
14322
14323    /*------------------------------------------------------------------------*/
14324
14325    // Add functions that return unwrapped values when chaining.
14326    lodash.add = add;
14327    lodash.attempt = attempt;
14328    lodash.camelCase = camelCase;
14329    lodash.capitalize = capitalize;
14330    lodash.ceil = ceil;
14331    lodash.clamp = clamp;
14332    lodash.clone = clone;
14333    lodash.cloneDeep = cloneDeep;
14334    lodash.cloneDeepWith = cloneDeepWith;
14335    lodash.cloneWith = cloneWith;
14336    lodash.deburr = deburr;
14337    lodash.endsWith = endsWith;
14338    lodash.eq = eq;
14339    lodash.escape = escape;
14340    lodash.escapeRegExp = escapeRegExp;
14341    lodash.every = every;
14342    lodash.find = find;
14343    lodash.findIndex = findIndex;
14344    lodash.findKey = findKey;
14345    lodash.findLast = findLast;
14346    lodash.findLastIndex = findLastIndex;
14347    lodash.findLastKey = findLastKey;
14348    lodash.floor = floor;
vendor: 4,687 bytes, lines 14349-14499
14349    lodash.forEach = forEach;
14350    lodash.forEachRight = forEachRight;
14351    lodash.forIn = forIn;
14352    lodash.forInRight = forInRight;
14353    lodash.forOwn = forOwn;
14354    lodash.forOwnRight = forOwnRight;
14355    lodash.get = get;
14356    lodash.gt = gt;
14357    lodash.gte = gte;
14358    lodash.has = has;
14359    lodash.hasIn = hasIn;
14360    lodash.head = head;
14361    lodash.identity = identity;
14362    lodash.includes = includes;
14363    lodash.indexOf = indexOf;
14364    lodash.inRange = inRange;
14365    lodash.invoke = invoke;
14366    lodash.isArguments = isArguments;
14367    lodash.isArray = isArray;
14368    lodash.isArrayBuffer = isArrayBuffer;
14369    lodash.isArrayLike = isArrayLike;
14370    lodash.isArrayLikeObject = isArrayLikeObject;
14371    lodash.isBoolean = isBoolean;
14372    lodash.isBuffer = isBuffer;
14373    lodash.isDate = isDate;
14374    lodash.isElement = isElement;
14375    lodash.isEmpty = isEmpty;
14376    lodash.isEqual = isEqual;
14377    lodash.isEqualWith = isEqualWith;
14378    lodash.isError = isError;
14379    lodash.isFinite = isFinite;
14380    lodash.isFunction = isFunction;
14381    lodash.isInteger = isInteger;
14382    lodash.isLength = isLength;
14383    lodash.isMap = isMap;
14384    lodash.isMatch = isMatch;
14385    lodash.isMatchWith = isMatchWith;
14386    lodash.isNaN = isNaN;
14387    lodash.isNative = isNative;
14388    lodash.isNil = isNil;
14389    lodash.isNull = isNull;
14390    lodash.isNumber = isNumber;
14391    lodash.isObject = isObject;
14392    lodash.isObjectLike = isObjectLike;
14393    lodash.isPlainObject = isPlainObject;
14394    lodash.isRegExp = isRegExp;
14395    lodash.isSafeInteger = isSafeInteger;
14396    lodash.isSet = isSet;
14397    lodash.isString = isString;
14398    lodash.isSymbol = isSymbol;
14399    lodash.isTypedArray = isTypedArray;
14400    lodash.isUndefined = isUndefined;
14401    lodash.isWeakMap = isWeakMap;
14402    lodash.isWeakSet = isWeakSet;
14403    lodash.join = join;
14404    lodash.kebabCase = kebabCase;
14405    lodash.last = last;
14406    lodash.lastIndexOf = lastIndexOf;
14407    lodash.lowerCase = lowerCase;
14408    lodash.lowerFirst = lowerFirst;
14409    lodash.lt = lt;
14410    lodash.lte = lte;
14411    lodash.max = max;
14412    lodash.maxBy = maxBy;
14413    lodash.mean = mean;
14414    lodash.min = min;
14415    lodash.minBy = minBy;
14416    lodash.noConflict = noConflict;
14417    lodash.noop = noop;
14418    lodash.now = now;
14419    lodash.pad = pad;
14420    lodash.padEnd = padEnd;
14421    lodash.padStart = padStart;
14422    lodash.parseInt = parseInt;
14423    lodash.random = random;
14424    lodash.reduce = reduce;
14425    lodash.reduceRight = reduceRight;
14426    lodash.repeat = repeat;
14427    lodash.replace = replace;
14428    lodash.result = result;
14429    lodash.round = round;
14430    lodash.runInContext = runInContext;
14431    lodash.sample = sample;
14432    lodash.size = size;
14433    lodash.snakeCase = snakeCase;
14434    lodash.some = some;
14435    lodash.sortedIndex = sortedIndex;
14436    lodash.sortedIndexBy = sortedIndexBy;
14437    lodash.sortedIndexOf = sortedIndexOf;
14438    lodash.sortedLastIndex = sortedLastIndex;
14439    lodash.sortedLastIndexBy = sortedLastIndexBy;
14440    lodash.sortedLastIndexOf = sortedLastIndexOf;
14441    lodash.startCase = startCase;
14442    lodash.startsWith = startsWith;
14443    lodash.subtract = subtract;
14444    lodash.sum = sum;
14445    lodash.sumBy = sumBy;
14446    lodash.template = template;
14447    lodash.times = times;
14448    lodash.toInteger = toInteger;
14449    lodash.toLength = toLength;
14450    lodash.toLower = toLower;
14451    lodash.toNumber = toNumber;
14452    lodash.toSafeInteger = toSafeInteger;
14453    lodash.toString = toString;
14454    lodash.toUpper = toUpper;
14455    lodash.trim = trim;
14456    lodash.trimEnd = trimEnd;
14457    lodash.trimStart = trimStart;
14458    lodash.truncate = truncate;
14459    lodash.unescape = unescape;
14460    lodash.uniqueId = uniqueId;
14461    lodash.upperCase = upperCase;
14462    lodash.upperFirst = upperFirst;
14463
14464    // Add aliases.
14465    lodash.each = forEach;
14466    lodash.eachRight = forEachRight;
14467    lodash.first = head;
14468
14469    mixin(lodash, (function() {
14470      var source = {};
14471      baseForOwn(lodash, function(func, methodName) {
14472        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
14473          source[methodName] = func;
14474        }
14475      });
14476      return source;
14477    }()), { 'chain': false });
14478
14479    /*------------------------------------------------------------------------*/
14480
14481    /**
14482     * The semantic version number.
14483     *
14484     * @static
14485     * @memberOf _
14486     * @type string
14487     */
14488    lodash.VERSION = VERSION;
14489
14490    // Assign default placeholders.
14491    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
14492      lodash[methodName].placeholder = lodash;
14493    });
14494
14495    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
14496    arrayEach(['drop', 'take'], function(methodName, index) {
14497      LazyWrapper.prototype[methodName] = function(n) {
14498        var filtered = this.__filtered__;
14499        if (filtered && !index) {
vendor: 4,423 bytes, lines 14500-14628
14500          return new LazyWrapper(this);
14501        }
14502        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
14503
14504        var result = this.clone();
14505        if (filtered) {
14506          result.__takeCount__ = nativeMin(n, result.__takeCount__);
14507        } else {
14508          result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') });
14509        }
14510        return result;
14511      };
14512
14513      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
14514        return this.reverse()[methodName](n).reverse();
14515      };
14516    });
14517
14518    // Add `LazyWrapper` methods that accept an `iteratee` value.
14519    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
14520      var type = index + 1,
14521          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
14522
14523      LazyWrapper.prototype[methodName] = function(iteratee) {
14524        var result = this.clone();
14525        result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type });
14526        result.__filtered__ = result.__filtered__ || isFilter;
14527        return result;
14528      };
14529    });
14530
14531    // Add `LazyWrapper` methods for `_.head` and `_.last`.
14532    arrayEach(['head', 'last'], function(methodName, index) {
14533      var takeName = 'take' + (index ? 'Right' : '');
14534
14535      LazyWrapper.prototype[methodName] = function() {
14536        return this[takeName](1).value()[0];
14537      };
14538    });
14539
14540    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
14541    arrayEach(['initial', 'tail'], function(methodName, index) {
14542      var dropName = 'drop' + (index ? '' : 'Right');
14543
14544      LazyWrapper.prototype[methodName] = function() {
14545        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
14546      };
14547    });
14548
14549    LazyWrapper.prototype.compact = function() {
14550      return this.filter(identity);
14551    };
14552
14553    LazyWrapper.prototype.find = function(predicate) {
14554      return this.filter(predicate).head();
14555    };
14556
14557    LazyWrapper.prototype.findLast = function(predicate) {
14558      return this.reverse().find(predicate);
14559    };
14560
14561    LazyWrapper.prototype.invokeMap = rest(function(path, args) {
14562      if (typeof path == 'function') {
14563        return new LazyWrapper(this);
14564      }
14565      return this.map(function(value) {
14566        return baseInvoke(value, path, args);
14567      });
14568    });
14569
14570    LazyWrapper.prototype.reject = function(predicate) {
14571      predicate = getIteratee(predicate, 3);
14572      return this.filter(function(value) {
14573        return !predicate(value);
14574      });
14575    };
14576
14577    LazyWrapper.prototype.slice = function(start, end) {
14578      start = toInteger(start);
14579
14580      var result = this;
14581      if (result.__filtered__ && (start > 0 || end < 0)) {
14582        return new LazyWrapper(result);
14583      }
14584      if (start < 0) {
14585        result = result.takeRight(-start);
14586      } else if (start) {
14587        result = result.drop(start);
14588      }
14589      if (end !== undefined) {
14590        end = toInteger(end);
14591        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
14592      }
14593      return result;
14594    };
14595
14596    LazyWrapper.prototype.takeRightWhile = function(predicate) {
14597      return this.reverse().takeWhile(predicate).reverse();
14598    };
14599
14600    LazyWrapper.prototype.toArray = function() {
14601      return this.take(MAX_ARRAY_LENGTH);
14602    };
14603
14604    // Add `LazyWrapper` methods to `lodash.prototype`.
14605    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14606      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
14607          isTaker = /^(?:head|last)$/.test(methodName),
14608          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
14609          retUnwrapped = isTaker || /^find/.test(methodName);
14610
14611      if (!lodashFunc) {
14612        return;
14613      }
14614      lodash.prototype[methodName] = function() {
14615        var value = this.__wrapped__,
14616            args = isTaker ? [1] : arguments,
14617            isLazy = value instanceof LazyWrapper,
14618            iteratee = args[0],
14619            useLazy = isLazy || isArray(value);
14620
14621        var interceptor = function(value) {
14622          var result = lodashFunc.apply(lodash, arrayPush([value], args));
14623          return (isTaker && chainAll) ? result[0] : result;
14624        };
14625
14626        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
14627          // Avoid lazy use if the iteratee has a "length" value other than `1`.
14628          isLazy = useLazy = false;
vendor: 3,058 bytes, lines 14629-14709
14629        }
14630        var chainAll = this.__chain__,
14631            isHybrid = !!this.__actions__.length,
14632            isUnwrapped = retUnwrapped && !chainAll,
14633            onlyLazy = isLazy && !isHybrid;
14634
14635        if (!retUnwrapped && useLazy) {
14636          value = onlyLazy ? value : new LazyWrapper(this);
14637          var result = func.apply(value, args);
14638          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
14639          return new LodashWrapper(result, chainAll);
14640        }
14641        if (isUnwrapped && onlyLazy) {
14642          return func.apply(this, args);
14643        }
14644        result = this.thru(interceptor);
14645        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
14646      };
14647    });
14648
14649    // Add `Array` and `String` methods to `lodash.prototype`.
14650    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
14651      var func = arrayProto[methodName],
14652          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
14653          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
14654
14655      lodash.prototype[methodName] = function() {
14656        var args = arguments;
14657        if (retUnwrapped && !this.__chain__) {
14658          return func.apply(this.value(), args);
14659        }
14660        return this[chainName](function(value) {
14661          return func.apply(value, args);
14662        });
14663      };
14664    });
14665
14666    // Map minified function names to their real names.
14667    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
14668      var lodashFunc = lodash[methodName];
14669      if (lodashFunc) {
14670        var key = (lodashFunc.name + ''),
14671            names = realNames[key] || (realNames[key] = []);
14672
14673        names.push({ 'name': methodName, 'func': lodashFunc });
14674      }
14675    });
14676
14677    realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }];
14678
14679    // Add functions to the lazy wrapper.
14680    LazyWrapper.prototype.clone = lazyClone;
14681    LazyWrapper.prototype.reverse = lazyReverse;
14682    LazyWrapper.prototype.value = lazyValue;
14683
14684    // Add chaining functions to the `lodash` wrapper.
14685    lodash.prototype.at = wrapperAt;
14686    lodash.prototype.chain = wrapperChain;
14687    lodash.prototype.commit = wrapperCommit;
14688    lodash.prototype.flatMap = wrapperFlatMap;
14689    lodash.prototype.next = wrapperNext;
14690    lodash.prototype.plant = wrapperPlant;
14691    lodash.prototype.reverse = wrapperReverse;
14692    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
14693
14694    if (iteratorSymbol) {
14695      lodash.prototype[iteratorSymbol] = wrapperToIterator;
14696    }
14697    return lodash;
14698  }
14699
14700  /*--------------------------------------------------------------------------*/
14701
14702  // Export lodash.
14703  var _ = runInContext();
14704
14705  // Expose lodash on the free variable `window` or `self` when available. This
14706  // prevents errors in cases where lodash is loaded by a script tag in the presence
14707  // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
14708  (freeWindow || freeSelf || {})._ = _;
14709
14710  // Some AMD build optimizers like r.js check for condition patterns like the following:
14711  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
14712    // Define as an anonymous module so, through path mapping, it can be
14713    // referenced as the "underscore" module.
14714    define(function() {
14715      return _;
14716    });
14717  }
14718  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
14719  else if (freeExports && freeModule) {
14720    // Export for Node.js.
14721    if (moduleExports) {
14722      (freeModule.exports = _)._ = _;
14723    }
14724    // Export for CommonJS support.
14725    freeExports._ = _;
14726  }
14727  else {
14728    // Export to the global object.
14729    root._ = _;
14730  }
14731}.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.