PageSourceSearch

https://newground.net/assets/frameworks/themes/fresnel/3.0.0/assets/dist/js/main-3.0.0.js

js newground.net collected 2026-10-04 02:13:17 UTC 943,781 bytes, 28,388 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2(function (global){(function (){
3/**
4 * @license
5 * Lodash <https://lodash.com/>
6 * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
7 * Released under MIT license <https://lodash.com/license>
8 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
9 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
10 */
11;(function() {
12
13  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
14  var undefined
vendor: 12,195 bytes, lines 14-317
14;
15
16  /** Used as the semantic version number. */
17  var VERSION = '4.17.21';
18
19  /** Used as the size to enable large array optimizations. */
20  var LARGE_ARRAY_SIZE = 200;
21
22  /** Error message constants. */
23  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
24      FUNC_ERROR_TEXT = 'Expected a function',
25      INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
26
27  /** Used to stand-in for `undefined` hash values. */
28  var HASH_UNDEFINED = '__lodash_hash_undefined__';
29
30  /** Used as the maximum memoize cache size. */
31  var MAX_MEMOIZE_SIZE = 500;
32
33  /** Used as the internal argument placeholder. */
34  var PLACEHOLDER = '__lodash_placeholder__';
35
36  /** Used to compose bitmasks for cloning. */
37  var CLONE_DEEP_FLAG = 1,
38      CLONE_FLAT_FLAG = 2,
39      CLONE_SYMBOLS_FLAG = 4;
40
41  /** Used to compose bitmasks for value comparisons. */
42  var COMPARE_PARTIAL_FLAG = 1,
43      COMPARE_UNORDERED_FLAG = 2;
44
45  /** Used to compose bitmasks for function metadata. */
46  var WRAP_BIND_FLAG = 1,
47      WRAP_BIND_KEY_FLAG = 2,
48      WRAP_CURRY_BOUND_FLAG = 4,
49      WRAP_CURRY_FLAG = 8,
50      WRAP_CURRY_RIGHT_FLAG = 16,
51      WRAP_PARTIAL_FLAG = 32,
52      WRAP_PARTIAL_RIGHT_FLAG = 64,
53      WRAP_ARY_FLAG = 128,
54      WRAP_REARG_FLAG = 256,
55      WRAP_FLIP_FLAG = 512;
56
57  /** Used as default options for `_.truncate`. */
58  var DEFAULT_TRUNC_LENGTH = 30,
59      DEFAULT_TRUNC_OMISSION = '...';
60
61  /** Used to detect hot functions by number of calls within a span of milliseconds. */
62  var HOT_COUNT = 800,
63      HOT_SPAN = 16;
64
65  /** Used to indicate the type of lazy iteratees. */
66  var LAZY_FILTER_FLAG = 1,
67      LAZY_MAP_FLAG = 2,
68      LAZY_WHILE_FLAG = 3;
69
70  /** Used as references for various `Number` constants. */
71  var INFINITY = 1 / 0,
72      MAX_SAFE_INTEGER = 9007199254740991,
73      MAX_INTEGER = 1.7976931348623157e+308,
74      NAN = 0 / 0;
75
76  /** Used as references for the maximum length and index of an array. */
77  var MAX_ARRAY_LENGTH = 4294967295,
78      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
79      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
80
81  /** Used to associate wrap methods with their bit flags. */
82  var wrapFlags = [
83    ['ary', WRAP_ARY_FLAG],
84    ['bind', WRAP_BIND_FLAG],
85    ['bindKey', WRAP_BIND_KEY_FLAG],
86    ['curry', WRAP_CURRY_FLAG],
87    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
88    ['flip', WRAP_FLIP_FLAG],
89    ['partial', WRAP_PARTIAL_FLAG],
90    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
91    ['rearg', WRAP_REARG_FLAG]
92  ];
93
94  /** `Object#toString` result references. */
95  var argsTag = '[object Arguments]',
96      arrayTag = '[object Array]',
97      asyncTag = '[object AsyncFunction]',
98      boolTag = '[object Boolean]',
99      dateTag = '[object Date]',
100      domExcTag = '[object DOMException]',
101      errorTag = '[object Error]',
102      funcTag = '[object Function]',
103      genTag = '[object GeneratorFunction]',
104      mapTag = '[object Map]',
105      numberTag = '[object Number]',
106      nullTag = '[object Null]',
107      objectTag = '[object Object]',
108      promiseTag = '[object Promise]',
109      proxyTag = '[object Proxy]',
110      regexpTag = '[object RegExp]',
111      setTag = '[object Set]',
112      stringTag = '[object String]',
113      symbolTag = '[object Symbol]',
114      undefinedTag = '[object Undefined]',
115      weakMapTag = '[object WeakMap]',
116      weakSetTag = '[object WeakSet]';
117
118  var arrayBufferTag = '[object ArrayBuffer]',
119      dataViewTag = '[object DataView]',
120      float32Tag = '[object Float32Array]',
121      float64Tag = '[object Float64Array]',
122      int8Tag = '[object Int8Array]',
123      int16Tag = '[object Int16Array]',
124      int32Tag = '[object Int32Array]',
125      uint8Tag = '[object Uint8Array]',
126      uint8ClampedTag = '[object Uint8ClampedArray]',
127      uint16Tag = '[object Uint16Array]',
128      uint32Tag = '[object Uint32Array]';
129
130  /** Used to match empty string literals in compiled template source. */
131  var reEmptyStringLeading = /\b__p \+= '';/g,
132      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
133      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
134
135  /** Used to match HTML entities and HTML characters. */
136  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
137      reUnescapedHtml = /[&<>"']/g,
138      reHasEscapedHtml = RegExp(reEscapedHtml.source),
139      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
140
141  /** Used to match template delimiters. */
142  var reEscape = /<%-([\s\S]+?)%>/g,
143      reEvaluate = /<%([\s\S]+?)%>/g,
144      reInterpolate = /<%=([\s\S]+?)%>/g;
145
146  /** Used to match property names within property paths. */
147  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
148      reIsPlainProp = /^\w*$/,
149      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
150
151  /**
152   * Used to match `RegExp`
153   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
154   */
155  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
156      reHasRegExpChar = RegExp(reRegExpChar.source);
157
158  /** Used to match leading whitespace. */
159  var reTrimStart = /^\s+/;
160
161  /** Used to match a single whitespace character. */
162  var reWhitespace = /\s/;
163
164  /** Used to match wrap detail comments. */
165  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
166      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
167      reSplitDetails = /,? & /;
168
169  /** Used to match words composed of alphanumeric characters. */
170  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
171
172  /**
173   * Used to validate the `validate` option in `_.template` variable.
174   *
175   * Forbids characters which could potentially change the meaning of the function argument definition:
176   * - "()," (modification of function parameters)
177   * - "=" (default value)
178   * - "[]{}" (destructuring of function parameters)
179   * - "/" (beginning of a comment)
180   * - whitespace
181   */
182  var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
183
184  /** Used to match backslashes in property paths. */
185  var reEscapeChar = /\\(\\)?/g;
186
187  /**
188   * Used to match
189   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
190   */
191  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
192
193  /** Used to match `RegExp` flags from their coerced string values. */
194  var reFlags = /\w*$/;
195
196  /** Used to detect bad signed hexadecimal string values. */
197  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
198
199  /** Used to detect binary string values. */
200  var reIsBinary = /^0b[01]+$/i;
201
202  /** Used to detect host constructors (Safari). */
203  var reIsHostCtor = /^\[object .+?Constructor\]$/;
204
205  /** Used to detect octal string values. */
206  var reIsOctal = /^0o[0-7]+$/i;
207
208  /** Used to detect unsigned integer values. */
209  var reIsUint = /^(?:0|[1-9]\d*)$/;
210
211  /** Used to match Latin Unicode letters (excluding mathematical operators). */
212  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
213
214  /** Used to ensure capturing order of template delimiters. */
215  var reNoMatch = /($^)/;
216
217  /** Used to match unescaped characters in compiled string literals. */
218  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
219
220  /** Used to compose unicode character classes. */
221  var rsAstralRange = '\\ud800-\\udfff',
222      rsComboMarksRange = '\\u0300-\\u036f',
223      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
224      rsComboSymbolsRange = '\\u20d0-\\u20ff',
225      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
226      rsDingbatRange = '\\u2700-\\u27bf',
227      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
228      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
229      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
230      rsPunctuationRange = '\\u2000-\\u206f',
231      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',
232      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
233      rsVarRange = '\\ufe0e\\ufe0f',
234      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
235
236  /** Used to compose unicode capture groups. */
237  var rsApos = "['\u2019]",
238      rsAstral = '[' + rsAstralRange + ']',
239      rsBreak = '[' + rsBreakRange + ']',
240      rsCombo = '[' + rsComboRange + ']',
241      rsDigits = '\\d+',
242      rsDingbat = '[' + rsDingbatRange + ']',
243      rsLower = '[' + rsLowerRange + ']',
244      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
245      rsFitz = '\\ud83c[\\udffb-\\udfff]',
246      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
247      rsNonAstral = '[^' + rsAstralRange + ']',
248      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
249      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
250      rsUpper = '[' + rsUpperRange + ']',
251      rsZWJ = '\\u200d';
252
253  /** Used to compose unicode regexes. */
254  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
255      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
256      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
257      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
258      reOptMod = rsModifier + '?',
259      rsOptVar = '[' + rsVarRange + ']?',
260      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
261      rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
262      rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
263      rsSeq = rsOptVar + reOptMod + rsOptJoin,
264      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
265      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
266
267  /** Used to match apostrophes. */
268  var reApos = RegExp(rsApos, 'g');
269
270  /**
271   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
272   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
273   */
274  var reComboMark = RegExp(rsCombo, 'g');
275
276  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
277  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
278
279  /** Used to match complex or compound words. */
280  var reUnicodeWord = RegExp([
281    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
282    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
283    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
284    rsUpper + '+' + rsOptContrUpper,
285    rsOrdUpper,
286    rsOrdLower,
287    rsDigits,
288    rsEmoji
289  ].join('|'), 'g');
290
291  /** 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/). */
292  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
293
294  /** Used to detect strings that need a more robust regexp to match words. */
295  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
296
297  /** Used to assign default `context` object properties. */
298  var contextProps = [
299    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
300    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
301    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
302    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
303    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
304  ];
305
306  /** Used to make template sourceURLs easier to identify. */
307  var templateCounter = -1;
308
309  /** Used to identify `toStringTag` values of typed arrays. */
310  var typedArrayTags = {};
311  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
312  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
313  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
314  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
315  typedArrayTags[uint32Tag] = true;
316  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
317  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
vendor: 5,923 bytes, lines 318-452
318  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
319  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
320  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
321  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
322  typedArrayTags[setTag] = typedArrayTags[stringTag] =
323  typedArrayTags[weakMapTag] = false;
324
325  /** Used to identify `toStringTag` values supported by `_.clone`. */
326  var cloneableTags = {};
327  cloneableTags[argsTag] = cloneableTags[arrayTag] =
328  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
329  cloneableTags[boolTag] = cloneableTags[dateTag] =
330  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
331  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
332  cloneableTags[int32Tag] = cloneableTags[mapTag] =
333  cloneableTags[numberTag] = cloneableTags[objectTag] =
334  cloneableTags[regexpTag] = cloneableTags[setTag] =
335  cloneableTags[stringTag] = cloneableTags[symbolTag] =
336  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
337  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
338  cloneableTags[errorTag] = cloneableTags[funcTag] =
339  cloneableTags[weakMapTag] = false;
340
341  /** Used to map Latin Unicode letters to basic Latin letters. */
342  var deburredLetters = {
343    // Latin-1 Supplement block.
344    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
345    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
346    '\xc7': 'C',  '\xe7': 'c',
347    '\xd0': 'D',  '\xf0': 'd',
348    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
349    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
350    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
351    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
352    '\xd1': 'N',  '\xf1': 'n',
353    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
354    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
355    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
356    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
357    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
358    '\xc6': 'Ae', '\xe6': 'ae',
359    '\xde': 'Th', '\xfe': 'th',
360    '\xdf': 'ss',
361    // Latin Extended-A block.
362    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
363    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
364    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
365    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
366    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
367    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
368    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
369    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
370    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
371    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
372    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
373    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
374    '\u0134': 'J',  '\u0135': 'j',
375    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
376    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
377    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
378    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
379    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
380    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
381    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
382    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
383    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
384    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
385    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
386    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
387    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
388    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
389    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
390    '\u0174': 'W',  '\u0175': 'w',
391    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
392    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
393    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
394    '\u0132': 'IJ', '\u0133': 'ij',
395    '\u0152': 'Oe', '\u0153': 'oe',
396    '\u0149': "'n", '\u017f': 's'
397  };
398
399  /** Used to map characters to HTML entities. */
400  var htmlEscapes = {
401    '&': '&amp;',
402    '<': '&lt;',
403    '>': '&gt;',
404    '"': '&quot;',
405    "'": '&#39;'
406  };
407
408  /** Used to map HTML entities to characters. */
409  var htmlUnescapes = {
410    '&amp;': '&',
411    '&lt;': '<',
412    '&gt;': '>',
413    '&quot;': '"',
414    '&#39;': "'"
415  };
416
417  /** Used to escape characters for inclusion in compiled string literals. */
418  var stringEscapes = {
419    '\\': '\\',
420    "'": "'",
421    '\n': 'n',
422    '\r': 'r',
423    '\u2028': 'u2028',
424    '\u2029': 'u2029'
425  };
426
427  /** Built-in method references without a dependency on `root`. */
428  var freeParseFloat = parseFloat,
429      freeParseInt = parseInt;
430
431  /** Detect free variable `global` from Node.js. */
432  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
433
434  /** Detect free variable `self`. */
435  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
436
437  /** Used as a reference to the global object. */
438  var root = freeGlobal || freeSelf || Function('return this')();
439
440  /** Detect free variable `exports`. */
441  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
442
443  /** Detect free variable `module`. */
444  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
445
446  /** Detect the popular CommonJS extension `module.exports`. */
447  var moduleExports = freeModule && freeModule.exports === freeExports;
448
449  /** Detect free variable `process` from Node.js. */
450  var freeProcess = moduleExports && freeGlobal.process;
451
452  /** Used to access faster Node.js helpers. */
vendor: 8,860 bytes, lines 453-746
453  var nodeUtil = (function() {
454    try {
455      // Use `util.types` for Node.js 10+.
456      var types = freeModule && freeModule.require && freeModule.require('util').types;
457
458      if (types) {
459        return types;
460      }
461
462      // Legacy `process.binding('util')` for Node.js < 10.
463      return freeProcess && freeProcess.binding && freeProcess.binding('util');
464    } catch (e) {}
465  }());
466
467  /* Node.js helper references. */
468  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
469      nodeIsDate = nodeUtil && nodeUtil.isDate,
470      nodeIsMap = nodeUtil && nodeUtil.isMap,
471      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
472      nodeIsSet = nodeUtil && nodeUtil.isSet,
473      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
474
475  /*--------------------------------------------------------------------------*/
476
477  /**
478   * A faster alternative to `Function#apply`, this function invokes `func`
479   * with the `this` binding of `thisArg` and the arguments of `args`.
480   *
481   * @private
482   * @param {Function} func The function to invoke.
483   * @param {*} thisArg The `this` binding of `func`.
484   * @param {Array} args The arguments to invoke `func` with.
485   * @returns {*} Returns the result of `func`.
486   */
487  function apply(func, thisArg, args) {
488    switch (args.length) {
489      case 0: return func.call(thisArg);
490      case 1: return func.call(thisArg, args[0]);
491      case 2: return func.call(thisArg, args[0], args[1]);
492      case 3: return func.call(thisArg, args[0], args[1], args[2]);
493    }
494    return func.apply(thisArg, args);
495  }
496
497  /**
498   * A specialized version of `baseAggregator` for arrays.
499   *
500   * @private
501   * @param {Array} [array] The array to iterate over.
502   * @param {Function} setter The function to set `accumulator` values.
503   * @param {Function} iteratee The iteratee to transform keys.
504   * @param {Object} accumulator The initial aggregated object.
505   * @returns {Function} Returns `accumulator`.
506   */
507  function arrayAggregator(array, setter, iteratee, accumulator) {
508    var index = -1,
509        length = array == null ? 0 : array.length;
510
511    while (++index < length) {
512      var value = array[index];
513      setter(accumulator, value, iteratee(value), array);
514    }
515    return accumulator;
516  }
517
518  /**
519   * A specialized version of `_.forEach` for arrays without support for
520   * iteratee shorthands.
521   *
522   * @private
523   * @param {Array} [array] The array to iterate over.
524   * @param {Function} iteratee The function invoked per iteration.
525   * @returns {Array} Returns `array`.
526   */
527  function arrayEach(array, iteratee) {
528    var index = -1,
529        length = array == null ? 0 : array.length;
530
531    while (++index < length) {
532      if (iteratee(array[index], index, array) === false) {
533        break;
534      }
535    }
536    return array;
537  }
538
539  /**
540   * A specialized version of `_.forEachRight` for arrays without support for
541   * iteratee shorthands.
542   *
543   * @private
544   * @param {Array} [array] The array to iterate over.
545   * @param {Function} iteratee The function invoked per iteration.
546   * @returns {Array} Returns `array`.
547   */
548  function arrayEachRight(array, iteratee) {
549    var length = array == null ? 0 : array.length;
550
551    while (length--) {
552      if (iteratee(array[length], length, array) === false) {
553        break;
554      }
555    }
556    return array;
557  }
558
559  /**
560   * A specialized version of `_.every` for arrays without support for
561   * iteratee shorthands.
562   *
563   * @private
564   * @param {Array} [array] The array to iterate over.
565   * @param {Function} predicate The function invoked per iteration.
566   * @returns {boolean} Returns `true` if all elements pass the predicate check,
567   *  else `false`.
568   */
569  function arrayEvery(array, predicate) {
570    var index = -1,
571        length = array == null ? 0 : array.length;
572
573    while (++index < length) {
574      if (!predicate(array[index], index, array)) {
575        return false;
576      }
577    }
578    return true;
579  }
580
581  /**
582   * A specialized version of `_.filter` for arrays without support for
583   * iteratee shorthands.
584   *
585   * @private
586   * @param {Array} [array] The array to iterate over.
587   * @param {Function} predicate The function invoked per iteration.
588   * @returns {Array} Returns the new filtered array.
589   */
590  function arrayFilter(array, predicate) {
591    var index = -1,
592        length = array == null ? 0 : array.length,
593        resIndex = 0,
594        result = [];
595
596    while (++index < length) {
597      var value = array[index];
598      if (predicate(value, index, array)) {
599        result[resIndex++] = value;
600      }
601    }
602    return result;
603  }
604
605  /**
606   * A specialized version of `_.includes` for arrays without support for
607   * specifying an index to search from.
608   *
609   * @private
610   * @param {Array} [array] The array to inspect.
611   * @param {*} target The value to search for.
612   * @returns {boolean} Returns `true` if `target` is found, else `false`.
613   */
614  function arrayIncludes(array, value) {
615    var length = array == null ? 0 : array.length;
616    return !!length && baseIndexOf(array, value, 0) > -1;
617  }
618
619  /**
620   * This function is like `arrayIncludes` except that it accepts a comparator.
621   *
622   * @private
623   * @param {Array} [array] The array to inspect.
624   * @param {*} target The value to search for.
625   * @param {Function} comparator The comparator invoked per element.
626   * @returns {boolean} Returns `true` if `target` is found, else `false`.
627   */
628  function arrayIncludesWith(array, value, comparator) {
629    var index = -1,
630        length = array == null ? 0 : array.length;
631
632    while (++index < length) {
633      if (comparator(value, array[index])) {
634        return true;
635      }
636    }
637    return false;
638  }
639
640  /**
641   * A specialized version of `_.map` for arrays without support for iteratee
642   * shorthands.
643   *
644   * @private
645   * @param {Array} [array] The array to iterate over.
646   * @param {Function} iteratee The function invoked per iteration.
647   * @returns {Array} Returns the new mapped array.
648   */
649  function arrayMap(array, iteratee) {
650    var index = -1,
651        length = array == null ? 0 : array.length,
652        result = Array(length);
653
654    while (++index < length) {
655      result[index] = iteratee(array[index], index, array);
656    }
657    return result;
658  }
659
660  /**
661   * Appends the elements of `values` to `array`.
662   *
663   * @private
664   * @param {Array} array The array to modify.
665   * @param {Array} values The values to append.
666   * @returns {Array} Returns `array`.
667   */
668  function arrayPush(array, values) {
669    var index = -1,
670        length = values.length,
671        offset = array.length;
672
673    while (++index < length) {
674      array[offset + index] = values[index];
675    }
676    return array;
677  }
678
679  /**
680   * A specialized version of `_.reduce` for arrays without support for
681   * iteratee shorthands.
682   *
683   * @private
684   * @param {Array} [array] The array to iterate over.
685   * @param {Function} iteratee The function invoked per iteration.
686   * @param {*} [accumulator] The initial value.
687   * @param {boolean} [initAccum] Specify using the first element of `array` as
688   *  the initial value.
689   * @returns {*} Returns the accumulated value.
690   */
691  function arrayReduce(array, iteratee, accumulator, initAccum) {
692    var index = -1,
693        length = array == null ? 0 : array.length;
694
695    if (initAccum && length) {
696      accumulator = array[++index];
697    }
698    while (++index < length) {
699      accumulator = iteratee(accumulator, array[index], index, array);
700    }
701    return accumulator;
702  }
703
704  /**
705   * A specialized version of `_.reduceRight` for arrays without support for
706   * iteratee shorthands.
707   *
708   * @private
709   * @param {Array} [array] The array to iterate over.
710   * @param {Function} iteratee The function invoked per iteration.
711   * @param {*} [accumulator] The initial value.
712   * @param {boolean} [initAccum] Specify using the last element of `array` as
713   *  the initial value.
714   * @returns {*} Returns the accumulated value.
715   */
716  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
717    var length = array == null ? 0 : array.length;
718    if (initAccum && length) {
719      accumulator = array[--length];
720    }
721    while (length--) {
722      accumulator = iteratee(accumulator, array[length], length, array);
723    }
724    return accumulator;
725  }
726
727  /**
728   * A specialized version of `_.some` for arrays without support for iteratee
729   * shorthands.
730   *
731   * @private
732   * @param {Array} [array] The array to iterate over.
733   * @param {Function} predicate The function invoked per iteration.
734   * @returns {boolean} Returns `true` if any element passes the predicate check,
735   *  else `false`.
736   */
737  function arraySome(array, predicate) {
738    var index = -1,
739        length = array == null ? 0 : array.length;
740
741    while (++index < length) {
742      if (predicate(array[index], index, array)) {
743        return true;
744      }
745    }
746    return false;
vendor: 12,899 bytes, lines 747-1184
747  }
748
749  /**
750   * Gets the size of an ASCII `string`.
751   *
752   * @private
753   * @param {string} string The string inspect.
754   * @returns {number} Returns the string size.
755   */
756  var asciiSize = baseProperty('length');
757
758  /**
759   * Converts an ASCII `string` to an array.
760   *
761   * @private
762   * @param {string} string The string to convert.
763   * @returns {Array} Returns the converted array.
764   */
765  function asciiToArray(string) {
766    return string.split('');
767  }
768
769  /**
770   * Splits an ASCII `string` into an array of its words.
771   *
772   * @private
773   * @param {string} The string to inspect.
774   * @returns {Array} Returns the words of `string`.
775   */
776  function asciiWords(string) {
777    return string.match(reAsciiWord) || [];
778  }
779
780  /**
781   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
782   * without support for iteratee shorthands, which iterates over `collection`
783   * using `eachFunc`.
784   *
785   * @private
786   * @param {Array|Object} collection The collection to inspect.
787   * @param {Function} predicate The function invoked per iteration.
788   * @param {Function} eachFunc The function to iterate over `collection`.
789   * @returns {*} Returns the found element or its key, else `undefined`.
790   */
791  function baseFindKey(collection, predicate, eachFunc) {
792    var result;
793    eachFunc(collection, function(value, key, collection) {
794      if (predicate(value, key, collection)) {
795        result = key;
796        return false;
797      }
798    });
799    return result;
800  }
801
802  /**
803   * The base implementation of `_.findIndex` and `_.findLastIndex` without
804   * support for iteratee shorthands.
805   *
806   * @private
807   * @param {Array} array The array to inspect.
808   * @param {Function} predicate The function invoked per iteration.
809   * @param {number} fromIndex The index to search from.
810   * @param {boolean} [fromRight] Specify iterating from right to left.
811   * @returns {number} Returns the index of the matched value, else `-1`.
812   */
813  function baseFindIndex(array, predicate, fromIndex, fromRight) {
814    var length = array.length,
815        index = fromIndex + (fromRight ? 1 : -1);
816
817    while ((fromRight ? index-- : ++index < length)) {
818      if (predicate(array[index], index, array)) {
819        return index;
820      }
821    }
822    return -1;
823  }
824
825  /**
826   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
827   *
828   * @private
829   * @param {Array} array The array to inspect.
830   * @param {*} value The value to search for.
831   * @param {number} fromIndex The index to search from.
832   * @returns {number} Returns the index of the matched value, else `-1`.
833   */
834  function baseIndexOf(array, value, fromIndex) {
835    return value === value
836      ? strictIndexOf(array, value, fromIndex)
837      : baseFindIndex(array, baseIsNaN, fromIndex);
838  }
839
840  /**
841   * This function is like `baseIndexOf` except that it accepts a comparator.
842   *
843   * @private
844   * @param {Array} array The array to inspect.
845   * @param {*} value The value to search for.
846   * @param {number} fromIndex The index to search from.
847   * @param {Function} comparator The comparator invoked per element.
848   * @returns {number} Returns the index of the matched value, else `-1`.
849   */
850  function baseIndexOfWith(array, value, fromIndex, comparator) {
851    var index = fromIndex - 1,
852        length = array.length;
853
854    while (++index < length) {
855      if (comparator(array[index], value)) {
856        return index;
857      }
858    }
859    return -1;
860  }
861
862  /**
863   * The base implementation of `_.isNaN` without support for number objects.
864   *
865   * @private
866   * @param {*} value The value to check.
867   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
868   */
869  function baseIsNaN(value) {
870    return value !== value;
871  }
872
873  /**
874   * The base implementation of `_.mean` and `_.meanBy` without support for
875   * iteratee shorthands.
876   *
877   * @private
878   * @param {Array} array The array to iterate over.
879   * @param {Function} iteratee The function invoked per iteration.
880   * @returns {number} Returns the mean.
881   */
882  function baseMean(array, iteratee) {
883    var length = array == null ? 0 : array.length;
884    return length ? (baseSum(array, iteratee) / length) : NAN;
885  }
886
887  /**
888   * The base implementation of `_.property` without support for deep paths.
889   *
890   * @private
891   * @param {string} key The key of the property to get.
892   * @returns {Function} Returns the new accessor function.
893   */
894  function baseProperty(key) {
895    return function(object) {
896      return object == null ? undefined : object[key];
897    };
898  }
899
900  /**
901   * The base implementation of `_.propertyOf` without support for deep paths.
902   *
903   * @private
904   * @param {Object} object The object to query.
905   * @returns {Function} Returns the new accessor function.
906   */
907  function basePropertyOf(object) {
908    return function(key) {
909      return object == null ? undefined : object[key];
910    };
911  }
912
913  /**
914   * The base implementation of `_.reduce` and `_.reduceRight`, without support
915   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
916   *
917   * @private
918   * @param {Array|Object} collection The collection to iterate over.
919   * @param {Function} iteratee The function invoked per iteration.
920   * @param {*} accumulator The initial value.
921   * @param {boolean} initAccum Specify using the first or last element of
922   *  `collection` as the initial value.
923   * @param {Function} eachFunc The function to iterate over `collection`.
924   * @returns {*} Returns the accumulated value.
925   */
926  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
927    eachFunc(collection, function(value, index, collection) {
928      accumulator = initAccum
929        ? (initAccum = false, value)
930        : iteratee(accumulator, value, index, collection);
931    });
932    return accumulator;
933  }
934
935  /**
936   * The base implementation of `_.sortBy` which uses `comparer` to define the
937   * sort order of `array` and replaces criteria objects with their corresponding
938   * values.
939   *
940   * @private
941   * @param {Array} array The array to sort.
942   * @param {Function} comparer The function to define sort order.
943   * @returns {Array} Returns `array`.
944   */
945  function baseSortBy(array, comparer) {
946    var length = array.length;
947
948    array.sort(comparer);
949    while (length--) {
950      array[length] = array[length].value;
951    }
952    return array;
953  }
954
955  /**
956   * The base implementation of `_.sum` and `_.sumBy` without support for
957   * iteratee shorthands.
958   *
959   * @private
960   * @param {Array} array The array to iterate over.
961   * @param {Function} iteratee The function invoked per iteration.
962   * @returns {number} Returns the sum.
963   */
964  function baseSum(array, iteratee) {
965    var result,
966        index = -1,
967        length = array.length;
968
969    while (++index < length) {
970      var current = iteratee(array[index]);
971      if (current !== undefined) {
972        result = result === undefined ? current : (result + current);
973      }
974    }
975    return result;
976  }
977
978  /**
979   * The base implementation of `_.times` without support for iteratee shorthands
980   * or max array length checks.
981   *
982   * @private
983   * @param {number} n The number of times to invoke `iteratee`.
984   * @param {Function} iteratee The function invoked per iteration.
985   * @returns {Array} Returns the array of results.
986   */
987  function baseTimes(n, iteratee) {
988    var index = -1,
989        result = Array(n);
990
991    while (++index < n) {
992      result[index] = iteratee(index);
993    }
994    return result;
995  }
996
997  /**
998   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
999   * of key-value pairs for `object` corresponding to the property names of `props`.
1000   *
1001   * @private
1002   * @param {Object} object The object to query.
1003   * @param {Array} props The property names to get values for.
1004   * @returns {Object} Returns the key-value pairs.
1005   */
1006  function baseToPairs(object, props) {
1007    return arrayMap(props, function(key) {
1008      return [key, object[key]];
1009    });
1010  }
1011
1012  /**
1013   * The base implementation of `_.trim`.
1014   *
1015   * @private
1016   * @param {string} string The string to trim.
1017   * @returns {string} Returns the trimmed string.
1018   */
1019  function baseTrim(string) {
1020    return string
1021      ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
1022      : string;
1023  }
1024
1025  /**
1026   * The base implementation of `_.unary` without support for storing metadata.
1027   *
1028   * @private
1029   * @param {Function} func The function to cap arguments for.
1030   * @returns {Function} Returns the new capped function.
1031   */
1032  function baseUnary(func) {
1033    return function(value) {
1034      return func(value);
1035    };
1036  }
1037
1038  /**
1039   * The base implementation of `_.values` and `_.valuesIn` which creates an
1040   * array of `object` property values corresponding to the property names
1041   * of `props`.
1042   *
1043   * @private
1044   * @param {Object} object The object to query.
1045   * @param {Array} props The property names to get values for.
1046   * @returns {Object} Returns the array of property values.
1047   */
1048  function baseValues(object, props) {
1049    return arrayMap(props, function(key) {
1050      return object[key];
1051    });
1052  }
1053
1054  /**
1055   * Checks if a `cache` value for `key` exists.
1056   *
1057   * @private
1058   * @param {Object} cache The cache to query.
1059   * @param {string} key The key of the entry to check.
1060   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1061   */
1062  function cacheHas(cache, key) {
1063    return cache.has(key);
1064  }
1065
1066  /**
1067   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1068   * that is not found in the character symbols.
1069   *
1070   * @private
1071   * @param {Array} strSymbols The string symbols to inspect.
1072   * @param {Array} chrSymbols The character symbols to find.
1073   * @returns {number} Returns the index of the first unmatched string symbol.
1074   */
1075  function charsStartIndex(strSymbols, chrSymbols) {
1076    var index = -1,
1077        length = strSymbols.length;
1078
1079    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1080    return index;
1081  }
1082
1083  /**
1084   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1085   * that is not found in the character symbols.
1086   *
1087   * @private
1088   * @param {Array} strSymbols The string symbols to inspect.
1089   * @param {Array} chrSymbols The character symbols to find.
1090   * @returns {number} Returns the index of the last unmatched string symbol.
1091   */
1092  function charsEndIndex(strSymbols, chrSymbols) {
1093    var index = strSymbols.length;
1094
1095    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1096    return index;
1097  }
1098
1099  /**
1100   * Gets the number of `placeholder` occurrences in `array`.
1101   *
1102   * @private
1103   * @param {Array} array The array to inspect.
1104   * @param {*} placeholder The placeholder to search for.
1105   * @returns {number} Returns the placeholder count.
1106   */
1107  function countHolders(array, placeholder) {
1108    var length = array.length,
1109        result = 0;
1110
1111    while (length--) {
1112      if (array[length] === placeholder) {
1113        ++result;
1114      }
1115    }
1116    return result;
1117  }
1118
1119  /**
1120   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
1121   * letters to basic Latin letters.
1122   *
1123   * @private
1124   * @param {string} letter The matched letter to deburr.
1125   * @returns {string} Returns the deburred letter.
1126   */
1127  var deburrLetter = basePropertyOf(deburredLetters);
1128
1129  /**
1130   * Used by `_.escape` to convert characters to HTML entities.
1131   *
1132   * @private
1133   * @param {string} chr The matched character to escape.
1134   * @returns {string} Returns the escaped character.
1135   */
1136  var escapeHtmlChar = basePropertyOf(htmlEscapes);
1137
1138  /**
1139   * Used by `_.template` to escape characters for inclusion in compiled string literals.
1140   *
1141   * @private
1142   * @param {string} chr The matched character to escape.
1143   * @returns {string} Returns the escaped character.
1144   */
1145  function escapeStringChar(chr) {
1146    return '\\' + stringEscapes[chr];
1147  }
1148
1149  /**
1150   * Gets the value at `key` of `object`.
1151   *
1152   * @private
1153   * @param {Object} [object] The object to query.
1154   * @param {string} key The key of the property to get.
1155   * @returns {*} Returns the property value.
1156   */
1157  function getValue(object, key) {
1158    return object == null ? undefined : object[key];
1159  }
1160
1161  /**
1162   * Checks if `string` contains Unicode symbols.
1163   *
1164   * @private
1165   * @param {string} string The string to inspect.
1166   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1167   */
1168  function hasUnicode(string) {
1169    return reHasUnicode.test(string);
1170  }
1171
1172  /**
1173   * Checks if `string` contains a word composed of Unicode symbols.
1174   *
1175   * @private
1176   * @param {string} string The string to inspect.
1177   * @returns {boolean} Returns `true` if a word is found, else `false`.
1178   */
1179  function hasUnicodeWord(string) {
1180    return reHasUnicodeWord.test(string);
1181  }
1182
1183  /**
1184   * Converts `iterator` to an array.
vendor: 8,214 bytes, lines 1185-1494
1185   *
1186   * @private
1187   * @param {Object} iterator The iterator to convert.
1188   * @returns {Array} Returns the converted array.
1189   */
1190  function iteratorToArray(iterator) {
1191    var data,
1192        result = [];
1193
1194    while (!(data = iterator.next()).done) {
1195      result.push(data.value);
1196    }
1197    return result;
1198  }
1199
1200  /**
1201   * Converts `map` to its key-value pairs.
1202   *
1203   * @private
1204   * @param {Object} map The map to convert.
1205   * @returns {Array} Returns the key-value pairs.
1206   */
1207  function mapToArray(map) {
1208    var index = -1,
1209        result = Array(map.size);
1210
1211    map.forEach(function(value, key) {
1212      result[++index] = [key, value];
1213    });
1214    return result;
1215  }
1216
1217  /**
1218   * Creates a unary function that invokes `func` with its argument transformed.
1219   *
1220   * @private
1221   * @param {Function} func The function to wrap.
1222   * @param {Function} transform The argument transform.
1223   * @returns {Function} Returns the new function.
1224   */
1225  function overArg(func, transform) {
1226    return function(arg) {
1227      return func(transform(arg));
1228    };
1229  }
1230
1231  /**
1232   * Replaces all `placeholder` elements in `array` with an internal placeholder
1233   * and returns an array of their indexes.
1234   *
1235   * @private
1236   * @param {Array} array The array to modify.
1237   * @param {*} placeholder The placeholder to replace.
1238   * @returns {Array} Returns the new array of placeholder indexes.
1239   */
1240  function replaceHolders(array, placeholder) {
1241    var index = -1,
1242        length = array.length,
1243        resIndex = 0,
1244        result = [];
1245
1246    while (++index < length) {
1247      var value = array[index];
1248      if (value === placeholder || value === PLACEHOLDER) {
1249        array[index] = PLACEHOLDER;
1250        result[resIndex++] = index;
1251      }
1252    }
1253    return result;
1254  }
1255
1256  /**
1257   * Converts `set` to an array of its values.
1258   *
1259   * @private
1260   * @param {Object} set The set to convert.
1261   * @returns {Array} Returns the values.
1262   */
1263  function setToArray(set) {
1264    var index = -1,
1265        result = Array(set.size);
1266
1267    set.forEach(function(value) {
1268      result[++index] = value;
1269    });
1270    return result;
1271  }
1272
1273  /**
1274   * Converts `set` to its value-value pairs.
1275   *
1276   * @private
1277   * @param {Object} set The set to convert.
1278   * @returns {Array} Returns the value-value pairs.
1279   */
1280  function setToPairs(set) {
1281    var index = -1,
1282        result = Array(set.size);
1283
1284    set.forEach(function(value) {
1285      result[++index] = [value, value];
1286    });
1287    return result;
1288  }
1289
1290  /**
1291   * A specialized version of `_.indexOf` which performs strict equality
1292   * comparisons of values, i.e. `===`.
1293   *
1294   * @private
1295   * @param {Array} array The array to inspect.
1296   * @param {*} value The value to search for.
1297   * @param {number} fromIndex The index to search from.
1298   * @returns {number} Returns the index of the matched value, else `-1`.
1299   */
1300  function strictIndexOf(array, value, fromIndex) {
1301    var index = fromIndex - 1,
1302        length = array.length;
1303
1304    while (++index < length) {
1305      if (array[index] === value) {
1306        return index;
1307      }
1308    }
1309    return -1;
1310  }
1311
1312  /**
1313   * A specialized version of `_.lastIndexOf` which performs strict equality
1314   * comparisons of values, i.e. `===`.
1315   *
1316   * @private
1317   * @param {Array} array The array to inspect.
1318   * @param {*} value The value to search for.
1319   * @param {number} fromIndex The index to search from.
1320   * @returns {number} Returns the index of the matched value, else `-1`.
1321   */
1322  function strictLastIndexOf(array, value, fromIndex) {
1323    var index = fromIndex + 1;
1324    while (index--) {
1325      if (array[index] === value) {
1326        return index;
1327      }
1328    }
1329    return index;
1330  }
1331
1332  /**
1333   * Gets the number of symbols in `string`.
1334   *
1335   * @private
1336   * @param {string} string The string to inspect.
1337   * @returns {number} Returns the string size.
1338   */
1339  function stringSize(string) {
1340    return hasUnicode(string)
1341      ? unicodeSize(string)
1342      : asciiSize(string);
1343  }
1344
1345  /**
1346   * Converts `string` to an array.
1347   *
1348   * @private
1349   * @param {string} string The string to convert.
1350   * @returns {Array} Returns the converted array.
1351   */
1352  function stringToArray(string) {
1353    return hasUnicode(string)
1354      ? unicodeToArray(string)
1355      : asciiToArray(string);
1356  }
1357
1358  /**
1359   * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
1360   * character of `string`.
1361   *
1362   * @private
1363   * @param {string} string The string to inspect.
1364   * @returns {number} Returns the index of the last non-whitespace character.
1365   */
1366  function trimmedEndIndex(string) {
1367    var index = string.length;
1368
1369    while (index-- && reWhitespace.test(string.charAt(index))) {}
1370    return index;
1371  }
1372
1373  /**
1374   * Used by `_.unescape` to convert HTML entities to characters.
1375   *
1376   * @private
1377   * @param {string} chr The matched character to unescape.
1378   * @returns {string} Returns the unescaped character.
1379   */
1380  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
1381
1382  /**
1383   * Gets the size of a Unicode `string`.
1384   *
1385   * @private
1386   * @param {string} string The string inspect.
1387   * @returns {number} Returns the string size.
1388   */
1389  function unicodeSize(string) {
1390    var result = reUnicode.lastIndex = 0;
1391    while (reUnicode.test(string)) {
1392      ++result;
1393    }
1394    return result;
1395  }
1396
1397  /**
1398   * Converts a Unicode `string` to an array.
1399   *
1400   * @private
1401   * @param {string} string The string to convert.
1402   * @returns {Array} Returns the converted array.
1403   */
1404  function unicodeToArray(string) {
1405    return string.match(reUnicode) || [];
1406  }
1407
1408  /**
1409   * Splits a Unicode `string` into an array of its words.
1410   *
1411   * @private
1412   * @param {string} The string to inspect.
1413   * @returns {Array} Returns the words of `string`.
1414   */
1415  function unicodeWords(string) {
1416    return string.match(reUnicodeWord) || [];
1417  }
1418
1419  /*--------------------------------------------------------------------------*/
1420
1421  /**
1422   * Create a new pristine `lodash` function using the `context` object.
1423   *
1424   * @static
1425   * @memberOf _
1426   * @since 1.1.0
1427   * @category Util
1428   * @param {Object} [context=root] The context object.
1429   * @returns {Function} Returns a new `lodash` function.
1430   * @example
1431   *
1432   * _.mixin({ 'foo': _.constant('foo') });
1433   *
1434   * var lodash = _.runInContext();
1435   * lodash.mixin({ 'bar': lodash.constant('bar') });
1436   *
1437   * _.isFunction(_.foo);
1438   * // => true
1439   * _.isFunction(_.bar);
1440   * // => false
1441   *
1442   * lodash.isFunction(lodash.foo);
1443   * // => false
1444   * lodash.isFunction(lodash.bar);
1445   * // => true
1446   *
1447   * // Create a suped-up `defer` in Node.js.
1448   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1449   */
1450  var runInContext = (function runInContext(context) {
1451    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
1452
1453    /** Built-in constructor references. */
1454    var Array = context.Array,
1455        Date = context.Date,
1456        Error = context.Error,
1457        Function = context.Function,
1458        Math = context.Math,
1459        Object = context.Object,
1460        RegExp = context.RegExp,
1461        String = context.String,
1462        TypeError = context.TypeError;
1463
1464    /** Used for built-in method references. */
1465    var arrayProto = Array.prototype,
1466        funcProto = Function.prototype,
1467        objectProto = Object.prototype;
1468
1469    /** Used to detect overreaching core-js shims. */
1470    var coreJsData = context['__core-js_shared__'];
1471
1472    /** Used to resolve the decompiled source of functions. */
1473    var funcToString = funcProto.toString;
1474
1475    /** Used to check objects for own properties. */
1476    var hasOwnProperty = objectProto.hasOwnProperty;
1477
1478    /** Used to generate unique IDs. */
1479    var idCounter = 0;
1480
1481    /** Used to detect methods masquerading as native. */
1482    var maskSrcKey = (function() {
1483      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1484      return uid ? ('Symbol(src)_1.' + uid) : '';
1485    }());
1486
1487    /**
1488     * Used to resolve the
1489     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1490     * of values.
1491     */
1492    var nativeObjectToString = objectProto.toString;
1493
1494    /** Used to infer the `Object` constructor. */
vendor: 25,659 bytes, lines 1495-2292
1495    var objectCtorString = funcToString.call(Object);
1496
1497    /** Used to restore the original `_` reference in `_.noConflict`. */
1498    var oldDash = root._;
1499
1500    /** Used to detect if a method is native. */
1501    var reIsNative = RegExp('^' +
1502      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1503      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1504    );
1505
1506    /** Built-in value references. */
1507    var Buffer = moduleExports ? context.Buffer : undefined,
1508        Symbol = context.Symbol,
1509        Uint8Array = context.Uint8Array,
1510        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
1511        getPrototype = overArg(Object.getPrototypeOf, Object),
1512        objectCreate = Object.create,
1513        propertyIsEnumerable = objectProto.propertyIsEnumerable,
1514        splice = arrayProto.splice,
1515        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
1516        symIterator = Symbol ? Symbol.iterator : undefined,
1517        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1518
1519    var defineProperty = (function() {
1520      try {
1521        var func = getNative(Object, 'defineProperty');
1522        func({}, '', {});
1523        return func;
1524      } catch (e) {}
1525    }());
1526
1527    /** Mocked built-ins. */
1528    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
1529        ctxNow = Date && Date.now !== root.Date.now && Date.now,
1530        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1531
1532    /* Built-in method references for those with the same name as other `lodash` methods. */
1533    var nativeCeil = Math.ceil,
1534        nativeFloor = Math.floor,
1535        nativeGetSymbols = Object.getOwnPropertySymbols,
1536        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1537        nativeIsFinite = context.isFinite,
1538        nativeJoin = arrayProto.join,
1539        nativeKeys = overArg(Object.keys, Object),
1540        nativeMax = Math.max,
1541        nativeMin = Math.min,
1542        nativeNow = Date.now,
1543        nativeParseInt = context.parseInt,
1544        nativeRandom = Math.random,
1545        nativeReverse = arrayProto.reverse;
1546
1547    /* Built-in method references that are verified to be native. */
1548    var DataView = getNative(context, 'DataView'),
1549        Map = getNative(context, 'Map'),
1550        Promise = getNative(context, 'Promise'),
1551        Set = getNative(context, 'Set'),
1552        WeakMap = getNative(context, 'WeakMap'),
1553        nativeCreate = getNative(Object, 'create');
1554
1555    /** Used to store function metadata. */
1556    var metaMap = WeakMap && new WeakMap;
1557
1558    /** Used to lookup unminified function names. */
1559    var realNames = {};
1560
1561    /** Used to detect maps, sets, and weakmaps. */
1562    var dataViewCtorString = toSource(DataView),
1563        mapCtorString = toSource(Map),
1564        promiseCtorString = toSource(Promise),
1565        setCtorString = toSource(Set),
1566        weakMapCtorString = toSource(WeakMap);
1567
1568    /** Used to convert symbols to primitives and strings. */
1569    var symbolProto = Symbol ? Symbol.prototype : undefined,
1570        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1571        symbolToString = symbolProto ? symbolProto.toString : undefined;
1572
1573    /*------------------------------------------------------------------------*/
1574
1575    /**
1576     * Creates a `lodash` object which wraps `value` to enable implicit method
1577     * chain sequences. Methods that operate on and return arrays, collections,
1578     * and functions can be chained together. Methods that retrieve a single value
1579     * or may return a primitive value will automatically end the chain sequence
1580     * and return the unwrapped value. Otherwise, the value must be unwrapped
1581     * with `_#value`.
1582     *
1583     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1584     * enabled using `_.chain`.
1585     *
1586     * The execution of chained methods is lazy, that is, it's deferred until
1587     * `_#value` is implicitly or explicitly called.
1588     *
1589     * Lazy evaluation allows several methods to support shortcut fusion.
1590     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1591     * the creation of intermediate arrays and can greatly reduce the number of
1592     * iteratee executions. Sections of a chain sequence qualify for shortcut
1593     * fusion if the section is applied to an array and iteratees accept only
1594     * one argument. The heuristic for whether a section qualifies for shortcut
1595     * fusion is subject to change.
1596     *
1597     * Chaining is supported in custom builds as long as the `_#value` method is
1598     * directly or indirectly included in the build.
1599     *
1600     * In addition to lodash methods, wrappers have `Array` and `String` methods.
1601     *
1602     * The wrapper `Array` methods are:
1603     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1604     *
1605     * The wrapper `String` methods are:
1606     * `replace` and `split`
1607     *
1608     * The wrapper methods that support shortcut fusion are:
1609     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1610     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1611     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1612     *
1613     * The chainable wrapper methods are:
1614     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1615     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1616     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1617     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1618     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1619     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1620     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1621     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1622     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1623     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1624     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1625     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1626     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1627     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1628     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1629     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1630     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1631     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1632     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1633     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1634     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1635     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1636     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1637     * `zipObject`, `zipObjectDeep`, and `zipWith`
1638     *
1639     * The wrapper methods that are **not** chainable by default are:
1640     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1641     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
1642     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
1643     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1644     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
1645     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1646     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1647     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
1648     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
1649     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
1650     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1651     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1652     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1653     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1654     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1655     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1656     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1657     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1658     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1659     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1660     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1661     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1662     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1663     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1664     * `upperFirst`, `value`, and `words`
1665     *
1666     * @name _
1667     * @constructor
1668     * @category Seq
1669     * @param {*} value The value to wrap in a `lodash` instance.
1670     * @returns {Object} Returns the new `lodash` wrapper instance.
1671     * @example
1672     *
1673     * function square(n) {
1674     *   return n * n;
1675     * }
1676     *
1677     * var wrapped = _([1, 2, 3]);
1678     *
1679     * // Returns an unwrapped value.
1680     * wrapped.reduce(_.add);
1681     * // => 6
1682     *
1683     * // Returns a wrapped value.
1684     * var squares = wrapped.map(square);
1685     *
1686     * _.isArray(squares);
1687     * // => false
1688     *
1689     * _.isArray(squares.value());
1690     * // => true
1691     */
1692    function lodash(value) {
1693      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1694        if (value instanceof LodashWrapper) {
1695          return value;
1696        }
1697        if (hasOwnProperty.call(value, '__wrapped__')) {
1698          return wrapperClone(value);
1699        }
1700      }
1701      return new LodashWrapper(value);
1702    }
1703
1704    /**
1705     * The base implementation of `_.create` without support for assigning
1706     * properties to the created object.
1707     *
1708     * @private
1709     * @param {Object} proto The object to inherit from.
1710     * @returns {Object} Returns the new object.
1711     */
1712    var baseCreate = (function() {
1713      function object() {}
1714      return function(proto) {
1715        if (!isObject(proto)) {
1716          return {};
1717        }
1718        if (objectCreate) {
1719          return objectCreate(proto);
1720        }
1721        object.prototype = proto;
1722        var result = new object;
1723        object.prototype = undefined;
1724        return result;
1725      };
1726    }());
1727
1728    /**
1729     * The function whose prototype chain sequence wrappers inherit from.
1730     *
1731     * @private
1732     */
1733    function baseLodash() {
1734      // No operation performed.
1735    }
1736
1737    /**
1738     * The base constructor for creating `lodash` wrapper objects.
1739     *
1740     * @private
1741     * @param {*} value The value to wrap.
1742     * @param {boolean} [chainAll] Enable explicit method chain sequences.
1743     */
1744    function LodashWrapper(value, chainAll) {
1745      this.__wrapped__ = value;
1746      this.__actions__ = [];
1747      this.__chain__ = !!chainAll;
1748      this.__index__ = 0;
1749      this.__values__ = undefined;
1750    }
1751
1752    /**
1753     * By default, the template delimiters used by lodash are like those in
1754     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
1755     * following template settings to use alternative delimiters.
1756     *
1757     * @static
1758     * @memberOf _
1759     * @type {Object}
1760     */
1761    lodash.templateSettings = {
1762
1763      /**
1764       * Used to detect `data` property values to be HTML-escaped.
1765       *
1766       * @memberOf _.templateSettings
1767       * @type {RegExp}
1768       */
1769      'escape': reEscape,
1770
1771      /**
1772       * Used to detect code to be evaluated.
1773       *
1774       * @memberOf _.templateSettings
1775       * @type {RegExp}
1776       */
1777      'evaluate': reEvaluate,
1778
1779      /**
1780       * Used to detect `data` property values to inject.
1781       *
1782       * @memberOf _.templateSettings
1783       * @type {RegExp}
1784       */
1785      'interpolate': reInterpolate,
1786
1787      /**
1788       * Used to reference the data object in the template text.
1789       *
1790       * @memberOf _.templateSettings
1791       * @type {string}
1792       */
1793      'variable': '',
1794
1795      /**
1796       * Used to import variables into the compiled template.
1797       *
1798       * @memberOf _.templateSettings
1799       * @type {Object}
1800       */
1801      'imports': {
1802
1803        /**
1804         * A reference to the `lodash` function.
1805         *
1806         * @memberOf _.templateSettings.imports
1807         * @type {Function}
1808         */
1809        '_': lodash
1810      }
1811    };
1812
1813    // Ensure wrappers are instances of `baseLodash`.
1814    lodash.prototype = baseLodash.prototype;
1815    lodash.prototype.constructor = lodash;
1816
1817    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1818    LodashWrapper.prototype.constructor = LodashWrapper;
1819
1820    /*------------------------------------------------------------------------*/
1821
1822    /**
1823     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1824     *
1825     * @private
1826     * @constructor
1827     * @param {*} value The value to wrap.
1828     */
1829    function LazyWrapper(value) {
1830      this.__wrapped__ = value;
1831      this.__actions__ = [];
1832      this.__dir__ = 1;
1833      this.__filtered__ = false;
1834      this.__iteratees__ = [];
1835      this.__takeCount__ = MAX_ARRAY_LENGTH;
1836      this.__views__ = [];
1837    }
1838
1839    /**
1840     * Creates a clone of the lazy wrapper object.
1841     *
1842     * @private
1843     * @name clone
1844     * @memberOf LazyWrapper
1845     * @returns {Object} Returns the cloned `LazyWrapper` object.
1846     */
1847    function lazyClone() {
1848      var result = new LazyWrapper(this.__wrapped__);
1849      result.__actions__ = copyArray(this.__actions__);
1850      result.__dir__ = this.__dir__;
1851      result.__filtered__ = this.__filtered__;
1852      result.__iteratees__ = copyArray(this.__iteratees__);
1853      result.__takeCount__ = this.__takeCount__;
1854      result.__views__ = copyArray(this.__views__);
1855      return result;
1856    }
1857
1858    /**
1859     * Reverses the direction of lazy iteration.
1860     *
1861     * @private
1862     * @name reverse
1863     * @memberOf LazyWrapper
1864     * @returns {Object} Returns the new reversed `LazyWrapper` object.
1865     */
1866    function lazyReverse() {
1867      if (this.__filtered__) {
1868        var result = new LazyWrapper(this);
1869        result.__dir__ = -1;
1870        result.__filtered__ = true;
1871      } else {
1872        result = this.clone();
1873        result.__dir__ *= -1;
1874      }
1875      return result;
1876    }
1877
1878    /**
1879     * Extracts the unwrapped value from its lazy wrapper.
1880     *
1881     * @private
1882     * @name value
1883     * @memberOf LazyWrapper
1884     * @returns {*} Returns the unwrapped value.
1885     */
1886    function lazyValue() {
1887      var array = this.__wrapped__.value(),
1888          dir = this.__dir__,
1889          isArr = isArray(array),
1890          isRight = dir < 0,
1891          arrLength = isArr ? array.length : 0,
1892          view = getView(0, arrLength, this.__views__),
1893          start = view.start,
1894          end = view.end,
1895          length = end - start,
1896          index = isRight ? end : (start - 1),
1897          iteratees = this.__iteratees__,
1898          iterLength = iteratees.length,
1899          resIndex = 0,
1900          takeCount = nativeMin(length, this.__takeCount__);
1901
1902      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
1903        return baseWrapperValue(array, this.__actions__);
1904      }
1905      var result = [];
1906
1907      outer:
1908      while (length-- && resIndex < takeCount) {
1909        index += dir;
1910
1911        var iterIndex = -1,
1912            value = array[index];
1913
1914        while (++iterIndex < iterLength) {
1915          var data = iteratees[iterIndex],
1916              iteratee = data.iteratee,
1917              type = data.type,
1918              computed = iteratee(value);
1919
1920          if (type == LAZY_MAP_FLAG) {
1921            value = computed;
1922          } else if (!computed) {
1923            if (type == LAZY_FILTER_FLAG) {
1924              continue outer;
1925            } else {
1926              break outer;
1927            }
1928          }
1929        }
1930        result[resIndex++] = value;
1931      }
1932      return result;
1933    }
1934
1935    // Ensure `LazyWrapper` is an instance of `baseLodash`.
1936    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1937    LazyWrapper.prototype.constructor = LazyWrapper;
1938
1939    /*------------------------------------------------------------------------*/
1940
1941    /**
1942     * Creates a hash object.
1943     *
1944     * @private
1945     * @constructor
1946     * @param {Array} [entries] The key-value pairs to cache.
1947     */
1948    function Hash(entries) {
1949      var index = -1,
1950          length = entries == null ? 0 : entries.length;
1951
1952      this.clear();
1953      while (++index < length) {
1954        var entry = entries[index];
1955        this.set(entry[0], entry[1]);
1956      }
1957    }
1958
1959    /**
1960     * Removes all key-value entries from the hash.
1961     *
1962     * @private
1963     * @name clear
1964     * @memberOf Hash
1965     */
1966    function hashClear() {
1967      this.__data__ = nativeCreate ? nativeCreate(null) : {};
1968      this.size = 0;
1969    }
1970
1971    /**
1972     * Removes `key` and its value from the hash.
1973     *
1974     * @private
1975     * @name delete
1976     * @memberOf Hash
1977     * @param {Object} hash The hash to modify.
1978     * @param {string} key The key of the value to remove.
1979     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1980     */
1981    function hashDelete(key) {
1982      var result = this.has(key) && delete this.__data__[key];
1983      this.size -= result ? 1 : 0;
1984      return result;
1985    }
1986
1987    /**
1988     * Gets the hash value for `key`.
1989     *
1990     * @private
1991     * @name get
1992     * @memberOf Hash
1993     * @param {string} key The key of the value to get.
1994     * @returns {*} Returns the entry value.
1995     */
1996    function hashGet(key) {
1997      var data = this.__data__;
1998      if (nativeCreate) {
1999        var result = data[key];
2000        return result === HASH_UNDEFINED ? undefined : result;
2001      }
2002      return hasOwnProperty.call(data, key) ? data[key] : undefined;
2003    }
2004
2005    /**
2006     * Checks if a hash value for `key` exists.
2007     *
2008     * @private
2009     * @name has
2010     * @memberOf Hash
2011     * @param {string} key The key of the entry to check.
2012     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2013     */
2014    function hashHas(key) {
2015      var data = this.__data__;
2016      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
2017    }
2018
2019    /**
2020     * Sets the hash `key` to `value`.
2021     *
2022     * @private
2023     * @name set
2024     * @memberOf Hash
2025     * @param {string} key The key of the value to set.
2026     * @param {*} value The value to set.
2027     * @returns {Object} Returns the hash instance.
2028     */
2029    function hashSet(key, value) {
2030      var data = this.__data__;
2031      this.size += this.has(key) ? 0 : 1;
2032      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
2033      return this;
2034    }
2035
2036    // Add methods to `Hash`.
2037    Hash.prototype.clear = hashClear;
2038    Hash.prototype['delete'] = hashDelete;
2039    Hash.prototype.get = hashGet;
2040    Hash.prototype.has = hashHas;
2041    Hash.prototype.set = hashSet;
2042
2043    /*------------------------------------------------------------------------*/
2044
2045    /**
2046     * Creates an list cache object.
2047     *
2048     * @private
2049     * @constructor
2050     * @param {Array} [entries] The key-value pairs to cache.
2051     */
2052    function ListCache(entries) {
2053      var index = -1,
2054          length = entries == null ? 0 : entries.length;
2055
2056      this.clear();
2057      while (++index < length) {
2058        var entry = entries[index];
2059        this.set(entry[0], entry[1]);
2060      }
2061    }
2062
2063    /**
2064     * Removes all key-value entries from the list cache.
2065     *
2066     * @private
2067     * @name clear
2068     * @memberOf ListCache
2069     */
2070    function listCacheClear() {
2071      this.__data__ = [];
2072      this.size = 0;
2073    }
2074
2075    /**
2076     * Removes `key` and its value from the list cache.
2077     *
2078     * @private
2079     * @name delete
2080     * @memberOf ListCache
2081     * @param {string} key The key of the value to remove.
2082     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2083     */
2084    function listCacheDelete(key) {
2085      var data = this.__data__,
2086          index = assocIndexOf(data, key);
2087
2088      if (index < 0) {
2089        return false;
2090      }
2091      var lastIndex = data.length - 1;
2092      if (index == lastIndex) {
2093        data.pop();
2094      } else {
2095        splice.call(data, index, 1);
2096      }
2097      --this.size;
2098      return true;
2099    }
2100
2101    /**
2102     * Gets the list cache value for `key`.
2103     *
2104     * @private
2105     * @name get
2106     * @memberOf ListCache
2107     * @param {string} key The key of the value to get.
2108     * @returns {*} Returns the entry value.
2109     */
2110    function listCacheGet(key) {
2111      var data = this.__data__,
2112          index = assocIndexOf(data, key);
2113
2114      return index < 0 ? undefined : data[index][1];
2115    }
2116
2117    /**
2118     * Checks if a list cache value for `key` exists.
2119     *
2120     * @private
2121     * @name has
2122     * @memberOf ListCache
2123     * @param {string} key The key of the entry to check.
2124     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2125     */
2126    function listCacheHas(key) {
2127      return assocIndexOf(this.__data__, key) > -1;
2128    }
2129
2130    /**
2131     * Sets the list cache `key` to `value`.
2132     *
2133     * @private
2134     * @name set
2135     * @memberOf ListCache
2136     * @param {string} key The key of the value to set.
2137     * @param {*} value The value to set.
2138     * @returns {Object} Returns the list cache instance.
2139     */
2140    function listCacheSet(key, value) {
2141      var data = this.__data__,
2142          index = assocIndexOf(data, key);
2143
2144      if (index < 0) {
2145        ++this.size;
2146        data.push([key, value]);
2147      } else {
2148        data[index][1] = value;
2149      }
2150      return this;
2151    }
2152
2153    // Add methods to `ListCache`.
2154    ListCache.prototype.clear = listCacheClear;
2155    ListCache.prototype['delete'] = listCacheDelete;
2156    ListCache.prototype.get = listCacheGet;
2157    ListCache.prototype.has = listCacheHas;
2158    ListCache.prototype.set = listCacheSet;
2159
2160    /*------------------------------------------------------------------------*/
2161
2162    /**
2163     * Creates a map cache object to store key-value pairs.
2164     *
2165     * @private
2166     * @constructor
2167     * @param {Array} [entries] The key-value pairs to cache.
2168     */
2169    function MapCache(entries) {
2170      var index = -1,
2171          length = entries == null ? 0 : entries.length;
2172
2173      this.clear();
2174      while (++index < length) {
2175        var entry = entries[index];
2176        this.set(entry[0], entry[1]);
2177      }
2178    }
2179
2180    /**
2181     * Removes all key-value entries from the map.
2182     *
2183     * @private
2184     * @name clear
2185     * @memberOf MapCache
2186     */
2187    function mapCacheClear() {
2188      this.size = 0;
2189      this.__data__ = {
2190        'hash': new Hash,
2191        'map': new (Map || ListCache),
2192        'string': new Hash
2193      };
2194    }
2195
2196    /**
2197     * Removes `key` and its value from the map.
2198     *
2199     * @private
2200     * @name delete
2201     * @memberOf MapCache
2202     * @param {string} key The key of the value to remove.
2203     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2204     */
2205    function mapCacheDelete(key) {
2206      var result = getMapData(this, key)['delete'](key);
2207      this.size -= result ? 1 : 0;
2208      return result;
2209    }
2210
2211    /**
2212     * Gets the map value for `key`.
2213     *
2214     * @private
2215     * @name get
2216     * @memberOf MapCache
2217     * @param {string} key The key of the value to get.
2218     * @returns {*} Returns the entry value.
2219     */
2220    function mapCacheGet(key) {
2221      return getMapData(this, key).get(key);
2222    }
2223
2224    /**
2225     * Checks if a map value for `key` exists.
2226     *
2227     * @private
2228     * @name has
2229     * @memberOf MapCache
2230     * @param {string} key The key of the entry to check.
2231     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2232     */
2233    function mapCacheHas(key) {
2234      return getMapData(this, key).has(key);
2235    }
2236
2237    /**
2238     * Sets the map `key` to `value`.
2239     *
2240     * @private
2241     * @name set
2242     * @memberOf MapCache
2243     * @param {string} key The key of the value to set.
2244     * @param {*} value The value to set.
2245     * @returns {Object} Returns the map cache instance.
2246     */
2247    function mapCacheSet(key, value) {
2248      var data = getMapData(this, key),
2249          size = data.size;
2250
2251      data.set(key, value);
2252      this.size += data.size == size ? 0 : 1;
2253      return this;
2254    }
2255
2256    // Add methods to `MapCache`.
2257    MapCache.prototype.clear = mapCacheClear;
2258    MapCache.prototype['delete'] = mapCacheDelete;
2259    MapCache.prototype.get = mapCacheGet;
2260    MapCache.prototype.has = mapCacheHas;
2261    MapCache.prototype.set = mapCacheSet;
2262
2263    /*------------------------------------------------------------------------*/
2264
2265    /**
2266     *
2267     * Creates an array cache object to store unique values.
2268     *
2269     * @private
2270     * @constructor
2271     * @param {Array} [values] The values to cache.
2272     */
2273    function SetCache(values) {
2274      var index = -1,
2275          length = values == null ? 0 : values.length;
2276
2277      this.__data__ = new MapCache;
2278      while (++index < length) {
2279        this.add(values[index]);
2280      }
2281    }
2282
2283    /**
2284     * Adds `value` to the array cache.
2285     *
2286     * @private
2287     * @name add
2288     * @memberOf SetCache
2289     * @alias push
2290     * @param {*} value The value to cache.
2291     * @returns {Object} Returns the cache instance.
2292     */
vendor: 3,741 bytes, lines 2293-2429
2293    function setCacheAdd(value) {
2294      this.__data__.set(value, HASH_UNDEFINED);
2295      return this;
2296    }
2297
2298    /**
2299     * Checks if `value` is in the array cache.
2300     *
2301     * @private
2302     * @name has
2303     * @memberOf SetCache
2304     * @param {*} value The value to search for.
2305     * @returns {number} Returns `true` if `value` is found, else `false`.
2306     */
2307    function setCacheHas(value) {
2308      return this.__data__.has(value);
2309    }
2310
2311    // Add methods to `SetCache`.
2312    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2313    SetCache.prototype.has = setCacheHas;
2314
2315    /*------------------------------------------------------------------------*/
2316
2317    /**
2318     * Creates a stack cache object to store key-value pairs.
2319     *
2320     * @private
2321     * @constructor
2322     * @param {Array} [entries] The key-value pairs to cache.
2323     */
2324    function Stack(entries) {
2325      var data = this.__data__ = new ListCache(entries);
2326      this.size = data.size;
2327    }
2328
2329    /**
2330     * Removes all key-value entries from the stack.
2331     *
2332     * @private
2333     * @name clear
2334     * @memberOf Stack
2335     */
2336    function stackClear() {
2337      this.__data__ = new ListCache;
2338      this.size = 0;
2339    }
2340
2341    /**
2342     * Removes `key` and its value from the stack.
2343     *
2344     * @private
2345     * @name delete
2346     * @memberOf Stack
2347     * @param {string} key The key of the value to remove.
2348     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2349     */
2350    function stackDelete(key) {
2351      var data = this.__data__,
2352          result = data['delete'](key);
2353
2354      this.size = data.size;
2355      return result;
2356    }
2357
2358    /**
2359     * Gets the stack value for `key`.
2360     *
2361     * @private
2362     * @name get
2363     * @memberOf Stack
2364     * @param {string} key The key of the value to get.
2365     * @returns {*} Returns the entry value.
2366     */
2367    function stackGet(key) {
2368      return this.__data__.get(key);
2369    }
2370
2371    /**
2372     * Checks if a stack value for `key` exists.
2373     *
2374     * @private
2375     * @name has
2376     * @memberOf Stack
2377     * @param {string} key The key of the entry to check.
2378     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2379     */
2380    function stackHas(key) {
2381      return this.__data__.has(key);
2382    }
2383
2384    /**
2385     * Sets the stack `key` to `value`.
2386     *
2387     * @private
2388     * @name set
2389     * @memberOf Stack
2390     * @param {string} key The key of the value to set.
2391     * @param {*} value The value to set.
2392     * @returns {Object} Returns the stack cache instance.
2393     */
2394    function stackSet(key, value) {
2395      var data = this.__data__;
2396      if (data instanceof ListCache) {
2397        var pairs = data.__data__;
2398        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2399          pairs.push([key, value]);
2400          this.size = ++data.size;
2401          return this;
2402        }
2403        data = this.__data__ = new MapCache(pairs);
2404      }
2405      data.set(key, value);
2406      this.size = data.size;
2407      return this;
2408    }
2409
2410    // Add methods to `Stack`.
2411    Stack.prototype.clear = stackClear;
2412    Stack.prototype['delete'] = stackDelete;
2413    Stack.prototype.get = stackGet;
2414    Stack.prototype.has = stackHas;
2415    Stack.prototype.set = stackSet;
2416
2417    /*------------------------------------------------------------------------*/
2418
2419    /**
2420     * Creates an array of the enumerable property names of the array-like `value`.
2421     *
2422     * @private
2423     * @param {*} value The value to query.
2424     * @param {boolean} inherited Specify returning inherited property names.
2425     * @returns {Array} Returns the array of property names.
2426     */
2427    function arrayLikeKeys(value, inherited) {
2428      var isArr = isArray(value),
2429          isArg = !isArr && isArguments(value),
vendor: 111,524 bytes, lines 2430-5723
2430          isBuff = !isArr && !isArg && isBuffer(value),
2431          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2432          skipIndexes = isArr || isArg || isBuff || isType,
2433          result = skipIndexes ? baseTimes(value.length, String) : [],
2434          length = result.length;
2435
2436      for (var key in value) {
2437        if ((inherited || hasOwnProperty.call(value, key)) &&
2438            !(skipIndexes && (
2439               // Safari 9 has enumerable `arguments.length` in strict mode.
2440               key == 'length' ||
2441               // Node.js 0.10 has enumerable non-index properties on buffers.
2442               (isBuff && (key == 'offset' || key == 'parent')) ||
2443               // PhantomJS 2 has enumerable non-index properties on typed arrays.
2444               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2445               // Skip index properties.
2446               isIndex(key, length)
2447            ))) {
2448          result.push(key);
2449        }
2450      }
2451      return result;
2452    }
2453
2454    /**
2455     * A specialized version of `_.sample` for arrays.
2456     *
2457     * @private
2458     * @param {Array} array The array to sample.
2459     * @returns {*} Returns the random element.
2460     */
2461    function arraySample(array) {
2462      var length = array.length;
2463      return length ? array[baseRandom(0, length - 1)] : undefined;
2464    }
2465
2466    /**
2467     * A specialized version of `_.sampleSize` for arrays.
2468     *
2469     * @private
2470     * @param {Array} array The array to sample.
2471     * @param {number} n The number of elements to sample.
2472     * @returns {Array} Returns the random elements.
2473     */
2474    function arraySampleSize(array, n) {
2475      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2476    }
2477
2478    /**
2479     * A specialized version of `_.shuffle` for arrays.
2480     *
2481     * @private
2482     * @param {Array} array The array to shuffle.
2483     * @returns {Array} Returns the new shuffled array.
2484     */
2485    function arrayShuffle(array) {
2486      return shuffleSelf(copyArray(array));
2487    }
2488
2489    /**
2490     * This function is like `assignValue` except that it doesn't assign
2491     * `undefined` values.
2492     *
2493     * @private
2494     * @param {Object} object The object to modify.
2495     * @param {string} key The key of the property to assign.
2496     * @param {*} value The value to assign.
2497     */
2498    function assignMergeValue(object, key, value) {
2499      if ((value !== undefined && !eq(object[key], value)) ||
2500          (value === undefined && !(key in object))) {
2501        baseAssignValue(object, key, value);
2502      }
2503    }
2504
2505    /**
2506     * Assigns `value` to `key` of `object` if the existing value is not equivalent
2507     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2508     * for equality comparisons.
2509     *
2510     * @private
2511     * @param {Object} object The object to modify.
2512     * @param {string} key The key of the property to assign.
2513     * @param {*} value The value to assign.
2514     */
2515    function assignValue(object, key, value) {
2516      var objValue = object[key];
2517      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2518          (value === undefined && !(key in object))) {
2519        baseAssignValue(object, key, value);
2520      }
2521    }
2522
2523    /**
2524     * Gets the index at which the `key` is found in `array` of key-value pairs.
2525     *
2526     * @private
2527     * @param {Array} array The array to inspect.
2528     * @param {*} key The key to search for.
2529     * @returns {number} Returns the index of the matched value, else `-1`.
2530     */
2531    function assocIndexOf(array, key) {
2532      var length = array.length;
2533      while (length--) {
2534        if (eq(array[length][0], key)) {
2535          return length;
2536        }
2537      }
2538      return -1;
2539    }
2540
2541    /**
2542     * Aggregates elements of `collection` on `accumulator` with keys transformed
2543     * by `iteratee` and values set by `setter`.
2544     *
2545     * @private
2546     * @param {Array|Object} collection The collection to iterate over.
2547     * @param {Function} setter The function to set `accumulator` values.
2548     * @param {Function} iteratee The iteratee to transform keys.
2549     * @param {Object} accumulator The initial aggregated object.
2550     * @returns {Function} Returns `accumulator`.
2551     */
2552    function baseAggregator(collection, setter, iteratee, accumulator) {
2553      baseEach(collection, function(value, key, collection) {
2554        setter(accumulator, value, iteratee(value), collection);
2555      });
2556      return accumulator;
2557    }
2558
2559    /**
2560     * The base implementation of `_.assign` without support for multiple sources
2561     * or `customizer` functions.
2562     *
2563     * @private
2564     * @param {Object} object The destination object.
2565     * @param {Object} source The source object.
2566     * @returns {Object} Returns `object`.
2567     */
2568    function baseAssign(object, source) {
2569      return object && copyObject(source, keys(source), object);
2570    }
2571
2572    /**
2573     * The base implementation of `_.assignIn` without support for multiple sources
2574     * or `customizer` functions.
2575     *
2576     * @private
2577     * @param {Object} object The destination object.
2578     * @param {Object} source The source object.
2579     * @returns {Object} Returns `object`.
2580     */
2581    function baseAssignIn(object, source) {
2582      return object && copyObject(source, keysIn(source), object);
2583    }
2584
2585    /**
2586     * The base implementation of `assignValue` and `assignMergeValue` without
2587     * value checks.
2588     *
2589     * @private
2590     * @param {Object} object The object to modify.
2591     * @param {string} key The key of the property to assign.
2592     * @param {*} value The value to assign.
2593     */
2594    function baseAssignValue(object, key, value) {
2595      if (key == '__proto__' && defineProperty) {
2596        defineProperty(object, key, {
2597          'configurable': true,
2598          'enumerable': true,
2599          'value': value,
2600          'writable': true
2601        });
2602      } else {
2603        object[key] = value;
2604      }
2605    }
2606
2607    /**
2608     * The base implementation of `_.at` without support for individual paths.
2609     *
2610     * @private
2611     * @param {Object} object The object to iterate over.
2612     * @param {string[]} paths The property paths to pick.
2613     * @returns {Array} Returns the picked elements.
2614     */
2615    function baseAt(object, paths) {
2616      var index = -1,
2617          length = paths.length,
2618          result = Array(length),
2619          skip = object == null;
2620
2621      while (++index < length) {
2622        result[index] = skip ? undefined : get(object, paths[index]);
2623      }
2624      return result;
2625    }
2626
2627    /**
2628     * The base implementation of `_.clamp` which doesn't coerce arguments.
2629     *
2630     * @private
2631     * @param {number} number The number to clamp.
2632     * @param {number} [lower] The lower bound.
2633     * @param {number} upper The upper bound.
2634     * @returns {number} Returns the clamped number.
2635     */
2636    function baseClamp(number, lower, upper) {
2637      if (number === number) {
2638        if (upper !== undefined) {
2639          number = number <= upper ? number : upper;
2640        }
2641        if (lower !== undefined) {
2642          number = number >= lower ? number : lower;
2643        }
2644      }
2645      return number;
2646    }
2647
2648    /**
2649     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2650     * traversed objects.
2651     *
2652     * @private
2653     * @param {*} value The value to clone.
2654     * @param {boolean} bitmask The bitmask flags.
2655     *  1 - Deep clone
2656     *  2 - Flatten inherited properties
2657     *  4 - Clone symbols
2658     * @param {Function} [customizer] The function to customize cloning.
2659     * @param {string} [key] The key of `value`.
2660     * @param {Object} [object] The parent object of `value`.
2661     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2662     * @returns {*} Returns the cloned value.
2663     */
2664    function baseClone(value, bitmask, customizer, key, object, stack) {
2665      var result,
2666          isDeep = bitmask & CLONE_DEEP_FLAG,
2667          isFlat = bitmask & CLONE_FLAT_FLAG,
2668          isFull = bitmask & CLONE_SYMBOLS_FLAG;
2669
2670      if (customizer) {
2671        result = object ? customizer(value, key, object, stack) : customizer(value);
2672      }
2673      if (result !== undefined) {
2674        return result;
2675      }
2676      if (!isObject(value)) {
2677        return value;
2678      }
2679      var isArr = isArray(value);
2680      if (isArr) {
2681        result = initCloneArray(value);
2682        if (!isDeep) {
2683          return copyArray(value, result);
2684        }
2685      } else {
2686        var tag = getTag(value),
2687            isFunc = tag == funcTag || tag == genTag;
2688
2689        if (isBuffer(value)) {
2690          return cloneBuffer(value, isDeep);
2691        }
2692        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2693          result = (isFlat || isFunc) ? {} : initCloneObject(value);
2694          if (!isDeep) {
2695            return isFlat
2696              ? copySymbolsIn(value, baseAssignIn(result, value))
2697              : copySymbols(value, baseAssign(result, value));
2698          }
2699        } else {
2700          if (!cloneableTags[tag]) {
2701            return object ? value : {};
2702          }
2703          result = initCloneByTag(value, tag, isDeep);
2704        }
2705      }
2706      // Check for circular references and return its corresponding clone.
2707      stack || (stack = new Stack);
2708      var stacked = stack.get(value);
2709      if (stacked) {
2710        return stacked;
2711      }
2712      stack.set(value, result);
2713
2714      if (isSet(value)) {
2715        value.forEach(function(subValue) {
2716          result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
2717        });
2718      } else if (isMap(value)) {
2719        value.forEach(function(subValue, key) {
2720          result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
2721        });
2722      }
2723
2724      var keysFunc = isFull
2725        ? (isFlat ? getAllKeysIn : getAllKeys)
2726        : (isFlat ? keysIn : keys);
2727
2728      var props = isArr ? undefined : keysFunc(value);
2729      arrayEach(props || value, function(subValue, key) {
2730        if (props) {
2731          key = subValue;
2732          subValue = value[key];
2733        }
2734        // Recursively populate clone (susceptible to call stack limits).
2735        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2736      });
2737      return result;
2738    }
2739
2740    /**
2741     * The base implementation of `_.conforms` which doesn't clone `source`.
2742     *
2743     * @private
2744     * @param {Object} source The object of property predicates to conform to.
2745     * @returns {Function} Returns the new spec function.
2746     */
2747    function baseConforms(source) {
2748      var props = keys(source);
2749      return function(object) {
2750        return baseConformsTo(object, source, props);
2751      };
2752    }
2753
2754    /**
2755     * The base implementation of `_.conformsTo` which accepts `props` to check.
2756     *
2757     * @private
2758     * @param {Object} object The object to inspect.
2759     * @param {Object} source The object of property predicates to conform to.
2760     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2761     */
2762    function baseConformsTo(object, source, props) {
2763      var length = props.length;
2764      if (object == null) {
2765        return !length;
2766      }
2767      object = Object(object);
2768      while (length--) {
2769        var key = props[length],
2770            predicate = source[key],
2771            value = object[key];
2772
2773        if ((value === undefined && !(key in object)) || !predicate(value)) {
2774          return false;
2775        }
2776      }
2777      return true;
2778    }
2779
2780    /**
2781     * The base implementation of `_.delay` and `_.defer` which accepts `args`
2782     * to provide to `func`.
2783     *
2784     * @private
2785     * @param {Function} func The function to delay.
2786     * @param {number} wait The number of milliseconds to delay invocation.
2787     * @param {Array} args The arguments to provide to `func`.
2788     * @returns {number|Object} Returns the timer id or timeout object.
2789     */
2790    function baseDelay(func, wait, args) {
2791      if (typeof func != 'function') {
2792        throw new TypeError(FUNC_ERROR_TEXT);
2793      }
2794      return setTimeout(function() { func.apply(undefined, args); }, wait);
2795    }
2796
2797    /**
2798     * The base implementation of methods like `_.difference` without support
2799     * for excluding multiple arrays or iteratee shorthands.
2800     *
2801     * @private
2802     * @param {Array} array The array to inspect.
2803     * @param {Array} values The values to exclude.
2804     * @param {Function} [iteratee] The iteratee invoked per element.
2805     * @param {Function} [comparator] The comparator invoked per element.
2806     * @returns {Array} Returns the new array of filtered values.
2807     */
2808    function baseDifference(array, values, iteratee, comparator) {
2809      var index = -1,
2810          includes = arrayIncludes,
2811          isCommon = true,
2812          length = array.length,
2813          result = [],
2814          valuesLength = values.length;
2815
2816      if (!length) {
2817        return result;
2818      }
2819      if (iteratee) {
2820        values = arrayMap(values, baseUnary(iteratee));
2821      }
2822      if (comparator) {
2823        includes = arrayIncludesWith;
2824        isCommon = false;
2825      }
2826      else if (values.length >= LARGE_ARRAY_SIZE) {
2827        includes = cacheHas;
2828        isCommon = false;
2829        values = new SetCache(values);
2830      }
2831      outer:
2832      while (++index < length) {
2833        var value = array[index],
2834            computed = iteratee == null ? value : iteratee(value);
2835
2836        value = (comparator || value !== 0) ? value : 0;
2837        if (isCommon && computed === computed) {
2838          var valuesIndex = valuesLength;
2839          while (valuesIndex--) {
2840            if (values[valuesIndex] === computed) {
2841              continue outer;
2842            }
2843          }
2844          result.push(value);
2845        }
2846        else if (!includes(values, computed, comparator)) {
2847          result.push(value);
2848        }
2849      }
2850      return result;
2851    }
2852
2853    /**
2854     * The base implementation of `_.forEach` without support for iteratee shorthands.
2855     *
2856     * @private
2857     * @param {Array|Object} collection The collection to iterate over.
2858     * @param {Function} iteratee The function invoked per iteration.
2859     * @returns {Array|Object} Returns `collection`.
2860     */
2861    var baseEach = createBaseEach(baseForOwn);
2862
2863    /**
2864     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2865     *
2866     * @private
2867     * @param {Array|Object} collection The collection to iterate over.
2868     * @param {Function} iteratee The function invoked per iteration.
2869     * @returns {Array|Object} Returns `collection`.
2870     */
2871    var baseEachRight = createBaseEach(baseForOwnRight, true);
2872
2873    /**
2874     * The base implementation of `_.every` without support for iteratee shorthands.
2875     *
2876     * @private
2877     * @param {Array|Object} collection The collection to iterate over.
2878     * @param {Function} predicate The function invoked per iteration.
2879     * @returns {boolean} Returns `true` if all elements pass the predicate check,
2880     *  else `false`
2881     */
2882    function baseEvery(collection, predicate) {
2883      var result = true;
2884      baseEach(collection, function(value, index, collection) {
2885        result = !!predicate(value, index, collection);
2886        return result;
2887      });
2888      return result;
2889    }
2890
2891    /**
2892     * The base implementation of methods like `_.max` and `_.min` which accepts a
2893     * `comparator` to determine the extremum value.
2894     *
2895     * @private
2896     * @param {Array} array The array to iterate over.
2897     * @param {Function} iteratee The iteratee invoked per iteration.
2898     * @param {Function} comparator The comparator used to compare values.
2899     * @returns {*} Returns the extremum value.
2900     */
2901    function baseExtremum(array, iteratee, comparator) {
2902      var index = -1,
2903          length = array.length;
2904
2905      while (++index < length) {
2906        var value = array[index],
2907            current = iteratee(value);
2908
2909        if (current != null && (computed === undefined
2910              ? (current === current && !isSymbol(current))
2911              : comparator(current, computed)
2912            )) {
2913          var computed = current,
2914              result = value;
2915        }
2916      }
2917      return result;
2918    }
2919
2920    /**
2921     * The base implementation of `_.fill` without an iteratee call guard.
2922     *
2923     * @private
2924     * @param {Array} array The array to fill.
2925     * @param {*} value The value to fill `array` with.
2926     * @param {number} [start=0] The start position.
2927     * @param {number} [end=array.length] The end position.
2928     * @returns {Array} Returns `array`.
2929     */
2930    function baseFill(array, value, start, end) {
2931      var length = array.length;
2932
2933      start = toInteger(start);
2934      if (start < 0) {
2935        start = -start > length ? 0 : (length + start);
2936      }
2937      end = (end === undefined || end > length) ? length : toInteger(end);
2938      if (end < 0) {
2939        end += length;
2940      }
2941      end = start > end ? 0 : toLength(end);
2942      while (start < end) {
2943        array[start++] = value;
2944      }
2945      return array;
2946    }
2947
2948    /**
2949     * The base implementation of `_.filter` without support for iteratee shorthands.
2950     *
2951     * @private
2952     * @param {Array|Object} collection The collection to iterate over.
2953     * @param {Function} predicate The function invoked per iteration.
2954     * @returns {Array} Returns the new filtered array.
2955     */
2956    function baseFilter(collection, predicate) {
2957      var result = [];
2958      baseEach(collection, function(value, index, collection) {
2959        if (predicate(value, index, collection)) {
2960          result.push(value);
2961        }
2962      });
2963      return result;
2964    }
2965
2966    /**
2967     * The base implementation of `_.flatten` with support for restricting flattening.
2968     *
2969     * @private
2970     * @param {Array} array The array to flatten.
2971     * @param {number} depth The maximum recursion depth.
2972     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2973     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2974     * @param {Array} [result=[]] The initial result value.
2975     * @returns {Array} Returns the new flattened array.
2976     */
2977    function baseFlatten(array, depth, predicate, isStrict, result) {
2978      var index = -1,
2979          length = array.length;
2980
2981      predicate || (predicate = isFlattenable);
2982      result || (result = []);
2983
2984      while (++index < length) {
2985        var value = array[index];
2986        if (depth > 0 && predicate(value)) {
2987          if (depth > 1) {
2988            // Recursively flatten arrays (susceptible to call stack limits).
2989            baseFlatten(value, depth - 1, predicate, isStrict, result);
2990          } else {
2991            arrayPush(result, value);
2992          }
2993        } else if (!isStrict) {
2994          result[result.length] = value;
2995        }
2996      }
2997      return result;
2998    }
2999
3000    /**
3001     * The base implementation of `baseForOwn` which iterates over `object`
3002     * properties returned by `keysFunc` and invokes `iteratee` for each property.
3003     * Iteratee functions may exit iteration early by explicitly returning `false`.
3004     *
3005     * @private
3006     * @param {Object} object The object to iterate over.
3007     * @param {Function} iteratee The function invoked per iteration.
3008     * @param {Function} keysFunc The function to get the keys of `object`.
3009     * @returns {Object} Returns `object`.
3010     */
3011    var baseFor = createBaseFor();
3012
3013    /**
3014     * This function is like `baseFor` except that it iterates over properties
3015     * in the opposite order.
3016     *
3017     * @private
3018     * @param {Object} object The object to iterate over.
3019     * @param {Function} iteratee The function invoked per iteration.
3020     * @param {Function} keysFunc The function to get the keys of `object`.
3021     * @returns {Object} Returns `object`.
3022     */
3023    var baseForRight = createBaseFor(true);
3024
3025    /**
3026     * The base implementation of `_.forOwn` without support for iteratee shorthands.
3027     *
3028     * @private
3029     * @param {Object} object The object to iterate over.
3030     * @param {Function} iteratee The function invoked per iteration.
3031     * @returns {Object} Returns `object`.
3032     */
3033    function baseForOwn(object, iteratee) {
3034      return object && baseFor(object, iteratee, keys);
3035    }
3036
3037    /**
3038     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
3039     *
3040     * @private
3041     * @param {Object} object The object to iterate over.
3042     * @param {Function} iteratee The function invoked per iteration.
3043     * @returns {Object} Returns `object`.
3044     */
3045    function baseForOwnRight(object, iteratee) {
3046      return object && baseForRight(object, iteratee, keys);
3047    }
3048
3049    /**
3050     * The base implementation of `_.functions` which creates an array of
3051     * `object` function property names filtered from `props`.
3052     *
3053     * @private
3054     * @param {Object} object The object to inspect.
3055     * @param {Array} props The property names to filter.
3056     * @returns {Array} Returns the function names.
3057     */
3058    function baseFunctions(object, props) {
3059      return arrayFilter(props, function(key) {
3060        return isFunction(object[key]);
3061      });
3062    }
3063
3064    /**
3065     * The base implementation of `_.get` without support for default values.
3066     *
3067     * @private
3068     * @param {Object} object The object to query.
3069     * @param {Array|string} path The path of the property to get.
3070     * @returns {*} Returns the resolved value.
3071     */
3072    function baseGet(object, path) {
3073      path = castPath(path, object);
3074
3075      var index = 0,
3076          length = path.length;
3077
3078      while (object != null && index < length) {
3079        object = object[toKey(path[index++])];
3080      }
3081      return (index && index == length) ? object : undefined;
3082    }
3083
3084    /**
3085     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3086     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3087     * symbols of `object`.
3088     *
3089     * @private
3090     * @param {Object} object The object to query.
3091     * @param {Function} keysFunc The function to get the keys of `object`.
3092     * @param {Function} symbolsFunc The function to get the symbols of `object`.
3093     * @returns {Array} Returns the array of property names and symbols.
3094     */
3095    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3096      var result = keysFunc(object);
3097      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3098    }
3099
3100    /**
3101     * The base implementation of `getTag` without fallbacks for buggy environments.
3102     *
3103     * @private
3104     * @param {*} value The value to query.
3105     * @returns {string} Returns the `toStringTag`.
3106     */
3107    function baseGetTag(value) {
3108      if (value == null) {
3109        return value === undefined ? undefinedTag : nullTag;
3110      }
3111      return (symToStringTag && symToStringTag in Object(value))
3112        ? getRawTag(value)
3113        : objectToString(value);
3114    }
3115
3116    /**
3117     * The base implementation of `_.gt` which doesn't coerce arguments.
3118     *
3119     * @private
3120     * @param {*} value The value to compare.
3121     * @param {*} other The other value to compare.
3122     * @returns {boolean} Returns `true` if `value` is greater than `other`,
3123     *  else `false`.
3124     */
3125    function baseGt(value, other) {
3126      return value > other;
3127    }
3128
3129    /**
3130     * The base implementation of `_.has` without support for deep paths.
3131     *
3132     * @private
3133     * @param {Object} [object] The object to query.
3134     * @param {Array|string} key The key to check.
3135     * @returns {boolean} Returns `true` if `key` exists, else `false`.
3136     */
3137    function baseHas(object, key) {
3138      return object != null && hasOwnProperty.call(object, key);
3139    }
3140
3141    /**
3142     * The base implementation of `_.hasIn` without support for deep paths.
3143     *
3144     * @private
3145     * @param {Object} [object] The object to query.
3146     * @param {Array|string} key The key to check.
3147     * @returns {boolean} Returns `true` if `key` exists, else `false`.
3148     */
3149    function baseHasIn(object, key) {
3150      return object != null && key in Object(object);
3151    }
3152
3153    /**
3154     * The base implementation of `_.inRange` which doesn't coerce arguments.
3155     *
3156     * @private
3157     * @param {number} number The number to check.
3158     * @param {number} start The start of the range.
3159     * @param {number} end The end of the range.
3160     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3161     */
3162    function baseInRange(number, start, end) {
3163      return number >= nativeMin(start, end) && number < nativeMax(start, end);
3164    }
3165
3166    /**
3167     * The base implementation of methods like `_.intersection`, without support
3168     * for iteratee shorthands, that accepts an array of arrays to inspect.
3169     *
3170     * @private
3171     * @param {Array} arrays The arrays to inspect.
3172     * @param {Function} [iteratee] The iteratee invoked per element.
3173     * @param {Function} [comparator] The comparator invoked per element.
3174     * @returns {Array} Returns the new array of shared values.
3175     */
3176    function baseIntersection(arrays, iteratee, comparator) {
3177      var includes = comparator ? arrayIncludesWith : arrayIncludes,
3178          length = arrays[0].length,
3179          othLength = arrays.length,
3180          othIndex = othLength,
3181          caches = Array(othLength),
3182          maxLength = Infinity,
3183          result = [];
3184
3185      while (othIndex--) {
3186        var array = arrays[othIndex];
3187        if (othIndex && iteratee) {
3188          array = arrayMap(array, baseUnary(iteratee));
3189        }
3190        maxLength = nativeMin(array.length, maxLength);
3191        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3192          ? new SetCache(othIndex && array)
3193          : undefined;
3194      }
3195      array = arrays[0];
3196
3197      var index = -1,
3198          seen = caches[0];
3199
3200      outer:
3201      while (++index < length && result.length < maxLength) {
3202        var value = array[index],
3203            computed = iteratee ? iteratee(value) : value;
3204
3205        value = (comparator || value !== 0) ? value : 0;
3206        if (!(seen
3207              ? cacheHas(seen, computed)
3208              : includes(result, computed, comparator)
3209            )) {
3210          othIndex = othLength;
3211          while (--othIndex) {
3212            var cache = caches[othIndex];
3213            if (!(cache
3214                  ? cacheHas(cache, computed)
3215                  : includes(arrays[othIndex], computed, comparator))
3216                ) {
3217              continue outer;
3218            }
3219          }
3220          if (seen) {
3221            seen.push(computed);
3222          }
3223          result.push(value);
3224        }
3225      }
3226      return result;
3227    }
3228
3229    /**
3230     * The base implementation of `_.invert` and `_.invertBy` which inverts
3231     * `object` with values transformed by `iteratee` and set by `setter`.
3232     *
3233     * @private
3234     * @param {Object} object The object to iterate over.
3235     * @param {Function} setter The function to set `accumulator` values.
3236     * @param {Function} iteratee The iteratee to transform values.
3237     * @param {Object} accumulator The initial inverted object.
3238     * @returns {Function} Returns `accumulator`.
3239     */
3240    function baseInverter(object, setter, iteratee, accumulator) {
3241      baseForOwn(object, function(value, key, object) {
3242        setter(accumulator, iteratee(value), key, object);
3243      });
3244      return accumulator;
3245    }
3246
3247    /**
3248     * The base implementation of `_.invoke` without support for individual
3249     * method arguments.
3250     *
3251     * @private
3252     * @param {Object} object The object to query.
3253     * @param {Array|string} path The path of the method to invoke.
3254     * @param {Array} args The arguments to invoke the method with.
3255     * @returns {*} Returns the result of the invoked method.
3256     */
3257    function baseInvoke(object, path, args) {
3258      path = castPath(path, object);
3259      object = parent(object, path);
3260      var func = object == null ? object : object[toKey(last(path))];
3261      return func == null ? undefined : apply(func, object, args);
3262    }
3263
3264    /**
3265     * The base implementation of `_.isArguments`.
3266     *
3267     * @private
3268     * @param {*} value The value to check.
3269     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3270     */
3271    function baseIsArguments(value) {
3272      return isObjectLike(value) && baseGetTag(value) == argsTag;
3273    }
3274
3275    /**
3276     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3277     *
3278     * @private
3279     * @param {*} value The value to check.
3280     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3281     */
3282    function baseIsArrayBuffer(value) {
3283      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3284    }
3285
3286    /**
3287     * The base implementation of `_.isDate` without Node.js optimizations.
3288     *
3289     * @private
3290     * @param {*} value The value to check.
3291     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3292     */
3293    function baseIsDate(value) {
3294      return isObjectLike(value) && baseGetTag(value) == dateTag;
3295    }
3296
3297    /**
3298     * The base implementation of `_.isEqual` which supports partial comparisons
3299     * and tracks traversed objects.
3300     *
3301     * @private
3302     * @param {*} value The value to compare.
3303     * @param {*} other The other value to compare.
3304     * @param {boolean} bitmask The bitmask flags.
3305     *  1 - Unordered comparison
3306     *  2 - Partial comparison
3307     * @param {Function} [customizer] The function to customize comparisons.
3308     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3309     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3310     */
3311    function baseIsEqual(value, other, bitmask, customizer, stack) {
3312      if (value === other) {
3313        return true;
3314      }
3315      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
3316        return value !== value && other !== other;
3317      }
3318      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3319    }
3320
3321    /**
3322     * A specialized version of `baseIsEqual` for arrays and objects which performs
3323     * deep comparisons and tracks traversed objects enabling objects with circular
3324     * references to be compared.
3325     *
3326     * @private
3327     * @param {Object} object The object to compare.
3328     * @param {Object} other The other object to compare.
3329     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3330     * @param {Function} customizer The function to customize comparisons.
3331     * @param {Function} equalFunc The function to determine equivalents of values.
3332     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3333     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3334     */
3335    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3336      var objIsArr = isArray(object),
3337          othIsArr = isArray(other),
3338          objTag = objIsArr ? arrayTag : getTag(object),
3339          othTag = othIsArr ? arrayTag : getTag(other);
3340
3341      objTag = objTag == argsTag ? objectTag : objTag;
3342      othTag = othTag == argsTag ? objectTag : othTag;
3343
3344      var objIsObj = objTag == objectTag,
3345          othIsObj = othTag == objectTag,
3346          isSameTag = objTag == othTag;
3347
3348      if (isSameTag && isBuffer(object)) {
3349        if (!isBuffer(other)) {
3350          return false;
3351        }
3352        objIsArr = true;
3353        objIsObj = false;
3354      }
3355      if (isSameTag && !objIsObj) {
3356        stack || (stack = new Stack);
3357        return (objIsArr || isTypedArray(object))
3358          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3359          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3360      }
3361      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3362        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3363            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3364
3365        if (objIsWrapped || othIsWrapped) {
3366          var objUnwrapped = objIsWrapped ? object.value() : object,
3367              othUnwrapped = othIsWrapped ? other.value() : other;
3368
3369          stack || (stack = new Stack);
3370          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3371        }
3372      }
3373      if (!isSameTag) {
3374        return false;
3375      }
3376      stack || (stack = new Stack);
3377      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3378    }
3379
3380    /**
3381     * The base implementation of `_.isMap` without Node.js optimizations.
3382     *
3383     * @private
3384     * @param {*} value The value to check.
3385     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3386     */
3387    function baseIsMap(value) {
3388      return isObjectLike(value) && getTag(value) == mapTag;
3389    }
3390
3391    /**
3392     * The base implementation of `_.isMatch` without support for iteratee shorthands.
3393     *
3394     * @private
3395     * @param {Object} object The object to inspect.
3396     * @param {Object} source The object of property values to match.
3397     * @param {Array} matchData The property names, values, and compare flags to match.
3398     * @param {Function} [customizer] The function to customize comparisons.
3399     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3400     */
3401    function baseIsMatch(object, source, matchData, customizer) {
3402      var index = matchData.length,
3403          length = index,
3404          noCustomizer = !customizer;
3405
3406      if (object == null) {
3407        return !length;
3408      }
3409      object = Object(object);
3410      while (index--) {
3411        var data = matchData[index];
3412        if ((noCustomizer && data[2])
3413              ? data[1] !== object[data[0]]
3414              : !(data[0] in object)
3415            ) {
3416          return false;
3417        }
3418      }
3419      while (++index < length) {
3420        data = matchData[index];
3421        var key = data[0],
3422            objValue = object[key],
3423            srcValue = data[1];
3424
3425        if (noCustomizer && data[2]) {
3426          if (objValue === undefined && !(key in object)) {
3427            return false;
3428          }
3429        } else {
3430          var stack = new Stack;
3431          if (customizer) {
3432            var result = customizer(objValue, srcValue, key, object, source, stack);
3433          }
3434          if (!(result === undefined
3435                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3436                : result
3437              )) {
3438            return false;
3439          }
3440        }
3441      }
3442      return true;
3443    }
3444
3445    /**
3446     * The base implementation of `_.isNative` without bad shim checks.
3447     *
3448     * @private
3449     * @param {*} value The value to check.
3450     * @returns {boolean} Returns `true` if `value` is a native function,
3451     *  else `false`.
3452     */
3453    function baseIsNative(value) {
3454      if (!isObject(value) || isMasked(value)) {
3455        return false;
3456      }
3457      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3458      return pattern.test(toSource(value));
3459    }
3460
3461    /**
3462     * The base implementation of `_.isRegExp` without Node.js optimizations.
3463     *
3464     * @private
3465     * @param {*} value The value to check.
3466     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3467     */
3468    function baseIsRegExp(value) {
3469      return isObjectLike(value) && baseGetTag(value) == regexpTag;
3470    }
3471
3472    /**
3473     * The base implementation of `_.isSet` without Node.js optimizations.
3474     *
3475     * @private
3476     * @param {*} value The value to check.
3477     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3478     */
3479    function baseIsSet(value) {
3480      return isObjectLike(value) && getTag(value) == setTag;
3481    }
3482
3483    /**
3484     * The base implementation of `_.isTypedArray` without Node.js optimizations.
3485     *
3486     * @private
3487     * @param {*} value The value to check.
3488     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3489     */
3490    function baseIsTypedArray(value) {
3491      return isObjectLike(value) &&
3492        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3493    }
3494
3495    /**
3496     * The base implementation of `_.iteratee`.
3497     *
3498     * @private
3499     * @param {*} [value=_.identity] The value to convert to an iteratee.
3500     * @returns {Function} Returns the iteratee.
3501     */
3502    function baseIteratee(value) {
3503      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3504      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3505      if (typeof value == 'function') {
3506        return value;
3507      }
3508      if (value == null) {
3509        return identity;
3510      }
3511      if (typeof value == 'object') {
3512        return isArray(value)
3513          ? baseMatchesProperty(value[0], value[1])
3514          : baseMatches(value);
3515      }
3516      return property(value);
3517    }
3518
3519    /**
3520     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3521     *
3522     * @private
3523     * @param {Object} object The object to query.
3524     * @returns {Array} Returns the array of property names.
3525     */
3526    function baseKeys(object) {
3527      if (!isPrototype(object)) {
3528        return nativeKeys(object);
3529      }
3530      var result = [];
3531      for (var key in Object(object)) {
3532        if (hasOwnProperty.call(object, key) && key != 'constructor') {
3533          result.push(key);
3534        }
3535      }
3536      return result;
3537    }
3538
3539    /**
3540     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3541     *
3542     * @private
3543     * @param {Object} object The object to query.
3544     * @returns {Array} Returns the array of property names.
3545     */
3546    function baseKeysIn(object) {
3547      if (!isObject(object)) {
3548        return nativeKeysIn(object);
3549      }
3550      var isProto = isPrototype(object),
3551          result = [];
3552
3553      for (var key in object) {
3554        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3555          result.push(key);
3556        }
3557      }
3558      return result;
3559    }
3560
3561    /**
3562     * The base implementation of `_.lt` which doesn't coerce arguments.
3563     *
3564     * @private
3565     * @param {*} value The value to compare.
3566     * @param {*} other The other value to compare.
3567     * @returns {boolean} Returns `true` if `value` is less than `other`,
3568     *  else `false`.
3569     */
3570    function baseLt(value, other) {
3571      return value < other;
3572    }
3573
3574    /**
3575     * The base implementation of `_.map` without support for iteratee shorthands.
3576     *
3577     * @private
3578     * @param {Array|Object} collection The collection to iterate over.
3579     * @param {Function} iteratee The function invoked per iteration.
3580     * @returns {Array} Returns the new mapped array.
3581     */
3582    function baseMap(collection, iteratee) {
3583      var index = -1,
3584          result = isArrayLike(collection) ? Array(collection.length) : [];
3585
3586      baseEach(collection, function(value, key, collection) {
3587        result[++index] = iteratee(value, key, collection);
3588      });
3589      return result;
3590    }
3591
3592    /**
3593     * The base implementation of `_.matches` which doesn't clone `source`.
3594     *
3595     * @private
3596     * @param {Object} source The object of property values to match.
3597     * @returns {Function} Returns the new spec function.
3598     */
3599    function baseMatches(source) {
3600      var matchData = getMatchData(source);
3601      if (matchData.length == 1 && matchData[0][2]) {
3602        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3603      }
3604      return function(object) {
3605        return object === source || baseIsMatch(object, source, matchData);
3606      };
3607    }
3608
3609    /**
3610     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3611     *
3612     * @private
3613     * @param {string} path The path of the property to get.
3614     * @param {*} srcValue The value to match.
3615     * @returns {Function} Returns the new spec function.
3616     */
3617    function baseMatchesProperty(path, srcValue) {
3618      if (isKey(path) && isStrictComparable(srcValue)) {
3619        return matchesStrictComparable(toKey(path), srcValue);
3620      }
3621      return function(object) {
3622        var objValue = get(object, path);
3623        return (objValue === undefined && objValue === srcValue)
3624          ? hasIn(object, path)
3625          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3626      };
3627    }
3628
3629    /**
3630     * The base implementation of `_.merge` without support for multiple sources.
3631     *
3632     * @private
3633     * @param {Object} object The destination object.
3634     * @param {Object} source The source object.
3635     * @param {number} srcIndex The index of `source`.
3636     * @param {Function} [customizer] The function to customize merged values.
3637     * @param {Object} [stack] Tracks traversed source values and their merged
3638     *  counterparts.
3639     */
3640    function baseMerge(object, source, srcIndex, customizer, stack) {
3641      if (object === source) {
3642        return;
3643      }
3644      baseFor(source, function(srcValue, key) {
3645        stack || (stack = new Stack);
3646        if (isObject(srcValue)) {
3647          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3648        }
3649        else {
3650          var newValue = customizer
3651            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
3652            : undefined;
3653
3654          if (newValue === undefined) {
3655            newValue = srcValue;
3656          }
3657          assignMergeValue(object, key, newValue);
3658        }
3659      }, keysIn);
3660    }
3661
3662    /**
3663     * A specialized version of `baseMerge` for arrays and objects which performs
3664     * deep merges and tracks traversed objects enabling objects with circular
3665     * references to be merged.
3666     *
3667     * @private
3668     * @param {Object} object The destination object.
3669     * @param {Object} source The source object.
3670     * @param {string} key The key of the value to merge.
3671     * @param {number} srcIndex The index of `source`.
3672     * @param {Function} mergeFunc The function to merge values.
3673     * @param {Function} [customizer] The function to customize assigned values.
3674     * @param {Object} [stack] Tracks traversed source values and their merged
3675     *  counterparts.
3676     */
3677    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3678      var objValue = safeGet(object, key),
3679          srcValue = safeGet(source, key),
3680          stacked = stack.get(srcValue);
3681
3682      if (stacked) {
3683        assignMergeValue(object, key, stacked);
3684        return;
3685      }
3686      var newValue = customizer
3687        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3688        : undefined;
3689
3690      var isCommon = newValue === undefined;
3691
3692      if (isCommon) {
3693        var isArr = isArray(srcValue),
3694            isBuff = !isArr && isBuffer(srcValue),
3695            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3696
3697        newValue = srcValue;
3698        if (isArr || isBuff || isTyped) {
3699          if (isArray(objValue)) {
3700            newValue = objValue;
3701          }
3702          else if (isArrayLikeObject(objValue)) {
3703            newValue = copyArray(objValue);
3704          }
3705          else if (isBuff) {
3706            isCommon = false;
3707            newValue = cloneBuffer(srcValue, true);
3708          }
3709          else if (isTyped) {
3710            isCommon = false;
3711            newValue = cloneTypedArray(srcValue, true);
3712          }
3713          else {
3714            newValue = [];
3715          }
3716        }
3717        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3718          newValue = objValue;
3719          if (isArguments(objValue)) {
3720            newValue = toPlainObject(objValue);
3721          }
3722          else if (!isObject(objValue) || isFunction(objValue)) {
3723            newValue = initCloneObject(srcValue);
3724          }
3725        }
3726        else {
3727          isCommon = false;
3728        }
3729      }
3730      if (isCommon) {
3731        // Recursively merge objects and arrays (susceptible to call stack limits).
3732        stack.set(srcValue, newValue);
3733        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3734        stack['delete'](srcValue);
3735      }
3736      assignMergeValue(object, key, newValue);
3737    }
3738
3739    /**
3740     * The base implementation of `_.nth` which doesn't coerce arguments.
3741     *
3742     * @private
3743     * @param {Array} array The array to query.
3744     * @param {number} n The index of the element to return.
3745     * @returns {*} Returns the nth element of `array`.
3746     */
3747    function baseNth(array, n) {
3748      var length = array.length;
3749      if (!length) {
3750        return;
3751      }
3752      n += n < 0 ? length : 0;
3753      return isIndex(n, length) ? array[n] : undefined;
3754    }
3755
3756    /**
3757     * The base implementation of `_.orderBy` without param guards.
3758     *
3759     * @private
3760     * @param {Array|Object} collection The collection to iterate over.
3761     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3762     * @param {string[]} orders The sort orders of `iteratees`.
3763     * @returns {Array} Returns the new sorted array.
3764     */
3765    function baseOrderBy(collection, iteratees, orders) {
3766      if (iteratees.length) {
3767        iteratees = arrayMap(iteratees, function(iteratee) {
3768          if (isArray(iteratee)) {
3769            return function(value) {
3770              return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
3771            }
3772          }
3773          return iteratee;
3774        });
3775      } else {
3776        iteratees = [identity];
3777      }
3778
3779      var index = -1;
3780      iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
3781
3782      var result = baseMap(collection, function(value, key, collection) {
3783        var criteria = arrayMap(iteratees, function(iteratee) {
3784          return iteratee(value);
3785        });
3786        return { 'criteria': criteria, 'index': ++index, 'value': value };
3787      });
3788
3789      return baseSortBy(result, function(object, other) {
3790        return compareMultiple(object, other, orders);
3791      });
3792    }
3793
3794    /**
3795     * The base implementation of `_.pick` without support for individual
3796     * property identifiers.
3797     *
3798     * @private
3799     * @param {Object} object The source object.
3800     * @param {string[]} paths The property paths to pick.
3801     * @returns {Object} Returns the new object.
3802     */
3803    function basePick(object, paths) {
3804      return basePickBy(object, paths, function(value, path) {
3805        return hasIn(object, path);
3806      });
3807    }
3808
3809    /**
3810     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3811     *
3812     * @private
3813     * @param {Object} object The source object.
3814     * @param {string[]} paths The property paths to pick.
3815     * @param {Function} predicate The function invoked per property.
3816     * @returns {Object} Returns the new object.
3817     */
3818    function basePickBy(object, paths, predicate) {
3819      var index = -1,
3820          length = paths.length,
3821          result = {};
3822
3823      while (++index < length) {
3824        var path = paths[index],
3825            value = baseGet(object, path);
3826
3827        if (predicate(value, path)) {
3828          baseSet(result, castPath(path, object), value);
3829        }
3830      }
3831      return result;
3832    }
3833
3834    /**
3835     * A specialized version of `baseProperty` which supports deep paths.
3836     *
3837     * @private
3838     * @param {Array|string} path The path of the property to get.
3839     * @returns {Function} Returns the new accessor function.
3840     */
3841    function basePropertyDeep(path) {
3842      return function(object) {
3843        return baseGet(object, path);
3844      };
3845    }
3846
3847    /**
3848     * The base implementation of `_.pullAllBy` without support for iteratee
3849     * shorthands.
3850     *
3851     * @private
3852     * @param {Array} array The array to modify.
3853     * @param {Array} values The values to remove.
3854     * @param {Function} [iteratee] The iteratee invoked per element.
3855     * @param {Function} [comparator] The comparator invoked per element.
3856     * @returns {Array} Returns `array`.
3857     */
3858    function basePullAll(array, values, iteratee, comparator) {
3859      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3860          index = -1,
3861          length = values.length,
3862          seen = array;
3863
3864      if (array === values) {
3865        values = copyArray(values);
3866      }
3867      if (iteratee) {
3868        seen = arrayMap(array, baseUnary(iteratee));
3869      }
3870      while (++index < length) {
3871        var fromIndex = 0,
3872            value = values[index],
3873            computed = iteratee ? iteratee(value) : value;
3874
3875        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3876          if (seen !== array) {
3877            splice.call(seen, fromIndex, 1);
3878          }
3879          splice.call(array, fromIndex, 1);
3880        }
3881      }
3882      return array;
3883    }
3884
3885    /**
3886     * The base implementation of `_.pullAt` without support for individual
3887     * indexes or capturing the removed elements.
3888     *
3889     * @private
3890     * @param {Array} array The array to modify.
3891     * @param {number[]} indexes The indexes of elements to remove.
3892     * @returns {Array} Returns `array`.
3893     */
3894    function basePullAt(array, indexes) {
3895      var length = array ? indexes.length : 0,
3896          lastIndex = length - 1;
3897
3898      while (length--) {
3899        var index = indexes[length];
3900        if (length == lastIndex || index !== previous) {
3901          var previous = index;
3902          if (isIndex(index)) {
3903            splice.call(array, index, 1);
3904          } else {
3905            baseUnset(array, index);
3906          }
3907        }
3908      }
3909      return array;
3910    }
3911
3912    /**
3913     * The base implementation of `_.random` without support for returning
3914     * floating-point numbers.
3915     *
3916     * @private
3917     * @param {number} lower The lower bound.
3918     * @param {number} upper The upper bound.
3919     * @returns {number} Returns the random number.
3920     */
3921    function baseRandom(lower, upper) {
3922      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3923    }
3924
3925    /**
3926     * The base implementation of `_.range` and `_.rangeRight` which doesn't
3927     * coerce arguments.
3928     *
3929     * @private
3930     * @param {number} start The start of the range.
3931     * @param {number} end The end of the range.
3932     * @param {number} step The value to increment or decrement by.
3933     * @param {boolean} [fromRight] Specify iterating from right to left.
3934     * @returns {Array} Returns the range of numbers.
3935     */
3936    function baseRange(start, end, step, fromRight) {
3937      var index = -1,
3938          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3939          result = Array(length);
3940
3941      while (length--) {
3942        result[fromRight ? length : ++index] = start;
3943        start += step;
3944      }
3945      return result;
3946    }
3947
3948    /**
3949     * The base implementation of `_.repeat` which doesn't coerce arguments.
3950     *
3951     * @private
3952     * @param {string} string The string to repeat.
3953     * @param {number} n The number of times to repeat the string.
3954     * @returns {string} Returns the repeated string.
3955     */
3956    function baseRepeat(string, n) {
3957      var result = '';
3958      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3959        return result;
3960      }
3961      // Leverage the exponentiation by squaring algorithm for a faster repeat.
3962      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3963      do {
3964        if (n % 2) {
3965          result += string;
3966        }
3967        n = nativeFloor(n / 2);
3968        if (n) {
3969          string += string;
3970        }
3971      } while (n);
3972
3973      return result;
3974    }
3975
3976    /**
3977     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3978     *
3979     * @private
3980     * @param {Function} func The function to apply a rest parameter to.
3981     * @param {number} [start=func.length-1] The start position of the rest parameter.
3982     * @returns {Function} Returns the new function.
3983     */
3984    function baseRest(func, start) {
3985      return setToString(overRest(func, start, identity), func + '');
3986    }
3987
3988    /**
3989     * The base implementation of `_.sample`.
3990     *
3991     * @private
3992     * @param {Array|Object} collection The collection to sample.
3993     * @returns {*} Returns the random element.
3994     */
3995    function baseSample(collection) {
3996      return arraySample(values(collection));
3997    }
3998
3999    /**
4000     * The base implementation of `_.sampleSize` without param guards.
4001     *
4002     * @private
4003     * @param {Array|Object} collection The collection to sample.
4004     * @param {number} n The number of elements to sample.
4005     * @returns {Array} Returns the random elements.
4006     */
4007    function baseSampleSize(collection, n) {
4008      var array = values(collection);
4009      return shuffleSelf(array, baseClamp(n, 0, array.length));
4010    }
4011
4012    /**
4013     * The base implementation of `_.set`.
4014     *
4015     * @private
4016     * @param {Object} object The object to modify.
4017     * @param {Array|string} path The path of the property to set.
4018     * @param {*} value The value to set.
4019     * @param {Function} [customizer] The function to customize path creation.
4020     * @returns {Object} Returns `object`.
4021     */
4022    function baseSet(object, path, value, customizer) {
4023      if (!isObject(object)) {
4024        return object;
4025      }
4026      path = castPath(path, object);
4027
4028      var index = -1,
4029          length = path.length,
4030          lastIndex = length - 1,
4031          nested = object;
4032
4033      while (nested != null && ++index < length) {
4034        var key = toKey(path[index]),
4035            newValue = value;
4036
4037        if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
4038          return object;
4039        }
4040
4041        if (index != lastIndex) {
4042          var objValue = nested[key];
4043          newValue = customizer ? customizer(objValue, key, nested) : undefined;
4044          if (newValue === undefined) {
4045            newValue = isObject(objValue)
4046              ? objValue
4047              : (isIndex(path[index + 1]) ? [] : {});
4048          }
4049        }
4050        assignValue(nested, key, newValue);
4051        nested = nested[key];
4052      }
4053      return object;
4054    }
4055
4056    /**
4057     * The base implementation of `setData` without support for hot loop shorting.
4058     *
4059     * @private
4060     * @param {Function} func The function to associate metadata with.
4061     * @param {*} data The metadata.
4062     * @returns {Function} Returns `func`.
4063     */
4064    var baseSetData = !metaMap ? identity : function(func, data) {
4065      metaMap.set(func, data);
4066      return func;
4067    };
4068
4069    /**
4070     * The base implementation of `setToString` without support for hot loop shorting.
4071     *
4072     * @private
4073     * @param {Function} func The function to modify.
4074     * @param {Function} string The `toString` result.
4075     * @returns {Function} Returns `func`.
4076     */
4077    var baseSetToString = !defineProperty ? identity : function(func, string) {
4078      return defineProperty(func, 'toString', {
4079        'configurable': true,
4080        'enumerable': false,
4081        'value': constant(string),
4082        'writable': true
4083      });
4084    };
4085
4086    /**
4087     * The base implementation of `_.shuffle`.
4088     *
4089     * @private
4090     * @param {Array|Object} collection The collection to shuffle.
4091     * @returns {Array} Returns the new shuffled array.
4092     */
4093    function baseShuffle(collection) {
4094      return shuffleSelf(values(collection));
4095    }
4096
4097    /**
4098     * The base implementation of `_.slice` without an iteratee call guard.
4099     *
4100     * @private
4101     * @param {Array} array The array to slice.
4102     * @param {number} [start=0] The start position.
4103     * @param {number} [end=array.length] The end position.
4104     * @returns {Array} Returns the slice of `array`.
4105     */
4106    function baseSlice(array, start, end) {
4107      var index = -1,
4108          length = array.length;
4109
4110      if (start < 0) {
4111        start = -start > length ? 0 : (length + start);
4112      }
4113      end = end > length ? length : end;
4114      if (end < 0) {
4115        end += length;
4116      }
4117      length = start > end ? 0 : ((end - start) >>> 0);
4118      start >>>= 0;
4119
4120      var result = Array(length);
4121      while (++index < length) {
4122        result[index] = array[index + start];
4123      }
4124      return result;
4125    }
4126
4127    /**
4128     * The base implementation of `_.some` without support for iteratee shorthands.
4129     *
4130     * @private
4131     * @param {Array|Object} collection The collection to iterate over.
4132     * @param {Function} predicate The function invoked per iteration.
4133     * @returns {boolean} Returns `true` if any element passes the predicate check,
4134     *  else `false`.
4135     */
4136    function baseSome(collection, predicate) {
4137      var result;
4138
4139      baseEach(collection, function(value, index, collection) {
4140        result = predicate(value, index, collection);
4141        return !result;
4142      });
4143      return !!result;
4144    }
4145
4146    /**
4147     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4148     * performs a binary search of `array` to determine the index at which `value`
4149     * should be inserted into `array` in order to maintain its sort order.
4150     *
4151     * @private
4152     * @param {Array} array The sorted array to inspect.
4153     * @param {*} value The value to evaluate.
4154     * @param {boolean} [retHighest] Specify returning the highest qualified index.
4155     * @returns {number} Returns the index at which `value` should be inserted
4156     *  into `array`.
4157     */
4158    function baseSortedIndex(array, value, retHighest) {
4159      var low = 0,
4160          high = array == null ? low : array.length;
4161
4162      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4163        while (low < high) {
4164          var mid = (low + high) >>> 1,
4165              computed = array[mid];
4166
4167          if (computed !== null && !isSymbol(computed) &&
4168              (retHighest ? (computed <= value) : (computed < value))) {
4169            low = mid + 1;
4170          } else {
4171            high = mid;
4172          }
4173        }
4174        return high;
4175      }
4176      return baseSortedIndexBy(array, value, identity, retHighest);
4177    }
4178
4179    /**
4180     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4181     * which invokes `iteratee` for `value` and each element of `array` to compute
4182     * their sort ranking. The iteratee is invoked with one argument; (value).
4183     *
4184     * @private
4185     * @param {Array} array The sorted array to inspect.
4186     * @param {*} value The value to evaluate.
4187     * @param {Function} iteratee The iteratee invoked per element.
4188     * @param {boolean} [retHighest] Specify returning the highest qualified index.
4189     * @returns {number} Returns the index at which `value` should be inserted
4190     *  into `array`.
4191     */
4192    function baseSortedIndexBy(array, value, iteratee, retHighest) {
4193      var low = 0,
4194          high = array == null ? 0 : array.length;
4195      if (high === 0) {
4196        return 0;
4197      }
4198
4199      value = iteratee(value);
4200      var valIsNaN = value !== value,
4201          valIsNull = value === null,
4202          valIsSymbol = isSymbol(value),
4203          valIsUndefined = value === undefined;
4204
4205      while (low < high) {
4206        var mid = nativeFloor((low + high) / 2),
4207            computed = iteratee(array[mid]),
4208            othIsDefined = computed !== undefined,
4209            othIsNull = computed === null,
4210            othIsReflexive = computed === computed,
4211            othIsSymbol = isSymbol(computed);
4212
4213        if (valIsNaN) {
4214          var setLow = retHighest || othIsReflexive;
4215        } else if (valIsUndefined) {
4216          setLow = othIsReflexive && (retHighest || othIsDefined);
4217        } else if (valIsNull) {
4218          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4219        } else if (valIsSymbol) {
4220          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4221        } else if (othIsNull || othIsSymbol) {
4222          setLow = false;
4223        } else {
4224          setLow = retHighest ? (computed <= value) : (computed < value);
4225        }
4226        if (setLow) {
4227          low = mid + 1;
4228        } else {
4229          high = mid;
4230        }
4231      }
4232      return nativeMin(high, MAX_ARRAY_INDEX);
4233    }
4234
4235    /**
4236     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4237     * support for iteratee shorthands.
4238     *
4239     * @private
4240     * @param {Array} array The array to inspect.
4241     * @param {Function} [iteratee] The iteratee invoked per element.
4242     * @returns {Array} Returns the new duplicate free array.
4243     */
4244    function baseSortedUniq(array, iteratee) {
4245      var index = -1,
4246          length = array.length,
4247          resIndex = 0,
4248          result = [];
4249
4250      while (++index < length) {
4251        var value = array[index],
4252            computed = iteratee ? iteratee(value) : value;
4253
4254        if (!index || !eq(computed, seen)) {
4255          var seen = computed;
4256          result[resIndex++] = value === 0 ? 0 : value;
4257        }
4258      }
4259      return result;
4260    }
4261
4262    /**
4263     * The base implementation of `_.toNumber` which doesn't ensure correct
4264     * conversions of binary, hexadecimal, or octal string values.
4265     *
4266     * @private
4267     * @param {*} value The value to process.
4268     * @returns {number} Returns the number.
4269     */
4270    function baseToNumber(value) {
4271      if (typeof value == 'number') {
4272        return value;
4273      }
4274      if (isSymbol(value)) {
4275        return NAN;
4276      }
4277      return +value;
4278    }
4279
4280    /**
4281     * The base implementation of `_.toString` which doesn't convert nullish
4282     * values to empty strings.
4283     *
4284     * @private
4285     * @param {*} value The value to process.
4286     * @returns {string} Returns the string.
4287     */
4288    function baseToString(value) {
4289      // Exit early for strings to avoid a performance hit in some environments.
4290      if (typeof value == 'string') {
4291        return value;
4292      }
4293      if (isArray(value)) {
4294        // Recursively convert values (susceptible to call stack limits).
4295        return arrayMap(value, baseToString) + '';
4296      }
4297      if (isSymbol(value)) {
4298        return symbolToString ? symbolToString.call(value) : '';
4299      }
4300      var result = (value + '');
4301      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4302    }
4303
4304    /**
4305     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4306     *
4307     * @private
4308     * @param {Array} array The array to inspect.
4309     * @param {Function} [iteratee] The iteratee invoked per element.
4310     * @param {Function} [comparator] The comparator invoked per element.
4311     * @returns {Array} Returns the new duplicate free array.
4312     */
4313    function baseUniq(array, iteratee, comparator) {
4314      var index = -1,
4315          includes = arrayIncludes,
4316          length = array.length,
4317          isCommon = true,
4318          result = [],
4319          seen = result;
4320
4321      if (comparator) {
4322        isCommon = false;
4323        includes = arrayIncludesWith;
4324      }
4325      else if (length >= LARGE_ARRAY_SIZE) {
4326        var set = iteratee ? null : createSet(array);
4327        if (set) {
4328          return setToArray(set);
4329        }
4330        isCommon = false;
4331        includes = cacheHas;
4332        seen = new SetCache;
4333      }
4334      else {
4335        seen = iteratee ? [] : result;
4336      }
4337      outer:
4338      while (++index < length) {
4339        var value = array[index],
4340            computed = iteratee ? iteratee(value) : value;
4341
4342        value = (comparator || value !== 0) ? value : 0;
4343        if (isCommon && computed === computed) {
4344          var seenIndex = seen.length;
4345          while (seenIndex--) {
4346            if (seen[seenIndex] === computed) {
4347              continue outer;
4348            }
4349          }
4350          if (iteratee) {
4351            seen.push(computed);
4352          }
4353          result.push(value);
4354        }
4355        else if (!includes(seen, computed, comparator)) {
4356          if (seen !== result) {
4357            seen.push(computed);
4358          }
4359          result.push(value);
4360        }
4361      }
4362      return result;
4363    }
4364
4365    /**
4366     * The base implementation of `_.unset`.
4367     *
4368     * @private
4369     * @param {Object} object The object to modify.
4370     * @param {Array|string} path The property path to unset.
4371     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4372     */
4373    function baseUnset(object, path) {
4374      path = castPath(path, object);
4375      object = parent(object, path);
4376      return object == null || delete object[toKey(last(path))];
4377    }
4378
4379    /**
4380     * The base implementation of `_.update`.
4381     *
4382     * @private
4383     * @param {Object} object The object to modify.
4384     * @param {Array|string} path The path of the property to update.
4385     * @param {Function} updater The function to produce the updated value.
4386     * @param {Function} [customizer] The function to customize path creation.
4387     * @returns {Object} Returns `object`.
4388     */
4389    function baseUpdate(object, path, updater, customizer) {
4390      return baseSet(object, path, updater(baseGet(object, path)), customizer);
4391    }
4392
4393    /**
4394     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4395     * without support for iteratee shorthands.
4396     *
4397     * @private
4398     * @param {Array} array The array to query.
4399     * @param {Function} predicate The function invoked per iteration.
4400     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4401     * @param {boolean} [fromRight] Specify iterating from right to left.
4402     * @returns {Array} Returns the slice of `array`.
4403     */
4404    function baseWhile(array, predicate, isDrop, fromRight) {
4405      var length = array.length,
4406          index = fromRight ? length : -1;
4407
4408      while ((fromRight ? index-- : ++index < length) &&
4409        predicate(array[index], index, array)) {}
4410
4411      return isDrop
4412        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4413        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4414    }
4415
4416    /**
4417     * The base implementation of `wrapperValue` which returns the result of
4418     * performing a sequence of actions on the unwrapped `value`, where each
4419     * successive action is supplied the return value of the previous.
4420     *
4421     * @private
4422     * @param {*} value The unwrapped value.
4423     * @param {Array} actions Actions to perform to resolve the unwrapped value.
4424     * @returns {*} Returns the resolved value.
4425     */
4426    function baseWrapperValue(value, actions) {
4427      var result = value;
4428      if (result instanceof LazyWrapper) {
4429        result = result.value();
4430      }
4431      return arrayReduce(actions, function(result, action) {
4432        return action.func.apply(action.thisArg, arrayPush([result], action.args));
4433      }, result);
4434    }
4435
4436    /**
4437     * The base implementation of methods like `_.xor`, without support for
4438     * iteratee shorthands, that accepts an array of arrays to inspect.
4439     *
4440     * @private
4441     * @param {Array} arrays The arrays to inspect.
4442     * @param {Function} [iteratee] The iteratee invoked per element.
4443     * @param {Function} [comparator] The comparator invoked per element.
4444     * @returns {Array} Returns the new array of values.
4445     */
4446    function baseXor(arrays, iteratee, comparator) {
4447      var length = arrays.length;
4448      if (length < 2) {
4449        return length ? baseUniq(arrays[0]) : [];
4450      }
4451      var index = -1,
4452          result = Array(length);
4453
4454      while (++index < length) {
4455        var array = arrays[index],
4456            othIndex = -1;
4457
4458        while (++othIndex < length) {
4459          if (othIndex != index) {
4460            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4461          }
4462        }
4463      }
4464      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4465    }
4466
4467    /**
4468     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4469     *
4470     * @private
4471     * @param {Array} props The property identifiers.
4472     * @param {Array} values The property values.
4473     * @param {Function} assignFunc The function to assign values.
4474     * @returns {Object} Returns the new object.
4475     */
4476    function baseZipObject(props, values, assignFunc) {
4477      var index = -1,
4478          length = props.length,
4479          valsLength = values.length,
4480          result = {};
4481
4482      while (++index < length) {
4483        var value = index < valsLength ? values[index] : undefined;
4484        assignFunc(result, props[index], value);
4485      }
4486      return result;
4487    }
4488
4489    /**
4490     * Casts `value` to an empty array if it's not an array like object.
4491     *
4492     * @private
4493     * @param {*} value The value to inspect.
4494     * @returns {Array|Object} Returns the cast array-like object.
4495     */
4496    function castArrayLikeObject(value) {
4497      return isArrayLikeObject(value) ? value : [];
4498    }
4499
4500    /**
4501     * Casts `value` to `identity` if it's not a function.
4502     *
4503     * @private
4504     * @param {*} value The value to inspect.
4505     * @returns {Function} Returns cast function.
4506     */
4507    function castFunction(value) {
4508      return typeof value == 'function' ? value : identity;
4509    }
4510
4511    /**
4512     * Casts `value` to a path array if it's not one.
4513     *
4514     * @private
4515     * @param {*} value The value to inspect.
4516     * @param {Object} [object] The object to query keys on.
4517     * @returns {Array} Returns the cast property path array.
4518     */
4519    function castPath(value, object) {
4520      if (isArray(value)) {
4521        return value;
4522      }
4523      return isKey(value, object) ? [value] : stringToPath(toString(value));
4524    }
4525
4526    /**
4527     * A `baseRest` alias which can be replaced with `identity` by module
4528     * replacement plugins.
4529     *
4530     * @private
4531     * @type {Function}
4532     * @param {Function} func The function to apply a rest parameter to.
4533     * @returns {Function} Returns the new function.
4534     */
4535    var castRest = baseRest;
4536
4537    /**
4538     * Casts `array` to a slice if it's needed.
4539     *
4540     * @private
4541     * @param {Array} array The array to inspect.
4542     * @param {number} start The start position.
4543     * @param {number} [end=array.length] The end position.
4544     * @returns {Array} Returns the cast slice.
4545     */
4546    function castSlice(array, start, end) {
4547      var length = array.length;
4548      end = end === undefined ? length : end;
4549      return (!start && end >= length) ? array : baseSlice(array, start, end);
4550    }
4551
4552    /**
4553     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4554     *
4555     * @private
4556     * @param {number|Object} id The timer id or timeout object of the timer to clear.
4557     */
4558    var clearTimeout = ctxClearTimeout || function(id) {
4559      return root.clearTimeout(id);
4560    };
4561
4562    /**
4563     * Creates a clone of  `buffer`.
4564     *
4565     * @private
4566     * @param {Buffer} buffer The buffer to clone.
4567     * @param {boolean} [isDeep] Specify a deep clone.
4568     * @returns {Buffer} Returns the cloned buffer.
4569     */
4570    function cloneBuffer(buffer, isDeep) {
4571      if (isDeep) {
4572        return buffer.slice();
4573      }
4574      var length = buffer.length,
4575          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4576
4577      buffer.copy(result);
4578      return result;
4579    }
4580
4581    /**
4582     * Creates a clone of `arrayBuffer`.
4583     *
4584     * @private
4585     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4586     * @returns {ArrayBuffer} Returns the cloned array buffer.
4587     */
4588    function cloneArrayBuffer(arrayBuffer) {
4589      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4590      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4591      return result;
4592    }
4593
4594    /**
4595     * Creates a clone of `dataView`.
4596     *
4597     * @private
4598     * @param {Object} dataView The data view to clone.
4599     * @param {boolean} [isDeep] Specify a deep clone.
4600     * @returns {Object} Returns the cloned data view.
4601     */
4602    function cloneDataView(dataView, isDeep) {
4603      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4604      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4605    }
4606
4607    /**
4608     * Creates a clone of `regexp`.
4609     *
4610     * @private
4611     * @param {Object} regexp The regexp to clone.
4612     * @returns {Object} Returns the cloned regexp.
4613     */
4614    function cloneRegExp(regexp) {
4615      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4616      result.lastIndex = regexp.lastIndex;
4617      return result;
4618    }
4619
4620    /**
4621     * Creates a clone of the `symbol` object.
4622     *
4623     * @private
4624     * @param {Object} symbol The symbol object to clone.
4625     * @returns {Object} Returns the cloned symbol object.
4626     */
4627    function cloneSymbol(symbol) {
4628      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4629    }
4630
4631    /**
4632     * Creates a clone of `typedArray`.
4633     *
4634     * @private
4635     * @param {Object} typedArray The typed array to clone.
4636     * @param {boolean} [isDeep] Specify a deep clone.
4637     * @returns {Object} Returns the cloned typed array.
4638     */
4639    function cloneTypedArray(typedArray, isDeep) {
4640      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4641      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4642    }
4643
4644    /**
4645     * Compares values to sort them in ascending order.
4646     *
4647     * @private
4648     * @param {*} value The value to compare.
4649     * @param {*} other The other value to compare.
4650     * @returns {number} Returns the sort order indicator for `value`.
4651     */
4652    function compareAscending(value, other) {
4653      if (value !== other) {
4654        var valIsDefined = value !== undefined,
4655            valIsNull = value === null,
4656            valIsReflexive = value === value,
4657            valIsSymbol = isSymbol(value);
4658
4659        var othIsDefined = other !== undefined,
4660            othIsNull = other === null,
4661            othIsReflexive = other === other,
4662            othIsSymbol = isSymbol(other);
4663
4664        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4665            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4666            (valIsNull && othIsDefined && othIsReflexive) ||
4667            (!valIsDefined && othIsReflexive) ||
4668            !valIsReflexive) {
4669          return 1;
4670        }
4671        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4672            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4673            (othIsNull && valIsDefined && valIsReflexive) ||
4674            (!othIsDefined && valIsReflexive) ||
4675            !othIsReflexive) {
4676          return -1;
4677        }
4678      }
4679      return 0;
4680    }
4681
4682    /**
4683     * Used by `_.orderBy` to compare multiple properties of a value to another
4684     * and stable sort them.
4685     *
4686     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4687     * specify an order of "desc" for descending or "asc" for ascending sort order
4688     * of corresponding values.
4689     *
4690     * @private
4691     * @param {Object} object The object to compare.
4692     * @param {Object} other The other object to compare.
4693     * @param {boolean[]|string[]} orders The order to sort by for each property.
4694     * @returns {number} Returns the sort order indicator for `object`.
4695     */
4696    function compareMultiple(object, other, orders) {
4697      var index = -1,
4698          objCriteria = object.criteria,
4699          othCriteria = other.criteria,
4700          length = objCriteria.length,
4701          ordersLength = orders.length;
4702
4703      while (++index < length) {
4704        var result = compareAscending(objCriteria[index], othCriteria[index]);
4705        if (result) {
4706          if (index >= ordersLength) {
4707            return result;
4708          }
4709          var order = orders[index];
4710          return result * (order == 'desc' ? -1 : 1);
4711        }
4712      }
4713      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4714      // that causes it, under certain circumstances, to provide the same value for
4715      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4716      // for more details.
4717      //
4718      // This also ensures a stable sort in V8 and other engines.
4719      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4720      return object.index - other.index;
4721    }
4722
4723    /**
4724     * Creates an array that is the composition of partially applied arguments,
4725     * placeholders, and provided arguments into a single array of arguments.
4726     *
4727     * @private
4728     * @param {Array} args The provided arguments.
4729     * @param {Array} partials The arguments to prepend to those provided.
4730     * @param {Array} holders The `partials` placeholder indexes.
4731     * @params {boolean} [isCurried] Specify composing for a curried function.
4732     * @returns {Array} Returns the new array of composed arguments.
4733     */
4734    function composeArgs(args, partials, holders, isCurried) {
4735      var argsIndex = -1,
4736          argsLength = args.length,
4737          holdersLength = holders.length,
4738          leftIndex = -1,
4739          leftLength = partials.length,
4740          rangeLength = nativeMax(argsLength - holdersLength, 0),
4741          result = Array(leftLength + rangeLength),
4742          isUncurried = !isCurried;
4743
4744      while (++leftIndex < leftLength) {
4745        result[leftIndex] = partials[leftIndex];
4746      }
4747      while (++argsIndex < holdersLength) {
4748        if (isUncurried || argsIndex < argsLength) {
4749          result[holders[argsIndex]] = args[argsIndex];
4750        }
4751      }
4752      while (rangeLength--) {
4753        result[leftIndex++] = args[argsIndex++];
4754      }
4755      return result;
4756    }
4757
4758    /**
4759     * This function is like `composeArgs` except that the arguments composition
4760     * is tailored for `_.partialRight`.
4761     *
4762     * @private
4763     * @param {Array} args The provided arguments.
4764     * @param {Array} partials The arguments to append to those provided.
4765     * @param {Array} holders The `partials` placeholder indexes.
4766     * @params {boolean} [isCurried] Specify composing for a curried function.
4767     * @returns {Array} Returns the new array of composed arguments.
4768     */
4769    function composeArgsRight(args, partials, holders, isCurried) {
4770      var argsIndex = -1,
4771          argsLength = args.length,
4772          holdersIndex = -1,
4773          holdersLength = holders.length,
4774          rightIndex = -1,
4775          rightLength = partials.length,
4776          rangeLength = nativeMax(argsLength - holdersLength, 0),
4777          result = Array(rangeLength + rightLength),
4778          isUncurried = !isCurried;
4779
4780      while (++argsIndex < rangeLength) {
4781        result[argsIndex] = args[argsIndex];
4782      }
4783      var offset = argsIndex;
4784      while (++rightIndex < rightLength) {
4785        result[offset + rightIndex] = partials[rightIndex];
4786      }
4787      while (++holdersIndex < holdersLength) {
4788        if (isUncurried || argsIndex < argsLength) {
4789          result[offset + holders[holdersIndex]] = args[argsIndex++];
4790        }
4791      }
4792      return result;
4793    }
4794
4795    /**
4796     * Copies the values of `source` to `array`.
4797     *
4798     * @private
4799     * @param {Array} source The array to copy values from.
4800     * @param {Array} [array=[]] The array to copy values to.
4801     * @returns {Array} Returns `array`.
4802     */
4803    function copyArray(source, array) {
4804      var index = -1,
4805          length = source.length;
4806
4807      array || (array = Array(length));
4808      while (++index < length) {
4809        array[index] = source[index];
4810      }
4811      return array;
4812    }
4813
4814    /**
4815     * Copies properties of `source` to `object`.
4816     *
4817     * @private
4818     * @param {Object} source The object to copy properties from.
4819     * @param {Array} props The property identifiers to copy.
4820     * @param {Object} [object={}] The object to copy properties to.
4821     * @param {Function} [customizer] The function to customize copied values.
4822     * @returns {Object} Returns `object`.
4823     */
4824    function copyObject(source, props, object, customizer) {
4825      var isNew = !object;
4826      object || (object = {});
4827
4828      var index = -1,
4829          length = props.length;
4830
4831      while (++index < length) {
4832        var key = props[index];
4833
4834        var newValue = customizer
4835          ? customizer(object[key], source[key], key, object, source)
4836          : undefined;
4837
4838        if (newValue === undefined) {
4839          newValue = source[key];
4840        }
4841        if (isNew) {
4842          baseAssignValue(object, key, newValue);
4843        } else {
4844          assignValue(object, key, newValue);
4845        }
4846      }
4847      return object;
4848    }
4849
4850    /**
4851     * Copies own symbols of `source` to `object`.
4852     *
4853     * @private
4854     * @param {Object} source The object to copy symbols from.
4855     * @param {Object} [object={}] The object to copy symbols to.
4856     * @returns {Object} Returns `object`.
4857     */
4858    function copySymbols(source, object) {
4859      return copyObject(source, getSymbols(source), object);
4860    }
4861
4862    /**
4863     * Copies own and inherited symbols of `source` to `object`.
4864     *
4865     * @private
4866     * @param {Object} source The object to copy symbols from.
4867     * @param {Object} [object={}] The object to copy symbols to.
4868     * @returns {Object} Returns `object`.
4869     */
4870    function copySymbolsIn(source, object) {
4871      return copyObject(source, getSymbolsIn(source), object);
4872    }
4873
4874    /**
4875     * Creates a function like `_.groupBy`.
4876     *
4877     * @private
4878     * @param {Function} setter The function to set accumulator values.
4879     * @param {Function} [initializer] The accumulator object initializer.
4880     * @returns {Function} Returns the new aggregator function.
4881     */
4882    function createAggregator(setter, initializer) {
4883      return function(collection, iteratee) {
4884        var func = isArray(collection) ? arrayAggregator : baseAggregator,
4885            accumulator = initializer ? initializer() : {};
4886
4887        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4888      };
4889    }
4890
4891    /**
4892     * Creates a function like `_.assign`.
4893     *
4894     * @private
4895     * @param {Function} assigner The function to assign values.
4896     * @returns {Function} Returns the new assigner function.
4897     */
4898    function createAssigner(assigner) {
4899      return baseRest(function(object, sources) {
4900        var index = -1,
4901            length = sources.length,
4902            customizer = length > 1 ? sources[length - 1] : undefined,
4903            guard = length > 2 ? sources[2] : undefined;
4904
4905        customizer = (assigner.length > 3 && typeof customizer == 'function')
4906          ? (length--, customizer)
4907          : undefined;
4908
4909        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4910          customizer = length < 3 ? undefined : customizer;
4911          length = 1;
4912        }
4913        object = Object(object);
4914        while (++index < length) {
4915          var source = sources[index];
4916          if (source) {
4917            assigner(object, source, index, customizer);
4918          }
4919        }
4920        return object;
4921      });
4922    }
4923
4924    /**
4925     * Creates a `baseEach` or `baseEachRight` function.
4926     *
4927     * @private
4928     * @param {Function} eachFunc The function to iterate over a collection.
4929     * @param {boolean} [fromRight] Specify iterating from right to left.
4930     * @returns {Function} Returns the new base function.
4931     */
4932    function createBaseEach(eachFunc, fromRight) {
4933      return function(collection, iteratee) {
4934        if (collection == null) {
4935          return collection;
4936        }
4937        if (!isArrayLike(collection)) {
4938          return eachFunc(collection, iteratee);
4939        }
4940        var length = collection.length,
4941            index = fromRight ? length : -1,
4942            iterable = Object(collection);
4943
4944        while ((fromRight ? index-- : ++index < length)) {
4945          if (iteratee(iterable[index], index, iterable) === false) {
4946            break;
4947          }
4948        }
4949        return collection;
4950      };
4951    }
4952
4953    /**
4954     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4955     *
4956     * @private
4957     * @param {boolean} [fromRight] Specify iterating from right to left.
4958     * @returns {Function} Returns the new base function.
4959     */
4960    function createBaseFor(fromRight) {
4961      return function(object, iteratee, keysFunc) {
4962        var index = -1,
4963            iterable = Object(object),
4964            props = keysFunc(object),
4965            length = props.length;
4966
4967        while (length--) {
4968          var key = props[fromRight ? length : ++index];
4969          if (iteratee(iterable[key], key, iterable) === false) {
4970            break;
4971          }
4972        }
4973        return object;
4974      };
4975    }
4976
4977    /**
4978     * Creates a function that wraps `func` to invoke it with the optional `this`
4979     * binding of `thisArg`.
4980     *
4981     * @private
4982     * @param {Function} func The function to wrap.
4983     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
4984     * @param {*} [thisArg] The `this` binding of `func`.
4985     * @returns {Function} Returns the new wrapped function.
4986     */
4987    function createBind(func, bitmask, thisArg) {
4988      var isBind = bitmask & WRAP_BIND_FLAG,
4989          Ctor = createCtor(func);
4990
4991      function wrapper() {
4992        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4993        return fn.apply(isBind ? thisArg : this, arguments);
4994      }
4995      return wrapper;
4996    }
4997
4998    /**
4999     * Creates a function like `_.lowerFirst`.
5000     *
5001     * @private
5002     * @param {string} methodName The name of the `String` case method to use.
5003     * @returns {Function} Returns the new case function.
5004     */
5005    function createCaseFirst(methodName) {
5006      return function(string) {
5007        string = toString(string);
5008
5009        var strSymbols = hasUnicode(string)
5010          ? stringToArray(string)
5011          : undefined;
5012
5013        var chr = strSymbols
5014          ? strSymbols[0]
5015          : string.charAt(0);
5016
5017        var trailing = strSymbols
5018          ? castSlice(strSymbols, 1).join('')
5019          : string.slice(1);
5020
5021        return chr[methodName]() + trailing;
5022      };
5023    }
5024
5025    /**
5026     * Creates a function like `_.camelCase`.
5027     *
5028     * @private
5029     * @param {Function} callback The function to combine each word.
5030     * @returns {Function} Returns the new compounder function.
5031     */
5032    function createCompounder(callback) {
5033      return function(string) {
5034        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
5035      };
5036    }
5037
5038    /**
5039     * Creates a function that produces an instance of `Ctor` regardless of
5040     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5041     *
5042     * @private
5043     * @param {Function} Ctor The constructor to wrap.
5044     * @returns {Function} Returns the new wrapped function.
5045     */
5046    function createCtor(Ctor) {
5047      return function() {
5048        // Use a `switch` statement to work with class constructors. See
5049        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5050        // for more details.
5051        var args = arguments;
5052        switch (args.length) {
5053          case 0: return new Ctor;
5054          case 1: return new Ctor(args[0]);
5055          case 2: return new Ctor(args[0], args[1]);
5056          case 3: return new Ctor(args[0], args[1], args[2]);
5057          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5058          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5059          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5060          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5061        }
5062        var thisBinding = baseCreate(Ctor.prototype),
5063            result = Ctor.apply(thisBinding, args);
5064
5065        // Mimic the constructor's `return` behavior.
5066        // See https://es5.github.io/#x13.2.2 for more details.
5067        return isObject(result) ? result : thisBinding;
5068      };
5069    }
5070
5071    /**
5072     * Creates a function that wraps `func` to enable currying.
5073     *
5074     * @private
5075     * @param {Function} func The function to wrap.
5076     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5077     * @param {number} arity The arity of `func`.
5078     * @returns {Function} Returns the new wrapped function.
5079     */
5080    function createCurry(func, bitmask, arity) {
5081      var Ctor = createCtor(func);
5082
5083      function wrapper() {
5084        var length = arguments.length,
5085            args = Array(length),
5086            index = length,
5087            placeholder = getHolder(wrapper);
5088
5089        while (index--) {
5090          args[index] = arguments[index];
5091        }
5092        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5093          ? []
5094          : replaceHolders(args, placeholder);
5095
5096        length -= holders.length;
5097        if (length < arity) {
5098          return createRecurry(
5099            func, bitmask, createHybrid, wrapper.placeholder, undefined,
5100            args, holders, undefined, undefined, arity - length);
5101        }
5102        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5103        return apply(fn, this, args);
5104      }
5105      return wrapper;
5106    }
5107
5108    /**
5109     * Creates a `_.find` or `_.findLast` function.
5110     *
5111     * @private
5112     * @param {Function} findIndexFunc The function to find the collection index.
5113     * @returns {Function} Returns the new find function.
5114     */
5115    function createFind(findIndexFunc) {
5116      return function(collection, predicate, fromIndex) {
5117        var iterable = Object(collection);
5118        if (!isArrayLike(collection)) {
5119          var iteratee = getIteratee(predicate, 3);
5120          collection = keys(collection);
5121          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5122        }
5123        var index = findIndexFunc(collection, predicate, fromIndex);
5124        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5125      };
5126    }
5127
5128    /**
5129     * Creates a `_.flow` or `_.flowRight` function.
5130     *
5131     * @private
5132     * @param {boolean} [fromRight] Specify iterating from right to left.
5133     * @returns {Function} Returns the new flow function.
5134     */
5135    function createFlow(fromRight) {
5136      return flatRest(function(funcs) {
5137        var length = funcs.length,
5138            index = length,
5139            prereq = LodashWrapper.prototype.thru;
5140
5141        if (fromRight) {
5142          funcs.reverse();
5143        }
5144        while (index--) {
5145          var func = funcs[index];
5146          if (typeof func != 'function') {
5147            throw new TypeError(FUNC_ERROR_TEXT);
5148          }
5149          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5150            var wrapper = new LodashWrapper([], true);
5151          }
5152        }
5153        index = wrapper ? index : length;
5154        while (++index < length) {
5155          func = funcs[index];
5156
5157          var funcName = getFuncName(func),
5158              data = funcName == 'wrapper' ? getData(func) : undefined;
5159
5160          if (data && isLaziable(data[0]) &&
5161                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5162                !data[4].length && data[9] == 1
5163              ) {
5164            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5165          } else {
5166            wrapper = (func.length == 1 && isLaziable(func))
5167              ? wrapper[funcName]()
5168              : wrapper.thru(func);
5169          }
5170        }
5171        return function() {
5172          var args = arguments,
5173              value = args[0];
5174
5175          if (wrapper && args.length == 1 && isArray(value)) {
5176            return wrapper.plant(value).value();
5177          }
5178          var index = 0,
5179              result = length ? funcs[index].apply(this, args) : value;
5180
5181          while (++index < length) {
5182            result = funcs[index].call(this, result);
5183          }
5184          return result;
5185        };
5186      });
5187    }
5188
5189    /**
5190     * Creates a function that wraps `func` to invoke it with optional `this`
5191     * binding of `thisArg`, partial application, and currying.
5192     *
5193     * @private
5194     * @param {Function|string} func The function or method name to wrap.
5195     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5196     * @param {*} [thisArg] The `this` binding of `func`.
5197     * @param {Array} [partials] The arguments to prepend to those provided to
5198     *  the new function.
5199     * @param {Array} [holders] The `partials` placeholder indexes.
5200     * @param {Array} [partialsRight] The arguments to append to those provided
5201     *  to the new function.
5202     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5203     * @param {Array} [argPos] The argument positions of the new function.
5204     * @param {number} [ary] The arity cap of `func`.
5205     * @param {number} [arity] The arity of `func`.
5206     * @returns {Function} Returns the new wrapped function.
5207     */
5208    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5209      var isAry = bitmask & WRAP_ARY_FLAG,
5210          isBind = bitmask & WRAP_BIND_FLAG,
5211          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5212          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5213          isFlip = bitmask & WRAP_FLIP_FLAG,
5214          Ctor = isBindKey ? undefined : createCtor(func);
5215
5216      function wrapper() {
5217        var length = arguments.length,
5218            args = Array(length),
5219            index = length;
5220
5221        while (index--) {
5222          args[index] = arguments[index];
5223        }
5224        if (isCurried) {
5225          var placeholder = getHolder(wrapper),
5226              holdersCount = countHolders(args, placeholder);
5227        }
5228        if (partials) {
5229          args = composeArgs(args, partials, holders, isCurried);
5230        }
5231        if (partialsRight) {
5232          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5233        }
5234        length -= holdersCount;
5235        if (isCurried && length < arity) {
5236          var newHolders = replaceHolders(args, placeholder);
5237          return createRecurry(
5238            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5239            args, newHolders, argPos, ary, arity - length
5240          );
5241        }
5242        var thisBinding = isBind ? thisArg : this,
5243            fn = isBindKey ? thisBinding[func] : func;
5244
5245        length = args.length;
5246        if (argPos) {
5247          args = reorder(args, argPos);
5248        } else if (isFlip && length > 1) {
5249          args.reverse();
5250        }
5251        if (isAry && ary < length) {
5252          args.length = ary;
5253        }
5254        if (this && this !== root && this instanceof wrapper) {
5255          fn = Ctor || createCtor(fn);
5256        }
5257        return fn.apply(thisBinding, args);
5258      }
5259      return wrapper;
5260    }
5261
5262    /**
5263     * Creates a function like `_.invertBy`.
5264     *
5265     * @private
5266     * @param {Function} setter The function to set accumulator values.
5267     * @param {Function} toIteratee The function to resolve iteratees.
5268     * @returns {Function} Returns the new inverter function.
5269     */
5270    function createInverter(setter, toIteratee) {
5271      return function(object, iteratee) {
5272        return baseInverter(object, setter, toIteratee(iteratee), {});
5273      };
5274    }
5275
5276    /**
5277     * Creates a function that performs a mathematical operation on two values.
5278     *
5279     * @private
5280     * @param {Function} operator The function to perform the operation.
5281     * @param {number} [defaultValue] The value used for `undefined` arguments.
5282     * @returns {Function} Returns the new mathematical operation function.
5283     */
5284    function createMathOperation(operator, defaultValue) {
5285      return function(value, other) {
5286        var result;
5287        if (value === undefined && other === undefined) {
5288          return defaultValue;
5289        }
5290        if (value !== undefined) {
5291          result = value;
5292        }
5293        if (other !== undefined) {
5294          if (result === undefined) {
5295            return other;
5296          }
5297          if (typeof value == 'string' || typeof other == 'string') {
5298            value = baseToString(value);
5299            other = baseToString(other);
5300          } else {
5301            value = baseToNumber(value);
5302            other = baseToNumber(other);
5303          }
5304          result = operator(value, other);
5305        }
5306        return result;
5307      };
5308    }
5309
5310    /**
5311     * Creates a function like `_.over`.
5312     *
5313     * @private
5314     * @param {Function} arrayFunc The function to iterate over iteratees.
5315     * @returns {Function} Returns the new over function.
5316     */
5317    function createOver(arrayFunc) {
5318      return flatRest(function(iteratees) {
5319        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5320        return baseRest(function(args) {
5321          var thisArg = this;
5322          return arrayFunc(iteratees, function(iteratee) {
5323            return apply(iteratee, thisArg, args);
5324          });
5325        });
5326      });
5327    }
5328
5329    /**
5330     * Creates the padding for `string` based on `length`. The `chars` string
5331     * is truncated if the number of characters exceeds `length`.
5332     *
5333     * @private
5334     * @param {number} length The padding length.
5335     * @param {string} [chars=' '] The string used as padding.
5336     * @returns {string} Returns the padding for `string`.
5337     */
5338    function createPadding(length, chars) {
5339      chars = chars === undefined ? ' ' : baseToString(chars);
5340
5341      var charsLength = chars.length;
5342      if (charsLength < 2) {
5343        return charsLength ? baseRepeat(chars, length) : chars;
5344      }
5345      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5346      return hasUnicode(chars)
5347        ? castSlice(stringToArray(result), 0, length).join('')
5348        : result.slice(0, length);
5349    }
5350
5351    /**
5352     * Creates a function that wraps `func` to invoke it with the `this` binding
5353     * of `thisArg` and `partials` prepended to the arguments it receives.
5354     *
5355     * @private
5356     * @param {Function} func The function to wrap.
5357     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5358     * @param {*} thisArg The `this` binding of `func`.
5359     * @param {Array} partials The arguments to prepend to those provided to
5360     *  the new function.
5361     * @returns {Function} Returns the new wrapped function.
5362     */
5363    function createPartial(func, bitmask, thisArg, partials) {
5364      var isBind = bitmask & WRAP_BIND_FLAG,
5365          Ctor = createCtor(func);
5366
5367      function wrapper() {
5368        var argsIndex = -1,
5369            argsLength = arguments.length,
5370            leftIndex = -1,
5371            leftLength = partials.length,
5372            args = Array(leftLength + argsLength),
5373            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5374
5375        while (++leftIndex < leftLength) {
5376          args[leftIndex] = partials[leftIndex];
5377        }
5378        while (argsLength--) {
5379          args[leftIndex++] = arguments[++argsIndex];
5380        }
5381        return apply(fn, isBind ? thisArg : this, args);
5382      }
5383      return wrapper;
5384    }
5385
5386    /**
5387     * Creates a `_.range` or `_.rangeRight` function.
5388     *
5389     * @private
5390     * @param {boolean} [fromRight] Specify iterating from right to left.
5391     * @returns {Function} Returns the new range function.
5392     */
5393    function createRange(fromRight) {
5394      return function(start, end, step) {
5395        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5396          end = step = undefined;
5397        }
5398        // Ensure the sign of `-0` is preserved.
5399        start = toFinite(start);
5400        if (end === undefined) {
5401          end = start;
5402          start = 0;
5403        } else {
5404          end = toFinite(end);
5405        }
5406        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5407        return baseRange(start, end, step, fromRight);
5408      };
5409    }
5410
5411    /**
5412     * Creates a function that performs a relational operation on two values.
5413     *
5414     * @private
5415     * @param {Function} operator The function to perform the operation.
5416     * @returns {Function} Returns the new relational operation function.
5417     */
5418    function createRelationalOperation(operator) {
5419      return function(value, other) {
5420        if (!(typeof value == 'string' && typeof other == 'string')) {
5421          value = toNumber(value);
5422          other = toNumber(other);
5423        }
5424        return operator(value, other);
5425      };
5426    }
5427
5428    /**
5429     * Creates a function that wraps `func` to continue currying.
5430     *
5431     * @private
5432     * @param {Function} func The function to wrap.
5433     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5434     * @param {Function} wrapFunc The function to create the `func` wrapper.
5435     * @param {*} placeholder The placeholder value.
5436     * @param {*} [thisArg] The `this` binding of `func`.
5437     * @param {Array} [partials] The arguments to prepend to those provided to
5438     *  the new function.
5439     * @param {Array} [holders] The `partials` placeholder indexes.
5440     * @param {Array} [argPos] The argument positions of the new function.
5441     * @param {number} [ary] The arity cap of `func`.
5442     * @param {number} [arity] The arity of `func`.
5443     * @returns {Function} Returns the new wrapped function.
5444     */
5445    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5446      var isCurry = bitmask & WRAP_CURRY_FLAG,
5447          newHolders = isCurry ? holders : undefined,
5448          newHoldersRight = isCurry ? undefined : holders,
5449          newPartials = isCurry ? partials : undefined,
5450          newPartialsRight = isCurry ? undefined : partials;
5451
5452      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5453      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5454
5455      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5456        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5457      }
5458      var newData = [
5459        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5460        newHoldersRight, argPos, ary, arity
5461      ];
5462
5463      var result = wrapFunc.apply(undefined, newData);
5464      if (isLaziable(func)) {
5465        setData(result, newData);
5466      }
5467      result.placeholder = placeholder;
5468      return setWrapToString(result, func, bitmask);
5469    }
5470
5471    /**
5472     * Creates a function like `_.round`.
5473     *
5474     * @private
5475     * @param {string} methodName The name of the `Math` method to use when rounding.
5476     * @returns {Function} Returns the new round function.
5477     */
5478    function createRound(methodName) {
5479      var func = Math[methodName];
5480      return function(number, precision) {
5481        number = toNumber(number);
5482        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
5483        if (precision && nativeIsFinite(number)) {
5484          // Shift with exponential notation to avoid floating-point issues.
5485          // See [MDN](https://mdn.io/round#Examples) for more details.
5486          var pair = (toString(number) + 'e').split('e'),
5487              value = func(pair[0] + 'e' + (+pair[1] + precision));
5488
5489          pair = (toString(value) + 'e').split('e');
5490          return +(pair[0] + 'e' + (+pair[1] - precision));
5491        }
5492        return func(number);
5493      };
5494    }
5495
5496    /**
5497     * Creates a set object of `values`.
5498     *
5499     * @private
5500     * @param {Array} values The values to add to the set.
5501     * @returns {Object} Returns the new set.
5502     */
5503    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5504      return new Set(values);
5505    };
5506
5507    /**
5508     * Creates a `_.toPairs` or `_.toPairsIn` function.
5509     *
5510     * @private
5511     * @param {Function} keysFunc The function to get the keys of a given object.
5512     * @returns {Function} Returns the new pairs function.
5513     */
5514    function createToPairs(keysFunc) {
5515      return function(object) {
5516        var tag = getTag(object);
5517        if (tag == mapTag) {
5518          return mapToArray(object);
5519        }
5520        if (tag == setTag) {
5521          return setToPairs(object);
5522        }
5523        return baseToPairs(object, keysFunc(object));
5524      };
5525    }
5526
5527    /**
5528     * Creates a function that either curries or invokes `func` with optional
5529     * `this` binding and partially applied arguments.
5530     *
5531     * @private
5532     * @param {Function|string} func The function or method name to wrap.
5533     * @param {number} bitmask The bitmask flags.
5534     *    1 - `_.bind`
5535     *    2 - `_.bindKey`
5536     *    4 - `_.curry` or `_.curryRight` of a bound function
5537     *    8 - `_.curry`
5538     *   16 - `_.curryRight`
5539     *   32 - `_.partial`
5540     *   64 - `_.partialRight`
5541     *  128 - `_.rearg`
5542     *  256 - `_.ary`
5543     *  512 - `_.flip`
5544     * @param {*} [thisArg] The `this` binding of `func`.
5545     * @param {Array} [partials] The arguments to be partially applied.
5546     * @param {Array} [holders] The `partials` placeholder indexes.
5547     * @param {Array} [argPos] The argument positions of the new function.
5548     * @param {number} [ary] The arity cap of `func`.
5549     * @param {number} [arity] The arity of `func`.
5550     * @returns {Function} Returns the new wrapped function.
5551     */
5552    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5553      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5554      if (!isBindKey && typeof func != 'function') {
5555        throw new TypeError(FUNC_ERROR_TEXT);
5556      }
5557      var length = partials ? partials.length : 0;
5558      if (!length) {
5559        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5560        partials = holders = undefined;
5561      }
5562      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5563      arity = arity === undefined ? arity : toInteger(arity);
5564      length -= holders ? holders.length : 0;
5565
5566      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5567        var partialsRight = partials,
5568            holdersRight = holders;
5569
5570        partials = holders = undefined;
5571      }
5572      var data = isBindKey ? undefined : getData(func);
5573
5574      var newData = [
5575        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5576        argPos, ary, arity
5577      ];
5578
5579      if (data) {
5580        mergeData(newData, data);
5581      }
5582      func = newData[0];
5583      bitmask = newData[1];
5584      thisArg = newData[2];
5585      partials = newData[3];
5586      holders = newData[4];
5587      arity = newData[9] = newData[9] === undefined
5588        ? (isBindKey ? 0 : func.length)
5589        : nativeMax(newData[9] - length, 0);
5590
5591      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5592        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5593      }
5594      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5595        var result = createBind(func, bitmask, thisArg);
5596      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5597        result = createCurry(func, bitmask, arity);
5598      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5599        result = createPartial(func, bitmask, thisArg, partials);
5600      } else {
5601        result = createHybrid.apply(undefined, newData);
5602      }
5603      var setter = data ? baseSetData : setData;
5604      return setWrapToString(setter(result, newData), func, bitmask);
5605    }
5606
5607    /**
5608     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
5609     * of source objects to the destination object for all destination properties
5610     * that resolve to `undefined`.
5611     *
5612     * @private
5613     * @param {*} objValue The destination value.
5614     * @param {*} srcValue The source value.
5615     * @param {string} key The key of the property to assign.
5616     * @param {Object} object The parent object of `objValue`.
5617     * @returns {*} Returns the value to assign.
5618     */
5619    function customDefaultsAssignIn(objValue, srcValue, key, object) {
5620      if (objValue === undefined ||
5621          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
5622        return srcValue;
5623      }
5624      return objValue;
5625    }
5626
5627    /**
5628     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
5629     * objects into destination objects that are passed thru.
5630     *
5631     * @private
5632     * @param {*} objValue The destination value.
5633     * @param {*} srcValue The source value.
5634     * @param {string} key The key of the property to merge.
5635     * @param {Object} object The parent object of `objValue`.
5636     * @param {Object} source The parent object of `srcValue`.
5637     * @param {Object} [stack] Tracks traversed source values and their merged
5638     *  counterparts.
5639     * @returns {*} Returns the value to assign.
5640     */
5641    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
5642      if (isObject(objValue) && isObject(srcValue)) {
5643        // Recursively merge objects and arrays (susceptible to call stack limits).
5644        stack.set(srcValue, objValue);
5645        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
5646        stack['delete'](srcValue);
5647      }
5648      return objValue;
5649    }
5650
5651    /**
5652     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
5653     * objects.
5654     *
5655     * @private
5656     * @param {*} value The value to inspect.
5657     * @param {string} key The key of the property to inspect.
5658     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
5659     */
5660    function customOmitClone(value) {
5661      return isPlainObject(value) ? undefined : value;
5662    }
5663
5664    /**
5665     * A specialized version of `baseIsEqualDeep` for arrays with support for
5666     * partial deep comparisons.
5667     *
5668     * @private
5669     * @param {Array} array The array to compare.
5670     * @param {Array} other The other array to compare.
5671     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5672     * @param {Function} customizer The function to customize comparisons.
5673     * @param {Function} equalFunc The function to determine equivalents of values.
5674     * @param {Object} stack Tracks traversed `array` and `other` objects.
5675     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5676     */
5677    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5678      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5679          arrLength = array.length,
5680          othLength = other.length;
5681
5682      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5683        return false;
5684      }
5685      // Check that cyclic values are equal.
5686      var arrStacked = stack.get(array);
5687      var othStacked = stack.get(other);
5688      if (arrStacked && othStacked) {
5689        return arrStacked == other && othStacked == array;
5690      }
5691      var index = -1,
5692          result = true,
5693          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5694
5695      stack.set(array, other);
5696      stack.set(other, array);
5697
5698      // Ignore non-index properties.
5699      while (++index < arrLength) {
5700        var arrValue = array[index],
5701            othValue = other[index];
5702
5703        if (customizer) {
5704          var compared = isPartial
5705            ? customizer(othValue, arrValue, index, other, array, stack)
5706            : customizer(arrValue, othValue, index, array, other, stack);
5707        }
5708        if (compared !== undefined) {
5709          if (compared) {
5710            continue;
5711          }
5712          result = false;
5713          break;
5714        }
5715        // Recursively compare arrays (susceptible to call stack limits).
5716        if (seen) {
5717          if (!arraySome(other, function(othValue, othIndex) {
5718                if (!cacheHas(seen, othIndex) &&
5719                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5720                  return seen.push(othIndex);
5721                }
5722              })) {
5723            result = false;
vendor: 4,179 bytes, lines 5724-5835
5724            break;
5725          }
5726        } else if (!(
5727              arrValue === othValue ||
5728                equalFunc(arrValue, othValue, bitmask, customizer, stack)
5729            )) {
5730          result = false;
5731          break;
5732        }
5733      }
5734      stack['delete'](array);
5735      stack['delete'](other);
5736      return result;
5737    }
5738
5739    /**
5740     * A specialized version of `baseIsEqualDeep` for comparing objects of
5741     * the same `toStringTag`.
5742     *
5743     * **Note:** This function only supports comparing values with tags of
5744     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5745     *
5746     * @private
5747     * @param {Object} object The object to compare.
5748     * @param {Object} other The other object to compare.
5749     * @param {string} tag The `toStringTag` of the objects to compare.
5750     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5751     * @param {Function} customizer The function to customize comparisons.
5752     * @param {Function} equalFunc The function to determine equivalents of values.
5753     * @param {Object} stack Tracks traversed `object` and `other` objects.
5754     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5755     */
5756    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5757      switch (tag) {
5758        case dataViewTag:
5759          if ((object.byteLength != other.byteLength) ||
5760              (object.byteOffset != other.byteOffset)) {
5761            return false;
5762          }
5763          object = object.buffer;
5764          other = other.buffer;
5765
5766        case arrayBufferTag:
5767          if ((object.byteLength != other.byteLength) ||
5768              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5769            return false;
5770          }
5771          return true;
5772
5773        case boolTag:
5774        case dateTag:
5775        case numberTag:
5776          // Coerce booleans to `1` or `0` and dates to milliseconds.
5777          // Invalid dates are coerced to `NaN`.
5778          return eq(+object, +other);
5779
5780        case errorTag:
5781          return object.name == other.name && object.message == other.message;
5782
5783        case regexpTag:
5784        case stringTag:
5785          // Coerce regexes to strings and treat strings, primitives and objects,
5786          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5787          // for more details.
5788          return object == (other + '');
5789
5790        case mapTag:
5791          var convert = mapToArray;
5792
5793        case setTag:
5794          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5795          convert || (convert = setToArray);
5796
5797          if (object.size != other.size && !isPartial) {
5798            return false;
5799          }
5800          // Assume cyclic values are equal.
5801          var stacked = stack.get(object);
5802          if (stacked) {
5803            return stacked == other;
5804          }
5805          bitmask |= COMPARE_UNORDERED_FLAG;
5806
5807          // Recursively compare objects (susceptible to call stack limits).
5808          stack.set(object, other);
5809          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5810          stack['delete'](object);
5811          return result;
5812
5813        case symbolTag:
5814          if (symbolValueOf) {
5815            return symbolValueOf.call(object) == symbolValueOf.call(other);
5816          }
5817      }
5818      return false;
5819    }
5820
5821    /**
5822     * A specialized version of `baseIsEqualDeep` for objects with support for
5823     * partial deep comparisons.
5824     *
5825     * @private
5826     * @param {Object} object The object to compare.
5827     * @param {Object} other The other object to compare.
5828     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5829     * @param {Function} customizer The function to customize comparisons.
5830     * @param {Function} equalFunc The function to determine equivalents of values.
5831     * @param {Object} stack Tracks traversed `object` and `other` objects.
5832     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5833     */
5834    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5835      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
vendor: 9,614 bytes, lines 5836-6143
5836          objProps = getAllKeys(object),
5837          objLength = objProps.length,
5838          othProps = getAllKeys(other),
5839          othLength = othProps.length;
5840
5841      if (objLength != othLength && !isPartial) {
5842        return false;
5843      }
5844      var index = objLength;
5845      while (index--) {
5846        var key = objProps[index];
5847        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5848          return false;
5849        }
5850      }
5851      // Check that cyclic values are equal.
5852      var objStacked = stack.get(object);
5853      var othStacked = stack.get(other);
5854      if (objStacked && othStacked) {
5855        return objStacked == other && othStacked == object;
5856      }
5857      var result = true;
5858      stack.set(object, other);
5859      stack.set(other, object);
5860
5861      var skipCtor = isPartial;
5862      while (++index < objLength) {
5863        key = objProps[index];
5864        var objValue = object[key],
5865            othValue = other[key];
5866
5867        if (customizer) {
5868          var compared = isPartial
5869            ? customizer(othValue, objValue, key, other, object, stack)
5870            : customizer(objValue, othValue, key, object, other, stack);
5871        }
5872        // Recursively compare objects (susceptible to call stack limits).
5873        if (!(compared === undefined
5874              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5875              : compared
5876            )) {
5877          result = false;
5878          break;
5879        }
5880        skipCtor || (skipCtor = key == 'constructor');
5881      }
5882      if (result && !skipCtor) {
5883        var objCtor = object.constructor,
5884            othCtor = other.constructor;
5885
5886        // Non `Object` object instances with different constructors are not equal.
5887        if (objCtor != othCtor &&
5888            ('constructor' in object && 'constructor' in other) &&
5889            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5890              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5891          result = false;
5892        }
5893      }
5894      stack['delete'](object);
5895      stack['delete'](other);
5896      return result;
5897    }
5898
5899    /**
5900     * A specialized version of `baseRest` which flattens the rest array.
5901     *
5902     * @private
5903     * @param {Function} func The function to apply a rest parameter to.
5904     * @returns {Function} Returns the new function.
5905     */
5906    function flatRest(func) {
5907      return setToString(overRest(func, undefined, flatten), func + '');
5908    }
5909
5910    /**
5911     * Creates an array of own enumerable property names and symbols of `object`.
5912     *
5913     * @private
5914     * @param {Object} object The object to query.
5915     * @returns {Array} Returns the array of property names and symbols.
5916     */
5917    function getAllKeys(object) {
5918      return baseGetAllKeys(object, keys, getSymbols);
5919    }
5920
5921    /**
5922     * Creates an array of own and inherited enumerable property names and
5923     * symbols of `object`.
5924     *
5925     * @private
5926     * @param {Object} object The object to query.
5927     * @returns {Array} Returns the array of property names and symbols.
5928     */
5929    function getAllKeysIn(object) {
5930      return baseGetAllKeys(object, keysIn, getSymbolsIn);
5931    }
5932
5933    /**
5934     * Gets metadata for `func`.
5935     *
5936     * @private
5937     * @param {Function} func The function to query.
5938     * @returns {*} Returns the metadata for `func`.
5939     */
5940    var getData = !metaMap ? noop : function(func) {
5941      return metaMap.get(func);
5942    };
5943
5944    /**
5945     * Gets the name of `func`.
5946     *
5947     * @private
5948     * @param {Function} func The function to query.
5949     * @returns {string} Returns the function name.
5950     */
5951    function getFuncName(func) {
5952      var result = (func.name + ''),
5953          array = realNames[result],
5954          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5955
5956      while (length--) {
5957        var data = array[length],
5958            otherFunc = data.func;
5959        if (otherFunc == null || otherFunc == func) {
5960          return data.name;
5961        }
5962      }
5963      return result;
5964    }
5965
5966    /**
5967     * Gets the argument placeholder value for `func`.
5968     *
5969     * @private
5970     * @param {Function} func The function to inspect.
5971     * @returns {*} Returns the placeholder value.
5972     */
5973    function getHolder(func) {
5974      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5975      return object.placeholder;
5976    }
5977
5978    /**
5979     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5980     * this function returns the custom method, otherwise it returns `baseIteratee`.
5981     * If arguments are provided, the chosen function is invoked with them and
5982     * its result is returned.
5983     *
5984     * @private
5985     * @param {*} [value] The value to convert to an iteratee.
5986     * @param {number} [arity] The arity of the created iteratee.
5987     * @returns {Function} Returns the chosen function or its result.
5988     */
5989    function getIteratee() {
5990      var result = lodash.iteratee || iteratee;
5991      result = result === iteratee ? baseIteratee : result;
5992      return arguments.length ? result(arguments[0], arguments[1]) : result;
5993    }
5994
5995    /**
5996     * Gets the data for `map`.
5997     *
5998     * @private
5999     * @param {Object} map The map to query.
6000     * @param {string} key The reference key.
6001     * @returns {*} Returns the map data.
6002     */
6003    function getMapData(map, key) {
6004      var data = map.__data__;
6005      return isKeyable(key)
6006        ? data[typeof key == 'string' ? 'string' : 'hash']
6007        : data.map;
6008    }
6009
6010    /**
6011     * Gets the property names, values, and compare flags of `object`.
6012     *
6013     * @private
6014     * @param {Object} object The object to query.
6015     * @returns {Array} Returns the match data of `object`.
6016     */
6017    function getMatchData(object) {
6018      var result = keys(object),
6019          length = result.length;
6020
6021      while (length--) {
6022        var key = result[length],
6023            value = object[key];
6024
6025        result[length] = [key, value, isStrictComparable(value)];
6026      }
6027      return result;
6028    }
6029
6030    /**
6031     * Gets the native function at `key` of `object`.
6032     *
6033     * @private
6034     * @param {Object} object The object to query.
6035     * @param {string} key The key of the method to get.
6036     * @returns {*} Returns the function if it's native, else `undefined`.
6037     */
6038    function getNative(object, key) {
6039      var value = getValue(object, key);
6040      return baseIsNative(value) ? value : undefined;
6041    }
6042
6043    /**
6044     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6045     *
6046     * @private
6047     * @param {*} value The value to query.
6048     * @returns {string} Returns the raw `toStringTag`.
6049     */
6050    function getRawTag(value) {
6051      var isOwn = hasOwnProperty.call(value, symToStringTag),
6052          tag = value[symToStringTag];
6053
6054      try {
6055        value[symToStringTag] = undefined;
6056        var unmasked = true;
6057      } catch (e) {}
6058
6059      var result = nativeObjectToString.call(value);
6060      if (unmasked) {
6061        if (isOwn) {
6062          value[symToStringTag] = tag;
6063        } else {
6064          delete value[symToStringTag];
6065        }
6066      }
6067      return result;
6068    }
6069
6070    /**
6071     * Creates an array of the own enumerable symbols of `object`.
6072     *
6073     * @private
6074     * @param {Object} object The object to query.
6075     * @returns {Array} Returns the array of symbols.
6076     */
6077    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
6078      if (object == null) {
6079        return [];
6080      }
6081      object = Object(object);
6082      return arrayFilter(nativeGetSymbols(object), function(symbol) {
6083        return propertyIsEnumerable.call(object, symbol);
6084      });
6085    };
6086
6087    /**
6088     * Creates an array of the own and inherited enumerable symbols of `object`.
6089     *
6090     * @private
6091     * @param {Object} object The object to query.
6092     * @returns {Array} Returns the array of symbols.
6093     */
6094    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6095      var result = [];
6096      while (object) {
6097        arrayPush(result, getSymbols(object));
6098        object = getPrototype(object);
6099      }
6100      return result;
6101    };
6102
6103    /**
6104     * Gets the `toStringTag` of `value`.
6105     *
6106     * @private
6107     * @param {*} value The value to query.
6108     * @returns {string} Returns the `toStringTag`.
6109     */
6110    var getTag = baseGetTag;
6111
6112    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6113    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6114        (Map && getTag(new Map) != mapTag) ||
6115        (Promise && getTag(Promise.resolve()) != promiseTag) ||
6116        (Set && getTag(new Set) != setTag) ||
6117        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6118      getTag = function(value) {
6119        var result = baseGetTag(value),
6120            Ctor = result == objectTag ? value.constructor : undefined,
6121            ctorString = Ctor ? toSource(Ctor) : '';
6122
6123        if (ctorString) {
6124          switch (ctorString) {
6125            case dataViewCtorString: return dataViewTag;
6126            case mapCtorString: return mapTag;
6127            case promiseCtorString: return promiseTag;
6128            case setCtorString: return setTag;
6129            case weakMapCtorString: return weakMapTag;
6130          }
6131        }
6132        return result;
6133      };
6134    }
6135
6136    /**
6137     * Gets the view, applying any `transforms` to the `start` and `end` positions.
6138     *
6139     * @private
6140     * @param {number} start The start of the view.
6141     * @param {number} end The end of the view.
6142     * @param {Array} transforms The transformations to apply to the view.
6143     * @returns {Object}
vendor: 6,432 bytes, lines 6143-6348
6143 Returns an object containing the `start` and `end`
6144     *  positions of the view.
6145     */
6146    function getView(start, end, transforms) {
6147      var index = -1,
6148          length = transforms.length;
6149
6150      while (++index < length) {
6151        var data = transforms[index],
6152            size = data.size;
6153
6154        switch (data.type) {
6155          case 'drop':      start += size; break;
6156          case 'dropRight': end -= size; break;
6157          case 'take':      end = nativeMin(end, start + size); break;
6158          case 'takeRight': start = nativeMax(start, end - size); break;
6159        }
6160      }
6161      return { 'start': start, 'end': end };
6162    }
6163
6164    /**
6165     * Extracts wrapper details from the `source` body comment.
6166     *
6167     * @private
6168     * @param {string} source The source to inspect.
6169     * @returns {Array} Returns the wrapper details.
6170     */
6171    function getWrapDetails(source) {
6172      var match = source.match(reWrapDetails);
6173      return match ? match[1].split(reSplitDetails) : [];
6174    }
6175
6176    /**
6177     * Checks if `path` exists on `object`.
6178     *
6179     * @private
6180     * @param {Object} object The object to query.
6181     * @param {Array|string} path The path to check.
6182     * @param {Function} hasFunc The function to check properties.
6183     * @returns {boolean} Returns `true` if `path` exists, else `false`.
6184     */
6185    function hasPath(object, path, hasFunc) {
6186      path = castPath(path, object);
6187
6188      var index = -1,
6189          length = path.length,
6190          result = false;
6191
6192      while (++index < length) {
6193        var key = toKey(path[index]);
6194        if (!(result = object != null && hasFunc(object, key))) {
6195          break;
6196        }
6197        object = object[key];
6198      }
6199      if (result || ++index != length) {
6200        return result;
6201      }
6202      length = object == null ? 0 : object.length;
6203      return !!length && isLength(length) && isIndex(key, length) &&
6204        (isArray(object) || isArguments(object));
6205    }
6206
6207    /**
6208     * Initializes an array clone.
6209     *
6210     * @private
6211     * @param {Array} array The array to clone.
6212     * @returns {Array} Returns the initialized clone.
6213     */
6214    function initCloneArray(array) {
6215      var length = array.length,
6216          result = new array.constructor(length);
6217
6218      // Add properties assigned by `RegExp#exec`.
6219      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6220        result.index = array.index;
6221        result.input = array.input;
6222      }
6223      return result;
6224    }
6225
6226    /**
6227     * Initializes an object clone.
6228     *
6229     * @private
6230     * @param {Object} object The object to clone.
6231     * @returns {Object} Returns the initialized clone.
6232     */
6233    function initCloneObject(object) {
6234      return (typeof object.constructor == 'function' && !isPrototype(object))
6235        ? baseCreate(getPrototype(object))
6236        : {};
6237    }
6238
6239    /**
6240     * Initializes an object clone based on its `toStringTag`.
6241     *
6242     * **Note:** This function only supports cloning values with tags of
6243     * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
6244     *
6245     * @private
6246     * @param {Object} object The object to clone.
6247     * @param {string} tag The `toStringTag` of the object to clone.
6248     * @param {boolean} [isDeep] Specify a deep clone.
6249     * @returns {Object} Returns the initialized clone.
6250     */
6251    function initCloneByTag(object, tag, isDeep) {
6252      var Ctor = object.constructor;
6253      switch (tag) {
6254        case arrayBufferTag:
6255          return cloneArrayBuffer(object);
6256
6257        case boolTag:
6258        case dateTag:
6259          return new Ctor(+object);
6260
6261        case dataViewTag:
6262          return cloneDataView(object, isDeep);
6263
6264        case float32Tag: case float64Tag:
6265        case int8Tag: case int16Tag: case int32Tag:
6266        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6267          return cloneTypedArray(object, isDeep);
6268
6269        case mapTag:
6270          return new Ctor;
6271
6272        case numberTag:
6273        case stringTag:
6274          return new Ctor(object);
6275
6276        case regexpTag:
6277          return cloneRegExp(object);
6278
6279        case setTag:
6280          return new Ctor;
6281
6282        case symbolTag:
6283          return cloneSymbol(object);
6284      }
6285    }
6286
6287    /**
6288     * Inserts wrapper `details` in a comment at the top of the `source` body.
6289     *
6290     * @private
6291     * @param {string} source The source to modify.
6292     * @returns {Array} details The details to insert.
6293     * @returns {string} Returns the modified source.
6294     */
6295    function insertWrapDetails(source, details) {
6296      var length = details.length;
6297      if (!length) {
6298        return source;
6299      }
6300      var lastIndex = length - 1;
6301      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6302      details = details.join(length > 2 ? ', ' : ' ');
6303      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6304    }
6305
6306    /**
6307     * Checks if `value` is a flattenable `arguments` object or array.
6308     *
6309     * @private
6310     * @param {*} value The value to check.
6311     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6312     */
6313    function isFlattenable(value) {
6314      return isArray(value) || isArguments(value) ||
6315        !!(spreadableSymbol && value && value[spreadableSymbol]);
6316    }
6317
6318    /**
6319     * Checks if `value` is a valid array-like index.
6320     *
6321     * @private
6322     * @param {*} value The value to check.
6323     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6324     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6325     */
6326    function isIndex(value, length) {
6327      var type = typeof value;
6328      length = length == null ? MAX_SAFE_INTEGER : length;
6329
6330      return !!length &&
6331        (type == 'number' ||
6332          (type != 'symbol' && reIsUint.test(value))) &&
6333            (value > -1 && value % 1 == 0 && value < length);
6334    }
6335
6336    /**
6337     * Checks if the given arguments are from an iteratee call.
6338     *
6339     * @private
6340     * @param {*} value The potential iteratee value argument.
6341     * @param {*} index The potential iteratee index or key argument.
6342     * @param {*} object The potential iteratee object argument.
6343     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6344     *  else `false`.
6345     */
6346    function isIterateeCall(value, index, object) {
6347      if (!isObject(object)) {
6348        return false;
vendor: 14,387 bytes, lines 6349-6795
6349      }
6350      var type = typeof index;
6351      if (type == 'number'
6352            ? (isArrayLike(object) && isIndex(index, object.length))
6353            : (type == 'string' && index in object)
6354          ) {
6355        return eq(object[index], value);
6356      }
6357      return false;
6358    }
6359
6360    /**
6361     * Checks if `value` is a property name and not a property path.
6362     *
6363     * @private
6364     * @param {*} value The value to check.
6365     * @param {Object} [object] The object to query keys on.
6366     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6367     */
6368    function isKey(value, object) {
6369      if (isArray(value)) {
6370        return false;
6371      }
6372      var type = typeof value;
6373      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6374          value == null || isSymbol(value)) {
6375        return true;
6376      }
6377      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6378        (object != null && value in Object(object));
6379    }
6380
6381    /**
6382     * Checks if `value` is suitable for use as unique object key.
6383     *
6384     * @private
6385     * @param {*} value The value to check.
6386     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6387     */
6388    function isKeyable(value) {
6389      var type = typeof value;
6390      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6391        ? (value !== '__proto__')
6392        : (value === null);
6393    }
6394
6395    /**
6396     * Checks if `func` has a lazy counterpart.
6397     *
6398     * @private
6399     * @param {Function} func The function to check.
6400     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6401     *  else `false`.
6402     */
6403    function isLaziable(func) {
6404      var funcName = getFuncName(func),
6405          other = lodash[funcName];
6406
6407      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6408        return false;
6409      }
6410      if (func === other) {
6411        return true;
6412      }
6413      var data = getData(other);
6414      return !!data && func === data[0];
6415    }
6416
6417    /**
6418     * Checks if `func` has its source masked.
6419     *
6420     * @private
6421     * @param {Function} func The function to check.
6422     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6423     */
6424    function isMasked(func) {
6425      return !!maskSrcKey && (maskSrcKey in func);
6426    }
6427
6428    /**
6429     * Checks if `func` is capable of being masked.
6430     *
6431     * @private
6432     * @param {*} value The value to check.
6433     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6434     */
6435    var isMaskable = coreJsData ? isFunction : stubFalse;
6436
6437    /**
6438     * Checks if `value` is likely a prototype object.
6439     *
6440     * @private
6441     * @param {*} value The value to check.
6442     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6443     */
6444    function isPrototype(value) {
6445      var Ctor = value && value.constructor,
6446          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6447
6448      return value === proto;
6449    }
6450
6451    /**
6452     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6453     *
6454     * @private
6455     * @param {*} value The value to check.
6456     * @returns {boolean} Returns `true` if `value` if suitable for strict
6457     *  equality comparisons, else `false`.
6458     */
6459    function isStrictComparable(value) {
6460      return value === value && !isObject(value);
6461    }
6462
6463    /**
6464     * A specialized version of `matchesProperty` for source values suitable
6465     * for strict equality comparisons, i.e. `===`.
6466     *
6467     * @private
6468     * @param {string} key The key of the property to get.
6469     * @param {*} srcValue The value to match.
6470     * @returns {Function} Returns the new spec function.
6471     */
6472    function matchesStrictComparable(key, srcValue) {
6473      return function(object) {
6474        if (object == null) {
6475          return false;
6476        }
6477        return object[key] === srcValue &&
6478          (srcValue !== undefined || (key in Object(object)));
6479      };
6480    }
6481
6482    /**
6483     * A specialized version of `_.memoize` which clears the memoized function's
6484     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6485     *
6486     * @private
6487     * @param {Function} func The function to have its output memoized.
6488     * @returns {Function} Returns the new memoized function.
6489     */
6490    function memoizeCapped(func) {
6491      var result = memoize(func, function(key) {
6492        if (cache.size === MAX_MEMOIZE_SIZE) {
6493          cache.clear();
6494        }
6495        return key;
6496      });
6497
6498      var cache = result.cache;
6499      return result;
6500    }
6501
6502    /**
6503     * Merges the function metadata of `source` into `data`.
6504     *
6505     * Merging metadata reduces the number of wrappers used to invoke a function.
6506     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6507     * may be applied regardless of execution order. Methods like `_.ary` and
6508     * `_.rearg` modify function arguments, making the order in which they are
6509     * executed important, preventing the merging of metadata. However, we make
6510     * an exception for a safe combined case where curried functions have `_.ary`
6511     * and or `_.rearg` applied.
6512     *
6513     * @private
6514     * @param {Array} data The destination metadata.
6515     * @param {Array} source The source metadata.
6516     * @returns {Array} Returns `data`.
6517     */
6518    function mergeData(data, source) {
6519      var bitmask = data[1],
6520          srcBitmask = source[1],
6521          newBitmask = bitmask | srcBitmask,
6522          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6523
6524      var isCombo =
6525        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6526        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6527        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6528
6529      // Exit early if metadata can't be merged.
6530      if (!(isCommon || isCombo)) {
6531        return data;
6532      }
6533      // Use source `thisArg` if available.
6534      if (srcBitmask & WRAP_BIND_FLAG) {
6535        data[2] = source[2];
6536        // Set when currying a bound function.
6537        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6538      }
6539      // Compose partial arguments.
6540      var value = source[3];
6541      if (value) {
6542        var partials = data[3];
6543        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6544        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6545      }
6546      // Compose partial right arguments.
6547      value = source[5];
6548      if (value) {
6549        partials = data[5];
6550        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6551        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6552      }
6553      // Use source `argPos` if available.
6554      value = source[7];
6555      if (value) {
6556        data[7] = value;
6557      }
6558      // Use source `ary` if it's smaller.
6559      if (srcBitmask & WRAP_ARY_FLAG) {
6560        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6561      }
6562      // Use source `arity` if one is not provided.
6563      if (data[9] == null) {
6564        data[9] = source[9];
6565      }
6566      // Use source `func` and merge bitmasks.
6567      data[0] = source[0];
6568      data[1] = newBitmask;
6569
6570      return data;
6571    }
6572
6573    /**
6574     * This function is like
6575     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6576     * except that it includes inherited enumerable properties.
6577     *
6578     * @private
6579     * @param {Object} object The object to query.
6580     * @returns {Array} Returns the array of property names.
6581     */
6582    function nativeKeysIn(object) {
6583      var result = [];
6584      if (object != null) {
6585        for (var key in Object(object)) {
6586          result.push(key);
6587        }
6588      }
6589      return result;
6590    }
6591
6592    /**
6593     * Converts `value` to a string using `Object.prototype.toString`.
6594     *
6595     * @private
6596     * @param {*} value The value to convert.
6597     * @returns {string} Returns the converted string.
6598     */
6599    function objectToString(value) {
6600      return nativeObjectToString.call(value);
6601    }
6602
6603    /**
6604     * A specialized version of `baseRest` which transforms the rest array.
6605     *
6606     * @private
6607     * @param {Function} func The function to apply a rest parameter to.
6608     * @param {number} [start=func.length-1] The start position of the rest parameter.
6609     * @param {Function} transform The rest array transform.
6610     * @returns {Function} Returns the new function.
6611     */
6612    function overRest(func, start, transform) {
6613      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6614      return function() {
6615        var args = arguments,
6616            index = -1,
6617            length = nativeMax(args.length - start, 0),
6618            array = Array(length);
6619
6620        while (++index < length) {
6621          array[index] = args[start + index];
6622        }
6623        index = -1;
6624        var otherArgs = Array(start + 1);
6625        while (++index < start) {
6626          otherArgs[index] = args[index];
6627        }
6628        otherArgs[start] = transform(array);
6629        return apply(func, this, otherArgs);
6630      };
6631    }
6632
6633    /**
6634     * Gets the parent value at `path` of `object`.
6635     *
6636     * @private
6637     * @param {Object} object The object to query.
6638     * @param {Array} path The path to get the parent value of.
6639     * @returns {*} Returns the parent value.
6640     */
6641    function parent(object, path) {
6642      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6643    }
6644
6645    /**
6646     * Reorder `array` according to the specified indexes where the element at
6647     * the first index is assigned as the first element, the element at
6648     * the second index is assigned as the second element, and so on.
6649     *
6650     * @private
6651     * @param {Array} array The array to reorder.
6652     * @param {Array} indexes The arranged array indexes.
6653     * @returns {Array} Returns `array`.
6654     */
6655    function reorder(array, indexes) {
6656      var arrLength = array.length,
6657          length = nativeMin(indexes.length, arrLength),
6658          oldArray = copyArray(array);
6659
6660      while (length--) {
6661        var index = indexes[length];
6662        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6663      }
6664      return array;
6665    }
6666
6667    /**
6668     * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
6669     *
6670     * @private
6671     * @param {Object} object The object to query.
6672     * @param {string} key The key of the property to get.
6673     * @returns {*} Returns the property value.
6674     */
6675    function safeGet(object, key) {
6676      if (key === 'constructor' && typeof object[key] === 'function') {
6677        return;
6678      }
6679
6680      if (key == '__proto__') {
6681        return;
6682      }
6683
6684      return object[key];
6685    }
6686
6687    /**
6688     * Sets metadata for `func`.
6689     *
6690     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6691     * period of time, it will trip its breaker and transition to an identity
6692     * function to avoid garbage collection pauses in V8. See
6693     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6694     * for more details.
6695     *
6696     * @private
6697     * @param {Function} func The function to associate metadata with.
6698     * @param {*} data The metadata.
6699     * @returns {Function} Returns `func`.
6700     */
6701    var setData = shortOut(baseSetData);
6702
6703    /**
6704     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6705     *
6706     * @private
6707     * @param {Function} func The function to delay.
6708     * @param {number} wait The number of milliseconds to delay invocation.
6709     * @returns {number|Object} Returns the timer id or timeout object.
6710     */
6711    var setTimeout = ctxSetTimeout || function(func, wait) {
6712      return root.setTimeout(func, wait);
6713    };
6714
6715    /**
6716     * Sets the `toString` method of `func` to return `string`.
6717     *
6718     * @private
6719     * @param {Function} func The function to modify.
6720     * @param {Function} string The `toString` result.
6721     * @returns {Function} Returns `func`.
6722     */
6723    var setToString = shortOut(baseSetToString);
6724
6725    /**
6726     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6727     * with wrapper details in a comment at the top of the source body.
6728     *
6729     * @private
6730     * @param {Function} wrapper The function to modify.
6731     * @param {Function} reference The reference function.
6732     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6733     * @returns {Function} Returns `wrapper`.
6734     */
6735    function setWrapToString(wrapper, reference, bitmask) {
6736      var source = (reference + '');
6737      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6738    }
6739
6740    /**
6741     * Creates a function that'll short out and invoke `identity` instead
6742     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6743     * milliseconds.
6744     *
6745     * @private
6746     * @param {Function} func The function to restrict.
6747     * @returns {Function} Returns the new shortable function.
6748     */
6749    function shortOut(func) {
6750      var count = 0,
6751          lastCalled = 0;
6752
6753      return function() {
6754        var stamp = nativeNow(),
6755            remaining = HOT_SPAN - (stamp - lastCalled);
6756
6757        lastCalled = stamp;
6758        if (remaining > 0) {
6759          if (++count >= HOT_COUNT) {
6760            return arguments[0];
6761          }
6762        } else {
6763          count = 0;
6764        }
6765        return func.apply(undefined, arguments);
6766      };
6767    }
6768
6769    /**
6770     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6771     *
6772     * @private
6773     * @param {Array} array The array to shuffle.
6774     * @param {number} [size=array.length] The size of `array`.
6775     * @returns {Array} Returns `array`.
6776     */
6777    function shuffleSelf(array, size) {
6778      var index = -1,
6779          length = array.length,
6780          lastIndex = length - 1;
6781
6782      size = size === undefined ? length : size;
6783      while (++index < size) {
6784        var rand = baseRandom(index, lastIndex),
6785            value = array[rand];
6786
6787        array[rand] = array[index];
6788        array[index] = value;
6789      }
6790      array.length = size;
6791      return array;
6792    }
6793
6794    /**
6795     * Converts `string` to a property path array.
vendor: 1,775 bytes, lines 6796-6856
6796     *
6797     * @private
6798     * @param {string} string The string to convert.
6799     * @returns {Array} Returns the property path array.
6800     */
6801    var stringToPath = memoizeCapped(function(string) {
6802      var result = [];
6803      if (string.charCodeAt(0) === 46 /* . */) {
6804        result.push('');
6805      }
6806      string.replace(rePropName, function(match, number, quote, subString) {
6807        result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
6808      });
6809      return result;
6810    });
6811
6812    /**
6813     * Converts `value` to a string key if it's not a string or symbol.
6814     *
6815     * @private
6816     * @param {*} value The value to inspect.
6817     * @returns {string|symbol} Returns the key.
6818     */
6819    function toKey(value) {
6820      if (typeof value == 'string' || isSymbol(value)) {
6821        return value;
6822      }
6823      var result = (value + '');
6824      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6825    }
6826
6827    /**
6828     * Converts `func` to its source code.
6829     *
6830     * @private
6831     * @param {Function} func The function to convert.
6832     * @returns {string} Returns the source code.
6833     */
6834    function toSource(func) {
6835      if (func != null) {
6836        try {
6837          return funcToString.call(func);
6838        } catch (e) {}
6839        try {
6840          return (func + '');
6841        } catch (e) {}
6842      }
6843      return '';
6844    }
6845
6846    /**
6847     * Updates wrapper `details` based on `bitmask` flags.
6848     *
6849     * @private
6850     * @returns {Array} details The details to modify.
6851     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6852     * @returns {Array} Returns `details`.
6853     */
6854    function updateWrapDetails(details, bitmask) {
6855      arrayEach(wrapFlags, function(pair) {
6856        var value = '_.' + pair[0];
vendor: 80,381 bytes, lines 6857-9440
6857        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6858          details.push(value);
6859        }
6860      });
6861      return details.sort();
6862    }
6863
6864    /**
6865     * Creates a clone of `wrapper`.
6866     *
6867     * @private
6868     * @param {Object} wrapper The wrapper to clone.
6869     * @returns {Object} Returns the cloned wrapper.
6870     */
6871    function wrapperClone(wrapper) {
6872      if (wrapper instanceof LazyWrapper) {
6873        return wrapper.clone();
6874      }
6875      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6876      result.__actions__ = copyArray(wrapper.__actions__);
6877      result.__index__  = wrapper.__index__;
6878      result.__values__ = wrapper.__values__;
6879      return result;
6880    }
6881
6882    /*------------------------------------------------------------------------*/
6883
6884    /**
6885     * Creates an array of elements split into groups the length of `size`.
6886     * If `array` can't be split evenly, the final chunk will be the remaining
6887     * elements.
6888     *
6889     * @static
6890     * @memberOf _
6891     * @since 3.0.0
6892     * @category Array
6893     * @param {Array} array The array to process.
6894     * @param {number} [size=1] The length of each chunk
6895     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6896     * @returns {Array} Returns the new array of chunks.
6897     * @example
6898     *
6899     * _.chunk(['a', 'b', 'c', 'd'], 2);
6900     * // => [['a', 'b'], ['c', 'd']]
6901     *
6902     * _.chunk(['a', 'b', 'c', 'd'], 3);
6903     * // => [['a', 'b', 'c'], ['d']]
6904     */
6905    function chunk(array, size, guard) {
6906      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6907        size = 1;
6908      } else {
6909        size = nativeMax(toInteger(size), 0);
6910      }
6911      var length = array == null ? 0 : array.length;
6912      if (!length || size < 1) {
6913        return [];
6914      }
6915      var index = 0,
6916          resIndex = 0,
6917          result = Array(nativeCeil(length / size));
6918
6919      while (index < length) {
6920        result[resIndex++] = baseSlice(array, index, (index += size));
6921      }
6922      return result;
6923    }
6924
6925    /**
6926     * Creates an array with all falsey values removed. The values `false`, `null`,
6927     * `0`, `""`, `undefined`, and `NaN` are falsey.
6928     *
6929     * @static
6930     * @memberOf _
6931     * @since 0.1.0
6932     * @category Array
6933     * @param {Array} array The array to compact.
6934     * @returns {Array} Returns the new array of filtered values.
6935     * @example
6936     *
6937     * _.compact([0, 1, false, 2, '', 3]);
6938     * // => [1, 2, 3]
6939     */
6940    function compact(array) {
6941      var index = -1,
6942          length = array == null ? 0 : array.length,
6943          resIndex = 0,
6944          result = [];
6945
6946      while (++index < length) {
6947        var value = array[index];
6948        if (value) {
6949          result[resIndex++] = value;
6950        }
6951      }
6952      return result;
6953    }
6954
6955    /**
6956     * Creates a new array concatenating `array` with any additional arrays
6957     * and/or values.
6958     *
6959     * @static
6960     * @memberOf _
6961     * @since 4.0.0
6962     * @category Array
6963     * @param {Array} array The array to concatenate.
6964     * @param {...*} [values] The values to concatenate.
6965     * @returns {Array} Returns the new concatenated array.
6966     * @example
6967     *
6968     * var array = [1];
6969     * var other = _.concat(array, 2, [3], [[4]]);
6970     *
6971     * console.log(other);
6972     * // => [1, 2, 3, [4]]
6973     *
6974     * console.log(array);
6975     * // => [1]
6976     */
6977    function concat() {
6978      var length = arguments.length;
6979      if (!length) {
6980        return [];
6981      }
6982      var args = Array(length - 1),
6983          array = arguments[0],
6984          index = length;
6985
6986      while (index--) {
6987        args[index - 1] = arguments[index];
6988      }
6989      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6990    }
6991
6992    /**
6993     * Creates an array of `array` values not included in the other given arrays
6994     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6995     * for equality comparisons. The order and references of result values are
6996     * determined by the first array.
6997     *
6998     * **Note:** Unlike `_.pullAll`, this method returns a new array.
6999     *
7000     * @static
7001     * @memberOf _
7002     * @since 0.1.0
7003     * @category Array
7004     * @param {Array} array The array to inspect.
7005     * @param {...Array} [values] The values to exclude.
7006     * @returns {Array} Returns the new array of filtered values.
7007     * @see _.without, _.xor
7008     * @example
7009     *
7010     * _.difference([2, 1], [2, 3]);
7011     * // => [1]
7012     */
7013    var difference = baseRest(function(array, values) {
7014      return isArrayLikeObject(array)
7015        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
7016        : [];
7017    });
7018
7019    /**
7020     * This method is like `_.difference` except that it accepts `iteratee` which
7021     * is invoked for each element of `array` and `values` to generate the criterion
7022     * by which they're compared. The order and references of result values are
7023     * determined by the first array. The iteratee is invoked with one argument:
7024     * (value).
7025     *
7026     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
7027     *
7028     * @static
7029     * @memberOf _
7030     * @since 4.0.0
7031     * @category Array
7032     * @param {Array} array The array to inspect.
7033     * @param {...Array} [values] The values to exclude.
7034     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7035     * @returns {Array} Returns the new array of filtered values.
7036     * @example
7037     *
7038     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7039     * // => [1.2]
7040     *
7041     * // The `_.property` iteratee shorthand.
7042     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
7043     * // => [{ 'x': 2 }]
7044     */
7045    var differenceBy = baseRest(function(array, values) {
7046      var iteratee = last(values);
7047      if (isArrayLikeObject(iteratee)) {
7048        iteratee = undefined;
7049      }
7050      return isArrayLikeObject(array)
7051        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7052        : [];
7053    });
7054
7055    /**
7056     * This method is like `_.difference` except that it accepts `comparator`
7057     * which is invoked to compare elements of `array` to `values`. The order and
7058     * references of result values are determined by the first array. The comparator
7059     * is invoked with two arguments: (arrVal, othVal).
7060     *
7061     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7062     *
7063     * @static
7064     * @memberOf _
7065     * @since 4.0.0
7066     * @category Array
7067     * @param {Array} array The array to inspect.
7068     * @param {...Array} [values] The values to exclude.
7069     * @param {Function} [comparator] The comparator invoked per element.
7070     * @returns {Array} Returns the new array of filtered values.
7071     * @example
7072     *
7073     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7074     *
7075     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7076     * // => [{ 'x': 2, 'y': 1 }]
7077     */
7078    var differenceWith = baseRest(function(array, values) {
7079      var comparator = last(values);
7080      if (isArrayLikeObject(comparator)) {
7081        comparator = undefined;
7082      }
7083      return isArrayLikeObject(array)
7084        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7085        : [];
7086    });
7087
7088    /**
7089     * Creates a slice of `array` with `n` elements dropped from the beginning.
7090     *
7091     * @static
7092     * @memberOf _
7093     * @since 0.5.0
7094     * @category Array
7095     * @param {Array} array The array to query.
7096     * @param {number} [n=1] The number of elements to drop.
7097     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7098     * @returns {Array} Returns the slice of `array`.
7099     * @example
7100     *
7101     * _.drop([1, 2, 3]);
7102     * // => [2, 3]
7103     *
7104     * _.drop([1, 2, 3], 2);
7105     * // => [3]
7106     *
7107     * _.drop([1, 2, 3], 5);
7108     * // => []
7109     *
7110     * _.drop([1, 2, 3], 0);
7111     * // => [1, 2, 3]
7112     */
7113    function drop(array, n, guard) {
7114      var length = array == null ? 0 : array.length;
7115      if (!length) {
7116        return [];
7117      }
7118      n = (guard || n === undefined) ? 1 : toInteger(n);
7119      return baseSlice(array, n < 0 ? 0 : n, length);
7120    }
7121
7122    /**
7123     * Creates a slice of `array` with `n` elements dropped from the end.
7124     *
7125     * @static
7126     * @memberOf _
7127     * @since 3.0.0
7128     * @category Array
7129     * @param {Array} array The array to query.
7130     * @param {number} [n=1] The number of elements to drop.
7131     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7132     * @returns {Array} Returns the slice of `array`.
7133     * @example
7134     *
7135     * _.dropRight([1, 2, 3]);
7136     * // => [1, 2]
7137     *
7138     * _.dropRight([1, 2, 3], 2);
7139     * // => [1]
7140     *
7141     * _.dropRight([1, 2, 3], 5);
7142     * // => []
7143     *
7144     * _.dropRight([1, 2, 3], 0);
7145     * // => [1, 2, 3]
7146     */
7147    function dropRight(array, n, guard) {
7148      var length = array == null ? 0 : array.length;
7149      if (!length) {
7150        return [];
7151      }
7152      n = (guard || n === undefined) ? 1 : toInteger(n);
7153      n = length - n;
7154      return baseSlice(array, 0, n < 0 ? 0 : n);
7155    }
7156
7157    /**
7158     * Creates a slice of `array` excluding elements dropped from the end.
7159     * Elements are dropped until `predicate` returns falsey. The predicate is
7160     * invoked with three arguments: (value, index, array).
7161     *
7162     * @static
7163     * @memberOf _
7164     * @since 3.0.0
7165     * @category Array
7166     * @param {Array} array The array to query.
7167     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7168     * @returns {Array} Returns the slice of `array`.
7169     * @example
7170     *
7171     * var users = [
7172     *   { 'user': 'barney',  'active': true },
7173     *   { 'user': 'fred',    'active': false },
7174     *   { 'user': 'pebbles', 'active': false }
7175     * ];
7176     *
7177     * _.dropRightWhile(users, function(o) { return !o.active; });
7178     * // => objects for ['barney']
7179     *
7180     * // The `_.matches` iteratee shorthand.
7181     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7182     * // => objects for ['barney', 'fred']
7183     *
7184     * // The `_.matchesProperty` iteratee shorthand.
7185     * _.dropRightWhile(users, ['active', false]);
7186     * // => objects for ['barney']
7187     *
7188     * // The `_.property` iteratee shorthand.
7189     * _.dropRightWhile(users, 'active');
7190     * // => objects for ['barney', 'fred', 'pebbles']
7191     */
7192    function dropRightWhile(array, predicate) {
7193      return (array && array.length)
7194        ? baseWhile(array, getIteratee(predicate, 3), true, true)
7195        : [];
7196    }
7197
7198    /**
7199     * Creates a slice of `array` excluding elements dropped from the beginning.
7200     * Elements are dropped until `predicate` returns falsey. The predicate is
7201     * invoked with three arguments: (value, index, array).
7202     *
7203     * @static
7204     * @memberOf _
7205     * @since 3.0.0
7206     * @category Array
7207     * @param {Array} array The array to query.
7208     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7209     * @returns {Array} Returns the slice of `array`.
7210     * @example
7211     *
7212     * var users = [
7213     *   { 'user': 'barney',  'active': false },
7214     *   { 'user': 'fred',    'active': false },
7215     *   { 'user': 'pebbles', 'active': true }
7216     * ];
7217     *
7218     * _.dropWhile(users, function(o) { return !o.active; });
7219     * // => objects for ['pebbles']
7220     *
7221     * // The `_.matches` iteratee shorthand.
7222     * _.dropWhile(users, { 'user': 'barney', 'active': false });
7223     * // => objects for ['fred', 'pebbles']
7224     *
7225     * // The `_.matchesProperty` iteratee shorthand.
7226     * _.dropWhile(users, ['active', false]);
7227     * // => objects for ['pebbles']
7228     *
7229     * // The `_.property` iteratee shorthand.
7230     * _.dropWhile(users, 'active');
7231     * // => objects for ['barney', 'fred', 'pebbles']
7232     */
7233    function dropWhile(array, predicate) {
7234      return (array && array.length)
7235        ? baseWhile(array, getIteratee(predicate, 3), true)
7236        : [];
7237    }
7238
7239    /**
7240     * Fills elements of `array` with `value` from `start` up to, but not
7241     * including, `end`.
7242     *
7243     * **Note:** This method mutates `array`.
7244     *
7245     * @static
7246     * @memberOf _
7247     * @since 3.2.0
7248     * @category Array
7249     * @param {Array} array The array to fill.
7250     * @param {*} value The value to fill `array` with.
7251     * @param {number} [start=0] The start position.
7252     * @param {number} [end=array.length] The end position.
7253     * @returns {Array} Returns `array`.
7254     * @example
7255     *
7256     * var array = [1, 2, 3];
7257     *
7258     * _.fill(array, 'a');
7259     * console.log(array);
7260     * // => ['a', 'a', 'a']
7261     *
7262     * _.fill(Array(3), 2);
7263     * // => [2, 2, 2]
7264     *
7265     * _.fill([4, 6, 8, 10], '*', 1, 3);
7266     * // => [4, '*', '*', 10]
7267     */
7268    function fill(array, value, start, end) {
7269      var length = array == null ? 0 : array.length;
7270      if (!length) {
7271        return [];
7272      }
7273      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7274        start = 0;
7275        end = length;
7276      }
7277      return baseFill(array, value, start, end);
7278    }
7279
7280    /**
7281     * This method is like `_.find` except that it returns the index of the first
7282     * element `predicate` returns truthy for instead of the element itself.
7283     *
7284     * @static
7285     * @memberOf _
7286     * @since 1.1.0
7287     * @category Array
7288     * @param {Array} array The array to inspect.
7289     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7290     * @param {number} [fromIndex=0] The index to search from.
7291     * @returns {number} Returns the index of the found element, else `-1`.
7292     * @example
7293     *
7294     * var users = [
7295     *   { 'user': 'barney',  'active': false },
7296     *   { 'user': 'fred',    'active': false },
7297     *   { 'user': 'pebbles', 'active': true }
7298     * ];
7299     *
7300     * _.findIndex(users, function(o) { return o.user == 'barney'; });
7301     * // => 0
7302     *
7303     * // The `_.matches` iteratee shorthand.
7304     * _.findIndex(users, { 'user': 'fred', 'active': false });
7305     * // => 1
7306     *
7307     * // The `_.matchesProperty` iteratee shorthand.
7308     * _.findIndex(users, ['active', false]);
7309     * // => 0
7310     *
7311     * // The `_.property` iteratee shorthand.
7312     * _.findIndex(users, 'active');
7313     * // => 2
7314     */
7315    function findIndex(array, predicate, fromIndex) {
7316      var length = array == null ? 0 : array.length;
7317      if (!length) {
7318        return -1;
7319      }
7320      var index = fromIndex == null ? 0 : toInteger(fromIndex);
7321      if (index < 0) {
7322        index = nativeMax(length + index, 0);
7323      }
7324      return baseFindIndex(array, getIteratee(predicate, 3), index);
7325    }
7326
7327    /**
7328     * This method is like `_.findIndex` except that it iterates over elements
7329     * of `collection` from right to left.
7330     *
7331     * @static
7332     * @memberOf _
7333     * @since 2.0.0
7334     * @category Array
7335     * @param {Array} array The array to inspect.
7336     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7337     * @param {number} [fromIndex=array.length-1] The index to search from.
7338     * @returns {number} Returns the index of the found element, else `-1`.
7339     * @example
7340     *
7341     * var users = [
7342     *   { 'user': 'barney',  'active': true },
7343     *   { 'user': 'fred',    'active': false },
7344     *   { 'user': 'pebbles', 'active': false }
7345     * ];
7346     *
7347     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7348     * // => 2
7349     *
7350     * // The `_.matches` iteratee shorthand.
7351     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7352     * // => 0
7353     *
7354     * // The `_.matchesProperty` iteratee shorthand.
7355     * _.findLastIndex(users, ['active', false]);
7356     * // => 2
7357     *
7358     * // The `_.property` iteratee shorthand.
7359     * _.findLastIndex(users, 'active');
7360     * // => 0
7361     */
7362    function findLastIndex(array, predicate, fromIndex) {
7363      var length = array == null ? 0 : array.length;
7364      if (!length) {
7365        return -1;
7366      }
7367      var index = length - 1;
7368      if (fromIndex !== undefined) {
7369        index = toInteger(fromIndex);
7370        index = fromIndex < 0
7371          ? nativeMax(length + index, 0)
7372          : nativeMin(index, length - 1);
7373      }
7374      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7375    }
7376
7377    /**
7378     * Flattens `array` a single level deep.
7379     *
7380     * @static
7381     * @memberOf _
7382     * @since 0.1.0
7383     * @category Array
7384     * @param {Array} array The array to flatten.
7385     * @returns {Array} Returns the new flattened array.
7386     * @example
7387     *
7388     * _.flatten([1, [2, [3, [4]], 5]]);
7389     * // => [1, 2, [3, [4]], 5]
7390     */
7391    function flatten(array) {
7392      var length = array == null ? 0 : array.length;
7393      return length ? baseFlatten(array, 1) : [];
7394    }
7395
7396    /**
7397     * Recursively flattens `array`.
7398     *
7399     * @static
7400     * @memberOf _
7401     * @since 3.0.0
7402     * @category Array
7403     * @param {Array} array The array to flatten.
7404     * @returns {Array} Returns the new flattened array.
7405     * @example
7406     *
7407     * _.flattenDeep([1, [2, [3, [4]], 5]]);
7408     * // => [1, 2, 3, 4, 5]
7409     */
7410    function flattenDeep(array) {
7411      var length = array == null ? 0 : array.length;
7412      return length ? baseFlatten(array, INFINITY) : [];
7413    }
7414
7415    /**
7416     * Recursively flatten `array` up to `depth` times.
7417     *
7418     * @static
7419     * @memberOf _
7420     * @since 4.4.0
7421     * @category Array
7422     * @param {Array} array The array to flatten.
7423     * @param {number} [depth=1] The maximum recursion depth.
7424     * @returns {Array} Returns the new flattened array.
7425     * @example
7426     *
7427     * var array = [1, [2, [3, [4]], 5]];
7428     *
7429     * _.flattenDepth(array, 1);
7430     * // => [1, 2, [3, [4]], 5]
7431     *
7432     * _.flattenDepth(array, 2);
7433     * // => [1, 2, 3, [4], 5]
7434     */
7435    function flattenDepth(array, depth) {
7436      var length = array == null ? 0 : array.length;
7437      if (!length) {
7438        return [];
7439      }
7440      depth = depth === undefined ? 1 : toInteger(depth);
7441      return baseFlatten(array, depth);
7442    }
7443
7444    /**
7445     * The inverse of `_.toPairs`; this method returns an object composed
7446     * from key-value `pairs`.
7447     *
7448     * @static
7449     * @memberOf _
7450     * @since 4.0.0
7451     * @category Array
7452     * @param {Array} pairs The key-value pairs.
7453     * @returns {Object} Returns the new object.
7454     * @example
7455     *
7456     * _.fromPairs([['a', 1], ['b', 2]]);
7457     * // => { 'a': 1, 'b': 2 }
7458     */
7459    function fromPairs(pairs) {
7460      var index = -1,
7461          length = pairs == null ? 0 : pairs.length,
7462          result = {};
7463
7464      while (++index < length) {
7465        var pair = pairs[index];
7466        result[pair[0]] = pair[1];
7467      }
7468      return result;
7469    }
7470
7471    /**
7472     * Gets the first element of `array`.
7473     *
7474     * @static
7475     * @memberOf _
7476     * @since 0.1.0
7477     * @alias first
7478     * @category Array
7479     * @param {Array} array The array to query.
7480     * @returns {*} Returns the first element of `array`.
7481     * @example
7482     *
7483     * _.head([1, 2, 3]);
7484     * // => 1
7485     *
7486     * _.head([]);
7487     * // => undefined
7488     */
7489    function head(array) {
7490      return (array && array.length) ? array[0] : undefined;
7491    }
7492
7493    /**
7494     * Gets the index at which the first occurrence of `value` is found in `array`
7495     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7496     * for equality comparisons. If `fromIndex` is negative, it's used as the
7497     * offset from the end of `array`.
7498     *
7499     * @static
7500     * @memberOf _
7501     * @since 0.1.0
7502     * @category Array
7503     * @param {Array} array The array to inspect.
7504     * @param {*} value The value to search for.
7505     * @param {number} [fromIndex=0] The index to search from.
7506     * @returns {number} Returns the index of the matched value, else `-1`.
7507     * @example
7508     *
7509     * _.indexOf([1, 2, 1, 2], 2);
7510     * // => 1
7511     *
7512     * // Search from the `fromIndex`.
7513     * _.indexOf([1, 2, 1, 2], 2, 2);
7514     * // => 3
7515     */
7516    function indexOf(array, value, fromIndex) {
7517      var length = array == null ? 0 : array.length;
7518      if (!length) {
7519        return -1;
7520      }
7521      var index = fromIndex == null ? 0 : toInteger(fromIndex);
7522      if (index < 0) {
7523        index = nativeMax(length + index, 0);
7524      }
7525      return baseIndexOf(array, value, index);
7526    }
7527
7528    /**
7529     * Gets all but the last element of `array`.
7530     *
7531     * @static
7532     * @memberOf _
7533     * @since 0.1.0
7534     * @category Array
7535     * @param {Array} array The array to query.
7536     * @returns {Array} Returns the slice of `array`.
7537     * @example
7538     *
7539     * _.initial([1, 2, 3]);
7540     * // => [1, 2]
7541     */
7542    function initial(array) {
7543      var length = array == null ? 0 : array.length;
7544      return length ? baseSlice(array, 0, -1) : [];
7545    }
7546
7547    /**
7548     * Creates an array of unique values that are included in all given arrays
7549     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7550     * for equality comparisons. The order and references of result values are
7551     * determined by the first array.
7552     *
7553     * @static
7554     * @memberOf _
7555     * @since 0.1.0
7556     * @category Array
7557     * @param {...Array} [arrays] The arrays to inspect.
7558     * @returns {Array} Returns the new array of intersecting values.
7559     * @example
7560     *
7561     * _.intersection([2, 1], [2, 3]);
7562     * // => [2]
7563     */
7564    var intersection = baseRest(function(arrays) {
7565      var mapped = arrayMap(arrays, castArrayLikeObject);
7566      return (mapped.length && mapped[0] === arrays[0])
7567        ? baseIntersection(mapped)
7568        : [];
7569    });
7570
7571    /**
7572     * This method is like `_.intersection` except that it accepts `iteratee`
7573     * which is invoked for each element of each `arrays` to generate the criterion
7574     * by which they're compared. The order and references of result values are
7575     * determined by the first array. The iteratee is invoked with one argument:
7576     * (value).
7577     *
7578     * @static
7579     * @memberOf _
7580     * @since 4.0.0
7581     * @category Array
7582     * @param {...Array} [arrays] The arrays to inspect.
7583     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7584     * @returns {Array} Returns the new array of intersecting values.
7585     * @example
7586     *
7587     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7588     * // => [2.1]
7589     *
7590     * // The `_.property` iteratee shorthand.
7591     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7592     * // => [{ 'x': 1 }]
7593     */
7594    var intersectionBy = baseRest(function(arrays) {
7595      var iteratee = last(arrays),
7596          mapped = arrayMap(arrays, castArrayLikeObject);
7597
7598      if (iteratee === last(mapped)) {
7599        iteratee = undefined;
7600      } else {
7601        mapped.pop();
7602      }
7603      return (mapped.length && mapped[0] === arrays[0])
7604        ? baseIntersection(mapped, getIteratee(iteratee, 2))
7605        : [];
7606    });
7607
7608    /**
7609     * This method is like `_.intersection` except that it accepts `comparator`
7610     * which is invoked to compare elements of `arrays`. The order and references
7611     * of result values are determined by the first array. The comparator is
7612     * invoked with two arguments: (arrVal, othVal).
7613     *
7614     * @static
7615     * @memberOf _
7616     * @since 4.0.0
7617     * @category Array
7618     * @param {...Array} [arrays] The arrays to inspect.
7619     * @param {Function} [comparator] The comparator invoked per element.
7620     * @returns {Array} Returns the new array of intersecting values.
7621     * @example
7622     *
7623     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7624     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7625     *
7626     * _.intersectionWith(objects, others, _.isEqual);
7627     * // => [{ 'x': 1, 'y': 2 }]
7628     */
7629    var intersectionWith = baseRest(function(arrays) {
7630      var comparator = last(arrays),
7631          mapped = arrayMap(arrays, castArrayLikeObject);
7632
7633      comparator = typeof comparator == 'function' ? comparator : undefined;
7634      if (comparator) {
7635        mapped.pop();
7636      }
7637      return (mapped.length && mapped[0] === arrays[0])
7638        ? baseIntersection(mapped, undefined, comparator)
7639        : [];
7640    });
7641
7642    /**
7643     * Converts all elements in `array` into a string separated by `separator`.
7644     *
7645     * @static
7646     * @memberOf _
7647     * @since 4.0.0
7648     * @category Array
7649     * @param {Array} array The array to convert.
7650     * @param {string} [separator=','] The element separator.
7651     * @returns {string} Returns the joined string.
7652     * @example
7653     *
7654     * _.join(['a', 'b', 'c'], '~');
7655     * // => 'a~b~c'
7656     */
7657    function join(array, separator) {
7658      return array == null ? '' : nativeJoin.call(array, separator);
7659    }
7660
7661    /**
7662     * Gets the last element of `array`.
7663     *
7664     * @static
7665     * @memberOf _
7666     * @since 0.1.0
7667     * @category Array
7668     * @param {Array} array The array to query.
7669     * @returns {*} Returns the last element of `array`.
7670     * @example
7671     *
7672     * _.last([1, 2, 3]);
7673     * // => 3
7674     */
7675    function last(array) {
7676      var length = array == null ? 0 : array.length;
7677      return length ? array[length - 1] : undefined;
7678    }
7679
7680    /**
7681     * This method is like `_.indexOf` except that it iterates over elements of
7682     * `array` from right to left.
7683     *
7684     * @static
7685     * @memberOf _
7686     * @since 0.1.0
7687     * @category Array
7688     * @param {Array} array The array to inspect.
7689     * @param {*} value The value to search for.
7690     * @param {number} [fromIndex=array.length-1] The index to search from.
7691     * @returns {number} Returns the index of the matched value, else `-1`.
7692     * @example
7693     *
7694     * _.lastIndexOf([1, 2, 1, 2], 2);
7695     * // => 3
7696     *
7697     * // Search from the `fromIndex`.
7698     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7699     * // => 1
7700     */
7701    function lastIndexOf(array, value, fromIndex) {
7702      var length = array == null ? 0 : array.length;
7703      if (!length) {
7704        return -1;
7705      }
7706      var index = length;
7707      if (fromIndex !== undefined) {
7708        index = toInteger(fromIndex);
7709        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7710      }
7711      return value === value
7712        ? strictLastIndexOf(array, value, index)
7713        : baseFindIndex(array, baseIsNaN, index, true);
7714    }
7715
7716    /**
7717     * Gets the element at index `n` of `array`. If `n` is negative, the nth
7718     * element from the end is returned.
7719     *
7720     * @static
7721     * @memberOf _
7722     * @since 4.11.0
7723     * @category Array
7724     * @param {Array} array The array to query.
7725     * @param {number} [n=0] The index of the element to return.
7726     * @returns {*} Returns the nth element of `array`.
7727     * @example
7728     *
7729     * var array = ['a', 'b', 'c', 'd'];
7730     *
7731     * _.nth(array, 1);
7732     * // => 'b'
7733     *
7734     * _.nth(array, -2);
7735     * // => 'c';
7736     */
7737    function nth(array, n) {
7738      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7739    }
7740
7741    /**
7742     * Removes all given values from `array` using
7743     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7744     * for equality comparisons.
7745     *
7746     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7747     * to remove elements from an array by predicate.
7748     *
7749     * @static
7750     * @memberOf _
7751     * @since 2.0.0
7752     * @category Array
7753     * @param {Array} array The array to modify.
7754     * @param {...*} [values] The values to remove.
7755     * @returns {Array} Returns `array`.
7756     * @example
7757     *
7758     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7759     *
7760     * _.pull(array, 'a', 'c');
7761     * console.log(array);
7762     * // => ['b', 'b']
7763     */
7764    var pull = baseRest(pullAll);
7765
7766    /**
7767     * This method is like `_.pull` except that it accepts an array of values to remove.
7768     *
7769     * **Note:** Unlike `_.difference`, this method mutates `array`.
7770     *
7771     * @static
7772     * @memberOf _
7773     * @since 4.0.0
7774     * @category Array
7775     * @param {Array} array The array to modify.
7776     * @param {Array} values The values to remove.
7777     * @returns {Array} Returns `array`.
7778     * @example
7779     *
7780     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7781     *
7782     * _.pullAll(array, ['a', 'c']);
7783     * console.log(array);
7784     * // => ['b', 'b']
7785     */
7786    function pullAll(array, values) {
7787      return (array && array.length && values && values.length)
7788        ? basePullAll(array, values)
7789        : array;
7790    }
7791
7792    /**
7793     * This method is like `_.pullAll` except that it accepts `iteratee` which is
7794     * invoked for each element of `array` and `values` to generate the criterion
7795     * by which they're compared. The iteratee is invoked with one argument: (value).
7796     *
7797     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7798     *
7799     * @static
7800     * @memberOf _
7801     * @since 4.0.0
7802     * @category Array
7803     * @param {Array} array The array to modify.
7804     * @param {Array} values The values to remove.
7805     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7806     * @returns {Array} Returns `array`.
7807     * @example
7808     *
7809     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7810     *
7811     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7812     * console.log(array);
7813     * // => [{ 'x': 2 }]
7814     */
7815    function pullAllBy(array, values, iteratee) {
7816      return (array && array.length && values && values.length)
7817        ? basePullAll(array, values, getIteratee(iteratee, 2))
7818        : array;
7819    }
7820
7821    /**
7822     * This method is like `_.pullAll` except that it accepts `comparator` which
7823     * is invoked to compare elements of `array` to `values`. The comparator is
7824     * invoked with two arguments: (arrVal, othVal).
7825     *
7826     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7827     *
7828     * @static
7829     * @memberOf _
7830     * @since 4.6.0
7831     * @category Array
7832     * @param {Array} array The array to modify.
7833     * @param {Array} values The values to remove.
7834     * @param {Function} [comparator] The comparator invoked per element.
7835     * @returns {Array} Returns `array`.
7836     * @example
7837     *
7838     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7839     *
7840     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7841     * console.log(array);
7842     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7843     */
7844    function pullAllWith(array, values, comparator) {
7845      return (array && array.length && values && values.length)
7846        ? basePullAll(array, values, undefined, comparator)
7847        : array;
7848    }
7849
7850    /**
7851     * Removes elements from `array` corresponding to `indexes` and returns an
7852     * array of removed elements.
7853     *
7854     * **Note:** Unlike `_.at`, this method mutates `array`.
7855     *
7856     * @static
7857     * @memberOf _
7858     * @since 3.0.0
7859     * @category Array
7860     * @param {Array} array The array to modify.
7861     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7862     * @returns {Array} Returns the new array of removed elements.
7863     * @example
7864     *
7865     * var array = ['a', 'b', 'c', 'd'];
7866     * var pulled = _.pullAt(array, [1, 3]);
7867     *
7868     * console.log(array);
7869     * // => ['a', 'c']
7870     *
7871     * console.log(pulled);
7872     * // => ['b', 'd']
7873     */
7874    var pullAt = flatRest(function(array, indexes) {
7875      var length = array == null ? 0 : array.length,
7876          result = baseAt(array, indexes);
7877
7878      basePullAt(array, arrayMap(indexes, function(index) {
7879        return isIndex(index, length) ? +index : index;
7880      }).sort(compareAscending));
7881
7882      return result;
7883    });
7884
7885    /**
7886     * Removes all elements from `array` that `predicate` returns truthy for
7887     * and returns an array of the removed elements. The predicate is invoked
7888     * with three arguments: (value, index, array).
7889     *
7890     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7891     * to pull elements from an array by value.
7892     *
7893     * @static
7894     * @memberOf _
7895     * @since 2.0.0
7896     * @category Array
7897     * @param {Array} array The array to modify.
7898     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7899     * @returns {Array} Returns the new array of removed elements.
7900     * @example
7901     *
7902     * var array = [1, 2, 3, 4];
7903     * var evens = _.remove(array, function(n) {
7904     *   return n % 2 == 0;
7905     * });
7906     *
7907     * console.log(array);
7908     * // => [1, 3]
7909     *
7910     * console.log(evens);
7911     * // => [2, 4]
7912     */
7913    function remove(array, predicate) {
7914      var result = [];
7915      if (!(array && array.length)) {
7916        return result;
7917      }
7918      var index = -1,
7919          indexes = [],
7920          length = array.length;
7921
7922      predicate = getIteratee(predicate, 3);
7923      while (++index < length) {
7924        var value = array[index];
7925        if (predicate(value, index, array)) {
7926          result.push(value);
7927          indexes.push(index);
7928        }
7929      }
7930      basePullAt(array, indexes);
7931      return result;
7932    }
7933
7934    /**
7935     * Reverses `array` so that the first element becomes the last, the second
7936     * element becomes the second to last, and so on.
7937     *
7938     * **Note:** This method mutates `array` and is based on
7939     * [`Array#reverse`](https://mdn.io/Array/reverse).
7940     *
7941     * @static
7942     * @memberOf _
7943     * @since 4.0.0
7944     * @category Array
7945     * @param {Array} array The array to modify.
7946     * @returns {Array} Returns `array`.
7947     * @example
7948     *
7949     * var array = [1, 2, 3];
7950     *
7951     * _.reverse(array);
7952     * // => [3, 2, 1]
7953     *
7954     * console.log(array);
7955     * // => [3, 2, 1]
7956     */
7957    function reverse(array) {
7958      return array == null ? array : nativeReverse.call(array);
7959    }
7960
7961    /**
7962     * Creates a slice of `array` from `start` up to, but not including, `end`.
7963     *
7964     * **Note:** This method is used instead of
7965     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7966     * returned.
7967     *
7968     * @static
7969     * @memberOf _
7970     * @since 3.0.0
7971     * @category Array
7972     * @param {Array} array The array to slice.
7973     * @param {number} [start=0] The start position.
7974     * @param {number} [end=array.length] The end position.
7975     * @returns {Array} Returns the slice of `array`.
7976     */
7977    function slice(array, start, end) {
7978      var length = array == null ? 0 : array.length;
7979      if (!length) {
7980        return [];
7981      }
7982      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7983        start = 0;
7984        end = length;
7985      }
7986      else {
7987        start = start == null ? 0 : toInteger(start);
7988        end = end === undefined ? length : toInteger(end);
7989      }
7990      return baseSlice(array, start, end);
7991    }
7992
7993    /**
7994     * Uses a binary search to determine the lowest index at which `value`
7995     * should be inserted into `array` in order to maintain its sort order.
7996     *
7997     * @static
7998     * @memberOf _
7999     * @since 0.1.0
8000     * @category Array
8001     * @param {Array} array The sorted array to inspect.
8002     * @param {*} value The value to evaluate.
8003     * @returns {number} Returns the index at which `value` should be inserted
8004     *  into `array`.
8005     * @example
8006     *
8007     * _.sortedIndex([30, 50], 40);
8008     * // => 1
8009     */
8010    function sortedIndex(array, value) {
8011      return baseSortedIndex(array, value);
8012    }
8013
8014    /**
8015     * This method is like `_.sortedIndex` except that it accepts `iteratee`
8016     * which is invoked for `value` and each element of `array` to compute their
8017     * sort ranking. The iteratee is invoked with one argument: (value).
8018     *
8019     * @static
8020     * @memberOf _
8021     * @since 4.0.0
8022     * @category Array
8023     * @param {Array} array The sorted array to inspect.
8024     * @param {*} value The value to evaluate.
8025     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8026     * @returns {number} Returns the index at which `value` should be inserted
8027     *  into `array`.
8028     * @example
8029     *
8030     * var objects = [{ 'x': 4 }, { 'x': 5 }];
8031     *
8032     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8033     * // => 0
8034     *
8035     * // The `_.property` iteratee shorthand.
8036     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
8037     * // => 0
8038     */
8039    function sortedIndexBy(array, value, iteratee) {
8040      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
8041    }
8042
8043    /**
8044     * This method is like `_.indexOf` except that it performs a binary
8045     * search on a sorted `array`.
8046     *
8047     * @static
8048     * @memberOf _
8049     * @since 4.0.0
8050     * @category Array
8051     * @param {Array} array The array to inspect.
8052     * @param {*} value The value to search for.
8053     * @returns {number} Returns the index of the matched value, else `-1`.
8054     * @example
8055     *
8056     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8057     * // => 1
8058     */
8059    function sortedIndexOf(array, value) {
8060      var length = array == null ? 0 : array.length;
8061      if (length) {
8062        var index = baseSortedIndex(array, value);
8063        if (index < length && eq(array[index], value)) {
8064          return index;
8065        }
8066      }
8067      return -1;
8068    }
8069
8070    /**
8071     * This method is like `_.sortedIndex` except that it returns the highest
8072     * index at which `value` should be inserted into `array` in order to
8073     * maintain its sort order.
8074     *
8075     * @static
8076     * @memberOf _
8077     * @since 3.0.0
8078     * @category Array
8079     * @param {Array} array The sorted array to inspect.
8080     * @param {*} value The value to evaluate.
8081     * @returns {number} Returns the index at which `value` should be inserted
8082     *  into `array`.
8083     * @example
8084     *
8085     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8086     * // => 4
8087     */
8088    function sortedLastIndex(array, value) {
8089      return baseSortedIndex(array, value, true);
8090    }
8091
8092    /**
8093     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8094     * which is invoked for `value` and each element of `array` to compute their
8095     * sort ranking. The iteratee is invoked with one argument: (value).
8096     *
8097     * @static
8098     * @memberOf _
8099     * @since 4.0.0
8100     * @category Array
8101     * @param {Array} array The sorted array to inspect.
8102     * @param {*} value The value to evaluate.
8103     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8104     * @returns {number} Returns the index at which `value` should be inserted
8105     *  into `array`.
8106     * @example
8107     *
8108     * var objects = [{ 'x': 4 }, { 'x': 5 }];
8109     *
8110     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8111     * // => 1
8112     *
8113     * // The `_.property` iteratee shorthand.
8114     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8115     * // => 1
8116     */
8117    function sortedLastIndexBy(array, value, iteratee) {
8118      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8119    }
8120
8121    /**
8122     * This method is like `_.lastIndexOf` except that it performs a binary
8123     * search on a sorted `array`.
8124     *
8125     * @static
8126     * @memberOf _
8127     * @since 4.0.0
8128     * @category Array
8129     * @param {Array} array The array to inspect.
8130     * @param {*} value The value to search for.
8131     * @returns {number} Returns the index of the matched value, else `-1`.
8132     * @example
8133     *
8134     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8135     * // => 3
8136     */
8137    function sortedLastIndexOf(array, value) {
8138      var length = array == null ? 0 : array.length;
8139      if (length) {
8140        var index = baseSortedIndex(array, value, true) - 1;
8141        if (eq(array[index], value)) {
8142          return index;
8143        }
8144      }
8145      return -1;
8146    }
8147
8148    /**
8149     * This method is like `_.uniq` except that it's designed and optimized
8150     * for sorted arrays.
8151     *
8152     * @static
8153     * @memberOf _
8154     * @since 4.0.0
8155     * @category Array
8156     * @param {Array} array The array to inspect.
8157     * @returns {Array} Returns the new duplicate free array.
8158     * @example
8159     *
8160     * _.sortedUniq([1, 1, 2]);
8161     * // => [1, 2]
8162     */
8163    function sortedUniq(array) {
8164      return (array && array.length)
8165        ? baseSortedUniq(array)
8166        : [];
8167    }
8168
8169    /**
8170     * This method is like `_.uniqBy` except that it's designed and optimized
8171     * for sorted arrays.
8172     *
8173     * @static
8174     * @memberOf _
8175     * @since 4.0.0
8176     * @category Array
8177     * @param {Array} array The array to inspect.
8178     * @param {Function} [iteratee] The iteratee invoked per element.
8179     * @returns {Array} Returns the new duplicate free array.
8180     * @example
8181     *
8182     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8183     * // => [1.1, 2.3]
8184     */
8185    function sortedUniqBy(array, iteratee) {
8186      return (array && array.length)
8187        ? baseSortedUniq(array, getIteratee(iteratee, 2))
8188        : [];
8189    }
8190
8191    /**
8192     * Gets all but the first element of `array`.
8193     *
8194     * @static
8195     * @memberOf _
8196     * @since 4.0.0
8197     * @category Array
8198     * @param {Array} array The array to query.
8199     * @returns {Array} Returns the slice of `array`.
8200     * @example
8201     *
8202     * _.tail([1, 2, 3]);
8203     * // => [2, 3]
8204     */
8205    function tail(array) {
8206      var length = array == null ? 0 : array.length;
8207      return length ? baseSlice(array, 1, length) : [];
8208    }
8209
8210    /**
8211     * Creates a slice of `array` with `n` elements taken from the beginning.
8212     *
8213     * @static
8214     * @memberOf _
8215     * @since 0.1.0
8216     * @category Array
8217     * @param {Array} array The array to query.
8218     * @param {number} [n=1] The number of elements to take.
8219     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8220     * @returns {Array} Returns the slice of `array`.
8221     * @example
8222     *
8223     * _.take([1, 2, 3]);
8224     * // => [1]
8225     *
8226     * _.take([1, 2, 3], 2);
8227     * // => [1, 2]
8228     *
8229     * _.take([1, 2, 3], 5);
8230     * // => [1, 2, 3]
8231     *
8232     * _.take([1, 2, 3], 0);
8233     * // => []
8234     */
8235    function take(array, n, guard) {
8236      if (!(array && array.length)) {
8237        return [];
8238      }
8239      n = (guard || n === undefined) ? 1 : toInteger(n);
8240      return baseSlice(array, 0, n < 0 ? 0 : n);
8241    }
8242
8243    /**
8244     * Creates a slice of `array` with `n` elements taken from the end.
8245     *
8246     * @static
8247     * @memberOf _
8248     * @since 3.0.0
8249     * @category Array
8250     * @param {Array} array The array to query.
8251     * @param {number} [n=1] The number of elements to take.
8252     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8253     * @returns {Array} Returns the slice of `array`.
8254     * @example
8255     *
8256     * _.takeRight([1, 2, 3]);
8257     * // => [3]
8258     *
8259     * _.takeRight([1, 2, 3], 2);
8260     * // => [2, 3]
8261     *
8262     * _.takeRight([1, 2, 3], 5);
8263     * // => [1, 2, 3]
8264     *
8265     * _.takeRight([1, 2, 3], 0);
8266     * // => []
8267     */
8268    function takeRight(array, n, guard) {
8269      var length = array == null ? 0 : array.length;
8270      if (!length) {
8271        return [];
8272      }
8273      n = (guard || n === undefined) ? 1 : toInteger(n);
8274      n = length - n;
8275      return baseSlice(array, n < 0 ? 0 : n, length);
8276    }
8277
8278    /**
8279     * Creates a slice of `array` with elements taken from the end. Elements are
8280     * taken until `predicate` returns falsey. The predicate is invoked with
8281     * three arguments: (value, index, array).
8282     *
8283     * @static
8284     * @memberOf _
8285     * @since 3.0.0
8286     * @category Array
8287     * @param {Array} array The array to query.
8288     * @param {Function} [predicate=_.identity] The function invoked per iteration.
8289     * @returns {Array} Returns the slice of `array`.
8290     * @example
8291     *
8292     * var users = [
8293     *   { 'user': 'barney',  'active': true },
8294     *   { 'user': 'fred',    'active': false },
8295     *   { 'user': 'pebbles', 'active': false }
8296     * ];
8297     *
8298     * _.takeRightWhile(users, function(o) { return !o.active; });
8299     * // => objects for ['fred', 'pebbles']
8300     *
8301     * // The `_.matches` iteratee shorthand.
8302     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8303     * // => objects for ['pebbles']
8304     *
8305     * // The `_.matchesProperty` iteratee shorthand.
8306     * _.takeRightWhile(users, ['active', false]);
8307     * // => objects for ['fred', 'pebbles']
8308     *
8309     * // The `_.property` iteratee shorthand.
8310     * _.takeRightWhile(users, 'active');
8311     * // => []
8312     */
8313    function takeRightWhile(array, predicate) {
8314      return (array && array.length)
8315        ? baseWhile(array, getIteratee(predicate, 3), false, true)
8316        : [];
8317    }
8318
8319    /**
8320     * Creates a slice of `array` with elements taken from the beginning. Elements
8321     * are taken until `predicate` returns falsey. The predicate is invoked with
8322     * three arguments: (value, index, array).
8323     *
8324     * @static
8325     * @memberOf _
8326     * @since 3.0.0
8327     * @category Array
8328     * @param {Array} array The array to query.
8329     * @param {Function} [predicate=_.identity] The function invoked per iteration.
8330     * @returns {Array} Returns the slice of `array`.
8331     * @example
8332     *
8333     * var users = [
8334     *   { 'user': 'barney',  'active': false },
8335     *   { 'user': 'fred',    'active': false },
8336     *   { 'user': 'pebbles', 'active': true }
8337     * ];
8338     *
8339     * _.takeWhile(users, function(o) { return !o.active; });
8340     * // => objects for ['barney', 'fred']
8341     *
8342     * // The `_.matches` iteratee shorthand.
8343     * _.takeWhile(users, { 'user': 'barney', 'active': false });
8344     * // => objects for ['barney']
8345     *
8346     * // The `_.matchesProperty` iteratee shorthand.
8347     * _.takeWhile(users, ['active', false]);
8348     * // => objects for ['barney', 'fred']
8349     *
8350     * // The `_.property` iteratee shorthand.
8351     * _.takeWhile(users, 'active');
8352     * // => []
8353     */
8354    function takeWhile(array, predicate) {
8355      return (array && array.length)
8356        ? baseWhile(array, getIteratee(predicate, 3))
8357        : [];
8358    }
8359
8360    /**
8361     * Creates an array of unique values, in order, from all given arrays using
8362     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8363     * for equality comparisons.
8364     *
8365     * @static
8366     * @memberOf _
8367     * @since 0.1.0
8368     * @category Array
8369     * @param {...Array} [arrays] The arrays to inspect.
8370     * @returns {Array} Returns the new array of combined values.
8371     * @example
8372     *
8373     * _.union([2], [1, 2]);
8374     * // => [2, 1]
8375     */
8376    var union = baseRest(function(arrays) {
8377      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8378    });
8379
8380    /**
8381     * This method is like `_.union` except that it accepts `iteratee` which is
8382     * invoked for each element of each `arrays` to generate the criterion by
8383     * which uniqueness is computed. Result values are chosen from the first
8384     * array in which the value occurs. The iteratee is invoked with one argument:
8385     * (value).
8386     *
8387     * @static
8388     * @memberOf _
8389     * @since 4.0.0
8390     * @category Array
8391     * @param {...Array} [arrays] The arrays to inspect.
8392     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8393     * @returns {Array} Returns the new array of combined values.
8394     * @example
8395     *
8396     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8397     * // => [2.1, 1.2]
8398     *
8399     * // The `_.property` iteratee shorthand.
8400     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8401     * // => [{ 'x': 1 }, { 'x': 2 }]
8402     */
8403    var unionBy = baseRest(function(arrays) {
8404      var iteratee = last(arrays);
8405      if (isArrayLikeObject(iteratee)) {
8406        iteratee = undefined;
8407      }
8408      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8409    });
8410
8411    /**
8412     * This method is like `_.union` except that it accepts `comparator` which
8413     * is invoked to compare elements of `arrays`. Result values are chosen from
8414     * the first array in which the value occurs. The comparator is invoked
8415     * with two arguments: (arrVal, othVal).
8416     *
8417     * @static
8418     * @memberOf _
8419     * @since 4.0.0
8420     * @category Array
8421     * @param {...Array} [arrays] The arrays to inspect.
8422     * @param {Function} [comparator] The comparator invoked per element.
8423     * @returns {Array} Returns the new array of combined values.
8424     * @example
8425     *
8426     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8427     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8428     *
8429     * _.unionWith(objects, others, _.isEqual);
8430     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8431     */
8432    var unionWith = baseRest(function(arrays) {
8433      var comparator = last(arrays);
8434      comparator = typeof comparator == 'function' ? comparator : undefined;
8435      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8436    });
8437
8438    /**
8439     * Creates a duplicate-free version of an array, using
8440     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8441     * for equality comparisons, in which only the first occurrence of each element
8442     * is kept. The order of result values is determined by the order they occur
8443     * in the array.
8444     *
8445     * @static
8446     * @memberOf _
8447     * @since 0.1.0
8448     * @category Array
8449     * @param {Array} array The array to inspect.
8450     * @returns {Array} Returns the new duplicate free array.
8451     * @example
8452     *
8453     * _.uniq([2, 1, 2]);
8454     * // => [2, 1]
8455     */
8456    function uniq(array) {
8457      return (array && array.length) ? baseUniq(array) : [];
8458    }
8459
8460    /**
8461     * This method is like `_.uniq` except that it accepts `iteratee` which is
8462     * invoked for each element in `array` to generate the criterion by which
8463     * uniqueness is computed. The order of result values is determined by the
8464     * order they occur in the array. The iteratee is invoked with one argument:
8465     * (value).
8466     *
8467     * @static
8468     * @memberOf _
8469     * @since 4.0.0
8470     * @category Array
8471     * @param {Array} array The array to inspect.
8472     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8473     * @returns {Array} Returns the new duplicate free array.
8474     * @example
8475     *
8476     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8477     * // => [2.1, 1.2]
8478     *
8479     * // The `_.property` iteratee shorthand.
8480     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8481     * // => [{ 'x': 1 }, { 'x': 2 }]
8482     */
8483    function uniqBy(array, iteratee) {
8484      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8485    }
8486
8487    /**
8488     * This method is like `_.uniq` except that it accepts `comparator` which
8489     * is invoked to compare elements of `array`. The order of result values is
8490     * determined by the order they occur in the array.The comparator is invoked
8491     * with two arguments: (arrVal, othVal).
8492     *
8493     * @static
8494     * @memberOf _
8495     * @since 4.0.0
8496     * @category Array
8497     * @param {Array} array The array to inspect.
8498     * @param {Function} [comparator] The comparator invoked per element.
8499     * @returns {Array} Returns the new duplicate free array.
8500     * @example
8501     *
8502     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8503     *
8504     * _.uniqWith(objects, _.isEqual);
8505     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8506     */
8507    function uniqWith(array, comparator) {
8508      comparator = typeof comparator == 'function' ? comparator : undefined;
8509      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8510    }
8511
8512    /**
8513     * This method is like `_.zip` except that it accepts an array of grouped
8514     * elements and creates an array regrouping the elements to their pre-zip
8515     * configuration.
8516     *
8517     * @static
8518     * @memberOf _
8519     * @since 1.2.0
8520     * @category Array
8521     * @param {Array} array The array of grouped elements to process.
8522     * @returns {Array} Returns the new array of regrouped elements.
8523     * @example
8524     *
8525     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8526     * // => [['a', 1, true], ['b', 2, false]]
8527     *
8528     * _.unzip(zipped);
8529     * // => [['a', 'b'], [1, 2], [true, false]]
8530     */
8531    function unzip(array) {
8532      if (!(array && array.length)) {
8533        return [];
8534      }
8535      var length = 0;
8536      array = arrayFilter(array, function(group) {
8537        if (isArrayLikeObject(group)) {
8538          length = nativeMax(group.length, length);
8539          return true;
8540        }
8541      });
8542      return baseTimes(length, function(index) {
8543        return arrayMap(array, baseProperty(index));
8544      });
8545    }
8546
8547    /**
8548     * This method is like `_.unzip` except that it accepts `iteratee` to specify
8549     * how regrouped values should be combined. The iteratee is invoked with the
8550     * elements of each group: (...group).
8551     *
8552     * @static
8553     * @memberOf _
8554     * @since 3.8.0
8555     * @category Array
8556     * @param {Array} array The array of grouped elements to process.
8557     * @param {Function} [iteratee=_.identity] The function to combine
8558     *  regrouped values.
8559     * @returns {Array} Returns the new array of regrouped elements.
8560     * @example
8561     *
8562     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8563     * // => [[1, 10, 100], [2, 20, 200]]
8564     *
8565     * _.unzipWith(zipped, _.add);
8566     * // => [3, 30, 300]
8567     */
8568    function unzipWith(array, iteratee) {
8569      if (!(array && array.length)) {
8570        return [];
8571      }
8572      var result = unzip(array);
8573      if (iteratee == null) {
8574        return result;
8575      }
8576      return arrayMap(result, function(group) {
8577        return apply(iteratee, undefined, group);
8578      });
8579    }
8580
8581    /**
8582     * Creates an array excluding all given values using
8583     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8584     * for equality comparisons.
8585     *
8586     * **Note:** Unlike `_.pull`, this method returns a new array.
8587     *
8588     * @static
8589     * @memberOf _
8590     * @since 0.1.0
8591     * @category Array
8592     * @param {Array} array The array to inspect.
8593     * @param {...*} [values] The values to exclude.
8594     * @returns {Array} Returns the new array of filtered values.
8595     * @see _.difference, _.xor
8596     * @example
8597     *
8598     * _.without([2, 1, 2, 3], 1, 2);
8599     * // => [3]
8600     */
8601    var without = baseRest(function(array, values) {
8602      return isArrayLikeObject(array)
8603        ? baseDifference(array, values)
8604        : [];
8605    });
8606
8607    /**
8608     * Creates an array of unique values that is the
8609     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8610     * of the given arrays. The order of result values is determined by the order
8611     * they occur in the arrays.
8612     *
8613     * @static
8614     * @memberOf _
8615     * @since 2.4.0
8616     * @category Array
8617     * @param {...Array} [arrays] The arrays to inspect.
8618     * @returns {Array} Returns the new array of filtered values.
8619     * @see _.difference, _.without
8620     * @example
8621     *
8622     * _.xor([2, 1], [2, 3]);
8623     * // => [1, 3]
8624     */
8625    var xor = baseRest(function(arrays) {
8626      return baseXor(arrayFilter(arrays, isArrayLikeObject));
8627    });
8628
8629    /**
8630     * This method is like `_.xor` except that it accepts `iteratee` which is
8631     * invoked for each element of each `arrays` to generate the criterion by
8632     * which by which they're compared. The order of result values is determined
8633     * by the order they occur in the arrays. The iteratee is invoked with one
8634     * argument: (value).
8635     *
8636     * @static
8637     * @memberOf _
8638     * @since 4.0.0
8639     * @category Array
8640     * @param {...Array} [arrays] The arrays to inspect.
8641     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8642     * @returns {Array} Returns the new array of filtered values.
8643     * @example
8644     *
8645     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8646     * // => [1.2, 3.4]
8647     *
8648     * // The `_.property` iteratee shorthand.
8649     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8650     * // => [{ 'x': 2 }]
8651     */
8652    var xorBy = baseRest(function(arrays) {
8653      var iteratee = last(arrays);
8654      if (isArrayLikeObject(iteratee)) {
8655        iteratee = undefined;
8656      }
8657      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8658    });
8659
8660    /**
8661     * This method is like `_.xor` except that it accepts `comparator` which is
8662     * invoked to compare elements of `arrays`. The order of result values is
8663     * determined by the order they occur in the arrays. The comparator is invoked
8664     * with two arguments: (arrVal, othVal).
8665     *
8666     * @static
8667     * @memberOf _
8668     * @since 4.0.0
8669     * @category Array
8670     * @param {...Array} [arrays] The arrays to inspect.
8671     * @param {Function} [comparator] The comparator invoked per element.
8672     * @returns {Array} Returns the new array of filtered values.
8673     * @example
8674     *
8675     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8676     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8677     *
8678     * _.xorWith(objects, others, _.isEqual);
8679     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8680     */
8681    var xorWith = baseRest(function(arrays) {
8682      var comparator = last(arrays);
8683      comparator = typeof comparator == 'function' ? comparator : undefined;
8684      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8685    });
8686
8687    /**
8688     * Creates an array of grouped elements, the first of which contains the
8689     * first elements of the given arrays, the second of which contains the
8690     * second elements of the given arrays, and so on.
8691     *
8692     * @static
8693     * @memberOf _
8694     * @since 0.1.0
8695     * @category Array
8696     * @param {...Array} [arrays] The arrays to process.
8697     * @returns {Array} Returns the new array of grouped elements.
8698     * @example
8699     *
8700     * _.zip(['a', 'b'], [1, 2], [true, false]);
8701     * // => [['a', 1, true], ['b', 2, false]]
8702     */
8703    var zip = baseRest(unzip);
8704
8705    /**
8706     * This method is like `_.fromPairs` except that it accepts two arrays,
8707     * one of property identifiers and one of corresponding values.
8708     *
8709     * @static
8710     * @memberOf _
8711     * @since 0.4.0
8712     * @category Array
8713     * @param {Array} [props=[]] The property identifiers.
8714     * @param {Array} [values=[]] The property values.
8715     * @returns {Object} Returns the new object.
8716     * @example
8717     *
8718     * _.zipObject(['a', 'b'], [1, 2]);
8719     * // => { 'a': 1, 'b': 2 }
8720     */
8721    function zipObject(props, values) {
8722      return baseZipObject(props || [], values || [], assignValue);
8723    }
8724
8725    /**
8726     * This method is like `_.zipObject` except that it supports property paths.
8727     *
8728     * @static
8729     * @memberOf _
8730     * @since 4.1.0
8731     * @category Array
8732     * @param {Array} [props=[]] The property identifiers.
8733     * @param {Array} [values=[]] The property values.
8734     * @returns {Object} Returns the new object.
8735     * @example
8736     *
8737     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
8738     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
8739     */
8740    function zipObjectDeep(props, values) {
8741      return baseZipObject(props || [], values || [], baseSet);
8742    }
8743
8744    /**
8745     * This method is like `_.zip` except that it accepts `iteratee` to specify
8746     * how grouped values should be combined. The iteratee is invoked with the
8747     * elements of each group: (...group).
8748     *
8749     * @static
8750     * @memberOf _
8751     * @since 3.8.0
8752     * @category Array
8753     * @param {...Array} [arrays] The arrays to process.
8754     * @param {Function} [iteratee=_.identity] The function to combine
8755     *  grouped values.
8756     * @returns {Array} Returns the new array of grouped elements.
8757     * @example
8758     *
8759     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
8760     *   return a + b + c;
8761     * });
8762     * // => [111, 222]
8763     */
8764    var zipWith = baseRest(function(arrays) {
8765      var length = arrays.length,
8766          iteratee = length > 1 ? arrays[length - 1] : undefined;
8767
8768      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
8769      return unzipWith(arrays, iteratee);
8770    });
8771
8772    /*------------------------------------------------------------------------*/
8773
8774    /**
8775     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8776     * chain sequences enabled. The result of such sequences must be unwrapped
8777     * with `_#value`.
8778     *
8779     * @static
8780     * @memberOf _
8781     * @since 1.3.0
8782     * @category Seq
8783     * @param {*} value The value to wrap.
8784     * @returns {Object} Returns the new `lodash` wrapper instance.
8785     * @example
8786     *
8787     * var users = [
8788     *   { 'user': 'barney',  'age': 36 },
8789     *   { 'user': 'fred',    'age': 40 },
8790     *   { 'user': 'pebbles', 'age': 1 }
8791     * ];
8792     *
8793     * var youngest = _
8794     *   .chain(users)
8795     *   .sortBy('age')
8796     *   .map(function(o) {
8797     *     return o.user + ' is ' + o.age;
8798     *   })
8799     *   .head()
8800     *   .value();
8801     * // => 'pebbles is 1'
8802     */
8803    function chain(value) {
8804      var result = lodash(value);
8805      result.__chain__ = true;
8806      return result;
8807    }
8808
8809    /**
8810     * This method invokes `interceptor` and returns `value`. The interceptor
8811     * is invoked with one argument; (value). The purpose of this method is to
8812     * "tap into" a method chain sequence in order to modify intermediate results.
8813     *
8814     * @static
8815     * @memberOf _
8816     * @since 0.1.0
8817     * @category Seq
8818     * @param {*} value The value to provide to `interceptor`.
8819     * @param {Function} interceptor The function to invoke.
8820     * @returns {*} Returns `value`.
8821     * @example
8822     *
8823     * _([1, 2, 3])
8824     *  .tap(function(array) {
8825     *    // Mutate input array.
8826     *    array.pop();
8827     *  })
8828     *  .reverse()
8829     *  .value();
8830     * // => [2, 1]
8831     */
8832    function tap(value, interceptor) {
8833      interceptor(value);
8834      return value;
8835    }
8836
8837    /**
8838     * This method is like `_.tap` except that it returns the result of `interceptor`.
8839     * The purpose of this method is to "pass thru" values replacing intermediate
8840     * results in a method chain sequence.
8841     *
8842     * @static
8843     * @memberOf _
8844     * @since 3.0.0
8845     * @category Seq
8846     * @param {*} value The value to provide to `interceptor`.
8847     * @param {Function} interceptor The function to invoke.
8848     * @returns {*} Returns the result of `interceptor`.
8849     * @example
8850     *
8851     * _('  abc  ')
8852     *  .chain()
8853     *  .trim()
8854     *  .thru(function(value) {
8855     *    return [value];
8856     *  })
8857     *  .value();
8858     * // => ['abc']
8859     */
8860    function thru(value, interceptor) {
8861      return interceptor(value);
8862    }
8863
8864    /**
8865     * This method is the wrapper version of `_.at`.
8866     *
8867     * @name at
8868     * @memberOf _
8869     * @since 1.0.0
8870     * @category Seq
8871     * @param {...(string|string[])} [paths] The property paths to pick.
8872     * @returns {Object} Returns the new `lodash` wrapper instance.
8873     * @example
8874     *
8875     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8876     *
8877     * _(object).at(['a[0].b.c', 'a[1]']).value();
8878     * // => [3, 4]
8879     */
8880    var wrapperAt = flatRest(function(paths) {
8881      var length = paths.length,
8882          start = length ? paths[0] : 0,
8883          value = this.__wrapped__,
8884          interceptor = function(object) { return baseAt(object, paths); };
8885
8886      if (length > 1 || this.__actions__.length ||
8887          !(value instanceof LazyWrapper) || !isIndex(start)) {
8888        return this.thru(interceptor);
8889      }
8890      value = value.slice(start, +start + (length ? 1 : 0));
8891      value.__actions__.push({
8892        'func': thru,
8893        'args': [interceptor],
8894        'thisArg': undefined
8895      });
8896      return new LodashWrapper(value, this.__chain__).thru(function(array) {
8897        if (length && !array.length) {
8898          array.push(undefined);
8899        }
8900        return array;
8901      });
8902    });
8903
8904    /**
8905     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8906     *
8907     * @name chain
8908     * @memberOf _
8909     * @since 0.1.0
8910     * @category Seq
8911     * @returns {Object} Returns the new `lodash` wrapper instance.
8912     * @example
8913     *
8914     * var users = [
8915     *   { 'user': 'barney', 'age': 36 },
8916     *   { 'user': 'fred',   'age': 40 }
8917     * ];
8918     *
8919     * // A sequence without explicit chaining.
8920     * _(users).head();
8921     * // => { 'user': 'barney', 'age': 36 }
8922     *
8923     * // A sequence with explicit chaining.
8924     * _(users)
8925     *   .chain()
8926     *   .head()
8927     *   .pick('user')
8928     *   .value();
8929     * // => { 'user': 'barney' }
8930     */
8931    function wrapperChain() {
8932      return chain(this);
8933    }
8934
8935    /**
8936     * Executes the chain sequence and returns the wrapped result.
8937     *
8938     * @name commit
8939     * @memberOf _
8940     * @since 3.2.0
8941     * @category Seq
8942     * @returns {Object} Returns the new `lodash` wrapper instance.
8943     * @example
8944     *
8945     * var array = [1, 2];
8946     * var wrapped = _(array).push(3);
8947     *
8948     * console.log(array);
8949     * // => [1, 2]
8950     *
8951     * wrapped = wrapped.commit();
8952     * console.log(array);
8953     * // => [1, 2, 3]
8954     *
8955     * wrapped.last();
8956     * // => 3
8957     *
8958     * console.log(array);
8959     * // => [1, 2, 3]
8960     */
8961    function wrapperCommit() {
8962      return new LodashWrapper(this.value(), this.__chain__);
8963    }
8964
8965    /**
8966     * Gets the next value on a wrapped object following the
8967     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8968     *
8969     * @name next
8970     * @memberOf _
8971     * @since 4.0.0
8972     * @category Seq
8973     * @returns {Object} Returns the next iterator value.
8974     * @example
8975     *
8976     * var wrapped = _([1, 2]);
8977     *
8978     * wrapped.next();
8979     * // => { 'done': false, 'value': 1 }
8980     *
8981     * wrapped.next();
8982     * // => { 'done': false, 'value': 2 }
8983     *
8984     * wrapped.next();
8985     * // => { 'done': true, 'value': undefined }
8986     */
8987    function wrapperNext() {
8988      if (this.__values__ === undefined) {
8989        this.__values__ = toArray(this.value());
8990      }
8991      var done = this.__index__ >= this.__values__.length,
8992          value = done ? undefined : this.__values__[this.__index__++];
8993
8994      return { 'done': done, 'value': value };
8995    }
8996
8997    /**
8998     * Enables the wrapper to be iterable.
8999     *
9000     * @name Symbol.iterator
9001     * @memberOf _
9002     * @since 4.0.0
9003     * @category Seq
9004     * @returns {Object} Returns the wrapper object.
9005     * @example
9006     *
9007     * var wrapped = _([1, 2]);
9008     *
9009     * wrapped[Symbol.iterator]() === wrapped;
9010     * // => true
9011     *
9012     * Array.from(wrapped);
9013     * // => [1, 2]
9014     */
9015    function wrapperToIterator() {
9016      return this;
9017    }
9018
9019    /**
9020     * Creates a clone of the chain sequence planting `value` as the wrapped value.
9021     *
9022     * @name plant
9023     * @memberOf _
9024     * @since 3.2.0
9025     * @category Seq
9026     * @param {*} value The value to plant.
9027     * @returns {Object} Returns the new `lodash` wrapper instance.
9028     * @example
9029     *
9030     * function square(n) {
9031     *   return n * n;
9032     * }
9033     *
9034     * var wrapped = _([1, 2]).map(square);
9035     * var other = wrapped.plant([3, 4]);
9036     *
9037     * other.value();
9038     * // => [9, 16]
9039     *
9040     * wrapped.value();
9041     * // => [1, 4]
9042     */
9043    function wrapperPlant(value) {
9044      var result,
9045          parent = this;
9046
9047      while (parent instanceof baseLodash) {
9048        var clone = wrapperClone(parent);
9049        clone.__index__ = 0;
9050        clone.__values__ = undefined;
9051        if (result) {
9052          previous.__wrapped__ = clone;
9053        } else {
9054          result = clone;
9055        }
9056        var previous = clone;
9057        parent = parent.__wrapped__;
9058      }
9059      previous.__wrapped__ = value;
9060      return result;
9061    }
9062
9063    /**
9064     * This method is the wrapper version of `_.reverse`.
9065     *
9066     * **Note:** This method mutates the wrapped array.
9067     *
9068     * @name reverse
9069     * @memberOf _
9070     * @since 0.1.0
9071     * @category Seq
9072     * @returns {Object} Returns the new `lodash` wrapper instance.
9073     * @example
9074     *
9075     * var array = [1, 2, 3];
9076     *
9077     * _(array).reverse().value()
9078     * // => [3, 2, 1]
9079     *
9080     * console.log(array);
9081     * // => [3, 2, 1]
9082     */
9083    function wrapperReverse() {
9084      var value = this.__wrapped__;
9085      if (value instanceof LazyWrapper) {
9086        var wrapped = value;
9087        if (this.__actions__.length) {
9088          wrapped = new LazyWrapper(this);
9089        }
9090        wrapped = wrapped.reverse();
9091        wrapped.__actions__.push({
9092          'func': thru,
9093          'args': [reverse],
9094          'thisArg': undefined
9095        });
9096        return new LodashWrapper(wrapped, this.__chain__);
9097      }
9098      return this.thru(reverse);
9099    }
9100
9101    /**
9102     * Executes the chain sequence to resolve the unwrapped value.
9103     *
9104     * @name value
9105     * @memberOf _
9106     * @since 0.1.0
9107     * @alias toJSON, valueOf
9108     * @category Seq
9109     * @returns {*} Returns the resolved unwrapped value.
9110     * @example
9111     *
9112     * _([1, 2, 3]).value();
9113     * // => [1, 2, 3]
9114     */
9115    function wrapperValue() {
9116      return baseWrapperValue(this.__wrapped__, this.__actions__);
9117    }
9118
9119    /*------------------------------------------------------------------------*/
9120
9121    /**
9122     * Creates an object composed of keys generated from the results of running
9123     * each element of `collection` thru `iteratee`. The corresponding value of
9124     * each key is the number of times the key was returned by `iteratee`. The
9125     * iteratee is invoked with one argument: (value).
9126     *
9127     * @static
9128     * @memberOf _
9129     * @since 0.5.0
9130     * @category Collection
9131     * @param {Array|Object} collection The collection to iterate over.
9132     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9133     * @returns {Object} Returns the composed aggregate object.
9134     * @example
9135     *
9136     * _.countBy([6.1, 4.2, 6.3], Math.floor);
9137     * // => { '4': 1, '6': 2 }
9138     *
9139     * // The `_.property` iteratee shorthand.
9140     * _.countBy(['one', 'two', 'three'], 'length');
9141     * // => { '3': 2, '5': 1 }
9142     */
9143    var countBy = createAggregator(function(result, value, key) {
9144      if (hasOwnProperty.call(result, key)) {
9145        ++result[key];
9146      } else {
9147        baseAssignValue(result, key, 1);
9148      }
9149    });
9150
9151    /**
9152     * Checks if `predicate` returns truthy for **all** elements of `collection`.
9153     * Iteration is stopped once `predicate` returns falsey. The predicate is
9154     * invoked with three arguments: (value, index|key, collection).
9155     *
9156     * **Note:** This method returns `true` for
9157     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
9158     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
9159     * elements of empty collections.
9160     *
9161     * @static
9162     * @memberOf _
9163     * @since 0.1.0
9164     * @category Collection
9165     * @param {Array|Object} collection The collection to iterate over.
9166     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9167     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9168     * @returns {boolean} Returns `true` if all elements pass the predicate check,
9169     *  else `false`.
9170     * @example
9171     *
9172     * _.every([true, 1, null, 'yes'], Boolean);
9173     * // => false
9174     *
9175     * var users = [
9176     *   { 'user': 'barney', 'age': 36, 'active': false },
9177     *   { 'user': 'fred',   'age': 40, 'active': false }
9178     * ];
9179     *
9180     * // The `_.matches` iteratee shorthand.
9181     * _.every(users, { 'user': 'barney', 'active': false });
9182     * // => false
9183     *
9184     * // The `_.matchesProperty` iteratee shorthand.
9185     * _.every(users, ['active', false]);
9186     * // => true
9187     *
9188     * // The `_.property` iteratee shorthand.
9189     * _.every(users, 'active');
9190     * // => false
9191     */
9192    function every(collection, predicate, guard) {
9193      var func = isArray(collection) ? arrayEvery : baseEvery;
9194      if (guard && isIterateeCall(collection, predicate, guard)) {
9195        predicate = undefined;
9196      }
9197      return func(collection, getIteratee(predicate, 3));
9198    }
9199
9200    /**
9201     * Iterates over elements of `collection`, returning an array of all elements
9202     * `predicate` returns truthy for. The predicate is invoked with three
9203     * arguments: (value, index|key, collection).
9204     *
9205     * **Note:** Unlike `_.remove`, this method returns a new array.
9206     *
9207     * @static
9208     * @memberOf _
9209     * @since 0.1.0
9210     * @category Collection
9211     * @param {Array|Object} collection The collection to iterate over.
9212     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9213     * @returns {Array} Returns the new filtered array.
9214     * @see _.reject
9215     * @example
9216     *
9217     * var users = [
9218     *   { 'user': 'barney', 'age': 36, 'active': true },
9219     *   { 'user': 'fred',   'age': 40, 'active': false }
9220     * ];
9221     *
9222     * _.filter(users, function(o) { return !o.active; });
9223     * // => objects for ['fred']
9224     *
9225     * // The `_.matches` iteratee shorthand.
9226     * _.filter(users, { 'age': 36, 'active': true });
9227     * // => objects for ['barney']
9228     *
9229     * // The `_.matchesProperty` iteratee shorthand.
9230     * _.filter(users, ['active', false]);
9231     * // => objects for ['fred']
9232     *
9233     * // The `_.property` iteratee shorthand.
9234     * _.filter(users, 'active');
9235     * // => objects for ['barney']
9236     *
9237     * // Combining several predicates using `_.overEvery` or `_.overSome`.
9238     * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
9239     * // => objects for ['fred', 'barney']
9240     */
9241    function filter(collection, predicate) {
9242      var func = isArray(collection) ? arrayFilter : baseFilter;
9243      return func(collection, getIteratee(predicate, 3));
9244    }
9245
9246    /**
9247     * Iterates over elements of `collection`, returning the first element
9248     * `predicate` returns truthy for. The predicate is invoked with three
9249     * arguments: (value, index|key, collection).
9250     *
9251     * @static
9252     * @memberOf _
9253     * @since 0.1.0
9254     * @category Collection
9255     * @param {Array|Object} collection The collection to inspect.
9256     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9257     * @param {number} [fromIndex=0] The index to search from.
9258     * @returns {*} Returns the matched element, else `undefined`.
9259     * @example
9260     *
9261     * var users = [
9262     *   { 'user': 'barney',  'age': 36, 'active': true },
9263     *   { 'user': 'fred',    'age': 40, 'active': false },
9264     *   { 'user': 'pebbles', 'age': 1,  'active': true }
9265     * ];
9266     *
9267     * _.find(users, function(o) { return o.age < 40; });
9268     * // => object for 'barney'
9269     *
9270     * // The `_.matches` iteratee shorthand.
9271     * _.find(users, { 'age': 1, 'active': true });
9272     * // => object for 'pebbles'
9273     *
9274     * // The `_.matchesProperty` iteratee shorthand.
9275     * _.find(users, ['active', false]);
9276     * // => object for 'fred'
9277     *
9278     * // The `_.property` iteratee shorthand.
9279     * _.find(users, 'active');
9280     * // => object for 'barney'
9281     */
9282    var find = createFind(findIndex);
9283
9284    /**
9285     * This method is like `_.find` except that it iterates over elements of
9286     * `collection` from right to left.
9287     *
9288     * @static
9289     * @memberOf _
9290     * @since 2.0.0
9291     * @category Collection
9292     * @param {Array|Object} collection The collection to inspect.
9293     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9294     * @param {number} [fromIndex=collection.length-1] The index to search from.
9295     * @returns {*} Returns the matched element, else `undefined`.
9296     * @example
9297     *
9298     * _.findLast([1, 2, 3, 4], function(n) {
9299     *   return n % 2 == 1;
9300     * });
9301     * // => 3
9302     */
9303    var findLast = createFind(findLastIndex);
9304
9305    /**
9306     * Creates a flattened array of values by running each element in `collection`
9307     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
9308     * with three arguments: (value, index|key, collection).
9309     *
9310     * @static
9311     * @memberOf _
9312     * @since 4.0.0
9313     * @category Collection
9314     * @param {Array|Object} collection The collection to iterate over.
9315     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9316     * @returns {Array} Returns the new flattened array.
9317     * @example
9318     *
9319     * function duplicate(n) {
9320     *   return [n, n];
9321     * }
9322     *
9323     * _.flatMap([1, 2], duplicate);
9324     * // => [1, 1, 2, 2]
9325     */
9326    function flatMap(collection, iteratee) {
9327      return baseFlatten(map(collection, iteratee), 1);
9328    }
9329
9330    /**
9331     * This method is like `_.flatMap` except that it recursively flattens the
9332     * mapped results.
9333     *
9334     * @static
9335     * @memberOf _
9336     * @since 4.7.0
9337     * @category Collection
9338     * @param {Array|Object} collection The collection to iterate over.
9339     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9340     * @returns {Array} Returns the new flattened array.
9341     * @example
9342     *
9343     * function duplicate(n) {
9344     *   return [[[n, n]]];
9345     * }
9346     *
9347     * _.flatMapDeep([1, 2], duplicate);
9348     * // => [1, 1, 2, 2]
9349     */
9350    function flatMapDeep(collection, iteratee) {
9351      return baseFlatten(map(collection, iteratee), INFINITY);
9352    }
9353
9354    /**
9355     * This method is like `_.flatMap` except that it recursively flattens the
9356     * mapped results up to `depth` times.
9357     *
9358     * @static
9359     * @memberOf _
9360     * @since 4.7.0
9361     * @category Collection
9362     * @param {Array|Object} collection The collection to iterate over.
9363     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9364     * @param {number} [depth=1] The maximum recursion depth.
9365     * @returns {Array} Returns the new flattened array.
9366     * @example
9367     *
9368     * function duplicate(n) {
9369     *   return [[[n, n]]];
9370     * }
9371     *
9372     * _.flatMapDepth([1, 2], duplicate, 2);
9373     * // => [[1, 1], [2, 2]]
9374     */
9375    function flatMapDepth(collection, iteratee, depth) {
9376      depth = depth === undefined ? 1 : toInteger(depth);
9377      return baseFlatten(map(collection, iteratee), depth);
9378    }
9379
9380    /**
9381     * Iterates over elements of `collection` and invokes `iteratee` for each element.
9382     * The iteratee is invoked with three arguments: (value, index|key, collection).
9383     * Iteratee functions may exit iteration early by explicitly returning `false`.
9384     *
9385     * **Note:** As with other "Collections" methods, objects with a "length"
9386     * property are iterated like arrays. To avoid this behavior use `_.forIn`
9387     * or `_.forOwn` for object iteration.
9388     *
9389     * @static
9390     * @memberOf _
9391     * @since 0.1.0
9392     * @alias each
9393     * @category Collection
9394     * @param {Array|Object} collection The collection to iterate over.
9395     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9396     * @returns {Array|Object} Returns `collection`.
9397     * @see _.forEachRight
9398     * @example
9399     *
9400     * _.forEach([1, 2], function(value) {
9401     *   console.log(value);
9402     * });
9403     * // => Logs `1` then `2`.
9404     *
9405     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
9406     *   console.log(key);
9407     * });
9408     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
9409     */
9410    function forEach(collection, iteratee) {
9411      var func = isArray(collection) ? arrayEach : baseEach;
9412      return func(collection, getIteratee(iteratee, 3));
9413    }
9414
9415    /**
9416     * This method is like `_.forEach` except that it iterates over elements of
9417     * `collection` from right to left.
9418     *
9419     * @static
9420     * @memberOf _
9421     * @since 2.0.0
9422     * @alias eachRight
9423     * @category Collection
9424     * @param {Array|Object} collection The collection to iterate over.
9425     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9426     * @returns {Array|Object} Returns `collection`.
9427     * @see _.forEach
9428     * @example
9429     *
9430     * _.forEachRight([1, 2], function(value) {
9431     *   console.log(value);
9432     * });
9433     * // => Logs `2` then `1`.
9434     */
9435    function forEachRight(collection, iteratee) {
9436      var func = isArray(collection) ? arrayEachRight : baseEachRight;
9437      return func(collection, getIteratee(iteratee, 3));
9438    }
9439
9440    /**
vendor: 4,136 bytes, lines 9441-9548
9441     * Creates an object composed of keys generated from the results of running
9442     * each element of `collection` thru `iteratee`. The order of grouped values
9443     * is determined by the order they occur in `collection`. The corresponding
9444     * value of each key is an array of elements responsible for generating the
9445     * key. The iteratee is invoked with one argument: (value).
9446     *
9447     * @static
9448     * @memberOf _
9449     * @since 0.1.0
9450     * @category Collection
9451     * @param {Array|Object} collection The collection to iterate over.
9452     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9453     * @returns {Object} Returns the composed aggregate object.
9454     * @example
9455     *
9456     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
9457     * // => { '4': [4.2], '6': [6.1, 6.3] }
9458     *
9459     * // The `_.property` iteratee shorthand.
9460     * _.groupBy(['one', 'two', 'three'], 'length');
9461     * // => { '3': ['one', 'two'], '5': ['three'] }
9462     */
9463    var groupBy = createAggregator(function(result, value, key) {
9464      if (hasOwnProperty.call(result, key)) {
9465        result[key].push(value);
9466      } else {
9467        baseAssignValue(result, key, [value]);
9468      }
9469    });
9470
9471    /**
9472     * Checks if `value` is in `collection`. If `collection` is a string, it's
9473     * checked for a substring of `value`, otherwise
9474     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9475     * is used for equality comparisons. If `fromIndex` is negative, it's used as
9476     * the offset from the end of `collection`.
9477     *
9478     * @static
9479     * @memberOf _
9480     * @since 0.1.0
9481     * @category Collection
9482     * @param {Array|Object|string} collection The collection to inspect.
9483     * @param {*} value The value to search for.
9484     * @param {number} [fromIndex=0] The index to search from.
9485     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9486     * @returns {boolean} Returns `true` if `value` is found, else `false`.
9487     * @example
9488     *
9489     * _.includes([1, 2, 3], 1);
9490     * // => true
9491     *
9492     * _.includes([1, 2, 3], 1, 2);
9493     * // => false
9494     *
9495     * _.includes({ 'a': 1, 'b': 2 }, 1);
9496     * // => true
9497     *
9498     * _.includes('abcd', 'bc');
9499     * // => true
9500     */
9501    function includes(collection, value, fromIndex, guard) {
9502      collection = isArrayLike(collection) ? collection : values(collection);
9503      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
9504
9505      var length = collection.length;
9506      if (fromIndex < 0) {
9507        fromIndex = nativeMax(length + fromIndex, 0);
9508      }
9509      return isString(collection)
9510        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
9511        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
9512    }
9513
9514    /**
9515     * Invokes the method at `path` of each element in `collection`, returning
9516     * an array of the results of each invoked method. Any additional arguments
9517     * are provided to each invoked method. If `path` is a function, it's invoked
9518     * for, and `this` bound to, each element in `collection`.
9519     *
9520     * @static
9521     * @memberOf _
9522     * @since 4.0.0
9523     * @category Collection
9524     * @param {Array|Object} collection The collection to iterate over.
9525     * @param {Array|Function|string} path The path of the method to invoke or
9526     *  the function invoked per iteration.
9527     * @param {...*} [args] The arguments to invoke each method with.
9528     * @returns {Array} Returns the array of results.
9529     * @example
9530     *
9531     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
9532     * // => [[1, 5, 7], [1, 2, 3]]
9533     *
9534     * _.invokeMap([123, 456], String.prototype.split, '');
9535     * // => [['1', '2', '3'], ['4', '5', '6']]
9536     */
9537    var invokeMap = baseRest(function(collection, path, args) {
9538      var index = -1,
9539          isFunc = typeof path == 'function',
9540          result = isArrayLike(collection) ? Array(collection.length) : [];
9541
9542      baseEach(collection, function(value) {
9543        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
9544      });
9545      return result;
9546    });
9547
9548    /**
vendor: 68,500 bytes, lines 9549-11663
9549     * Creates an object composed of keys generated from the results of running
9550     * each element of `collection` thru `iteratee`. The corresponding value of
9551     * each key is the last element responsible for generating the key. The
9552     * iteratee is invoked with one argument: (value).
9553     *
9554     * @static
9555     * @memberOf _
9556     * @since 4.0.0
9557     * @category Collection
9558     * @param {Array|Object} collection The collection to iterate over.
9559     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9560     * @returns {Object} Returns the composed aggregate object.
9561     * @example
9562     *
9563     * var array = [
9564     *   { 'dir': 'left', 'code': 97 },
9565     *   { 'dir': 'right', 'code': 100 }
9566     * ];
9567     *
9568     * _.keyBy(array, function(o) {
9569     *   return String.fromCharCode(o.code);
9570     * });
9571     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
9572     *
9573     * _.keyBy(array, 'dir');
9574     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
9575     */
9576    var keyBy = createAggregator(function(result, value, key) {
9577      baseAssignValue(result, key, value);
9578    });
9579
9580    /**
9581     * Creates an array of values by running each element in `collection` thru
9582     * `iteratee`. The iteratee is invoked with three arguments:
9583     * (value, index|key, collection).
9584     *
9585     * Many lodash methods are guarded to work as iteratees for methods like
9586     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
9587     *
9588     * The guarded methods are:
9589     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
9590     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
9591     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
9592     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
9593     *
9594     * @static
9595     * @memberOf _
9596     * @since 0.1.0
9597     * @category Collection
9598     * @param {Array|Object} collection The collection to iterate over.
9599     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9600     * @returns {Array} Returns the new mapped array.
9601     * @example
9602     *
9603     * function square(n) {
9604     *   return n * n;
9605     * }
9606     *
9607     * _.map([4, 8], square);
9608     * // => [16, 64]
9609     *
9610     * _.map({ 'a': 4, 'b': 8 }, square);
9611     * // => [16, 64] (iteration order is not guaranteed)
9612     *
9613     * var users = [
9614     *   { 'user': 'barney' },
9615     *   { 'user': 'fred' }
9616     * ];
9617     *
9618     * // The `_.property` iteratee shorthand.
9619     * _.map(users, 'user');
9620     * // => ['barney', 'fred']
9621     */
9622    function map(collection, iteratee) {
9623      var func = isArray(collection) ? arrayMap : baseMap;
9624      return func(collection, getIteratee(iteratee, 3));
9625    }
9626
9627    /**
9628     * This method is like `_.sortBy` except that it allows specifying the sort
9629     * orders of the iteratees to sort by. If `orders` is unspecified, all values
9630     * are sorted in ascending order. Otherwise, specify an order of "desc" for
9631     * descending or "asc" for ascending sort order of corresponding values.
9632     *
9633     * @static
9634     * @memberOf _
9635     * @since 4.0.0
9636     * @category Collection
9637     * @param {Array|Object} collection The collection to iterate over.
9638     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
9639     *  The iteratees to sort by.
9640     * @param {string[]} [orders] The sort orders of `iteratees`.
9641     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9642     * @returns {Array} Returns the new sorted array.
9643     * @example
9644     *
9645     * var users = [
9646     *   { 'user': 'fred',   'age': 48 },
9647     *   { 'user': 'barney', 'age': 34 },
9648     *   { 'user': 'fred',   'age': 40 },
9649     *   { 'user': 'barney', 'age': 36 }
9650     * ];
9651     *
9652     * // Sort by `user` in ascending order and by `age` in descending order.
9653     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
9654     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9655     */
9656    function orderBy(collection, iteratees, orders, guard) {
9657      if (collection == null) {
9658        return [];
9659      }
9660      if (!isArray(iteratees)) {
9661        iteratees = iteratees == null ? [] : [iteratees];
9662      }
9663      orders = guard ? undefined : orders;
9664      if (!isArray(orders)) {
9665        orders = orders == null ? [] : [orders];
9666      }
9667      return baseOrderBy(collection, iteratees, orders);
9668    }
9669
9670    /**
9671     * Creates an array of elements split into two groups, the first of which
9672     * contains elements `predicate` returns truthy for, the second of which
9673     * contains elements `predicate` returns falsey for. The predicate is
9674     * invoked with one argument: (value).
9675     *
9676     * @static
9677     * @memberOf _
9678     * @since 3.0.0
9679     * @category Collection
9680     * @param {Array|Object} collection The collection to iterate over.
9681     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9682     * @returns {Array} Returns the array of grouped elements.
9683     * @example
9684     *
9685     * var users = [
9686     *   { 'user': 'barney',  'age': 36, 'active': false },
9687     *   { 'user': 'fred',    'age': 40, 'active': true },
9688     *   { 'user': 'pebbles', 'age': 1,  'active': false }
9689     * ];
9690     *
9691     * _.partition(users, function(o) { return o.active; });
9692     * // => objects for [['fred'], ['barney', 'pebbles']]
9693     *
9694     * // The `_.matches` iteratee shorthand.
9695     * _.partition(users, { 'age': 1, 'active': false });
9696     * // => objects for [['pebbles'], ['barney', 'fred']]
9697     *
9698     * // The `_.matchesProperty` iteratee shorthand.
9699     * _.partition(users, ['active', false]);
9700     * // => objects for [['barney', 'pebbles'], ['fred']]
9701     *
9702     * // The `_.property` iteratee shorthand.
9703     * _.partition(users, 'active');
9704     * // => objects for [['fred'], ['barney', 'pebbles']]
9705     */
9706    var partition = createAggregator(function(result, value, key) {
9707      result[key ? 0 : 1].push(value);
9708    }, function() { return [[], []]; });
9709
9710    /**
9711     * Reduces `collection` to a value which is the accumulated result of running
9712     * each element in `collection` thru `iteratee`, where each successive
9713     * invocation is supplied the return value of the previous. If `accumulator`
9714     * is not given, the first element of `collection` is used as the initial
9715     * value. The iteratee is invoked with four arguments:
9716     * (accumulator, value, index|key, collection).
9717     *
9718     * Many lodash methods are guarded to work as iteratees for methods like
9719     * `_.reduce`, `_.reduceRight`, and `_.transform`.
9720     *
9721     * The guarded methods are:
9722     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
9723     * and `sortBy`
9724     *
9725     * @static
9726     * @memberOf _
9727     * @since 0.1.0
9728     * @category Collection
9729     * @param {Array|Object} collection The collection to iterate over.
9730     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9731     * @param {*} [accumulator] The initial value.
9732     * @returns {*} Returns the accumulated value.
9733     * @see _.reduceRight
9734     * @example
9735     *
9736     * _.reduce([1, 2], function(sum, n) {
9737     *   return sum + n;
9738     * }, 0);
9739     * // => 3
9740     *
9741     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
9742     *   (result[value] || (result[value] = [])).push(key);
9743     *   return result;
9744     * }, {});
9745     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
9746     */
9747    function reduce(collection, iteratee, accumulator) {
9748      var func = isArray(collection) ? arrayReduce : baseReduce,
9749          initAccum = arguments.length < 3;
9750
9751      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
9752    }
9753
9754    /**
9755     * This method is like `_.reduce` except that it iterates over elements of
9756     * `collection` from right to left.
9757     *
9758     * @static
9759     * @memberOf _
9760     * @since 0.1.0
9761     * @category Collection
9762     * @param {Array|Object} collection The collection to iterate over.
9763     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9764     * @param {*} [accumulator] The initial value.
9765     * @returns {*} Returns the accumulated value.
9766     * @see _.reduce
9767     * @example
9768     *
9769     * var array = [[0, 1], [2, 3], [4, 5]];
9770     *
9771     * _.reduceRight(array, function(flattened, other) {
9772     *   return flattened.concat(other);
9773     * }, []);
9774     * // => [4, 5, 2, 3, 0, 1]
9775     */
9776    function reduceRight(collection, iteratee, accumulator) {
9777      var func = isArray(collection) ? arrayReduceRight : baseReduce,
9778          initAccum = arguments.length < 3;
9779
9780      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9781    }
9782
9783    /**
9784     * The opposite of `_.filter`; this method returns the elements of `collection`
9785     * that `predicate` does **not** return truthy for.
9786     *
9787     * @static
9788     * @memberOf _
9789     * @since 0.1.0
9790     * @category Collection
9791     * @param {Array|Object} collection The collection to iterate over.
9792     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9793     * @returns {Array} Returns the new filtered array.
9794     * @see _.filter
9795     * @example
9796     *
9797     * var users = [
9798     *   { 'user': 'barney', 'age': 36, 'active': false },
9799     *   { 'user': 'fred',   'age': 40, 'active': true }
9800     * ];
9801     *
9802     * _.reject(users, function(o) { return !o.active; });
9803     * // => objects for ['fred']
9804     *
9805     * // The `_.matches` iteratee shorthand.
9806     * _.reject(users, { 'age': 40, 'active': true });
9807     * // => objects for ['barney']
9808     *
9809     * // The `_.matchesProperty` iteratee shorthand.
9810     * _.reject(users, ['active', false]);
9811     * // => objects for ['fred']
9812     *
9813     * // The `_.property` iteratee shorthand.
9814     * _.reject(users, 'active');
9815     * // => objects for ['barney']
9816     */
9817    function reject(collection, predicate) {
9818      var func = isArray(collection) ? arrayFilter : baseFilter;
9819      return func(collection, negate(getIteratee(predicate, 3)));
9820    }
9821
9822    /**
9823     * Gets a random element from `collection`.
9824     *
9825     * @static
9826     * @memberOf _
9827     * @since 2.0.0
9828     * @category Collection
9829     * @param {Array|Object} collection The collection to sample.
9830     * @returns {*} Returns the random element.
9831     * @example
9832     *
9833     * _.sample([1, 2, 3, 4]);
9834     * // => 2
9835     */
9836    function sample(collection) {
9837      var func = isArray(collection) ? arraySample : baseSample;
9838      return func(collection);
9839    }
9840
9841    /**
9842     * Gets `n` random elements at unique keys from `collection` up to the
9843     * size of `collection`.
9844     *
9845     * @static
9846     * @memberOf _
9847     * @since 4.0.0
9848     * @category Collection
9849     * @param {Array|Object} collection The collection to sample.
9850     * @param {number} [n=1] The number of elements to sample.
9851     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9852     * @returns {Array} Returns the random elements.
9853     * @example
9854     *
9855     * _.sampleSize([1, 2, 3], 2);
9856     * // => [3, 1]
9857     *
9858     * _.sampleSize([1, 2, 3], 4);
9859     * // => [2, 3, 1]
9860     */
9861    function sampleSize(collection, n, guard) {
9862      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9863        n = 1;
9864      } else {
9865        n = toInteger(n);
9866      }
9867      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
9868      return func(collection, n);
9869    }
9870
9871    /**
9872     * Creates an array of shuffled values, using a version of the
9873     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9874     *
9875     * @static
9876     * @memberOf _
9877     * @since 0.1.0
9878     * @category Collection
9879     * @param {Array|Object} collection The collection to shuffle.
9880     * @returns {Array} Returns the new shuffled array.
9881     * @example
9882     *
9883     * _.shuffle([1, 2, 3, 4]);
9884     * // => [4, 1, 3, 2]
9885     */
9886    function shuffle(collection) {
9887      var func = isArray(collection) ? arrayShuffle : baseShuffle;
9888      return func(collection);
9889    }
9890
9891    /**
9892     * Gets the size of `collection` by returning its length for array-like
9893     * values or the number of own enumerable string keyed properties for objects.
9894     *
9895     * @static
9896     * @memberOf _
9897     * @since 0.1.0
9898     * @category Collection
9899     * @param {Array|Object|string} collection The collection to inspect.
9900     * @returns {number} Returns the collection size.
9901     * @example
9902     *
9903     * _.size([1, 2, 3]);
9904     * // => 3
9905     *
9906     * _.size({ 'a': 1, 'b': 2 });
9907     * // => 2
9908     *
9909     * _.size('pebbles');
9910     * // => 7
9911     */
9912    function size(collection) {
9913      if (collection == null) {
9914        return 0;
9915      }
9916      if (isArrayLike(collection)) {
9917        return isString(collection) ? stringSize(collection) : collection.length;
9918      }
9919      var tag = getTag(collection);
9920      if (tag == mapTag || tag == setTag) {
9921        return collection.size;
9922      }
9923      return baseKeys(collection).length;
9924    }
9925
9926    /**
9927     * Checks if `predicate` returns truthy for **any** element of `collection`.
9928     * Iteration is stopped once `predicate` returns truthy. The predicate is
9929     * invoked with three arguments: (value, index|key, collection).
9930     *
9931     * @static
9932     * @memberOf _
9933     * @since 0.1.0
9934     * @category Collection
9935     * @param {Array|Object} collection The collection to iterate over.
9936     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9937     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9938     * @returns {boolean} Returns `true` if any element passes the predicate check,
9939     *  else `false`.
9940     * @example
9941     *
9942     * _.some([null, 0, 'yes', false], Boolean);
9943     * // => true
9944     *
9945     * var users = [
9946     *   { 'user': 'barney', 'active': true },
9947     *   { 'user': 'fred',   'active': false }
9948     * ];
9949     *
9950     * // The `_.matches` iteratee shorthand.
9951     * _.some(users, { 'user': 'barney', 'active': false });
9952     * // => false
9953     *
9954     * // The `_.matchesProperty` iteratee shorthand.
9955     * _.some(users, ['active', false]);
9956     * // => true
9957     *
9958     * // The `_.property` iteratee shorthand.
9959     * _.some(users, 'active');
9960     * // => true
9961     */
9962    function some(collection, predicate, guard) {
9963      var func = isArray(collection) ? arraySome : baseSome;
9964      if (guard && isIterateeCall(collection, predicate, guard)) {
9965        predicate = undefined;
9966      }
9967      return func(collection, getIteratee(predicate, 3));
9968    }
9969
9970    /**
9971     * Creates an array of elements, sorted in ascending order by the results of
9972     * running each element in a collection thru each iteratee. This method
9973     * performs a stable sort, that is, it preserves the original sort order of
9974     * equal elements. The iteratees are invoked with one argument: (value).
9975     *
9976     * @static
9977     * @memberOf _
9978     * @since 0.1.0
9979     * @category Collection
9980     * @param {Array|Object} collection The collection to iterate over.
9981     * @param {...(Function|Function[])} [iteratees=[_.identity]]
9982     *  The iteratees to sort by.
9983     * @returns {Array} Returns the new sorted array.
9984     * @example
9985     *
9986     * var users = [
9987     *   { 'user': 'fred',   'age': 48 },
9988     *   { 'user': 'barney', 'age': 36 },
9989     *   { 'user': 'fred',   'age': 30 },
9990     *   { 'user': 'barney', 'age': 34 }
9991     * ];
9992     *
9993     * _.sortBy(users, [function(o) { return o.user; }]);
9994     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
9995     *
9996     * _.sortBy(users, ['user', 'age']);
9997     * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
9998     */
9999    var sortBy = baseRest(function(collection, iteratees) {
10000      if (collection == null) {
10001        return [];
10002      }
10003      var length = iteratees.length;
10004      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
10005        iteratees = [];
10006      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
10007        iteratees = [iteratees[0]];
10008      }
10009      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
10010    });
10011
10012    /*------------------------------------------------------------------------*/
10013
10014    /**
10015     * Gets the timestamp of the number of milliseconds that have elapsed since
10016     * the Unix epoch (1 January 1970 00:00:00 UTC).
10017     *
10018     * @static
10019     * @memberOf _
10020     * @since 2.4.0
10021     * @category Date
10022     * @returns {number} Returns the timestamp.
10023     * @example
10024     *
10025     * _.defer(function(stamp) {
10026     *   console.log(_.now() - stamp);
10027     * }, _.now());
10028     * // => Logs the number of milliseconds it took for the deferred invocation.
10029     */
10030    var now = ctxNow || function() {
10031      return root.Date.now();
10032    };
10033
10034    /*------------------------------------------------------------------------*/
10035
10036    /**
10037     * The opposite of `_.before`; this method creates a function that invokes
10038     * `func` once it's called `n` or more times.
10039     *
10040     * @static
10041     * @memberOf _
10042     * @since 0.1.0
10043     * @category Function
10044     * @param {number} n The number of calls before `func` is invoked.
10045     * @param {Function} func The function to restrict.
10046     * @returns {Function} Returns the new restricted function.
10047     * @example
10048     *
10049     * var saves = ['profile', 'settings'];
10050     *
10051     * var done = _.after(saves.length, function() {
10052     *   console.log('done saving!');
10053     * });
10054     *
10055     * _.forEach(saves, function(type) {
10056     *   asyncSave({ 'type': type, 'complete': done });
10057     * });
10058     * // => Logs 'done saving!' after the two async saves have completed.
10059     */
10060    function after(n, func) {
10061      if (typeof func != 'function') {
10062        throw new TypeError(FUNC_ERROR_TEXT);
10063      }
10064      n = toInteger(n);
10065      return function() {
10066        if (--n < 1) {
10067          return func.apply(this, arguments);
10068        }
10069      };
10070    }
10071
10072    /**
10073     * Creates a function that invokes `func`, with up to `n` arguments,
10074     * ignoring any additional arguments.
10075     *
10076     * @static
10077     * @memberOf _
10078     * @since 3.0.0
10079     * @category Function
10080     * @param {Function} func The function to cap arguments for.
10081     * @param {number} [n=func.length] The arity cap.
10082     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10083     * @returns {Function} Returns the new capped function.
10084     * @example
10085     *
10086     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
10087     * // => [6, 8, 10]
10088     */
10089    function ary(func, n, guard) {
10090      n = guard ? undefined : n;
10091      n = (func && n == null) ? func.length : n;
10092      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
10093    }
10094
10095    /**
10096     * Creates a function that invokes `func`, with the `this` binding and arguments
10097     * of the created function, while it's called less than `n` times. Subsequent
10098     * calls to the created function return the result of the last `func` invocation.
10099     *
10100     * @static
10101     * @memberOf _
10102     * @since 3.0.0
10103     * @category Function
10104     * @param {number} n The number of calls at which `func` is no longer invoked.
10105     * @param {Function} func The function to restrict.
10106     * @returns {Function} Returns the new restricted function.
10107     * @example
10108     *
10109     * jQuery(element).on('click', _.before(5, addContactToList));
10110     * // => Allows adding up to 4 contacts to the list.
10111     */
10112    function before(n, func) {
10113      var result;
10114      if (typeof func != 'function') {
10115        throw new TypeError(FUNC_ERROR_TEXT);
10116      }
10117      n = toInteger(n);
10118      return function() {
10119        if (--n > 0) {
10120          result = func.apply(this, arguments);
10121        }
10122        if (n <= 1) {
10123          func = undefined;
10124        }
10125        return result;
10126      };
10127    }
10128
10129    /**
10130     * Creates a function that invokes `func` with the `this` binding of `thisArg`
10131     * and `partials` prepended to the arguments it receives.
10132     *
10133     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
10134     * may be used as a placeholder for partially applied arguments.
10135     *
10136     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
10137     * property of bound functions.
10138     *
10139     * @static
10140     * @memberOf _
10141     * @since 0.1.0
10142     * @category Function
10143     * @param {Function} func The function to bind.
10144     * @param {*} thisArg The `this` binding of `func`.
10145     * @param {...*} [partials] The arguments to be partially applied.
10146     * @returns {Function} Returns the new bound function.
10147     * @example
10148     *
10149     * function greet(greeting, punctuation) {
10150     *   return greeting + ' ' + this.user + punctuation;
10151     * }
10152     *
10153     * var object = { 'user': 'fred' };
10154     *
10155     * var bound = _.bind(greet, object, 'hi');
10156     * bound('!');
10157     * // => 'hi fred!'
10158     *
10159     * // Bound with placeholders.
10160     * var bound = _.bind(greet, object, _, '!');
10161     * bound('hi');
10162     * // => 'hi fred!'
10163     */
10164    var bind = baseRest(function(func, thisArg, partials) {
10165      var bitmask = WRAP_BIND_FLAG;
10166      if (partials.length) {
10167        var holders = replaceHolders(partials, getHolder(bind));
10168        bitmask |= WRAP_PARTIAL_FLAG;
10169      }
10170      return createWrap(func, bitmask, thisArg, partials, holders);
10171    });
10172
10173    /**
10174     * Creates a function that invokes the method at `object[key]` with `partials`
10175     * prepended to the arguments it receives.
10176     *
10177     * This method differs from `_.bind` by allowing bound functions to reference
10178     * methods that may be redefined or don't yet exist. See
10179     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
10180     * for more details.
10181     *
10182     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
10183     * builds, may be used as a placeholder for partially applied arguments.
10184     *
10185     * @static
10186     * @memberOf _
10187     * @since 0.10.0
10188     * @category Function
10189     * @param {Object} object The object to invoke the method on.
10190     * @param {string} key The key of the method.
10191     * @param {...*} [partials] The arguments to be partially applied.
10192     * @returns {Function} Returns the new bound function.
10193     * @example
10194     *
10195     * var object = {
10196     *   'user': 'fred',
10197     *   'greet': function(greeting, punctuation) {
10198     *     return greeting + ' ' + this.user + punctuation;
10199     *   }
10200     * };
10201     *
10202     * var bound = _.bindKey(object, 'greet', 'hi');
10203     * bound('!');
10204     * // => 'hi fred!'
10205     *
10206     * object.greet = function(greeting, punctuation) {
10207     *   return greeting + 'ya ' + this.user + punctuation;
10208     * };
10209     *
10210     * bound('!');
10211     * // => 'hiya fred!'
10212     *
10213     * // Bound with placeholders.
10214     * var bound = _.bindKey(object, 'greet', _, '!');
10215     * bound('hi');
10216     * // => 'hiya fred!'
10217     */
10218    var bindKey = baseRest(function(object, key, partials) {
10219      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10220      if (partials.length) {
10221        var holders = replaceHolders(partials, getHolder(bindKey));
10222        bitmask |= WRAP_PARTIAL_FLAG;
10223      }
10224      return createWrap(key, bitmask, object, partials, holders);
10225    });
10226
10227    /**
10228     * Creates a function that accepts arguments of `func` and either invokes
10229     * `func` returning its result, if at least `arity` number of arguments have
10230     * been provided, or returns a function that accepts the remaining `func`
10231     * arguments, and so on. The arity of `func` may be specified if `func.length`
10232     * is not sufficient.
10233     *
10234     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
10235     * may be used as a placeholder for provided arguments.
10236     *
10237     * **Note:** This method doesn't set the "length" property of curried functions.
10238     *
10239     * @static
10240     * @memberOf _
10241     * @since 2.0.0
10242     * @category Function
10243     * @param {Function} func The function to curry.
10244     * @param {number} [arity=func.length] The arity of `func`.
10245     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10246     * @returns {Function} Returns the new curried function.
10247     * @example
10248     *
10249     * var abc = function(a, b, c) {
10250     *   return [a, b, c];
10251     * };
10252     *
10253     * var curried = _.curry(abc);
10254     *
10255     * curried(1)(2)(3);
10256     * // => [1, 2, 3]
10257     *
10258     * curried(1, 2)(3);
10259     * // => [1, 2, 3]
10260     *
10261     * curried(1, 2, 3);
10262     * // => [1, 2, 3]
10263     *
10264     * // Curried with placeholders.
10265     * curried(1)(_, 3)(2);
10266     * // => [1, 2, 3]
10267     */
10268    function curry(func, arity, guard) {
10269      arity = guard ? undefined : arity;
10270      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10271      result.placeholder = curry.placeholder;
10272      return result;
10273    }
10274
10275    /**
10276     * This method is like `_.curry` except that arguments are applied to `func`
10277     * in the manner of `_.partialRight` instead of `_.partial`.
10278     *
10279     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
10280     * builds, may be used as a placeholder for provided arguments.
10281     *
10282     * **Note:** This method doesn't set the "length" property of curried functions.
10283     *
10284     * @static
10285     * @memberOf _
10286     * @since 3.0.0
10287     * @category Function
10288     * @param {Function} func The function to curry.
10289     * @param {number} [arity=func.length] The arity of `func`.
10290     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10291     * @returns {Function} Returns the new curried function.
10292     * @example
10293     *
10294     * var abc = function(a, b, c) {
10295     *   return [a, b, c];
10296     * };
10297     *
10298     * var curried = _.curryRight(abc);
10299     *
10300     * curried(3)(2)(1);
10301     * // => [1, 2, 3]
10302     *
10303     * curried(2, 3)(1);
10304     * // => [1, 2, 3]
10305     *
10306     * curried(1, 2, 3);
10307     * // => [1, 2, 3]
10308     *
10309     * // Curried with placeholders.
10310     * curried(3)(1, _)(2);
10311     * // => [1, 2, 3]
10312     */
10313    function curryRight(func, arity, guard) {
10314      arity = guard ? undefined : arity;
10315      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10316      result.placeholder = curryRight.placeholder;
10317      return result;
10318    }
10319
10320    /**
10321     * Creates a debounced function that delays invoking `func` until after `wait`
10322     * milliseconds have elapsed since the last time the debounced function was
10323     * invoked. The debounced function comes with a `cancel` method to cancel
10324     * delayed `func` invocations and a `flush` method to immediately invoke them.
10325     * Provide `options` to indicate whether `func` should be invoked on the
10326     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
10327     * with the last arguments provided to the debounced function. Subsequent
10328     * calls to the debounced function return the result of the last `func`
10329     * invocation.
10330     *
10331     * **Note:** If `leading` and `trailing` options are `true`, `func` is
10332     * invoked on the trailing edge of the timeout only if the debounced function
10333     * is invoked more than once during the `wait` timeout.
10334     *
10335     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10336     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10337     *
10338     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10339     * for details over the differences between `_.debounce` and `_.throttle`.
10340     *
10341     * @static
10342     * @memberOf _
10343     * @since 0.1.0
10344     * @category Function
10345     * @param {Function} func The function to debounce.
10346     * @param {number} [wait=0] The number of milliseconds to delay.
10347     * @param {Object} [options={}] The options object.
10348     * @param {boolean} [options.leading=false]
10349     *  Specify invoking on the leading edge of the timeout.
10350     * @param {number} [options.maxWait]
10351     *  The maximum time `func` is allowed to be delayed before it's invoked.
10352     * @param {boolean} [options.trailing=true]
10353     *  Specify invoking on the trailing edge of the timeout.
10354     * @returns {Function} Returns the new debounced function.
10355     * @example
10356     *
10357     * // Avoid costly calculations while the window size is in flux.
10358     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
10359     *
10360     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
10361     * jQuery(element).on('click', _.debounce(sendMail, 300, {
10362     *   'leading': true,
10363     *   'trailing': false
10364     * }));
10365     *
10366     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
10367     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
10368     * var source = new EventSource('/stream');
10369     * jQuery(source).on('message', debounced);
10370     *
10371     * // Cancel the trailing debounced invocation.
10372     * jQuery(window).on('popstate', debounced.cancel);
10373     */
10374    function debounce(func, wait, options) {
10375      var lastArgs,
10376          lastThis,
10377          maxWait,
10378          result,
10379          timerId,
10380          lastCallTime,
10381          lastInvokeTime = 0,
10382          leading = false,
10383          maxing = false,
10384          trailing = true;
10385
10386      if (typeof func != 'function') {
10387        throw new TypeError(FUNC_ERROR_TEXT);
10388      }
10389      wait = toNumber(wait) || 0;
10390      if (isObject(options)) {
10391        leading = !!options.leading;
10392        maxing = 'maxWait' in options;
10393        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
10394        trailing = 'trailing' in options ? !!options.trailing : trailing;
10395      }
10396
10397      function invokeFunc(time) {
10398        var args = lastArgs,
10399            thisArg = lastThis;
10400
10401        lastArgs = lastThis = undefined;
10402        lastInvokeTime = time;
10403        result = func.apply(thisArg, args);
10404        return result;
10405      }
10406
10407      function leadingEdge(time) {
10408        // Reset any `maxWait` timer.
10409        lastInvokeTime = time;
10410        // Start the timer for the trailing edge.
10411        timerId = setTimeout(timerExpired, wait);
10412        // Invoke the leading edge.
10413        return leading ? invokeFunc(time) : result;
10414      }
10415
10416      function remainingWait(time) {
10417        var timeSinceLastCall = time - lastCallTime,
10418            timeSinceLastInvoke = time - lastInvokeTime,
10419            timeWaiting = wait - timeSinceLastCall;
10420
10421        return maxing
10422          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
10423          : timeWaiting;
10424      }
10425
10426      function shouldInvoke(time) {
10427        var timeSinceLastCall = time - lastCallTime,
10428            timeSinceLastInvoke = time - lastInvokeTime;
10429
10430        // Either this is the first call, activity has stopped and we're at the
10431        // trailing edge, the system time has gone backwards and we're treating
10432        // it as the trailing edge, or we've hit the `maxWait` limit.
10433        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
10434          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
10435      }
10436
10437      function timerExpired() {
10438        var time = now();
10439        if (shouldInvoke(time)) {
10440          return trailingEdge(time);
10441        }
10442        // Restart the timer.
10443        timerId = setTimeout(timerExpired, remainingWait(time));
10444      }
10445
10446      function trailingEdge(time) {
10447        timerId = undefined;
10448
10449        // Only invoke if we have `lastArgs` which means `func` has been
10450        // debounced at least once.
10451        if (trailing && lastArgs) {
10452          return invokeFunc(time);
10453        }
10454        lastArgs = lastThis = undefined;
10455        return result;
10456      }
10457
10458      function cancel() {
10459        if (timerId !== undefined) {
10460          clearTimeout(timerId);
10461        }
10462        lastInvokeTime = 0;
10463        lastArgs = lastCallTime = lastThis = timerId = undefined;
10464      }
10465
10466      function flush() {
10467        return timerId === undefined ? result : trailingEdge(now());
10468      }
10469
10470      function debounced() {
10471        var time = now(),
10472            isInvoking = shouldInvoke(time);
10473
10474        lastArgs = arguments;
10475        lastThis = this;
10476        lastCallTime = time;
10477
10478        if (isInvoking) {
10479          if (timerId === undefined) {
10480            return leadingEdge(lastCallTime);
10481          }
10482          if (maxing) {
10483            // Handle invocations in a tight loop.
10484            clearTimeout(timerId);
10485            timerId = setTimeout(timerExpired, wait);
10486            return invokeFunc(lastCallTime);
10487          }
10488        }
10489        if (timerId === undefined) {
10490          timerId = setTimeout(timerExpired, wait);
10491        }
10492        return result;
10493      }
10494      debounced.cancel = cancel;
10495      debounced.flush = flush;
10496      return debounced;
10497    }
10498
10499    /**
10500     * Defers invoking the `func` until the current call stack has cleared. Any
10501     * additional arguments are provided to `func` when it's invoked.
10502     *
10503     * @static
10504     * @memberOf _
10505     * @since 0.1.0
10506     * @category Function
10507     * @param {Function} func The function to defer.
10508     * @param {...*} [args] The arguments to invoke `func` with.
10509     * @returns {number} Returns the timer id.
10510     * @example
10511     *
10512     * _.defer(function(text) {
10513     *   console.log(text);
10514     * }, 'deferred');
10515     * // => Logs 'deferred' after one millisecond.
10516     */
10517    var defer = baseRest(function(func, args) {
10518      return baseDelay(func, 1, args);
10519    });
10520
10521    /**
10522     * Invokes `func` after `wait` milliseconds. Any additional arguments are
10523     * provided to `func` when it's invoked.
10524     *
10525     * @static
10526     * @memberOf _
10527     * @since 0.1.0
10528     * @category Function
10529     * @param {Function} func The function to delay.
10530     * @param {number} wait The number of milliseconds to delay invocation.
10531     * @param {...*} [args] The arguments to invoke `func` with.
10532     * @returns {number} Returns the timer id.
10533     * @example
10534     *
10535     * _.delay(function(text) {
10536     *   console.log(text);
10537     * }, 1000, 'later');
10538     * // => Logs 'later' after one second.
10539     */
10540    var delay = baseRest(function(func, wait, args) {
10541      return baseDelay(func, toNumber(wait) || 0, args);
10542    });
10543
10544    /**
10545     * Creates a function that invokes `func` with arguments reversed.
10546     *
10547     * @static
10548     * @memberOf _
10549     * @since 4.0.0
10550     * @category Function
10551     * @param {Function} func The function to flip arguments for.
10552     * @returns {Function} Returns the new flipped function.
10553     * @example
10554     *
10555     * var flipped = _.flip(function() {
10556     *   return _.toArray(arguments);
10557     * });
10558     *
10559     * flipped('a', 'b', 'c', 'd');
10560     * // => ['d', 'c', 'b', 'a']
10561     */
10562    function flip(func) {
10563      return createWrap(func, WRAP_FLIP_FLAG);
10564    }
10565
10566    /**
10567     * Creates a function that memoizes the result of `func`. If `resolver` is
10568     * provided, it determines the cache key for storing the result based on the
10569     * arguments provided to the memoized function. By default, the first argument
10570     * provided to the memoized function is used as the map cache key. The `func`
10571     * is invoked with the `this` binding of the memoized function.
10572     *
10573     * **Note:** The cache is exposed as the `cache` property on the memoized
10574     * function. Its creation may be customized by replacing the `_.memoize.Cache`
10575     * constructor with one whose instances implement the
10576     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
10577     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
10578     *
10579     * @static
10580     * @memberOf _
10581     * @since 0.1.0
10582     * @category Function
10583     * @param {Function} func The function to have its output memoized.
10584     * @param {Function} [resolver] The function to resolve the cache key.
10585     * @returns {Function} Returns the new memoized function.
10586     * @example
10587     *
10588     * var object = { 'a': 1, 'b': 2 };
10589     * var other = { 'c': 3, 'd': 4 };
10590     *
10591     * var values = _.memoize(_.values);
10592     * values(object);
10593     * // => [1, 2]
10594     *
10595     * values(other);
10596     * // => [3, 4]
10597     *
10598     * object.a = 2;
10599     * values(object);
10600     * // => [1, 2]
10601     *
10602     * // Modify the result cache.
10603     * values.cache.set(object, ['a', 'b']);
10604     * values(object);
10605     * // => ['a', 'b']
10606     *
10607     * // Replace `_.memoize.Cache`.
10608     * _.memoize.Cache = WeakMap;
10609     */
10610    function memoize(func, resolver) {
10611      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
10612        throw new TypeError(FUNC_ERROR_TEXT);
10613      }
10614      var memoized = function() {
10615        var args = arguments,
10616            key = resolver ? resolver.apply(this, args) : args[0],
10617            cache = memoized.cache;
10618
10619        if (cache.has(key)) {
10620          return cache.get(key);
10621        }
10622        var result = func.apply(this, args);
10623        memoized.cache = cache.set(key, result) || cache;
10624        return result;
10625      };
10626      memoized.cache = new (memoize.Cache || MapCache);
10627      return memoized;
10628    }
10629
10630    // Expose `MapCache`.
10631    memoize.Cache = MapCache;
10632
10633    /**
10634     * Creates a function that negates the result of the predicate `func`. The
10635     * `func` predicate is invoked with the `this` binding and arguments of the
10636     * created function.
10637     *
10638     * @static
10639     * @memberOf _
10640     * @since 3.0.0
10641     * @category Function
10642     * @param {Function} predicate The predicate to negate.
10643     * @returns {Function} Returns the new negated function.
10644     * @example
10645     *
10646     * function isEven(n) {
10647     *   return n % 2 == 0;
10648     * }
10649     *
10650     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
10651     * // => [1, 3, 5]
10652     */
10653    function negate(predicate) {
10654      if (typeof predicate != 'function') {
10655        throw new TypeError(FUNC_ERROR_TEXT);
10656      }
10657      return function() {
10658        var args = arguments;
10659        switch (args.length) {
10660          case 0: return !predicate.call(this);
10661          case 1: return !predicate.call(this, args[0]);
10662          case 2: return !predicate.call(this, args[0], args[1]);
10663          case 3: return !predicate.call(this, args[0], args[1], args[2]);
10664        }
10665        return !predicate.apply(this, args);
10666      };
10667    }
10668
10669    /**
10670     * Creates a function that is restricted to invoking `func` once. Repeat calls
10671     * to the function return the value of the first invocation. The `func` is
10672     * invoked with the `this` binding and arguments of the created function.
10673     *
10674     * @static
10675     * @memberOf _
10676     * @since 0.1.0
10677     * @category Function
10678     * @param {Function} func The function to restrict.
10679     * @returns {Function} Returns the new restricted function.
10680     * @example
10681     *
10682     * var initialize = _.once(createApplication);
10683     * initialize();
10684     * initialize();
10685     * // => `createApplication` is invoked once
10686     */
10687    function once(func) {
10688      return before(2, func);
10689    }
10690
10691    /**
10692     * Creates a function that invokes `func` with its arguments transformed.
10693     *
10694     * @static
10695     * @since 4.0.0
10696     * @memberOf _
10697     * @category Function
10698     * @param {Function} func The function to wrap.
10699     * @param {...(Function|Function[])} [transforms=[_.identity]]
10700     *  The argument transforms.
10701     * @returns {Function} Returns the new function.
10702     * @example
10703     *
10704     * function doubled(n) {
10705     *   return n * 2;
10706     * }
10707     *
10708     * function square(n) {
10709     *   return n * n;
10710     * }
10711     *
10712     * var func = _.overArgs(function(x, y) {
10713     *   return [x, y];
10714     * }, [square, doubled]);
10715     *
10716     * func(9, 3);
10717     * // => [81, 6]
10718     *
10719     * func(10, 5);
10720     * // => [100, 10]
10721     */
10722    var overArgs = castRest(function(func, transforms) {
10723      transforms = (transforms.length == 1 && isArray(transforms[0]))
10724        ? arrayMap(transforms[0], baseUnary(getIteratee()))
10725        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10726
10727      var funcsLength = transforms.length;
10728      return baseRest(function(args) {
10729        var index = -1,
10730            length = nativeMin(args.length, funcsLength);
10731
10732        while (++index < length) {
10733          args[index] = transforms[index].call(this, args[index]);
10734        }
10735        return apply(func, this, args);
10736      });
10737    });
10738
10739    /**
10740     * Creates a function that invokes `func` with `partials` prepended to the
10741     * arguments it receives. This method is like `_.bind` except it does **not**
10742     * alter the `this` binding.
10743     *
10744     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
10745     * builds, may be used as a placeholder for partially applied arguments.
10746     *
10747     * **Note:** This method doesn't set the "length" property of partially
10748     * applied functions.
10749     *
10750     * @static
10751     * @memberOf _
10752     * @since 0.2.0
10753     * @category Function
10754     * @param {Function} func The function to partially apply arguments to.
10755     * @param {...*} [partials] The arguments to be partially applied.
10756     * @returns {Function} Returns the new partially applied function.
10757     * @example
10758     *
10759     * function greet(greeting, name) {
10760     *   return greeting + ' ' + name;
10761     * }
10762     *
10763     * var sayHelloTo = _.partial(greet, 'hello');
10764     * sayHelloTo('fred');
10765     * // => 'hello fred'
10766     *
10767     * // Partially applied with placeholders.
10768     * var greetFred = _.partial(greet, _, 'fred');
10769     * greetFred('hi');
10770     * // => 'hi fred'
10771     */
10772    var partial = baseRest(function(func, partials) {
10773      var holders = replaceHolders(partials, getHolder(partial));
10774      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
10775    });
10776
10777    /**
10778     * This method is like `_.partial` except that partially applied arguments
10779     * are appended to the arguments it receives.
10780     *
10781     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10782     * builds, may be used as a placeholder for partially applied arguments.
10783     *
10784     * **Note:** This method doesn't set the "length" property of partially
10785     * applied functions.
10786     *
10787     * @static
10788     * @memberOf _
10789     * @since 1.0.0
10790     * @category Function
10791     * @param {Function} func The function to partially apply arguments to.
10792     * @param {...*} [partials] The arguments to be partially applied.
10793     * @returns {Function} Returns the new partially applied function.
10794     * @example
10795     *
10796     * function greet(greeting, name) {
10797     *   return greeting + ' ' + name;
10798     * }
10799     *
10800     * var greetFred = _.partialRight(greet, 'fred');
10801     * greetFred('hi');
10802     * // => 'hi fred'
10803     *
10804     * // Partially applied with placeholders.
10805     * var sayHelloTo = _.partialRight(greet, 'hello', _);
10806     * sayHelloTo('fred');
10807     * // => 'hello fred'
10808     */
10809    var partialRight = baseRest(function(func, partials) {
10810      var holders = replaceHolders(partials, getHolder(partialRight));
10811      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10812    });
10813
10814    /**
10815     * Creates a function that invokes `func` with arguments arranged according
10816     * to the specified `indexes` where the argument value at the first index is
10817     * provided as the first argument, the argument value at the second index is
10818     * provided as the second argument, and so on.
10819     *
10820     * @static
10821     * @memberOf _
10822     * @since 3.0.0
10823     * @category Function
10824     * @param {Function} func The function to rearrange arguments for.
10825     * @param {...(number|number[])} indexes The arranged argument indexes.
10826     * @returns {Function} Returns the new function.
10827     * @example
10828     *
10829     * var rearged = _.rearg(function(a, b, c) {
10830     *   return [a, b, c];
10831     * }, [2, 0, 1]);
10832     *
10833     * rearged('b', 'c', 'a')
10834     * // => ['a', 'b', 'c']
10835     */
10836    var rearg = flatRest(function(func, indexes) {
10837      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
10838    });
10839
10840    /**
10841     * Creates a function that invokes `func` with the `this` binding of the
10842     * created function and arguments from `start` and beyond provided as
10843     * an array.
10844     *
10845     * **Note:** This method is based on the
10846     * [rest parameter](https://mdn.io/rest_parameters).
10847     *
10848     * @static
10849     * @memberOf _
10850     * @since 4.0.0
10851     * @category Function
10852     * @param {Function} func The function to apply a rest parameter to.
10853     * @param {number} [start=func.length-1] The start position of the rest parameter.
10854     * @returns {Function} Returns the new function.
10855     * @example
10856     *
10857     * var say = _.rest(function(what, names) {
10858     *   return what + ' ' + _.initial(names).join(', ') +
10859     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10860     * });
10861     *
10862     * say('hello', 'fred', 'barney', 'pebbles');
10863     * // => 'hello fred, barney, & pebbles'
10864     */
10865    function rest(func, start) {
10866      if (typeof func != 'function') {
10867        throw new TypeError(FUNC_ERROR_TEXT);
10868      }
10869      start = start === undefined ? start : toInteger(start);
10870      return baseRest(func, start);
10871    }
10872
10873    /**
10874     * Creates a function that invokes `func` with the `this` binding of the
10875     * create function and an array of arguments much like
10876     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
10877     *
10878     * **Note:** This method is based on the
10879     * [spread operator](https://mdn.io/spread_operator).
10880     *
10881     * @static
10882     * @memberOf _
10883     * @since 3.2.0
10884     * @category Function
10885     * @param {Function} func The function to spread arguments over.
10886     * @param {number} [start=0] The start position of the spread.
10887     * @returns {Function} Returns the new function.
10888     * @example
10889     *
10890     * var say = _.spread(function(who, what) {
10891     *   return who + ' says ' + what;
10892     * });
10893     *
10894     * say(['fred', 'hello']);
10895     * // => 'fred says hello'
10896     *
10897     * var numbers = Promise.all([
10898     *   Promise.resolve(40),
10899     *   Promise.resolve(36)
10900     * ]);
10901     *
10902     * numbers.then(_.spread(function(x, y) {
10903     *   return x + y;
10904     * }));
10905     * // => a Promise of 76
10906     */
10907    function spread(func, start) {
10908      if (typeof func != 'function') {
10909        throw new TypeError(FUNC_ERROR_TEXT);
10910      }
10911      start = start == null ? 0 : nativeMax(toInteger(start), 0);
10912      return baseRest(function(args) {
10913        var array = args[start],
10914            otherArgs = castSlice(args, 0, start);
10915
10916        if (array) {
10917          arrayPush(otherArgs, array);
10918        }
10919        return apply(func, this, otherArgs);
10920      });
10921    }
10922
10923    /**
10924     * Creates a throttled function that only invokes `func` at most once per
10925     * every `wait` milliseconds. The throttled function comes with a `cancel`
10926     * method to cancel delayed `func` invocations and a `flush` method to
10927     * immediately invoke them. Provide `options` to indicate whether `func`
10928     * should be invoked on the leading and/or trailing edge of the `wait`
10929     * timeout. The `func` is invoked with the last arguments provided to the
10930     * throttled function. Subsequent calls to the throttled function return the
10931     * result of the last `func` invocation.
10932     *
10933     * **Note:** If `leading` and `trailing` options are `true`, `func` is
10934     * invoked on the trailing edge of the timeout only if the throttled function
10935     * is invoked more than once during the `wait` timeout.
10936     *
10937     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10938     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10939     *
10940     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10941     * for details over the differences between `_.throttle` and `_.debounce`.
10942     *
10943     * @static
10944     * @memberOf _
10945     * @since 0.1.0
10946     * @category Function
10947     * @param {Function} func The function to throttle.
10948     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10949     * @param {Object} [options={}] The options object.
10950     * @param {boolean} [options.leading=true]
10951     *  Specify invoking on the leading edge of the timeout.
10952     * @param {boolean} [options.trailing=true]
10953     *  Specify invoking on the trailing edge of the timeout.
10954     * @returns {Function} Returns the new throttled function.
10955     * @example
10956     *
10957     * // Avoid excessively updating the position while scrolling.
10958     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10959     *
10960     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10961     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10962     * jQuery(element).on('click', throttled);
10963     *
10964     * // Cancel the trailing throttled invocation.
10965     * jQuery(window).on('popstate', throttled.cancel);
10966     */
10967    function throttle(func, wait, options) {
10968      var leading = true,
10969          trailing = true;
10970
10971      if (typeof func != 'function') {
10972        throw new TypeError(FUNC_ERROR_TEXT);
10973      }
10974      if (isObject(options)) {
10975        leading = 'leading' in options ? !!options.leading : leading;
10976        trailing = 'trailing' in options ? !!options.trailing : trailing;
10977      }
10978      return debounce(func, wait, {
10979        'leading': leading,
10980        'maxWait': wait,
10981        'trailing': trailing
10982      });
10983    }
10984
10985    /**
10986     * Creates a function that accepts up to one argument, ignoring any
10987     * additional arguments.
10988     *
10989     * @static
10990     * @memberOf _
10991     * @since 4.0.0
10992     * @category Function
10993     * @param {Function} func The function to cap arguments for.
10994     * @returns {Function} Returns the new capped function.
10995     * @example
10996     *
10997     * _.map(['6', '8', '10'], _.unary(parseInt));
10998     * // => [6, 8, 10]
10999     */
11000    function unary(func) {
11001      return ary(func, 1);
11002    }
11003
11004    /**
11005     * Creates a function that provides `value` to `wrapper` as its first
11006     * argument. Any additional arguments provided to the function are appended
11007     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
11008     * binding of the created function.
11009     *
11010     * @static
11011     * @memberOf _
11012     * @since 0.1.0
11013     * @category Function
11014     * @param {*} value The value to wrap.
11015     * @param {Function} [wrapper=identity] The wrapper function.
11016     * @returns {Function} Returns the new function.
11017     * @example
11018     *
11019     * var p = _.wrap(_.escape, function(func, text) {
11020     *   return '<p>' + func(text) + '</p>';
11021     * });
11022     *
11023     * p('fred, barney, & pebbles');
11024     * // => '<p>fred, barney, &amp; pebbles</p>'
11025     */
11026    function wrap(value, wrapper) {
11027      return partial(castFunction(wrapper), value);
11028    }
11029
11030    /*------------------------------------------------------------------------*/
11031
11032    /**
11033     * Casts `value` as an array if it's not one.
11034     *
11035     * @static
11036     * @memberOf _
11037     * @since 4.4.0
11038     * @category Lang
11039     * @param {*} value The value to inspect.
11040     * @returns {Array} Returns the cast array.
11041     * @example
11042     *
11043     * _.castArray(1);
11044     * // => [1]
11045     *
11046     * _.castArray({ 'a': 1 });
11047     * // => [{ 'a': 1 }]
11048     *
11049     * _.castArray('abc');
11050     * // => ['abc']
11051     *
11052     * _.castArray(null);
11053     * // => [null]
11054     *
11055     * _.castArray(undefined);
11056     * // => [undefined]
11057     *
11058     * _.castArray();
11059     * // => []
11060     *
11061     * var array = [1, 2, 3];
11062     * console.log(_.castArray(array) === array);
11063     * // => true
11064     */
11065    function castArray() {
11066      if (!arguments.length) {
11067        return [];
11068      }
11069      var value = arguments[0];
11070      return isArray(value) ? value : [value];
11071    }
11072
11073    /**
11074     * Creates a shallow clone of `value`.
11075     *
11076     * **Note:** This method is loosely based on the
11077     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
11078     * and supports cloning arrays, array buffers, booleans, date objects, maps,
11079     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
11080     * arrays. The own enumerable properties of `arguments` objects are cloned
11081     * as plain objects. An empty object is returned for uncloneable values such
11082     * as error objects, functions, DOM nodes, and WeakMaps.
11083     *
11084     * @static
11085     * @memberOf _
11086     * @since 0.1.0
11087     * @category Lang
11088     * @param {*} value The value to clone.
11089     * @returns {*} Returns the cloned value.
11090     * @see _.cloneDeep
11091     * @example
11092     *
11093     * var objects = [{ 'a': 1 }, { 'b': 2 }];
11094     *
11095     * var shallow = _.clone(objects);
11096     * console.log(shallow[0] === objects[0]);
11097     * // => true
11098     */
11099    function clone(value) {
11100      return baseClone(value, CLONE_SYMBOLS_FLAG);
11101    }
11102
11103    /**
11104     * This method is like `_.clone` except that it accepts `customizer` which
11105     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
11106     * cloning is handled by the method instead. The `customizer` is invoked with
11107     * up to four arguments; (value [, index|key, object, stack]).
11108     *
11109     * @static
11110     * @memberOf _
11111     * @since 4.0.0
11112     * @category Lang
11113     * @param {*} value The value to clone.
11114     * @param {Function} [customizer] The function to customize cloning.
11115     * @returns {*} Returns the cloned value.
11116     * @see _.cloneDeepWith
11117     * @example
11118     *
11119     * function customizer(value) {
11120     *   if (_.isElement(value)) {
11121     *     return value.cloneNode(false);
11122     *   }
11123     * }
11124     *
11125     * var el = _.cloneWith(document.body, customizer);
11126     *
11127     * console.log(el === document.body);
11128     * // => false
11129     * console.log(el.nodeName);
11130     * // => 'BODY'
11131     * console.log(el.childNodes.length);
11132     * // => 0
11133     */
11134    function cloneWith(value, customizer) {
11135      customizer = typeof customizer == 'function' ? customizer : undefined;
11136      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
11137    }
11138
11139    /**
11140     * This method is like `_.clone` except that it recursively clones `value`.
11141     *
11142     * @static
11143     * @memberOf _
11144     * @since 1.0.0
11145     * @category Lang
11146     * @param {*} value The value to recursively clone.
11147     * @returns {*} Returns the deep cloned value.
11148     * @see _.clone
11149     * @example
11150     *
11151     * var objects = [{ 'a': 1 }, { 'b': 2 }];
11152     *
11153     * var deep = _.cloneDeep(objects);
11154     * console.log(deep[0] === objects[0]);
11155     * // => false
11156     */
11157    function cloneDeep(value) {
11158      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
11159    }
11160
11161    /**
11162     * This method is like `_.cloneWith` except that it recursively clones `value`.
11163     *
11164     * @static
11165     * @memberOf _
11166     * @since 4.0.0
11167     * @category Lang
11168     * @param {*} value The value to recursively clone.
11169     * @param {Function} [customizer] The function to customize cloning.
11170     * @returns {*} Returns the deep cloned value.
11171     * @see _.cloneWith
11172     * @example
11173     *
11174     * function customizer(value) {
11175     *   if (_.isElement(value)) {
11176     *     return value.cloneNode(true);
11177     *   }
11178     * }
11179     *
11180     * var el = _.cloneDeepWith(document.body, customizer);
11181     *
11182     * console.log(el === document.body);
11183     * // => false
11184     * console.log(el.nodeName);
11185     * // => 'BODY'
11186     * console.log(el.childNodes.length);
11187     * // => 20
11188     */
11189    function cloneDeepWith(value, customizer) {
11190      customizer = typeof customizer == 'function' ? customizer : undefined;
11191      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
11192    }
11193
11194    /**
11195     * Checks if `object` conforms to `source` by invoking the predicate
11196     * properties of `source` with the corresponding property values of `object`.
11197     *
11198     * **Note:** This method is equivalent to `_.conforms` when `source` is
11199     * partially applied.
11200     *
11201     * @static
11202     * @memberOf _
11203     * @since 4.14.0
11204     * @category Lang
11205     * @param {Object} object The object to inspect.
11206     * @param {Object} source The object of property predicates to conform to.
11207     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
11208     * @example
11209     *
11210     * var object = { 'a': 1, 'b': 2 };
11211     *
11212     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
11213     * // => true
11214     *
11215     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
11216     * // => false
11217     */
11218    function conformsTo(object, source) {
11219      return source == null || baseConformsTo(object, source, keys(source));
11220    }
11221
11222    /**
11223     * Performs a
11224     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
11225     * comparison between two values to determine if they are equivalent.
11226     *
11227     * @static
11228     * @memberOf _
11229     * @since 4.0.0
11230     * @category Lang
11231     * @param {*} value The value to compare.
11232     * @param {*} other The other value to compare.
11233     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11234     * @example
11235     *
11236     * var object = { 'a': 1 };
11237     * var other = { 'a': 1 };
11238     *
11239     * _.eq(object, object);
11240     * // => true
11241     *
11242     * _.eq(object, other);
11243     * // => false
11244     *
11245     * _.eq('a', 'a');
11246     * // => true
11247     *
11248     * _.eq('a', Object('a'));
11249     * // => false
11250     *
11251     * _.eq(NaN, NaN);
11252     * // => true
11253     */
11254    function eq(value, other) {
11255      return value === other || (value !== value && other !== other);
11256    }
11257
11258    /**
11259     * Checks if `value` is greater than `other`.
11260     *
11261     * @static
11262     * @memberOf _
11263     * @since 3.9.0
11264     * @category Lang
11265     * @param {*} value The value to compare.
11266     * @param {*} other The other value to compare.
11267     * @returns {boolean} Returns `true` if `value` is greater than `other`,
11268     *  else `false`.
11269     * @see _.lt
11270     * @example
11271     *
11272     * _.gt(3, 1);
11273     * // => true
11274     *
11275     * _.gt(3, 3);
11276     * // => false
11277     *
11278     * _.gt(1, 3);
11279     * // => false
11280     */
11281    var gt = createRelationalOperation(baseGt);
11282
11283    /**
11284     * Checks if `value` is greater than or equal to `other`.
11285     *
11286     * @static
11287     * @memberOf _
11288     * @since 3.9.0
11289     * @category Lang
11290     * @param {*} value The value to compare.
11291     * @param {*} other The other value to compare.
11292     * @returns {boolean} Returns `true` if `value` is greater than or equal to
11293     *  `other`, else `false`.
11294     * @see _.lte
11295     * @example
11296     *
11297     * _.gte(3, 1);
11298     * // => true
11299     *
11300     * _.gte(3, 3);
11301     * // => true
11302     *
11303     * _.gte(1, 3);
11304     * // => false
11305     */
11306    var gte = createRelationalOperation(function(value, other) {
11307      return value >= other;
11308    });
11309
11310    /**
11311     * Checks if `value` is likely an `arguments` object.
11312     *
11313     * @static
11314     * @memberOf _
11315     * @since 0.1.0
11316     * @category Lang
11317     * @param {*} value The value to check.
11318     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
11319     *  else `false`.
11320     * @example
11321     *
11322     * _.isArguments(function() { return arguments; }());
11323     * // => true
11324     *
11325     * _.isArguments([1, 2, 3]);
11326     * // => false
11327     */
11328    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
11329      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
11330        !propertyIsEnumerable.call(value, 'callee');
11331    };
11332
11333    /**
11334     * Checks if `value` is classified as an `Array` object.
11335     *
11336     * @static
11337     * @memberOf _
11338     * @since 0.1.0
11339     * @category Lang
11340     * @param {*} value The value to check.
11341     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
11342     * @example
11343     *
11344     * _.isArray([1, 2, 3]);
11345     * // => true
11346     *
11347     * _.isArray(document.body.children);
11348     * // => false
11349     *
11350     * _.isArray('abc');
11351     * // => false
11352     *
11353     * _.isArray(_.noop);
11354     * // => false
11355     */
11356    var isArray = Array.isArray;
11357
11358    /**
11359     * Checks if `value` is classified as an `ArrayBuffer` object.
11360     *
11361     * @static
11362     * @memberOf _
11363     * @since 4.3.0
11364     * @category Lang
11365     * @param {*} value The value to check.
11366     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
11367     * @example
11368     *
11369     * _.isArrayBuffer(new ArrayBuffer(2));
11370     * // => true
11371     *
11372     * _.isArrayBuffer(new Array(2));
11373     * // => false
11374     */
11375    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
11376
11377    /**
11378     * Checks if `value` is array-like. A value is considered array-like if it's
11379     * not a function and has a `value.length` that's an integer greater than or
11380     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
11381     *
11382     * @static
11383     * @memberOf _
11384     * @since 4.0.0
11385     * @category Lang
11386     * @param {*} value The value to check.
11387     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
11388     * @example
11389     *
11390     * _.isArrayLike([1, 2, 3]);
11391     * // => true
11392     *
11393     * _.isArrayLike(document.body.children);
11394     * // => true
11395     *
11396     * _.isArrayLike('abc');
11397     * // => true
11398     *
11399     * _.isArrayLike(_.noop);
11400     * // => false
11401     */
11402    function isArrayLike(value) {
11403      return value != null && isLength(value.length) && !isFunction(value);
11404    }
11405
11406    /**
11407     * This method is like `_.isArrayLike` except that it also checks if `value`
11408     * is an object.
11409     *
11410     * @static
11411     * @memberOf _
11412     * @since 4.0.0
11413     * @category Lang
11414     * @param {*} value The value to check.
11415     * @returns {boolean} Returns `true` if `value` is an array-like object,
11416     *  else `false`.
11417     * @example
11418     *
11419     * _.isArrayLikeObject([1, 2, 3]);
11420     * // => true
11421     *
11422     * _.isArrayLikeObject(document.body.children);
11423     * // => true
11424     *
11425     * _.isArrayLikeObject('abc');
11426     * // => false
11427     *
11428     * _.isArrayLikeObject(_.noop);
11429     * // => false
11430     */
11431    function isArrayLikeObject(value) {
11432      return isObjectLike(value) && isArrayLike(value);
11433    }
11434
11435    /**
11436     * Checks if `value` is classified as a boolean primitive or object.
11437     *
11438     * @static
11439     * @memberOf _
11440     * @since 0.1.0
11441     * @category Lang
11442     * @param {*} value The value to check.
11443     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
11444     * @example
11445     *
11446     * _.isBoolean(false);
11447     * // => true
11448     *
11449     * _.isBoolean(null);
11450     * // => false
11451     */
11452    function isBoolean(value) {
11453      return value === true || value === false ||
11454        (isObjectLike(value) && baseGetTag(value) == boolTag);
11455    }
11456
11457    /**
11458     * Checks if `value` is a buffer.
11459     *
11460     * @static
11461     * @memberOf _
11462     * @since 4.3.0
11463     * @category Lang
11464     * @param {*} value The value to check.
11465     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
11466     * @example
11467     *
11468     * _.isBuffer(new Buffer(2));
11469     * // => true
11470     *
11471     * _.isBuffer(new Uint8Array(2));
11472     * // => false
11473     */
11474    var isBuffer = nativeIsBuffer || stubFalse;
11475
11476    /**
11477     * Checks if `value` is classified as a `Date` object.
11478     *
11479     * @static
11480     * @memberOf _
11481     * @since 0.1.0
11482     * @category Lang
11483     * @param {*} value The value to check.
11484     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
11485     * @example
11486     *
11487     * _.isDate(new Date);
11488     * // => true
11489     *
11490     * _.isDate('Mon April 23 2012');
11491     * // => false
11492     */
11493    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
11494
11495    /**
11496     * Checks if `value` is likely a DOM element.
11497     *
11498     * @static
11499     * @memberOf _
11500     * @since 0.1.0
11501     * @category Lang
11502     * @param {*} value The value to check.
11503     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
11504     * @example
11505     *
11506     * _.isElement(document.body);
11507     * // => true
11508     *
11509     * _.isElement('<body>');
11510     * // => false
11511     */
11512    function isElement(value) {
11513      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
11514    }
11515
11516    /**
11517     * Checks if `value` is an empty object, collection, map, or set.
11518     *
11519     * Objects are considered empty if they have no own enumerable string keyed
11520     * properties.
11521     *
11522     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
11523     * jQuery-like collections are considered empty if they have a `length` of `0`.
11524     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
11525     *
11526     * @static
11527     * @memberOf _
11528     * @since 0.1.0
11529     * @category Lang
11530     * @param {*} value The value to check.
11531     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
11532     * @example
11533     *
11534     * _.isEmpty(null);
11535     * // => true
11536     *
11537     * _.isEmpty(true);
11538     * // => true
11539     *
11540     * _.isEmpty(1);
11541     * // => true
11542     *
11543     * _.isEmpty([1, 2, 3]);
11544     * // => false
11545     *
11546     * _.isEmpty({ 'a': 1 });
11547     * // => false
11548     */
11549    function isEmpty(value) {
11550      if (value == null) {
11551        return true;
11552      }
11553      if (isArrayLike(value) &&
11554          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
11555            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
11556        return !value.length;
11557      }
11558      var tag = getTag(value);
11559      if (tag == mapTag || tag == setTag) {
11560        return !value.size;
11561      }
11562      if (isPrototype(value)) {
11563        return !baseKeys(value).length;
11564      }
11565      for (var key in value) {
11566        if (hasOwnProperty.call(value, key)) {
11567          return false;
11568        }
11569      }
11570      return true;
11571    }
11572
11573    /**
11574     * Performs a deep comparison between two values to determine if they are
11575     * equivalent.
11576     *
11577     * **Note:** This method supports comparing arrays, array buffers, booleans,
11578     * date objects, error objects, maps, numbers, `Object` objects, regexes,
11579     * sets, strings, symbols, and typed arrays. `Object` objects are compared
11580     * by their own, not inherited, enumerable properties. Functions and DOM
11581     * nodes are compared by strict equality, i.e. `===`.
11582     *
11583     * @static
11584     * @memberOf _
11585     * @since 0.1.0
11586     * @category Lang
11587     * @param {*} value The value to compare.
11588     * @param {*} other The other value to compare.
11589     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11590     * @example
11591     *
11592     * var object = { 'a': 1 };
11593     * var other = { 'a': 1 };
11594     *
11595     * _.isEqual(object, other);
11596     * // => true
11597     *
11598     * object === other;
11599     * // => false
11600     */
11601    function isEqual(value, other) {
11602      return baseIsEqual(value, other);
11603    }
11604
11605    /**
11606     * This method is like `_.isEqual` except that it accepts `customizer` which
11607     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11608     * are handled by the method instead. The `customizer` is invoked with up to
11609     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
11610     *
11611     * @static
11612     * @memberOf _
11613     * @since 4.0.0
11614     * @category Lang
11615     * @param {*} value The value to compare.
11616     * @param {*} other The other value to compare.
11617     * @param {Function} [customizer] The function to customize comparisons.
11618     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11619     * @example
11620     *
11621     * function isGreeting(value) {
11622     *   return /^h(?:i|ello)$/.test(value);
11623     * }
11624     *
11625     * function customizer(objValue, othValue) {
11626     *   if (isGreeting(objValue) && isGreeting(othValue)) {
11627     *     return true;
11628     *   }
11629     * }
11630     *
11631     * var array = ['hello', 'goodbye'];
11632     * var other = ['hi', 'goodbye'];
11633     *
11634     * _.isEqualWith(array, other, customizer);
11635     * // => true
11636     */
11637    function isEqualWith(value, other, customizer) {
11638      customizer = typeof customizer == 'function' ? customizer : undefined;
11639      var result = customizer ? customizer(value, other) : undefined;
11640      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
11641    }
11642
11643    /**
11644     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
11645     * `SyntaxError`, `TypeError`, or `URIError` object.
11646     *
11647     * @static
11648     * @memberOf _
11649     * @since 3.0.0
11650     * @category Lang
11651     * @param {*} value The value to check.
11652     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
11653     * @example
11654     *
11655     * _.isError(new Error);
11656     * // => true
11657     *
11658     * _.isError(Error);
11659     * // => false
11660     */
11661    function isError(value) {
11662      if (!isObjectLike(value)) {
11663        return false;
vendor: 6,607 bytes, lines 11664-11901
11664      }
11665      var tag = baseGetTag(value);
11666      return tag == errorTag || tag == domExcTag ||
11667        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
11668    }
11669
11670    /**
11671     * Checks if `value` is a finite primitive number.
11672     *
11673     * **Note:** This method is based on
11674     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
11675     *
11676     * @static
11677     * @memberOf _
11678     * @since 0.1.0
11679     * @category Lang
11680     * @param {*} value The value to check.
11681     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
11682     * @example
11683     *
11684     * _.isFinite(3);
11685     * // => true
11686     *
11687     * _.isFinite(Number.MIN_VALUE);
11688     * // => true
11689     *
11690     * _.isFinite(Infinity);
11691     * // => false
11692     *
11693     * _.isFinite('3');
11694     * // => false
11695     */
11696    function isFinite(value) {
11697      return typeof value == 'number' && nativeIsFinite(value);
11698    }
11699
11700    /**
11701     * Checks if `value` is classified as a `Function` object.
11702     *
11703     * @static
11704     * @memberOf _
11705     * @since 0.1.0
11706     * @category Lang
11707     * @param {*} value The value to check.
11708     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
11709     * @example
11710     *
11711     * _.isFunction(_);
11712     * // => true
11713     *
11714     * _.isFunction(/abc/);
11715     * // => false
11716     */
11717    function isFunction(value) {
11718      if (!isObject(value)) {
11719        return false;
11720      }
11721      // The use of `Object#toString` avoids issues with the `typeof` operator
11722      // in Safari 9 which returns 'object' for typed arrays and other constructors.
11723      var tag = baseGetTag(value);
11724      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
11725    }
11726
11727    /**
11728     * Checks if `value` is an integer.
11729     *
11730     * **Note:** This method is based on
11731     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
11732     *
11733     * @static
11734     * @memberOf _
11735     * @since 4.0.0
11736     * @category Lang
11737     * @param {*} value The value to check.
11738     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
11739     * @example
11740     *
11741     * _.isInteger(3);
11742     * // => true
11743     *
11744     * _.isInteger(Number.MIN_VALUE);
11745     * // => false
11746     *
11747     * _.isInteger(Infinity);
11748     * // => false
11749     *
11750     * _.isInteger('3');
11751     * // => false
11752     */
11753    function isInteger(value) {
11754      return typeof value == 'number' && value == toInteger(value);
11755    }
11756
11757    /**
11758     * Checks if `value` is a valid array-like length.
11759     *
11760     * **Note:** This method is loosely based on
11761     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
11762     *
11763     * @static
11764     * @memberOf _
11765     * @since 4.0.0
11766     * @category Lang
11767     * @param {*} value The value to check.
11768     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
11769     * @example
11770     *
11771     * _.isLength(3);
11772     * // => true
11773     *
11774     * _.isLength(Number.MIN_VALUE);
11775     * // => false
11776     *
11777     * _.isLength(Infinity);
11778     * // => false
11779     *
11780     * _.isLength('3');
11781     * // => false
11782     */
11783    function isLength(value) {
11784      return typeof value == 'number' &&
11785        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11786    }
11787
11788    /**
11789     * Checks if `value` is the
11790     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
11791     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11792     *
11793     * @static
11794     * @memberOf _
11795     * @since 0.1.0
11796     * @category Lang
11797     * @param {*} value The value to check.
11798     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11799     * @example
11800     *
11801     * _.isObject({});
11802     * // => true
11803     *
11804     * _.isObject([1, 2, 3]);
11805     * // => true
11806     *
11807     * _.isObject(_.noop);
11808     * // => true
11809     *
11810     * _.isObject(null);
11811     * // => false
11812     */
11813    function isObject(value) {
11814      var type = typeof value;
11815      return value != null && (type == 'object' || type == 'function');
11816    }
11817
11818    /**
11819     * Checks if `value` is object-like. A value is object-like if it's not `null`
11820     * and has a `typeof` result of "object".
11821     *
11822     * @static
11823     * @memberOf _
11824     * @since 4.0.0
11825     * @category Lang
11826     * @param {*} value The value to check.
11827     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11828     * @example
11829     *
11830     * _.isObjectLike({});
11831     * // => true
11832     *
11833     * _.isObjectLike([1, 2, 3]);
11834     * // => true
11835     *
11836     * _.isObjectLike(_.noop);
11837     * // => false
11838     *
11839     * _.isObjectLike(null);
11840     * // => false
11841     */
11842    function isObjectLike(value) {
11843      return value != null && typeof value == 'object';
11844    }
11845
11846    /**
11847     * Checks if `value` is classified as a `Map` object.
11848     *
11849     * @static
11850     * @memberOf _
11851     * @since 4.3.0
11852     * @category Lang
11853     * @param {*} value The value to check.
11854     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
11855     * @example
11856     *
11857     * _.isMap(new Map);
11858     * // => true
11859     *
11860     * _.isMap(new WeakMap);
11861     * // => false
11862     */
11863    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
11864
11865    /**
11866     * Performs a partial deep comparison between `object` and `source` to
11867     * determine if `object` contains equivalent property values.
11868     *
11869     * **Note:** This method is equivalent to `_.matches` when `source` is
11870     * partially applied.
11871     *
11872     * Partial comparisons will match empty array and empty object `source`
11873     * values against any array or object value, respectively. See `_.isEqual`
11874     * for a list of supported value comparisons.
11875     *
11876     * @static
11877     * @memberOf _
11878     * @since 3.0.0
11879     * @category Lang
11880     * @param {Object} object The object to inspect.
11881     * @param {Object} source The object of property values to match.
11882     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11883     * @example
11884     *
11885     * var object = { 'a': 1, 'b': 2 };
11886     *
11887     * _.isMatch(object, { 'b': 2 });
11888     * // => true
11889     *
11890     * _.isMatch(object, { 'b': 1 });
11891     * // => false
11892     */
11893    function isMatch(object, source) {
11894      return object === source || baseIsMatch(object, source, getMatchData(source));
11895    }
11896
11897    /**
11898     * This method is like `_.isMatch` except that it accepts `customizer` which
11899     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11900     * are handled by the method instead. The `customizer` is invoked with five
11901     * arguments: (objValue, srcValue, index|key, object, source).
vendor: 12,241 bytes, lines 11902-12367
11902     *
11903     * @static
11904     * @memberOf _
11905     * @since 4.0.0
11906     * @category Lang
11907     * @param {Object} object The object to inspect.
11908     * @param {Object} source The object of property values to match.
11909     * @param {Function} [customizer] The function to customize comparisons.
11910     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11911     * @example
11912     *
11913     * function isGreeting(value) {
11914     *   return /^h(?:i|ello)$/.test(value);
11915     * }
11916     *
11917     * function customizer(objValue, srcValue) {
11918     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
11919     *     return true;
11920     *   }
11921     * }
11922     *
11923     * var object = { 'greeting': 'hello' };
11924     * var source = { 'greeting': 'hi' };
11925     *
11926     * _.isMatchWith(object, source, customizer);
11927     * // => true
11928     */
11929    function isMatchWith(object, source, customizer) {
11930      customizer = typeof customizer == 'function' ? customizer : undefined;
11931      return baseIsMatch(object, source, getMatchData(source), customizer);
11932    }
11933
11934    /**
11935     * Checks if `value` is `NaN`.
11936     *
11937     * **Note:** This method is based on
11938     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11939     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11940     * `undefined` and other non-number values.
11941     *
11942     * @static
11943     * @memberOf _
11944     * @since 0.1.0
11945     * @category Lang
11946     * @param {*} value The value to check.
11947     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11948     * @example
11949     *
11950     * _.isNaN(NaN);
11951     * // => true
11952     *
11953     * _.isNaN(new Number(NaN));
11954     * // => true
11955     *
11956     * isNaN(undefined);
11957     * // => true
11958     *
11959     * _.isNaN(undefined);
11960     * // => false
11961     */
11962    function isNaN(value) {
11963      // An `NaN` primitive is the only value that is not equal to itself.
11964      // Perform the `toStringTag` check first to avoid errors with some
11965      // ActiveX objects in IE.
11966      return isNumber(value) && value != +value;
11967    }
11968
11969    /**
11970     * Checks if `value` is a pristine native function.
11971     *
11972     * **Note:** This method can't reliably detect native functions in the presence
11973     * of the core-js package because core-js circumvents this kind of detection.
11974     * Despite multiple requests, the core-js maintainer has made it clear: any
11975     * attempt to fix the detection will be obstructed. As a result, we're left
11976     * with little choice but to throw an error. Unfortunately, this also affects
11977     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11978     * which rely on core-js.
11979     *
11980     * @static
11981     * @memberOf _
11982     * @since 3.0.0
11983     * @category Lang
11984     * @param {*} value The value to check.
11985     * @returns {boolean} Returns `true` if `value` is a native function,
11986     *  else `false`.
11987     * @example
11988     *
11989     * _.isNative(Array.prototype.push);
11990     * // => true
11991     *
11992     * _.isNative(_);
11993     * // => false
11994     */
11995    function isNative(value) {
11996      if (isMaskable(value)) {
11997        throw new Error(CORE_ERROR_TEXT);
11998      }
11999      return baseIsNative(value);
12000    }
12001
12002    /**
12003     * Checks if `value` is `null`.
12004     *
12005     * @static
12006     * @memberOf _
12007     * @since 0.1.0
12008     * @category Lang
12009     * @param {*} value The value to check.
12010     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
12011     * @example
12012     *
12013     * _.isNull(null);
12014     * // => true
12015     *
12016     * _.isNull(void 0);
12017     * // => false
12018     */
12019    function isNull(value) {
12020      return value === null;
12021    }
12022
12023    /**
12024     * Checks if `value` is `null` or `undefined`.
12025     *
12026     * @static
12027     * @memberOf _
12028     * @since 4.0.0
12029     * @category Lang
12030     * @param {*} value The value to check.
12031     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
12032     * @example
12033     *
12034     * _.isNil(null);
12035     * // => true
12036     *
12037     * _.isNil(void 0);
12038     * // => true
12039     *
12040     * _.isNil(NaN);
12041     * // => false
12042     */
12043    function isNil(value) {
12044      return value == null;
12045    }
12046
12047    /**
12048     * Checks if `value` is classified as a `Number` primitive or object.
12049     *
12050     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
12051     * classified as numbers, use the `_.isFinite` method.
12052     *
12053     * @static
12054     * @memberOf _
12055     * @since 0.1.0
12056     * @category Lang
12057     * @param {*} value The value to check.
12058     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
12059     * @example
12060     *
12061     * _.isNumber(3);
12062     * // => true
12063     *
12064     * _.isNumber(Number.MIN_VALUE);
12065     * // => true
12066     *
12067     * _.isNumber(Infinity);
12068     * // => true
12069     *
12070     * _.isNumber('3');
12071     * // => false
12072     */
12073    function isNumber(value) {
12074      return typeof value == 'number' ||
12075        (isObjectLike(value) && baseGetTag(value) == numberTag);
12076    }
12077
12078    /**
12079     * Checks if `value` is a plain object, that is, an object created by the
12080     * `Object` constructor or one with a `[[Prototype]]` of `null`.
12081     *
12082     * @static
12083     * @memberOf _
12084     * @since 0.8.0
12085     * @category Lang
12086     * @param {*} value The value to check.
12087     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
12088     * @example
12089     *
12090     * function Foo() {
12091     *   this.a = 1;
12092     * }
12093     *
12094     * _.isPlainObject(new Foo);
12095     * // => false
12096     *
12097     * _.isPlainObject([1, 2, 3]);
12098     * // => false
12099     *
12100     * _.isPlainObject({ 'x': 0, 'y': 0 });
12101     * // => true
12102     *
12103     * _.isPlainObject(Object.create(null));
12104     * // => true
12105     */
12106    function isPlainObject(value) {
12107      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
12108        return false;
12109      }
12110      var proto = getPrototype(value);
12111      if (proto === null) {
12112        return true;
12113      }
12114      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
12115      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
12116        funcToString.call(Ctor) == objectCtorString;
12117    }
12118
12119    /**
12120     * Checks if `value` is classified as a `RegExp` object.
12121     *
12122     * @static
12123     * @memberOf _
12124     * @since 0.1.0
12125     * @category Lang
12126     * @param {*} value The value to check.
12127     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
12128     * @example
12129     *
12130     * _.isRegExp(/abc/);
12131     * // => true
12132     *
12133     * _.isRegExp('/abc/');
12134     * // => false
12135     */
12136    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
12137
12138    /**
12139     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
12140     * double precision number which isn't the result of a rounded unsafe integer.
12141     *
12142     * **Note:** This method is based on
12143     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
12144     *
12145     * @static
12146     * @memberOf _
12147     * @since 4.0.0
12148     * @category Lang
12149     * @param {*} value The value to check.
12150     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
12151     * @example
12152     *
12153     * _.isSafeInteger(3);
12154     * // => true
12155     *
12156     * _.isSafeInteger(Number.MIN_VALUE);
12157     * // => false
12158     *
12159     * _.isSafeInteger(Infinity);
12160     * // => false
12161     *
12162     * _.isSafeInteger('3');
12163     * // => false
12164     */
12165    function isSafeInteger(value) {
12166      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
12167    }
12168
12169    /**
12170     * Checks if `value` is classified as a `Set` object.
12171     *
12172     * @static
12173     * @memberOf _
12174     * @since 4.3.0
12175     * @category Lang
12176     * @param {*} value The value to check.
12177     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
12178     * @example
12179     *
12180     * _.isSet(new Set);
12181     * // => true
12182     *
12183     * _.isSet(new WeakSet);
12184     * // => false
12185     */
12186    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
12187
12188    /**
12189     * Checks if `value` is classified as a `String` primitive or object.
12190     *
12191     * @static
12192     * @since 0.1.0
12193     * @memberOf _
12194     * @category Lang
12195     * @param {*} value The value to check.
12196     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
12197     * @example
12198     *
12199     * _.isString('abc');
12200     * // => true
12201     *
12202     * _.isString(1);
12203     * // => false
12204     */
12205    function isString(value) {
12206      return typeof value == 'string' ||
12207        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
12208    }
12209
12210    /**
12211     * Checks if `value` is classified as a `Symbol` primitive or object.
12212     *
12213     * @static
12214     * @memberOf _
12215     * @since 4.0.0
12216     * @category Lang
12217     * @param {*} value The value to check.
12218     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
12219     * @example
12220     *
12221     * _.isSymbol(Symbol.iterator);
12222     * // => true
12223     *
12224     * _.isSymbol('abc');
12225     * // => false
12226     */
12227    function isSymbol(value) {
12228      return typeof value == 'symbol' ||
12229        (isObjectLike(value) && baseGetTag(value) == symbolTag);
12230    }
12231
12232    /**
12233     * Checks if `value` is classified as a typed array.
12234     *
12235     * @static
12236     * @memberOf _
12237     * @since 3.0.0
12238     * @category Lang
12239     * @param {*} value The value to check.
12240     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
12241     * @example
12242     *
12243     * _.isTypedArray(new Uint8Array);
12244     * // => true
12245     *
12246     * _.isTypedArray([]);
12247     * // => false
12248     */
12249    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
12250
12251    /**
12252     * Checks if `value` is `undefined`.
12253     *
12254     * @static
12255     * @since 0.1.0
12256     * @memberOf _
12257     * @category Lang
12258     * @param {*} value The value to check.
12259     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
12260     * @example
12261     *
12262     * _.isUndefined(void 0);
12263     * // => true
12264     *
12265     * _.isUndefined(null);
12266     * // => false
12267     */
12268    function isUndefined(value) {
12269      return value === undefined;
12270    }
12271
12272    /**
12273     * Checks if `value` is classified as a `WeakMap` object.
12274     *
12275     * @static
12276     * @memberOf _
12277     * @since 4.3.0
12278     * @category Lang
12279     * @param {*} value The value to check.
12280     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
12281     * @example
12282     *
12283     * _.isWeakMap(new WeakMap);
12284     * // => true
12285     *
12286     * _.isWeakMap(new Map);
12287     * // => false
12288     */
12289    function isWeakMap(value) {
12290      return isObjectLike(value) && getTag(value) == weakMapTag;
12291    }
12292
12293    /**
12294     * Checks if `value` is classified as a `WeakSet` object.
12295     *
12296     * @static
12297     * @memberOf _
12298     * @since 4.3.0
12299     * @category Lang
12300     * @param {*} value The value to check.
12301     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
12302     * @example
12303     *
12304     * _.isWeakSet(new WeakSet);
12305     * // => true
12306     *
12307     * _.isWeakSet(new Set);
12308     * // => false
12309     */
12310    function isWeakSet(value) {
12311      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
12312    }
12313
12314    /**
12315     * Checks if `value` is less than `other`.
12316     *
12317     * @static
12318     * @memberOf _
12319     * @since 3.9.0
12320     * @category Lang
12321     * @param {*} value The value to compare.
12322     * @param {*} other The other value to compare.
12323     * @returns {boolean} Returns `true` if `value` is less than `other`,
12324     *  else `false`.
12325     * @see _.gt
12326     * @example
12327     *
12328     * _.lt(1, 3);
12329     * // => true
12330     *
12331     * _.lt(3, 3);
12332     * // => false
12333     *
12334     * _.lt(3, 1);
12335     * // => false
12336     */
12337    var lt = createRelationalOperation(baseLt);
12338
12339    /**
12340     * Checks if `value` is less than or equal to `other`.
12341     *
12342     * @static
12343     * @memberOf _
12344     * @since 3.9.0
12345     * @category Lang
12346     * @param {*} value The value to compare.
12347     * @param {*} other The other value to compare.
12348     * @returns {boolean} Returns `true` if `value` is less than or equal to
12349     *  `other`, else `false`.
12350     * @see _.gte
12351     * @example
12352     *
12353     * _.lte(1, 3);
12354     * // => true
12355     *
12356     * _.lte(3, 3);
12357     * // => true
12358     *
12359     * _.lte(3, 1);
12360     * // => false
12361     */
12362    var lte = createRelationalOperation(function(value, other) {
12363      return value <= other;
12364    });
12365
12366    /**
12367     * Converts `value` to an array.
vendor: 11,756 bytes, lines 12368-12797
12368     *
12369     * @static
12370     * @since 0.1.0
12371     * @memberOf _
12372     * @category Lang
12373     * @param {*} value The value to convert.
12374     * @returns {Array} Returns the converted array.
12375     * @example
12376     *
12377     * _.toArray({ 'a': 1, 'b': 2 });
12378     * // => [1, 2]
12379     *
12380     * _.toArray('abc');
12381     * // => ['a', 'b', 'c']
12382     *
12383     * _.toArray(1);
12384     * // => []
12385     *
12386     * _.toArray(null);
12387     * // => []
12388     */
12389    function toArray(value) {
12390      if (!value) {
12391        return [];
12392      }
12393      if (isArrayLike(value)) {
12394        return isString(value) ? stringToArray(value) : copyArray(value);
12395      }
12396      if (symIterator && value[symIterator]) {
12397        return iteratorToArray(value[symIterator]());
12398      }
12399      var tag = getTag(value),
12400          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
12401
12402      return func(value);
12403    }
12404
12405    /**
12406     * Converts `value` to a finite number.
12407     *
12408     * @static
12409     * @memberOf _
12410     * @since 4.12.0
12411     * @category Lang
12412     * @param {*} value The value to convert.
12413     * @returns {number} Returns the converted number.
12414     * @example
12415     *
12416     * _.toFinite(3.2);
12417     * // => 3.2
12418     *
12419     * _.toFinite(Number.MIN_VALUE);
12420     * // => 5e-324
12421     *
12422     * _.toFinite(Infinity);
12423     * // => 1.7976931348623157e+308
12424     *
12425     * _.toFinite('3.2');
12426     * // => 3.2
12427     */
12428    function toFinite(value) {
12429      if (!value) {
12430        return value === 0 ? value : 0;
12431      }
12432      value = toNumber(value);
12433      if (value === INFINITY || value === -INFINITY) {
12434        var sign = (value < 0 ? -1 : 1);
12435        return sign * MAX_INTEGER;
12436      }
12437      return value === value ? value : 0;
12438    }
12439
12440    /**
12441     * Converts `value` to an integer.
12442     *
12443     * **Note:** This method is loosely based on
12444     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
12445     *
12446     * @static
12447     * @memberOf _
12448     * @since 4.0.0
12449     * @category Lang
12450     * @param {*} value The value to convert.
12451     * @returns {number} Returns the converted integer.
12452     * @example
12453     *
12454     * _.toInteger(3.2);
12455     * // => 3
12456     *
12457     * _.toInteger(Number.MIN_VALUE);
12458     * // => 0
12459     *
12460     * _.toInteger(Infinity);
12461     * // => 1.7976931348623157e+308
12462     *
12463     * _.toInteger('3.2');
12464     * // => 3
12465     */
12466    function toInteger(value) {
12467      var result = toFinite(value),
12468          remainder = result % 1;
12469
12470      return result === result ? (remainder ? result - remainder : result) : 0;
12471    }
12472
12473    /**
12474     * Converts `value` to an integer suitable for use as the length of an
12475     * array-like object.
12476     *
12477     * **Note:** This method is based on
12478     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12479     *
12480     * @static
12481     * @memberOf _
12482     * @since 4.0.0
12483     * @category Lang
12484     * @param {*} value The value to convert.
12485     * @returns {number} Returns the converted integer.
12486     * @example
12487     *
12488     * _.toLength(3.2);
12489     * // => 3
12490     *
12491     * _.toLength(Number.MIN_VALUE);
12492     * // => 0
12493     *
12494     * _.toLength(Infinity);
12495     * // => 4294967295
12496     *
12497     * _.toLength('3.2');
12498     * // => 3
12499     */
12500    function toLength(value) {
12501      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
12502    }
12503
12504    /**
12505     * Converts `value` to a number.
12506     *
12507     * @static
12508     * @memberOf _
12509     * @since 4.0.0
12510     * @category Lang
12511     * @param {*} value The value to process.
12512     * @returns {number} Returns the number.
12513     * @example
12514     *
12515     * _.toNumber(3.2);
12516     * // => 3.2
12517     *
12518     * _.toNumber(Number.MIN_VALUE);
12519     * // => 5e-324
12520     *
12521     * _.toNumber(Infinity);
12522     * // => Infinity
12523     *
12524     * _.toNumber('3.2');
12525     * // => 3.2
12526     */
12527    function toNumber(value) {
12528      if (typeof value == 'number') {
12529        return value;
12530      }
12531      if (isSymbol(value)) {
12532        return NAN;
12533      }
12534      if (isObject(value)) {
12535        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
12536        value = isObject(other) ? (other + '') : other;
12537      }
12538      if (typeof value != 'string') {
12539        return value === 0 ? value : +value;
12540      }
12541      value = baseTrim(value);
12542      var isBinary = reIsBinary.test(value);
12543      return (isBinary || reIsOctal.test(value))
12544        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
12545        : (reIsBadHex.test(value) ? NAN : +value);
12546    }
12547
12548    /**
12549     * Converts `value` to a plain object flattening inherited enumerable string
12550     * keyed properties of `value` to own properties of the plain object.
12551     *
12552     * @static
12553     * @memberOf _
12554     * @since 3.0.0
12555     * @category Lang
12556     * @param {*} value The value to convert.
12557     * @returns {Object} Returns the converted plain object.
12558     * @example
12559     *
12560     * function Foo() {
12561     *   this.b = 2;
12562     * }
12563     *
12564     * Foo.prototype.c = 3;
12565     *
12566     * _.assign({ 'a': 1 }, new Foo);
12567     * // => { 'a': 1, 'b': 2 }
12568     *
12569     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
12570     * // => { 'a': 1, 'b': 2, 'c': 3 }
12571     */
12572    function toPlainObject(value) {
12573      return copyObject(value, keysIn(value));
12574    }
12575
12576    /**
12577     * Converts `value` to a safe integer. A safe integer can be compared and
12578     * represented correctly.
12579     *
12580     * @static
12581     * @memberOf _
12582     * @since 4.0.0
12583     * @category Lang
12584     * @param {*} value The value to convert.
12585     * @returns {number} Returns the converted integer.
12586     * @example
12587     *
12588     * _.toSafeInteger(3.2);
12589     * // => 3
12590     *
12591     * _.toSafeInteger(Number.MIN_VALUE);
12592     * // => 0
12593     *
12594     * _.toSafeInteger(Infinity);
12595     * // => 9007199254740991
12596     *
12597     * _.toSafeInteger('3.2');
12598     * // => 3
12599     */
12600    function toSafeInteger(value) {
12601      return value
12602        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
12603        : (value === 0 ? value : 0);
12604    }
12605
12606    /**
12607     * Converts `value` to a string. An empty string is returned for `null`
12608     * and `undefined` values. The sign of `-0` is preserved.
12609     *
12610     * @static
12611     * @memberOf _
12612     * @since 4.0.0
12613     * @category Lang
12614     * @param {*} value The value to convert.
12615     * @returns {string} Returns the converted string.
12616     * @example
12617     *
12618     * _.toString(null);
12619     * // => ''
12620     *
12621     * _.toString(-0);
12622     * // => '-0'
12623     *
12624     * _.toString([1, 2, 3]);
12625     * // => '1,2,3'
12626     */
12627    function toString(value) {
12628      return value == null ? '' : baseToString(value);
12629    }
12630
12631    /*------------------------------------------------------------------------*/
12632
12633    /**
12634     * Assigns own enumerable string keyed properties of source objects to the
12635     * destination object. Source objects are applied from left to right.
12636     * Subsequent sources overwrite property assignments of previous sources.
12637     *
12638     * **Note:** This method mutates `object` and is loosely based on
12639     * [`Object.assign`](https://mdn.io/Object/assign).
12640     *
12641     * @static
12642     * @memberOf _
12643     * @since 0.10.0
12644     * @category Object
12645     * @param {Object} object The destination object.
12646     * @param {...Object} [sources] The source objects.
12647     * @returns {Object} Returns `object`.
12648     * @see _.assignIn
12649     * @example
12650     *
12651     * function Foo() {
12652     *   this.a = 1;
12653     * }
12654     *
12655     * function Bar() {
12656     *   this.c = 3;
12657     * }
12658     *
12659     * Foo.prototype.b = 2;
12660     * Bar.prototype.d = 4;
12661     *
12662     * _.assign({ 'a': 0 }, new Foo, new Bar);
12663     * // => { 'a': 1, 'c': 3 }
12664     */
12665    var assign = createAssigner(function(object, source) {
12666      if (isPrototype(source) || isArrayLike(source)) {
12667        copyObject(source, keys(source), object);
12668        return;
12669      }
12670      for (var key in source) {
12671        if (hasOwnProperty.call(source, key)) {
12672          assignValue(object, key, source[key]);
12673        }
12674      }
12675    });
12676
12677    /**
12678     * This method is like `_.assign` except that it iterates over own and
12679     * inherited source properties.
12680     *
12681     * **Note:** This method mutates `object`.
12682     *
12683     * @static
12684     * @memberOf _
12685     * @since 4.0.0
12686     * @alias extend
12687     * @category Object
12688     * @param {Object} object The destination object.
12689     * @param {...Object} [sources] The source objects.
12690     * @returns {Object} Returns `object`.
12691     * @see _.assign
12692     * @example
12693     *
12694     * function Foo() {
12695     *   this.a = 1;
12696     * }
12697     *
12698     * function Bar() {
12699     *   this.c = 3;
12700     * }
12701     *
12702     * Foo.prototype.b = 2;
12703     * Bar.prototype.d = 4;
12704     *
12705     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
12706     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
12707     */
12708    var assignIn = createAssigner(function(object, source) {
12709      copyObject(source, keysIn(source), object);
12710    });
12711
12712    /**
12713     * This method is like `_.assignIn` except that it accepts `customizer`
12714     * which is invoked to produce the assigned values. If `customizer` returns
12715     * `undefined`, assignment is handled by the method instead. The `customizer`
12716     * is invoked with five arguments: (objValue, srcValue, key, object, source).
12717     *
12718     * **Note:** This method mutates `object`.
12719     *
12720     * @static
12721     * @memberOf _
12722     * @since 4.0.0
12723     * @alias extendWith
12724     * @category Object
12725     * @param {Object} object The destination object.
12726     * @param {...Object} sources The source objects.
12727     * @param {Function} [customizer] The function to customize assigned values.
12728     * @returns {Object} Returns `object`.
12729     * @see _.assignWith
12730     * @example
12731     *
12732     * function customizer(objValue, srcValue) {
12733     *   return _.isUndefined(objValue) ? srcValue : objValue;
12734     * }
12735     *
12736     * var defaults = _.partialRight(_.assignInWith, customizer);
12737     *
12738     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12739     * // => { 'a': 1, 'b': 2 }
12740     */
12741    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12742      copyObject(source, keysIn(source), object, customizer);
12743    });
12744
12745    /**
12746     * This method is like `_.assign` except that it accepts `customizer`
12747     * which is invoked to produce the assigned values. If `customizer` returns
12748     * `undefined`, assignment is handled by the method instead. The `customizer`
12749     * is invoked with five arguments: (objValue, srcValue, key, object, source).
12750     *
12751     * **Note:** This method mutates `object`.
12752     *
12753     * @static
12754     * @memberOf _
12755     * @since 4.0.0
12756     * @category Object
12757     * @param {Object} object The destination object.
12758     * @param {...Object} sources The source objects.
12759     * @param {Function} [customizer] The function to customize assigned values.
12760     * @returns {Object} Returns `object`.
12761     * @see _.assignInWith
12762     * @example
12763     *
12764     * function customizer(objValue, srcValue) {
12765     *   return _.isUndefined(objValue) ? srcValue : objValue;
12766     * }
12767     *
12768     * var defaults = _.partialRight(_.assignWith, customizer);
12769     *
12770     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12771     * // => { 'a': 1, 'b': 2 }
12772     */
12773    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12774      copyObject(source, keys(source), object, customizer);
12775    });
12776
12777    /**
12778     * Creates an array of values corresponding to `paths` of `object`.
12779     *
12780     * @static
12781     * @memberOf _
12782     * @since 1.0.0
12783     * @category Object
12784     * @param {Object} object The object to iterate over.
12785     * @param {...(string|string[])} [paths] The property paths to pick.
12786     * @returns {Array} Returns the picked values.
12787     * @example
12788     *
12789     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12790     *
12791     * _.at(object, ['a[0].b.c', 'a[1]']);
12792     * // => [3, 4]
12793     */
12794    var at = flatRest(baseAt);
12795
12796    /**
12797     * Creates an object that inherits from the `prototype` object. If a
vendor: 13,619 bytes, lines 12798-13262
12798     * `properties` object is given, its own enumerable string keyed properties
12799     * are assigned to the created object.
12800     *
12801     * @static
12802     * @memberOf _
12803     * @since 2.3.0
12804     * @category Object
12805     * @param {Object} prototype The object to inherit from.
12806     * @param {Object} [properties] The properties to assign to the object.
12807     * @returns {Object} Returns the new object.
12808     * @example
12809     *
12810     * function Shape() {
12811     *   this.x = 0;
12812     *   this.y = 0;
12813     * }
12814     *
12815     * function Circle() {
12816     *   Shape.call(this);
12817     * }
12818     *
12819     * Circle.prototype = _.create(Shape.prototype, {
12820     *   'constructor': Circle
12821     * });
12822     *
12823     * var circle = new Circle;
12824     * circle instanceof Circle;
12825     * // => true
12826     *
12827     * circle instanceof Shape;
12828     * // => true
12829     */
12830    function create(prototype, properties) {
12831      var result = baseCreate(prototype);
12832      return properties == null ? result : baseAssign(result, properties);
12833    }
12834
12835    /**
12836     * Assigns own and inherited enumerable string keyed properties of source
12837     * objects to the destination object for all destination properties that
12838     * resolve to `undefined`. Source objects are applied from left to right.
12839     * Once a property is set, additional values of the same property are ignored.
12840     *
12841     * **Note:** This method mutates `object`.
12842     *
12843     * @static
12844     * @since 0.1.0
12845     * @memberOf _
12846     * @category Object
12847     * @param {Object} object The destination object.
12848     * @param {...Object} [sources] The source objects.
12849     * @returns {Object} Returns `object`.
12850     * @see _.defaultsDeep
12851     * @example
12852     *
12853     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12854     * // => { 'a': 1, 'b': 2 }
12855     */
12856    var defaults = baseRest(function(object, sources) {
12857      object = Object(object);
12858
12859      var index = -1;
12860      var length = sources.length;
12861      var guard = length > 2 ? sources[2] : undefined;
12862
12863      if (guard && isIterateeCall(sources[0], sources[1], guard)) {
12864        length = 1;
12865      }
12866
12867      while (++index < length) {
12868        var source = sources[index];
12869        var props = keysIn(source);
12870        var propsIndex = -1;
12871        var propsLength = props.length;
12872
12873        while (++propsIndex < propsLength) {
12874          var key = props[propsIndex];
12875          var value = object[key];
12876
12877          if (value === undefined ||
12878              (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
12879            object[key] = source[key];
12880          }
12881        }
12882      }
12883
12884      return object;
12885    });
12886
12887    /**
12888     * This method is like `_.defaults` except that it recursively assigns
12889     * default properties.
12890     *
12891     * **Note:** This method mutates `object`.
12892     *
12893     * @static
12894     * @memberOf _
12895     * @since 3.10.0
12896     * @category Object
12897     * @param {Object} object The destination object.
12898     * @param {...Object} [sources] The source objects.
12899     * @returns {Object} Returns `object`.
12900     * @see _.defaults
12901     * @example
12902     *
12903     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
12904     * // => { 'a': { 'b': 2, 'c': 3 } }
12905     */
12906    var defaultsDeep = baseRest(function(args) {
12907      args.push(undefined, customDefaultsMerge);
12908      return apply(mergeWith, undefined, args);
12909    });
12910
12911    /**
12912     * This method is like `_.find` except that it returns the key of the first
12913     * element `predicate` returns truthy for instead of the element itself.
12914     *
12915     * @static
12916     * @memberOf _
12917     * @since 1.1.0
12918     * @category Object
12919     * @param {Object} object The object to inspect.
12920     * @param {Function} [predicate=_.identity] The function invoked per iteration.
12921     * @returns {string|undefined} Returns the key of the matched element,
12922     *  else `undefined`.
12923     * @example
12924     *
12925     * var users = {
12926     *   'barney':  { 'age': 36, 'active': true },
12927     *   'fred':    { 'age': 40, 'active': false },
12928     *   'pebbles': { 'age': 1,  'active': true }
12929     * };
12930     *
12931     * _.findKey(users, function(o) { return o.age < 40; });
12932     * // => 'barney' (iteration order is not guaranteed)
12933     *
12934     * // The `_.matches` iteratee shorthand.
12935     * _.findKey(users, { 'age': 1, 'active': true });
12936     * // => 'pebbles'
12937     *
12938     * // The `_.matchesProperty` iteratee shorthand.
12939     * _.findKey(users, ['active', false]);
12940     * // => 'fred'
12941     *
12942     * // The `_.property` iteratee shorthand.
12943     * _.findKey(users, 'active');
12944     * // => 'barney'
12945     */
12946    function findKey(object, predicate) {
12947      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12948    }
12949
12950    /**
12951     * This method is like `_.findKey` except that it iterates over elements of
12952     * a collection in the opposite order.
12953     *
12954     * @static
12955     * @memberOf _
12956     * @since 2.0.0
12957     * @category Object
12958     * @param {Object} object The object to inspect.
12959     * @param {Function} [predicate=_.identity] The function invoked per iteration.
12960     * @returns {string|undefined} Returns the key of the matched element,
12961     *  else `undefined`.
12962     * @example
12963     *
12964     * var users = {
12965     *   'barney':  { 'age': 36, 'active': true },
12966     *   'fred':    { 'age': 40, 'active': false },
12967     *   'pebbles': { 'age': 1,  'active': true }
12968     * };
12969     *
12970     * _.findLastKey(users, function(o) { return o.age < 40; });
12971     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12972     *
12973     * // The `_.matches` iteratee shorthand.
12974     * _.findLastKey(users, { 'age': 36, 'active': true });
12975     * // => 'barney'
12976     *
12977     * // The `_.matchesProperty` iteratee shorthand.
12978     * _.findLastKey(users, ['active', false]);
12979     * // => 'fred'
12980     *
12981     * // The `_.property` iteratee shorthand.
12982     * _.findLastKey(users, 'active');
12983     * // => 'pebbles'
12984     */
12985    function findLastKey(object, predicate) {
12986      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12987    }
12988
12989    /**
12990     * Iterates over own and inherited enumerable string keyed properties of an
12991     * object and invokes `iteratee` for each property. The iteratee is invoked
12992     * with three arguments: (value, key, object). Iteratee functions may exit
12993     * iteration early by explicitly returning `false`.
12994     *
12995     * @static
12996     * @memberOf _
12997     * @since 0.3.0
12998     * @category Object
12999     * @param {Object} object The object to iterate over.
13000     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13001     * @returns {Object} Returns `object`.
13002     * @see _.forInRight
13003     * @example
13004     *
13005     * function Foo() {
13006     *   this.a = 1;
13007     *   this.b = 2;
13008     * }
13009     *
13010     * Foo.prototype.c = 3;
13011     *
13012     * _.forIn(new Foo, function(value, key) {
13013     *   console.log(key);
13014     * });
13015     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
13016     */
13017    function forIn(object, iteratee) {
13018      return object == null
13019        ? object
13020        : baseFor(object, getIteratee(iteratee, 3), keysIn);
13021    }
13022
13023    /**
13024     * This method is like `_.forIn` except that it iterates over properties of
13025     * `object` in the opposite order.
13026     *
13027     * @static
13028     * @memberOf _
13029     * @since 2.0.0
13030     * @category Object
13031     * @param {Object} object The object to iterate over.
13032     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13033     * @returns {Object} Returns `object`.
13034     * @see _.forIn
13035     * @example
13036     *
13037     * function Foo() {
13038     *   this.a = 1;
13039     *   this.b = 2;
13040     * }
13041     *
13042     * Foo.prototype.c = 3;
13043     *
13044     * _.forInRight(new Foo, function(value, key) {
13045     *   console.log(key);
13046     * });
13047     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
13048     */
13049    function forInRight(object, iteratee) {
13050      return object == null
13051        ? object
13052        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
13053    }
13054
13055    /**
13056     * Iterates over own enumerable string keyed properties of an object and
13057     * invokes `iteratee` for each property. The iteratee is invoked with three
13058     * arguments: (value, key, object). Iteratee functions may exit iteration
13059     * early by explicitly returning `false`.
13060     *
13061     * @static
13062     * @memberOf _
13063     * @since 0.3.0
13064     * @category Object
13065     * @param {Object} object The object to iterate over.
13066     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13067     * @returns {Object} Returns `object`.
13068     * @see _.forOwnRight
13069     * @example
13070     *
13071     * function Foo() {
13072     *   this.a = 1;
13073     *   this.b = 2;
13074     * }
13075     *
13076     * Foo.prototype.c = 3;
13077     *
13078     * _.forOwn(new Foo, function(value, key) {
13079     *   console.log(key);
13080     * });
13081     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
13082     */
13083    function forOwn(object, iteratee) {
13084      return object && baseForOwn(object, getIteratee(iteratee, 3));
13085    }
13086
13087    /**
13088     * This method is like `_.forOwn` except that it iterates over properties of
13089     * `object` in the opposite order.
13090     *
13091     * @static
13092     * @memberOf _
13093     * @since 2.0.0
13094     * @category Object
13095     * @param {Object} object The object to iterate over.
13096     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13097     * @returns {Object} Returns `object`.
13098     * @see _.forOwn
13099     * @example
13100     *
13101     * function Foo() {
13102     *   this.a = 1;
13103     *   this.b = 2;
13104     * }
13105     *
13106     * Foo.prototype.c = 3;
13107     *
13108     * _.forOwnRight(new Foo, function(value, key) {
13109     *   console.log(key);
13110     * });
13111     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
13112     */
13113    function forOwnRight(object, iteratee) {
13114      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
13115    }
13116
13117    /**
13118     * Creates an array of function property names from own enumerable properties
13119     * of `object`.
13120     *
13121     * @static
13122     * @since 0.1.0
13123     * @memberOf _
13124     * @category Object
13125     * @param {Object} object The object to inspect.
13126     * @returns {Array} Returns the function names.
13127     * @see _.functionsIn
13128     * @example
13129     *
13130     * function Foo() {
13131     *   this.a = _.constant('a');
13132     *   this.b = _.constant('b');
13133     * }
13134     *
13135     * Foo.prototype.c = _.constant('c');
13136     *
13137     * _.functions(new Foo);
13138     * // => ['a', 'b']
13139     */
13140    function functions(object) {
13141      return object == null ? [] : baseFunctions(object, keys(object));
13142    }
13143
13144    /**
13145     * Creates an array of function property names from own and inherited
13146     * enumerable properties of `object`.
13147     *
13148     * @static
13149     * @memberOf _
13150     * @since 4.0.0
13151     * @category Object
13152     * @param {Object} object The object to inspect.
13153     * @returns {Array} Returns the function names.
13154     * @see _.functions
13155     * @example
13156     *
13157     * function Foo() {
13158     *   this.a = _.constant('a');
13159     *   this.b = _.constant('b');
13160     * }
13161     *
13162     * Foo.prototype.c = _.constant('c');
13163     *
13164     * _.functionsIn(new Foo);
13165     * // => ['a', 'b', 'c']
13166     */
13167    function functionsIn(object) {
13168      return object == null ? [] : baseFunctions(object, keysIn(object));
13169    }
13170
13171    /**
13172     * Gets the value at `path` of `object`. If the resolved value is
13173     * `undefined`, the `defaultValue` is returned in its place.
13174     *
13175     * @static
13176     * @memberOf _
13177     * @since 3.7.0
13178     * @category Object
13179     * @param {Object} object The object to query.
13180     * @param {Array|string} path The path of the property to get.
13181     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13182     * @returns {*} Returns the resolved value.
13183     * @example
13184     *
13185     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13186     *
13187     * _.get(object, 'a[0].b.c');
13188     * // => 3
13189     *
13190     * _.get(object, ['a', '0', 'b', 'c']);
13191     * // => 3
13192     *
13193     * _.get(object, 'a.b.c', 'default');
13194     * // => 'default'
13195     */
13196    function get(object, path, defaultValue) {
13197      var result = object == null ? undefined : baseGet(object, path);
13198      return result === undefined ? defaultValue : result;
13199    }
13200
13201    /**
13202     * Checks if `path` is a direct property of `object`.
13203     *
13204     * @static
13205     * @since 0.1.0
13206     * @memberOf _
13207     * @category Object
13208     * @param {Object} object The object to query.
13209     * @param {Array|string} path The path to check.
13210     * @returns {boolean} Returns `true` if `path` exists, else `false`.
13211     * @example
13212     *
13213     * var object = { 'a': { 'b': 2 } };
13214     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
13215     *
13216     * _.has(object, 'a');
13217     * // => true
13218     *
13219     * _.has(object, 'a.b');
13220     * // => true
13221     *
13222     * _.has(object, ['a', 'b']);
13223     * // => true
13224     *
13225     * _.has(other, 'a');
13226     * // => false
13227     */
13228    function has(object, path) {
13229      return object != null && hasPath(object, path, baseHas);
13230    }
13231
13232    /**
13233     * Checks if `path` is a direct or inherited property of `object`.
13234     *
13235     * @static
13236     * @memberOf _
13237     * @since 4.0.0
13238     * @category Object
13239     * @param {Object} object The object to query.
13240     * @param {Array|string} path The path to check.
13241     * @returns {boolean} Returns `true` if `path` exists, else `false`.
13242     * @example
13243     *
13244     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
13245     *
13246     * _.hasIn(object, 'a');
13247     * // => true
13248     *
13249     * _.hasIn(object, 'a.b');
13250     * // => true
13251     *
13252     * _.hasIn(object, ['a', 'b']);
13253     * // => true
13254     *
13255     * _.hasIn(object, 'b');
13256     * // => false
13257     */
13258    function hasIn(object, path) {
13259      return object != null && hasPath(object, path, baseHasIn);
13260    }
13261
13262    /**
vendor: 11,848 bytes, lines 13263-13633
13263     * Creates an object composed of the inverted keys and values of `object`.
13264     * If `object` contains duplicate values, subsequent values overwrite
13265     * property assignments of previous values.
13266     *
13267     * @static
13268     * @memberOf _
13269     * @since 0.7.0
13270     * @category Object
13271     * @param {Object} object The object to invert.
13272     * @returns {Object} Returns the new inverted object.
13273     * @example
13274     *
13275     * var object = { 'a': 1, 'b': 2, 'c': 1 };
13276     *
13277     * _.invert(object);
13278     * // => { '1': 'c', '2': 'b' }
13279     */
13280    var invert = createInverter(function(result, value, key) {
13281      if (value != null &&
13282          typeof value.toString != 'function') {
13283        value = nativeObjectToString.call(value);
13284      }
13285
13286      result[value] = key;
13287    }, constant(identity));
13288
13289    /**
13290     * This method is like `_.invert` except that the inverted object is generated
13291     * from the results of running each element of `object` thru `iteratee`. The
13292     * corresponding inverted value of each inverted key is an array of keys
13293     * responsible for generating the inverted value. The iteratee is invoked
13294     * with one argument: (value).
13295     *
13296     * @static
13297     * @memberOf _
13298     * @since 4.1.0
13299     * @category Object
13300     * @param {Object} object The object to invert.
13301     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
13302     * @returns {Object} Returns the new inverted object.
13303     * @example
13304     *
13305     * var object = { 'a': 1, 'b': 2, 'c': 1 };
13306     *
13307     * _.invertBy(object);
13308     * // => { '1': ['a', 'c'], '2': ['b'] }
13309     *
13310     * _.invertBy(object, function(value) {
13311     *   return 'group' + value;
13312     * });
13313     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
13314     */
13315    var invertBy = createInverter(function(result, value, key) {
13316      if (value != null &&
13317          typeof value.toString != 'function') {
13318        value = nativeObjectToString.call(value);
13319      }
13320
13321      if (hasOwnProperty.call(result, value)) {
13322        result[value].push(key);
13323      } else {
13324        result[value] = [key];
13325      }
13326    }, getIteratee);
13327
13328    /**
13329     * Invokes the method at `path` of `object`.
13330     *
13331     * @static
13332     * @memberOf _
13333     * @since 4.0.0
13334     * @category Object
13335     * @param {Object} object The object to query.
13336     * @param {Array|string} path The path of the method to invoke.
13337     * @param {...*} [args] The arguments to invoke the method with.
13338     * @returns {*} Returns the result of the invoked method.
13339     * @example
13340     *
13341     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
13342     *
13343     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
13344     * // => [2, 3]
13345     */
13346    var invoke = baseRest(baseInvoke);
13347
13348    /**
13349     * Creates an array of the own enumerable property names of `object`.
13350     *
13351     * **Note:** Non-object values are coerced to objects. See the
13352     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13353     * for more details.
13354     *
13355     * @static
13356     * @since 0.1.0
13357     * @memberOf _
13358     * @category Object
13359     * @param {Object} object The object to query.
13360     * @returns {Array} Returns the array of property names.
13361     * @example
13362     *
13363     * function Foo() {
13364     *   this.a = 1;
13365     *   this.b = 2;
13366     * }
13367     *
13368     * Foo.prototype.c = 3;
13369     *
13370     * _.keys(new Foo);
13371     * // => ['a', 'b'] (iteration order is not guaranteed)
13372     *
13373     * _.keys('hi');
13374     * // => ['0', '1']
13375     */
13376    function keys(object) {
13377      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
13378    }
13379
13380    /**
13381     * Creates an array of the own and inherited enumerable property names of `object`.
13382     *
13383     * **Note:** Non-object values are coerced to objects.
13384     *
13385     * @static
13386     * @memberOf _
13387     * @since 3.0.0
13388     * @category Object
13389     * @param {Object} object The object to query.
13390     * @returns {Array} Returns the array of property names.
13391     * @example
13392     *
13393     * function Foo() {
13394     *   this.a = 1;
13395     *   this.b = 2;
13396     * }
13397     *
13398     * Foo.prototype.c = 3;
13399     *
13400     * _.keysIn(new Foo);
13401     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
13402     */
13403    function keysIn(object) {
13404      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
13405    }
13406
13407    /**
13408     * The opposite of `_.mapValues`; this method creates an object with the
13409     * same values as `object` and keys generated by running each own enumerable
13410     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
13411     * with three arguments: (value, key, object).
13412     *
13413     * @static
13414     * @memberOf _
13415     * @since 3.8.0
13416     * @category Object
13417     * @param {Object} object The object to iterate over.
13418     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13419     * @returns {Object} Returns the new mapped object.
13420     * @see _.mapValues
13421     * @example
13422     *
13423     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
13424     *   return key + value;
13425     * });
13426     * // => { 'a1': 1, 'b2': 2 }
13427     */
13428    function mapKeys(object, iteratee) {
13429      var result = {};
13430      iteratee = getIteratee(iteratee, 3);
13431
13432      baseForOwn(object, function(value, key, object) {
13433        baseAssignValue(result, iteratee(value, key, object), value);
13434      });
13435      return result;
13436    }
13437
13438    /**
13439     * Creates an object with the same keys as `object` and values generated
13440     * by running each own enumerable string keyed property of `object` thru
13441     * `iteratee`. The iteratee is invoked with three arguments:
13442     * (value, key, object).
13443     *
13444     * @static
13445     * @memberOf _
13446     * @since 2.4.0
13447     * @category Object
13448     * @param {Object} object The object to iterate over.
13449     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13450     * @returns {Object} Returns the new mapped object.
13451     * @see _.mapKeys
13452     * @example
13453     *
13454     * var users = {
13455     *   'fred':    { 'user': 'fred',    'age': 40 },
13456     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
13457     * };
13458     *
13459     * _.mapValues(users, function(o) { return o.age; });
13460     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13461     *
13462     * // The `_.property` iteratee shorthand.
13463     * _.mapValues(users, 'age');
13464     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13465     */
13466    function mapValues(object, iteratee) {
13467      var result = {};
13468      iteratee = getIteratee(iteratee, 3);
13469
13470      baseForOwn(object, function(value, key, object) {
13471        baseAssignValue(result, key, iteratee(value, key, object));
13472      });
13473      return result;
13474    }
13475
13476    /**
13477     * This method is like `_.assign` except that it recursively merges own and
13478     * inherited enumerable string keyed properties of source objects into the
13479     * destination object. Source properties that resolve to `undefined` are
13480     * skipped if a destination value exists. Array and plain object properties
13481     * are merged recursively. Other objects and value types are overridden by
13482     * assignment. Source objects are applied from left to right. Subsequent
13483     * sources overwrite property assignments of previous sources.
13484     *
13485     * **Note:** This method mutates `object`.
13486     *
13487     * @static
13488     * @memberOf _
13489     * @since 0.5.0
13490     * @category Object
13491     * @param {Object} object The destination object.
13492     * @param {...Object} [sources] The source objects.
13493     * @returns {Object} Returns `object`.
13494     * @example
13495     *
13496     * var object = {
13497     *   'a': [{ 'b': 2 }, { 'd': 4 }]
13498     * };
13499     *
13500     * var other = {
13501     *   'a': [{ 'c': 3 }, { 'e': 5 }]
13502     * };
13503     *
13504     * _.merge(object, other);
13505     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
13506     */
13507    var merge = createAssigner(function(object, source, srcIndex) {
13508      baseMerge(object, source, srcIndex);
13509    });
13510
13511    /**
13512     * This method is like `_.merge` except that it accepts `customizer` which
13513     * is invoked to produce the merged values of the destination and source
13514     * properties. If `customizer` returns `undefined`, merging is handled by the
13515     * method instead. The `customizer` is invoked with six arguments:
13516     * (objValue, srcValue, key, object, source, stack).
13517     *
13518     * **Note:** This method mutates `object`.
13519     *
13520     * @static
13521     * @memberOf _
13522     * @since 4.0.0
13523     * @category Object
13524     * @param {Object} object The destination object.
13525     * @param {...Object} sources The source objects.
13526     * @param {Function} customizer The function to customize assigned values.
13527     * @returns {Object} Returns `object`.
13528     * @example
13529     *
13530     * function customizer(objValue, srcValue) {
13531     *   if (_.isArray(objValue)) {
13532     *     return objValue.concat(srcValue);
13533     *   }
13534     * }
13535     *
13536     * var object = { 'a': [1], 'b': [2] };
13537     * var other = { 'a': [3], 'b': [4] };
13538     *
13539     * _.mergeWith(object, other, customizer);
13540     * // => { 'a': [1, 3], 'b': [2, 4] }
13541     */
13542    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
13543      baseMerge(object, source, srcIndex, customizer);
13544    });
13545
13546    /**
13547     * The opposite of `_.pick`; this method creates an object composed of the
13548     * own and inherited enumerable property paths of `object` that are not omitted.
13549     *
13550     * **Note:** This method is considerably slower than `_.pick`.
13551     *
13552     * @static
13553     * @since 0.1.0
13554     * @memberOf _
13555     * @category Object
13556     * @param {Object} object The source object.
13557     * @param {...(string|string[])} [paths] The property paths to omit.
13558     * @returns {Object} Returns the new object.
13559     * @example
13560     *
13561     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13562     *
13563     * _.omit(object, ['a', 'c']);
13564     * // => { 'b': '2' }
13565     */
13566    var omit = flatRest(function(object, paths) {
13567      var result = {};
13568      if (object == null) {
13569        return result;
13570      }
13571      var isDeep = false;
13572      paths = arrayMap(paths, function(path) {
13573        path = castPath(path, object);
13574        isDeep || (isDeep = path.length > 1);
13575        return path;
13576      });
13577      copyObject(object, getAllKeysIn(object), result);
13578      if (isDeep) {
13579        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
13580      }
13581      var length = paths.length;
13582      while (length--) {
13583        baseUnset(result, paths[length]);
13584      }
13585      return result;
13586    });
13587
13588    /**
13589     * The opposite of `_.pickBy`; this method creates an object composed of
13590     * the own and inherited enumerable string keyed properties of `object` that
13591     * `predicate` doesn't return truthy for. The predicate is invoked with two
13592     * arguments: (value, key).
13593     *
13594     * @static
13595     * @memberOf _
13596     * @since 4.0.0
13597     * @category Object
13598     * @param {Object} object The source object.
13599     * @param {Function} [predicate=_.identity] The function invoked per property.
13600     * @returns {Object} Returns the new object.
13601     * @example
13602     *
13603     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13604     *
13605     * _.omitBy(object, _.isNumber);
13606     * // => { 'b': '2' }
13607     */
13608    function omitBy(object, predicate) {
13609      return pickBy(object, negate(getIteratee(predicate)));
13610    }
13611
13612    /**
13613     * Creates an object composed of the picked `object` properties.
13614     *
13615     * @static
13616     * @since 0.1.0
13617     * @memberOf _
13618     * @category Object
13619     * @param {Object} object The source object.
13620     * @param {...(string|string[])} [paths] The property paths to pick.
13621     * @returns {Object} Returns the new object.
13622     * @example
13623     *
13624     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13625     *
13626     * _.pick(object, ['a', 'c']);
13627     * // => { 'a': 1, 'c': 3 }
13628     */
13629    var pick = flatRest(function(object, paths) {
13630      return object == null ? {} : basePick(object, paths);
13631    });
13632
13633    /**
vendor: 11,160 bytes, lines 13634-13972
13634     * Creates an object composed of the `object` properties `predicate` returns
13635     * truthy for. The predicate is invoked with two arguments: (value, key).
13636     *
13637     * @static
13638     * @memberOf _
13639     * @since 4.0.0
13640     * @category Object
13641     * @param {Object} object The source object.
13642     * @param {Function} [predicate=_.identity] The function invoked per property.
13643     * @returns {Object} Returns the new object.
13644     * @example
13645     *
13646     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13647     *
13648     * _.pickBy(object, _.isNumber);
13649     * // => { 'a': 1, 'c': 3 }
13650     */
13651    function pickBy(object, predicate) {
13652      if (object == null) {
13653        return {};
13654      }
13655      var props = arrayMap(getAllKeysIn(object), function(prop) {
13656        return [prop];
13657      });
13658      predicate = getIteratee(predicate);
13659      return basePickBy(object, props, function(value, path) {
13660        return predicate(value, path[0]);
13661      });
13662    }
13663
13664    /**
13665     * This method is like `_.get` except that if the resolved value is a
13666     * function it's invoked with the `this` binding of its parent object and
13667     * its result is returned.
13668     *
13669     * @static
13670     * @since 0.1.0
13671     * @memberOf _
13672     * @category Object
13673     * @param {Object} object The object to query.
13674     * @param {Array|string} path The path of the property to resolve.
13675     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13676     * @returns {*} Returns the resolved value.
13677     * @example
13678     *
13679     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
13680     *
13681     * _.result(object, 'a[0].b.c1');
13682     * // => 3
13683     *
13684     * _.result(object, 'a[0].b.c2');
13685     * // => 4
13686     *
13687     * _.result(object, 'a[0].b.c3', 'default');
13688     * // => 'default'
13689     *
13690     * _.result(object, 'a[0].b.c3', _.constant('default'));
13691     * // => 'default'
13692     */
13693    function result(object, path, defaultValue) {
13694      path = castPath(path, object);
13695
13696      var index = -1,
13697          length = path.length;
13698
13699      // Ensure the loop is entered when path is empty.
13700      if (!length) {
13701        length = 1;
13702        object = undefined;
13703      }
13704      while (++index < length) {
13705        var value = object == null ? undefined : object[toKey(path[index])];
13706        if (value === undefined) {
13707          index = length;
13708          value = defaultValue;
13709        }
13710        object = isFunction(value) ? value.call(object) : value;
13711      }
13712      return object;
13713    }
13714
13715    /**
13716     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
13717     * it's created. Arrays are created for missing index properties while objects
13718     * are created for all other missing properties. Use `_.setWith` to customize
13719     * `path` creation.
13720     *
13721     * **Note:** This method mutates `object`.
13722     *
13723     * @static
13724     * @memberOf _
13725     * @since 3.7.0
13726     * @category Object
13727     * @param {Object} object The object to modify.
13728     * @param {Array|string} path The path of the property to set.
13729     * @param {*} value The value to set.
13730     * @returns {Object} Returns `object`.
13731     * @example
13732     *
13733     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13734     *
13735     * _.set(object, 'a[0].b.c', 4);
13736     * console.log(object.a[0].b.c);
13737     * // => 4
13738     *
13739     * _.set(object, ['x', '0', 'y', 'z'], 5);
13740     * console.log(object.x[0].y.z);
13741     * // => 5
13742     */
13743    function set(object, path, value) {
13744      return object == null ? object : baseSet(object, path, value);
13745    }
13746
13747    /**
13748     * This method is like `_.set` except that it accepts `customizer` which is
13749     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13750     * path creation is handled by the method instead. The `customizer` is invoked
13751     * with three arguments: (nsValue, key, nsObject).
13752     *
13753     * **Note:** This method mutates `object`.
13754     *
13755     * @static
13756     * @memberOf _
13757     * @since 4.0.0
13758     * @category Object
13759     * @param {Object} object The object to modify.
13760     * @param {Array|string} path The path of the property to set.
13761     * @param {*} value The value to set.
13762     * @param {Function} [customizer] The function to customize assigned values.
13763     * @returns {Object} Returns `object`.
13764     * @example
13765     *
13766     * var object = {};
13767     *
13768     * _.setWith(object, '[0][1]', 'a', Object);
13769     * // => { '0': { '1': 'a' } }
13770     */
13771    function setWith(object, path, value, customizer) {
13772      customizer = typeof customizer == 'function' ? customizer : undefined;
13773      return object == null ? object : baseSet(object, path, value, customizer);
13774    }
13775
13776    /**
13777     * Creates an array of own enumerable string keyed-value pairs for `object`
13778     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13779     * entries are returned.
13780     *
13781     * @static
13782     * @memberOf _
13783     * @since 4.0.0
13784     * @alias entries
13785     * @category Object
13786     * @param {Object} object The object to query.
13787     * @returns {Array} Returns the key-value pairs.
13788     * @example
13789     *
13790     * function Foo() {
13791     *   this.a = 1;
13792     *   this.b = 2;
13793     * }
13794     *
13795     * Foo.prototype.c = 3;
13796     *
13797     * _.toPairs(new Foo);
13798     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13799     */
13800    var toPairs = createToPairs(keys);
13801
13802    /**
13803     * Creates an array of own and inherited enumerable string keyed-value pairs
13804     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13805     * or set, its entries are returned.
13806     *
13807     * @static
13808     * @memberOf _
13809     * @since 4.0.0
13810     * @alias entriesIn
13811     * @category Object
13812     * @param {Object} object The object to query.
13813     * @returns {Array} Returns the key-value pairs.
13814     * @example
13815     *
13816     * function Foo() {
13817     *   this.a = 1;
13818     *   this.b = 2;
13819     * }
13820     *
13821     * Foo.prototype.c = 3;
13822     *
13823     * _.toPairsIn(new Foo);
13824     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13825     */
13826    var toPairsIn = createToPairs(keysIn);
13827
13828    /**
13829     * An alternative to `_.reduce`; this method transforms `object` to a new
13830     * `accumulator` object which is the result of running each of its own
13831     * enumerable string keyed properties thru `iteratee`, with each invocation
13832     * potentially mutating the `accumulator` object. If `accumulator` is not
13833     * provided, a new object with the same `[[Prototype]]` will be used. The
13834     * iteratee is invoked with four arguments: (accumulator, value, key, object).
13835     * Iteratee functions may exit iteration early by explicitly returning `false`.
13836     *
13837     * @static
13838     * @memberOf _
13839     * @since 1.3.0
13840     * @category Object
13841     * @param {Object} object The object to iterate over.
13842     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13843     * @param {*} [accumulator] The custom accumulator value.
13844     * @returns {*} Returns the accumulated value.
13845     * @example
13846     *
13847     * _.transform([2, 3, 4], function(result, n) {
13848     *   result.push(n *= n);
13849     *   return n % 2 == 0;
13850     * }, []);
13851     * // => [4, 9]
13852     *
13853     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13854     *   (result[value] || (result[value] = [])).push(key);
13855     * }, {});
13856     * // => { '1': ['a', 'c'], '2': ['b'] }
13857     */
13858    function transform(object, iteratee, accumulator) {
13859      var isArr = isArray(object),
13860          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
13861
13862      iteratee = getIteratee(iteratee, 4);
13863      if (accumulator == null) {
13864        var Ctor = object && object.constructor;
13865        if (isArrLike) {
13866          accumulator = isArr ? new Ctor : [];
13867        }
13868        else if (isObject(object)) {
13869          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13870        }
13871        else {
13872          accumulator = {};
13873        }
13874      }
13875      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
13876        return iteratee(accumulator, value, index, object);
13877      });
13878      return accumulator;
13879    }
13880
13881    /**
13882     * Removes the property at `path` of `object`.
13883     *
13884     * **Note:** This method mutates `object`.
13885     *
13886     * @static
13887     * @memberOf _
13888     * @since 4.0.0
13889     * @category Object
13890     * @param {Object} object The object to modify.
13891     * @param {Array|string} path The path of the property to unset.
13892     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13893     * @example
13894     *
13895     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13896     * _.unset(object, 'a[0].b.c');
13897     * // => true
13898     *
13899     * console.log(object);
13900     * // => { 'a': [{ 'b': {} }] };
13901     *
13902     * _.unset(object, ['a', '0', 'b', 'c']);
13903     * // => true
13904     *
13905     * console.log(object);
13906     * // => { 'a': [{ 'b': {} }] };
13907     */
13908    function unset(object, path) {
13909      return object == null ? true : baseUnset(object, path);
13910    }
13911
13912    /**
13913     * This method is like `_.set` except that accepts `updater` to produce the
13914     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13915     * is invoked with one argument: (value).
13916     *
13917     * **Note:** This method mutates `object`.
13918     *
13919     * @static
13920     * @memberOf _
13921     * @since 4.6.0
13922     * @category Object
13923     * @param {Object} object The object to modify.
13924     * @param {Array|string} path The path of the property to set.
13925     * @param {Function} updater The function to produce the updated value.
13926     * @returns {Object} Returns `object`.
13927     * @example
13928     *
13929     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13930     *
13931     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13932     * console.log(object.a[0].b.c);
13933     * // => 9
13934     *
13935     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13936     * console.log(object.x[0].y.z);
13937     * // => 0
13938     */
13939    function update(object, path, updater) {
13940      return object == null ? object : baseUpdate(object, path, castFunction(updater));
13941    }
13942
13943    /**
13944     * This method is like `_.update` except that it accepts `customizer` which is
13945     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13946     * path creation is handled by the method instead. The `customizer` is invoked
13947     * with three arguments: (nsValue, key, nsObject).
13948     *
13949     * **Note:** This method mutates `object`.
13950     *
13951     * @static
13952     * @memberOf _
13953     * @since 4.6.0
13954     * @category Object
13955     * @param {Object} object The object to modify.
13956     * @param {Array|string} path The path of the property to set.
13957     * @param {Function} updater The function to produce the updated value.
13958     * @param {Function} [customizer] The function to customize assigned values.
13959     * @returns {Object} Returns `object`.
13960     * @example
13961     *
13962     * var object = {};
13963     *
13964     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13965     * // => { '0': { '1': 'a' } }
13966     */
13967    function updateWith(object, path, updater, customizer) {
13968      customizer = typeof customizer == 'function' ? customizer : undefined;
13969      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13970    }
13971
13972    /**
vendor: 1,263 bytes, lines 13973-14022
13973     * Creates an array of the own enumerable string keyed property values of `object`.
13974     *
13975     * **Note:** Non-object values are coerced to objects.
13976     *
13977     * @static
13978     * @since 0.1.0
13979     * @memberOf _
13980     * @category Object
13981     * @param {Object} object The object to query.
13982     * @returns {Array} Returns the array of property values.
13983     * @example
13984     *
13985     * function Foo() {
13986     *   this.a = 1;
13987     *   this.b = 2;
13988     * }
13989     *
13990     * Foo.prototype.c = 3;
13991     *
13992     * _.values(new Foo);
13993     * // => [1, 2] (iteration order is not guaranteed)
13994     *
13995     * _.values('hi');
13996     * // => ['h', 'i']
13997     */
13998    function values(object) {
13999      return object == null ? [] : baseValues(object, keys(object));
14000    }
14001
14002    /**
14003     * Creates an array of the own and inherited enumerable string keyed property
14004     * values of `object`.
14005     *
14006     * **Note:** Non-object values are coerced to objects.
14007     *
14008     * @static
14009     * @memberOf _
14010     * @since 3.0.0
14011     * @category Object
14012     * @param {Object} object The object to query.
14013     * @returns {Array} Returns the array of property values.
14014     * @example
14015     *
14016     * function Foo() {
14017     *   this.a = 1;
14018     *   this.b = 2;
14019     * }
14020     *
14021     * Foo.prototype.c = 3;
14022     *
vendor: 9,679 bytes, lines 14023-14343
14023     * _.valuesIn(new Foo);
14024     * // => [1, 2, 3] (iteration order is not guaranteed)
14025     */
14026    function valuesIn(object) {
14027      return object == null ? [] : baseValues(object, keysIn(object));
14028    }
14029
14030    /*------------------------------------------------------------------------*/
14031
14032    /**
14033     * Clamps `number` within the inclusive `lower` and `upper` bounds.
14034     *
14035     * @static
14036     * @memberOf _
14037     * @since 4.0.0
14038     * @category Number
14039     * @param {number} number The number to clamp.
14040     * @param {number} [lower] The lower bound.
14041     * @param {number} upper The upper bound.
14042     * @returns {number} Returns the clamped number.
14043     * @example
14044     *
14045     * _.clamp(-10, -5, 5);
14046     * // => -5
14047     *
14048     * _.clamp(10, -5, 5);
14049     * // => 5
14050     */
14051    function clamp(number, lower, upper) {
14052      if (upper === undefined) {
14053        upper = lower;
14054        lower = undefined;
14055      }
14056      if (upper !== undefined) {
14057        upper = toNumber(upper);
14058        upper = upper === upper ? upper : 0;
14059      }
14060      if (lower !== undefined) {
14061        lower = toNumber(lower);
14062        lower = lower === lower ? lower : 0;
14063      }
14064      return baseClamp(toNumber(number), lower, upper);
14065    }
14066
14067    /**
14068     * Checks if `n` is between `start` and up to, but not including, `end`. If
14069     * `end` is not specified, it's set to `start` with `start` then set to `0`.
14070     * If `start` is greater than `end` the params are swapped to support
14071     * negative ranges.
14072     *
14073     * @static
14074     * @memberOf _
14075     * @since 3.3.0
14076     * @category Number
14077     * @param {number} number The number to check.
14078     * @param {number} [start=0] The start of the range.
14079     * @param {number} end The end of the range.
14080     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
14081     * @see _.range, _.rangeRight
14082     * @example
14083     *
14084     * _.inRange(3, 2, 4);
14085     * // => true
14086     *
14087     * _.inRange(4, 8);
14088     * // => true
14089     *
14090     * _.inRange(4, 2);
14091     * // => false
14092     *
14093     * _.inRange(2, 2);
14094     * // => false
14095     *
14096     * _.inRange(1.2, 2);
14097     * // => true
14098     *
14099     * _.inRange(5.2, 4);
14100     * // => false
14101     *
14102     * _.inRange(-3, -2, -6);
14103     * // => true
14104     */
14105    function inRange(number, start, end) {
14106      start = toFinite(start);
14107      if (end === undefined) {
14108        end = start;
14109        start = 0;
14110      } else {
14111        end = toFinite(end);
14112      }
14113      number = toNumber(number);
14114      return baseInRange(number, start, end);
14115    }
14116
14117    /**
14118     * Produces a random number between the inclusive `lower` and `upper` bounds.
14119     * If only one argument is provided a number between `0` and the given number
14120     * is returned. If `floating` is `true`, or either `lower` or `upper` are
14121     * floats, a floating-point number is returned instead of an integer.
14122     *
14123     * **Note:** JavaScript follows the IEEE-754 standard for resolving
14124     * floating-point values which can produce unexpected results.
14125     *
14126     * @static
14127     * @memberOf _
14128     * @since 0.7.0
14129     * @category Number
14130     * @param {number} [lower=0] The lower bound.
14131     * @param {number} [upper=1] The upper bound.
14132     * @param {boolean} [floating] Specify returning a floating-point number.
14133     * @returns {number} Returns the random number.
14134     * @example
14135     *
14136     * _.random(0, 5);
14137     * // => an integer between 0 and 5
14138     *
14139     * _.random(5);
14140     * // => also an integer between 0 and 5
14141     *
14142     * _.random(5, true);
14143     * // => a floating-point number between 0 and 5
14144     *
14145     * _.random(1.2, 5.2);
14146     * // => a floating-point number between 1.2 and 5.2
14147     */
14148    function random(lower, upper, floating) {
14149      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
14150        upper = floating = undefined;
14151      }
14152      if (floating === undefined) {
14153        if (typeof upper == 'boolean') {
14154          floating = upper;
14155          upper = undefined;
14156        }
14157        else if (typeof lower == 'boolean') {
14158          floating = lower;
14159          lower = undefined;
14160        }
14161      }
14162      if (lower === undefined && upper === undefined) {
14163        lower = 0;
14164        upper = 1;
14165      }
14166      else {
14167        lower = toFinite(lower);
14168        if (upper === undefined) {
14169          upper = lower;
14170          lower = 0;
14171        } else {
14172          upper = toFinite(upper);
14173        }
14174      }
14175      if (lower > upper) {
14176        var temp = lower;
14177        lower = upper;
14178        upper = temp;
14179      }
14180      if (floating || lower % 1 || upper % 1) {
14181        var rand = nativeRandom();
14182        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
14183      }
14184      return baseRandom(lower, upper);
14185    }
14186
14187    /*------------------------------------------------------------------------*/
14188
14189    /**
14190     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
14191     *
14192     * @static
14193     * @memberOf _
14194     * @since 3.0.0
14195     * @category String
14196     * @param {string} [string=''] The string to convert.
14197     * @returns {string} Returns the camel cased string.
14198     * @example
14199     *
14200     * _.camelCase('Foo Bar');
14201     * // => 'fooBar'
14202     *
14203     * _.camelCase('--foo-bar--');
14204     * // => 'fooBar'
14205     *
14206     * _.camelCase('__FOO_BAR__');
14207     * // => 'fooBar'
14208     */
14209    var camelCase = createCompounder(function(result, word, index) {
14210      word = word.toLowerCase();
14211      return result + (index ? capitalize(word) : word);
14212    });
14213
14214    /**
14215     * Converts the first character of `string` to upper case and the remaining
14216     * to lower case.
14217     *
14218     * @static
14219     * @memberOf _
14220     * @since 3.0.0
14221     * @category String
14222     * @param {string} [string=''] The string to capitalize.
14223     * @returns {string} Returns the capitalized string.
14224     * @example
14225     *
14226     * _.capitalize('FRED');
14227     * // => 'Fred'
14228     */
14229    function capitalize(string) {
14230      return upperFirst(toString(string).toLowerCase());
14231    }
14232
14233    /**
14234     * Deburrs `string` by converting
14235     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
14236     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
14237     * letters to basic Latin letters and removing
14238     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
14239     *
14240     * @static
14241     * @memberOf _
14242     * @since 3.0.0
14243     * @category String
14244     * @param {string} [string=''] The string to deburr.
14245     * @returns {string} Returns the deburred string.
14246     * @example
14247     *
14248     * _.deburr('déjà vu');
14249     * // => 'deja vu'
14250     */
14251    function deburr(string) {
14252      string = toString(string);
14253      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
14254    }
14255
14256    /**
14257     * Checks if `string` ends with the given target string.
14258     *
14259     * @static
14260     * @memberOf _
14261     * @since 3.0.0
14262     * @category String
14263     * @param {string} [string=''] The string to inspect.
14264     * @param {string} [target] The string to search for.
14265     * @param {number} [position=string.length] The position to search up to.
14266     * @returns {boolean} Returns `true` if `string` ends with `target`,
14267     *  else `false`.
14268     * @example
14269     *
14270     * _.endsWith('abc', 'c');
14271     * // => true
14272     *
14273     * _.endsWith('abc', 'b');
14274     * // => false
14275     *
14276     * _.endsWith('abc', 'b', 2);
14277     * // => true
14278     */
14279    function endsWith(string, target, position) {
14280      string = toString(string);
14281      target = baseToString(target);
14282
14283      var length = string.length;
14284      position = position === undefined
14285        ? length
14286        : baseClamp(toInteger(position), 0, length);
14287
14288      var end = position;
14289      position -= target.length;
14290      return position >= 0 && string.slice(position, end) == target;
14291    }
14292
14293    /**
14294     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
14295     * corresponding HTML entities.
14296     *
14297     * **Note:** No other characters are escaped. To escape additional
14298     * characters use a third-party library like [_he_](https://mths.be/he).
14299     *
14300     * Though the ">" character is escaped for symmetry, characters like
14301     * ">" and "/" don't need escaping in HTML and have no special meaning
14302     * unless they're part of a tag or unquoted attribute value. See
14303     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
14304     * (under "semi-related fun fact") for more details.
14305     *
14306     * When working with HTML you should always
14307     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
14308     * XSS vectors.
14309     *
14310     * @static
14311     * @since 0.1.0
14312     * @memberOf _
14313     * @category String
14314     * @param {string} [string=''] The string to escape.
14315     * @returns {string} Returns the escaped string.
14316     * @example
14317     *
14318     * _.escape('fred, barney, & pebbles');
14319     * // => 'fred, barney, &amp; pebbles'
14320     */
14321    function escape(string) {
14322      string = toString(string);
14323      return (string && reHasUnescapedHtml.test(string))
14324        ? string.replace(reUnescapedHtml, escapeHtmlChar)
14325        : string;
14326    }
14327
14328    /**
14329     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
14330     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
14331     *
14332     * @static
14333     * @memberOf _
14334     * @since 3.0.0
14335     * @category String
14336     * @param {string} [string=''] The string to escape.
14337     * @returns {string} Returns the escaped string.
14338     * @example
14339     *
14340     * _.escapeRegExp('[lodash](https://lodash.com/)');
14341     * // => '\[lodash\]\(https://lodash\.com/\)'
14342     */
14343    function escapeRegExp(string) {
vendor: 4,658 bytes, lines 14344-14513
14344      string = toString(string);
14345      return (string && reHasRegExpChar.test(string))
14346        ? string.replace(reRegExpChar, '\\$&')
14347        : string;
14348    }
14349
14350    /**
14351     * Converts `string` to
14352     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
14353     *
14354     * @static
14355     * @memberOf _
14356     * @since 3.0.0
14357     * @category String
14358     * @param {string} [string=''] The string to convert.
14359     * @returns {string} Returns the kebab cased string.
14360     * @example
14361     *
14362     * _.kebabCase('Foo Bar');
14363     * // => 'foo-bar'
14364     *
14365     * _.kebabCase('fooBar');
14366     * // => 'foo-bar'
14367     *
14368     * _.kebabCase('__FOO_BAR__');
14369     * // => 'foo-bar'
14370     */
14371    var kebabCase = createCompounder(function(result, word, index) {
14372      return result + (index ? '-' : '') + word.toLowerCase();
14373    });
14374
14375    /**
14376     * Converts `string`, as space separated words, to lower case.
14377     *
14378     * @static
14379     * @memberOf _
14380     * @since 4.0.0
14381     * @category String
14382     * @param {string} [string=''] The string to convert.
14383     * @returns {string} Returns the lower cased string.
14384     * @example
14385     *
14386     * _.lowerCase('--Foo-Bar--');
14387     * // => 'foo bar'
14388     *
14389     * _.lowerCase('fooBar');
14390     * // => 'foo bar'
14391     *
14392     * _.lowerCase('__FOO_BAR__');
14393     * // => 'foo bar'
14394     */
14395    var lowerCase = createCompounder(function(result, word, index) {
14396      return result + (index ? ' ' : '') + word.toLowerCase();
14397    });
14398
14399    /**
14400     * Converts the first character of `string` to lower case.
14401     *
14402     * @static
14403     * @memberOf _
14404     * @since 4.0.0
14405     * @category String
14406     * @param {string} [string=''] The string to convert.
14407     * @returns {string} Returns the converted string.
14408     * @example
14409     *
14410     * _.lowerFirst('Fred');
14411     * // => 'fred'
14412     *
14413     * _.lowerFirst('FRED');
14414     * // => 'fRED'
14415     */
14416    var lowerFirst = createCaseFirst('toLowerCase');
14417
14418    /**
14419     * Pads `string` on the left and right sides if it's shorter than `length`.
14420     * Padding characters are truncated if they can't be evenly divided by `length`.
14421     *
14422     * @static
14423     * @memberOf _
14424     * @since 3.0.0
14425     * @category String
14426     * @param {string} [string=''] The string to pad.
14427     * @param {number} [length=0] The padding length.
14428     * @param {string} [chars=' '] The string used as padding.
14429     * @returns {string} Returns the padded string.
14430     * @example
14431     *
14432     * _.pad('abc', 8);
14433     * // => '  abc   '
14434     *
14435     * _.pad('abc', 8, '_-');
14436     * // => '_-abc_-_'
14437     *
14438     * _.pad('abc', 3);
14439     * // => 'abc'
14440     */
14441    function pad(string, length, chars) {
14442      string = toString(string);
14443      length = toInteger(length);
14444
14445      var strLength = length ? stringSize(string) : 0;
14446      if (!length || strLength >= length) {
14447        return string;
14448      }
14449      var mid = (length - strLength) / 2;
14450      return (
14451        createPadding(nativeFloor(mid), chars) +
14452        string +
14453        createPadding(nativeCeil(mid), chars)
14454      );
14455    }
14456
14457    /**
14458     * Pads `string` on the right side if it's shorter than `length`. Padding
14459     * characters are truncated if they exceed `length`.
14460     *
14461     * @static
14462     * @memberOf _
14463     * @since 4.0.0
14464     * @category String
14465     * @param {string} [string=''] The string to pad.
14466     * @param {number} [length=0] The padding length.
14467     * @param {string} [chars=' '] The string used as padding.
14468     * @returns {string} Returns the padded string.
14469     * @example
14470     *
14471     * _.padEnd('abc', 6);
14472     * // => 'abc   '
14473     *
14474     * _.padEnd('abc', 6, '_-');
14475     * // => 'abc_-_'
14476     *
14477     * _.padEnd('abc', 3);
14478     * // => 'abc'
14479     */
14480    function padEnd(string, length, chars) {
14481      string = toString(string);
14482      length = toInteger(length);
14483
14484      var strLength = length ? stringSize(string) : 0;
14485      return (length && strLength < length)
14486        ? (string + createPadding(length - strLength, chars))
14487        : string;
14488    }
14489
14490    /**
14491     * Pads `string` on the left side if it's shorter than `length`. Padding
14492     * characters are truncated if they exceed `length`.
14493     *
14494     * @static
14495     * @memberOf _
14496     * @since 4.0.0
14497     * @category String
14498     * @param {string} [string=''] The string to pad.
14499     * @param {number} [length=0] The padding length.
14500     * @param {string} [chars=' '] The string used as padding.
14501     * @returns {string} Returns the padded string.
14502     * @example
14503     *
14504     * _.padStart('abc', 6);
14505     * // => '   abc'
14506     *
14507     * _.padStart('abc', 6, '_-');
14508     * // => '_-_abc'
14509     *
14510     * _.padStart('abc', 3);
14511     * // => 'abc'
14512     */
14513    function padStart(string, length, chars) {
vendor: 29,827 bytes, lines 14514-15411
14514      string = toString(string);
14515      length = toInteger(length);
14516
14517      var strLength = length ? stringSize(string) : 0;
14518      return (length && strLength < length)
14519        ? (createPadding(length - strLength, chars) + string)
14520        : string;
14521    }
14522
14523    /**
14524     * Converts `string` to an integer of the specified radix. If `radix` is
14525     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
14526     * hexadecimal, in which case a `radix` of `16` is used.
14527     *
14528     * **Note:** This method aligns with the
14529     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
14530     *
14531     * @static
14532     * @memberOf _
14533     * @since 1.1.0
14534     * @category String
14535     * @param {string} string The string to convert.
14536     * @param {number} [radix=10] The radix to interpret `value` by.
14537     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14538     * @returns {number} Returns the converted integer.
14539     * @example
14540     *
14541     * _.parseInt('08');
14542     * // => 8
14543     *
14544     * _.map(['6', '08', '10'], _.parseInt);
14545     * // => [6, 8, 10]
14546     */
14547    function parseInt(string, radix, guard) {
14548      if (guard || radix == null) {
14549        radix = 0;
14550      } else if (radix) {
14551        radix = +radix;
14552      }
14553      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
14554    }
14555
14556    /**
14557     * Repeats the given string `n` times.
14558     *
14559     * @static
14560     * @memberOf _
14561     * @since 3.0.0
14562     * @category String
14563     * @param {string} [string=''] The string to repeat.
14564     * @param {number} [n=1] The number of times to repeat the string.
14565     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14566     * @returns {string} Returns the repeated string.
14567     * @example
14568     *
14569     * _.repeat('*', 3);
14570     * // => '***'
14571     *
14572     * _.repeat('abc', 2);
14573     * // => 'abcabc'
14574     *
14575     * _.repeat('abc', 0);
14576     * // => ''
14577     */
14578    function repeat(string, n, guard) {
14579      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
14580        n = 1;
14581      } else {
14582        n = toInteger(n);
14583      }
14584      return baseRepeat(toString(string), n);
14585    }
14586
14587    /**
14588     * Replaces matches for `pattern` in `string` with `replacement`.
14589     *
14590     * **Note:** This method is based on
14591     * [`String#replace`](https://mdn.io/String/replace).
14592     *
14593     * @static
14594     * @memberOf _
14595     * @since 4.0.0
14596     * @category String
14597     * @param {string} [string=''] The string to modify.
14598     * @param {RegExp|string} pattern The pattern to replace.
14599     * @param {Function|string} replacement The match replacement.
14600     * @returns {string} Returns the modified string.
14601     * @example
14602     *
14603     * _.replace('Hi Fred', 'Fred', 'Barney');
14604     * // => 'Hi Barney'
14605     */
14606    function replace() {
14607      var args = arguments,
14608          string = toString(args[0]);
14609
14610      return args.length < 3 ? string : string.replace(args[1], args[2]);
14611    }
14612
14613    /**
14614     * Converts `string` to
14615     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
14616     *
14617     * @static
14618     * @memberOf _
14619     * @since 3.0.0
14620     * @category String
14621     * @param {string} [string=''] The string to convert.
14622     * @returns {string} Returns the snake cased string.
14623     * @example
14624     *
14625     * _.snakeCase('Foo Bar');
14626     * // => 'foo_bar'
14627     *
14628     * _.snakeCase('fooBar');
14629     * // => 'foo_bar'
14630     *
14631     * _.snakeCase('--FOO-BAR--');
14632     * // => 'foo_bar'
14633     */
14634    var snakeCase = createCompounder(function(result, word, index) {
14635      return result + (index ? '_' : '') + word.toLowerCase();
14636    });
14637
14638    /**
14639     * Splits `string` by `separator`.
14640     *
14641     * **Note:** This method is based on
14642     * [`String#split`](https://mdn.io/String/split).
14643     *
14644     * @static
14645     * @memberOf _
14646     * @since 4.0.0
14647     * @category String
14648     * @param {string} [string=''] The string to split.
14649     * @param {RegExp|string} separator The separator pattern to split by.
14650     * @param {number} [limit] The length to truncate results to.
14651     * @returns {Array} Returns the string segments.
14652     * @example
14653     *
14654     * _.split('a-b-c', '-', 2);
14655     * // => ['a', 'b']
14656     */
14657    function split(string, separator, limit) {
14658      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
14659        separator = limit = undefined;
14660      }
14661      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
14662      if (!limit) {
14663        return [];
14664      }
14665      string = toString(string);
14666      if (string && (
14667            typeof separator == 'string' ||
14668            (separator != null && !isRegExp(separator))
14669          )) {
14670        separator = baseToString(separator);
14671        if (!separator && hasUnicode(string)) {
14672          return castSlice(stringToArray(string), 0, limit);
14673        }
14674      }
14675      return string.split(separator, limit);
14676    }
14677
14678    /**
14679     * Converts `string` to
14680     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
14681     *
14682     * @static
14683     * @memberOf _
14684     * @since 3.1.0
14685     * @category String
14686     * @param {string} [string=''] The string to convert.
14687     * @returns {string} Returns the start cased string.
14688     * @example
14689     *
14690     * _.startCase('--foo-bar--');
14691     * // => 'Foo Bar'
14692     *
14693     * _.startCase('fooBar');
14694     * // => 'Foo Bar'
14695     *
14696     * _.startCase('__FOO_BAR__');
14697     * // => 'FOO BAR'
14698     */
14699    var startCase = createCompounder(function(result, word, index) {
14700      return result + (index ? ' ' : '') + upperFirst(word);
14701    });
14702
14703    /**
14704     * Checks if `string` starts with the given target string.
14705     *
14706     * @static
14707     * @memberOf _
14708     * @since 3.0.0
14709     * @category String
14710     * @param {string} [string=''] The string to inspect.
14711     * @param {string} [target] The string to search for.
14712     * @param {number} [position=0] The position to search from.
14713     * @returns {boolean} Returns `true` if `string` starts with `target`,
14714     *  else `false`.
14715     * @example
14716     *
14717     * _.startsWith('abc', 'a');
14718     * // => true
14719     *
14720     * _.startsWith('abc', 'b');
14721     * // => false
14722     *
14723     * _.startsWith('abc', 'b', 1);
14724     * // => true
14725     */
14726    function startsWith(string, target, position) {
14727      string = toString(string);
14728      position = position == null
14729        ? 0
14730        : baseClamp(toInteger(position), 0, string.length);
14731
14732      target = baseToString(target);
14733      return string.slice(position, position + target.length) == target;
14734    }
14735
14736    /**
14737     * Creates a compiled template function that can interpolate data properties
14738     * in "interpolate" delimiters, HTML-escape interpolated data properties in
14739     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
14740     * properties may be accessed as free variables in the template. If a setting
14741     * object is given, it takes precedence over `_.templateSettings` values.
14742     *
14743     * **Note:** In the development build `_.template` utilizes
14744     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14745     * for easier debugging.
14746     *
14747     * For more information on precompiling templates see
14748     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14749     *
14750     * For more information on Chrome extension sandboxes see
14751     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14752     *
14753     * @static
14754     * @since 0.1.0
14755     * @memberOf _
14756     * @category String
14757     * @param {string} [string=''] The template string.
14758     * @param {Object} [options={}] The options object.
14759     * @param {RegExp} [options.escape=_.templateSettings.escape]
14760     *  The HTML "escape" delimiter.
14761     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14762     *  The "evaluate" delimiter.
14763     * @param {Object} [options.imports=_.templateSettings.imports]
14764     *  An object to import into the template as free variables.
14765     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14766     *  The "interpolate" delimiter.
14767     * @param {string} [options.sourceURL='lodash.templateSources[n]']
14768     *  The sourceURL of the compiled template.
14769     * @param {string} [options.variable='obj']
14770     *  The data object variable name.
14771     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14772     * @returns {Function} Returns the compiled template function.
14773     * @example
14774     *
14775     * // Use the "interpolate" delimiter to create a compiled template.
14776     * var compiled = _.template('hello <%= user %>!');
14777     * compiled({ 'user': 'fred' });
14778     * // => 'hello fred!'
14779     *
14780     * // Use the HTML "escape" delimiter to escape data property values.
14781     * var compiled = _.template('<b><%- value %></b>');
14782     * compiled({ 'value': '<script>' });
14783     * // => '<b>&lt;script&gt;</b>'
14784     *
14785     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14786     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14787     * compiled({ 'users': ['fred', 'barney'] });
14788     * // => '<li>fred</li><li>barney</li>'
14789     *
14790     * // Use the internal `print` function in "evaluate" delimiters.
14791     * var compiled = _.template('<% print("hello " + user); %>!');
14792     * compiled({ 'user': 'barney' });
14793     * // => 'hello barney!'
14794     *
14795     * // Use the ES template literal delimiter as an "interpolate" delimiter.
14796     * // Disable support by replacing the "interpolate" delimiter.
14797     * var compiled = _.template('hello ${ user }!');
14798     * compiled({ 'user': 'pebbles' });
14799     * // => 'hello pebbles!'
14800     *
14801     * // Use backslashes to treat delimiters as plain text.
14802     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14803     * compiled({ 'value': 'ignored' });
14804     * // => '<%- value %>'
14805     *
14806     * // Use the `imports` option to import `jQuery` as `jq`.
14807     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14808     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14809     * compiled({ 'users': ['fred', 'barney'] });
14810     * // => '<li>fred</li><li>barney</li>'
14811     *
14812     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14813     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14814     * compiled(data);
14815     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14816     *
14817     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14818     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14819     * compiled.source;
14820     * // => function(data) {
14821     * //   var __t, __p = '';
14822     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14823     * //   return __p;
14824     * // }
14825     *
14826     * // Use custom template delimiters.
14827     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14828     * var compiled = _.template('hello {{ user }}!');
14829     * compiled({ 'user': 'mustache' });
14830     * // => 'hello mustache!'
14831     *
14832     * // Use the `source` property to inline compiled templates for meaningful
14833     * // line numbers in error messages and stack traces.
14834     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14835     *   var JST = {\
14836     *     "main": ' + _.template(mainText).source + '\
14837     *   };\
14838     * ');
14839     */
14840    function template(string, options, guard) {
14841      // Based on John Resig's `tmpl` implementation
14842      // (http://ejohn.org/blog/javascript-micro-templating/)
14843      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14844      var settings = lodash.templateSettings;
14845
14846      if (guard && isIterateeCall(string, options, guard)) {
14847        options = undefined;
14848      }
14849      string = toString(string);
14850      options = assignInWith({}, options, settings, customDefaultsAssignIn);
14851
14852      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
14853          importsKeys = keys(imports),
14854          importsValues = baseValues(imports, importsKeys);
14855
14856      var isEscaping,
14857          isEvaluating,
14858          index = 0,
14859          interpolate = options.interpolate || reNoMatch,
14860          source = "__p += '";
14861
14862      // Compile the regexp to match each delimiter.
14863      var reDelimiters = RegExp(
14864        (options.escape || reNoMatch).source + '|' +
14865        interpolate.source + '|' +
14866        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14867        (options.evaluate || reNoMatch).source + '|$'
14868      , 'g');
14869
14870      // Use a sourceURL for easier debugging.
14871      // The sourceURL gets injected into the source that's eval-ed, so be careful
14872      // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
14873      // and escape the comment, thus injecting code that gets evaled.
14874      var sourceURL = '//# sourceURL=' +
14875        (hasOwnProperty.call(options, 'sourceURL')
14876          ? (options.sourceURL + '').replace(/\s/g, ' ')
14877          : ('lodash.templateSources[' + (++templateCounter) + ']')
14878        ) + '\n';
14879
14880      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14881        interpolateValue || (interpolateValue = esTemplateValue);
14882
14883        // Escape characters that can't be included in string literals.
14884        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14885
14886        // Replace delimiters with snippets.
14887        if (escapeValue) {
14888          isEscaping = true;
14889          source += "' +\n__e(" + escapeValue + ") +\n'";
14890        }
14891        if (evaluateValue) {
14892          isEvaluating = true;
14893          source += "';\n" + evaluateValue + ";\n__p += '";
14894        }
14895        if (interpolateValue) {
14896          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14897        }
14898        index = offset + match.length;
14899
14900        // The JS engine embedded in Adobe products needs `match` returned in
14901        // order to produce the correct `offset` value.
14902        return match;
14903      });
14904
14905      source += "';\n";
14906
14907      // If `variable` is not specified wrap a with-statement around the generated
14908      // code to add the data object to the top of the scope chain.
14909      var variable = hasOwnProperty.call(options, 'variable') && options.variable;
14910      if (!variable) {
14911        source = 'with (obj) {\n' + source + '\n}\n';
14912      }
14913      // Throw an error if a forbidden character was found in `variable`, to prevent
14914      // potential command injection attacks.
14915      else if (reForbiddenIdentifierChars.test(variable)) {
14916        throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
14917      }
14918
14919      // Cleanup code by stripping empty strings.
14920      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14921        .replace(reEmptyStringMiddle, '$1')
14922        .replace(reEmptyStringTrailing, '$1;');
14923
14924      // Frame code as the function body.
14925      source = 'function(' + (variable || 'obj') + ') {\n' +
14926        (variable
14927          ? ''
14928          : 'obj || (obj = {});\n'
14929        ) +
14930        "var __t, __p = ''" +
14931        (isEscaping
14932           ? ', __e = _.escape'
14933           : ''
14934        ) +
14935        (isEvaluating
14936          ? ', __j = Array.prototype.join;\n' +
14937            "function print() { __p += __j.call(arguments, '') }\n"
14938          : ';\n'
14939        ) +
14940        source +
14941        'return __p\n}';
14942
14943      var result = attempt(function() {
14944        return Function(importsKeys, sourceURL + 'return ' + source)
14945          .apply(undefined, importsValues);
14946      });
14947
14948      // Provide the compiled function's source by its `toString` method or
14949      // the `source` property as a convenience for inlining compiled templates.
14950      result.source = source;
14951      if (isError(result)) {
14952        throw result;
14953      }
14954      return result;
14955    }
14956
14957    /**
14958     * Converts `string`, as a whole, to lower case just like
14959     * [String#toLowerCase](https://mdn.io/toLowerCase).
14960     *
14961     * @static
14962     * @memberOf _
14963     * @since 4.0.0
14964     * @category String
14965     * @param {string} [string=''] The string to convert.
14966     * @returns {string} Returns the lower cased string.
14967     * @example
14968     *
14969     * _.toLower('--Foo-Bar--');
14970     * // => '--foo-bar--'
14971     *
14972     * _.toLower('fooBar');
14973     * // => 'foobar'
14974     *
14975     * _.toLower('__FOO_BAR__');
14976     * // => '__foo_bar__'
14977     */
14978    function toLower(value) {
14979      return toString(value).toLowerCase();
14980    }
14981
14982    /**
14983     * Converts `string`, as a whole, to upper case just like
14984     * [String#toUpperCase](https://mdn.io/toUpperCase).
14985     *
14986     * @static
14987     * @memberOf _
14988     * @since 4.0.0
14989     * @category String
14990     * @param {string} [string=''] The string to convert.
14991     * @returns {string} Returns the upper cased string.
14992     * @example
14993     *
14994     * _.toUpper('--foo-bar--');
14995     * // => '--FOO-BAR--'
14996     *
14997     * _.toUpper('fooBar');
14998     * // => 'FOOBAR'
14999     *
15000     * _.toUpper('__foo_bar__');
15001     * // => '__FOO_BAR__'
15002     */
15003    function toUpper(value) {
15004      return toString(value).toUpperCase();
15005    }
15006
15007    /**
15008     * Removes leading and trailing whitespace or specified characters from `string`.
15009     *
15010     * @static
15011     * @memberOf _
15012     * @since 3.0.0
15013     * @category String
15014     * @param {string} [string=''] The string to trim.
15015     * @param {string} [chars=whitespace] The characters to trim.
15016     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15017     * @returns {string} Returns the trimmed string.
15018     * @example
15019     *
15020     * _.trim('  abc  ');
15021     * // => 'abc'
15022     *
15023     * _.trim('-_-abc-_-', '_-');
15024     * // => 'abc'
15025     *
15026     * _.map(['  foo  ', '  bar  '], _.trim);
15027     * // => ['foo', 'bar']
15028     */
15029    function trim(string, chars, guard) {
15030      string = toString(string);
15031      if (string && (guard || chars === undefined)) {
15032        return baseTrim(string);
15033      }
15034      if (!string || !(chars = baseToString(chars))) {
15035        return string;
15036      }
15037      var strSymbols = stringToArray(string),
15038          chrSymbols = stringToArray(chars),
15039          start = charsStartIndex(strSymbols, chrSymbols),
15040          end = charsEndIndex(strSymbols, chrSymbols) + 1;
15041
15042      return castSlice(strSymbols, start, end).join('');
15043    }
15044
15045    /**
15046     * Removes trailing whitespace or specified characters from `string`.
15047     *
15048     * @static
15049     * @memberOf _
15050     * @since 4.0.0
15051     * @category String
15052     * @param {string} [string=''] The string to trim.
15053     * @param {string} [chars=whitespace] The characters to trim.
15054     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15055     * @returns {string} Returns the trimmed string.
15056     * @example
15057     *
15058     * _.trimEnd('  abc  ');
15059     * // => '  abc'
15060     *
15061     * _.trimEnd('-_-abc-_-', '_-');
15062     * // => '-_-abc'
15063     */
15064    function trimEnd(string, chars, guard) {
15065      string = toString(string);
15066      if (string && (guard || chars === undefined)) {
15067        return string.slice(0, trimmedEndIndex(string) + 1);
15068      }
15069      if (!string || !(chars = baseToString(chars))) {
15070        return string;
15071      }
15072      var strSymbols = stringToArray(string),
15073          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
15074
15075      return castSlice(strSymbols, 0, end).join('');
15076    }
15077
15078    /**
15079     * Removes leading whitespace or specified characters from `string`.
15080     *
15081     * @static
15082     * @memberOf _
15083     * @since 4.0.0
15084     * @category String
15085     * @param {string} [string=''] The string to trim.
15086     * @param {string} [chars=whitespace] The characters to trim.
15087     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15088     * @returns {string} Returns the trimmed string.
15089     * @example
15090     *
15091     * _.trimStart('  abc  ');
15092     * // => 'abc  '
15093     *
15094     * _.trimStart('-_-abc-_-', '_-');
15095     * // => 'abc-_-'
15096     */
15097    function trimStart(string, chars, guard) {
15098      string = toString(string);
15099      if (string && (guard || chars === undefined)) {
15100        return string.replace(reTrimStart, '');
15101      }
15102      if (!string || !(chars = baseToString(chars))) {
15103        return string;
15104      }
15105      var strSymbols = stringToArray(string),
15106          start = charsStartIndex(strSymbols, stringToArray(chars));
15107
15108      return castSlice(strSymbols, start).join('');
15109    }
15110
15111    /**
15112     * Truncates `string` if it's longer than the given maximum string length.
15113     * The last characters of the truncated string are replaced with the omission
15114     * string which defaults to "...".
15115     *
15116     * @static
15117     * @memberOf _
15118     * @since 4.0.0
15119     * @category String
15120     * @param {string} [string=''] The string to truncate.
15121     * @param {Object} [options={}] The options object.
15122     * @param {number} [options.length=30] The maximum string length.
15123     * @param {string} [options.omission='...'] The string to indicate text is omitted.
15124     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
15125     * @returns {string} Returns the truncated string.
15126     * @example
15127     *
15128     * _.truncate('hi-diddly-ho there, neighborino');
15129     * // => 'hi-diddly-ho there, neighbo...'
15130     *
15131     * _.truncate('hi-diddly-ho there, neighborino', {
15132     *   'length': 24,
15133     *   'separator': ' '
15134     * });
15135     * // => 'hi-diddly-ho there,...'
15136     *
15137     * _.truncate('hi-diddly-ho there, neighborino', {
15138     *   'length': 24,
15139     *   'separator': /,? +/
15140     * });
15141     * // => 'hi-diddly-ho there...'
15142     *
15143     * _.truncate('hi-diddly-ho there, neighborino', {
15144     *   'omission': ' [...]'
15145     * });
15146     * // => 'hi-diddly-ho there, neig [...]'
15147     */
15148    function truncate(string, options) {
15149      var length = DEFAULT_TRUNC_LENGTH,
15150          omission = DEFAULT_TRUNC_OMISSION;
15151
15152      if (isObject(options)) {
15153        var separator = 'separator' in options ? options.separator : separator;
15154        length = 'length' in options ? toInteger(options.length) : length;
15155        omission = 'omission' in options ? baseToString(options.omission) : omission;
15156      }
15157      string = toString(string);
15158
15159      var strLength = string.length;
15160      if (hasUnicode(string)) {
15161        var strSymbols = stringToArray(string);
15162        strLength = strSymbols.length;
15163      }
15164      if (length >= strLength) {
15165        return string;
15166      }
15167      var end = length - stringSize(omission);
15168      if (end < 1) {
15169        return omission;
15170      }
15171      var result = strSymbols
15172        ? castSlice(strSymbols, 0, end).join('')
15173        : string.slice(0, end);
15174
15175      if (separator === undefined) {
15176        return result + omission;
15177      }
15178      if (strSymbols) {
15179        end += (result.length - end);
15180      }
15181      if (isRegExp(separator)) {
15182        if (string.slice(end).search(separator)) {
15183          var match,
15184              substring = result;
15185
15186          if (!separator.global) {
15187            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
15188          }
15189          separator.lastIndex = 0;
15190          while ((match = separator.exec(substring))) {
15191            var newEnd = match.index;
15192          }
15193          result = result.slice(0, newEnd === undefined ? end : newEnd);
15194        }
15195      } else if (string.indexOf(baseToString(separator), end) != end) {
15196        var index = result.lastIndexOf(separator);
15197        if (index > -1) {
15198          result = result.slice(0, index);
15199        }
15200      }
15201      return result + omission;
15202    }
15203
15204    /**
15205     * The inverse of `_.escape`; this method converts the HTML entities
15206     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
15207     * their corresponding characters.
15208     *
15209     * **Note:** No other HTML entities are unescaped. To unescape additional
15210     * HTML entities use a third-party library like [_he_](https://mths.be/he).
15211     *
15212     * @static
15213     * @memberOf _
15214     * @since 0.6.0
15215     * @category String
15216     * @param {string} [string=''] The string to unescape.
15217     * @returns {string} Returns the unescaped string.
15218     * @example
15219     *
15220     * _.unescape('fred, barney, &amp; pebbles');
15221     * // => 'fred, barney, & pebbles'
15222     */
15223    function unescape(string) {
15224      string = toString(string);
15225      return (string && reHasEscapedHtml.test(string))
15226        ? string.replace(reEscapedHtml, unescapeHtmlChar)
15227        : string;
15228    }
15229
15230    /**
15231     * Converts `string`, as space separated words, to upper case.
15232     *
15233     * @static
15234     * @memberOf _
15235     * @since 4.0.0
15236     * @category String
15237     * @param {string} [string=''] The string to convert.
15238     * @returns {string} Returns the upper cased string.
15239     * @example
15240     *
15241     * _.upperCase('--foo-bar');
15242     * // => 'FOO BAR'
15243     *
15244     * _.upperCase('fooBar');
15245     * // => 'FOO BAR'
15246     *
15247     * _.upperCase('__foo_bar__');
15248     * // => 'FOO BAR'
15249     */
15250    var upperCase = createCompounder(function(result, word, index) {
15251      return result + (index ? ' ' : '') + word.toUpperCase();
15252    });
15253
15254    /**
15255     * Converts the first character of `string` to upper case.
15256     *
15257     * @static
15258     * @memberOf _
15259     * @since 4.0.0
15260     * @category String
15261     * @param {string} [string=''] The string to convert.
15262     * @returns {string} Returns the converted string.
15263     * @example
15264     *
15265     * _.upperFirst('fred');
15266     * // => 'Fred'
15267     *
15268     * _.upperFirst('FRED');
15269     * // => 'FRED'
15270     */
15271    var upperFirst = createCaseFirst('toUpperCase');
15272
15273    /**
15274     * Splits `string` into an array of its words.
15275     *
15276     * @static
15277     * @memberOf _
15278     * @since 3.0.0
15279     * @category String
15280     * @param {string} [string=''] The string to inspect.
15281     * @param {RegExp|string} [pattern] The pattern to match words.
15282     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15283     * @returns {Array} Returns the words of `string`.
15284     * @example
15285     *
15286     * _.words('fred, barney, & pebbles');
15287     * // => ['fred', 'barney', 'pebbles']
15288     *
15289     * _.words('fred, barney, & pebbles', /[^, ]+/g);
15290     * // => ['fred', 'barney', '&', 'pebbles']
15291     */
15292    function words(string, pattern, guard) {
15293      string = toString(string);
15294      pattern = guard ? undefined : pattern;
15295
15296      if (pattern === undefined) {
15297        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
15298      }
15299      return string.match(pattern) || [];
15300    }
15301
15302    /*------------------------------------------------------------------------*/
15303
15304    /**
15305     * Attempts to invoke `func`, returning either the result or the caught error
15306     * object. Any additional arguments are provided to `func` when it's invoked.
15307     *
15308     * @static
15309     * @memberOf _
15310     * @since 3.0.0
15311     * @category Util
15312     * @param {Function} func The function to attempt.
15313     * @param {...*} [args] The arguments to invoke `func` with.
15314     * @returns {*} Returns the `func` result or error object.
15315     * @example
15316     *
15317     * // Avoid throwing errors for invalid selectors.
15318     * var elements = _.attempt(function(selector) {
15319     *   return document.querySelectorAll(selector);
15320     * }, '>_>');
15321     *
15322     * if (_.isError(elements)) {
15323     *   elements = [];
15324     * }
15325     */
15326    var attempt = baseRest(function(func, args) {
15327      try {
15328        return apply(func, undefined, args);
15329      } catch (e) {
15330        return isError(e) ? e : new Error(e);
15331      }
15332    });
15333
15334    /**
15335     * Binds methods of an object to the object itself, overwriting the existing
15336     * method.
15337     *
15338     * **Note:** This method doesn't set the "length" property of bound functions.
15339     *
15340     * @static
15341     * @since 0.1.0
15342     * @memberOf _
15343     * @category Util
15344     * @param {Object} object The object to bind and assign the bound methods to.
15345     * @param {...(string|string[])} methodNames The object method names to bind.
15346     * @returns {Object} Returns `object`.
15347     * @example
15348     *
15349     * var view = {
15350     *   'label': 'docs',
15351     *   'click': function() {
15352     *     console.log('clicked ' + this.label);
15353     *   }
15354     * };
15355     *
15356     * _.bindAll(view, ['click']);
15357     * jQuery(element).on('click', view.click);
15358     * // => Logs 'clicked docs' when clicked.
15359     */
15360    var bindAll = flatRest(function(object, methodNames) {
15361      arrayEach(methodNames, function(key) {
15362        key = toKey(key);
15363        baseAssignValue(object, key, bind(object[key], object));
15364      });
15365      return object;
15366    });
15367
15368    /**
15369     * Creates a function that iterates over `pairs` and invokes the corresponding
15370     * function of the first predicate to return truthy. The predicate-function
15371     * pairs are invoked with the `this` binding and arguments of the created
15372     * function.
15373     *
15374     * @static
15375     * @memberOf _
15376     * @since 4.0.0
15377     * @category Util
15378     * @param {Array} pairs The predicate-function pairs.
15379     * @returns {Function} Returns the new composite function.
15380     * @example
15381     *
15382     * var func = _.cond([
15383     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
15384     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
15385     *   [_.stubTrue,                      _.constant('no match')]
15386     * ]);
15387     *
15388     * func({ 'a': 1, 'b': 2 });
15389     * // => 'matches A'
15390     *
15391     * func({ 'a': 0, 'b': 1 });
15392     * // => 'matches B'
15393     *
15394     * func({ 'a': '1', 'b': '2' });
15395     * // => 'no match'
15396     */
15397    function cond(pairs) {
15398      var length = pairs == null ? 0 : pairs.length,
15399          toIteratee = getIteratee();
15400
15401      pairs = !length ? [] : arrayMap(pairs, function(pair) {
15402        if (typeof pair[1] != 'function') {
15403          throw new TypeError(FUNC_ERROR_TEXT);
15404        }
15405        return [toIteratee(pair[0]), pair[1]];
15406      });
15407
15408      return baseRest(function(args) {
15409        var index = -1;
15410        while (++index < length) {
15411          var pair = pairs[index];
vendor: 10,296 bytes, lines 15412-15744
15412          if (apply(pair[0], this, args)) {
15413            return apply(pair[1], this, args);
15414          }
15415        }
15416      });
15417    }
15418
15419    /**
15420     * Creates a function that invokes the predicate properties of `source` with
15421     * the corresponding property values of a given object, returning `true` if
15422     * all predicates return truthy, else `false`.
15423     *
15424     * **Note:** The created function is equivalent to `_.conformsTo` with
15425     * `source` partially applied.
15426     *
15427     * @static
15428     * @memberOf _
15429     * @since 4.0.0
15430     * @category Util
15431     * @param {Object} source The object of property predicates to conform to.
15432     * @returns {Function} Returns the new spec function.
15433     * @example
15434     *
15435     * var objects = [
15436     *   { 'a': 2, 'b': 1 },
15437     *   { 'a': 1, 'b': 2 }
15438     * ];
15439     *
15440     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
15441     * // => [{ 'a': 1, 'b': 2 }]
15442     */
15443    function conforms(source) {
15444      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
15445    }
15446
15447    /**
15448     * Creates a function that returns `value`.
15449     *
15450     * @static
15451     * @memberOf _
15452     * @since 2.4.0
15453     * @category Util
15454     * @param {*} value The value to return from the new function.
15455     * @returns {Function} Returns the new constant function.
15456     * @example
15457     *
15458     * var objects = _.times(2, _.constant({ 'a': 1 }));
15459     *
15460     * console.log(objects);
15461     * // => [{ 'a': 1 }, { 'a': 1 }]
15462     *
15463     * console.log(objects[0] === objects[1]);
15464     * // => true
15465     */
15466    function constant(value) {
15467      return function() {
15468        return value;
15469      };
15470    }
15471
15472    /**
15473     * Checks `value` to determine whether a default value should be returned in
15474     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
15475     * or `undefined`.
15476     *
15477     * @static
15478     * @memberOf _
15479     * @since 4.14.0
15480     * @category Util
15481     * @param {*} value The value to check.
15482     * @param {*} defaultValue The default value.
15483     * @returns {*} Returns the resolved value.
15484     * @example
15485     *
15486     * _.defaultTo(1, 10);
15487     * // => 1
15488     *
15489     * _.defaultTo(undefined, 10);
15490     * // => 10
15491     */
15492    function defaultTo(value, defaultValue) {
15493      return (value == null || value !== value) ? defaultValue : value;
15494    }
15495
15496    /**
15497     * Creates a function that returns the result of invoking the given functions
15498     * with the `this` binding of the created function, where each successive
15499     * invocation is supplied the return value of the previous.
15500     *
15501     * @static
15502     * @memberOf _
15503     * @since 3.0.0
15504     * @category Util
15505     * @param {...(Function|Function[])} [funcs] The functions to invoke.
15506     * @returns {Function} Returns the new composite function.
15507     * @see _.flowRight
15508     * @example
15509     *
15510     * function square(n) {
15511     *   return n * n;
15512     * }
15513     *
15514     * var addSquare = _.flow([_.add, square]);
15515     * addSquare(1, 2);
15516     * // => 9
15517     */
15518    var flow = createFlow();
15519
15520    /**
15521     * This method is like `_.flow` except that it creates a function that
15522     * invokes the given functions from right to left.
15523     *
15524     * @static
15525     * @since 3.0.0
15526     * @memberOf _
15527     * @category Util
15528     * @param {...(Function|Function[])} [funcs] The functions to invoke.
15529     * @returns {Function} Returns the new composite function.
15530     * @see _.flow
15531     * @example
15532     *
15533     * function square(n) {
15534     *   return n * n;
15535     * }
15536     *
15537     * var addSquare = _.flowRight([square, _.add]);
15538     * addSquare(1, 2);
15539     * // => 9
15540     */
15541    var flowRight = createFlow(true);
15542
15543    /**
15544     * This method returns the first argument it receives.
15545     *
15546     * @static
15547     * @since 0.1.0
15548     * @memberOf _
15549     * @category Util
15550     * @param {*} value Any value.
15551     * @returns {*} Returns `value`.
15552     * @example
15553     *
15554     * var object = { 'a': 1 };
15555     *
15556     * console.log(_.identity(object) === object);
15557     * // => true
15558     */
15559    function identity(value) {
15560      return value;
15561    }
15562
15563    /**
15564     * Creates a function that invokes `func` with the arguments of the created
15565     * function. If `func` is a property name, the created function returns the
15566     * property value for a given element. If `func` is an array or object, the
15567     * created function returns `true` for elements that contain the equivalent
15568     * source properties, otherwise it returns `false`.
15569     *
15570     * @static
15571     * @since 4.0.0
15572     * @memberOf _
15573     * @category Util
15574     * @param {*} [func=_.identity] The value to convert to a callback.
15575     * @returns {Function} Returns the callback.
15576     * @example
15577     *
15578     * var users = [
15579     *   { 'user': 'barney', 'age': 36, 'active': true },
15580     *   { 'user': 'fred',   'age': 40, 'active': false }
15581     * ];
15582     *
15583     * // The `_.matches` iteratee shorthand.
15584     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
15585     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
15586     *
15587     * // The `_.matchesProperty` iteratee shorthand.
15588     * _.filter(users, _.iteratee(['user', 'fred']));
15589     * // => [{ 'user': 'fred', 'age': 40 }]
15590     *
15591     * // The `_.property` iteratee shorthand.
15592     * _.map(users, _.iteratee('user'));
15593     * // => ['barney', 'fred']
15594     *
15595     * // Create custom iteratee shorthands.
15596     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
15597     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
15598     *     return func.test(string);
15599     *   };
15600     * });
15601     *
15602     * _.filter(['abc', 'def'], /ef/);
15603     * // => ['def']
15604     */
15605    function iteratee(func) {
15606      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
15607    }
15608
15609    /**
15610     * Creates a function that performs a partial deep comparison between a given
15611     * object and `source`, returning `true` if the given object has equivalent
15612     * property values, else `false`.
15613     *
15614     * **Note:** The created function is equivalent to `_.isMatch` with `source`
15615     * partially applied.
15616     *
15617     * Partial comparisons will match empty array and empty object `source`
15618     * values against any array or object value, respectively. See `_.isEqual`
15619     * for a list of supported value comparisons.
15620     *
15621     * **Note:** Multiple values can be checked by combining several matchers
15622     * using `_.overSome`
15623     *
15624     * @static
15625     * @memberOf _
15626     * @since 3.0.0
15627     * @category Util
15628     * @param {Object} source The object of property values to match.
15629     * @returns {Function} Returns the new spec function.
15630     * @example
15631     *
15632     * var objects = [
15633     *   { 'a': 1, 'b': 2, 'c': 3 },
15634     *   { 'a': 4, 'b': 5, 'c': 6 }
15635     * ];
15636     *
15637     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
15638     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
15639     *
15640     * // Checking for several possible values
15641     * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
15642     * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
15643     */
15644    function matches(source) {
15645      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
15646    }
15647
15648    /**
15649     * Creates a function that performs a partial deep comparison between the
15650     * value at `path` of a given object to `srcValue`, returning `true` if the
15651     * object value is equivalent, else `false`.
15652     *
15653     * **Note:** Partial comparisons will match empty array and empty object
15654     * `srcValue` values against any array or object value, respectively. See
15655     * `_.isEqual` for a list of supported value comparisons.
15656     *
15657     * **Note:** Multiple values can be checked by combining several matchers
15658     * using `_.overSome`
15659     *
15660     * @static
15661     * @memberOf _
15662     * @since 3.2.0
15663     * @category Util
15664     * @param {Array|string} path The path of the property to get.
15665     * @param {*} srcValue The value to match.
15666     * @returns {Function} Returns the new spec function.
15667     * @example
15668     *
15669     * var objects = [
15670     *   { 'a': 1, 'b': 2, 'c': 3 },
15671     *   { 'a': 4, 'b': 5, 'c': 6 }
15672     * ];
15673     *
15674     * _.find(objects, _.matchesProperty('a', 4));
15675     * // => { 'a': 4, 'b': 5, 'c': 6 }
15676     *
15677     * // Checking for several possible values
15678     * _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
15679     * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
15680     */
15681    function matchesProperty(path, srcValue) {
15682      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
15683    }
15684
15685    /**
15686     * Creates a function that invokes the method at `path` of a given object.
15687     * Any additional arguments are provided to the invoked method.
15688     *
15689     * @static
15690     * @memberOf _
15691     * @since 3.7.0
15692     * @category Util
15693     * @param {Array|string} path The path of the method to invoke.
15694     * @param {...*} [args] The arguments to invoke the method with.
15695     * @returns {Function} Returns the new invoker function.
15696     * @example
15697     *
15698     * var objects = [
15699     *   { 'a': { 'b': _.constant(2) } },
15700     *   { 'a': { 'b': _.constant(1) } }
15701     * ];
15702     *
15703     * _.map(objects, _.method('a.b'));
15704     * // => [2, 1]
15705     *
15706     * _.map(objects, _.method(['a', 'b']));
15707     * // => [2, 1]
15708     */
15709    var method = baseRest(function(path, args) {
15710      return function(object) {
15711        return baseInvoke(object, path, args);
15712      };
15713    });
15714
15715    /**
15716     * The opposite of `_.method`; this method creates a function that invokes
15717     * the method at a given path of `object`. Any additional arguments are
15718     * provided to the invoked method.
15719     *
15720     * @static
15721     * @memberOf _
15722     * @since 3.7.0
15723     * @category Util
15724     * @param {Object} object The object to query.
15725     * @param {...*} [args] The arguments to invoke the method with.
15726     * @returns {Function} Returns the new invoker function.
15727     * @example
15728     *
15729     * var array = _.times(3, _.constant),
15730     *     object = { 'a': array, 'b': array, 'c': array };
15731     *
15732     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
15733     * // => [2, 0]
15734     *
15735     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
15736     * // => [2, 0]
15737     */
15738    var methodOf = baseRest(function(object, args) {
15739      return function(path) {
15740        return baseInvoke(object, path, args);
15741      };
15742    });
15743
15744    /**
vendor: 10,734 bytes, lines 15745-16132
15745     * Adds all own enumerable string keyed function properties of a source
15746     * object to the destination object. If `object` is a function, then methods
15747     * are added to its prototype as well.
15748     *
15749     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
15750     * avoid conflicts caused by modifying the original.
15751     *
15752     * @static
15753     * @since 0.1.0
15754     * @memberOf _
15755     * @category Util
15756     * @param {Function|Object} [object=lodash] The destination object.
15757     * @param {Object} source The object of functions to add.
15758     * @param {Object} [options={}] The options object.
15759     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
15760     * @returns {Function|Object} Returns `object`.
15761     * @example
15762     *
15763     * function vowels(string) {
15764     *   return _.filter(string, function(v) {
15765     *     return /[aeiou]/i.test(v);
15766     *   });
15767     * }
15768     *
15769     * _.mixin({ 'vowels': vowels });
15770     * _.vowels('fred');
15771     * // => ['e']
15772     *
15773     * _('fred').vowels().value();
15774     * // => ['e']
15775     *
15776     * _.mixin({ 'vowels': vowels }, { 'chain': false });
15777     * _('fred').vowels();
15778     * // => ['e']
15779     */
15780    function mixin(object, source, options) {
15781      var props = keys(source),
15782          methodNames = baseFunctions(source, props);
15783
15784      if (options == null &&
15785          !(isObject(source) && (methodNames.length || !props.length))) {
15786        options = source;
15787        source = object;
15788        object = this;
15789        methodNames = baseFunctions(source, keys(source));
15790      }
15791      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
15792          isFunc = isFunction(object);
15793
15794      arrayEach(methodNames, function(methodName) {
15795        var func = source[methodName];
15796        object[methodName] = func;
15797        if (isFunc) {
15798          object.prototype[methodName] = function() {
15799            var chainAll = this.__chain__;
15800            if (chain || chainAll) {
15801              var result = object(this.__wrapped__),
15802                  actions = result.__actions__ = copyArray(this.__actions__);
15803
15804              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15805              result.__chain__ = chainAll;
15806              return result;
15807            }
15808            return func.apply(object, arrayPush([this.value()], arguments));
15809          };
15810        }
15811      });
15812
15813      return object;
15814    }
15815
15816    /**
15817     * Reverts the `_` variable to its previous value and returns a reference to
15818     * the `lodash` function.
15819     *
15820     * @static
15821     * @since 0.1.0
15822     * @memberOf _
15823     * @category Util
15824     * @returns {Function} Returns the `lodash` function.
15825     * @example
15826     *
15827     * var lodash = _.noConflict();
15828     */
15829    function noConflict() {
15830      if (root._ === this) {
15831        root._ = oldDash;
15832      }
15833      return this;
15834    }
15835
15836    /**
15837     * This method returns `undefined`.
15838     *
15839     * @static
15840     * @memberOf _
15841     * @since 2.3.0
15842     * @category Util
15843     * @example
15844     *
15845     * _.times(2, _.noop);
15846     * // => [undefined, undefined]
15847     */
15848    function noop() {
15849      // No operation performed.
15850    }
15851
15852    /**
15853     * Creates a function that gets the argument at index `n`. If `n` is negative,
15854     * the nth argument from the end is returned.
15855     *
15856     * @static
15857     * @memberOf _
15858     * @since 4.0.0
15859     * @category Util
15860     * @param {number} [n=0] The index of the argument to return.
15861     * @returns {Function} Returns the new pass-thru function.
15862     * @example
15863     *
15864     * var func = _.nthArg(1);
15865     * func('a', 'b', 'c', 'd');
15866     * // => 'b'
15867     *
15868     * var func = _.nthArg(-2);
15869     * func('a', 'b', 'c', 'd');
15870     * // => 'c'
15871     */
15872    function nthArg(n) {
15873      n = toInteger(n);
15874      return baseRest(function(args) {
15875        return baseNth(args, n);
15876      });
15877    }
15878
15879    /**
15880     * Creates a function that invokes `iteratees` with the arguments it receives
15881     * and returns their results.
15882     *
15883     * @static
15884     * @memberOf _
15885     * @since 4.0.0
15886     * @category Util
15887     * @param {...(Function|Function[])} [iteratees=[_.identity]]
15888     *  The iteratees to invoke.
15889     * @returns {Function} Returns the new function.
15890     * @example
15891     *
15892     * var func = _.over([Math.max, Math.min]);
15893     *
15894     * func(1, 2, 3, 4);
15895     * // => [4, 1]
15896     */
15897    var over = createOver(arrayMap);
15898
15899    /**
15900     * Creates a function that checks if **all** of the `predicates` return
15901     * truthy when invoked with the arguments it receives.
15902     *
15903     * Following shorthands are possible for providing predicates.
15904     * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
15905     * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
15906     *
15907     * @static
15908     * @memberOf _
15909     * @since 4.0.0
15910     * @category Util
15911     * @param {...(Function|Function[])} [predicates=[_.identity]]
15912     *  The predicates to check.
15913     * @returns {Function} Returns the new function.
15914     * @example
15915     *
15916     * var func = _.overEvery([Boolean, isFinite]);
15917     *
15918     * func('1');
15919     * // => true
15920     *
15921     * func(null);
15922     * // => false
15923     *
15924     * func(NaN);
15925     * // => false
15926     */
15927    var overEvery = createOver(arrayEvery);
15928
15929    /**
15930     * Creates a function that checks if **any** of the `predicates` return
15931     * truthy when invoked with the arguments it receives.
15932     *
15933     * Following shorthands are possible for providing predicates.
15934     * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
15935     * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
15936     *
15937     * @static
15938     * @memberOf _
15939     * @since 4.0.0
15940     * @category Util
15941     * @param {...(Function|Function[])} [predicates=[_.identity]]
15942     *  The predicates to check.
15943     * @returns {Function} Returns the new function.
15944     * @example
15945     *
15946     * var func = _.overSome([Boolean, isFinite]);
15947     *
15948     * func('1');
15949     * // => true
15950     *
15951     * func(null);
15952     * // => true
15953     *
15954     * func(NaN);
15955     * // => false
15956     *
15957     * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
15958     * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
15959     */
15960    var overSome = createOver(arraySome);
15961
15962    /**
15963     * Creates a function that returns the value at `path` of a given object.
15964     *
15965     * @static
15966     * @memberOf _
15967     * @since 2.4.0
15968     * @category Util
15969     * @param {Array|string} path The path of the property to get.
15970     * @returns {Function} Returns the new accessor function.
15971     * @example
15972     *
15973     * var objects = [
15974     *   { 'a': { 'b': 2 } },
15975     *   { 'a': { 'b': 1 } }
15976     * ];
15977     *
15978     * _.map(objects, _.property('a.b'));
15979     * // => [2, 1]
15980     *
15981     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15982     * // => [1, 2]
15983     */
15984    function property(path) {
15985      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15986    }
15987
15988    /**
15989     * The opposite of `_.property`; this method creates a function that returns
15990     * the value at a given path of `object`.
15991     *
15992     * @static
15993     * @memberOf _
15994     * @since 3.0.0
15995     * @category Util
15996     * @param {Object} object The object to query.
15997     * @returns {Function} Returns the new accessor function.
15998     * @example
15999     *
16000     * var array = [0, 1, 2],
16001     *     object = { 'a': array, 'b': array, 'c': array };
16002     *
16003     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
16004     * // => [2, 0]
16005     *
16006     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
16007     * // => [2, 0]
16008     */
16009    function propertyOf(object) {
16010      return function(path) {
16011        return object == null ? undefined : baseGet(object, path);
16012      };
16013    }
16014
16015    /**
16016     * Creates an array of numbers (positive and/or negative) progressing from
16017     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
16018     * `start` is specified without an `end` or `step`. If `end` is not specified,
16019     * it's set to `start` with `start` then set to `0`.
16020     *
16021     * **Note:** JavaScript follows the IEEE-754 standard for resolving
16022     * floating-point values which can produce unexpected results.
16023     *
16024     * @static
16025     * @since 0.1.0
16026     * @memberOf _
16027     * @category Util
16028     * @param {number} [start=0] The start of the range.
16029     * @param {number} end The end of the range.
16030     * @param {number} [step=1] The value to increment or decrement by.
16031     * @returns {Array} Returns the range of numbers.
16032     * @see _.inRange, _.rangeRight
16033     * @example
16034     *
16035     * _.range(4);
16036     * // => [0, 1, 2, 3]
16037     *
16038     * _.range(-4);
16039     * // => [0, -1, -2, -3]
16040     *
16041     * _.range(1, 5);
16042     * // => [1, 2, 3, 4]
16043     *
16044     * _.range(0, 20, 5);
16045     * // => [0, 5, 10, 15]
16046     *
16047     * _.range(0, -4, -1);
16048     * // => [0, -1, -2, -3]
16049     *
16050     * _.range(1, 4, 0);
16051     * // => [1, 1, 1]
16052     *
16053     * _.range(0);
16054     * // => []
16055     */
16056    var range = createRange();
16057
16058    /**
16059     * This method is like `_.range` except that it populates values in
16060     * descending order.
16061     *
16062     * @static
16063     * @memberOf _
16064     * @since 4.0.0
16065     * @category Util
16066     * @param {number} [start=0] The start of the range.
16067     * @param {number} end The end of the range.
16068     * @param {number} [step=1] The value to increment or decrement by.
16069     * @returns {Array} Returns the range of numbers.
16070     * @see _.inRange, _.range
16071     * @example
16072     *
16073     * _.rangeRight(4);
16074     * // => [3, 2, 1, 0]
16075     *
16076     * _.rangeRight(-4);
16077     * // => [-3, -2, -1, 0]
16078     *
16079     * _.rangeRight(1, 5);
16080     * // => [4, 3, 2, 1]
16081     *
16082     * _.rangeRight(0, 20, 5);
16083     * // => [15, 10, 5, 0]
16084     *
16085     * _.rangeRight(0, -4, -1);
16086     * // => [-3, -2, -1, 0]
16087     *
16088     * _.rangeRight(1, 4, 0);
16089     * // => [1, 1, 1]
16090     *
16091     * _.rangeRight(0);
16092     * // => []
16093     */
16094    var rangeRight = createRange(true);
16095
16096    /**
16097     * This method returns a new empty array.
16098     *
16099     * @static
16100     * @memberOf _
16101     * @since 4.13.0
16102     * @category Util
16103     * @returns {Array} Returns the new empty array.
16104     * @example
16105     *
16106     * var arrays = _.times(2, _.stubArray);
16107     *
16108     * console.log(arrays);
16109     * // => [[], []]
16110     *
16111     * console.log(arrays[0] === arrays[1]);
16112     * // => false
16113     */
16114    function stubArray() {
16115      return [];
16116    }
16117
16118    /**
16119     * This method returns `false`.
16120     *
16121     * @static
16122     * @memberOf _
16123     * @since 4.13.0
16124     * @category Util
16125     * @returns {boolean} Returns `false`.
16126     * @example
16127     *
16128     * _.times(2, _.stubFalse);
16129     * // => [false, false]
16130     */
16131    function stubFalse() {
16132      return false;
vendor: 1,044 bytes, lines 16133-16186
16133    }
16134
16135    /**
16136     * This method returns a new empty object.
16137     *
16138     * @static
16139     * @memberOf _
16140     * @since 4.13.0
16141     * @category Util
16142     * @returns {Object} Returns the new empty object.
16143     * @example
16144     *
16145     * var objects = _.times(2, _.stubObject);
16146     *
16147     * console.log(objects);
16148     * // => [{}, {}]
16149     *
16150     * console.log(objects[0] === objects[1]);
16151     * // => false
16152     */
16153    function stubObject() {
16154      return {};
16155    }
16156
16157    /**
16158     * This method returns an empty string.
16159     *
16160     * @static
16161     * @memberOf _
16162     * @since 4.13.0
16163     * @category Util
16164     * @returns {string} Returns the empty string.
16165     * @example
16166     *
16167     * _.times(2, _.stubString);
16168     * // => ['', '']
16169     */
16170    function stubString() {
16171      return '';
16172    }
16173
16174    /**
16175     * This method returns `true`.
16176     *
16177     * @static
16178     * @memberOf _
16179     * @since 4.13.0
16180     * @category Util
16181     * @returns {boolean} Returns `true`.
16182     * @example
16183     *
16184     * _.times(2, _.stubTrue);
16185     * // => [true, true]
16186     */
vendor: 9,081 bytes, lines 16187-16530
16187    function stubTrue() {
16188      return true;
16189    }
16190
16191    /**
16192     * Invokes the iteratee `n` times, returning an array of the results of
16193     * each invocation. The iteratee is invoked with one argument; (index).
16194     *
16195     * @static
16196     * @since 0.1.0
16197     * @memberOf _
16198     * @category Util
16199     * @param {number} n The number of times to invoke `iteratee`.
16200     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
16201     * @returns {Array} Returns the array of results.
16202     * @example
16203     *
16204     * _.times(3, String);
16205     * // => ['0', '1', '2']
16206     *
16207     *  _.times(4, _.constant(0));
16208     * // => [0, 0, 0, 0]
16209     */
16210    function times(n, iteratee) {
16211      n = toInteger(n);
16212      if (n < 1 || n > MAX_SAFE_INTEGER) {
16213        return [];
16214      }
16215      var index = MAX_ARRAY_LENGTH,
16216          length = nativeMin(n, MAX_ARRAY_LENGTH);
16217
16218      iteratee = getIteratee(iteratee);
16219      n -= MAX_ARRAY_LENGTH;
16220
16221      var result = baseTimes(length, iteratee);
16222      while (++index < n) {
16223        iteratee(index);
16224      }
16225      return result;
16226    }
16227
16228    /**
16229     * Converts `value` to a property path array.
16230     *
16231     * @static
16232     * @memberOf _
16233     * @since 4.0.0
16234     * @category Util
16235     * @param {*} value The value to convert.
16236     * @returns {Array} Returns the new property path array.
16237     * @example
16238     *
16239     * _.toPath('a.b.c');
16240     * // => ['a', 'b', 'c']
16241     *
16242     * _.toPath('a[0].b.c');
16243     * // => ['a', '0', 'b', 'c']
16244     */
16245    function toPath(value) {
16246      if (isArray(value)) {
16247        return arrayMap(value, toKey);
16248      }
16249      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
16250    }
16251
16252    /**
16253     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
16254     *
16255     * @static
16256     * @since 0.1.0
16257     * @memberOf _
16258     * @category Util
16259     * @param {string} [prefix=''] The value to prefix the ID with.
16260     * @returns {string} Returns the unique ID.
16261     * @example
16262     *
16263     * _.uniqueId('contact_');
16264     * // => 'contact_104'
16265     *
16266     * _.uniqueId();
16267     * // => '105'
16268     */
16269    function uniqueId(prefix) {
16270      var id = ++idCounter;
16271      return toString(prefix) + id;
16272    }
16273
16274    /*------------------------------------------------------------------------*/
16275
16276    /**
16277     * Adds two numbers.
16278     *
16279     * @static
16280     * @memberOf _
16281     * @since 3.4.0
16282     * @category Math
16283     * @param {number} augend The first number in an addition.
16284     * @param {number} addend The second number in an addition.
16285     * @returns {number} Returns the total.
16286     * @example
16287     *
16288     * _.add(6, 4);
16289     * // => 10
16290     */
16291    var add = createMathOperation(function(augend, addend) {
16292      return augend + addend;
16293    }, 0);
16294
16295    /**
16296     * Computes `number` rounded up to `precision`.
16297     *
16298     * @static
16299     * @memberOf _
16300     * @since 3.10.0
16301     * @category Math
16302     * @param {number} number The number to round up.
16303     * @param {number} [precision=0] The precision to round up to.
16304     * @returns {number} Returns the rounded up number.
16305     * @example
16306     *
16307     * _.ceil(4.006);
16308     * // => 5
16309     *
16310     * _.ceil(6.004, 2);
16311     * // => 6.01
16312     *
16313     * _.ceil(6040, -2);
16314     * // => 6100
16315     */
16316    var ceil = createRound('ceil');
16317
16318    /**
16319     * Divide two numbers.
16320     *
16321     * @static
16322     * @memberOf _
16323     * @since 4.7.0
16324     * @category Math
16325     * @param {number} dividend The first number in a division.
16326     * @param {number} divisor The second number in a division.
16327     * @returns {number} Returns the quotient.
16328     * @example
16329     *
16330     * _.divide(6, 4);
16331     * // => 1.5
16332     */
16333    var divide = createMathOperation(function(dividend, divisor) {
16334      return dividend / divisor;
16335    }, 1);
16336
16337    /**
16338     * Computes `number` rounded down to `precision`.
16339     *
16340     * @static
16341     * @memberOf _
16342     * @since 3.10.0
16343     * @category Math
16344     * @param {number} number The number to round down.
16345     * @param {number} [precision=0] The precision to round down to.
16346     * @returns {number} Returns the rounded down number.
16347     * @example
16348     *
16349     * _.floor(4.006);
16350     * // => 4
16351     *
16352     * _.floor(0.046, 2);
16353     * // => 0.04
16354     *
16355     * _.floor(4060, -2);
16356     * // => 4000
16357     */
16358    var floor = createRound('floor');
16359
16360    /**
16361     * Computes the maximum value of `array`. If `array` is empty or falsey,
16362     * `undefined` is returned.
16363     *
16364     * @static
16365     * @since 0.1.0
16366     * @memberOf _
16367     * @category Math
16368     * @param {Array} array The array to iterate over.
16369     * @returns {*} Returns the maximum value.
16370     * @example
16371     *
16372     * _.max([4, 2, 8, 6]);
16373     * // => 8
16374     *
16375     * _.max([]);
16376     * // => undefined
16377     */
16378    function max(array) {
16379      return (array && array.length)
16380        ? baseExtremum(array, identity, baseGt)
16381        : undefined;
16382    }
16383
16384    /**
16385     * This method is like `_.max` except that it accepts `iteratee` which is
16386     * invoked for each element in `array` to generate the criterion by which
16387     * the value is ranked. The iteratee is invoked with one argument: (value).
16388     *
16389     * @static
16390     * @memberOf _
16391     * @since 4.0.0
16392     * @category Math
16393     * @param {Array} array The array to iterate over.
16394     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16395     * @returns {*} Returns the maximum value.
16396     * @example
16397     *
16398     * var objects = [{ 'n': 1 }, { 'n': 2 }];
16399     *
16400     * _.maxBy(objects, function(o) { return o.n; });
16401     * // => { 'n': 2 }
16402     *
16403     * // The `_.property` iteratee shorthand.
16404     * _.maxBy(objects, 'n');
16405     * // => { 'n': 2 }
16406     */
16407    function maxBy(array, iteratee) {
16408      return (array && array.length)
16409        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
16410        : undefined;
16411    }
16412
16413    /**
16414     * Computes the mean of the values in `array`.
16415     *
16416     * @static
16417     * @memberOf _
16418     * @since 4.0.0
16419     * @category Math
16420     * @param {Array} array The array to iterate over.
16421     * @returns {number} Returns the mean.
16422     * @example
16423     *
16424     * _.mean([4, 2, 8, 6]);
16425     * // => 5
16426     */
16427    function mean(array) {
16428      return baseMean(array, identity);
16429    }
16430
16431    /**
16432     * This method is like `_.mean` except that it accepts `iteratee` which is
16433     * invoked for each element in `array` to generate the value to be averaged.
16434     * The iteratee is invoked with one argument: (value).
16435     *
16436     * @static
16437     * @memberOf _
16438     * @since 4.7.0
16439     * @category Math
16440     * @param {Array} array The array to iterate over.
16441     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16442     * @returns {number} Returns the mean.
16443     * @example
16444     *
16445     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16446     *
16447     * _.meanBy(objects, function(o) { return o.n; });
16448     * // => 5
16449     *
16450     * // The `_.property` iteratee shorthand.
16451     * _.meanBy(objects, 'n');
16452     * // => 5
16453     */
16454    function meanBy(array, iteratee) {
16455      return baseMean(array, getIteratee(iteratee, 2));
16456    }
16457
16458    /**
16459     * Computes the minimum value of `array`. If `array` is empty or falsey,
16460     * `undefined` is returned.
16461     *
16462     * @static
16463     * @since 0.1.0
16464     * @memberOf _
16465     * @category Math
16466     * @param {Array} array The array to iterate over.
16467     * @returns {*} Returns the minimum value.
16468     * @example
16469     *
16470     * _.min([4, 2, 8, 6]);
16471     * // => 2
16472     *
16473     * _.min([]);
16474     * // => undefined
16475     */
16476    function min(array) {
16477      return (array && array.length)
16478        ? baseExtremum(array, identity, baseLt)
16479        : undefined;
16480    }
16481
16482    /**
16483     * This method is like `_.min` except that it accepts `iteratee` which is
16484     * invoked for each element in `array` to generate the criterion by which
16485     * the value is ranked. The iteratee is invoked with one argument: (value).
16486     *
16487     * @static
16488     * @memberOf _
16489     * @since 4.0.0
16490     * @category Math
16491     * @param {Array} array The array to iterate over.
16492     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16493     * @returns {*} Returns the minimum value.
16494     * @example
16495     *
16496     * var objects = [{ 'n': 1 }, { 'n': 2 }];
16497     *
16498     * _.minBy(objects, function(o) { return o.n; });
16499     * // => { 'n': 1 }
16500     *
16501     * // The `_.property` iteratee shorthand.
16502     * _.minBy(objects, 'n');
16503     * // => { 'n': 1 }
16504     */
16505    function minBy(array, iteratee) {
16506      return (array && array.length)
16507        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
16508        : undefined;
16509    }
16510
16511    /**
16512     * Multiply two numbers.
16513     *
16514     * @static
16515     * @memberOf _
16516     * @since 4.7.0
16517     * @category Math
16518     * @param {number} multiplier The first number in a multiplication.
16519     * @param {number} multiplicand The second number in a multiplication.
16520     * @returns {number} Returns the product.
16521     * @example
16522     *
16523     * _.multiply(6, 4);
16524     * // => 24
16525     */
16526    var multiply = createMathOperation(function(multiplier, multiplicand) {
16527      return multiplier * multiplicand;
16528    }, 1);
16529
16530    /**
vendor: 13,137 bytes, lines 16531-16969
16531     * Computes `number` rounded to `precision`.
16532     *
16533     * @static
16534     * @memberOf _
16535     * @since 3.10.0
16536     * @category Math
16537     * @param {number} number The number to round.
16538     * @param {number} [precision=0] The precision to round to.
16539     * @returns {number} Returns the rounded number.
16540     * @example
16541     *
16542     * _.round(4.006);
16543     * // => 4
16544     *
16545     * _.round(4.006, 2);
16546     * // => 4.01
16547     *
16548     * _.round(4060, -2);
16549     * // => 4100
16550     */
16551    var round = createRound('round');
16552
16553    /**
16554     * Subtract two numbers.
16555     *
16556     * @static
16557     * @memberOf _
16558     * @since 4.0.0
16559     * @category Math
16560     * @param {number} minuend The first number in a subtraction.
16561     * @param {number} subtrahend The second number in a subtraction.
16562     * @returns {number} Returns the difference.
16563     * @example
16564     *
16565     * _.subtract(6, 4);
16566     * // => 2
16567     */
16568    var subtract = createMathOperation(function(minuend, subtrahend) {
16569      return minuend - subtrahend;
16570    }, 0);
16571
16572    /**
16573     * Computes the sum of the values in `array`.
16574     *
16575     * @static
16576     * @memberOf _
16577     * @since 3.4.0
16578     * @category Math
16579     * @param {Array} array The array to iterate over.
16580     * @returns {number} Returns the sum.
16581     * @example
16582     *
16583     * _.sum([4, 2, 8, 6]);
16584     * // => 20
16585     */
16586    function sum(array) {
16587      return (array && array.length)
16588        ? baseSum(array, identity)
16589        : 0;
16590    }
16591
16592    /**
16593     * This method is like `_.sum` except that it accepts `iteratee` which is
16594     * invoked for each element in `array` to generate the value to be summed.
16595     * The iteratee is invoked with one argument: (value).
16596     *
16597     * @static
16598     * @memberOf _
16599     * @since 4.0.0
16600     * @category Math
16601     * @param {Array} array The array to iterate over.
16602     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16603     * @returns {number} Returns the sum.
16604     * @example
16605     *
16606     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16607     *
16608     * _.sumBy(objects, function(o) { return o.n; });
16609     * // => 20
16610     *
16611     * // The `_.property` iteratee shorthand.
16612     * _.sumBy(objects, 'n');
16613     * // => 20
16614     */
16615    function sumBy(array, iteratee) {
16616      return (array && array.length)
16617        ? baseSum(array, getIteratee(iteratee, 2))
16618        : 0;
16619    }
16620
16621    /*------------------------------------------------------------------------*/
16622
16623    // Add methods that return wrapped values in chain sequences.
16624    lodash.after = after;
16625    lodash.ary = ary;
16626    lodash.assign = assign;
16627    lodash.assignIn = assignIn;
16628    lodash.assignInWith = assignInWith;
16629    lodash.assignWith = assignWith;
16630    lodash.at = at;
16631    lodash.before = before;
16632    lodash.bind = bind;
16633    lodash.bindAll = bindAll;
16634    lodash.bindKey = bindKey;
16635    lodash.castArray = castArray;
16636    lodash.chain = chain;
16637    lodash.chunk = chunk;
16638    lodash.compact = compact;
16639    lodash.concat = concat;
16640    lodash.cond = cond;
16641    lodash.conforms = conforms;
16642    lodash.constant = constant;
16643    lodash.countBy = countBy;
16644    lodash.create = create;
16645    lodash.curry = curry;
16646    lodash.curryRight = curryRight;
16647    lodash.debounce = debounce;
16648    lodash.defaults = defaults;
16649    lodash.defaultsDeep = defaultsDeep;
16650    lodash.defer = defer;
16651    lodash.delay = delay;
16652    lodash.difference = difference;
16653    lodash.differenceBy = differenceBy;
16654    lodash.differenceWith = differenceWith;
16655    lodash.drop = drop;
16656    lodash.dropRight = dropRight;
16657    lodash.dropRightWhile = dropRightWhile;
16658    lodash.dropWhile = dropWhile;
16659    lodash.fill = fill;
16660    lodash.filter = filter;
16661    lodash.flatMap = flatMap;
16662    lodash.flatMapDeep = flatMapDeep;
16663    lodash.flatMapDepth = flatMapDepth;
16664    lodash.flatten = flatten;
16665    lodash.flattenDeep = flattenDeep;
16666    lodash.flattenDepth = flattenDepth;
16667    lodash.flip = flip;
16668    lodash.flow = flow;
16669    lodash.flowRight = flowRight;
16670    lodash.fromPairs = fromPairs;
16671    lodash.functions = functions;
16672    lodash.functionsIn = functionsIn;
16673    lodash.groupBy = groupBy;
16674    lodash.initial = initial;
16675    lodash.intersection = intersection;
16676    lodash.intersectionBy = intersectionBy;
16677    lodash.intersectionWith = intersectionWith;
16678    lodash.invert = invert;
16679    lodash.invertBy = invertBy;
16680    lodash.invokeMap = invokeMap;
16681    lodash.iteratee = iteratee;
16682    lodash.keyBy = keyBy;
16683    lodash.keys = keys;
16684    lodash.keysIn = keysIn;
16685    lodash.map = map;
16686    lodash.mapKeys = mapKeys;
16687    lodash.mapValues = mapValues;
16688    lodash.matches = matches;
16689    lodash.matchesProperty = matchesProperty;
16690    lodash.memoize = memoize;
16691    lodash.merge = merge;
16692    lodash.mergeWith = mergeWith;
16693    lodash.method = method;
16694    lodash.methodOf = methodOf;
16695    lodash.mixin = mixin;
16696    lodash.negate = negate;
16697    lodash.nthArg = nthArg;
16698    lodash.omit = omit;
16699    lodash.omitBy = omitBy;
16700    lodash.once = once;
16701    lodash.orderBy = orderBy;
16702    lodash.over = over;
16703    lodash.overArgs = overArgs;
16704    lodash.overEvery = overEvery;
16705    lodash.overSome = overSome;
16706    lodash.partial = partial;
16707    lodash.partialRight = partialRight;
16708    lodash.partition = partition;
16709    lodash.pick = pick;
16710    lodash.pickBy = pickBy;
16711    lodash.property = property;
16712    lodash.propertyOf = propertyOf;
16713    lodash.pull = pull;
16714    lodash.pullAll = pullAll;
16715    lodash.pullAllBy = pullAllBy;
16716    lodash.pullAllWith = pullAllWith;
16717    lodash.pullAt = pullAt;
16718    lodash.range = range;
16719    lodash.rangeRight = rangeRight;
16720    lodash.rearg = rearg;
16721    lodash.reject = reject;
16722    lodash.remove = remove;
16723    lodash.rest = rest;
16724    lodash.reverse = reverse;
16725    lodash.sampleSize = sampleSize;
16726    lodash.set = set;
16727    lodash.setWith = setWith;
16728    lodash.shuffle = shuffle;
16729    lodash.slice = slice;
16730    lodash.sortBy = sortBy;
16731    lodash.sortedUniq = sortedUniq;
16732    lodash.sortedUniqBy = sortedUniqBy;
16733    lodash.split = split;
16734    lodash.spread = spread;
16735    lodash.tail = tail;
16736    lodash.take = take;
16737    lodash.takeRight = takeRight;
16738    lodash.takeRightWhile = takeRightWhile;
16739    lodash.takeWhile = takeWhile;
16740    lodash.tap = tap;
16741    lodash.throttle = throttle;
16742    lodash.thru = thru;
16743    lodash.toArray = toArray;
16744    lodash.toPairs = toPairs;
16745    lodash.toPairsIn = toPairsIn;
16746    lodash.toPath = toPath;
16747    lodash.toPlainObject = toPlainObject;
16748    lodash.transform = transform;
16749    lodash.unary = unary;
16750    lodash.union = union;
16751    lodash.unionBy = unionBy;
16752    lodash.unionWith = unionWith;
16753    lodash.uniq = uniq;
16754    lodash.uniqBy = uniqBy;
16755    lodash.uniqWith = uniqWith;
16756    lodash.unset = unset;
16757    lodash.unzip = unzip;
16758    lodash.unzipWith = unzipWith;
16759    lodash.update = update;
16760    lodash.updateWith = updateWith;
16761    lodash.values = values;
16762    lodash.valuesIn = valuesIn;
16763    lodash.without = without;
16764    lodash.words = words;
16765    lodash.wrap = wrap;
16766    lodash.xor = xor;
16767    lodash.xorBy = xorBy;
16768    lodash.xorWith = xorWith;
16769    lodash.zip = zip;
16770    lodash.zipObject = zipObject;
16771    lodash.zipObjectDeep = zipObjectDeep;
16772    lodash.zipWith = zipWith;
16773
16774    // Add aliases.
16775    lodash.entries = toPairs;
16776    lodash.entriesIn = toPairsIn;
16777    lodash.extend = assignIn;
16778    lodash.extendWith = assignInWith;
16779
16780    // Add methods to `lodash.prototype`.
16781    mixin(lodash, lodash);
16782
16783    /*------------------------------------------------------------------------*/
16784
16785    // Add methods that return unwrapped values in chain sequences.
16786    lodash.add = add;
16787    lodash.attempt = attempt;
16788    lodash.camelCase = camelCase;
16789    lodash.capitalize = capitalize;
16790    lodash.ceil = ceil;
16791    lodash.clamp = clamp;
16792    lodash.clone = clone;
16793    lodash.cloneDeep = cloneDeep;
16794    lodash.cloneDeepWith = cloneDeepWith;
16795    lodash.cloneWith = cloneWith;
16796    lodash.conformsTo = conformsTo;
16797    lodash.deburr = deburr;
16798    lodash.defaultTo = defaultTo;
16799    lodash.divide = divide;
16800    lodash.endsWith = endsWith;
16801    lodash.eq = eq;
16802    lodash.escape = escape;
16803    lodash.escapeRegExp = escapeRegExp;
16804    lodash.every = every;
16805    lodash.find = find;
16806    lodash.findIndex = findIndex;
16807    lodash.findKey = findKey;
16808    lodash.findLast = findLast;
16809    lodash.findLastIndex = findLastIndex;
16810    lodash.findLastKey = findLastKey;
16811    lodash.floor = floor;
16812    lodash.forEach = forEach;
16813    lodash.forEachRight = forEachRight;
16814    lodash.forIn = forIn;
16815    lodash.forInRight = forInRight;
16816    lodash.forOwn = forOwn;
16817    lodash.forOwnRight = forOwnRight;
16818    lodash.get = get;
16819    lodash.gt = gt;
16820    lodash.gte = gte;
16821    lodash.has = has;
16822    lodash.hasIn = hasIn;
16823    lodash.head = head;
16824    lodash.identity = identity;
16825    lodash.includes = includes;
16826    lodash.indexOf = indexOf;
16827    lodash.inRange = inRange;
16828    lodash.invoke = invoke;
16829    lodash.isArguments = isArguments;
16830    lodash.isArray = isArray;
16831    lodash.isArrayBuffer = isArrayBuffer;
16832    lodash.isArrayLike = isArrayLike;
16833    lodash.isArrayLikeObject = isArrayLikeObject;
16834    lodash.isBoolean = isBoolean;
16835    lodash.isBuffer = isBuffer;
16836    lodash.isDate = isDate;
16837    lodash.isElement = isElement;
16838    lodash.isEmpty = isEmpty;
16839    lodash.isEqual = isEqual;
16840    lodash.isEqualWith = isEqualWith;
16841    lodash.isError = isError;
16842    lodash.isFinite = isFinite;
16843    lodash.isFunction = isFunction;
16844    lodash.isInteger = isInteger;
16845    lodash.isLength = isLength;
16846    lodash.isMap = isMap;
16847    lodash.isMatch = isMatch;
16848    lodash.isMatchWith = isMatchWith;
16849    lodash.isNaN = isNaN;
16850    lodash.isNative = isNative;
16851    lodash.isNil = isNil;
16852    lodash.isNull = isNull;
16853    lodash.isNumber = isNumber;
16854    lodash.isObject = isObject;
16855    lodash.isObjectLike = isObjectLike;
16856    lodash.isPlainObject = isPlainObject;
16857    lodash.isRegExp = isRegExp;
16858    lodash.isSafeInteger = isSafeInteger;
16859    lodash.isSet = isSet;
16860    lodash.isString = isString;
16861    lodash.isSymbol = isSymbol;
16862    lodash.isTypedArray = isTypedArray;
16863    lodash.isUndefined = isUndefined;
16864    lodash.isWeakMap = isWeakMap;
16865    lodash.isWeakSet = isWeakSet;
16866    lodash.join = join;
16867    lodash.kebabCase = kebabCase;
16868    lodash.last = last;
16869    lodash.lastIndexOf = lastIndexOf;
16870    lodash.lowerCase = lowerCase;
16871    lodash.lowerFirst = lowerFirst;
16872    lodash.lt = lt;
16873    lodash.lte = lte;
16874    lodash.max = max;
16875    lodash.maxBy = maxBy;
16876    lodash.mean = mean;
16877    lodash.meanBy = meanBy;
16878    lodash.min = min;
16879    lodash.minBy = minBy;
16880    lodash.stubArray = stubArray;
16881    lodash.stubFalse = stubFalse;
16882    lodash.stubObject = stubObject;
16883    lodash.stubString = stubString;
16884    lodash.stubTrue = stubTrue;
16885    lodash.multiply = multiply;
16886    lodash.nth = nth;
16887    lodash.noConflict = noConflict;
16888    lodash.noop = noop;
16889    lodash.now = now;
16890    lodash.pad = pad;
16891    lodash.padEnd = padEnd;
16892    lodash.padStart = padStart;
16893    lodash.parseInt = parseInt;
16894    lodash.random = random;
16895    lodash.reduce = reduce;
16896    lodash.reduceRight = reduceRight;
16897    lodash.repeat = repeat;
16898    lodash.replace = replace;
16899    lodash.result = result;
16900    lodash.round = round;
16901    lodash.runInContext = runInContext;
16902    lodash.sample = sample;
16903    lodash.size = size;
16904    lodash.snakeCase = snakeCase;
16905    lodash.some = some;
16906    lodash.sortedIndex = sortedIndex;
16907    lodash.sortedIndexBy = sortedIndexBy;
16908    lodash.sortedIndexOf = sortedIndexOf;
16909    lodash.sortedLastIndex = sortedLastIndex;
16910    lodash.sortedLastIndexBy = sortedLastIndexBy;
16911    lodash.sortedLastIndexOf = sortedLastIndexOf;
16912    lodash.startCase = startCase;
16913    lodash.startsWith = startsWith;
16914    lodash.subtract = subtract;
16915    lodash.sum = sum;
16916    lodash.sumBy = sumBy;
16917    lodash.template = template;
16918    lodash.times = times;
16919    lodash.toFinite = toFinite;
16920    lodash.toInteger = toInteger;
16921    lodash.toLength = toLength;
16922    lodash.toLower = toLower;
16923    lodash.toNumber = toNumber;
16924    lodash.toSafeInteger = toSafeInteger;
16925    lodash.toString = toString;
16926    lodash.toUpper = toUpper;
16927    lodash.trim = trim;
16928    lodash.trimEnd = trimEnd;
16929    lodash.trimStart = trimStart;
16930    lodash.truncate = truncate;
16931    lodash.unescape = unescape;
16932    lodash.uniqueId = uniqueId;
16933    lodash.upperCase = upperCase;
16934    lodash.upperFirst = upperFirst;
16935
16936    // Add aliases.
16937    lodash.each = forEach;
16938    lodash.eachRight = forEachRight;
16939    lodash.first = head;
16940
16941    mixin(lodash, (function() {
16942      var source = {};
16943      baseForOwn(lodash, function(func, methodName) {
16944        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16945          source[methodName] = func;
16946        }
16947      });
16948      return source;
16949    }()), { 'chain': false });
16950
16951    /*------------------------------------------------------------------------*/
16952
16953    /**
16954     * The semantic version number.
16955     *
16956     * @static
16957     * @memberOf _
16958     * @type {string}
16959     */
16960    lodash.VERSION = VERSION;
16961
16962    // Assign default placeholders.
16963    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16964      lodash[methodName].placeholder = lodash;
16965    });
16966
16967    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16968    arrayEach(['drop', 'take'], function(methodName, index) {
16969      LazyWrapper.prototype[methodName] = function(n) {
vendor: 7,434 bytes, lines 16970-17187
16970        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16971
16972        var result = (this.__filtered__ && !index)
16973          ? new LazyWrapper(this)
16974          : this.clone();
16975
16976        if (result.__filtered__) {
16977          result.__takeCount__ = nativeMin(n, result.__takeCount__);
16978        } else {
16979          result.__views__.push({
16980            'size': nativeMin(n, MAX_ARRAY_LENGTH),
16981            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16982          });
16983        }
16984        return result;
16985      };
16986
16987      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16988        return this.reverse()[methodName](n).reverse();
16989      };
16990    });
16991
16992    // Add `LazyWrapper` methods that accept an `iteratee` value.
16993    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16994      var type = index + 1,
16995          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16996
16997      LazyWrapper.prototype[methodName] = function(iteratee) {
16998        var result = this.clone();
16999        result.__iteratees__.push({
17000          'iteratee': getIteratee(iteratee, 3),
17001          'type': type
17002        });
17003        result.__filtered__ = result.__filtered__ || isFilter;
17004        return result;
17005      };
17006    });
17007
17008    // Add `LazyWrapper` methods for `_.head` and `_.last`.
17009    arrayEach(['head', 'last'], function(methodName, index) {
17010      var takeName = 'take' + (index ? 'Right' : '');
17011
17012      LazyWrapper.prototype[methodName] = function() {
17013        return this[takeName](1).value()[0];
17014      };
17015    });
17016
17017    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
17018    arrayEach(['initial', 'tail'], function(methodName, index) {
17019      var dropName = 'drop' + (index ? '' : 'Right');
17020
17021      LazyWrapper.prototype[methodName] = function() {
17022        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
17023      };
17024    });
17025
17026    LazyWrapper.prototype.compact = function() {
17027      return this.filter(identity);
17028    };
17029
17030    LazyWrapper.prototype.find = function(predicate) {
17031      return this.filter(predicate).head();
17032    };
17033
17034    LazyWrapper.prototype.findLast = function(predicate) {
17035      return this.reverse().find(predicate);
17036    };
17037
17038    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
17039      if (typeof path == 'function') {
17040        return new LazyWrapper(this);
17041      }
17042      return this.map(function(value) {
17043        return baseInvoke(value, path, args);
17044      });
17045    });
17046
17047    LazyWrapper.prototype.reject = function(predicate) {
17048      return this.filter(negate(getIteratee(predicate)));
17049    };
17050
17051    LazyWrapper.prototype.slice = function(start, end) {
17052      start = toInteger(start);
17053
17054      var result = this;
17055      if (result.__filtered__ && (start > 0 || end < 0)) {
17056        return new LazyWrapper(result);
17057      }
17058      if (start < 0) {
17059        result = result.takeRight(-start);
17060      } else if (start) {
17061        result = result.drop(start);
17062      }
17063      if (end !== undefined) {
17064        end = toInteger(end);
17065        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
17066      }
17067      return result;
17068    };
17069
17070    LazyWrapper.prototype.takeRightWhile = function(predicate) {
17071      return this.reverse().takeWhile(predicate).reverse();
17072    };
17073
17074    LazyWrapper.prototype.toArray = function() {
17075      return this.take(MAX_ARRAY_LENGTH);
17076    };
17077
17078    // Add `LazyWrapper` methods to `lodash.prototype`.
17079    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17080      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
17081          isTaker = /^(?:head|last)$/.test(methodName),
17082          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
17083          retUnwrapped = isTaker || /^find/.test(methodName);
17084
17085      if (!lodashFunc) {
17086        return;
17087      }
17088      lodash.prototype[methodName] = function() {
17089        var value = this.__wrapped__,
17090            args = isTaker ? [1] : arguments,
17091            isLazy = value instanceof LazyWrapper,
17092            iteratee = args[0],
17093            useLazy = isLazy || isArray(value);
17094
17095        var interceptor = function(value) {
17096          var result = lodashFunc.apply(lodash, arrayPush([value], args));
17097          return (isTaker && chainAll) ? result[0] : result;
17098        };
17099
17100        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
17101          // Avoid lazy use if the iteratee has a "length" value other than `1`.
17102          isLazy = useLazy = false;
17103        }
17104        var chainAll = this.__chain__,
17105            isHybrid = !!this.__actions__.length,
17106            isUnwrapped = retUnwrapped && !chainAll,
17107            onlyLazy = isLazy && !isHybrid;
17108
17109        if (!retUnwrapped && useLazy) {
17110          value = onlyLazy ? value : new LazyWrapper(this);
17111          var result = func.apply(value, args);
17112          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
17113          return new LodashWrapper(result, chainAll);
17114        }
17115        if (isUnwrapped && onlyLazy) {
17116          return func.apply(this, args);
17117        }
17118        result = this.thru(interceptor);
17119        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
17120      };
17121    });
17122
17123    // Add `Array` methods to `lodash.prototype`.
17124    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
17125      var func = arrayProto[methodName],
17126          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
17127          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
17128
17129      lodash.prototype[methodName] = function() {
17130        var args = arguments;
17131        if (retUnwrapped && !this.__chain__) {
17132          var value = this.value();
17133          return func.apply(isArray(value) ? value : [], args);
17134        }
17135        return this[chainName](function(value) {
17136          return func.apply(isArray(value) ? value : [], args);
17137        });
17138      };
17139    });
17140
17141    // Map minified method names to their real names.
17142    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17143      var lodashFunc = lodash[methodName];
17144      if (lodashFunc) {
17145        var key = lodashFunc.name + '';
17146        if (!hasOwnProperty.call(realNames, key)) {
17147          realNames[key] = [];
17148        }
17149        realNames[key].push({ 'name': methodName, 'func': lodashFunc });
17150      }
17151    });
17152
17153    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
17154      'name': 'wrapper',
17155      'func': undefined
17156    }];
17157
17158    // Add methods to `LazyWrapper`.
17159    LazyWrapper.prototype.clone = lazyClone;
17160    LazyWrapper.prototype.reverse = lazyReverse;
17161    LazyWrapper.prototype.value = lazyValue;
17162
17163    // Add chain sequence methods to the `lodash` wrapper.
17164    lodash.prototype.at = wrapperAt;
17165    lodash.prototype.chain = wrapperChain;
17166    lodash.prototype.commit = wrapperCommit;
17167    lodash.prototype.next = wrapperNext;
17168    lodash.prototype.plant = wrapperPlant;
17169    lodash.prototype.reverse = wrapperReverse;
17170    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
17171
17172    // Add lazy aliases.
17173    lodash.prototype.first = lodash.prototype.head;
17174
17175    if (symIterator) {
17176      lodash.prototype[symIterator] = wrapperToIterator;
17177    }
17178    return lodash;
17179  });
17180
17181  /*--------------------------------------------------------------------------*/
17182
17183  // Export lodash.
17184  var _ = runInContext();
17185
17186  // Some AMD build optimizers, like r.js, check for condition patterns like:
17187  if (t
17187ypeof define == 'function' && typeof define.amd == 'object' && define.amd) {
17188    // Expose Lodash on the global object to prevent errors when Lodash is
17189    // loaded by a script tag in the presence of an AMD loader.
17190    // See http://requirejs.org/docs/errors.html#mismatch for more details.
17191    // Use `_.noConflict` to remove Lodash from the global object.
17192    root._ = _;
17193
17194    // Define as an anonymous module so, through path mapping, it can be
17195    // referenced as the "underscore" module.
17196    define(function() {
17197      return _;
17198    });
17199  }
17200  // Check for `exports` after `define` in case a build optimizer adds it.
17201  else if (freeModule) {
17202    // Export for Node.js.
17203    (freeModule.exports = _)._ = _;
17204    // Export for CommonJS support.
17205    freeExports._ = _;
17206  }
17207  else {
17208    // Export to the global object.
17209    root._ = _;
17210  }
17211}.call(this));
17212
17213}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
17214},{}],2:[function(require,module,exports){
17215//! moment.js
17216//! version : 2.29.4
17217//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
17218//! license : MIT
17219//! momentjs.com
17220
17221;(function (global, factory) {
17222    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
17223    typeof define === 'function' && define.amd ? define(factory) :
17224    global.moment = factory()
17225}(this, (function () { 'use strict';
17226
17227    var hookCallback;
17228
17229    function hooks() {
17230        return hookCallback.apply(null, arguments);
17231    }
17232
17233    // This is done to register the method called with moment()
17234    // without creating circular dependencies.
17235    function setHookCallback(callback) {
17236        hookCallback = callback;
17237    }
17238
17239    function isArray(input) {
17240        return (
17241            input instanceof Array ||
17242            Object.prototype.toString.call(input) === '[object Array]'
17243        );
17244    }
17245
17246    function isObject(input) {
17247        // IE8 will treat undefined and null as object if it wasn't for
17248        // input != null
17249        return (
17250            input != null &&
17251            Object.prototype.toString.call(input) === '[object Object]'
17252        );
17253    }
17254
17255    function hasOwnProp(a, b) {
17256        return Object.prototype.hasOwnProperty.call(a, b);
17257    }
17258
17259    function isObjectEmpty(obj) {
17260        if (Object.getOwnPropertyNames) {
17261            return Object.getOwnPropertyNames(obj).length === 0;
17262        } else {
17263            var k;
17264            for (k in obj) {
17265                if (hasOwnProp(obj, k)) {
17266                    return false;
vendor: 11,502 bytes, lines 17267-17669
17267                }
17268            }
17269            return true;
17270        }
17271    }
17272
17273    function isUndefined(input) {
17274        return input === void 0;
17275    }
17276
17277    function isNumber(input) {
17278        return (
17279            typeof input === 'number' ||
17280            Object.prototype.toString.call(input) === '[object Number]'
17281        );
17282    }
17283
17284    function isDate(input) {
17285        return (
17286            input instanceof Date ||
17287            Object.prototype.toString.call(input) === '[object Date]'
17288        );
17289    }
17290
17291    function map(arr, fn) {
17292        var res = [],
17293            i,
17294            arrLen = arr.length;
17295        for (i = 0; i < arrLen; ++i) {
17296            res.push(fn(arr[i], i));
17297        }
17298        return res;
17299    }
17300
17301    function extend(a, b) {
17302        for (var i in b) {
17303            if (hasOwnProp(b, i)) {
17304                a[i] = b[i];
17305            }
17306        }
17307
17308        if (hasOwnProp(b, 'toString')) {
17309            a.toString = b.toString;
17310        }
17311
17312        if (hasOwnProp(b, 'valueOf')) {
17313            a.valueOf = b.valueOf;
17314        }
17315
17316        return a;
17317    }
17318
17319    function createUTC(input, format, locale, strict) {
17320        return createLocalOrUTC(input, format, locale, strict, true).utc();
17321    }
17322
17323    function defaultParsingFlags() {
17324        // We need to deep clone this object.
17325        return {
17326            empty: false,
17327            unusedTokens: [],
17328            unusedInput: [],
17329            overflow: -2,
17330            charsLeftOver: 0,
17331            nullInput: false,
17332            invalidEra: null,
17333            invalidMonth: null,
17334            invalidFormat: false,
17335            userInvalidated: false,
17336            iso: false,
17337            parsedDateParts: [],
17338            era: null,
17339            meridiem: null,
17340            rfc2822: false,
17341            weekdayMismatch: false,
17342        };
17343    }
17344
17345    function getParsingFlags(m) {
17346        if (m._pf == null) {
17347            m._pf = defaultParsingFlags();
17348        }
17349        return m._pf;
17350    }
17351
17352    var some;
17353    if (Array.prototype.some) {
17354        some = Array.prototype.some;
17355    } else {
17356        some = function (fun) {
17357            var t = Object(this),
17358                len = t.length >>> 0,
17359                i;
17360
17361            for (i = 0; i < len; i++) {
17362                if (i in t && fun.call(this, t[i], i, t)) {
17363                    return true;
17364                }
17365            }
17366
17367            return false;
17368        };
17369    }
17370
17371    function isValid(m) {
17372        if (m._isValid == null) {
17373            var flags = getParsingFlags(m),
17374                parsedParts = some.call(flags.parsedDateParts, function (i) {
17375                    return i != null;
17376                }),
17377                isNowValid =
17378                    !isNaN(m._d.getTime()) &&
17379                    flags.overflow < 0 &&
17380                    !flags.empty &&
17381                    !flags.invalidEra &&
17382                    !flags.invalidMonth &&
17383                    !flags.invalidWeekday &&
17384                    !flags.weekdayMismatch &&
17385                    !flags.nullInput &&
17386                    !flags.invalidFormat &&
17387                    !flags.userInvalidated &&
17388                    (!flags.meridiem || (flags.meridiem && parsedParts));
17389
17390            if (m._strict) {
17391                isNowValid =
17392                    isNowValid &&
17393                    flags.charsLeftOver === 0 &&
17394                    flags.unusedTokens.length === 0 &&
17395                    flags.bigHour === undefined;
17396            }
17397
17398            if (Object.isFrozen == null || !Object.isFrozen(m)) {
17399                m._isValid = isNowValid;
17400            } else {
17401                return isNowValid;
17402            }
17403        }
17404        return m._isValid;
17405    }
17406
17407    function createInvalid(flags) {
17408        var m = createUTC(NaN);
17409        if (flags != null) {
17410            extend(getParsingFlags(m), flags);
17411        } else {
17412            getParsingFlags(m).userInvalidated = true;
17413        }
17414
17415        return m;
17416    }
17417
17418    // Plugins that add properties should also add the key here (null value),
17419    // so we can properly clone ourselves.
17420    var momentProperties = (hooks.momentProperties = []),
17421        updateInProgress = false;
17422
17423    function copyConfig(to, from) {
17424        var i,
17425            prop,
17426            val,
17427            momentPropertiesLen = momentProperties.length;
17428
17429        if (!isUndefined(from._isAMomentObject)) {
17430            to._isAMomentObject = from._isAMomentObject;
17431        }
17432        if (!isUndefined(from._i)) {
17433            to._i = from._i;
17434        }
17435        if (!isUndefined(from._f)) {
17436            to._f = from._f;
17437        }
17438        if (!isUndefined(from._l)) {
17439            to._l = from._l;
17440        }
17441        if (!isUndefined(from._strict)) {
17442            to._strict = from._strict;
17443        }
17444        if (!isUndefined(from._tzm)) {
17445            to._tzm = from._tzm;
17446        }
17447        if (!isUndefined(from._isUTC)) {
17448            to._isUTC = from._isUTC;
17449        }
17450        if (!isUndefined(from._offset)) {
17451            to._offset = from._offset;
17452        }
17453        if (!isUndefined(from._pf)) {
17454            to._pf = getParsingFlags(from);
17455        }
17456        if (!isUndefined(from._locale)) {
17457            to._locale = from._locale;
17458        }
17459
17460        if (momentPropertiesLen > 0) {
17461            for (i = 0; i < momentPropertiesLen; i++) {
17462                prop = momentProperties[i];
17463                val = from[prop];
17464                if (!isUndefined(val)) {
17465                    to[prop] = val;
17466                }
17467            }
17468        }
17469
17470        return to;
17471    }
17472
17473    // Moment prototype object
17474    function Moment(config) {
17475        copyConfig(this, config);
17476        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
17477        if (!this.isValid()) {
17478            this._d = new Date(NaN);
17479        }
17480        // Prevent infinite loop in case updateOffset creates new moment
17481        // objects.
17482        if (updateInProgress === false) {
17483            updateInProgress = true;
17484            hooks.updateOffset(this);
17485            updateInProgress = false;
17486        }
17487    }
17488
17489    function isMoment(obj) {
17490        return (
17491            obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
17492        );
17493    }
17494
17495    function warn(msg) {
17496        if (
17497            hooks.suppressDeprecationWarnings === false &&
17498            typeof console !== 'undefined' &&
17499            console.warn
17500        ) {
17501            console.warn('Deprecation warning: ' + msg);
17502        }
17503    }
17504
17505    function deprecate(msg, fn) {
17506        var firstTime = true;
17507
17508        return extend(function () {
17509            if (hooks.deprecationHandler != null) {
17510                hooks.deprecationHandler(null, msg);
17511            }
17512            if (firstTime) {
17513                var args = [],
17514                    arg,
17515                    i,
17516                    key,
17517                    argLen = arguments.length;
17518                for (i = 0; i < argLen; i++) {
17519                    arg = '';
17520                    if (typeof arguments[i] === 'object') {
17521                        arg += '\n[' + i + '] ';
17522                        for (key in arguments[0]) {
17523                            if (hasOwnProp(arguments[0], key)) {
17524                                arg += key + ': ' + arguments[0][key] + ', ';
17525                            }
17526                        }
17527                        arg = arg.slice(0, -2); // Remove trailing comma and space
17528                    } else {
17529                        arg = arguments[i];
17530                    }
17531                    args.push(arg);
17532                }
17533                warn(
17534                    msg +
17535                        '\nArguments: ' +
17536                        Array.prototype.slice.call(args).join('') +
17537                        '\n' +
17538                        new Error().stack
17539                );
17540                firstTime = false;
17541            }
17542            return fn.apply(this, arguments);
17543        }, fn);
17544    }
17545
17546    var deprecations = {};
17547
17548    function deprecateSimple(name, msg) {
17549        if (hooks.deprecationHandler != null) {
17550            hooks.deprecationHandler(name, msg);
17551        }
17552        if (!deprecations[name]) {
17553            warn(msg);
17554            deprecations[name] = true;
17555        }
17556    }
17557
17558    hooks.suppressDeprecationWarnings = false;
17559    hooks.deprecationHandler = null;
17560
17561    function isFunction(input) {
17562        return (
17563            (typeof Function !== 'undefined' && input instanceof Function) ||
17564            Object.prototype.toString.call(input) === '[object Function]'
17565        );
17566    }
17567
17568    function set(config) {
17569        var prop, i;
17570        for (i in config) {
17571            if (hasOwnProp(config, i)) {
17572                prop = config[i];
17573                if (isFunction(prop)) {
17574                    this[i] = prop;
17575                } else {
17576                    this['_' + i] = prop;
17577                }
17578            }
17579        }
17580        this._config = config;
17581        // Lenient ordinal parsing accepts just a number in addition to
17582        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
17583        // TODO: Remove "ordinalParse" fallback in next major release.
17584        this._dayOfMonthOrdinalParseLenient = new RegExp(
17585            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
17586                '|' +
17587                /\d{1,2}/.source
17588        );
17589    }
17590
17591    function mergeConfigs(parentConfig, childConfig) {
17592        var res = extend({}, parentConfig),
17593            prop;
17594        for (prop in childConfig) {
17595            if (hasOwnProp(childConfig, prop)) {
17596                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
17597                    res[prop] = {};
17598                    extend(res[prop], parentConfig[prop]);
17599                    extend(res[prop], childConfig[prop]);
17600                } else if (childConfig[prop] != null) {
17601                    res[prop] = childConfig[prop];
17602                } else {
17603                    delete res[prop];
17604                }
17605            }
17606        }
17607        for (prop in parentConfig) {
17608            if (
17609                hasOwnProp(parentConfig, prop) &&
17610                !hasOwnProp(childConfig, prop) &&
17611                isObject(parentConfig[prop])
17612            ) {
17613                // make sure changes to properties don't modify parent config
17614                res[prop] = extend({}, res[prop]);
17615            }
17616        }
17617        return res;
17618    }
17619
17620    function Locale(config) {
17621        if (config != null) {
17622            this.set(config);
17623        }
17624    }
17625
17626    var keys;
17627
17628    if (Object.keys) {
17629        keys = Object.keys;
17630    } else {
17631        keys = function (obj) {
17632            var i,
17633                res = [];
17634            for (i in obj) {
17635                if (hasOwnProp(obj, i)) {
17636                    res.push(i);
17637                }
17638            }
17639            return res;
17640        };
17641    }
17642
17643    var defaultCalendar = {
17644        sameDay: '[Today at] LT',
17645        nextDay: '[Tomorrow at] LT',
17646        nextWeek: 'dddd [at] LT',
17647        lastDay: '[Yesterday at] LT',
17648        lastWeek: '[Last] dddd [at] LT',
17649        sameElse: 'L',
17650    };
17651
17652    function calendar(key, mom, now) {
17653        var output = this._calendar[key] || this._calendar['sameElse'];
17654        return isFunction(output) ? output.call(mom, now) : output;
17655    }
17656
17657    function zeroFill(number, targetLength, forceSign) {
17658        var absNumber = '' + Math.abs(number),
17659            zerosToFill = targetLength - absNumber.length,
17660            sign = number >= 0;
17661        return (
17662            (sign ? (forceSign ? '+' : '') : '-') +
17663            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
17664            absNumber
17665        );
17666    }
17667
17668    var formattingTokens =
17669           
vendor: 8,563 bytes, lines 17669-17973
17669 /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
17670        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
17671        formatFunctions = {},
17672        formatTokenFunctions = {};
17673
17674    // token:    'M'
17675    // padded:   ['MM', 2]
17676    // ordinal:  'Mo'
17677    // callback: function () { this.month() + 1 }
17678    function addFormatToken(token, padded, ordinal, callback) {
17679        var func = callback;
17680        if (typeof callback === 'string') {
17681            func = function () {
17682                return this[callback]();
17683            };
17684        }
17685        if (token) {
17686            formatTokenFunctions[token] = func;
17687        }
17688        if (padded) {
17689            formatTokenFunctions[padded[0]] = function () {
17690                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
17691            };
17692        }
17693        if (ordinal) {
17694            formatTokenFunctions[ordinal] = function () {
17695                return this.localeData().ordinal(
17696                    func.apply(this, arguments),
17697                    token
17698                );
17699            };
17700        }
17701    }
17702
17703    function removeFormattingTokens(input) {
17704        if (input.match(/\[[\s\S]/)) {
17705            return input.replace(/^\[|\]$/g, '');
17706        }
17707        return input.replace(/\\/g, '');
17708    }
17709
17710    function makeFormatFunction(format) {
17711        var array = format.match(formattingTokens),
17712            i,
17713            length;
17714
17715        for (i = 0, length = array.length; i < length; i++) {
17716            if (formatTokenFunctions[array[i]]) {
17717                array[i] = formatTokenFunctions[array[i]];
17718            } else {
17719                array[i] = removeFormattingTokens(array[i]);
17720            }
17721        }
17722
17723        return function (mom) {
17724            var output = '',
17725                i;
17726            for (i = 0; i < length; i++) {
17727                output += isFunction(array[i])
17728                    ? array[i].call(mom, format)
17729                    : array[i];
17730            }
17731            return output;
17732        };
17733    }
17734
17735    // format date using native date object
17736    function formatMoment(m, format) {
17737        if (!m.isValid()) {
17738            return m.localeData().invalidDate();
17739        }
17740
17741        format = expandFormat(format, m.localeData());
17742        formatFunctions[format] =
17743            formatFunctions[format] || makeFormatFunction(format);
17744
17745        return formatFunctions[format](m);
17746    }
17747
17748    function expandFormat(format, locale) {
17749        var i = 5;
17750
17751        function replaceLongDateFormatTokens(input) {
17752            return locale.longDateFormat(input) || input;
17753        }
17754
17755        localFormattingTokens.lastIndex = 0;
17756        while (i >= 0 && localFormattingTokens.test(format)) {
17757            format = format.replace(
17758                localFormattingTokens,
17759                replaceLongDateFormatTokens
17760            );
17761            localFormattingTokens.lastIndex = 0;
17762            i -= 1;
17763        }
17764
17765        return format;
17766    }
17767
17768    var defaultLongDateFormat = {
17769        LTS: 'h:mm:ss A',
17770        LT: 'h:mm A',
17771        L: 'MM/DD/YYYY',
17772        LL: 'MMMM D, YYYY',
17773        LLL: 'MMMM D, YYYY h:mm A',
17774        LLLL: 'dddd, MMMM D, YYYY h:mm A',
17775    };
17776
17777    function longDateFormat(key) {
17778        var format = this._longDateFormat[key],
17779            formatUpper = this._longDateFormat[key.toUpperCase()];
17780
17781        if (format || !formatUpper) {
17782            return format;
17783        }
17784
17785        this._longDateFormat[key] = formatUpper
17786            .match(formattingTokens)
17787            .map(function (tok) {
17788                if (
17789                    tok === 'MMMM' ||
17790                    tok === 'MM' ||
17791                    tok === 'DD' ||
17792                    tok === 'dddd'
17793                ) {
17794                    return tok.slice(1);
17795                }
17796                return tok;
17797            })
17798            .join('');
17799
17800        return this._longDateFormat[key];
17801    }
17802
17803    var defaultInvalidDate = 'Invalid date';
17804
17805    function invalidDate() {
17806        return this._invalidDate;
17807    }
17808
17809    var defaultOrdinal = '%d',
17810        defaultDayOfMonthOrdinalParse = /\d{1,2}/;
17811
17812    function ordinal(number) {
17813        return this._ordinal.replace('%d', number);
17814    }
17815
17816    var defaultRelativeTime = {
17817        future: 'in %s',
17818        past: '%s ago',
17819        s: 'a few seconds',
17820        ss: '%d seconds',
17821        m: 'a minute',
17822        mm: '%d minutes',
17823        h: 'an hour',
17824        hh: '%d hours',
17825        d: 'a day',
17826        dd: '%d days',
17827        w: 'a week',
17828        ww: '%d weeks',
17829        M: 'a month',
17830        MM: '%d months',
17831        y: 'a year',
17832        yy: '%d years',
17833    };
17834
17835    function relativeTime(number, withoutSuffix, string, isFuture) {
17836        var output = this._relativeTime[string];
17837        return isFunction(output)
17838            ? output(number, withoutSuffix, string, isFuture)
17839            : output.replace(/%d/i, number);
17840    }
17841
17842    function pastFuture(diff, output) {
17843        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
17844        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
17845    }
17846
17847    var aliases = {};
17848
17849    function addUnitAlias(unit, shorthand) {
17850        var lowerCase = unit.toLowerCase();
17851        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
17852    }
17853
17854    function normalizeUnits(units) {
17855        return typeof units === 'string'
17856            ? aliases[units] || aliases[units.toLowerCase()]
17857            : undefined;
17858    }
17859
17860    function normalizeObjectUnits(inputObject) {
17861        var normalizedInput = {},
17862            normalizedProp,
17863            prop;
17864
17865        for (prop in inputObject) {
17866            if (hasOwnProp(inputObject, prop)) {
17867                normalizedProp = normalizeUnits(prop);
17868                if (normalizedProp) {
17869                    normalizedInput[normalizedProp] = inputObject[prop];
17870                }
17871            }
17872        }
17873
17874        return normalizedInput;
17875    }
17876
17877    var priorities = {};
17878
17879    function addUnitPriority(unit, priority) {
17880        priorities[unit] = priority;
17881    }
17882
17883    function getPrioritizedUnits(unitsObj) {
17884        var units = [],
17885            u;
17886        for (u in unitsObj) {
17887            if (hasOwnProp(unitsObj, u)) {
17888                units.push({ unit: u, priority: priorities[u] });
17889            }
17890        }
17891        units.sort(function (a, b) {
17892            return a.priority - b.priority;
17893        });
17894        return units;
17895    }
17896
17897    function isLeapYear(year) {
17898        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
17899    }
17900
17901    function absFloor(number) {
17902        if (number < 0) {
17903            // -0 -> 0
17904            return Math.ceil(number) || 0;
17905        } else {
17906            return Math.floor(number);
17907        }
17908    }
17909
17910    function toInt(argumentForCoercion) {
17911        var coercedNumber = +argumentForCoercion,
17912            value = 0;
17913
17914        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
17915            value = absFloor(coercedNumber);
17916        }
17917
17918        return value;
17919    }
17920
17921    function makeGetSet(unit, keepTime) {
17922        return function (value) {
17923            if (value != null) {
17924                set$1(this, unit, value);
17925                hooks.updateOffset(this, keepTime);
17926                return this;
17927            } else {
17928                return get(this, unit);
17929            }
17930        };
17931    }
17932
17933    function get(mom, unit) {
17934        return mom.isValid()
17935            ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
17936            : NaN;
17937    }
17938
17939    function set$1(mom, unit, value) {
17940        if (mom.isValid() && !isNaN(value)) {
17941            if (
17942                unit === 'FullYear' &&
17943                isLeapYear(mom.year()) &&
17944                mom.month() === 1 &&
17945                mom.date() === 29
17946            ) {
17947                value = toInt(value);
17948                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
17949                    value,
17950                    mom.month(),
17951                    daysInMonth(value, mom.month())
17952                );
17953            } else {
17954                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
17955            }
17956        }
17957    }
17958
17959    // MOMENTS
17960
17961    function stringGet(units) {
17962        units = normalizeUnits(units);
17963        if (isFunction(this[units])) {
17964            return this[units]();
17965        }
17966        return this;
17967    }
17968
17969    function stringSet(units, value) {
17970        if (typeof units === 'object') {
17971            units = normalizeObjectUnits(units);
17972            var prioritized = getPrioritizedUnits(units),
17973                i
vendor: 5,547 bytes, lines 17973-18159
17973,
17974                prioritizedLen = prioritized.length;
17975            for (i = 0; i < prioritizedLen; i++) {
17976                this[prioritized[i].unit](units[prioritized[i].unit]);
17977            }
17978        } else {
17979            units = normalizeUnits(units);
17980            if (isFunction(this[units])) {
17981                return this[units](value);
17982            }
17983        }
17984        return this;
17985    }
17986
17987    var match1 = /\d/, //       0 - 9
17988        match2 = /\d\d/, //      00 - 99
17989        match3 = /\d{3}/, //     000 - 999
17990        match4 = /\d{4}/, //    0000 - 9999
17991        match6 = /[+-]?\d{6}/, // -999999 - 999999
17992        match1to2 = /\d\d?/, //       0 - 99
17993        match3to4 = /\d\d\d\d?/, //     999 - 9999
17994        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
17995        match1to3 = /\d{1,3}/, //       0 - 999
17996        match1to4 = /\d{1,4}/, //       0 - 9999
17997        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
17998        matchUnsigned = /\d+/, //       0 - inf
17999        matchSigned = /[+-]?\d+/, //    -inf - inf
18000        matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
18001        matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
18002        matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
18003        // any word (or two) characters or numbers including two/three word month in arabic.
18004        // includes scottish gaelic two word and hyphenated months
18005        matchWord =
18006            /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,
18007        regexes;
18008
18009    regexes = {};
18010
18011    function addRegexToken(token, regex, strictRegex) {
18012        regexes[token] = isFunction(regex)
18013            ? regex
18014            : function (isStrict, localeData) {
18015                  return isStrict && strictRegex ? strictRegex : regex;
18016              };
18017    }
18018
18019    function getParseRegexForToken(token, config) {
18020        if (!hasOwnProp(regexes, token)) {
18021            return new RegExp(unescapeFormat(token));
18022        }
18023
18024        return regexes[token](config._strict, config._locale);
18025    }
18026
18027    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
18028    function unescapeFormat(s) {
18029        return regexEscape(
18030            s
18031                .replace('\\', '')
18032                .replace(
18033                    /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,
18034                    function (matched, p1, p2, p3, p4) {
18035                        return p1 || p2 || p3 || p4;
18036                    }
18037                )
18038        );
18039    }
18040
18041    function regexEscape(s) {
18042        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
18043    }
18044
18045    var tokens = {};
18046
18047    function addParseToken(token, callback) {
18048        var i,
18049            func = callback,
18050            tokenLen;
18051        if (typeof token === 'string') {
18052            token = [token];
18053        }
18054        if (isNumber(callback)) {
18055            func = function (input, array) {
18056                array[callback] = toInt(input);
18057            };
18058        }
18059        tokenLen = token.length;
18060        for (i = 0; i < tokenLen; i++) {
18061            tokens[token[i]] = func;
18062        }
18063    }
18064
18065    function addWeekParseToken(token, callback) {
18066        addParseToken(token, function (input, array, config, token) {
18067            config._w = config._w || {};
18068            callback(input, config._w, config, token);
18069        });
18070    }
18071
18072    function addTimeToArrayFromToken(token, input, config) {
18073        if (input != null && hasOwnProp(tokens, token)) {
18074            tokens[token](input, config._a, config, token);
18075        }
18076    }
18077
18078    var YEAR = 0,
18079        MONTH = 1,
18080        DATE = 2,
18081        HOUR = 3,
18082        MINUTE = 4,
18083        SECOND = 5,
18084        MILLISECOND = 6,
18085        WEEK = 7,
18086        WEEKDAY = 8;
18087
18088    function mod(n, x) {
18089        return ((n % x) + x) % x;
18090    }
18091
18092    var indexOf;
18093
18094    if (Array.prototype.indexOf) {
18095        indexOf = Array.prototype.indexOf;
18096    } else {
18097        indexOf = function (o) {
18098            // I know
18099            var i;
18100            for (i = 0; i < this.length; ++i) {
18101                if (this[i] === o) {
18102                    return i;
18103                }
18104            }
18105            return -1;
18106        };
18107    }
18108
18109    function daysInMonth(year, month) {
18110        if (isNaN(year) || isNaN(month)) {
18111            return NaN;
18112        }
18113        var modMonth = mod(month, 12);
18114        year += (month - modMonth) / 12;
18115        return modMonth === 1
18116            ? isLeapYear(year)
18117                ? 29
18118                : 28
18119            : 31 - ((modMonth % 7) % 2);
18120    }
18121
18122    // FORMATTING
18123
18124    addFormatToken('M', ['MM', 2], 'Mo', function () {
18125        return this.month() + 1;
18126    });
18127
18128    addFormatToken('MMM', 0, 0, function (format) {
18129        return this.localeData().monthsShort(this, format);
18130    });
18131
18132    addFormatToken('MMMM', 0, 0, function (format) {
18133        return this.localeData().months(this, format);
18134    });
18135
18136    // ALIASES
18137
18138    addUnitAlias('month', 'M');
18139
18140    // PRIORITY
18141
18142    addUnitPriority('month', 8);
18143
18144    // PARSING
18145
18146    addRegexToken('M', match1to2);
18147    addRegexToken('MM', match1to2, match2);
18148    addRegexToken('MMM', function (isStrict, locale) {
18149        return locale.monthsShortRegex(isStrict);
18150    });
18151    addRegexToken('MMMM', function (isStrict, locale) {
18152        return locale.monthsRegex(isStrict);
18153    });
18154
18155    addParseToken(['M', 'MM'], function (input, array) {
18156        array[MONTH] = toInt(input) - 1;
18157    });
18158
18159    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
18160        var month = config._locale.monthsParse(input, token, config._strict);
18161        // if we didn't find a month name, mark the date as invalid.
18162        if (month != null) {
18163            array[MONTH] = month;
18164        } else {
18165            getParsingFlags(config).invalidMonth = input;
18166        }
18167    });
18168
18169    // LOCALES
18170
18171    var defaultLocaleMonths =
18172            'January_February_March_April_May_June_July_August_September_October_November_December'.split(
18173                '_'
18174            ),
18175        defaultLocaleMonthsShort =
18176            'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'
vendor: 13,773 bytes, lines 18176-18618
18176),
18177        MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
18178        defaultMonthsShortRegex = matchWord,
18179        defaultMonthsRegex = matchWord;
18180
18181    function localeMonths(m, format) {
18182        if (!m) {
18183            return isArray(this._months)
18184                ? this._months
18185                : this._months['standalone'];
18186        }
18187        return isArray(this._months)
18188            ? this._months[m.month()]
18189            : this._months[
18190                  (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
18191                      ? 'format'
18192                      : 'standalone'
18193              ][m.month()];
18194    }
18195
18196    function localeMonthsShort(m, format) {
18197        if (!m) {
18198            return isArray(this._monthsShort)
18199                ? this._monthsShort
18200                : this._monthsShort['standalone'];
18201        }
18202        return isArray(this._monthsShort)
18203            ? this._monthsShort[m.month()]
18204            : this._monthsShort[
18205                  MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
18206              ][m.month()];
18207    }
18208
18209    function handleStrictParse(monthName, format, strict) {
18210        var i,
18211            ii,
18212            mom,
18213            llc = monthName.toLocaleLowerCase();
18214        if (!this._monthsParse) {
18215            // this is not used
18216            this._monthsParse = [];
18217            this._longMonthsParse = [];
18218            this._shortMonthsParse = [];
18219            for (i = 0; i < 12; ++i) {
18220                mom = createUTC([2000, i]);
18221                this._shortMonthsParse[i] = this.monthsShort(
18222                    mom,
18223                    ''
18224                ).toLocaleLowerCase();
18225                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
18226            }
18227        }
18228
18229        if (strict) {
18230            if (format === 'MMM') {
18231                ii = indexOf.call(this._shortMonthsParse, llc);
18232                return ii !== -1 ? ii : null;
18233            } else {
18234                ii = indexOf.call(this._longMonthsParse, llc);
18235                return ii !== -1 ? ii : null;
18236            }
18237        } else {
18238            if (format === 'MMM') {
18239                ii = indexOf.call(this._shortMonthsParse, llc);
18240                if (ii !== -1) {
18241                    return ii;
18242                }
18243                ii = indexOf.call(this._longMonthsParse, llc);
18244                return ii !== -1 ? ii : null;
18245            } else {
18246                ii = indexOf.call(this._longMonthsParse, llc);
18247                if (ii !== -1) {
18248                    return ii;
18249                }
18250                ii = indexOf.call(this._shortMonthsParse, llc);
18251                return ii !== -1 ? ii : null;
18252            }
18253        }
18254    }
18255
18256    function localeMonthsParse(monthName, format, strict) {
18257        var i, mom, regex;
18258
18259        if (this._monthsParseExact) {
18260            return handleStrictParse.call(this, monthName, format, strict);
18261        }
18262
18263        if (!this._monthsParse) {
18264            this._monthsParse = [];
18265            this._longMonthsParse = [];
18266            this._shortMonthsParse = [];
18267        }
18268
18269        // TODO: add sorting
18270        // Sorting makes sure if one month (or abbr) is a prefix of another
18271        // see sorting in computeMonthsParse
18272        for (i = 0; i < 12; i++) {
18273            // make the regex if we don't have it already
18274            mom = createUTC([2000, i]);
18275            if (strict && !this._longMonthsParse[i]) {
18276                this._longMonthsParse[i] = new RegExp(
18277                    '^' + this.months(mom, '').replace('.', '') + '$',
18278                    'i'
18279                );
18280                this._shortMonthsParse[i] = new RegExp(
18281                    '^' + this.monthsShort(mom, '').replace('.', '') + '$',
18282                    'i'
18283                );
18284            }
18285            if (!strict && !this._monthsParse[i]) {
18286                regex =
18287                    '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
18288                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
18289            }
18290            // test the regex
18291            if (
18292                strict &&
18293                format === 'MMMM' &&
18294                this._longMonthsParse[i].test(monthName)
18295            ) {
18296                return i;
18297            } else if (
18298                strict &&
18299                format === 'MMM' &&
18300                this._shortMonthsParse[i].test(monthName)
18301            ) {
18302                return i;
18303            } else if (!strict && this._monthsParse[i].test(monthName)) {
18304                return i;
18305            }
18306        }
18307    }
18308
18309    // MOMENTS
18310
18311    function setMonth(mom, value) {
18312        var dayOfMonth;
18313
18314        if (!mom.isValid()) {
18315            // No op
18316            return mom;
18317        }
18318
18319        if (typeof value === 'string') {
18320            if (/^\d+$/.test(value)) {
18321                value = toInt(value);
18322            } else {
18323                value = mom.localeData().monthsParse(value);
18324                // TODO: Another silent failure?
18325                if (!isNumber(value)) {
18326                    return mom;
18327                }
18328            }
18329        }
18330
18331        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
18332        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
18333        return mom;
18334    }
18335
18336    function getSetMonth(value) {
18337        if (value != null) {
18338            setMonth(this, value);
18339            hooks.updateOffset(this, true);
18340            return this;
18341        } else {
18342            return get(this, 'Month');
18343        }
18344    }
18345
18346    function getDaysInMonth() {
18347        return daysInMonth(this.year(), this.month());
18348    }
18349
18350    function monthsShortRegex(isStrict) {
18351        if (this._monthsParseExact) {
18352            if (!hasOwnProp(this, '_monthsRegex')) {
18353                computeMonthsParse.call(this);
18354            }
18355            if (isStrict) {
18356                return this._monthsShortStrictRegex;
18357            } else {
18358                return this._monthsShortRegex;
18359            }
18360        } else {
18361            if (!hasOwnProp(this, '_monthsShortRegex')) {
18362                this._monthsShortRegex = defaultMonthsShortRegex;
18363            }
18364            return this._monthsShortStrictRegex && isStrict
18365                ? this._monthsShortStrictRegex
18366                : this._monthsShortRegex;
18367        }
18368    }
18369
18370    function monthsRegex(isStrict) {
18371        if (this._monthsParseExact) {
18372            if (!hasOwnProp(this, '_monthsRegex')) {
18373                computeMonthsParse.call(this);
18374            }
18375            if (isStrict) {
18376                return this._monthsStrictRegex;
18377            } else {
18378                return this._monthsRegex;
18379            }
18380        } else {
18381            if (!hasOwnProp(this, '_monthsRegex')) {
18382                this._monthsRegex = defaultMonthsRegex;
18383            }
18384            return this._monthsStrictRegex && isStrict
18385                ? this._monthsStrictRegex
18386                : this._monthsRegex;
18387        }
18388    }
18389
18390    function computeMonthsParse() {
18391        function cmpLenRev(a, b) {
18392            return b.length - a.length;
18393        }
18394
18395        var shortPieces = [],
18396            longPieces = [],
18397            mixedPieces = [],
18398            i,
18399            mom;
18400        for (i = 0; i < 12; i++) {
18401            // make the regex if we don't have it already
18402            mom = createUTC([2000, i]);
18403            shortPieces.push(this.monthsShort(mom, ''));
18404            longPieces.push(this.months(mom, ''));
18405            mixedPieces.push(this.months(mom, ''));
18406            mixedPieces.push(this.monthsShort(mom, ''));
18407        }
18408        // Sorting makes sure if one month (or abbr) is a prefix of another it
18409        // will match the longer piece.
18410        shortPieces.sort(cmpLenRev);
18411        longPieces.sort(cmpLenRev);
18412        mixedPieces.sort(cmpLenRev);
18413        for (i = 0; i < 12; i++) {
18414            shortPieces[i] = regexEscape(shortPieces[i]);
18415            longPieces[i] = regexEscape(longPieces[i]);
18416        }
18417        for (i = 0; i < 24; i++) {
18418            mixedPieces[i] = regexEscape(mixedPieces[i]);
18419        }
18420
18421        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
18422        this._monthsShortRegex = this._monthsRegex;
18423        this._monthsStrictRegex = new RegExp(
18424            '^(' + longPieces.join('|') + ')',
18425            'i'
18426        );
18427        this._monthsShortStrictRegex = new RegExp(
18428            '^(' + shortPieces.join('|') + ')',
18429            'i'
18430        );
18431    }
18432
18433    // FORMATTING
18434
18435    addFormatToken('Y', 0, 0, function () {
18436        var y = this.year();
18437        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
18438    });
18439
18440    addFormatToken(0, ['YY', 2], 0, function () {
18441        return this.year() % 100;
18442    });
18443
18444    addFormatToken(0, ['YYYY', 4], 0, 'year');
18445    addFormatToken(0, ['YYYYY', 5], 0, 'year');
18446    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
18447
18448    // ALIASES
18449
18450    addUnitAlias('year', 'y');
18451
18452    // PRIORITIES
18453
18454    addUnitPriority('year', 1);
18455
18456    // PARSING
18457
18458    addRegexToken('Y', matchSigned);
18459    addRegexToken('YY', match1to2, match2);
18460    addRegexToken('YYYY', match1to4, match4);
18461    addRegexToken('YYYYY', match1to6, match6);
18462    addRegexToken('YYYYYY', match1to6, match6);
18463
18464    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
18465    addParseToken('YYYY', function (input, array) {
18466        array[YEAR] =
18467            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
18468    });
18469    addParseToken('YY', function (input, array) {
18470        array[YEAR] = hooks.parseTwoDigitYear(input);
18471    });
18472    addParseToken('Y', function (input, array) {
18473        array[YEAR] = parseInt(input, 10);
18474    });
18475
18476    // HELPERS
18477
18478    function daysInYear(year) {
18479        return isLeapYear(year) ? 366 : 365;
18480    }
18481
18482    // HOOKS
18483
18484    hooks.parseTwoDigitYear = function (input) {
18485        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
18486    };
18487
18488    // MOMENTS
18489
18490    var getSetYear = makeGetSet('FullYear', true);
18491
18492    function getIsLeapYear() {
18493        return isLeapYear(this.year());
18494    }
18495
18496    function createDate(y, m, d, h, M, s, ms) {
18497        // can't just apply() to create a date:
18498        // https://stackoverflow.com/q/181348
18499        var date;
18500        // the date constructor remaps years 0-99 to 1900-1999
18501        if (y < 100 && y >= 0) {
18502            // preserve leap years using a full 400 year cycle, then reset
18503            date = new Date(y + 400, m, d, h, M, s, ms);
18504            if (isFinite(date.getFullYear())) {
18505                date.setFullYear(y);
18506            }
18507        } else {
18508            date = new Date(y, m, d, h, M, s, ms);
18509        }
18510
18511        return date;
18512    }
18513
18514    function createUTCDate(y) {
18515        var date, args;
18516        // the Date.UTC function remaps years 0-99 to 1900-1999
18517        if (y < 100 && y >= 0) {
18518            args = Array.prototype.slice.call(arguments);
18519            // preserve leap years using a full 400 year cycle, then reset
18520            args[0] = y + 400;
18521            date = new Date(Date.UTC.apply(null, args));
18522            if (isFinite(date.getUTCFullYear())) {
18523                date.setUTCFullYear(y);
18524            }
18525        } else {
18526            date = new Date(Date.UTC.apply(null, arguments));
18527        }
18528
18529        return date;
18530    }
18531
18532    // start-of-first-week - start-of-year
18533    function firstWeekOffset(year, dow, doy) {
18534        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
18535            fwd = 7 + dow - doy,
18536            // first-week day local weekday -- which local weekday is fwd
18537            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
18538
18539        return -fwdlw + fwd - 1;
18540    }
18541
18542    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
18543    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
18544        var localWeekday = (7 + weekday - dow) % 7,
18545            weekOffset = firstWeekOffset(year, dow, doy),
18546            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
18547            resYear,
18548            resDayOfYear;
18549
18550        if (dayOfYear <= 0) {
18551            resYear = year - 1;
18552            resDayOfYear = daysInYear(resYear) + dayOfYear;
18553        } else if (dayOfYear > daysInYear(year)) {
18554            resYear = year + 1;
18555            resDayOfYear = dayOfYear - daysInYear(year);
18556        } else {
18557            resYear = year;
18558            resDayOfYear = dayOfYear;
18559        }
18560
18561        return {
18562            year: resYear,
18563            dayOfYear: resDayOfYear,
18564        };
18565    }
18566
18567    function weekOfYear(mom, dow, doy) {
18568        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
18569            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
18570            resWeek,
18571            resYear;
18572
18573        if (week < 1) {
18574            resYear = mom.year() - 1;
18575            resWeek = week + weeksInYear(resYear, dow, doy);
18576        } else if (week > weeksInYear(mom.year(), dow, doy)) {
18577            resWeek = week - weeksInYear(mom.year(), dow, doy);
18578            resYear = mom.year() + 1;
18579        } else {
18580            resYear = mom.year();
18581            resWeek = week;
18582        }
18583
18584        return {
18585            week: resWeek,
18586            year: resYear,
18587        };
18588    }
18589
18590    function weeksInYear(year, dow, doy) {
18591        var weekOffset = firstWeekOffset(year, dow, doy),
18592            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
18593        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
18594    }
18595
18596    // FORMATTING
18597
18598    addFormatToken('w', ['ww', 2], 'wo', 'week');
18599    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
18600
18601    // ALIASES
18602
18603    addUnitAlias('week', 'w');
18604    addUnitAlias('isoWeek', 'W');
18605
18606    // PRIORITIES
18607
18608    addUnitPriority('week', 5);
18609    addUnitPriority('isoWeek', 5);
18610
18611    // PARSING
18612
18613    addRegexToken('w', match1to2);
18614    addRegexToken('ww', match1to2, match2);
18615    addRegexToken('W', match1to2);
18616    addRegexToken('WW', match1to2, match2);
18617
18618    addWeekParseToken(
vendor: 3,487 bytes, lines 18618-18749
18618
18619        ['w', 'ww', 'W', 'WW'],
18620        function (input, week, config, token) {
18621            week[token.substr(0, 1)] = toInt(input);
18622        }
18623    );
18624
18625    // HELPERS
18626
18627    // LOCALES
18628
18629    function localeWeek(mom) {
18630        return weekOfYear(mom, this._week.dow, this._week.doy).week;
18631    }
18632
18633    var defaultLocaleWeek = {
18634        dow: 0, // Sunday is the first day of the week.
18635        doy: 6, // The week that contains Jan 6th is the first week of the year.
18636    };
18637
18638    function localeFirstDayOfWeek() {
18639        return this._week.dow;
18640    }
18641
18642    function localeFirstDayOfYear() {
18643        return this._week.doy;
18644    }
18645
18646    // MOMENTS
18647
18648    function getSetWeek(input) {
18649        var week = this.localeData().week(this);
18650        return input == null ? week : this.add((input - week) * 7, 'd');
18651    }
18652
18653    function getSetISOWeek(input) {
18654        var week = weekOfYear(this, 1, 4).week;
18655        return input == null ? week : this.add((input - week) * 7, 'd');
18656    }
18657
18658    // FORMATTING
18659
18660    addFormatToken('d', 0, 'do', 'day');
18661
18662    addFormatToken('dd', 0, 0, function (format) {
18663        return this.localeData().weekdaysMin(this, format);
18664    });
18665
18666    addFormatToken('ddd', 0, 0, function (format) {
18667        return this.localeData().weekdaysShort(this, format);
18668    });
18669
18670    addFormatToken('dddd', 0, 0, function (format) {
18671        return this.localeData().weekdays(this, format);
18672    });
18673
18674    addFormatToken('e', 0, 0, 'weekday');
18675    addFormatToken('E', 0, 0, 'isoWeekday');
18676
18677    // ALIASES
18678
18679    addUnitAlias('day', 'd');
18680    addUnitAlias('weekday', 'e');
18681    addUnitAlias('isoWeekday', 'E');
18682
18683    // PRIORITY
18684    addUnitPriority('day', 11);
18685    addUnitPriority('weekday', 11);
18686    addUnitPriority('isoWeekday', 11);
18687
18688    // PARSING
18689
18690    addRegexToken('d', match1to2);
18691    addRegexToken('e', match1to2);
18692    addRegexToken('E', match1to2);
18693    addRegexToken('dd', function (isStrict, locale) {
18694        return locale.weekdaysMinRegex(isStrict);
18695    });
18696    addRegexToken('ddd', function (isStrict, locale) {
18697        return locale.weekdaysShortRegex(isStrict);
18698    });
18699    addRegexToken('dddd', function (isStrict, locale) {
18700        return locale.weekdaysRegex(isStrict);
18701    });
18702
18703    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
18704        var weekday = config._locale.weekdaysParse(input, token, config._strict);
18705        // if we didn't get a weekday name, mark the date as invalid
18706        if (weekday != null) {
18707            week.d = weekday;
18708        } else {
18709            getParsingFlags(config).invalidWeekday = input;
18710        }
18711    });
18712
18713    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
18714        week[token] = toInt(input);
18715    });
18716
18717    // HELPERS
18718
18719    function parseWeekday(input, locale) {
18720        if (typeof input !== 'string') {
18721            return input;
18722        }
18723
18724        if (!isNaN(input)) {
18725            return parseInt(input, 10);
18726        }
18727
18728        input = locale.weekdaysParse(input);
18729        if (typeof input === 'number') {
18730            return input;
18731        }
18732
18733        return null;
18734    }
18735
18736    function parseIsoWeekday(input, locale) {
18737        if (typeof input === 'string') {
18738            return locale.weekdaysParse(input) % 7 || 7;
18739        }
18740        return isNaN(input) ? null : input;
18741    }
18742
18743    // LOCALES
18744    function shiftWeekdays(ws, n) {
18745        return ws.slice(n, 7).concat(ws.slice(0, n));
18746    }
18747
18748    var defaultLocaleWeekdays =
18749            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'
vendor: 17,864 bytes, lines 18749-19297
18749),
18750        defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
18751        defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
18752        defaultWeekdaysRegex = matchWord,
18753        defaultWeekdaysShortRegex = matchWord,
18754        defaultWeekdaysMinRegex = matchWord;
18755
18756    function localeWeekdays(m, format) {
18757        var weekdays = isArray(this._weekdays)
18758            ? this._weekdays
18759            : this._weekdays[
18760                  m && m !== true && this._weekdays.isFormat.test(format)
18761                      ? 'format'
18762                      : 'standalone'
18763              ];
18764        return m === true
18765            ? shiftWeekdays(weekdays, this._week.dow)
18766            : m
18767            ? weekdays[m.day()]
18768            : weekdays;
18769    }
18770
18771    function localeWeekdaysShort(m) {
18772        return m === true
18773            ? shiftWeekdays(this._weekdaysShort, this._week.dow)
18774            : m
18775            ? this._weekdaysShort[m.day()]
18776            : this._weekdaysShort;
18777    }
18778
18779    function localeWeekdaysMin(m) {
18780        return m === true
18781            ? shiftWeekdays(this._weekdaysMin, this._week.dow)
18782            : m
18783            ? this._weekdaysMin[m.day()]
18784            : this._weekdaysMin;
18785    }
18786
18787    function handleStrictParse$1(weekdayName, format, strict) {
18788        var i,
18789            ii,
18790            mom,
18791            llc = weekdayName.toLocaleLowerCase();
18792        if (!this._weekdaysParse) {
18793            this._weekdaysParse = [];
18794            this._shortWeekdaysParse = [];
18795            this._minWeekdaysParse = [];
18796
18797            for (i = 0; i < 7; ++i) {
18798                mom = createUTC([2000, 1]).day(i);
18799                this._minWeekdaysParse[i] = this.weekdaysMin(
18800                    mom,
18801                    ''
18802                ).toLocaleLowerCase();
18803                this._shortWeekdaysParse[i] = this.weekdaysShort(
18804                    mom,
18805                    ''
18806                ).toLocaleLowerCase();
18807                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
18808            }
18809        }
18810
18811        if (strict) {
18812            if (format === 'dddd') {
18813                ii = indexOf.call(this._weekdaysParse, llc);
18814                return ii !== -1 ? ii : null;
18815            } else if (format === 'ddd') {
18816                ii = indexOf.call(this._shortWeekdaysParse, llc);
18817                return ii !== -1 ? ii : null;
18818            } else {
18819                ii = indexOf.call(this._minWeekdaysParse, llc);
18820                return ii !== -1 ? ii : null;
18821            }
18822        } else {
18823            if (format === 'dddd') {
18824                ii = indexOf.call(this._weekdaysParse, llc);
18825                if (ii !== -1) {
18826                    return ii;
18827                }
18828                ii = indexOf.call(this._shortWeekdaysParse, llc);
18829                if (ii !== -1) {
18830                    return ii;
18831                }
18832                ii = indexOf.call(this._minWeekdaysParse, llc);
18833                return ii !== -1 ? ii : null;
18834            } else if (format === 'ddd') {
18835                ii = indexOf.call(this._shortWeekdaysParse, llc);
18836                if (ii !== -1) {
18837                    return ii;
18838                }
18839                ii = indexOf.call(this._weekdaysParse, llc);
18840                if (ii !== -1) {
18841                    return ii;
18842                }
18843                ii = indexOf.call(this._minWeekdaysParse, llc);
18844                return ii !== -1 ? ii : null;
18845            } else {
18846                ii = indexOf.call(this._minWeekdaysParse, llc);
18847                if (ii !== -1) {
18848                    return ii;
18849                }
18850                ii = indexOf.call(this._weekdaysParse, llc);
18851                if (ii !== -1) {
18852                    return ii;
18853                }
18854                ii = indexOf.call(this._shortWeekdaysParse, llc);
18855                return ii !== -1 ? ii : null;
18856            }
18857        }
18858    }
18859
18860    function localeWeekdaysParse(weekdayName, format, strict) {
18861        var i, mom, regex;
18862
18863        if (this._weekdaysParseExact) {
18864            return handleStrictParse$1.call(this, weekdayName, format, strict);
18865        }
18866
18867        if (!this._weekdaysParse) {
18868            this._weekdaysParse = [];
18869            this._minWeekdaysParse = [];
18870            this._shortWeekdaysParse = [];
18871            this._fullWeekdaysParse = [];
18872        }
18873
18874        for (i = 0; i < 7; i++) {
18875            // make the regex if we don't have it already
18876
18877            mom = createUTC([2000, 1]).day(i);
18878            if (strict && !this._fullWeekdaysParse[i]) {
18879                this._fullWeekdaysParse[i] = new RegExp(
18880                    '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
18881                    'i'
18882                );
18883                this._shortWeekdaysParse[i] = new RegExp(
18884                    '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
18885                    'i'
18886                );
18887                this._minWeekdaysParse[i] = new RegExp(
18888                    '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
18889                    'i'
18890                );
18891            }
18892            if (!this._weekdaysParse[i]) {
18893                regex =
18894                    '^' +
18895                    this.weekdays(mom, '') +
18896                    '|^' +
18897                    this.weekdaysShort(mom, '') +
18898                    '|^' +
18899                    this.weekdaysMin(mom, '');
18900                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
18901            }
18902            // test the regex
18903            if (
18904                strict &&
18905                format === 'dddd' &&
18906                this._fullWeekdaysParse[i].test(weekdayName)
18907            ) {
18908                return i;
18909            } else if (
18910                strict &&
18911                format === 'ddd' &&
18912                this._shortWeekdaysParse[i].test(weekdayName)
18913            ) {
18914                return i;
18915            } else if (
18916                strict &&
18917                format === 'dd' &&
18918                this._minWeekdaysParse[i].test(weekdayName)
18919            ) {
18920                return i;
18921            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
18922                return i;
18923            }
18924        }
18925    }
18926
18927    // MOMENTS
18928
18929    function getSetDayOfWeek(input) {
18930        if (!this.isValid()) {
18931            return input != null ? this : NaN;
18932        }
18933        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
18934        if (input != null) {
18935            input = parseWeekday(input, this.localeData());
18936            return this.add(input - day, 'd');
18937        } else {
18938            return day;
18939        }
18940    }
18941
18942    function getSetLocaleDayOfWeek(input) {
18943        if (!this.isValid()) {
18944            return input != null ? this : NaN;
18945        }
18946        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
18947        return input == null ? weekday : this.add(input - weekday, 'd');
18948    }
18949
18950    function getSetISODayOfWeek(input) {
18951        if (!this.isValid()) {
18952            return input != null ? this : NaN;
18953        }
18954
18955        // behaves the same as moment#day except
18956        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
18957        // as a setter, sunday should belong to the previous week.
18958
18959        if (input != null) {
18960            var weekday = parseIsoWeekday(input, this.localeData());
18961            return this.day(this.day() % 7 ? weekday : weekday - 7);
18962        } else {
18963            return this.day() || 7;
18964        }
18965    }
18966
18967    function weekdaysRegex(isStrict) {
18968        if (this._weekdaysParseExact) {
18969            if (!hasOwnProp(this, '_weekdaysRegex')) {
18970                computeWeekdaysParse.call(this);
18971            }
18972            if (isStrict) {
18973                return this._weekdaysStrictRegex;
18974            } else {
18975                return this._weekdaysRegex;
18976            }
18977        } else {
18978            if (!hasOwnProp(this, '_weekdaysRegex')) {
18979                this._weekdaysRegex = defaultWeekdaysRegex;
18980            }
18981            return this._weekdaysStrictRegex && isStrict
18982                ? this._weekdaysStrictRegex
18983                : this._weekdaysRegex;
18984        }
18985    }
18986
18987    function weekdaysShortRegex(isStrict) {
18988        if (this._weekdaysParseExact) {
18989            if (!hasOwnProp(this, '_weekdaysRegex')) {
18990                computeWeekdaysParse.call(this);
18991            }
18992            if (isStrict) {
18993                return this._weekdaysShortStrictRegex;
18994            } else {
18995                return this._weekdaysShortRegex;
18996            }
18997        } else {
18998            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
18999                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
19000            }
19001            return this._weekdaysShortStrictRegex && isStrict
19002                ? this._weekdaysShortStrictRegex
19003                : this._weekdaysShortRegex;
19004        }
19005    }
19006
19007    function weekdaysMinRegex(isStrict) {
19008        if (this._weekdaysParseExact) {
19009            if (!hasOwnProp(this, '_weekdaysRegex')) {
19010                computeWeekdaysParse.call(this);
19011            }
19012            if (isStrict) {
19013                return this._weekdaysMinStrictRegex;
19014            } else {
19015                return this._weekdaysMinRegex;
19016            }
19017        } else {
19018            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
19019                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
19020            }
19021            return this._weekdaysMinStrictRegex && isStrict
19022                ? this._weekdaysMinStrictRegex
19023                : this._weekdaysMinRegex;
19024        }
19025    }
19026
19027    function computeWeekdaysParse() {
19028        function cmpLenRev(a, b) {
19029            return b.length - a.length;
19030        }
19031
19032        var minPieces = [],
19033            shortPieces = [],
19034            longPieces = [],
19035            mixedPieces = [],
19036            i,
19037            mom,
19038            minp,
19039            shortp,
19040            longp;
19041        for (i = 0; i < 7; i++) {
19042            // make the regex if we don't have it already
19043            mom = createUTC([2000, 1]).day(i);
19044            minp = regexEscape(this.weekdaysMin(mom, ''));
19045            shortp = regexEscape(this.weekdaysShort(mom, ''));
19046            longp = regexEscape(this.weekdays(mom, ''));
19047            minPieces.push(minp);
19048            shortPieces.push(shortp);
19049            longPieces.push(longp);
19050            mixedPieces.push(minp);
19051            mixedPieces.push(shortp);
19052            mixedPieces.push(longp);
19053        }
19054        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
19055        // will match the longer piece.
19056        minPieces.sort(cmpLenRev);
19057        shortPieces.sort(cmpLenRev);
19058        longPieces.sort(cmpLenRev);
19059        mixedPieces.sort(cmpLenRev);
19060
19061        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
19062        this._weekdaysShortRegex = this._weekdaysRegex;
19063        this._weekdaysMinRegex = this._weekdaysRegex;
19064
19065        this._weekdaysStrictRegex = new RegExp(
19066            '^(' + longPieces.join('|') + ')',
19067            'i'
19068        );
19069        this._weekdaysShortStrictRegex = new RegExp(
19070            '^(' + shortPieces.join('|') + ')',
19071            'i'
19072        );
19073        this._weekdaysMinStrictRegex = new RegExp(
19074            '^(' + minPieces.join('|') + ')',
19075            'i'
19076        );
19077    }
19078
19079    // FORMATTING
19080
19081    function hFormat() {
19082        return this.hours() % 12 || 12;
19083    }
19084
19085    function kFormat() {
19086        return this.hours() || 24;
19087    }
19088
19089    addFormatToken('H', ['HH', 2], 0, 'hour');
19090    addFormatToken('h', ['hh', 2], 0, hFormat);
19091    addFormatToken('k', ['kk', 2], 0, kFormat);
19092
19093    addFormatToken('hmm', 0, 0, function () {
19094        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
19095    });
19096
19097    addFormatToken('hmmss', 0, 0, function () {
19098        return (
19099            '' +
19100            hFormat.apply(this) +
19101            zeroFill(this.minutes(), 2) +
19102            zeroFill(this.seconds(), 2)
19103        );
19104    });
19105
19106    addFormatToken('Hmm', 0, 0, function () {
19107        return '' + this.hours() + zeroFill(this.minutes(), 2);
19108    });
19109
19110    addFormatToken('Hmmss', 0, 0, function () {
19111        return (
19112            '' +
19113            this.hours() +
19114            zeroFill(this.minutes(), 2) +
19115            zeroFill(this.seconds(), 2)
19116        );
19117    });
19118
19119    function meridiem(token, lowercase) {
19120        addFormatToken(token, 0, 0, function () {
19121            return this.localeData().meridiem(
19122                this.hours(),
19123                this.minutes(),
19124                lowercase
19125            );
19126        });
19127    }
19128
19129    meridiem('a', true);
19130    meridiem('A', false);
19131
19132    // ALIASES
19133
19134    addUnitAlias('hour', 'h');
19135
19136    // PRIORITY
19137    addUnitPriority('hour', 13);
19138
19139    // PARSING
19140
19141    function matchMeridiem(isStrict, locale) {
19142        return locale._meridiemParse;
19143    }
19144
19145    addRegexToken('a', matchMeridiem);
19146    addRegexToken('A', matchMeridiem);
19147    addRegexToken('H', match1to2);
19148    addRegexToken('h', match1to2);
19149    addRegexToken('k', match1to2);
19150    addRegexToken('HH', match1to2, match2);
19151    addRegexToken('hh', match1to2, match2);
19152    addRegexToken('kk', match1to2, match2);
19153
19154    addRegexToken('hmm', match3to4);
19155    addRegexToken('hmmss', match5to6);
19156    addRegexToken('Hmm', match3to4);
19157    addRegexToken('Hmmss', match5to6);
19158
19159    addParseToken(['H', 'HH'], HOUR);
19160    addParseToken(['k', 'kk'], function (input, array, config) {
19161        var kInput = toInt(input);
19162        array[HOUR] = kInput === 24 ? 0 : kInput;
19163    });
19164    addParseToken(['a', 'A'], function (input, array, config) {
19165        config._isPm = config._locale.isPM(input);
19166        config._meridiem = input;
19167    });
19168    addParseToken(['h', 'hh'], function (input, array, config) {
19169        array[HOUR] = toInt(input);
19170        getParsingFlags(config).bigHour = true;
19171    });
19172    addParseToken('hmm', function (input, array, config) {
19173        var pos = input.length - 2;
19174        array[HOUR] = toInt(input.substr(0, pos));
19175        array[MINUTE] = toInt(input.substr(pos));
19176        getParsingFlags(config).bigHour = true;
19177    });
19178    addParseToken('hmmss', function (input, array, config) {
19179        var pos1 = input.length - 4,
19180            pos2 = input.length - 2;
19181        array[HOUR] = toInt(input.substr(0, pos1));
19182        array[MINUTE] = toInt(input.substr(pos1, 2));
19183        array[SECOND] = toInt(input.substr(pos2));
19184        getParsingFlags(config).bigHour = true;
19185    });
19186    addParseToken('Hmm', function (input, array, config) {
19187        var pos = input.length - 2;
19188        array[HOUR] = toInt(input.substr(0, pos));
19189        array[MINUTE] = toInt(input.substr(pos));
19190    });
19191    addParseToken('Hmmss', function (input, array, config) {
19192        var pos1 = input.length - 4,
19193            pos2 = input.length - 2;
19194        array[HOUR] = toInt(input.substr(0, pos1));
19195        array[MINUTE] = toInt(input.substr(pos1, 2));
19196        array[SECOND] = toInt(input.substr(pos2));
19197    });
19198
19199    // LOCALES
19200
19201    function localeIsPM(input) {
19202        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
19203        // Using charAt should be more compatible.
19204        return (input + '').toLowerCase().charAt(0) === 'p';
19205    }
19206
19207    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
19208        // Setting the hour should keep the time, because the user explicitly
19209        // specified which hour they want. So trying to maintain the same hour (in
19210        // a new timezone) makes sense. Adding/subtracting hours does not follow
19211        // this rule.
19212        getSetHour = makeGetSet('Hours', true);
19213
19214    function localeMeridiem(hours, minutes, isLower) {
19215        if (hours > 11) {
19216            return isLower ? 'pm' : 'PM';
19217        } else {
19218            return isLower ? 'am' : 'AM';
19219        }
19220    }
19221
19222    var baseConfig = {
19223        calendar: defaultCalendar,
19224        longDateFormat: defaultLongDateFormat,
19225        invalidDate: defaultInvalidDate,
19226        ordinal: defaultOrdinal,
19227        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
19228        relativeTime: defaultRelativeTime,
19229
19230        months: defaultLocaleMonths,
19231        monthsShort: defaultLocaleMonthsShort,
19232
19233        week: defaultLocaleWeek,
19234
19235        weekdays: defaultLocaleWeekdays,
19236        weekdaysMin: defaultLocaleWeekdaysMin,
19237        weekdaysShort: defaultLocaleWeekdaysShort,
19238
19239        meridiemParse: defaultLocaleMeridiemParse,
19240    };
19241
19242    // internal storage for locale config files
19243    var locales = {},
19244        localeFamilies = {},
19245        globalLocale;
19246
19247    function commonPrefix(arr1, arr2) {
19248        var i,
19249            minl = Math.min(arr1.length, arr2.length);
19250        for (i = 0; i < minl; i += 1) {
19251            if (arr1[i] !== arr2[i]) {
19252                return i;
19253            }
19254        }
19255        return minl;
19256    }
19257
19258    function normalizeLocale(key) {
19259        return key ? key.toLowerCase().replace('_', '-') : key;
19260    }
19261
19262    // pick the locale from the array
19263    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
19264    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
19265    function chooseLocale(names) {
19266        var i = 0,
19267            j,
19268            next,
19269            locale,
19270            split;
19271
19272        while (i < names.length) {
19273            split = normalizeLocale(names[i]).split('-');
19274            j = split.length;
19275            next = normalizeLocale(names[i + 1]);
19276            next = next ? next.split('-') : null;
19277            while (j > 0) {
19278                locale = loadLocale(split.slice(0, j).join('-'));
19279                if (locale) {
19280                    return locale;
19281                }
19282                if (
19283                    next &&
19284                    next.length >= j &&
19285                    commonPrefix(split, next) >= j - 1
19286                ) {
19287                    //the next array item is better than a shallower substring of this one
19288                    break;
19289                }
19290                j--;
19291            }
19292            i++;
19293        }
19294        return globalLocale;
19295    }
19296
19297    function 
vendor: 7,449 bytes, lines 19297-19504
19297isLocaleNameSane(name) {
19298        // Prevent names that look like filesystem paths, i.e contain '/' or '\'
19299        return name.match('^[^/\\\\]*$') != null;
19300    }
19301
19302    function loadLocale(name) {
19303        var oldLocale = null,
19304            aliasedRequire;
19305        // TODO: Find a better way to register and load all the locales in Node
19306        if (
19307            locales[name] === undefined &&
19308            typeof module !== 'undefined' &&
19309            module &&
19310            module.exports &&
19311            isLocaleNameSane(name)
19312        ) {
19313            try {
19314                oldLocale = globalLocale._abbr;
19315                aliasedRequire = require;
19316                aliasedRequire('./locale/' + name);
19317                getSetGlobalLocale(oldLocale);
19318            } catch (e) {
19319                // mark as not found to avoid repeating expensive file require call causing high CPU
19320                // when trying to find en-US, en_US, en-us for every format call
19321                locales[name] = null; // null means not found
19322            }
19323        }
19324        return locales[name];
19325    }
19326
19327    // This function will load locale and then set the global locale.  If
19328    // no arguments are passed in, it will simply return the current global
19329    // locale key.
19330    function getSetGlobalLocale(key, values) {
19331        var data;
19332        if (key) {
19333            if (isUndefined(values)) {
19334                data = getLocale(key);
19335            } else {
19336                data = defineLocale(key, values);
19337            }
19338
19339            if (data) {
19340                // moment.duration._locale = moment._locale = data;
19341                globalLocale = data;
19342            } else {
19343                if (typeof console !== 'undefined' && console.warn) {
19344                    //warn user if arguments are passed but the locale could not be set
19345                    console.warn(
19346                        'Locale ' + key + ' not found. Did you forget to load it?'
19347                    );
19348                }
19349            }
19350        }
19351
19352        return globalLocale._abbr;
19353    }
19354
19355    function defineLocale(name, config) {
19356        if (config !== null) {
19357            var locale,
19358                parentConfig = baseConfig;
19359            config.abbr = name;
19360            if (locales[name] != null) {
19361                deprecateSimple(
19362                    'defineLocaleOverride',
19363                    'use moment.updateLocale(localeName, config) to change ' +
19364                        'an existing locale. moment.defineLocale(localeName, ' +
19365                        'config) should only be used for creating a new locale ' +
19366                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
19367                );
19368                parentConfig = locales[name]._config;
19369            } else if (config.parentLocale != null) {
19370                if (locales[config.parentLocale] != null) {
19371                    parentConfig = locales[config.parentLocale]._config;
19372                } else {
19373                    locale = loadLocale(config.parentLocale);
19374                    if (locale != null) {
19375                        parentConfig = locale._config;
19376                    } else {
19377                        if (!localeFamilies[config.parentLocale]) {
19378                            localeFamilies[config.parentLocale] = [];
19379                        }
19380                        localeFamilies[config.parentLocale].push({
19381                            name: name,
19382                            config: config,
19383                        });
19384                        return null;
19385                    }
19386                }
19387            }
19388            locales[name] = new Locale(mergeConfigs(parentConfig, config));
19389
19390            if (localeFamilies[name]) {
19391                localeFamilies[name].forEach(function (x) {
19392                    defineLocale(x.name, x.config);
19393                });
19394            }
19395
19396            // backwards compat for now: also set the locale
19397            // make sure we set the locale AFTER all child locales have been
19398            // created, so we won't end up with the child locale set.
19399            getSetGlobalLocale(name);
19400
19401            return locales[name];
19402        } else {
19403            // useful for testing
19404            delete locales[name];
19405            return null;
19406        }
19407    }
19408
19409    function updateLocale(name, config) {
19410        if (config != null) {
19411            var locale,
19412                tmpLocale,
19413                parentConfig = baseConfig;
19414
19415            if (locales[name] != null && locales[name].parentLocale != null) {
19416                // Update existing child locale in-place to avoid memory-leaks
19417                locales[name].set(mergeConfigs(locales[name]._config, config));
19418            } else {
19419                // MERGE
19420                tmpLocale = loadLocale(name);
19421                if (tmpLocale != null) {
19422                    parentConfig = tmpLocale._config;
19423                }
19424                config = mergeConfigs(parentConfig, config);
19425                if (tmpLocale == null) {
19426                    // updateLocale is called for creating a new locale
19427                    // Set abbr so it will have a name (getters return
19428                    // undefined otherwise).
19429                    config.abbr = name;
19430                }
19431                locale = new Locale(config);
19432                locale.parentLocale = locales[name];
19433                locales[name] = locale;
19434            }
19435
19436            // backwards compat for now: also set the locale
19437            getSetGlobalLocale(name);
19438        } else {
19439            // pass null for config to unupdate, useful for tests
19440            if (locales[name] != null) {
19441                if (locales[name].parentLocale != null) {
19442                    locales[name] = locales[name].parentLocale;
19443                    if (name === getSetGlobalLocale()) {
19444                        getSetGlobalLocale(name);
19445                    }
19446                } else if (locales[name] != null) {
19447                    delete locales[name];
19448                }
19449            }
19450        }
19451        return locales[name];
19452    }
19453
19454    // returns locale data
19455    function getLocale(key) {
19456        var locale;
19457
19458        if (key && key._locale && key._locale._abbr) {
19459            key = key._locale._abbr;
19460        }
19461
19462        if (!key) {
19463            return globalLocale;
19464        }
19465
19466        if (!isArray(key)) {
19467            //short-circuit everything else
19468            locale = loadLocale(key);
19469            if (locale) {
19470                return locale;
19471            }
19472            key = [key];
19473        }
19474
19475        return chooseLocale(key);
19476    }
19477
19478    function listLocales() {
19479        return keys(locales);
19480    }
19481
19482    function checkOverflow(m) {
19483        var overflow,
19484            a = m._a;
19485
19486        if (a && getParsingFlags(m).overflow === -2) {
19487            overflow =
19488                a[MONTH] < 0 || a[MONTH] > 11
19489                    ? MONTH
19490                    : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
19491                    ? DATE
19492                    : a[HOUR] < 0 ||
19493                      a[HOUR] > 24 ||
19494                      (a[HOUR] === 24 &&
19495                          (a[MINUTE] !== 0 ||
19496                              a[SECOND] !== 0 ||
19497                              a[MILLISECOND] !== 0))
19498                    ? HOUR
19499                    : a[MINUTE] < 0 || a[MINUTE] > 59
19500                    ? MINUTE
19501                    : a[SECOND] < 0 || a[SECOND] > 59
19502                    ? SECOND
19503                    : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
19504                    ? MILLISECOND
vendor: 9,346 bytes, lines 19505-19788
19505                    : -1;
19506
19507            if (
19508                getParsingFlags(m)._overflowDayOfYear &&
19509                (overflow < YEAR || overflow > DATE)
19510            ) {
19511                overflow = DATE;
19512            }
19513            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
19514                overflow = WEEK;
19515            }
19516            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
19517                overflow = WEEKDAY;
19518            }
19519
19520            getParsingFlags(m).overflow = overflow;
19521        }
19522
19523        return m;
19524    }
19525
19526    // iso 8601 regex
19527    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
19528    var extendedIsoRegex =
19529            /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
19530        basicIsoRegex =
19531            /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
19532        tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
19533        isoDates = [
19534            ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
19535            ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
19536            ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
19537            ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
19538            ['YYYY-DDD', /\d{4}-\d{3}/],
19539            ['YYYY-MM', /\d{4}-\d\d/, false],
19540            ['YYYYYYMMDD', /[+-]\d{10}/],
19541            ['YYYYMMDD', /\d{8}/],
19542            ['GGGG[W]WWE', /\d{4}W\d{3}/],
19543            ['GGGG[W]WW', /\d{4}W\d{2}/, false],
19544            ['YYYYDDD', /\d{7}/],
19545            ['YYYYMM', /\d{6}/, false],
19546            ['YYYY', /\d{4}/, false],
19547        ],
19548        // iso time formats and regexes
19549        isoTimes = [
19550            ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
19551            ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
19552            ['HH:mm:ss', /\d\d:\d\d:\d\d/],
19553            ['HH:mm', /\d\d:\d\d/],
19554            ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
19555            ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
19556            ['HHmmss', /\d\d\d\d\d\d/],
19557            ['HHmm', /\d\d\d\d/],
19558            ['HH', /\d\d/],
19559        ],
19560        aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
19561        // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
19562        rfc2822 =
19563            /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,
19564        obsOffsets = {
19565            UT: 0,
19566            GMT: 0,
19567            EDT: -4 * 60,
19568            EST: -5 * 60,
19569            CDT: -5 * 60,
19570            CST: -6 * 60,
19571            MDT: -6 * 60,
19572            MST: -7 * 60,
19573            PDT: -7 * 60,
19574            PST: -8 * 60,
19575        };
19576
19577    // date from iso format
19578    function configFromISO(config) {
19579        var i,
19580            l,
19581            string = config._i,
19582            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
19583            allowTime,
19584            dateFormat,
19585            timeFormat,
19586            tzFormat,
19587            isoDatesLen = isoDates.length,
19588            isoTimesLen = isoTimes.length;
19589
19590        if (match) {
19591            getParsingFlags(config).iso = true;
19592            for (i = 0, l = isoDatesLen; i < l; i++) {
19593                if (isoDates[i][1].exec(match[1])) {
19594                    dateFormat = isoDates[i][0];
19595                    allowTime = isoDates[i][2] !== false;
19596                    break;
19597                }
19598            }
19599            if (dateFormat == null) {
19600                config._isValid = false;
19601                return;
19602            }
19603            if (match[3]) {
19604                for (i = 0, l = isoTimesLen; i < l; i++) {
19605                    if (isoTimes[i][1].exec(match[3])) {
19606                        // match[2] should be 'T' or space
19607                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
19608                        break;
19609                    }
19610                }
19611                if (timeFormat == null) {
19612                    config._isValid = false;
19613                    return;
19614                }
19615            }
19616            if (!allowTime && timeFormat != null) {
19617                config._isValid = false;
19618                return;
19619            }
19620            if (match[4]) {
19621                if (tzRegex.exec(match[4])) {
19622                    tzFormat = 'Z';
19623                } else {
19624                    config._isValid = false;
19625                    return;
19626                }
19627            }
19628            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
19629            configFromStringAndFormat(config);
19630        } else {
19631            config._isValid = false;
19632        }
19633    }
19634
19635    function extractFromRFC2822Strings(
19636        yearStr,
19637        monthStr,
19638        dayStr,
19639        hourStr,
19640        minuteStr,
19641        secondStr
19642    ) {
19643        var result = [
19644            untruncateYear(yearStr),
19645            defaultLocaleMonthsShort.indexOf(monthStr),
19646            parseInt(dayStr, 10),
19647            parseInt(hourStr, 10),
19648            parseInt(minuteStr, 10),
19649        ];
19650
19651        if (secondStr) {
19652            result.push(parseInt(secondStr, 10));
19653        }
19654
19655        return result;
19656    }
19657
19658    function untruncateYear(yearStr) {
19659        var year = parseInt(yearStr, 10);
19660        if (year <= 49) {
19661            return 2000 + year;
19662        } else if (year <= 999) {
19663            return 1900 + year;
19664        }
19665        return year;
19666    }
19667
19668    function preprocessRFC2822(s) {
19669        // Remove comments and folding whitespace and replace multiple-spaces with a single space
19670        return s
19671            .replace(/\([^()]*\)|[\n\t]/g, ' ')
19672            .replace(/(\s\s+)/g, ' ')
19673            .replace(/^\s\s*/, '')
19674            .replace(/\s\s*$/, '');
19675    }
19676
19677    function checkWeekday(weekdayStr, parsedInput, config) {
19678        if (weekdayStr) {
19679            // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
19680            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
19681                weekdayActual = new Date(
19682                    parsedInput[0],
19683                    parsedInput[1],
19684                    parsedInput[2]
19685                ).getDay();
19686            if (weekdayProvided !== weekdayActual) {
19687                getParsingFlags(config).weekdayMismatch = true;
19688                config._isValid = false;
19689                return false;
19690            }
19691        }
19692        return true;
19693    }
19694
19695    function calculateOffset(obsOffset, militaryOffset, numOffset) {
19696        if (obsOffset) {
19697            return obsOffsets[obsOffset];
19698        } else if (militaryOffset) {
19699            // the only allowed military tz is Z
19700            return 0;
19701        } else {
19702            var hm = parseInt(numOffset, 10),
19703                m = hm % 100,
19704                h = (hm - m) / 100;
19705            return h * 60 + m;
19706        }
19707    }
19708
19709    // date and time from ref 2822 format
19710    function configFromRFC2822(config) {
19711        var match = rfc2822.exec(preprocessRFC2822(config._i)),
19712            parsedArray;
19713        if (match) {
19714            parsedArray = extractFromRFC2822Strings(
19715                match[4],
19716                match[3],
19717                match[2],
19718                match[5],
19719                match[6],
19720                match[7]
19721            );
19722            if (!checkWeekday(match[1], parsedArray, config)) {
19723                return;
19724            }
19725
19726            config._a = parsedArray;
19727            config._tzm = calculateOffset(match[8], match[9], match[10]);
19728
19729            config._d = createUTCDate.apply(null, config._a);
19730            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
19731
19732            getParsingFlags(config).rfc2822 = true;
19733        } else {
19734            config._isValid = false;
19735        }
19736    }
19737
19738    // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
19739    function configFromString(config) {
19740        var matched = aspNetJsonRegex.exec(config._i);
19741        if (matched !== null) {
19742            config._d = new Date(+matched[1]);
19743            return;
19744        }
19745
19746        configFromISO(config);
19747        if (config._isValid === false) {
19748            delete config._isValid;
19749        } else {
19750            return;
19751        }
19752
19753        configFromRFC2822(config);
19754        if (config._isValid === false) {
19755            delete config._isValid;
19756        } else {
19757            return;
19758        }
19759
19760        if (config._strict) {
19761            config._isValid = false;
19762        } else {
19763            // Final attempt, use Input Fallback
19764            hooks.createFromInputFallback(config);
19765        }
19766    }
19767
19768    hooks.createFromInputFallback = deprecate(
19769        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
19770            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
19771            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
19772        function (config) {
19773            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
19774        }
19775    );
19776
19777    // Pick the first defined of two or three arguments.
19778    function defaults(a, b, c) {
19779        if (a != null) {
19780            return a;
19781        }
19782        if (b != null) {
19783            return b;
19784        }
19785        return c;
19786    }
19787
19788    function currentDateArray(config
vendor: 17,694 bytes, lines 19788-20349
19788) {
19789        // hooks is actually the exported moment object
19790        var nowValue = new Date(hooks.now());
19791        if (config._useUTC) {
19792            return [
19793                nowValue.getUTCFullYear(),
19794                nowValue.getUTCMonth(),
19795                nowValue.getUTCDate(),
19796            ];
19797        }
19798        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
19799    }
19800
19801    // convert an array to a date.
19802    // the array should mirror the parameters below
19803    // note: all values past the year are optional and will default to the lowest possible value.
19804    // [year, month, day , hour, minute, second, millisecond]
19805    function configFromArray(config) {
19806        var i,
19807            date,
19808            input = [],
19809            currentDate,
19810            expectedWeekday,
19811            yearToUse;
19812
19813        if (config._d) {
19814            return;
19815        }
19816
19817        currentDate = currentDateArray(config);
19818
19819        //compute day of the year from weeks and weekdays
19820        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
19821            dayOfYearFromWeekInfo(config);
19822        }
19823
19824        //if the day of the year is set, figure out what it is
19825        if (config._dayOfYear != null) {
19826            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
19827
19828            if (
19829                config._dayOfYear > daysInYear(yearToUse) ||
19830                config._dayOfYear === 0
19831            ) {
19832                getParsingFlags(config)._overflowDayOfYear = true;
19833            }
19834
19835            date = createUTCDate(yearToUse, 0, config._dayOfYear);
19836            config._a[MONTH] = date.getUTCMonth();
19837            config._a[DATE] = date.getUTCDate();
19838        }
19839
19840        // Default to current date.
19841        // * if no year, month, day of month are given, default to today
19842        // * if day of month is given, default month and year
19843        // * if month is given, default only year
19844        // * if year is given, don't default anything
19845        for (i = 0; i < 3 && config._a[i] == null; ++i) {
19846            config._a[i] = input[i] = currentDate[i];
19847        }
19848
19849        // Zero out whatever was not defaulted, including time
19850        for (; i < 7; i++) {
19851            config._a[i] = input[i] =
19852                config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
19853        }
19854
19855        // Check for 24:00:00.000
19856        if (
19857            config._a[HOUR] === 24 &&
19858            config._a[MINUTE] === 0 &&
19859            config._a[SECOND] === 0 &&
19860            config._a[MILLISECOND] === 0
19861        ) {
19862            config._nextDay = true;
19863            config._a[HOUR] = 0;
19864        }
19865
19866        config._d = (config._useUTC ? createUTCDate : createDate).apply(
19867            null,
19868            input
19869        );
19870        expectedWeekday = config._useUTC
19871            ? config._d.getUTCDay()
19872            : config._d.getDay();
19873
19874        // Apply timezone offset from input. The actual utcOffset can be changed
19875        // with parseZone.
19876        if (config._tzm != null) {
19877            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
19878        }
19879
19880        if (config._nextDay) {
19881            config._a[HOUR] = 24;
19882        }
19883
19884        // check for mismatching day of week
19885        if (
19886            config._w &&
19887            typeof config._w.d !== 'undefined' &&
19888            config._w.d !== expectedWeekday
19889        ) {
19890            getParsingFlags(config).weekdayMismatch = true;
19891        }
19892    }
19893
19894    function dayOfYearFromWeekInfo(config) {
19895        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
19896
19897        w = config._w;
19898        if (w.GG != null || w.W != null || w.E != null) {
19899            dow = 1;
19900            doy = 4;
19901
19902            // TODO: We need to take the current isoWeekYear, but that depends on
19903            // how we interpret now (local, utc, fixed offset). So create
19904            // a now version of current config (take local/utc/offset flags, and
19905            // create now).
19906            weekYear = defaults(
19907                w.GG,
19908                config._a[YEAR],
19909                weekOfYear(createLocal(), 1, 4).year
19910            );
19911            week = defaults(w.W, 1);
19912            weekday = defaults(w.E, 1);
19913            if (weekday < 1 || weekday > 7) {
19914                weekdayOverflow = true;
19915            }
19916        } else {
19917            dow = config._locale._week.dow;
19918            doy = config._locale._week.doy;
19919
19920            curWeek = weekOfYear(createLocal(), dow, doy);
19921
19922            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
19923
19924            // Default to current week.
19925            week = defaults(w.w, curWeek.week);
19926
19927            if (w.d != null) {
19928                // weekday -- low day numbers are considered next week
19929                weekday = w.d;
19930                if (weekday < 0 || weekday > 6) {
19931                    weekdayOverflow = true;
19932                }
19933            } else if (w.e != null) {
19934                // local weekday -- counting starts from beginning of week
19935                weekday = w.e + dow;
19936                if (w.e < 0 || w.e > 6) {
19937                    weekdayOverflow = true;
19938                }
19939            } else {
19940                // default to beginning of week
19941                weekday = dow;
19942            }
19943        }
19944        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
19945            getParsingFlags(config)._overflowWeeks = true;
19946        } else if (weekdayOverflow != null) {
19947            getParsingFlags(config)._overflowWeekday = true;
19948        } else {
19949            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
19950            config._a[YEAR] = temp.year;
19951            config._dayOfYear = temp.dayOfYear;
19952        }
19953    }
19954
19955    // constant that refers to the ISO standard
19956    hooks.ISO_8601 = function () {};
19957
19958    // constant that refers to the RFC 2822 form
19959    hooks.RFC_2822 = function () {};
19960
19961    // date from string and format string
19962    function configFromStringAndFormat(config) {
19963        // TODO: Move this to another part of the creation flow to prevent circular deps
19964        if (config._f === hooks.ISO_8601) {
19965            configFromISO(config);
19966            return;
19967        }
19968        if (config._f === hooks.RFC_2822) {
19969            configFromRFC2822(config);
19970            return;
19971        }
19972        config._a = [];
19973        getParsingFlags(config).empty = true;
19974
19975        // This array is used to make a Date, either with `new Date` or `Date.UTC`
19976        var string = '' + config._i,
19977            i,
19978            parsedInput,
19979            tokens,
19980            token,
19981            skipped,
19982            stringLength = string.length,
19983            totalParsedInputLength = 0,
19984            era,
19985            tokenLen;
19986
19987        tokens =
19988            expandFormat(config._f, config._locale).match(formattingTokens) || [];
19989        tokenLen = tokens.length;
19990        for (i = 0; i < tokenLen; i++) {
19991            token = tokens[i];
19992            parsedInput = (string.match(getParseRegexForToken(token, config)) ||
19993                [])[0];
19994            if (parsedInput) {
19995                skipped = string.substr(0, string.indexOf(parsedInput));
19996                if (skipped.length > 0) {
19997                    getParsingFlags(config).unusedInput.push(skipped);
19998                }
19999                string = string.slice(
20000                    string.indexOf(parsedInput) + parsedInput.length
20001                );
20002                totalParsedInputLength += parsedInput.length;
20003            }
20004            // don't parse if it's not a known token
20005            if (formatTokenFunctions[token]) {
20006                if (parsedInput) {
20007                    getParsingFlags(config).empty = false;
20008                } else {
20009                    getParsingFlags(config).unusedTokens.push(token);
20010                }
20011                addTimeToArrayFromToken(token, parsedInput, config);
20012            } else if (config._strict && !parsedInput) {
20013                getParsingFlags(config).unusedTokens.push(token);
20014            }
20015        }
20016
20017        // add remaining unparsed input length to the string
20018        getParsingFlags(config).charsLeftOver =
20019            stringLength - totalParsedInputLength;
20020        if (string.length > 0) {
20021            getParsingFlags(config).unusedInput.push(string);
20022        }
20023
20024        // clear _12h flag if hour is <= 12
20025        if (
20026            config._a[HOUR] <= 12 &&
20027            getParsingFlags(config).bigHour === true &&
20028            config._a[HOUR] > 0
20029        ) {
20030            getParsingFlags(config).bigHour = undefined;
20031        }
20032
20033        getParsingFlags(config).parsedDateParts = config._a.slice(0);
20034        getParsingFlags(config).meridiem = config._meridiem;
20035        // handle meridiem
20036        config._a[HOUR] = meridiemFixWrap(
20037            config._locale,
20038            config._a[HOUR],
20039            config._meridiem
20040        );
20041
20042        // handle era
20043        era = getParsingFlags(config).era;
20044        if (era !== null) {
20045            config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
20046        }
20047
20048        configFromArray(config);
20049        checkOverflow(config);
20050    }
20051
20052    function meridiemFixWrap(locale, hour, meridiem) {
20053        var isPm;
20054
20055        if (meridiem == null) {
20056            // nothing to do
20057            return hour;
20058        }
20059        if (locale.meridiemHour != null) {
20060            return locale.meridiemHour(hour, meridiem);
20061        } else if (locale.isPM != null) {
20062            // Fallback
20063            isPm = locale.isPM(meridiem);
20064            if (isPm && hour < 12) {
20065                hour += 12;
20066            }
20067            if (!isPm && hour === 12) {
20068                hour = 0;
20069            }
20070            return hour;
20071        } else {
20072            // this is not supposed to happen
20073            return hour;
20074        }
20075    }
20076
20077    // date from string and array of format strings
20078    function configFromStringAndArray(config) {
20079        var tempConfig,
20080            bestMoment,
20081            scoreToBeat,
20082            i,
20083            currentScore,
20084            validFormatFound,
20085            bestFormatIsValid = false,
20086            configfLen = config._f.length;
20087
20088        if (configfLen === 0) {
20089            getParsingFlags(config).invalidFormat = true;
20090            config._d = new Date(NaN);
20091            return;
20092        }
20093
20094        for (i = 0; i < configfLen; i++) {
20095            currentScore = 0;
20096            validFormatFound = false;
20097            tempConfig = copyConfig({}, config);
20098            if (config._useUTC != null) {
20099                tempConfig._useUTC = config._useUTC;
20100            }
20101            tempConfig._f = config._f[i];
20102            configFromStringAndFormat(tempConfig);
20103
20104            if (isValid(tempConfig)) {
20105                validFormatFound = true;
20106            }
20107
20108            // if there is any input that was not parsed add a penalty for that format
20109            currentScore += getParsingFlags(tempConfig).charsLeftOver;
20110
20111            //or tokens
20112            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
20113
20114            getParsingFlags(tempConfig).score = currentScore;
20115
20116            if (!bestFormatIsValid) {
20117                if (
20118                    scoreToBeat == null ||
20119                    currentScore < scoreToBeat ||
20120                    validFormatFound
20121                ) {
20122                    scoreToBeat = currentScore;
20123                    bestMoment = tempConfig;
20124                    if (validFormatFound) {
20125                        bestFormatIsValid = true;
20126                    }
20127                }
20128            } else {
20129                if (currentScore < scoreToBeat) {
20130                    scoreToBeat = currentScore;
20131                    bestMoment = tempConfig;
20132                }
20133            }
20134        }
20135
20136        extend(config, bestMoment || tempConfig);
20137    }
20138
20139    function configFromObject(config) {
20140        if (config._d) {
20141            return;
20142        }
20143
20144        var i = normalizeObjectUnits(config._i),
20145            dayOrDate = i.day === undefined ? i.date : i.day;
20146        config._a = map(
20147            [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
20148            function (obj) {
20149                return obj && parseInt(obj, 10);
20150            }
20151        );
20152
20153        configFromArray(config);
20154    }
20155
20156    function createFromConfig(config) {
20157        var res = new Moment(checkOverflow(prepareConfig(config)));
20158        if (res._nextDay) {
20159            // Adding is smart enough around DST
20160            res.add(1, 'd');
20161            res._nextDay = undefined;
20162        }
20163
20164        return res;
20165    }
20166
20167    function prepareConfig(config) {
20168        var input = config._i,
20169            format = config._f;
20170
20171        config._locale = config._locale || getLocale(config._l);
20172
20173        if (input === null || (format === undefined && input === '')) {
20174            return createInvalid({ nullInput: true });
20175        }
20176
20177        if (typeof input === 'string') {
20178            config._i = input = config._locale.preparse(input);
20179        }
20180
20181        if (isMoment(input)) {
20182            return new Moment(checkOverflow(input));
20183        } else if (isDate(input)) {
20184            config._d = input;
20185        } else if (isArray(format)) {
20186            configFromStringAndArray(config);
20187        } else if (format) {
20188            configFromStringAndFormat(config);
20189        } else {
20190            configFromInput(config);
20191        }
20192
20193        if (!isValid(config)) {
20194            config._d = null;
20195        }
20196
20197        return config;
20198    }
20199
20200    function configFromInput(config) {
20201        var input = config._i;
20202        if (isUndefined(input)) {
20203            config._d = new Date(hooks.now());
20204        } else if (isDate(input)) {
20205            config._d = new Date(input.valueOf());
20206        } else if (typeof input === 'string') {
20207            configFromString(config);
20208        } else if (isArray(input)) {
20209            config._a = map(input.slice(0), function (obj) {
20210                return parseInt(obj, 10);
20211            });
20212            configFromArray(config);
20213        } else if (isObject(input)) {
20214            configFromObject(config);
20215        } else if (isNumber(input)) {
20216            // from milliseconds
20217            config._d = new Date(input);
20218        } else {
20219            hooks.createFromInputFallback(config);
20220        }
20221    }
20222
20223    function createLocalOrUTC(input, format, locale, strict, isUTC) {
20224        var c = {};
20225
20226        if (format === true || format === false) {
20227            strict = format;
20228            format = undefined;
20229        }
20230
20231        if (locale === true || locale === false) {
20232            strict = locale;
20233            locale = undefined;
20234        }
20235
20236        if (
20237            (isObject(input) && isObjectEmpty(input)) ||
20238            (isArray(input) && input.length === 0)
20239        ) {
20240            input = undefined;
20241        }
20242        // object construction must be done this way.
20243        // https://github.com/moment/moment/issues/1423
20244        c._isAMomentObject = true;
20245        c._useUTC = c._isUTC = isUTC;
20246        c._l = locale;
20247        c._i = input;
20248        c._f = format;
20249        c._strict = strict;
20250
20251        return createFromConfig(c);
20252    }
20253
20254    function createLocal(input, format, locale, strict) {
20255        return createLocalOrUTC(input, format, locale, strict, false);
20256    }
20257
20258    var prototypeMin = deprecate(
20259            'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
20260            function () {
20261                var other = createLocal.apply(null, arguments);
20262                if (this.isValid() && other.isValid()) {
20263                    return other < this ? this : other;
20264                } else {
20265                    return createInvalid();
20266                }
20267            }
20268        ),
20269        prototypeMax = deprecate(
20270            'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
20271            function () {
20272                var other = createLocal.apply(null, arguments);
20273                if (this.isValid() && other.isValid()) {
20274                    return other > this ? this : other;
20275                } else {
20276                    return createInvalid();
20277                }
20278            }
20279        );
20280
20281    // Pick a moment m from moments so that m[fn](other) is true for all
20282    // other. This relies on the function fn to be transitive.
20283    //
20284    // moments should either be an array of moment objects or an array, whose
20285    // first element is an array of moment objects.
20286    function pickBy(fn, moments) {
20287        var res, i;
20288        if (moments.length === 1 && isArray(moments[0])) {
20289            moments = moments[0];
20290        }
20291        if (!moments.length) {
20292            return createLocal();
20293        }
20294        res = moments[0];
20295        for (i = 1; i < moments.length; ++i) {
20296            if (!moments[i].isValid() || moments[i][fn](res)) {
20297                res = moments[i];
20298            }
20299        }
20300        return res;
20301    }
20302
20303    // TODO: Use [].sort instead?
20304    function min() {
20305        var args = [].slice.call(arguments, 0);
20306
20307        return pickBy('isBefore', args);
20308    }
20309
20310    function max() {
20311        var args = [].slice.call(arguments, 0);
20312
20313        return pickBy('isAfter', args);
20314    }
20315
20316    var now = function () {
20317        return Date.now ? Date.now() : +new Date();
20318    };
20319
20320    var ordering = [
20321        'year',
20322        'quarter',
20323        'month',
20324        'week',
20325        'day',
20326        'hour',
20327        'minute',
20328        'second',
20329        'millisecond',
20330    ];
20331
20332    function isDurationValid(m) {
20333        var key,
20334            unitHasDecimal = false,
20335            i,
20336            orderLen = ordering.length;
20337        for (key in m) {
20338            if (
20339                hasOwnProp(m, key) &&
20340                !(
20341                    indexOf.call(ordering, key) !== -1 &&
20342                    (m[key] == null || !isNaN(m[key]))
20343                )
20344            ) {
20345                return false;
20346            }
20347        }
20348
20349        for (i = 0; i < orderLen
vendor: 10,251 bytes, lines 20349-20674
20349; ++i) {
20350            if (m[ordering[i]]) {
20351                if (unitHasDecimal) {
20352                    return false; // only allow non-integers for smallest unit
20353                }
20354                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
20355                    unitHasDecimal = true;
20356                }
20357            }
20358        }
20359
20360        return true;
20361    }
20362
20363    function isValid$1() {
20364        return this._isValid;
20365    }
20366
20367    function createInvalid$1() {
20368        return createDuration(NaN);
20369    }
20370
20371    function Duration(duration) {
20372        var normalizedInput = normalizeObjectUnits(duration),
20373            years = normalizedInput.year || 0,
20374            quarters = normalizedInput.quarter || 0,
20375            months = normalizedInput.month || 0,
20376            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
20377            days = normalizedInput.day || 0,
20378            hours = normalizedInput.hour || 0,
20379            minutes = normalizedInput.minute || 0,
20380            seconds = normalizedInput.second || 0,
20381            milliseconds = normalizedInput.millisecond || 0;
20382
20383        this._isValid = isDurationValid(normalizedInput);
20384
20385        // representation for dateAddRemove
20386        this._milliseconds =
20387            +milliseconds +
20388            seconds * 1e3 + // 1000
20389            minutes * 6e4 + // 1000 * 60
20390            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
20391        // Because of dateAddRemove treats 24 hours as different from a
20392        // day when working around DST, we need to store them separately
20393        this._days = +days + weeks * 7;
20394        // It is impossible to translate months into days without knowing
20395        // which months you are are talking about, so we have to store
20396        // it separately.
20397        this._months = +months + quarters * 3 + years * 12;
20398
20399        this._data = {};
20400
20401        this._locale = getLocale();
20402
20403        this._bubble();
20404    }
20405
20406    function isDuration(obj) {
20407        return obj instanceof Duration;
20408    }
20409
20410    function absRound(number) {
20411        if (number < 0) {
20412            return Math.round(-1 * number) * -1;
20413        } else {
20414            return Math.round(number);
20415        }
20416    }
20417
20418    // compare two arrays, return the number of differences
20419    function compareArrays(array1, array2, dontConvert) {
20420        var len = Math.min(array1.length, array2.length),
20421            lengthDiff = Math.abs(array1.length - array2.length),
20422            diffs = 0,
20423            i;
20424        for (i = 0; i < len; i++) {
20425            if (
20426                (dontConvert && array1[i] !== array2[i]) ||
20427                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
20428            ) {
20429                diffs++;
20430            }
20431        }
20432        return diffs + lengthDiff;
20433    }
20434
20435    // FORMATTING
20436
20437    function offset(token, separator) {
20438        addFormatToken(token, 0, 0, function () {
20439            var offset = this.utcOffset(),
20440                sign = '+';
20441            if (offset < 0) {
20442                offset = -offset;
20443                sign = '-';
20444            }
20445            return (
20446                sign +
20447                zeroFill(~~(offset / 60), 2) +
20448                separator +
20449                zeroFill(~~offset % 60, 2)
20450            );
20451        });
20452    }
20453
20454    offset('Z', ':');
20455    offset('ZZ', '');
20456
20457    // PARSING
20458
20459    addRegexToken('Z', matchShortOffset);
20460    addRegexToken('ZZ', matchShortOffset);
20461    addParseToken(['Z', 'ZZ'], function (input, array, config) {
20462        config._useUTC = true;
20463        config._tzm = offsetFromString(matchShortOffset, input);
20464    });
20465
20466    // HELPERS
20467
20468    // timezone chunker
20469    // '+10:00' > ['10',  '00']
20470    // '-1530'  > ['-15', '30']
20471    var chunkOffset = /([\+\-]|\d\d)/gi;
20472
20473    function offsetFromString(matcher, string) {
20474        var matches = (string || '').match(matcher),
20475            chunk,
20476            parts,
20477            minutes;
20478
20479        if (matches === null) {
20480            return null;
20481        }
20482
20483        chunk = matches[matches.length - 1] || [];
20484        parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
20485        minutes = +(parts[1] * 60) + toInt(parts[2]);
20486
20487        return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
20488    }
20489
20490    // Return a moment from input, that is local/utc/zone equivalent to model.
20491    function cloneWithOffset(input, model) {
20492        var res, diff;
20493        if (model._isUTC) {
20494            res = model.clone();
20495            diff =
20496                (isMoment(input) || isDate(input)
20497                    ? input.valueOf()
20498                    : createLocal(input).valueOf()) - res.valueOf();
20499            // Use low-level api, because this fn is low-level api.
20500            res._d.setTime(res._d.valueOf() + diff);
20501            hooks.updateOffset(res, false);
20502            return res;
20503        } else {
20504            return createLocal(input).local();
20505        }
20506    }
20507
20508    function getDateOffset(m) {
20509        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
20510        // https://github.com/moment/moment/pull/1871
20511        return -Math.round(m._d.getTimezoneOffset());
20512    }
20513
20514    // HOOKS
20515
20516    // This function will be called whenever a moment is mutated.
20517    // It is intended to keep the offset in sync with the timezone.
20518    hooks.updateOffset = function () {};
20519
20520    // MOMENTS
20521
20522    // keepLocalTime = true means only change the timezone, without
20523    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
20524    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
20525    // +0200, so we adjust the time as needed, to be valid.
20526    //
20527    // Keeping the time actually adds/subtracts (one hour)
20528    // from the actual represented time. That is why we call updateOffset
20529    // a second time. In case it wants us to change the offset again
20530    // _changeInProgress == true case, then we have to adjust, because
20531    // there is no such time in the given timezone.
20532    function getSetOffset(input, keepLocalTime, keepMinutes) {
20533        var offset = this._offset || 0,
20534            localAdjust;
20535        if (!this.isValid()) {
20536            return input != null ? this : NaN;
20537        }
20538        if (input != null) {
20539            if (typeof input === 'string') {
20540                input = offsetFromString(matchShortOffset, input);
20541                if (input === null) {
20542                    return this;
20543                }
20544            } else if (Math.abs(input) < 16 && !keepMinutes) {
20545                input = input * 60;
20546            }
20547            if (!this._isUTC && keepLocalTime) {
20548                localAdjust = getDateOffset(this);
20549            }
20550            this._offset = input;
20551            this._isUTC = true;
20552            if (localAdjust != null) {
20553                this.add(localAdjust, 'm');
20554            }
20555            if (offset !== input) {
20556                if (!keepLocalTime || this._changeInProgress) {
20557                    addSubtract(
20558                        this,
20559                        createDuration(input - offset, 'm'),
20560                        1,
20561                        false
20562                    );
20563                } else if (!this._changeInProgress) {
20564                    this._changeInProgress = true;
20565                    hooks.updateOffset(this, true);
20566                    this._changeInProgress = null;
20567                }
20568            }
20569            return this;
20570        } else {
20571            return this._isUTC ? offset : getDateOffset(this);
20572        }
20573    }
20574
20575    function getSetZone(input, keepLocalTime) {
20576        if (input != null) {
20577            if (typeof input !== 'string') {
20578                input = -input;
20579            }
20580
20581            this.utcOffset(input, keepLocalTime);
20582
20583            return this;
20584        } else {
20585            return -this.utcOffset();
20586        }
20587    }
20588
20589    function setOffsetToUTC(keepLocalTime) {
20590        return this.utcOffset(0, keepLocalTime);
20591    }
20592
20593    function setOffsetToLocal(keepLocalTime) {
20594        if (this._isUTC) {
20595            this.utcOffset(0, keepLocalTime);
20596            this._isUTC = false;
20597
20598            if (keepLocalTime) {
20599                this.subtract(getDateOffset(this), 'm');
20600            }
20601        }
20602        return this;
20603    }
20604
20605    function setOffsetToParsedOffset() {
20606        if (this._tzm != null) {
20607            this.utcOffset(this._tzm, false, true);
20608        } else if (typeof this._i === 'string') {
20609            var tZone = offsetFromString(matchOffset, this._i);
20610            if (tZone != null) {
20611                this.utcOffset(tZone);
20612            } else {
20613                this.utcOffset(0, true);
20614            }
20615        }
20616        return this;
20617    }
20618
20619    function hasAlignedHourOffset(input) {
20620        if (!this.isValid()) {
20621            return false;
20622        }
20623        input = input ? createLocal(input).utcOffset() : 0;
20624
20625        return (this.utcOffset() - input) % 60 === 0;
20626    }
20627
20628    function isDaylightSavingTime() {
20629        return (
20630            this.utcOffset() > this.clone().month(0).utcOffset() ||
20631            this.utcOffset() > this.clone().month(5).utcOffset()
20632        );
20633    }
20634
20635    function isDaylightSavingTimeShifted() {
20636        if (!isUndefined(this._isDSTShifted)) {
20637            return this._isDSTShifted;
20638        }
20639
20640        var c = {},
20641            other;
20642
20643        copyConfig(c, this);
20644        c = prepareConfig(c);
20645
20646        if (c._a) {
20647            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
20648            this._isDSTShifted =
20649                this.isValid() && compareArrays(c._a, other.toArray()) > 0;
20650        } else {
20651            this._isDSTShifted = false;
20652        }
20653
20654        return this._isDSTShifted;
20655    }
20656
20657    function isLocal() {
20658        return this.isValid() ? !this._isUTC : false;
20659    }
20660
20661    function isUtcOffset() {
20662        return this.isValid() ? this._isUTC : false;
20663    }
20664
20665    function isUtc() {
20666        return this.isValid() ? this._isUTC && this._offset === 0 : false;
20667    }
20668
20669    // ASP.NET json date format regex
20670    var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
20671        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
20672        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
20673        // and further modified to allow for strings containing both week and day
20674        isoRegex =
vendor: 9,021 bytes, lines 20674-20964
20674
20675            /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
20676
20677    function createDuration(input, key) {
20678        var duration = input,
20679            // matching against regexp is expensive, do it on demand
20680            match = null,
20681            sign,
20682            ret,
20683            diffRes;
20684
20685        if (isDuration(input)) {
20686            duration = {
20687                ms: input._milliseconds,
20688                d: input._days,
20689                M: input._months,
20690            };
20691        } else if (isNumber(input) || !isNaN(+input)) {
20692            duration = {};
20693            if (key) {
20694                duration[key] = +input;
20695            } else {
20696                duration.milliseconds = +input;
20697            }
20698        } else if ((match = aspNetRegex.exec(input))) {
20699            sign = match[1] === '-' ? -1 : 1;
20700            duration = {
20701                y: 0,
20702                d: toInt(match[DATE]) * sign,
20703                h: toInt(match[HOUR]) * sign,
20704                m: toInt(match[MINUTE]) * sign,
20705                s: toInt(match[SECOND]) * sign,
20706                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
20707            };
20708        } else if ((match = isoRegex.exec(input))) {
20709            sign = match[1] === '-' ? -1 : 1;
20710            duration = {
20711                y: parseIso(match[2], sign),
20712                M: parseIso(match[3], sign),
20713                w: parseIso(match[4], sign),
20714                d: parseIso(match[5], sign),
20715                h: parseIso(match[6], sign),
20716                m: parseIso(match[7], sign),
20717                s: parseIso(match[8], sign),
20718            };
20719        } else if (duration == null) {
20720            // checks for null or undefined
20721            duration = {};
20722        } else if (
20723            typeof duration === 'object' &&
20724            ('from' in duration || 'to' in duration)
20725        ) {
20726            diffRes = momentsDifference(
20727                createLocal(duration.from),
20728                createLocal(duration.to)
20729            );
20730
20731            duration = {};
20732            duration.ms = diffRes.milliseconds;
20733            duration.M = diffRes.months;
20734        }
20735
20736        ret = new Duration(duration);
20737
20738        if (isDuration(input) && hasOwnProp(input, '_locale')) {
20739            ret._locale = input._locale;
20740        }
20741
20742        if (isDuration(input) && hasOwnProp(input, '_isValid')) {
20743            ret._isValid = input._isValid;
20744        }
20745
20746        return ret;
20747    }
20748
20749    createDuration.fn = Duration.prototype;
20750    createDuration.invalid = createInvalid$1;
20751
20752    function parseIso(inp, sign) {
20753        // We'd normally use ~~inp for this, but unfortunately it also
20754        // converts floats to ints.
20755        // inp may be undefined, so careful calling replace on it.
20756        var res = inp && parseFloat(inp.replace(',', '.'));
20757        // apply sign while we're at it
20758        return (isNaN(res) ? 0 : res) * sign;
20759    }
20760
20761    function positiveMomentsDifference(base, other) {
20762        var res = {};
20763
20764        res.months =
20765            other.month() - base.month() + (other.year() - base.year()) * 12;
20766        if (base.clone().add(res.months, 'M').isAfter(other)) {
20767            --res.months;
20768        }
20769
20770        res.milliseconds = +other - +base.clone().add(res.months, 'M');
20771
20772        return res;
20773    }
20774
20775    function momentsDifference(base, other) {
20776        var res;
20777        if (!(base.isValid() && other.isValid())) {
20778            return { milliseconds: 0, months: 0 };
20779        }
20780
20781        other = cloneWithOffset(other, base);
20782        if (base.isBefore(other)) {
20783            res = positiveMomentsDifference(base, other);
20784        } else {
20785            res = positiveMomentsDifference(other, base);
20786            res.milliseconds = -res.milliseconds;
20787            res.months = -res.months;
20788        }
20789
20790        return res;
20791    }
20792
20793    // TODO: remove 'name' arg after deprecation is removed
20794    function createAdder(direction, name) {
20795        return function (val, period) {
20796            var dur, tmp;
20797            //invert the arguments, but complain about it
20798            if (period !== null && !isNaN(+period)) {
20799                deprecateSimple(
20800                    name,
20801                    'moment().' +
20802                        name +
20803                        '(period, number) is deprecated. Please use moment().' +
20804                        name +
20805                        '(number, period). ' +
20806                        'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
20807                );
20808                tmp = val;
20809                val = period;
20810                period = tmp;
20811            }
20812
20813            dur = createDuration(val, period);
20814            addSubtract(this, dur, direction);
20815            return this;
20816        };
20817    }
20818
20819    function addSubtract(mom, duration, isAdding, updateOffset) {
20820        var milliseconds = duration._milliseconds,
20821            days = absRound(duration._days),
20822            months = absRound(duration._months);
20823
20824        if (!mom.isValid()) {
20825            // No op
20826            return;
20827        }
20828
20829        updateOffset = updateOffset == null ? true : updateOffset;
20830
20831        if (months) {
20832            setMonth(mom, get(mom, 'Month') + months * isAdding);
20833        }
20834        if (days) {
20835            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
20836        }
20837        if (milliseconds) {
20838            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
20839        }
20840        if (updateOffset) {
20841            hooks.updateOffset(mom, days || months);
20842        }
20843    }
20844
20845    var add = createAdder(1, 'add'),
20846        subtract = createAdder(-1, 'subtract');
20847
20848    function isString(input) {
20849        return typeof input === 'string' || input instanceof String;
20850    }
20851
20852    // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
20853    function isMomentInput(input) {
20854        return (
20855            isMoment(input) ||
20856            isDate(input) ||
20857            isString(input) ||
20858            isNumber(input) ||
20859            isNumberOrStringArray(input) ||
20860            isMomentInputObject(input) ||
20861            input === null ||
20862            input === undefined
20863        );
20864    }
20865
20866    function isMomentInputObject(input) {
20867        var objectTest = isObject(input) && !isObjectEmpty(input),
20868            propertyTest = false,
20869            properties = [
20870                'years',
20871                'year',
20872                'y',
20873                'months',
20874                'month',
20875                'M',
20876                'days',
20877                'day',
20878                'd',
20879                'dates',
20880                'date',
20881                'D',
20882                'hours',
20883                'hour',
20884                'h',
20885                'minutes',
20886                'minute',
20887                'm',
20888                'seconds',
20889                'second',
20890                's',
20891                'milliseconds',
20892                'millisecond',
20893                'ms',
20894            ],
20895            i,
20896            property,
20897            propertyLen = properties.length;
20898
20899        for (i = 0; i < propertyLen; i += 1) {
20900            property = properties[i];
20901            propertyTest = propertyTest || hasOwnProp(input, property);
20902        }
20903
20904        return objectTest && propertyTest;
20905    }
20906
20907    function isNumberOrStringArray(input) {
20908        var arrayTest = isArray(input),
20909            dataTypeTest = false;
20910        if (arrayTest) {
20911            dataTypeTest =
20912                input.filter(function (item) {
20913                    return !isNumber(item) && isString(input);
20914                }).length === 0;
20915        }
20916        return arrayTest && dataTypeTest;
20917    }
20918
20919    function isCalendarSpec(input) {
20920        var objectTest = isObject(input) && !isObjectEmpty(input),
20921            propertyTest = false,
20922            properties = [
20923                'sameDay',
20924                'nextDay',
20925                'lastDay',
20926                'nextWeek',
20927                'lastWeek',
20928                'sameElse',
20929            ],
20930            i,
20931            property;
20932
20933        for (i = 0; i < properties.length; i += 1) {
20934            property = properties[i];
20935            propertyTest = propertyTest || hasOwnProp(input, property);
20936        }
20937
20938        return objectTest && propertyTest;
20939    }
20940
20941    function getCalendarFormat(myMoment, now) {
20942        var diff = myMoment.diff(now, 'days', true);
20943        return diff < -6
20944            ? 'sameElse'
20945            : diff < -1
20946            ? 'lastWeek'
20947            : diff < 0
20948            ? 'lastDay'
20949            : diff < 1
20950            ? 'sameDay'
20951            : diff < 2
20952            ? 'nextDay'
20953            : diff < 7
20954            ? 'nextWeek'
20955            : 'sameElse';
20956    }
20957
20958    function calendar$1(time, formats) {
20959        // Support for single parameter, formats only overload to the calendar function
20960        if (arguments.length === 1) {
20961            if (!arguments[0]) {
20962                time = undefined;
20963                formats = undefined;
20964            } else
vendor: 17,627 bytes, lines 20964-21522
20964 if (isMomentInput(arguments[0])) {
20965                time = arguments[0];
20966                formats = undefined;
20967            } else if (isCalendarSpec(arguments[0])) {
20968                formats = arguments[0];
20969                time = undefined;
20970            }
20971        }
20972        // We want to compare the start of today, vs this.
20973        // Getting start-of-today depends on whether we're local/utc/offset or not.
20974        var now = time || createLocal(),
20975            sod = cloneWithOffset(now, this).startOf('day'),
20976            format = hooks.calendarFormat(this, sod) || 'sameElse',
20977            output =
20978                formats &&
20979                (isFunction(formats[format])
20980                    ? formats[format].call(this, now)
20981                    : formats[format]);
20982
20983        return this.format(
20984            output || this.localeData().calendar(format, this, createLocal(now))
20985        );
20986    }
20987
20988    function clone() {
20989        return new Moment(this);
20990    }
20991
20992    function isAfter(input, units) {
20993        var localInput = isMoment(input) ? input : createLocal(input);
20994        if (!(this.isValid() && localInput.isValid())) {
20995            return false;
20996        }
20997        units = normalizeUnits(units) || 'millisecond';
20998        if (units === 'millisecond') {
20999            return this.valueOf() > localInput.valueOf();
21000        } else {
21001            return localInput.valueOf() < this.clone().startOf(units).valueOf();
21002        }
21003    }
21004
21005    function isBefore(input, units) {
21006        var localInput = isMoment(input) ? input : createLocal(input);
21007        if (!(this.isValid() && localInput.isValid())) {
21008            return false;
21009        }
21010        units = normalizeUnits(units) || 'millisecond';
21011        if (units === 'millisecond') {
21012            return this.valueOf() < localInput.valueOf();
21013        } else {
21014            return this.clone().endOf(units).valueOf() < localInput.valueOf();
21015        }
21016    }
21017
21018    function isBetween(from, to, units, inclusivity) {
21019        var localFrom = isMoment(from) ? from : createLocal(from),
21020            localTo = isMoment(to) ? to : createLocal(to);
21021        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
21022            return false;
21023        }
21024        inclusivity = inclusivity || '()';
21025        return (
21026            (inclusivity[0] === '('
21027                ? this.isAfter(localFrom, units)
21028                : !this.isBefore(localFrom, units)) &&
21029            (inclusivity[1] === ')'
21030                ? this.isBefore(localTo, units)
21031                : !this.isAfter(localTo, units))
21032        );
21033    }
21034
21035    function isSame(input, units) {
21036        var localInput = isMoment(input) ? input : createLocal(input),
21037            inputMs;
21038        if (!(this.isValid() && localInput.isValid())) {
21039            return false;
21040        }
21041        units = normalizeUnits(units) || 'millisecond';
21042        if (units === 'millisecond') {
21043            return this.valueOf() === localInput.valueOf();
21044        } else {
21045            inputMs = localInput.valueOf();
21046            return (
21047                this.clone().startOf(units).valueOf() <= inputMs &&
21048                inputMs <= this.clone().endOf(units).valueOf()
21049            );
21050        }
21051    }
21052
21053    function isSameOrAfter(input, units) {
21054        return this.isSame(input, units) || this.isAfter(input, units);
21055    }
21056
21057    function isSameOrBefore(input, units) {
21058        return this.isSame(input, units) || this.isBefore(input, units);
21059    }
21060
21061    function diff(input, units, asFloat) {
21062        var that, zoneDelta, output;
21063
21064        if (!this.isValid()) {
21065            return NaN;
21066        }
21067
21068        that = cloneWithOffset(input, this);
21069
21070        if (!that.isValid()) {
21071            return NaN;
21072        }
21073
21074        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
21075
21076        units = normalizeUnits(units);
21077
21078        switch (units) {
21079            case 'year':
21080                output = monthDiff(this, that) / 12;
21081                break;
21082            case 'month':
21083                output = monthDiff(this, that);
21084                break;
21085            case 'quarter':
21086                output = monthDiff(this, that) / 3;
21087                break;
21088            case 'second':
21089                output = (this - that) / 1e3;
21090                break; // 1000
21091            case 'minute':
21092                output = (this - that) / 6e4;
21093                break; // 1000 * 60
21094            case 'hour':
21095                output = (this - that) / 36e5;
21096                break; // 1000 * 60 * 60
21097            case 'day':
21098                output = (this - that - zoneDelta) / 864e5;
21099                break; // 1000 * 60 * 60 * 24, negate dst
21100            case 'week':
21101                output = (this - that - zoneDelta) / 6048e5;
21102                break; // 1000 * 60 * 60 * 24 * 7, negate dst
21103            default:
21104                output = this - that;
21105        }
21106
21107        return asFloat ? output : absFloor(output);
21108    }
21109
21110    function monthDiff(a, b) {
21111        if (a.date() < b.date()) {
21112            // end-of-month calculations work correct when the start month has more
21113            // days than the end month.
21114            return -monthDiff(b, a);
21115        }
21116        // difference in months
21117        var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
21118            // b is in (anchor - 1 month, anchor + 1 month)
21119            anchor = a.clone().add(wholeMonthDiff, 'months'),
21120            anchor2,
21121            adjust;
21122
21123        if (b - anchor < 0) {
21124            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
21125            // linear across the month
21126            adjust = (b - anchor) / (anchor - anchor2);
21127        } else {
21128            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
21129            // linear across the month
21130            adjust = (b - anchor) / (anchor2 - anchor);
21131        }
21132
21133        //check for negative zero, return zero if negative zero
21134        return -(wholeMonthDiff + adjust) || 0;
21135    }
21136
21137    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
21138    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
21139
21140    function toString() {
21141        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
21142    }
21143
21144    function toISOString(keepOffset) {
21145        if (!this.isValid()) {
21146            return null;
21147        }
21148        var utc = keepOffset !== true,
21149            m = utc ? this.clone().utc() : this;
21150        if (m.year() < 0 || m.year() > 9999) {
21151            return formatMoment(
21152                m,
21153                utc
21154                    ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
21155                    : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
21156            );
21157        }
21158        if (isFunction(Date.prototype.toISOString)) {
21159            // native implementation is ~50x faster, use it when we can
21160            if (utc) {
21161                return this.toDate().toISOString();
21162            } else {
21163                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
21164                    .toISOString()
21165                    .replace('Z', formatMoment(m, 'Z'));
21166            }
21167        }
21168        return formatMoment(
21169            m,
21170            utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
21171        );
21172    }
21173
21174    /**
21175     * Return a human readable representation of a moment that can
21176     * also be evaluated to get a new moment which is the same
21177     *
21178     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
21179     */
21180    function inspect() {
21181        if (!this.isValid()) {
21182            return 'moment.invalid(/* ' + this._i + ' */)';
21183        }
21184        var func = 'moment',
21185            zone = '',
21186            prefix,
21187            year,
21188            datetime,
21189            suffix;
21190        if (!this.isLocal()) {
21191            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
21192            zone = 'Z';
21193        }
21194        prefix = '[' + func + '("]';
21195        year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
21196        datetime = '-MM-DD[T]HH:mm:ss.SSS';
21197        suffix = zone + '[")]';
21198
21199        return this.format(prefix + year + datetime + suffix);
21200    }
21201
21202    function format(inputString) {
21203        if (!inputString) {
21204            inputString = this.isUtc()
21205                ? hooks.defaultFormatUtc
21206                : hooks.defaultFormat;
21207        }
21208        var output = formatMoment(this, inputString);
21209        return this.localeData().postformat(output);
21210    }
21211
21212    function from(time, withoutSuffix) {
21213        if (
21214            this.isValid() &&
21215            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
21216        ) {
21217            return createDuration({ to: this, from: time })
21218                .locale(this.locale())
21219                .humanize(!withoutSuffix);
21220        } else {
21221            return this.localeData().invalidDate();
21222        }
21223    }
21224
21225    function fromNow(withoutSuffix) {
21226        return this.from(createLocal(), withoutSuffix);
21227    }
21228
21229    function to(time, withoutSuffix) {
21230        if (
21231            this.isValid() &&
21232            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
21233        ) {
21234            return createDuration({ from: this, to: time })
21235                .locale(this.locale())
21236                .humanize(!withoutSuffix);
21237        } else {
21238            return this.localeData().invalidDate();
21239        }
21240    }
21241
21242    function toNow(withoutSuffix) {
21243        return this.to(createLocal(), withoutSuffix);
21244    }
21245
21246    // If passed a locale key, it will set the locale for this
21247    // instance.  Otherwise, it will return the locale configuration
21248    // variables for this instance.
21249    function locale(key) {
21250        var newLocaleData;
21251
21252        if (key === undefined) {
21253            return this._locale._abbr;
21254        } else {
21255            newLocaleData = getLocale(key);
21256            if (newLocaleData != null) {
21257                this._locale = newLocaleData;
21258            }
21259            return this;
21260        }
21261    }
21262
21263    var lang = deprecate(
21264        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
21265        function (key) {
21266            if (key === undefined) {
21267                return this.localeData();
21268            } else {
21269                return this.locale(key);
21270            }
21271        }
21272    );
21273
21274    function localeData() {
21275        return this._locale;
21276    }
21277
21278    var MS_PER_SECOND = 1000,
21279        MS_PER_MINUTE = 60 * MS_PER_SECOND,
21280        MS_PER_HOUR = 60 * MS_PER_MINUTE,
21281        MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
21282
21283    // actual modulo - handles negative numbers (for dates before 1970):
21284    function mod$1(dividend, divisor) {
21285        return ((dividend % divisor) + divisor) % divisor;
21286    }
21287
21288    function localStartOfDate(y, m, d) {
21289        // the date constructor remaps years 0-99 to 1900-1999
21290        if (y < 100 && y >= 0) {
21291            // preserve leap years using a full 400 year cycle, then reset
21292            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
21293        } else {
21294            return new Date(y, m, d).valueOf();
21295        }
21296    }
21297
21298    function utcStartOfDate(y, m, d) {
21299        // Date.UTC remaps years 0-99 to 1900-1999
21300        if (y < 100 && y >= 0) {
21301            // preserve leap years using a full 400 year cycle, then reset
21302            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
21303        } else {
21304            return Date.UTC(y, m, d);
21305        }
21306    }
21307
21308    function startOf(units) {
21309        var time, startOfDate;
21310        units = normalizeUnits(units);
21311        if (units === undefined || units === 'millisecond' || !this.isValid()) {
21312            return this;
21313        }
21314
21315        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
21316
21317        switch (units) {
21318            case 'year':
21319                time = startOfDate(this.year(), 0, 1);
21320                break;
21321            case 'quarter':
21322                time = startOfDate(
21323                    this.year(),
21324                    this.month() - (this.month() % 3),
21325                    1
21326                );
21327                break;
21328            case 'month':
21329                time = startOfDate(this.year(), this.month(), 1);
21330                break;
21331            case 'week':
21332                time = startOfDate(
21333                    this.year(),
21334                    this.month(),
21335                    this.date() - this.weekday()
21336                );
21337                break;
21338            case 'isoWeek':
21339                time = startOfDate(
21340                    this.year(),
21341                    this.month(),
21342                    this.date() - (this.isoWeekday() - 1)
21343                );
21344                break;
21345            case 'day':
21346            case 'date':
21347                time = startOfDate(this.year(), this.month(), this.date());
21348                break;
21349            case 'hour':
21350                time = this._d.valueOf();
21351                time -= mod$1(
21352                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
21353                    MS_PER_HOUR
21354                );
21355                break;
21356            case 'minute':
21357                time = this._d.valueOf();
21358                time -= mod$1(time, MS_PER_MINUTE);
21359                break;
21360            case 'second':
21361                time = this._d.valueOf();
21362                time -= mod$1(time, MS_PER_SECOND);
21363                break;
21364        }
21365
21366        this._d.setTime(time);
21367        hooks.updateOffset(this, true);
21368        return this;
21369    }
21370
21371    function endOf(units) {
21372        var time, startOfDate;
21373        units = normalizeUnits(units);
21374        if (units === undefined || units === 'millisecond' || !this.isValid()) {
21375            return this;
21376        }
21377
21378        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
21379
21380        switch (units) {
21381            case 'year':
21382                time = startOfDate(this.year() + 1, 0, 1) - 1;
21383                break;
21384            case 'quarter':
21385                time =
21386                    startOfDate(
21387                        this.year(),
21388                        this.month() - (this.month() % 3) + 3,
21389                        1
21390                    ) - 1;
21391                break;
21392            case 'month':
21393                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
21394                break;
21395            case 'week':
21396                time =
21397                    startOfDate(
21398                        this.year(),
21399                        this.month(),
21400                        this.date() - this.weekday() + 7
21401                    ) - 1;
21402                break;
21403            case 'isoWeek':
21404                time =
21405                    startOfDate(
21406                        this.year(),
21407                        this.month(),
21408                        this.date() - (this.isoWeekday() - 1) + 7
21409                    ) - 1;
21410                break;
21411            case 'day':
21412            case 'date':
21413                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
21414                break;
21415            case 'hour':
21416                time = this._d.valueOf();
21417                time +=
21418                    MS_PER_HOUR -
21419                    mod$1(
21420                        time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
21421                        MS_PER_HOUR
21422                    ) -
21423                    1;
21424                break;
21425            case 'minute':
21426                time = this._d.valueOf();
21427                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
21428                break;
21429            case 'second':
21430                time = this._d.valueOf();
21431                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
21432                break;
21433        }
21434
21435        this._d.setTime(time);
21436        hooks.updateOffset(this, true);
21437        return this;
21438    }
21439
21440    function valueOf() {
21441        return this._d.valueOf() - (this._offset || 0) * 60000;
21442    }
21443
21444    function unix() {
21445        return Math.floor(this.valueOf() / 1000);
21446    }
21447
21448    function toDate() {
21449        return new Date(this.valueOf());
21450    }
21451
21452    function toArray() {
21453        var m = this;
21454        return [
21455            m.year(),
21456            m.month(),
21457            m.date(),
21458            m.hour(),
21459            m.minute(),
21460            m.second(),
21461            m.millisecond(),
21462        ];
21463    }
21464
21465    function toObject() {
21466        var m = this;
21467        return {
21468            years: m.year(),
21469            months: m.month(),
21470            date: m.date(),
21471            hours: m.hours(),
21472            minutes: m.minutes(),
21473            seconds: m.seconds(),
21474            milliseconds: m.milliseconds(),
21475        };
21476    }
21477
21478    function toJSON() {
21479        // new Date(NaN).toJSON() === null
21480        return this.isValid() ? this.toISOString() : null;
21481    }
21482
21483    function isValid$2() {
21484        return isValid(this);
21485    }
21486
21487    function parsingFlags() {
21488        return extend({}, getParsingFlags(this));
21489    }
21490
21491    function invalidAt() {
21492        return getParsingFlags(this).overflow;
21493    }
21494
21495    function creationData() {
21496        return {
21497            input: this._i,
21498            format: this._f,
21499            locale: this._locale,
21500            isUTC: this._isUTC,
21501            strict: this._strict,
21502        };
21503    }
21504
21505    addFormatToken('N', 0, 0, 'eraAbbr');
21506    addFormatToken('NN', 0, 0, 'eraAbbr');
21507    addFormatToken('NNN', 0, 0, 'eraAbbr');
21508    addFormatToken('NNNN', 0, 0, 'eraName');
21509    addFormatToken('NNNNN', 0, 0, 'eraNarrow');
21510
21511    addFormatToken('y', ['y', 1], 'yo', 'eraYear');
21512    addFormatToken('y', ['yy', 2], 0, 'eraYear');
21513    addFormatToken('y', ['yyy', 3], 0, 'eraYear');
21514    addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
21515
21516    addRegexToken('N', matchEraAbbr);
21517    addRegexToken('NN', matchEraAbbr);
21518    addRegexToken('NNN', matchEraAbbr);
21519    addRegexToken('NNNN', matchEraName);
21520    addRegexToken('NNNNN', matchEraNarrow);
21521
21522    addParseToken(
vendor: 8,145 bytes, lines 21522-21797
21522
21523        ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
21524        function (input, array, config, token) {
21525            var era = config._locale.erasParse(input, token, config._strict);
21526            if (era) {
21527                getParsingFlags(config).era = era;
21528            } else {
21529                getParsingFlags(config).invalidEra = input;
21530            }
21531        }
21532    );
21533
21534    addRegexToken('y', matchUnsigned);
21535    addRegexToken('yy', matchUnsigned);
21536    addRegexToken('yyy', matchUnsigned);
21537    addRegexToken('yyyy', matchUnsigned);
21538    addRegexToken('yo', matchEraYearOrdinal);
21539
21540    addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
21541    addParseToken(['yo'], function (input, array, config, token) {
21542        var match;
21543        if (config._locale._eraYearOrdinalRegex) {
21544            match = input.match(config._locale._eraYearOrdinalRegex);
21545        }
21546
21547        if (config._locale.eraYearOrdinalParse) {
21548            array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
21549        } else {
21550            array[YEAR] = parseInt(input, 10);
21551        }
21552    });
21553
21554    function localeEras(m, format) {
21555        var i,
21556            l,
21557            date,
21558            eras = this._eras || getLocale('en')._eras;
21559        for (i = 0, l = eras.length; i < l; ++i) {
21560            switch (typeof eras[i].since) {
21561                case 'string':
21562                    // truncate time
21563                    date = hooks(eras[i].since).startOf('day');
21564                    eras[i].since = date.valueOf();
21565                    break;
21566            }
21567
21568            switch (typeof eras[i].until) {
21569                case 'undefined':
21570                    eras[i].until = +Infinity;
21571                    break;
21572                case 'string':
21573                    // truncate time
21574                    date = hooks(eras[i].until).startOf('day').valueOf();
21575                    eras[i].until = date.valueOf();
21576                    break;
21577            }
21578        }
21579        return eras;
21580    }
21581
21582    function localeErasParse(eraName, format, strict) {
21583        var i,
21584            l,
21585            eras = this.eras(),
21586            name,
21587            abbr,
21588            narrow;
21589        eraName = eraName.toUpperCase();
21590
21591        for (i = 0, l = eras.length; i < l; ++i) {
21592            name = eras[i].name.toUpperCase();
21593            abbr = eras[i].abbr.toUpperCase();
21594            narrow = eras[i].narrow.toUpperCase();
21595
21596            if (strict) {
21597                switch (format) {
21598                    case 'N':
21599                    case 'NN':
21600                    case 'NNN':
21601                        if (abbr === eraName) {
21602                            return eras[i];
21603                        }
21604                        break;
21605
21606                    case 'NNNN':
21607                        if (name === eraName) {
21608                            return eras[i];
21609                        }
21610                        break;
21611
21612                    case 'NNNNN':
21613                        if (narrow === eraName) {
21614                            return eras[i];
21615                        }
21616                        break;
21617                }
21618            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
21619                return eras[i];
21620            }
21621        }
21622    }
21623
21624    function localeErasConvertYear(era, year) {
21625        var dir = era.since <= era.until ? +1 : -1;
21626        if (year === undefined) {
21627            return hooks(era.since).year();
21628        } else {
21629            return hooks(era.since).year() + (year - era.offset) * dir;
21630        }
21631    }
21632
21633    function getEraName() {
21634        var i,
21635            l,
21636            val,
21637            eras = this.localeData().eras();
21638        for (i = 0, l = eras.length; i < l; ++i) {
21639            // truncate time
21640            val = this.clone().startOf('day').valueOf();
21641
21642            if (eras[i].since <= val && val <= eras[i].until) {
21643                return eras[i].name;
21644            }
21645            if (eras[i].until <= val && val <= eras[i].since) {
21646                return eras[i].name;
21647            }
21648        }
21649
21650        return '';
21651    }
21652
21653    function getEraNarrow() {
21654        var i,
21655            l,
21656            val,
21657            eras = this.localeData().eras();
21658        for (i = 0, l = eras.length; i < l; ++i) {
21659            // truncate time
21660            val = this.clone().startOf('day').valueOf();
21661
21662            if (eras[i].since <= val && val <= eras[i].until) {
21663                return eras[i].narrow;
21664            }
21665            if (eras[i].until <= val && val <= eras[i].since) {
21666                return eras[i].narrow;
21667            }
21668        }
21669
21670        return '';
21671    }
21672
21673    function getEraAbbr() {
21674        var i,
21675            l,
21676            val,
21677            eras = this.localeData().eras();
21678        for (i = 0, l = eras.length; i < l; ++i) {
21679            // truncate time
21680            val = this.clone().startOf('day').valueOf();
21681
21682            if (eras[i].since <= val && val <= eras[i].until) {
21683                return eras[i].abbr;
21684            }
21685            if (eras[i].until <= val && val <= eras[i].since) {
21686                return eras[i].abbr;
21687            }
21688        }
21689
21690        return '';
21691    }
21692
21693    function getEraYear() {
21694        var i,
21695            l,
21696            dir,
21697            val,
21698            eras = this.localeData().eras();
21699        for (i = 0, l = eras.length; i < l; ++i) {
21700            dir = eras[i].since <= eras[i].until ? +1 : -1;
21701
21702            // truncate time
21703            val = this.clone().startOf('day').valueOf();
21704
21705            if (
21706                (eras[i].since <= val && val <= eras[i].until) ||
21707                (eras[i].until <= val && val <= eras[i].since)
21708            ) {
21709                return (
21710                    (this.year() - hooks(eras[i].since).year()) * dir +
21711                    eras[i].offset
21712                );
21713            }
21714        }
21715
21716        return this.year();
21717    }
21718
21719    function erasNameRegex(isStrict) {
21720        if (!hasOwnProp(this, '_erasNameRegex')) {
21721            computeErasParse.call(this);
21722        }
21723        return isStrict ? this._erasNameRegex : this._erasRegex;
21724    }
21725
21726    function erasAbbrRegex(isStrict) {
21727        if (!hasOwnProp(this, '_erasAbbrRegex')) {
21728            computeErasParse.call(this);
21729        }
21730        return isStrict ? this._erasAbbrRegex : this._erasRegex;
21731    }
21732
21733    function erasNarrowRegex(isStrict) {
21734        if (!hasOwnProp(this, '_erasNarrowRegex')) {
21735            computeErasParse.call(this);
21736        }
21737        return isStrict ? this._erasNarrowRegex : this._erasRegex;
21738    }
21739
21740    function matchEraAbbr(isStrict, locale) {
21741        return locale.erasAbbrRegex(isStrict);
21742    }
21743
21744    function matchEraName(isStrict, locale) {
21745        return locale.erasNameRegex(isStrict);
21746    }
21747
21748    function matchEraNarrow(isStrict, locale) {
21749        return locale.erasNarrowRegex(isStrict);
21750    }
21751
21752    function matchEraYearOrdinal(isStrict, locale) {
21753        return locale._eraYearOrdinalRegex || matchUnsigned;
21754    }
21755
21756    function computeErasParse() {
21757        var abbrPieces = [],
21758            namePieces = [],
21759            narrowPieces = [],
21760            mixedPieces = [],
21761            i,
21762            l,
21763            eras = this.eras();
21764
21765        for (i = 0, l = eras.length; i < l; ++i) {
21766            namePieces.push(regexEscape(eras[i].name));
21767            abbrPieces.push(regexEscape(eras[i].abbr));
21768            narrowPieces.push(regexEscape(eras[i].narrow));
21769
21770            mixedPieces.push(regexEscape(eras[i].name));
21771            mixedPieces.push(regexEscape(eras[i].abbr));
21772            mixedPieces.push(regexEscape(eras[i].narrow));
21773        }
21774
21775        this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
21776        this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
21777        this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
21778        this._erasNarrowRegex = new RegExp(
21779            '^(' + narrowPieces.join('|') + ')',
21780            'i'
21781        );
21782    }
21783
21784    // FORMATTING
21785
21786    addFormatToken(0, ['gg', 2], 0, function () {
21787        return this.weekYear() % 100;
21788    });
21789
21790    addFormatToken(0, ['GG', 2], 0, function () {
21791        return this.isoWeekYear() % 100;
21792    });
21793
21794    function addWeekYearFormatToken(token, getter) {
21795        addFormatToken(0, [token, token.length], 0, getter);
21796    }
21797
21798    addWeekYearFormatToken('gggg', 'weekYear');
21799    addWeekYearFormatToken('ggggg', 'weekYear');
21800    addWeekYearFormatToken('GGGG', 'isoWeekYear');
21801    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
21802
21803    // ALIASES
21804
21805    addUnitAlias('weekYear', 'gg');
21806    addUnitAlias('isoWeekYear', 'GG');
21807
21808    // PRIORITY
21809
21810    addUnitPriority('weekYear', 1);
21811    addUnitPriority('isoWeekYear', 1);
21812
21813    // PARSING
21814
21815    addRegexToken('G', matchSigned);
21816    addRegexToken('g', matchSigned);
21817    addRegexToken('GG', match1to2, match2);
21818    addRegexToken('gg', match1to2, match2);
21819    addRegexToken('GGGG', match1to4, match4);
21820    addRegexToken('gggg', match1to4, match4);
21821    addRegexToken('GGGGG', match1to6, match6);
21822    addRegexToken('ggggg', match1to6, match6);
21823
21824    addWeekParseToken(
21825        ['gggg', 'ggggg', 'GGGG', 'GGGGG'],
21826        function (input, week, config, token) {
21827            week[token.substr(0, 2)] = toInt(input);
21828        }
21829    
vendor: 29,543 bytes, lines 21829-22852
21829);
21830
21831    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
21832        week[token] = hooks.parseTwoDigitYear(input);
21833    });
21834
21835    // MOMENTS
21836
21837    function getSetWeekYear(input) {
21838        return getSetWeekYearHelper.call(
21839            this,
21840            input,
21841            this.week(),
21842            this.weekday(),
21843            this.localeData()._week.dow,
21844            this.localeData()._week.doy
21845        );
21846    }
21847
21848    function getSetISOWeekYear(input) {
21849        return getSetWeekYearHelper.call(
21850            this,
21851            input,
21852            this.isoWeek(),
21853            this.isoWeekday(),
21854            1,
21855            4
21856        );
21857    }
21858
21859    function getISOWeeksInYear() {
21860        return weeksInYear(this.year(), 1, 4);
21861    }
21862
21863    function getISOWeeksInISOWeekYear() {
21864        return weeksInYear(this.isoWeekYear(), 1, 4);
21865    }
21866
21867    function getWeeksInYear() {
21868        var weekInfo = this.localeData()._week;
21869        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
21870    }
21871
21872    function getWeeksInWeekYear() {
21873        var weekInfo = this.localeData()._week;
21874        return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
21875    }
21876
21877    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
21878        var weeksTarget;
21879        if (input == null) {
21880            return weekOfYear(this, dow, doy).year;
21881        } else {
21882            weeksTarget = weeksInYear(input, dow, doy);
21883            if (week > weeksTarget) {
21884                week = weeksTarget;
21885            }
21886            return setWeekAll.call(this, input, week, weekday, dow, doy);
21887        }
21888    }
21889
21890    function setWeekAll(weekYear, week, weekday, dow, doy) {
21891        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
21892            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
21893
21894        this.year(date.getUTCFullYear());
21895        this.month(date.getUTCMonth());
21896        this.date(date.getUTCDate());
21897        return this;
21898    }
21899
21900    // FORMATTING
21901
21902    addFormatToken('Q', 0, 'Qo', 'quarter');
21903
21904    // ALIASES
21905
21906    addUnitAlias('quarter', 'Q');
21907
21908    // PRIORITY
21909
21910    addUnitPriority('quarter', 7);
21911
21912    // PARSING
21913
21914    addRegexToken('Q', match1);
21915    addParseToken('Q', function (input, array) {
21916        array[MONTH] = (toInt(input) - 1) * 3;
21917    });
21918
21919    // MOMENTS
21920
21921    function getSetQuarter(input) {
21922        return input == null
21923            ? Math.ceil((this.month() + 1) / 3)
21924            : this.month((input - 1) * 3 + (this.month() % 3));
21925    }
21926
21927    // FORMATTING
21928
21929    addFormatToken('D', ['DD', 2], 'Do', 'date');
21930
21931    // ALIASES
21932
21933    addUnitAlias('date', 'D');
21934
21935    // PRIORITY
21936    addUnitPriority('date', 9);
21937
21938    // PARSING
21939
21940    addRegexToken('D', match1to2);
21941    addRegexToken('DD', match1to2, match2);
21942    addRegexToken('Do', function (isStrict, locale) {
21943        // TODO: Remove "ordinalParse" fallback in next major release.
21944        return isStrict
21945            ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
21946            : locale._dayOfMonthOrdinalParseLenient;
21947    });
21948
21949    addParseToken(['D', 'DD'], DATE);
21950    addParseToken('Do', function (input, array) {
21951        array[DATE] = toInt(input.match(match1to2)[0]);
21952    });
21953
21954    // MOMENTS
21955
21956    var getSetDayOfMonth = makeGetSet('Date', true);
21957
21958    // FORMATTING
21959
21960    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
21961
21962    // ALIASES
21963
21964    addUnitAlias('dayOfYear', 'DDD');
21965
21966    // PRIORITY
21967    addUnitPriority('dayOfYear', 4);
21968
21969    // PARSING
21970
21971    addRegexToken('DDD', match1to3);
21972    addRegexToken('DDDD', match3);
21973    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
21974        config._dayOfYear = toInt(input);
21975    });
21976
21977    // HELPERS
21978
21979    // MOMENTS
21980
21981    function getSetDayOfYear(input) {
21982        var dayOfYear =
21983            Math.round(
21984                (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
21985            ) + 1;
21986        return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
21987    }
21988
21989    // FORMATTING
21990
21991    addFormatToken('m', ['mm', 2], 0, 'minute');
21992
21993    // ALIASES
21994
21995    addUnitAlias('minute', 'm');
21996
21997    // PRIORITY
21998
21999    addUnitPriority('minute', 14);
22000
22001    // PARSING
22002
22003    addRegexToken('m', match1to2);
22004    addRegexToken('mm', match1to2, match2);
22005    addParseToken(['m', 'mm'], MINUTE);
22006
22007    // MOMENTS
22008
22009    var getSetMinute = makeGetSet('Minutes', false);
22010
22011    // FORMATTING
22012
22013    addFormatToken('s', ['ss', 2], 0, 'second');
22014
22015    // ALIASES
22016
22017    addUnitAlias('second', 's');
22018
22019    // PRIORITY
22020
22021    addUnitPriority('second', 15);
22022
22023    // PARSING
22024
22025    addRegexToken('s', match1to2);
22026    addRegexToken('ss', match1to2, match2);
22027    addParseToken(['s', 'ss'], SECOND);
22028
22029    // MOMENTS
22030
22031    var getSetSecond = makeGetSet('Seconds', false);
22032
22033    // FORMATTING
22034
22035    addFormatToken('S', 0, 0, function () {
22036        return ~~(this.millisecond() / 100);
22037    });
22038
22039    addFormatToken(0, ['SS', 2], 0, function () {
22040        return ~~(this.millisecond() / 10);
22041    });
22042
22043    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
22044    addFormatToken(0, ['SSSS', 4], 0, function () {
22045        return this.millisecond() * 10;
22046    });
22047    addFormatToken(0, ['SSSSS', 5], 0, function () {
22048        return this.millisecond() * 100;
22049    });
22050    addFormatToken(0, ['SSSSSS', 6], 0, function () {
22051        return this.millisecond() * 1000;
22052    });
22053    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
22054        return this.millisecond() * 10000;
22055    });
22056    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
22057        return this.millisecond() * 100000;
22058    });
22059    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
22060        return this.millisecond() * 1000000;
22061    });
22062
22063    // ALIASES
22064
22065    addUnitAlias('millisecond', 'ms');
22066
22067    // PRIORITY
22068
22069    addUnitPriority('millisecond', 16);
22070
22071    // PARSING
22072
22073    addRegexToken('S', match1to3, match1);
22074    addRegexToken('SS', match1to3, match2);
22075    addRegexToken('SSS', match1to3, match3);
22076
22077    var token, getSetMillisecond;
22078    for (token = 'SSSS'; token.length <= 9; token += 'S') {
22079        addRegexToken(token, matchUnsigned);
22080    }
22081
22082    function parseMs(input, array) {
22083        array[MILLISECOND] = toInt(('0.' + input) * 1000);
22084    }
22085
22086    for (token = 'S'; token.length <= 9; token += 'S') {
22087        addParseToken(token, parseMs);
22088    }
22089
22090    getSetMillisecond = makeGetSet('Milliseconds', false);
22091
22092    // FORMATTING
22093
22094    addFormatToken('z', 0, 0, 'zoneAbbr');
22095    addFormatToken('zz', 0, 0, 'zoneName');
22096
22097    // MOMENTS
22098
22099    function getZoneAbbr() {
22100        return this._isUTC ? 'UTC' : '';
22101    }
22102
22103    function getZoneName() {
22104        return this._isUTC ? 'Coordinated Universal Time' : '';
22105    }
22106
22107    var proto = Moment.prototype;
22108
22109    proto.add = add;
22110    proto.calendar = calendar$1;
22111    proto.clone = clone;
22112    proto.diff = diff;
22113    proto.endOf = endOf;
22114    proto.format = format;
22115    proto.from = from;
22116    proto.fromNow = fromNow;
22117    proto.to = to;
22118    proto.toNow = toNow;
22119    proto.get = stringGet;
22120    proto.invalidAt = invalidAt;
22121    proto.isAfter = isAfter;
22122    proto.isBefore = isBefore;
22123    proto.isBetween = isBetween;
22124    proto.isSame = isSame;
22125    proto.isSameOrAfter = isSameOrAfter;
22126    proto.isSameOrBefore = isSameOrBefore;
22127    proto.isValid = isValid$2;
22128    proto.lang = lang;
22129    proto.locale = locale;
22130    proto.localeData = localeData;
22131    proto.max = prototypeMax;
22132    proto.min = prototypeMin;
22133    proto.parsingFlags = parsingFlags;
22134    proto.set = stringSet;
22135    proto.startOf = startOf;
22136    proto.subtract = subtract;
22137    proto.toArray = toArray;
22138    proto.toObject = toObject;
22139    proto.toDate = toDate;
22140    proto.toISOString = toISOString;
22141    proto.inspect = inspect;
22142    if (typeof Symbol !== 'undefined' && Symbol.for != null) {
22143        proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
22144            return 'Moment<' + this.format() + '>';
22145        };
22146    }
22147    proto.toJSON = toJSON;
22148    proto.toString = toString;
22149    proto.unix = unix;
22150    proto.valueOf = valueOf;
22151    proto.creationData = creationData;
22152    proto.eraName = getEraName;
22153    proto.eraNarrow = getEraNarrow;
22154    proto.eraAbbr = getEraAbbr;
22155    proto.eraYear = getEraYear;
22156    proto.year = getSetYear;
22157    proto.isLeapYear = getIsLeapYear;
22158    proto.weekYear = getSetWeekYear;
22159    proto.isoWeekYear = getSetISOWeekYear;
22160    proto.quarter = proto.quarters = getSetQuarter;
22161    proto.month = getSetMonth;
22162    proto.daysInMonth = getDaysInMonth;
22163    proto.week = proto.weeks = getSetWeek;
22164    proto.isoWeek = proto.isoWeeks = getSetISOWeek;
22165    proto.weeksInYear = getWeeksInYear;
22166    proto.weeksInWeekYear = getWeeksInWeekYear;
22167    proto.isoWeeksInYear = getISOWeeksInYear;
22168    proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
22169    proto.date = getSetDayOfMonth;
22170    proto.day = proto.days = getSetDayOfWeek;
22171    proto.weekday = getSetLocaleDayOfWeek;
22172    proto.isoWeekday = getSetISODayOfWeek;
22173    proto.dayOfYear = getSetDayOfYear;
22174    proto.hour = proto.hours = getSetHour;
22175    proto.minute = proto.minutes = getSetMinute;
22176    proto.second = proto.seconds = getSetSecond;
22177    proto.millisecond = proto.milliseconds = getSetMillisecond;
22178    proto.utcOffset = getSetOffset;
22179    proto.utc = setOffsetToUTC;
22180    proto.local = setOffsetToLocal;
22181    proto.parseZone = setOffsetToParsedOffset;
22182    proto.hasAlignedHourOffset = hasAlignedHourOffset;
22183    proto.isDST = isDaylightSavingTime;
22184    proto.isLocal = isLocal;
22185    proto.isUtcOffset = isUtcOffset;
22186    proto.isUtc = isUtc;
22187    proto.isUTC = isUtc;
22188    proto.zoneAbbr = getZoneAbbr;
22189    proto.zoneName = getZoneName;
22190    proto.dates = deprecate(
22191        'dates accessor is deprecated. Use date instead.',
22192        getSetDayOfMonth
22193    );
22194    proto.months = deprecate(
22195        'months accessor is deprecated. Use month instead',
22196        getSetMonth
22197    );
22198    proto.years = deprecate(
22199        'years accessor is deprecated. Use year instead',
22200        getSetYear
22201    );
22202    proto.zone = deprecate(
22203        'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
22204        getSetZone
22205    );
22206    proto.isDSTShifted = deprecate(
22207        'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
22208        isDaylightSavingTimeShifted
22209    );
22210
22211    function createUnix(input) {
22212        return createLocal(input * 1000);
22213    }
22214
22215    function createInZone() {
22216        return createLocal.apply(null, arguments).parseZone();
22217    }
22218
22219    function preParsePostFormat(string) {
22220        return string;
22221    }
22222
22223    var proto$1 = Locale.prototype;
22224
22225    proto$1.calendar = calendar;
22226    proto$1.longDateFormat = longDateFormat;
22227    proto$1.invalidDate = invalidDate;
22228    proto$1.ordinal = ordinal;
22229    proto$1.preparse = preParsePostFormat;
22230    proto$1.postformat = preParsePostFormat;
22231    proto$1.relativeTime = relativeTime;
22232    proto$1.pastFuture = pastFuture;
22233    proto$1.set = set;
22234    proto$1.eras = localeEras;
22235    proto$1.erasParse = localeErasParse;
22236    proto$1.erasConvertYear = localeErasConvertYear;
22237    proto$1.erasAbbrRegex = erasAbbrRegex;
22238    proto$1.erasNameRegex = erasNameRegex;
22239    proto$1.erasNarrowRegex = erasNarrowRegex;
22240
22241    proto$1.months = localeMonths;
22242    proto$1.monthsShort = localeMonthsShort;
22243    proto$1.monthsParse = localeMonthsParse;
22244    proto$1.monthsRegex = monthsRegex;
22245    proto$1.monthsShortRegex = monthsShortRegex;
22246    proto$1.week = localeWeek;
22247    proto$1.firstDayOfYear = localeFirstDayOfYear;
22248    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
22249
22250    proto$1.weekdays = localeWeekdays;
22251    proto$1.weekdaysMin = localeWeekdaysMin;
22252    proto$1.weekdaysShort = localeWeekdaysShort;
22253    proto$1.weekdaysParse = localeWeekdaysParse;
22254
22255    proto$1.weekdaysRegex = weekdaysRegex;
22256    proto$1.weekdaysShortRegex = weekdaysShortRegex;
22257    proto$1.weekdaysMinRegex = weekdaysMinRegex;
22258
22259    proto$1.isPM = localeIsPM;
22260    proto$1.meridiem = localeMeridiem;
22261
22262    function get$1(format, index, field, setter) {
22263        var locale = getLocale(),
22264            utc = createUTC().set(setter, index);
22265        return locale[field](utc, format);
22266    }
22267
22268    function listMonthsImpl(format, index, field) {
22269        if (isNumber(format)) {
22270            index = format;
22271            format = undefined;
22272        }
22273
22274        format = format || '';
22275
22276        if (index != null) {
22277            return get$1(format, index, field, 'month');
22278        }
22279
22280        var i,
22281            out = [];
22282        for (i = 0; i < 12; i++) {
22283            out[i] = get$1(format, i, field, 'month');
22284        }
22285        return out;
22286    }
22287
22288    // ()
22289    // (5)
22290    // (fmt, 5)
22291    // (fmt)
22292    // (true)
22293    // (true, 5)
22294    // (true, fmt, 5)
22295    // (true, fmt)
22296    function listWeekdaysImpl(localeSorted, format, index, field) {
22297        if (typeof localeSorted === 'boolean') {
22298            if (isNumber(format)) {
22299                index = format;
22300                format = undefined;
22301            }
22302
22303            format = format || '';
22304        } else {
22305            format = localeSorted;
22306            index = format;
22307            localeSorted = false;
22308
22309            if (isNumber(format)) {
22310                index = format;
22311                format = undefined;
22312            }
22313
22314            format = format || '';
22315        }
22316
22317        var locale = getLocale(),
22318            shift = localeSorted ? locale._week.dow : 0,
22319            i,
22320            out = [];
22321
22322        if (index != null) {
22323            return get$1(format, (index + shift) % 7, field, 'day');
22324        }
22325
22326        for (i = 0; i < 7; i++) {
22327            out[i] = get$1(format, (i + shift) % 7, field, 'day');
22328        }
22329        return out;
22330    }
22331
22332    function listMonths(format, index) {
22333        return listMonthsImpl(format, index, 'months');
22334    }
22335
22336    function listMonthsShort(format, index) {
22337        return listMonthsImpl(format, index, 'monthsShort');
22338    }
22339
22340    function listWeekdays(localeSorted, format, index) {
22341        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
22342    }
22343
22344    function listWeekdaysShort(localeSorted, format, index) {
22345        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
22346    }
22347
22348    function listWeekdaysMin(localeSorted, format, index) {
22349        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
22350    }
22351
22352    getSetGlobalLocale('en', {
22353        eras: [
22354            {
22355                since: '0001-01-01',
22356                until: +Infinity,
22357                offset: 1,
22358                name: 'Anno Domini',
22359                narrow: 'AD',
22360                abbr: 'AD',
22361            },
22362            {
22363                since: '0000-12-31',
22364                until: -Infinity,
22365                offset: 1,
22366                name: 'Before Christ',
22367                narrow: 'BC',
22368                abbr: 'BC',
22369            },
22370        ],
22371        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
22372        ordinal: function (number) {
22373            var b = number % 10,
22374                output =
22375                    toInt((number % 100) / 10) === 1
22376                        ? 'th'
22377                        : b === 1
22378                        ? 'st'
22379                        : b === 2
22380                        ? 'nd'
22381                        : b === 3
22382                        ? 'rd'
22383                        : 'th';
22384            return number + output;
22385        },
22386    });
22387
22388    // Side effect imports
22389
22390    hooks.lang = deprecate(
22391        'moment.lang is deprecated. Use moment.locale instead.',
22392        getSetGlobalLocale
22393    );
22394    hooks.langData = deprecate(
22395        'moment.langData is deprecated. Use moment.localeData instead.',
22396        getLocale
22397    );
22398
22399    var mathAbs = Math.abs;
22400
22401    function abs() {
22402        var data = this._data;
22403
22404        this._milliseconds = mathAbs(this._milliseconds);
22405        this._days = mathAbs(this._days);
22406        this._months = mathAbs(this._months);
22407
22408        data.milliseconds = mathAbs(data.milliseconds);
22409        data.seconds = mathAbs(data.seconds);
22410        data.minutes = mathAbs(data.minutes);
22411        data.hours = mathAbs(data.hours);
22412        data.months = mathAbs(data.months);
22413        data.years = mathAbs(data.years);
22414
22415        return this;
22416    }
22417
22418    function addSubtract$1(duration, input, value, direction) {
22419        var other = createDuration(input, value);
22420
22421        duration._milliseconds += direction * other._milliseconds;
22422        duration._days += direction * other._days;
22423        duration._months += direction * other._months;
22424
22425        return duration._bubble();
22426    }
22427
22428    // supports only 2.0-style add(1, 's') or add(duration)
22429    function add$1(input, value) {
22430        return addSubtract$1(this, input, value, 1);
22431    }
22432
22433    // supports only 2.0-style subtract(1, 's') or subtract(duration)
22434    function subtract$1(input, value) {
22435        return addSubtract$1(this, input, value, -1);
22436    }
22437
22438    function absCeil(number) {
22439        if (number < 0) {
22440            return Math.floor(number);
22441        } else {
22442            return Math.ceil(number);
22443        }
22444    }
22445
22446    function bubble() {
22447        var milliseconds = this._milliseconds,
22448            days = this._days,
22449            months = this._months,
22450            data = this._data,
22451            seconds,
22452            minutes,
22453            hours,
22454            years,
22455            monthsFromDays;
22456
22457        // if we have a mix of positive and negative values, bubble down first
22458        // check: https://github.com/moment/moment/issues/2166
22459        if (
22460            !(
22461                (milliseconds >= 0 && days >= 0 && months >= 0) ||
22462                (milliseconds <= 0 && days <= 0 && months <= 0)
22463            )
22464        ) {
22465            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
22466            days = 0;
22467            months = 0;
22468        }
22469
22470        // The following code bubbles up values, see the tests for
22471        // examples of what that means.
22472        data.milliseconds = milliseconds % 1000;
22473
22474        seconds = absFloor(milliseconds / 1000);
22475        data.seconds = seconds % 60;
22476
22477        minutes = absFloor(seconds / 60);
22478        data.minutes = minutes % 60;
22479
22480        hours = absFloor(minutes / 60);
22481        data.hours = hours % 24;
22482
22483        days += absFloor(hours / 24);
22484
22485        // convert days to months
22486        monthsFromDays = absFloor(daysToMonths(days));
22487        months += monthsFromDays;
22488        days -= absCeil(monthsToDays(monthsFromDays));
22489
22490        // 12 months -> 1 year
22491        years = absFloor(months / 12);
22492        months %= 12;
22493
22494        data.days = days;
22495        data.months = months;
22496        data.years = years;
22497
22498        return this;
22499    }
22500
22501    function daysToMonths(days) {
22502        // 400 years have 146097 days (taking into account leap year rules)
22503        // 400 years have 12 months === 4800
22504        return (days * 4800) / 146097;
22505    }
22506
22507    function monthsToDays(months) {
22508        // the reverse of daysToMonths
22509        return (months * 146097) / 4800;
22510    }
22511
22512    function as(units) {
22513        if (!this.isValid()) {
22514            return NaN;
22515        }
22516        var days,
22517            months,
22518            milliseconds = this._milliseconds;
22519
22520        units = normalizeUnits(units);
22521
22522        if (units === 'month' || units === 'quarter' || units === 'year') {
22523            days = this._days + milliseconds / 864e5;
22524            months = this._months + daysToMonths(days);
22525            switch (units) {
22526                case 'month':
22527                    return months;
22528                case 'quarter':
22529                    return months / 3;
22530                case 'year':
22531                    return months / 12;
22532            }
22533        } else {
22534            // handle milliseconds separately because of floating point math errors (issue #1867)
22535            days = this._days + Math.round(monthsToDays(this._months));
22536            switch (units) {
22537                case 'week':
22538                    return days / 7 + milliseconds / 6048e5;
22539                case 'day':
22540                    return days + milliseconds / 864e5;
22541                case 'hour':
22542                    return days * 24 + milliseconds / 36e5;
22543                case 'minute':
22544                    return days * 1440 + milliseconds / 6e4;
22545                case 'second':
22546                    return days * 86400 + milliseconds / 1000;
22547                // Math.floor prevents floating point math errors here
22548                case 'millisecond':
22549                    return Math.floor(days * 864e5) + milliseconds;
22550                default:
22551                    throw new Error('Unknown unit ' + units);
22552            }
22553        }
22554    }
22555
22556    // TODO: Use this.as('ms')?
22557    function valueOf$1() {
22558        if (!this.isValid()) {
22559            return NaN;
22560        }
22561        return (
22562            this._milliseconds +
22563            this._days * 864e5 +
22564            (this._months % 12) * 2592e6 +
22565            toInt(this._months / 12) * 31536e6
22566        );
22567    }
22568
22569    function makeAs(alias) {
22570        return function () {
22571            return this.as(alias);
22572        };
22573    }
22574
22575    var asMilliseconds = makeAs('ms'),
22576        asSeconds = makeAs('s'),
22577        asMinutes = makeAs('m'),
22578        asHours = makeAs('h'),
22579        asDays = makeAs('d'),
22580        asWeeks = makeAs('w'),
22581        asMonths = makeAs('M'),
22582        asQuarters = makeAs('Q'),
22583        asYears = makeAs('y');
22584
22585    function clone$1() {
22586        return createDuration(this);
22587    }
22588
22589    function get$2(units) {
22590        units = normalizeUnits(units);
22591        return this.isValid() ? this[units + 's']() : NaN;
22592    }
22593
22594    function makeGetter(name) {
22595        return function () {
22596            return this.isValid() ? this._data[name] : NaN;
22597        };
22598    }
22599
22600    var milliseconds = makeGetter('milliseconds'),
22601        seconds = makeGetter('seconds'),
22602        minutes = makeGetter('minutes'),
22603        hours = makeGetter('hours'),
22604        days = makeGetter('days'),
22605        months = makeGetter('months'),
22606        years = makeGetter('years');
22607
22608    function weeks() {
22609        return absFloor(this.days() / 7);
22610    }
22611
22612    var round = Math.round,
22613        thresholds = {
22614            ss: 44, // a few seconds to seconds
22615            s: 45, // seconds to minute
22616            m: 45, // minutes to hour
22617            h: 22, // hours to day
22618            d: 26, // days to month/week
22619            w: null, // weeks to month
22620            M: 11, // months to year
22621        };
22622
22623    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
22624    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
22625        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
22626    }
22627
22628    function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
22629        var duration = createDuration(posNegDuration).abs(),
22630            seconds = round(duration.as('s')),
22631            minutes = round(duration.as('m')),
22632            hours = round(duration.as('h')),
22633            days = round(duration.as('d')),
22634            months = round(duration.as('M')),
22635            weeks = round(duration.as('w')),
22636            years = round(duration.as('y')),
22637            a =
22638                (seconds <= thresholds.ss && ['s', seconds]) ||
22639                (seconds < thresholds.s && ['ss', seconds]) ||
22640                (minutes <= 1 && ['m']) ||
22641                (minutes < thresholds.m && ['mm', minutes]) ||
22642                (hours <= 1 && ['h']) ||
22643                (hours < thresholds.h && ['hh', hours]) ||
22644                (days <= 1 && ['d']) ||
22645                (days < thresholds.d && ['dd', days]);
22646
22647        if (thresholds.w != null) {
22648            a =
22649                a ||
22650                (weeks <= 1 && ['w']) ||
22651                (weeks < thresholds.w && ['ww', weeks]);
22652        }
22653        a = a ||
22654            (months <= 1 && ['M']) ||
22655            (months < thresholds.M && ['MM', months]) ||
22656            (years <= 1 && ['y']) || ['yy', years];
22657
22658        a[2] = withoutSuffix;
22659        a[3] = +posNegDuration > 0;
22660        a[4] = locale;
22661        return substituteTimeAgo.apply(null, a);
22662    }
22663
22664    // This function allows you to set the rounding function for relative time strings
22665    function getSetRelativeTimeRounding(roundingFunction) {
22666        if (roundingFunction === undefined) {
22667            return round;
22668        }
22669        if (typeof roundingFunction === 'function') {
22670            round = roundingFunction;
22671            return true;
22672        }
22673        return false;
22674    }
22675
22676    // This function allows you to set a threshold for relative time strings
22677    function getSetRelativeTimeThreshold(threshold, limit) {
22678        if (thresholds[threshold] === undefined) {
22679            return false;
22680        }
22681        if (limit === undefined) {
22682            return thresholds[threshold];
22683        }
22684        thresholds[threshold] = limit;
22685        if (threshold === 's') {
22686            thresholds.ss = limit - 1;
22687        }
22688        return true;
22689    }
22690
22691    function humanize(argWithSuffix, argThresholds) {
22692        if (!this.isValid()) {
22693            return this.localeData().invalidDate();
22694        }
22695
22696        var withSuffix = false,
22697            th = thresholds,
22698            locale,
22699            output;
22700
22701        if (typeof argWithSuffix === 'object') {
22702            argThresholds = argWithSuffix;
22703            argWithSuffix = false;
22704        }
22705        if (typeof argWithSuffix === 'boolean') {
22706            withSuffix = argWithSuffix;
22707        }
22708        if (typeof argThresholds === 'object') {
22709            th = Object.assign({}, thresholds, argThresholds);
22710            if (argThresholds.s != null && argThresholds.ss == null) {
22711                th.ss = argThresholds.s - 1;
22712            }
22713        }
22714
22715        locale = this.localeData();
22716        output = relativeTime$1(this, !withSuffix, th, locale);
22717
22718        if (withSuffix) {
22719            output = locale.pastFuture(+this, output);
22720        }
22721
22722        return locale.postformat(output);
22723    }
22724
22725    var abs$1 = Math.abs;
22726
22727    function sign(x) {
22728        return (x > 0) - (x < 0) || +x;
22729    }
22730
22731    function toISOString$1() {
22732        // for ISO strings we do not use the normal bubbling rules:
22733        //  * milliseconds bubble up until they become hours
22734        //  * days do not bubble at all
22735        //  * months bubble up until they become years
22736        // This is because there is no context-free conversion between hours and days
22737        // (think of clock changes)
22738        // and also not between days and months (28-31 days per month)
22739        if (!this.isValid()) {
22740            return this.localeData().invalidDate();
22741        }
22742
22743        var seconds = abs$1(this._milliseconds) / 1000,
22744            days = abs$1(this._days),
22745            months = abs$1(this._months),
22746            minutes,
22747            hours,
22748            years,
22749            s,
22750            total = this.asSeconds(),
22751            totalSign,
22752            ymSign,
22753            daysSign,
22754            hmsSign;
22755
22756        if (!total) {
22757            // this is the same as C#'s (Noda) and python (isodate)...
22758            // but not other JS (goog.date)
22759            return 'P0D';
22760        }
22761
22762        // 3600 seconds -> 60 minutes -> 1 hour
22763        minutes = absFloor(seconds / 60);
22764        hours = absFloor(minutes / 60);
22765        seconds %= 60;
22766        minutes %= 60;
22767
22768        // 12 months -> 1 year
22769        years = absFloor(months / 12);
22770        months %= 12;
22771
22772        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
22773        s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
22774
22775        totalSign = total < 0 ? '-' : '';
22776        ymSign = sign(this._months) !== sign(total) ? '-' : '';
22777        daysSign = sign(this._days) !== sign(total) ? '-' : '';
22778        hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
22779
22780        return (
22781            totalSign +
22782            'P' +
22783            (years ? ymSign + years + 'Y' : '') +
22784            (months ? ymSign + months + 'M' : '') +
22785            (days ? daysSign + days + 'D' : '') +
22786            (hours || minutes || seconds ? 'T' : '') +
22787            (hours ? hmsSign + hours + 'H' : '') +
22788            (minutes ? hmsSign + minutes + 'M' : '') +
22789            (seconds ? hmsSign + s + 'S' : '')
22790        );
22791    }
22792
22793    var proto$2 = Duration.prototype;
22794
22795    proto$2.isValid = isValid$1;
22796    proto$2.abs = abs;
22797    proto$2.add = add$1;
22798    proto$2.subtract = subtract$1;
22799    proto$2.as = as;
22800    proto$2.asMilliseconds = asMilliseconds;
22801    proto$2.asSeconds = asSeconds;
22802    proto$2.asMinutes = asMinutes;
22803    proto$2.asHours = asHours;
22804    proto$2.asDays = asDays;
22805    proto$2.asWeeks = asWeeks;
22806    proto$2.asMonths = asMonths;
22807    proto$2.asQuarters = asQuarters;
22808    proto$2.asYears = asYears;
22809    proto$2.valueOf = valueOf$1;
22810    proto$2._bubble = bubble;
22811    proto$2.clone = clone$1;
22812    proto$2.get = get$2;
22813    proto$2.milliseconds = milliseconds;
22814    proto$2.seconds = seconds;
22815    proto$2.minutes = minutes;
22816    proto$2.hours = hours;
22817    proto$2.days = days;
22818    proto$2.weeks = weeks;
22819    proto$2.months = months;
22820    proto$2.years = years;
22821    proto$2.humanize = humanize;
22822    proto$2.toISOString = toISOString$1;
22823    proto$2.toString = toISOString$1;
22824    proto$2.toJSON = toISOString$1;
22825    proto$2.locale = locale;
22826    proto$2.localeData = localeData;
22827
22828    proto$2.toIsoString = deprecate(
22829        'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
22830        toISOString$1
22831    );
22832    proto$2.lang = lang;
22833
22834    // FORMATTING
22835
22836    addFormatToken('X', 0, 0, 'unix');
22837    addFormatToken('x', 0, 0, 'valueOf');
22838
22839    // PARSING
22840
22841    addRegexToken('x', matchSigned);
22842    addRegexToken('X', matchTimestamp);
22843    addParseToken('X', function (input, array, config) {
22844        config._d = new Date(parseFloat(input) * 1000);
22845    });
22846    addParseToken('x', function (input, array, config) {
22847        config._d = new Date(toInt(input));
22848    });
22849
22850    //! moment.js
22851
22852    hooks.version = '2.2
228529.4';
22853
22854    setHookCallback(createLocal);
22855
22856    hooks.fn = proto;
22857    hooks.min = min;
22858    hooks.max = max;
22859    hooks.now = now;
22860    hooks.utc = createUTC;
22861    hooks.unix = createUnix;
22862    hooks.months = listMonths;
22863    hooks.isDate = isDate;
22864    hooks.locale = getSetGlobalLocale;
22865    hooks.invalid = createInvalid;
22866    hooks.duration = createDuration;
22867    hooks.isMoment = isMoment;
22868    hooks.weekdays = listWeekdays;
22869    hooks.parseZone = createInZone;
22870    hooks.localeData = getLocale;
22871    hooks.isDuration = isDuration;
22872    hooks.monthsShort = listMonthsShort;
22873    hooks.weekdaysMin = listWeekdaysMin;
22874    hooks.defineLocale = defineLocale;
22875    hooks.updateLocale = updateLocale;
22876    hooks.locales = listLocales;
22877    hooks.weekdaysShort = listWeekdaysShort;
22878    hooks.normalizeUnits = normalizeUnits;
22879    hooks.relativeTimeRounding = getSetRelativeTimeRounding;
22880    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
22881    hooks.calendarFormat = getCalendarFormat;
22882    hooks.prototype = proto;
22883
22884    // currently HTML5 input type only supports 24-hour formats
22885    hooks.HTML5_FMT = {
22886        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
22887        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
22888        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
22889        DATE: 'YYYY-MM-DD', // <input type="date" />
22890        TIME: 'HH:mm', // <input type="time" />
22891        TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
22892        TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
22893        WEEK: 'GGGG-[W]WW', // <input type="week" />
22894        MONTH: 'YYYY-MM', // <input type="month" />
22895    };
22896
22897    return hooks;
22898
22899})));
22900
22901},{}],3:[function(require,module,exports){
vendor: 18,315 bytes, lines 22902-23504
22902/*!
22903 * Salvattore 1.0.9 by @rnmp and @ppold
22904 * https://github.com/rnmp/salvattore
22905 */
22906(function(root, factory) {
22907  if (typeof define === 'function' && define.amd) {
22908    define([], factory);
22909  } else if (typeof exports === 'object') {
22910    module.exports = factory();
22911  } else {
22912    root.salvattore = factory();
22913  }
22914}(this, function() {
22915/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
22916
22917if (!window.matchMedia) {
22918    window.matchMedia = function() {
22919        "use strict";
22920
22921        // For browsers that support matchMedium api such as IE 9 and webkit
22922        var styleMedia = (window.styleMedia || window.media);
22923
22924        // For those that don't support matchMedium
22925        if (!styleMedia) {
22926            var style       = document.createElement('style'),
22927                script      = document.getElementsByTagName('script')[0],
22928                info        = null;
22929
22930            style.type  = 'text/css';
22931            style.id    = 'matchmediajs-test';
22932
22933            script.parentNode.insertBefore(style, script);
22934
22935            // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
22936            info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
22937
22938            styleMedia = {
22939                matchMedium: function(media) {
22940                    var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
22941
22942                    // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
22943                    if (style.styleSheet) {
22944                        style.styleSheet.cssText = text;
22945                    } else {
22946                        style.textContent = text;
22947                    }
22948
22949                    // Test if media query is true or false
22950                    return info.width === '1px';
22951                }
22952            };
22953        }
22954
22955        return function(media) {
22956            return {
22957                matches: styleMedia.matchMedium(media || 'all'),
22958                media: media || 'all'
22959            };
22960        };
22961    }();
22962}
22963
22964/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
22965(function(){
22966    "use strict";
22967
22968    // Bail out for browsers that have addListener support
22969    if (window.matchMedia && window.matchMedia('all').addListener) {
22970        return false;
22971    }
22972
22973    var localMatchMedia = window.matchMedia,
22974        hasMediaQueries = localMatchMedia('only all').matches,
22975        isListening     = false,
22976        timeoutID       = 0,    // setTimeout for debouncing 'handleChange'
22977        queries         = [],   // Contains each 'mql' and associated 'listeners' if 'addListener' is used
22978        handleChange    = function(evt) {
22979            // Debounce
22980            clearTimeout(timeoutID);
22981
22982            timeoutID = setTimeout(function() {
22983                for (var i = 0, il = queries.length; i < il; i++) {
22984                    var mql         = queries[i].mql,
22985                        listeners   = queries[i].listeners || [],
22986                        matches     = localMatchMedia(mql.media).matches;
22987
22988                    // Update mql.matches value and call listeners
22989                    // Fire listeners only if transitioning to or from matched state
22990                    if (matches !== mql.matches) {
22991                        mql.matches = matches;
22992
22993                        for (var j = 0, jl = listeners.length; j < jl; j++) {
22994                            listeners[j].call(window, mql);
22995                        }
22996                    }
22997                }
22998            }, 30);
22999        };
23000
23001    window.matchMedia = function(media) {
23002        var mql         = localMatchMedia(media),
23003            listeners   = [],
23004            index       = 0;
23005
23006        mql.addListener = function(listener) {
23007            // Changes would not occur to css media type so return now (Affects IE <= 8)
23008            if (!hasMediaQueries) {
23009                return;
23010            }
23011
23012            // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8)
23013            // There should only ever be 1 resize listener running for performance
23014            if (!isListening) {
23015                isListening = true;
23016                window.addEventListener('resize', handleChange, true);
23017            }
23018
23019            // Push object only if it has not been pushed already
23020            if (index === 0) {
23021                index = queries.push({
23022                    mql         : mql,
23023                    listeners   : listeners
23024                });
23025            }
23026
23027            listeners.push(listener);
23028        };
23029
23030        mql.removeListener = function(listener) {
23031            for (var i = 0, il = listeners.length; i < il; i++){
23032                if (listeners[i] === listener){
23033                    listeners.splice(i, 1);
23034                }
23035            }
23036        };
23037
23038        return mql;
23039    };
23040}());
23041
23042// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
23043// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
23044
23045// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
23046
23047// MIT license
23048
23049(function() {
23050    "use strict";
23051
23052    var lastTime = 0;
23053    var vendors = ['ms', 'moz', 'webkit', 'o'];
23054    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
23055        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
23056        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] ||
23057            window[vendors[x]+'CancelRequestAnimationFrame'];
23058    }
23059
23060    if (!window.requestAnimationFrame)
23061        window.requestAnimationFrame = function(callback, element) {
23062            var currTime = new Date().getTime();
23063            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
23064            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
23065              timeToCall);
23066            lastTime = currTime + timeToCall;
23067            return id;
23068        };
23069
23070    if (!window.cancelAnimationFrame)
23071        window.cancelAnimationFrame = function(id) {
23072            clearTimeout(id);
23073        };
23074}());
23075
23076// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent
23077
23078if (typeof window.CustomEvent !== "function") {
23079  (function() {
23080    "use strict";
23081    function CustomEvent(event, params) {
23082      params = params || { bubbles: false, cancelable: false, detail: undefined };
23083      var evt = document.createEvent('CustomEvent');
23084      evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
23085      return evt;
23086     }
23087
23088    CustomEvent.prototype = window.Event.prototype;
23089
23090    window.CustomEvent = CustomEvent;
23091  })();
23092}
23093
23094/* jshint laxcomma: true */
23095var salvattore = (function (global, document, undefined) {
23096"use strict";
23097
23098var self = {},
23099    grids = [],
23100    mediaRules = [],
23101    mediaQueries = [],
23102    add_to_dataset = function(element, key, value) {
23103      // uses dataset function or a fallback for <ie10
23104      if (element.dataset) {
23105        element.dataset[key] = value;
23106      } else {
23107        element.setAttribute("data-" + key, value);
23108      }
23109      return;
23110    };
23111
23112self.obtainGridSettings = function obtainGridSettings(element) {
23113  // returns the number of columns and the classes a column should have,
23114  // from computing the style of the ::before pseudo-element of the grid.
23115
23116  var computedStyle = global.getComputedStyle(element, ":before")
23117    , content = computedStyle.getPropertyValue("content").slice(1, -1)
23118    , matchResult = content.match(/^\s*(\d+)(?:\s?\.(.+))?\s*$/)
23119    , numberOfColumns = 1
23120    , columnClasses = []
23121  ;
23122
23123  if (matchResult) {
23124    numberOfColumns = matchResult[1];
23125    columnClasses = matchResult[2];
23126    columnClasses = columnClasses? columnClasses.split(".") : ["column"];
23127  } else {
23128    matchResult = content.match(/^\s*\.(.+)\s+(\d+)\s*$/);
23129    if (matchResult) {
23130      columnClasses = matchResult[1];
23131      numberOfColumns = matchResult[2];
23132      if (numberOfColumns) {
23133            numberOfColumns = numberOfColumns.split(".");
23134      }
23135    }
23136  }
23137
23138  return {
23139    numberOfColumns: numberOfColumns,
23140    columnClasses: columnClasses
23141  };
23142};
23143
23144
23145self.addColumns = function addColumns(grid, items) {
23146  // from the settings obtained, it creates columns with
23147  // the configured classes and adds to them a list of items.
23148
23149  var settings = self.obtainGridSettings(grid)
23150    , numberOfColumns = settings.numberOfColumns
23151    , columnClasses = settings.columnClasses
23152    , columnsItems = new Array(+numberOfColumns)
23153    , columnsFragment = document.createDocumentFragment()
23154    , i = numberOfColumns
23155    , selector
23156  ;
23157
23158  while (i-- !== 0) {
23159    selector = "[data-columns] > *:nth-child(" + numberOfColumns + "n-" + i + ")";
23160    columnsItems.push(items.querySelectorAll(selector));
23161  }
23162
23163  columnsItems.forEach(function append_to_grid_fragment(rows) {
23164    var column = document.createElement("div")
23165      , rowsFragment = document.createDocumentFragment()
23166    ;
23167
23168    column.className = columnClasses.join(" ");
23169
23170    Array.prototype.forEach.call(rows, function append_to_column(row) {
23171      rowsFragment.appendChild(row);
23172    });
23173    column.appendChild(rowsFragment);
23174    columnsFragment.appendChild(column);
23175  });
23176
23177  grid.appendChild(columnsFragment);
23178  add_to_dataset(grid, 'columns', numberOfColumns);
23179};
23180
23181
23182self.removeColumns = function removeColumns(grid) {
23183  // removes all the columns from a grid, and returns a list
23184  // of items sorted by the ordering of columns.
23185
23186  var range = document.createRange();
23187  range.selectNodeContents(grid);
23188
23189  var columns = Array.prototype.filter.call(range.extractContents().childNodes, function filter_elements(node) {
23190    return node instanceof global.HTMLElement;
23191  });
23192
23193  var numberOfColumns = columns.length
23194    , numberOfRowsInFirstColumn = columns[0].childNodes.length
23195    , sortedRows = new Array(numberOfRowsInFirstColumn * numberOfColumns)
23196  ;
23197
23198  Array.prototype.forEach.call(columns, function iterate_columns(column, columnIndex) {
23199    Array.prototype.forEach.call(column.children, function iterate_rows(row, rowIndex) {
23200      sortedRows[rowIndex * numberOfColumns + columnIndex] = row;
23201    });
23202  });
23203
23204  var container = document.createElement("div");
23205  add_to_dataset(container, 'columns', 0);
23206
23207  sortedRows.filter(function filter_non_null(child) {
23208    return !!child;
23209  }).forEach(function append_row(child) {
23210    container.appendChild(child);
23211  });
23212
23213  return container;
23214};
23215
23216
23217self.recreateColumns = function recreateColumns(grid) {
23218  // removes all the columns from the grid, and adds them again,
23219  // it is used when the number of columns change.
23220
23221  global.requestAnimationFrame(function render_after_css_mediaQueryChange() {
23222    self.addColumns(grid, self.removeColumns(grid));
23223    var columnsChange = new CustomEvent("columnsChange");
23224    grid.dispatchEvent(columnsChange);
23225  });
23226};
23227
23228
23229self.mediaQueryChange = function mediaQueryChange(mql) {
23230  // recreates the columns when a media query matches the current state
23231  // of the browser.
23232
23233  if (mql.matches) {
23234    Array.prototype.forEach.call(grids, self.recreateColumns);
23235  }
23236};
23237
23238
23239self.getCSSRules = function getCSSRules(stylesheet) {
23240  // returns a list of css rules from a stylesheet
23241
23242  var cssRules;
23243  try {
23244    cssRules = stylesheet.sheet.cssRules || stylesheet.sheet.rules;
23245  } catch (e) {
23246    return [];
23247  }
23248
23249  return cssRules || [];
23250};
23251
23252
23253self.getStylesheets = function getStylesheets() {
23254  // returns a list of all the styles in the document (that are accessible).
23255
23256  var inlineStyleBlocks = Array.prototype.slice.call(document.querySelectorAll("style"));
23257  inlineStyleBlocks.forEach(function(stylesheet, idx) {
23258    if (stylesheet.type !== 'text/css' && stylesheet.type !== '') {
23259      inlineStyleBlocks.splice(idx, 1);
23260    }
23261  });
23262
23263  return Array.prototype.concat.call(
23264    inlineStyleBlocks,
23265    Array.prototype.slice.call(document.querySelectorAll("link[rel='stylesheet']"))
23266  );
23267};
23268
23269
23270self.mediaRuleHasColumnsSelector = function mediaRuleHasColumnsSelector(rules) {
23271  // checks if a media query css rule has in its contents a selector that
23272  // styles the grid.
23273
23274  var i, rule;
23275
23276  try {
23277    i = rules.length;
23278  }
23279  catch (e) {
23280    i = 0;
23281  }
23282
23283  while (i--) {
23284    rule = rules[i];
23285    if (rule.selectorText && rule.selectorText.match(/\[data-columns\](.*)::?before$/)) {
23286      return true;
23287    }
23288  }
23289
23290  return false;
23291};
23292
23293
23294self.scanMediaQueries = function scanMediaQueries() {
23295  // scans all the stylesheets for selectors that style grids,
23296  // if the matchMedia API is supported.
23297
23298  var newMediaRules = [];
23299
23300  if (!global.matchMedia) {
23301    return;
23302  }
23303
23304  self.getStylesheets().forEach(function extract_rules(stylesheet) {
23305    Array.prototype.forEach.call(self.getCSSRules(stylesheet), function filter_by_column_selector(rule) {
23306      // rule.media throws an 'not implemented error' in ie9 for import rules occasionally
23307      try {
23308        if (rule.media && rule.cssRules && self.mediaRuleHasColumnsSelector(rule.cssRules)) {
23309          newMediaRules.push(rule);
23310        }
23311      } catch (e) {}
23312    });
23313  });
23314
23315  // remove matchMedia listeners from the old rules
23316  var oldRules = mediaRules.filter(function (el) {
23317      return newMediaRules.indexOf(el) === -1;
23318  });
23319  mediaQueries.filter(function (el) {
23320    return oldRules.indexOf(el.rule) !== -1;
23321  }).forEach(function (el) {
23322      el.mql.removeListener(self.mediaQueryChange);
23323  });
23324  mediaQueries = mediaQueries.filter(function (el) {
23325    return oldRules.indexOf(el.rule) === -1;
23326  });
23327
23328  // add matchMedia listeners to the new rules
23329  newMediaRules.filter(function (el) {
23330    return mediaRules.indexOf(el) == -1;
23331  }).forEach(function (rule) {
23332      var mql = global.matchMedia(rule.media.mediaText);
23333      mql.addListener(self.mediaQueryChange);
23334      mediaQueries.push({rule: rule, mql:mql});
23335  });
23336
23337  // swap mediaRules with the new set
23338  mediaRules.length = 0;
23339  mediaRules = newMediaRules;
23340};
23341
23342
23343self.rescanMediaQueries = function rescanMediaQueries() {
23344    self.scanMediaQueries();
23345    Array.prototype.forEach.call(grids, self.recreateColumns);
23346};
23347
23348
23349self.nextElementColumnIndex = function nextElementColumnIndex(grid, fragments) {
23350  // returns the index of the column where the given element must be added.
23351
23352  var children = grid.children
23353    , m = children.length
23354    , lowestRowCount = 0
23355    , child
23356    , currentRowCount
23357    , i
23358    , index = 0
23359  ;
23360  for (i = 0; i < m; i++) {
23361    child = children[i];
23362    currentRowCount = child.children.length + (fragments[i].children || fragments[i].childNodes).length;
23363  if(lowestRowCount === 0) {
23364    lowestRowCount = currentRowCount;
23365  }
23366    if(currentRowCount < lowestRowCount) {
23367      index = i;
23368      lowestRowCount = currentRowCount;
23369    }
23370  }
23371
23372  return index;
23373};
23374
23375
23376self.createFragmentsList = function createFragmentsList(quantity) {
23377  // returns a list of fragments
23378
23379  var fragments = new Array(quantity)
23380    , i = 0
23381  ;
23382
23383  while (i !== quantity) {
23384    fragments[i] = document.createDocumentFragment();
23385    i++;
23386  }
23387
23388  return fragments;
23389};
23390
23391
23392self.appendElements = function appendElements(grid, elements) {
23393  // adds a list of elements to the end of a grid
23394
23395  var columns = grid.children
23396    , numberOfColumns = columns.length
23397    , fragments = self.createFragmentsList(numberOfColumns)
23398  ;
23399
23400  Array.prototype.forEach.call(elements, function append_to_next_fragment(element) {
23401    var columnIndex = self.nextElementColumnIndex(grid, fragments);
23402    fragments[columnIndex].appendChild(element);
23403  });
23404
23405  Array.prototype.forEach.call(columns, function insert_column(column, index) {
23406    column.appendChild(fragments[index]);
23407  });
23408};
23409
23410
23411self.prependElements = function prependElements(grid, elements) {
23412  // adds a list of elements to the start of a grid
23413
23414  var columns = grid.children
23415    , numberOfColumns = columns.length
23416    , fragments = self.createFragmentsList(numberOfColumns)
23417    , columnIndex = numberOfColumns - 1
23418  ;
23419
23420  elements.forEach(function append_to_next_fragment(element) {
23421    var fragment = fragments[columnIndex];
23422    fragment.insertBefore(element, fragment.firstChild);
23423    if (columnIndex === 0) {
23424      columnIndex = numberOfColumns - 1;
23425    } else {
23426      columnIndex--;
23427    }
23428  });
23429
23430  Array.prototype.forEach.call(columns, function insert_column(column, index) {
23431    column.insertBefore(fragments[index], column.firstChild);
23432  });
23433
23434  // populates a fragment with n columns till the right
23435  var fragment = document.createDocumentFragment()
23436    , numberOfColumnsToExtract = elements.length % numberOfColumns
23437  ;
23438
23439  while (numberOfColumnsToExtract-- !== 0) {
23440    fragment.appendChild(grid.lastChild);
23441  }
23442
23443  // adds the fragment to the left
23444  grid.insertBefore(fragment, grid.firstChild);
23445};
23446
23447
23448self.registerGrid = function registerGrid (grid) {
23449  if (global.getComputedStyle(grid).display === "none") {
23450    return;
23451  }
23452
23453  // retrieve the list of items from the grid itself
23454  var range = document.createRange();
23455  range.selectNodeContents(grid);
23456
23457  var items = document.createElement("div");
23458  items.appendChild(range.extractContents());
23459
23460
23461  add_to_dataset(items, 'columns', 0);
23462  self.addColumns(grid, items);
23463  grids.push(grid);
23464};
23465
23466
23467self.init = function init() {
23468  // adds required CSS rule to hide 'content' based
23469  // configuration.
23470
23471  var css = document.createElement("style");
23472  css.innerHTML = "[data-columns]::before{display:block;visibility:hidden;position:absolute;font-size:1px;}";
23473  document.head.appendChild(css);
23474
23475  // scans all the grids in the document and generates
23476  // columns from their configuration.
23477
23478  var gridElements = document.querySelectorAll("[data-columns]");
23479  Array.prototype.forEach.call(gridElements, self.registerGrid);
23480  self.scanMediaQueries();
23481};
23482
23483self.init();
23484
23485return {
23486  appendElements: self.appendElements,
23487  prependElements: self.prependElements,
23488  registerGrid: self.registerGrid,
23489  recreateColumns: self.recreateColumns,
23490  rescanMediaQueries: self.rescanMediaQueries,
23491  init: self.init,
23492
23493  // maintains backwards compatibility with underscore style method names
23494  append_elements: self.appendElements,
23495  prepend_elements: self.prependElements,
23496  register_grid: self.registerGrid,
23497  recreate_columns: self.recreateColumns,
23498  rescan_media_queries: self.rescanMediaQueries
23499};
23500
23501})(window, window.document);
23502
23503return salvattore;
23504}));
vendor: 193,754 bytes, lines 23505-28052
23505
23506},{}],4:[function(require,module,exports){
23507/*! VelocityJS.org (1.4.0). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
23508
23509/*************************
23510 Velocity jQuery Shim
23511 *************************/
23512
23513/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */
23514
23515/* This file contains the jQuery functions that Velocity relies on, thereby removing Velocity's dependency on a full copy of jQuery, and allowing it to work in any environment. */
23516/* These shimmed functions are only used if jQuery isn't present. If both this shim and jQuery are loaded, Velocity defaults to jQuery proper. */
23517/* Browser support: Using this shim instead of jQuery proper removes support for IE8. */
23518
23519(function(window) {
23520	"use strict";
23521	/***************
23522	 Setup
23523	 ***************/
23524
23525	/* If jQuery is already loaded, there's no point in loading this shim. */
23526	if (window.jQuery) {
23527		return;
23528	}
23529
23530	/* jQuery base. */
23531	var $ = function(selector, context) {
23532		return new $.fn.init(selector, context);
23533	};
23534
23535	/********************
23536	 Private Methods
23537	 ********************/
23538
23539	/* jQuery */
23540	$.isWindow = function(obj) {
23541		/* jshint eqeqeq: false */
23542		return obj && obj === obj.window;
23543	};
23544
23545	/* jQuery */
23546	$.type = function(obj) {
23547		if (!obj) {
23548			return obj + "";
23549		}
23550
23551		return typeof obj === "object" || typeof obj === "function" ?
23552				class2type[toString.call(obj)] || "object" :
23553				typeof obj;
23554	};
23555
23556	/* jQuery */
23557	$.isArray = Array.isArray || function(obj) {
23558		return $.type(obj) === "array";
23559	};
23560
23561	/* jQuery */
23562	function isArraylike(obj) {
23563		var length = obj.length,
23564				type = $.type(obj);
23565
23566		if (type === "function" || $.isWindow(obj)) {
23567			return false;
23568		}
23569
23570		if (obj.nodeType === 1 && length) {
23571			return true;
23572		}
23573
23574		return type === "array" || length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj;
23575	}
23576
23577	/***************
23578	 $ Methods
23579	 ***************/
23580
23581	/* jQuery: Support removed for IE<9. */
23582	$.isPlainObject = function(obj) {
23583		var key;
23584
23585		if (!obj || $.type(obj) !== "object" || obj.nodeType || $.isWindow(obj)) {
23586			return false;
23587		}
23588
23589		try {
23590			if (obj.constructor &&
23591					!hasOwn.call(obj, "constructor") &&
23592					!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
23593				return false;
23594			}
23595		} catch (e) {
23596			return false;
23597		}
23598
23599		for (key in obj) {
23600		}
23601
23602		return key === undefined || hasOwn.call(obj, key);
23603	};
23604
23605	/* jQuery */
23606	$.each = function(obj, callback, args) {
23607		var value,
23608				i = 0,
23609				length = obj.length,
23610				isArray = isArraylike(obj);
23611
23612		if (args) {
23613			if (isArray) {
23614				for (; i < length; i++) {
23615					value = callback.apply(obj[i], args);
23616
23617					if (value === false) {
23618						break;
23619					}
23620				}
23621			} else {
23622				for (i in obj) {
23623					if (!obj.hasOwnProperty(i)) {
23624						continue;
23625					}
23626					value = callback.apply(obj[i], args);
23627
23628					if (value === false) {
23629						break;
23630					}
23631				}
23632			}
23633
23634		} else {
23635			if (isArray) {
23636				for (; i < length; i++) {
23637					value = callback.call(obj[i], i, obj[i]);
23638
23639					if (value === false) {
23640						break;
23641					}
23642				}
23643			} else {
23644				for (i in obj) {
23645					if (!obj.hasOwnProperty(i)) {
23646						continue;
23647					}
23648					value = callback.call(obj[i], i, obj[i]);
23649
23650					if (value === false) {
23651						break;
23652					}
23653				}
23654			}
23655		}
23656
23657		return obj;
23658	};
23659
23660	/* Custom */
23661	$.data = function(node, key, value) {
23662		/* $.getData() */
23663		if (value === undefined) {
23664			var getId = node[$.expando],
23665					store = getId && cache[getId];
23666
23667			if (key === undefined) {
23668				return store;
23669			} else if (store) {
23670				if (key in store) {
23671					return store[key];
23672				}
23673			}
23674			/* $.setData() */
23675		} else if (key !== undefined) {
23676			var setId = node[$.expando] || (node[$.expando] = ++$.uuid);
23677
23678			cache[setId] = cache[setId] || {};
23679			cache[setId][key] = value;
23680
23681			return value;
23682		}
23683	};
23684
23685	/* Custom */
23686	$.removeData = function(node, keys) {
23687		var id = node[$.expando],
23688				store = id && cache[id];
23689
23690		if (store) {
23691			// Cleanup the entire store if no keys are provided.
23692			if (!keys) {
23693				delete cache[id];
23694			} else {
23695				$.each(keys, function(_, key) {
23696					delete store[key];
23697				});
23698			}
23699		}
23700	};
23701
23702	/* jQuery */
23703	$.extend = function() {
23704		var src, copyIsArray, copy, name, options, clone,
23705				target = arguments[0] || {},
23706				i = 1,
23707				length = arguments.length,
23708				deep = false;
23709
23710		if (typeof target === "boolean") {
23711			deep = target;
23712
23713			target = arguments[i] || {};
23714			i++;
23715		}
23716
23717		if (typeof target !== "object" && $.type(target) !== "function") {
23718			target = {};
23719		}
23720
23721		if (i === length) {
23722			target = this;
23723			i--;
23724		}
23725
23726		for (; i < length; i++) {
23727			if ((options = arguments[i])) {
23728				for (name in options) {
23729					if (!options.hasOwnProperty(name)) {
23730						continue;
23731					}
23732					src = target[name];
23733					copy = options[name];
23734
23735					if (target === copy) {
23736						continue;
23737					}
23738
23739					if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
23740						if (copyIsArray) {
23741							copyIsArray = false;
23742							clone = src && $.isArray(src) ? src : [];
23743
23744						} else {
23745							clone = src && $.isPlainObject(src) ? src : {};
23746						}
23747
23748						target[name] = $.extend(deep, clone, copy);
23749
23750					} else if (copy !== undefined) {
23751						target[name] = copy;
23752					}
23753				}
23754			}
23755		}
23756
23757		return target;
23758	};
23759
23760	/* jQuery 1.4.3 */
23761	$.queue = function(elem, type, data) {
23762		function $makeArray(arr, results) {
23763			var ret = results || [];
23764
23765			if (arr) {
23766				if (isArraylike(Object(arr))) {
23767					/* $.merge */
23768					(function(first, second) {
23769						var len = +second.length,
23770								j = 0,
23771								i = first.length;
23772
23773						while (j < len) {
23774							first[i++] = second[j++];
23775						}
23776
23777						if (len !== len) {
23778							while (second[j] !== undefined) {
23779								first[i++] = second[j++];
23780							}
23781						}
23782
23783						first.length = i;
23784
23785						return first;
23786					})(ret, typeof arr === "string" ? [arr] : arr);
23787				} else {
23788					[].push.call(ret, arr);
23789				}
23790			}
23791
23792			return ret;
23793		}
23794
23795		if (!elem) {
23796			return;
23797		}
23798
23799		type = (type || "fx") + "queue";
23800
23801		var q = $.data(elem, type);
23802
23803		if (!data) {
23804			return q || [];
23805		}
23806
23807		if (!q || $.isArray(data)) {
23808			q = $.data(elem, type, $makeArray(data));
23809		} else {
23810			q.push(data);
23811		}
23812
23813		return q;
23814	};
23815
23816	/* jQuery 1.4.3 */
23817	$.dequeue = function(elems, type) {
23818		/* Custom: Embed element iteration. */
23819		$.each(elems.nodeType ? [elems] : elems, function(i, elem) {
23820			type = type || "fx";
23821
23822			var queue = $.queue(elem, type),
23823					fn = queue.shift();
23824
23825			if (fn === "inprogress") {
23826				fn = queue.shift();
23827			}
23828
23829			if (fn) {
23830				if (type === "fx") {
23831					queue.unshift("inprogress");
23832				}
23833
23834				fn.call(elem, function() {
23835					$.dequeue(elem, type);
23836				});
23837			}
23838		});
23839	};
23840
23841	/******************
23842	 $.fn Methods
23843	 ******************/
23844
23845	/* jQuery */
23846	$.fn = $.prototype = {
23847		init: function(selector) {
23848			/* Just return the element wrapped inside an array; don't proceed with the actual jQuery node wrapping process. */
23849			if (selector.nodeType) {
23850				this[0] = selector;
23851
23852				return this;
23853			} else {
23854				throw new Error("Not a DOM node.");
23855			}
23856		},
23857		offset: function() {
23858			/* jQuery altered code: Dropped disconnected DOM node checking. */
23859			var box = this[0].getBoundingClientRect ? this[0].getBoundingClientRect() : {top: 0, left: 0};
23860
23861			return {
23862				top: box.top + (window.pageYOffset || document.scrollTop || 0) - (document.clientTop || 0),
23863				left: box.left + (window.pageXOffset || document.scrollLeft || 0) - (document.clientLeft || 0)
23864			};
23865		},
23866		position: function() {
23867			/* jQuery */
23868			function offsetParentFn(elem) {
23869				var offsetParent = elem.offsetParent;
23870
23871				while (offsetParent && offsetParent.nodeName.toLowerCase() !== "html" && offsetParent.style && offsetParent.style.position === "static") {
23872					offsetParent = offsetParent.offsetParent;
23873				}
23874
23875				return offsetParent || document;
23876			}
23877
23878			/* Zepto */
23879			var elem = this[0],
23880					offsetParent = offsetParentFn(elem),
23881					offset = this.offset(),
23882					parentOffset = /^(?:body|html)$/i.test(offsetParent.nodeName) ? {top: 0, left: 0} : $(offsetParent).offset();
23883
23884			offset.top -= parseFloat(elem.style.marginTop) || 0;
23885			offset.left -= parseFloat(elem.style.marginLeft) || 0;
23886
23887			if (offsetParent.style) {
23888				parentOffset.top += parseFloat(offsetParent.style.borderTopWidth) || 0;
23889				parentOffset.left += parseFloat(offsetParent.style.borderLeftWidth) || 0;
23890			}
23891
23892			return {
23893				top: offset.top - parentOffset.top,
23894				left: offset.left - parentOffset.left
23895			};
23896		}
23897	};
23898
23899	/**********************
23900	 Private Variables
23901	 **********************/
23902
23903	/* For $.data() */
23904	var cache = {};
23905	$.expando = "velocity" + (new Date().getTime());
23906	$.uuid = 0;
23907
23908	/* For $.queue() */
23909	var class2type = {},
23910			hasOwn = class2type.hasOwnProperty,
23911			toString = class2type.toString;
23912
23913	var types = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
23914	for (var i = 0; i < types.length; i++) {
23915		class2type["[object " + types[i] + "]"] = types[i].toLowerCase();
23916	}
23917
23918	/* Makes $(node) possible, without having to call init. */
23919	$.fn.init.prototype = $.fn;
23920
23921	/* Globalize Velocity onto the window, and assign its Utilities property. */
23922	window.Velocity = {Utilities: $};
23923})(window);
23924
23925/******************
23926 Velocity.js
23927 ******************/
23928
23929(function(factory) {
23930	"use strict";
23931	/* CommonJS module. */
23932	if (typeof module === "object" && typeof module.exports === "object") {
23933		module.exports = factory();
23934		/* AMD module. */
23935	} else if (typeof define === "function" && define.amd) {
23936		define(factory);
23937		/* Browser globals. */
23938	} else {
23939		factory();
23940	}
23941}(function() {
23942	"use strict";
23943	return function(global, window, document, undefined) {
23944
23945		/***************
23946		 Summary
23947		 ***************/
23948
23949		/*
23950		 - CSS: CSS stack that works independently from the rest of Velocity.
23951		 - animate(): Core animation method that iterates over the targeted elements and queues the incoming call onto each element individually.
23952		 - Pre-Queueing: Prepare the element for animation by instantiating its data cache and processing the call's options.
23953		 - Queueing: The logic that runs once the call has reached its point of execution in the element's $.queue() stack.
23954		 Most logic is placed here to avoid risking it becoming stale (if the element's properties have changed).
23955		 - Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.
23956		 - tick(): The single requestAnimationFrame loop responsible for tweening all in-progress calls.
23957		 - completeCall(): Handles the cleanup process for each Velocity call.
23958		 */
23959
23960		/*********************
23961		 Helper Functions
23962		 *********************/
23963
23964		/* IE detection. Gist: https://gist.github.com/julianshapiro/9098609 */
23965		var IE = (function() {
23966			if (document.documentMode) {
23967				return document.documentMode;
23968			} else {
23969				for (var i = 7; i > 4; i--) {
23970					var div = document.createElement("div");
23971
23972					div.innerHTML = "<!--[if IE " + i + "]><span></span><![endif]-->";
23973
23974					if (div.getElementsByTagName("span").length) {
23975						div = null;
23976
23977						return i;
23978					}
23979				}
23980			}
23981
23982			return undefined;
23983		})();
23984
23985		/* rAF shim. Gist: https://gist.github.com/julianshapiro/9497513 */
23986		var rAFShim = (function() {
23987			var timeLast = 0;
23988
23989			return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
23990				var timeCurrent = (new Date()).getTime(),
23991						timeDelta;
23992
23993				/* Dynamically set delay on a per-tick basis to match 60fps. */
23994				/* Technique by Erik Moller. MIT license: https://gist.github.com/paulirish/1579671 */
23995				timeDelta = Math.max(0, 16 - (timeCurrent - timeLast));
23996				timeLast = timeCurrent + timeDelta;
23997
23998				return setTimeout(function() {
23999					callback(timeCurrent + timeDelta);
24000				}, timeDelta);
24001			};
24002		})();
24003
24004		var performance = (function() {
24005			var perf = window.performance || {};
24006
24007			if (!perf.hasOwnProperty("now")) {
24008				var nowOffset = perf.timing && perf.timing.domComplete ? perf.timing.domComplete : (new Date()).getTime();
24009
24010				perf.now = function() {
24011					return (new Date()).getTime() - nowOffset;
24012				};
24013			}
24014			return perf;
24015		})();
24016
24017		/* Array compacting. Copyright Lo-Dash. MIT License: https://github.com/lodash/lodash/blob/master/LICENSE.txt */
24018		function compactSparseArray(array) {
24019			var index = -1,
24020					length = array ? array.length : 0,
24021					result = [];
24022
24023			while (++index < length) {
24024				var value = array[index];
24025
24026				if (value) {
24027					result.push(value);
24028				}
24029			}
24030
24031			return result;
24032		}
24033
24034		function sanitizeElements(elements) {
24035			/* Unwrap jQuery/Zepto objects. */
24036			if (Type.isWrapped(elements)) {
24037				elements = [].slice.call(elements);
24038				/* Wrap a single element in an array so that $.each() can iterate with the element instead of its node's children. */
24039			} else if (Type.isNode(elements)) {
24040				elements = [elements];
24041			}
24042
24043			return elements;
24044		}
24045
24046		var Type = {
24047			isNumber: function(variable) {
24048				return (typeof variable === "number");
24049			},
24050			isString: function(variable) {
24051				return (typeof variable === "string");
24052			},
24053			isArray: Array.isArray || function(variable) {
24054				return Object.prototype.toString.call(variable) === "[object Array]";
24055			},
24056			isFunction: function(variable) {
24057				return Object.prototype.toString.call(variable) === "[object Function]";
24058			},
24059			isNode: function(variable) {
24060				return variable && variable.nodeType;
24061			},
24062			/* Copyright Martin Bohm. MIT License: https://gist.github.com/Tomalak/818a78a226a0738eaade */
24063			isNodeList: function(variable) {
24064				return typeof variable === "object" &&
24065						/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(variable)) &&
24066						variable.length !== undefined &&
24067						(variable.length === 0 || (typeof variable[0] === "object" && variable[0].nodeType > 0));
24068			},
24069			/* Determine if variable is an array-like wrapped jQuery, Zepto or similar element. */
24070			isWrapped: function(variable) {
24071				return variable && (Type.isArray(variable) || (Type.isNumber(variable.length) && !Type.isString(variable) && !Type.isFunction(variable)));
24072			},
24073			isSVG: function(variable) {
24074				return window.SVGElement && (variable instanceof window.SVGElement);
24075			},
24076			isEmptyObject: function(variable) {
24077				for (var name in variable) {
24078					if (variable.hasOwnProperty(name)) {
24079						return false;
24080					}
24081				}
24082
24083				return true;
24084			}
24085		};
24086
24087		/*****************
24088		 Dependencies
24089		 *****************/
24090
24091		var $,
24092				isJQuery = false;
24093
24094		if (global.fn && global.fn.jquery) {
24095			$ = global;
24096			isJQuery = true;
24097		} else {
24098			$ = window.Velocity.Utilities;
24099		}
24100
24101		if (IE <= 8 && !isJQuery) {
24102			throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");
24103		} else if (IE <= 7) {
24104			/* Revert to jQuery's $.animate(), and lose Velocity's extra features. */
24105			jQuery.fn.velocity = jQuery.fn.animate;
24106
24107			/* Now that $.fn.velocity is aliased, abort this Velocity declaration. */
24108			return;
24109		}
24110
24111		/*****************
24112		 Constants
24113		 *****************/
24114
24115		var DURATION_DEFAULT = 400,
24116				EASING_DEFAULT = "swing";
24117
24118		/*************
24119		 State
24120		 *************/
24121
24122		var Velocity = {
24123			/* Container for page-wide Velocity state data. */
24124			State: {
24125				/* Detect mobile devices to determine if mobileHA should be turned on. */
24126				isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
24127				/* The mobileHA option's behavior changes on older Android devices (Gingerbread, versions 2.3.3-2.3.7). */
24128				isAndroid: /Android/i.test(navigator.userAgent),
24129				isGingerbread: /Android 2\.3\.[3-7]/i.test(navigator.userAgent),
24130				isChrome: window.chrome,
24131				isFirefox: /Firefox/i.test(navigator.userAgent),
24132				/* Create a cached element for re-use when checking for CSS property prefixes. */
24133				prefixElement: document.createElement("div"),
24134				/* Cache every prefix match to avoid repeating lookups. */
24135				prefixMatches: {},
24136				/* Cache the anchor used for animating window scrolling. */
24137				scrollAnchor: null,
24138				/* Cache the browser-specific property names associated with the scroll anchor. */
24139				scrollPropertyLeft: null,
24140				scrollPropertyTop: null,
24141				/* Keep track of whether our RAF tick is running. */
24142				isTicking: false,
24143				/* Container for every in-progress call to Velocity. */
24144				calls: [],
24145				delayedElements: {
24146					count: 0
24147				}
24148			},
24149			/* Velocity's custom CSS stack. Made global for unit testing. */
24150			CSS: {/* Defined below. */},
24151			/* A shim of the jQuery utility functions used by Velocity -- provided by Velocity's optional jQuery shim. */
24152			Utilities: $,
24153			/* Container for the user's custom animation redirects that are referenced by name in place of the properties map argument. */
24154			Redirects: {/* Manually registered by the user. */},
24155			Easings: {/* Defined below. */},
24156			/* Attempt to use ES6 Promises by default. Users can override this with a third-party promises library. */
24157			Promise: window.Promise,
24158			/* Velocity option defaults, which can be overriden by the user. */
24159			defaults: {
24160				queue: "",
24161				duration: DURATION_DEFAULT,
24162				easing: EASING_DEFAULT,
24163				begin: undefined,
24164				complete: undefined,
24165				progress: undefined,
24166				display: undefined,
24167				visibility: undefined,
24168				loop: false,
24169				delay: false,
24170				mobileHA: true,
24171				/* Advanced: Set to false to prevent property values from being cached between consecutive Velocity-initiated chain calls. */
24172				_cacheValues: true,
24173				/* Advanced: Set to false if the promise should always resolve on empty element lists. */
24174				promiseRejectEmpty: true
24175			},
24176			/* A design goal of Velocity is to cache data wherever possible in order to avoid DOM requerying. Accordingly, each element has a data cache. */
24177			init: function(element) {
24178				$.data(element, "velocity", {
24179					/* Store whether this is an SVG element, since its properties are retrieved and updated differently than standard HTML elements. */
24180					isSVG: Type.isSVG(element),
24181					/* Keep track of whether the element is currently being animated by Velocity.
24182					 This is used to ensure that property values are not transferred between non-consecutive (stale) calls. */
24183					isAnimating: false,
24184					/* A reference to the element's live computedStyle object. Learn more here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */
24185					computedStyle: null,
24186					/* Tween data is cached for each animation on the element so that data can be passed across calls --
24187					 in particular, end values are used as subsequent start values in consecutive Velocity calls. */
24188					tweensContainer: null,
24189					/* The full root property values of each CSS hook being animated on this element are cached so that:
24190					 1) Concurrently-animating hooks sharing the same root can have their root values' merged into one while tweening.
24191					 2) Post-hook-injection root values can be transferred over to consecutively chained Velocity calls as starting root values. */
24192					rootPropertyValueCache: {},
24193					/* A cache for transform updates, which must be manually flushed via CSS.flushTransformCache(). */
24194					transformCache: {}
24195				});
24196			},
24197			/* A parallel to jQuery's $.css(), used for getting/setting Velocity's hooked CSS properties. */
24198			hook: null, /* Defined below. */
24199			/* Velocity-wide animation time remapping for testing purposes. */
24200			mock: false,
24201			version: {major: 1, minor: 4, patch: 0},
24202			/* Set to 1 or 2 (most verbose) to output debug info to console. */
24203			debug: false,
24204			/* Use rAF high resolution timestamp when available */
24205			timestamp: true,
24206			/* Pause all animations */
24207			pauseAll: function(queueName) {
24208				var currentTime = (new Date()).getTime();
24209
24210				$.each(Velocity.State.calls, function(i, activeCall) {
24211
24212					if (activeCall) {
24213
24214						/* If we have a queueName and this call is not on that queue, skip */
24215						if (queueName !== undefined && ((activeCall[2].queue !== queueName) || (activeCall[2].queue === false))) {
24216							return true;
24217						}
24218
24219						/* Set call to paused */
24220						activeCall[5] = {
24221							resume: false
24222						};
24223					}
24224				});
24225
24226				/* Pause timers on any currently delayed calls */
24227				$.each(Velocity.State.delayedElements, function(k, element) {
24228					if (!element) {
24229						return;
24230					}
24231					pauseDelayOnElement(element, currentTime);
24232				});
24233			},
24234			/* Resume all animations */
24235			resumeAll: function(queueName) {
24236				var currentTime = (new Date()).getTime();
24237
24238				$.each(Velocity.State.calls, function(i, activeCall) {
24239
24240					if (activeCall) {
24241
24242						/* If we have a queueName and this call is not on that queue, skip */
24243						if (queueName !== undefined && ((activeCall[2].queue !== queueName) || (activeCall[2].queue === false))) {
24244							return true;
24245						}
24246
24247						/* Set call to resumed if it was paused */
24248						if (activeCall[5]) {
24249							activeCall[5].resume = true;
24250						}
24251					}
24252				});
24253				/* Resume timers on any currently delayed calls */
24254				$.each(Velocity.State.delayedElements, function(k, element) {
24255					if (!element) {
24256						return;
24257					}
24258					resumeDelayOnElement(element, currentTime);
24259				});
24260			}
24261		};
24262
24263		/* Retrieve the appropriate scroll anchor and property name for the browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY */
24264		if (window.pageYOffset !== undefined) {
24265			Velocity.State.scrollAnchor = window;
24266			Velocity.State.scrollPropertyLeft = "pageXOffset";
24267			Velocity.State.scrollPropertyTop = "pageYOffset";
24268		} else {
24269			Velocity.State.scrollAnchor = document.documentElement || document.body.parentNode || document.body;
24270			Velocity.State.scrollPropertyLeft = "scrollLeft";
24271			Velocity.State.scrollPropertyTop = "scrollTop";
24272		}
24273
24274		/* Shorthand alias for jQuery's $.data() utility. */
24275		function Data(element) {
24276			/* Hardcode a reference to the plugin name. */
24277			var response = $.data(element, "velocity");
24278
24279			/* jQuery <=1.4.2 returns null instead of undefined when no match is found. We normalize this behavior. */
24280			return response === null ? undefined : response;
24281		}
24282
24283		/**************
24284		 Delay Timer
24285		 **************/
24286
24287		function pauseDelayOnElement(element, currentTime) {
24288			/* Check for any delay timers, and pause the set timeouts (while preserving time data)
24289			 to be resumed when the "resume" command is issued */
24290			var data = Data(element);
24291			if (data && data.delayTimer && !data.delayPaused) {
24292				data.delayRemaining = data.delay - currentTime + data.delayBegin;
24293				data.delayPaused = true;
24294				clearTimeout(data.delayTimer.setTimeout);
24295			}
24296		}
24297
24298		function resumeDelayOnElement(element, currentTime) {
24299			/* Check for any paused timers and resume */
24300			var data = Data(element);
24301			if (data && data.delayTimer && data.delayPaused) {
24302				/* If the element was mid-delay, re initiate the timeout with the remaining delay */
24303				data.delayPaused = false;
24304				data.delayTimer.setTimeout = setTimeout(data.delayTimer.next, data.delayRemaining);
24305			}
24306		}
24307
24308
24309
24310		/**************
24311		 Easing
24312		 **************/
24313
24314		/* Step easing generator. */
24315		function generateStep(steps) {
24316			return function(p) {
24317				return Math.round(p * steps) * (1 / steps);
24318			};
24319		}
24320
24321		/* Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */
24322		function generateBezier(mX1, mY1, mX2, mY2) {
24323			var NEWTON_ITERATIONS = 4,
24324					NEWTON_MIN_SLOPE = 0.001,
24325					SUBDIVISION_PRECISION = 0.0000001,
24326					SUBDIVISION_MAX_ITERATIONS = 10,
24327					kSplineTableSize = 11,
24328					kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),
24329					float32ArraySupported = "Float32Array" in window;
24330
24331			/* Must contain four arguments. */
24332			if (arguments.length !== 4) {
24333				return false;
24334			}
24335
24336			/* Arguments must be numbers. */
24337			for (var i = 0; i < 4; ++i) {
24338				if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) {
24339					return false;
24340				}
24341			}
24342
24343			/* X values must be in the [0, 1] range. */
24344			mX1 = Math.min(mX1, 1);
24345			mX2 = Math.min(mX2, 1);
24346			mX1 = Math.max(mX1, 0);
24347			mX2 = Math.max(mX2, 0);
24348
24349			var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
24350
24351			function A(aA1, aA2) {
24352				return 1.0 - 3.0 * aA2 + 3.0 * aA1;
24353			}
24354			function B(aA1, aA2) {
24355				return 3.0 * aA2 - 6.0 * aA1;
24356			}
24357			function C(aA1) {
24358				return 3.0 * aA1;
24359			}
24360
24361			function calcBezier(aT, aA1, aA2) {
24362				return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
24363			}
24364
24365			function getSlope(aT, aA1, aA2) {
24366				return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
24367			}
24368
24369			function newtonRaphsonIterate(aX, aGuessT) {
24370				for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
24371					var currentSlope = getSlope(aGuessT, mX1, mX2);
24372
24373					if (currentSlope === 0.0) {
24374						return aGuessT;
24375					}
24376
24377					var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
24378					aGuessT -= currentX / currentSlope;
24379				}
24380
24381				return aGuessT;
24382			}
24383
24384			function calcSampleValues() {
24385				for (var i = 0; i < kSplineTableSize; ++i) {
24386					mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
24387				}
24388			}
24389
24390			function binarySubdivide(aX, aA, aB) {
24391				var currentX, currentT, i = 0;
24392
24393				do {
24394					currentT = aA + (aB - aA) / 2.0;
24395					currentX = calcBezier(currentT, mX1, mX2) - aX;
24396					if (currentX > 0.0) {
24397						aB = currentT;
24398					} else {
24399						aA = currentT;
24400					}
24401				} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
24402
24403				return currentT;
24404			}
24405
24406			function getTForX(aX) {
24407				var intervalStart = 0.0,
24408						currentSample = 1,
24409						lastSample = kSplineTableSize - 1;
24410
24411				for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
24412					intervalStart += kSampleStepSize;
24413				}
24414
24415				--currentSample;
24416
24417				var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]),
24418						guessForT = intervalStart + dist * kSampleStepSize,
24419						initialSlope = getSlope(guessForT, mX1, mX2);
24420
24421				if (initialSlope >= NEWTON_MIN_SLOPE) {
24422					return newtonRaphsonIterate(aX, guessForT);
24423				} else if (initialSlope === 0.0) {
24424					return guessForT;
24425				} else {
24426					return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);
24427				}
24428			}
24429
24430			var _precomputed = false;
24431
24432			function precompute() {
24433				_precomputed = true;
24434				if (mX1 !== mY1 || mX2 !== mY2) {
24435					calcSampleValues();
24436				}
24437			}
24438
24439			var f = function(aX) {
24440				if (!_precomputed) {
24441					precompute();
24442				}
24443				if (mX1 === mY1 && mX2 === mY2) {
24444					return aX;
24445				}
24446				if (aX === 0) {
24447					return 0;
24448				}
24449				if (aX === 1) {
24450					return 1;
24451				}
24452
24453				return calcBezier(getTForX(aX), mY1, mY2);
24454			};
24455
24456			f.getControlPoints = function() {
24457				return [{x: mX1, y: mY1}, {x: mX2, y: mY2}];
24458			};
24459
24460			var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")";
24461			f.toString = function() {
24462				return str;
24463			};
24464
24465			return f;
24466		}
24467
24468		/* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */
24469		/* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass
24470		 then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */
24471		var generateSpringRK4 = (function() {
24472			function springAccelerationForState(state) {
24473				return (-state.tension * state.x) - (state.friction * state.v);
24474			}
24475
24476			function springEvaluateStateWithDerivative(initialState, dt, derivative) {
24477				var state = {
24478					x: initialState.x + derivative.dx * dt,
24479					v: initialState.v + derivative.dv * dt,
24480					tension: initialState.tension,
24481					friction: initialState.friction
24482				};
24483
24484				return {dx: state.v, dv: springAccelerationForState(state)};
24485			}
24486
24487			function springIntegrateState(state, dt) {
24488				var a = {
24489					dx: state.v,
24490					dv: springAccelerationForState(state)
24491				},
24492						b = springEvaluateStateWithDerivative(state, dt * 0.5, a),
24493						c = springEvaluateStateWithDerivative(state, dt * 0.5, b),
24494						d = springEvaluateStateWithDerivative(state, dt, c),
24495						dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),
24496						dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);
24497
24498				state.x = state.x + dxdt * dt;
24499				state.v = state.v + dvdt * dt;
24500
24501				return state;
24502			}
24503
24504			return function springRK4Factory(tension, friction, duration) {
24505
24506				var initState = {
24507					x: -1,
24508					v: 0,
24509					tension: null,
24510					friction: null
24511				},
24512						path = [0],
24513						time_lapsed = 0,
24514						tolerance = 1 / 10000,
24515						DT = 16 / 1000,
24516						have_duration, dt, last_state;
24517
24518				tension = parseFloat(tension) || 500;
24519				friction = parseFloat(friction) || 20;
24520				duration = duration || null;
24521
24522				initState.tension = tension;
24523				initState.friction = friction;
24524
24525				have_duration = duration !== null;
24526
24527				/* Calculate the actual time it takes for this animation to complete with the provided conditions. */
24528				if (have_duration) {
24529					/* Run the simulation without a duration. */
24530					time_lapsed = springRK4Factory(tension, friction);
24531					/* Compute the adjusted time delta. */
24532					dt = time_lapsed / duration * DT;
24533				} else {
24534					dt = DT;
24535				}
24536
24537				while (true) {
24538					/* Next/step function .*/
24539					last_state = springIntegrateState(last_state || initState, dt);
24540					/* Store the position. */
24541					path.push(1 + last_state.x);
24542					time_lapsed += 16;
24543					/* If the change threshold is reached, break. */
24544					if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {
24545						break;
24546					}
24547				}
24548
24549				/* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the
24550				 computed path and returns a snapshot of the position according to a given percentComplete. */
24551				return !have_duration ? time_lapsed : function(percentComplete) {
24552					return path[ (percentComplete * (path.length - 1)) | 0 ];
24553				};
24554			};
24555		}());
24556
24557		/* jQuery easings. */
24558		Velocity.Easings = {
24559			linear: function(p) {
24560				return p;
24561			},
24562			swing: function(p) {
24563				return 0.5 - Math.cos(p * Math.PI) / 2;
24564			},
24565			/* Bonus "spring" easing, which is a less exaggerated version of easeInOutElastic. */
24566			spring: function(p) {
24567				return 1 - (Math.cos(p * 4.5 * Math.PI) * Math.exp(-p * 6));
24568			}
24569		};
24570
24571		/* CSS3 and Robert Penner easings. */
24572		$.each(
24573				[
24574					["ease", [0.25, 0.1, 0.25, 1.0]],
24575					["ease-in", [0.42, 0.0, 1.00, 1.0]],
24576					["ease-out", [0.00, 0.0, 0.58, 1.0]],
24577					["ease-in-out", [0.42, 0.0, 0.58, 1.0]],
24578					["easeInSine", [0.47, 0, 0.745, 0.715]],
24579					["easeOutSine", [0.39, 0.575, 0.565, 1]],
24580					["easeInOutSine", [0.445, 0.05, 0.55, 0.95]],
24581					["easeInQuad", [0.55, 0.085, 0.68, 0.53]],
24582					["easeOutQuad", [0.25, 0.46, 0.45, 0.94]],
24583					["easeInOutQuad", [0.455, 0.03, 0.515, 0.955]],
24584					["easeInCubic", [0.55, 0.055, 0.675, 0.19]],
24585					["easeOutCubic", [0.215, 0.61, 0.355, 1]],
24586					["easeInOutCubic", [0.645, 0.045, 0.355, 1]],
24587					["easeInQuart", [0.895, 0.03, 0.685, 0.22]],
24588					["easeOutQuart", [0.165, 0.84, 0.44, 1]],
24589					["easeInOutQuart", [0.77, 0, 0.175, 1]],
24590					["easeInQuint", [0.755, 0.05, 0.855, 0.06]],
24591					["easeOutQuint", [0.23, 1, 0.32, 1]],
24592					["easeInOutQuint", [0.86, 0, 0.07, 1]],
24593					["easeInExpo", [0.95, 0.05, 0.795, 0.035]],
24594					["easeOutExpo", [0.19, 1, 0.22, 1]],
24595					["easeInOutExpo", [1, 0, 0, 1]],
24596					["easeInCirc", [0.6, 0.04, 0.98, 0.335]],
24597					["easeOutCirc", [0.075, 0.82, 0.165, 1]],
24598					["easeInOutCirc", [0.785, 0.135, 0.15, 0.86]]
24599				], function(i, easingArray) {
24600			Velocity.Easings[easingArray[0]] = generateBezier.apply(null, easingArray[1]);
24601		});
24602
24603		/* Determine the appropriate easing type given an easing input. */
24604		function getEasing(value, duration) {
24605			var easing = value;
24606
24607			/* The easing option can either be a string that references a pre-registered easing,
24608			 or it can be a two-/four-item array of integers to be converted into a bezier/spring function. */
24609			if (Type.isString(value)) {
24610				/* Ensure that the easing has been assigned to jQuery's Velocity.Easings object. */
24611				if (!Velocity.Easings[value]) {
24612					easing = false;
24613				}
24614			} else if (Type.isArray(value) && value.length === 1) {
24615				easing = generateStep.apply(null, value);
24616			} else if (Type.isArray(value) && value.length === 2) {
24617				/* springRK4 must be passed the animation's duration. */
24618				/* Note: If the springRK4 array contains non-numbers, generateSpringRK4() returns an easing
24619				 function generated with default tension and friction values. */
24620				easing = generateSpringRK4.apply(null, value.concat([duration]));
24621			} else if (Type.isArray(value) && value.length === 4) {
24622				/* Note: If the bezier array contains non-numbers, generateBezier() returns false. */
24623				easing = generateBezier.apply(null, value);
24624			} else {
24625				easing = false;
24626			}
24627
24628			/* Revert to the Velocity-wide default easing type, or fall back to "swing" (which is also jQuery's default)
24629			 if the Velocity-wide default has been incorrectly modified. */
24630			if (easing === false) {
24631				if (Velocity.Easings[Velocity.defaults.easing]) {
24632					easing = Velocity.defaults.easing;
24633				} else {
24634					easing = EASING_DEFAULT;
24635				}
24636			}
24637
24638			return easing;
24639		}
24640
24641		/*****************
24642		 CSS Stack
24643		 *****************/
24644
24645		/* The CSS object is a highly condensed and performant CSS stack that fully replaces jQuery's.
24646		 It handles the validation, getting, and setting of both standard CSS properties and CSS property hooks. */
24647		/* Note: A "CSS" shorthand is aliased so that our code is easier to read. */
24648		var CSS = Velocity.CSS = {
24649			/*************
24650			 RegEx
24651			 *************/
24652
24653			RegEx: {
24654				isHex: /^#([A-f\d]{3}){1,2}$/i,
24655				/* Unwrap a property value's surrounding text, e.g. "rgba(4, 3, 2, 1)" ==> "4, 3, 2, 1" and "rect(4px 3px 2px 1px)" ==> "4px 3px 2px 1px". */
24656				valueUnwrap: /^[A-z]+\((.*)\)$/i,
24657				wrappedValueAlreadyExtracted: /[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,
24658				/* Split a multi-value property into an array of subvalues, e.g. "rgba(4, 3, 2, 1) 4px 3px 2px 1px" ==> [ "rgba(4, 3, 2, 1)", "4px", "3px", "2px", "1px" ]. */
24659				valueSplit: /([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/ig
24660			},
24661			/************
24662			 Lists
24663			 ************/
24664
24665			Lists: {
24666				colors: ["fill", "stroke", "stopColor", "color", "backgroundColor", "borderColor", "borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor", "outlineColor"],
24667				transformsBase: ["translateX", "translateY", "scale", "scaleX", "scaleY", "skewX", "skewY", "rotateZ"],
24668				transforms3D: ["transformPerspective", "translateZ", "scaleZ", "rotateX", "rotateY"],
24669				units: [
24670					"%", // relative
24671					"em", "ex", "ch", "rem", // font relative
24672					"vw", "vh", "vmin", "vmax", // viewport relative
24673					"cm", "mm", "Q", "in", "pc", "pt", "px", // absolute lengths
24674					"deg", "grad", "rad", "turn", // angles
24675					"s", "ms" // time
24676				],
24677				colorNames: {
24678					"aliceblue": "240,248,255",
24679					"antiquewhite": "250,235,215",
24680					"aquamarine": "127,255,212",
24681					"aqua": "0,255,255",
24682					"azure": "240,255,255",
24683					"beige": "245,245,220",
24684					"bisque": "255,228,196",
24685					"black": "0,0,0",
24686					"blanchedalmond": "255,235,205",
24687					"blueviolet": "138,43,226",
24688					"blue": "0,0,255",
24689					"brown": "165,42,42",
24690					"burlywood": "222,184,135",
24691					"cadetblue": "95,158,160",
24692					"chartreuse": "127,255,0",
24693					"chocolate": "210,105,30",
24694					"coral": "255,127,80",
24695					"cornflowerblue": "100,149,237",
24696					"cornsilk": "255,248,220",
24697					"crimson": "220,20,60",
24698					"cyan": "0,255,255",
24699					"darkblue": "0,0,139",
24700					"darkcyan": "0,139,139",
24701					"darkgoldenrod": "184,134,11",
24702					"darkgray": "169,169,169",
24703					"darkgrey": "169,169,169",
24704					"darkgreen": "0,100,0",
24705					"darkkhaki": "189,183,107",
24706					"darkmagenta": "139,0,139",
24707					"darkolivegreen": "85,107,47",
24708					"darkorange": "255,140,0",
24709					"darkorchid": "153,50,204",
24710					"darkred": "139,0,0",
24711					"darksalmon": "233,150,122",
24712					"darkseagreen": "143,188,143",
24713					"darkslateblue": "72,61,139",
24714					"darkslategray": "47,79,79",
24715					"darkturquoise": "0,206,209",
24716					"darkviolet": "148,0,211",
24717					"deeppink": "255,20,147",
24718					"deepskyblue": "0,191,255",
24719					"dimgray": "105,105,105",
24720					"dimgrey": "105,105,105",
24721					"dodgerblue": "30,144,255",
24722					"firebrick": "178,34,34",
24723					"floralwhite": "255,250,240",
24724					"forestgreen": "34,139,34",
24725					"fuchsia": "255,0,255",
24726					"gainsboro": "220,220,220",
24727					"ghostwhite": "248,248,255",
24728					"gold": "255,215,0",
24729					"goldenrod": "218,165,32",
24730					"gray": "128,128,128",
24731					"grey": "128,128,128",
24732					"greenyellow": "173,255,47",
24733					"green": "0,128,0",
24734					"honeydew": "240,255,240",
24735					"hotpink": "255,105,180",
24736					"indianred": "205,92,92",
24737					"indigo": "75,0,130",
24738					"ivory": "255,255,240",
24739					"khaki": "240,230,140",
24740					"lavenderblush": "255,240,245",
24741					"lavender": "230,230,250",
24742					"lawngreen": "124,252,0",
24743					"lemonchiffon": "255,250,205",
24744					"lightblue": "173,216,230",
24745					"lightcoral": "240,128,128",
24746					"lightcyan": "224,255,255",
24747					"lightgoldenrodyellow": "250,250,210",
24748					"lightgray": "211,211,211",
24749					"lightgrey": "211,211,211",
24750					"lightgreen": "144,238,144",
24751					"lightpink": "255,182,193",
24752					"lightsalmon": "255,160,122",
24753					"lightseagreen": "32,178,170",
24754					"lightskyblue": "135,206,250",
24755					"lightslategray": "119,136,153",
24756					"lightsteelblue": "176,196,222",
24757					"lightyellow": "255,255,224",
24758					"limegreen": "50,205,50",
24759					"lime": "0,255,0",
24760					"linen": "250,240,230",
24761					"magenta": "255,0,255",
24762					"maroon": "128,0,0",
24763					"mediumaquamarine": "102,205,170",
24764					"mediumblue": "0,0,205",
24765					"mediumorchid": "186,85,211",
24766					"mediumpurple": "147,112,219",
24767					"mediumseagreen": "60,179,113",
24768					"mediumslateblue": "123,104,238",
24769					"mediumspringgreen": "0,250,154",
24770					"mediumturquoise": "72,209,204",
24771					"mediumvioletred": "199,21,133",
24772					"midnightblue": "25,25,112",
24773					"mintcream": "245,255,250",
24774					"mistyrose": "255,228,225",
24775					"moccasin": "255,228,181",
24776					"navajowhite": "255,222,173",
24777					"navy": "0,0,128",
24778					"oldlace": "253,245,230",
24779					"olivedrab": "107,142,35",
24780					"olive": "128,128,0",
24781					"orangered": "255,69,0",
24782					"orange": "255,165,0",
24783					"orchid": "218,112,214",
24784					"palegoldenrod": "238,232,170",
24785					"palegreen": "152,251,152",
24786					"paleturquoise": "175,238,238",
24787					"palevioletred": "219,112,147",
24788					"papayawhip": "255,239,213",
24789					"peachpuff": "255,218,185",
24790					"peru": "205,133,63",
24791					"pink": "255,192,203",
24792					"plum": "221,160,221",
24793					"powderblue": "176,224,230",
24794					"purple": "128,0,128",
24795					"red": "255,0,0",
24796					"rosybrown": "188,143,143",
24797					"royalblue": "65,105,225",
24798					"saddlebrown": "139,69,19",
24799					"salmon": "250,128,114",
24800					"sandybrown": "244,164,96",
24801					"seagreen": "46,139,87",
24802					"seashell": "255,245,238",
24803					"sienna": "160,82,45",
24804					"silver": "192,192,192",
24805					"skyblue": "135,206,235",
24806					"slateblue": "106,90,205",
24807					"slategray": "112,128,144",
24808					"snow": "255,250,250",
24809					"springgreen": "0,255,127",
24810					"steelblue": "70,130,180",
24811					"tan": "210,180,140",
24812					"teal": "0,128,128",
24813					"thistle": "216,191,216",
24814					"tomato": "255,99,71",
24815					"turquoise": "64,224,208",
24816					"violet": "238,130,238",
24817					"wheat": "245,222,179",
24818					"whitesmoke": "245,245,245",
24819					"white": "255,255,255",
24820					"yellowgreen": "154,205,50",
24821					"yellow": "255,255,0"
24822				}
24823			},
24824			/************
24825			 Hooks
24826			 ************/
24827
24828			/* Hooks allow a subproperty (e.g. "boxShadowBlur") of a compound-value CSS property
24829			 (e.g. "boxShadow: X Y Blur Spread Color") to be animated as if it were a discrete property. */
24830			/* Note: Beyond enabling fine-grained property animation, hooking is necessary since Velocity only
24831			 tweens properties with single numeric values; unlike CSS transitions, Velocity does not interpolate compound-values. */
24832			Hooks: {
24833				/********************
24834				 Registration
24835				 ********************/
24836
24837				/* Templates are a concise way of indicating which subproperties must be individually registered for each compound-value CSS property. */
24838				/* Each template consists of the compound-value's base name, its constituent subproperty names, and those subproperties' default values. */
24839				templates: {
24840					"textShadow": ["Color X Y Blur", "black 0px 0px 0px"],
24841					"boxShadow": ["Color X Y Blur Spread", "black 0px 0px 0px 0px"],
24842					"clip": ["Top Right Bottom Left", "0px 0px 0px 0px"],
24843					"backgroundPosition": ["X Y", "0% 0%"],
24844					"transformOrigin": ["X Y Z", "50% 50% 0px"],
24845					"perspectiveOrigin": ["X Y", "50% 50%"]
24846				},
24847				/* A "registered" hook is one that has been converted from its template form into a live,
24848				 tweenable property. It contains data to associate it with its root property. */
24849				registered: {
24850					/* Note: A registered hook looks like this ==> textShadowBlur: [ "textShadow", 3 ],
24851					 which consists of the subproperty's name, the associated root property's name,
24852					 and the subproperty's position in the root's value. */
24853				},
24854				/* Convert the templates into individual hooks then append them to the registered object above. */
24855				register: function() {
24856					/* Color hooks registration: Colors are defaulted to white -- as opposed to black -- since colors that are
24857					 currently set to "transparent" default to their respective template below when color-animated,
24858					 and white is typically a closer match to transparent than black is. An exception is made for text ("color"),
24859					 which is almost always set closer to black than white. */
24860					for (var i = 0; i < CSS.Lists.colors.length; i++) {
24861						var rgbComponents = (CSS.Lists.colors[i] === "color") ? "0 0 0 1" : "255 255 255 1";
24862						CSS.Hooks.templates[CSS.Lists.colors[i]] = ["Red Green Blue Alpha", rgbComponents];
24863					}
24864
24865					var rootProperty,
24866							hookTemplate,
24867							hookNames;
24868
24869					/* In IE, color values inside compound-value properties are positioned at the end the value instead of at the beginning.
24870					 Thus, we re-arrange the templates accordingly. */
24871					if (IE) {
24872						for (rootProperty in CSS.Hooks.templates) {
24873							if (!CSS.Hooks.templates.hasOwnProperty(rootProperty)) {
24874								continue;
24875							}
24876							hookTemplate = CSS.Hooks.templates[rootProperty];
24877							hookNames = hookTemplate[0].split(" ");
24878
24879							var defaultValues = hookTemplate[1].match(CSS.RegEx.valueSplit);
24880
24881							if (hookNames[0] === "Color") {
24882								/* Reposition both the hook's name and its default value to the end of their respective strings. */
24883								hookNames.push(hookNames.shift());
24884								defaultValues.push(defaultValues.shift());
24885
24886								/* Replace the existing template for the hook's root property. */
24887								CSS.Hooks.templates[rootProperty] = [hookNames.join(" "), defaultValues.join(" ")];
24888							}
24889						}
24890					}
24891
24892					/* Hook registration. */
24893					for (rootProperty in CSS.Hooks.templates) {
24894						if (!CSS.Hooks.templates.hasOwnProperty(rootProperty)) {
24895							continue;
24896						}
24897						hookTemplate = CSS.Hooks.templates[rootProperty];
24898						hookNames = hookTemplate[0].split(" ");
24899
24900						for (var j in hookNames) {
24901							if (!hookNames.hasOwnProperty(j)) {
24902								continue;
24903							}
24904							var fullHookName = rootProperty + hookNames[j],
24905									hookPosition = j;
24906
24907							/* For each hook, register its full name (e.g. textShadowBlur) with its root property (e.g. textShadow)
24908							 and the hook's position in its template's default value string. */
24909							CSS.Hooks.registered[fullHookName] = [rootProperty, hookPosition];
24910						}
24911					}
24912				},
24913				/*****************************
24914				 Injection and Extraction
24915				 *****************************/
24916
24917				/* Look up the root property associated with the hook (e.g. return "textShadow" for "textShadowBlur"). */
24918				/* Since a hook cannot be set directly (the browser won't recognize it), style updating for hooks is routed through the hook's root property. */
24919				getRoot: function(property) {
24920					var hookData = CSS.Hooks.registered[property];
24921
24922					if (hookData) {
24923						return hookData[0];
24924					} else {
24925						/* If there was no hook match, return the property name untouched. */
24926						return property;
24927					}
24928				},
24929				getUnit: function(str, start) {
24930					var unit = (str.substr(start || 0, 5).match(/^[a-z%]+/) || [])[0] || "";
24931
24932					if (unit && CSS.Lists.units.indexOf(unit) >= 0) {
24933						return unit;
24934					}
24935					return "";
24936				},
24937				fixColors: function(str) {
24938					return str.replace(/(rgba?\(\s*)?(\b[a-z]+\b)/g, function($0, $1, $2) {
24939						if (CSS.Lists.colorNames.hasOwnProperty($2)) {
24940							return ($1 ? $1 : "rgba(") + CSS.Lists.colorNames[$2] + ($1 ? "" : ",1)");
24941						}
24942						return $1 + $2;
24943					});
24944				},
24945				/* Convert any rootPropertyValue, null or otherwise, into a space-delimited list of hook values so that
24946				 the targeted hook can be injected or extracted at its standard position. */
24947				cleanRootPropertyValue: function(rootProperty, rootPropertyValue) {
24948					/* If the rootPropertyValue is wrapped with "rgb()", "clip()", etc., remove the wrapping to normalize the value before manipulation. */
24949					if (CSS.RegEx.valueUnwrap.test(rootPropertyValue)) {
24950						rootPropertyValue = rootPropertyValue.match(CSS.RegEx.valueUnwrap)[1];
24951					}
24952
24953					/* If rootPropertyValue is a CSS null-value (from which there's inherently no hook value to extract),
24954					 default to the root's default value as defined in CSS.Hooks.templates. */
24955					/* Note: CSS null-values include "none", "auto", and "transparent". They must be converted into their
24956					 zero-values (e.g. textShadow: "none" ==> textShadow: "0px 0px 0px black") for hook manipulation to proceed. */
24957					if (CSS.Values.isCSSNullValue(rootPropertyValue)) {
24958						rootPropertyValue = CSS.Hooks.templates[rootProperty][1];
24959					}
24960
24961					return rootPropertyValue;
24962				},
24963				/* Extracted the hook's value from its root property's value. This is used to get the starting value of an animating hook. */
24964				extractValue: function(fullHookName, rootPropertyValue) {
24965					var hookData = CSS.Hooks.registered[fullHookName];
24966
24967					if (hookData) {
24968						var hookRoot = hookData[0],
24969								hookPosition = hookData[1];
24970
24971						rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);
24972
24973						/* Split rootPropertyValue into its constituent hook values then grab the desired hook at its standard position. */
24974						return rootPropertyValue.toString().match(CSS.RegEx.valueSplit)[hookPosition];
24975					} else {
24976						/* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */
24977						return rootPropertyValue;
24978					}
24979				},
24980				/* Inject the hook's value into its root property's value. This is used to piece back together the root property
24981				 once Velocity has updated one of its individually hooked values through tweening. */
24982				injectValue: function(fullHookName, hookValue, rootPropertyValue) {
24983					var hookData = CSS.Hooks.registered[fullHookName];
24984
24985					if (hookData) {
24986						var hookRoot = hookData[0],
24987								hookPosition = hookData[1],
24988								rootPropertyValueParts,
24989								rootPropertyValueUpdated;
24990
24991						rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);
24992
24993						/* Split rootPropertyValue into its individual hook values, replace the targeted value with hookValue,
24994						 then reconstruct the rootPropertyValue string. */
24995						rootPropertyValueParts = rootPropertyValue.toString().match(CSS.RegEx.valueSplit);
24996						rootPropertyValueParts[hookPosition] = hookValue;
24997						rootPropertyValueUpdated = rootPropertyValueParts.join(" ");
24998
24999						return rootPropertyValueUpdated;
25000					} else {
25001						/* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */
25002						return rootPropertyValue;
25003					}
25004				}
25005			},
25006			/*******************
25007			 Normalizations
25008			 *******************/
25009
25010			/* Normalizations standardize CSS property manipulation by pollyfilling browser-specific implementations (e.g. opacity)
25011			 and reformatting special properties (e.g. clip, rgba) to look like standard ones. */
25012			Normalizations: {
25013				/* Normalizations are passed a normalization target (either the property's name, its extracted value, or its injected value),
25014				 the targeted element (which may need to be queried), and the targeted property value. */
25015				registered: {
25016					clip: function(type, element, propertyValue) {
25017						switch (type) {
25018							case "name":
25019								return "clip";
25020								/* Clip needs to be unwrapped and stripped of its commas during extraction. */
25021							case "extract":
25022								var extracted;
25023
25024								/* If Velocity also extracted this value, skip extraction. */
25025								if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {
25026									extracted = propertyValue;
25027								} else {
25028									/* Remove the "rect()" wrapper. */
25029									extracted = propertyValue.toString().match(CSS.RegEx.valueUnwrap);
25030
25031									/* Strip off commas. */
25032									extracted = extracted ? extracted[1].replace(/,(\s+)?/g, " ") : propertyValue;
25033								}
25034
25035								return extracted;
25036								/* Clip needs to be re-wrapped during injection. */
25037							case "inject":
25038								return "rect(" + propertyValue + ")";
25039						}
25040					},
25041					blur: function(type, element, propertyValue) {
25042						switch (type) {
25043							case "name":
25044								return Velocity.State.isFirefox ? "filter" : "-webkit-filter";
25045							case "extract":
25046								var extracted = parseFloat(propertyValue);
25047
25048								/* If extracted is NaN, meaning the value isn't already extracted. */
25049								if (!(extracted || extracted === 0)) {
25050									var blurComponent = propertyValue.toString().match(/blur\(([0-9]+[A-z]+)\)/i);
25051
25052									/* If the filter string had a blur component, return just the blur value and unit type. */
25053									if (blurComponent) {
25054										extracted = blurComponent[1];
25055										/* If the component doesn't exist, default blur to 0. */
25056									} else {
25057										extracted = 0;
25058									}
25059								}
25060
25061								return extracted;
25062								/* Blur needs to be re-wrapped during injection. */
25063							case "inject":
25064								/* For the blur effect to be fully de-applied, it needs to be set to "none" instead of 0. */
25065								if (!parseFloat(propertyValue)) {
25066									return "none";
25067								} else {
25068									return "blur(" + propertyValue + ")";
25069								}
25070						}
25071					},
25072					/* <=IE8 do not support the standard opacity property. They use filter:alpha(opacity=INT) instead. */
25073					opacity: function(type, element, propertyValue) {
25074						if (IE <= 8) {
25075							switch (type) {
25076								case "name":
25077									return "filter";
25078								case "extract":
25079									/* <=IE8 return a "filter" value of "alpha(opacity=\d{1,3})".
25080									 Extract the value and convert it to a decimal value to match the standard CSS opacity property's formatting. */
25081									var extracted = propertyValue.toString().match(/alpha\(opacity=(.*)\)/i);
25082
25083									if (extracted) {
25084										/* Convert to decimal value. */
25085										propertyValue = extracted[1] / 100;
25086									} else {
25087										/* When extracting opacity, default to 1 since a null value means opacity hasn't been set. */
25088										propertyValue = 1;
25089									}
25090
25091									return propertyValue;
25092								case "inject":
25093									/* Opacified elements are required to have their zoom property set to a non-zero value. */
25094									element.style.zoom = 1;
25095
25096									/* Setting the filter property on elements with certain font property combinations can result in a
25097									 highly unappealing ultra-bolding effect. There's no way to remedy this throughout a tween, but dropping the
25098									 value altogether (when opacity hits 1) at leasts ensures that the glitch is gone post-tweening. */
25099									if (parseFloat(propertyValue) >= 1) {
25100										return "";
25101									} else {
25102										/* As per the filter property's spec, convert the decimal value to a whole number and wrap the value. */
25103										return "alpha(opacity=" + parseInt(parseFloat(propertyValue) * 100, 10) + ")";
25104									}
25105							}
25106							/* With all other browsers, normalization is not required; return the same values that were passed in. */
25107						} else {
25108							switch (type) {
25109								case "name":
25110									return "opacity";
25111								case "extract":
25112									return propertyValue;
25113								case "inject":
25114									return propertyValue;
25115							}
25116						}
25117					}
25118				},
25119				/*****************************
25120				 Batched Registrations
25121				 *****************************/
25122
25123				/* Note: Batched normalizations extend the CSS.Normalizations.registered object. */
25124				register: function() {
25125
25126					/*****************
25127					 Transforms
25128					 *****************/
25129
25130					/* Transforms are the subproperties contained by the CSS "transform" property. Transforms must undergo normalization
25131					 so that they can be referenced in a properties map by their individual names. */
25132					/* Note: When transforms are "set", they are actually assigned to a per-element transformCache. When all transform
25133					 setting is complete complete, CSS.flushTransformCache() must be manually called to flush the values to the DOM.
25134					 Transform setting is batched in this way to improve performance: the transform style only needs to be updated
25135					 once when multiple transform subproperties are being animated simultaneously. */
25136					/* Note: IE9 and Android Gingerbread have support for 2D -- but not 3D -- transforms. Since animating unsupported
25137					 transform properties results in the browser ignoring the *entire* transform string, we prevent these 3D values
25138					 from being normalized for these browsers so that tweening skips these properties altogether
25139					 (since it will ignore them as being unsupported by the browser.) */
25140					if ((!IE || IE > 9) && !Velocity.State.isGingerbread) {
25141						/* Note: Since the standalone CSS "perspective" property and the CSS transform "perspective" subproperty
25142						 share the same name, the latter is given a unique token within Velocity: "transformPerspective". */
25143						CSS.Lists.transformsBase = CSS.Lists.transformsBase.concat(CSS.Lists.transforms3D);
25144					}
25145
25146					for (var i = 0; i < CSS.Lists.transformsBase.length; i++) {
25147						/* Wrap the dynamically generated normalization function in a new scope so that transformName's value is
25148						 paired with its respective function. (Otherwise, all functions would take the final for loop's transformName.) */
25149						(function() {
25150							var transformName = CSS.Lists.transformsBase[i];
25151
25152							CSS.Normalizations.registered[transformName] = function(type, element, propertyValue) {
25153								switch (type) {
25154									/* The normalized property name is the parent "transform" property -- the property that is actually set in CSS. */
25155									case "name":
25156										return "transform";
25157										/* Transform values are cached onto a per-element transformCache object. */
25158									case "extract":
25159										/* If this transform has yet to be assigned a value, return its null value. */
25160										if (Data(element) === undefined || Data(element).transformCache[transformName] === undefined) {
25161											/* Scale CSS.Lists.transformsBase default to 1 whereas all other transform properties default to 0. */
25162											return /^scale/i.test(transformName) ? 1 : 0;
25163											/* When transform values are set, they are wrapped in parentheses as per the CSS spec.
25164											 Thus, when extracting their values (for tween calculations), we strip off the parentheses. */
25165										}
25166										return Data(element).transformCache[transformName].replace(/[()]/g, "");
25167									case "inject":
25168										var invalid = false;
25169
25170										/* If an individual transform property contains an unsupported unit type, the browser ignores the *entire* transform property.
25171										 Thus, protect users from themselves by skipping setting for transform values supplied with invalid unit types. */
25172										/* Switch on the base transform type; ignore the axis by removing the last letter from the transform's name. */
25173										switch (transformName.substr(0, transformName.length - 1)) {
25174											/* Whitelist unit types for each transform. */
25175											case "translate":
25176												invalid = !/(%|px|em|rem|vw|vh|\d)$/i.test(propertyValue);
25177												break;
25178												/* Since an axis-free "scale" property is supported as well, a little hack is used here to detect it by chopping off its last letter. */
25179											case "scal":
25180											case "scale":
25181												/* Chrome on Android has a bug in which scaled elements blur if their initial scale
25182												 value is below 1 (which can happen with forcefeeding). Thus, we detect a yet-unset scale property
25183												 and ensure that its first value is always 1. More info: http://stackoverflow.com/questions/10417890/css3-animations-with-transform-causes-blurred-elements-on-webkit/10417962#10417962 */
25184												if (Velocity.State.isAndroid && Data(element).transformCache[transformName] === undefined && propertyValue < 1) {
25185													propertyValue = 1;
25186												}
25187
25188												invalid = !/(\d)$/i.test(propertyValue);
25189												break;
25190											case "skew":
25191												invalid = !/(deg|\d)$/i.test(propertyValue);
25192												break;
25193											case "rotate":
25194												invalid = !/(deg|\d)$/i.test(propertyValue);
25195												break;
25196										}
25197
25198										if (!invalid) {
25199											/* As per the CSS spec, wrap the value in parentheses. */
25200											Data(element).transformCache[transformName] = "(" + propertyValue + ")";
25201										}
25202
25203										/* Although the value is set on the transformCache object, return the newly-updated value for the calling code to process as normal. */
25204										return Data(element).transformCache[transformName];
25205								}
25206							};
25207						})();
25208					}
25209
25210					/*************
25211					 Colors
25212					 *************/
25213
25214					/* Since Velocity only animates a single numeric value per property, color animation is achieved by hooking the individual RGBA components of CSS color properties.
25215					 Accordingly, color values must be normalized (e.g. "#ff0000", "red", and "rgb(255, 0, 0)" ==> "255 0 0 1") so that their components can be injected/extracted by CSS.Hooks logic. */
25216					for (var j = 0; j < CSS.Lists.colors.length; j++) {
25217						/* Wrap the dynamically generated normalization function in a new scope so that colorName's value is paired with its respective function.
25218						 (Otherwise, all functions would take the final for loop's colorName.) */
25219						(function() {
25220							var colorName = CSS.Lists.colors[j];
25221
25222							/* Note: In IE<=8, which support rgb but not rgba, color properties are reverted to rgb by stripping off the alpha component. */
25223							CSS.Normalizations.registered[colorName] = function(type, element, propertyValue) {
25224								switch (type) {
25225									case "name":
25226										return colorName;
25227										/* Convert all color values into the rgb format. (Old IE can return hex values and color names instead of rgb/rgba.) */
25228									case "extract":
25229										var extracted;
25230
25231										/* If the color is already in its hookable form (e.g. "255 255 255 1") due to having been previously extracted, skip extraction. */
25232										if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {
25233											extracted = propertyValue;
25234										} else {
25235											var converted,
25236													colorNames = {
25237														black: "rgb(0, 0, 0)",
25238														blue: "rgb(0, 0, 255)",
25239														gray: "rgb(128, 128, 128)",
25240														green: "rgb(0, 128, 0)",
25241														red: "rgb(255, 0, 0)",
25242														white: "rgb(255, 255, 255)"
25243													};
25244
25245											/* Convert color names to rgb. */
25246											if (/^[A-z]+$/i.test(propertyValue)) {
25247												if (colorNames[propertyValue] !== undefined) {
25248													converted = colorNames[propertyValue];
25249												} else {
25250													/* If an unmatched color name is provided, default to black. */
25251													converted = colorNames.black;
25252												}
25253												/* Convert hex values to rgb. */
25254											} else if (CSS.RegEx.isHex.test(propertyValue)) {
25255												converted = "rgb(" + CSS.Values.hexToRgb(propertyValue).join(" ") + ")";
25256												/* If the provided color doesn't match any of the accepted color formats, default to black. */
25257											} else if (!(/^rgba?\(/i.test(propertyValue))) {
25258												converted = colorNames.black;
25259											}
25260
25261											/* Remove the surrounding "rgb/rgba()" string then replace commas with spaces and strip
25262											 repeated spaces (in case the value included spaces to begin with). */
25263											extracted = (converted || propertyValue).toString().match(CSS.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g, " ");
25264										}
25265
25266										/* So long as this isn't <=IE8, add a fourth (alpha) component if it's missing and default it to 1 (visible). */
25267										if ((!IE || IE > 8) && extracted.split(" ").length === 3) {
25268											extracted += " 1";
25269										}
25270
25271										return extracted;
25272									case "inject":
25273										/* If we have a pattern then it might already have the right values */
25274										if (/^rgb/.test(propertyValue)) {
25275											return propertyValue;
25276										}
25277
25278										/* If this is IE<=8 and an alpha component exists, strip it off. */
25279										if (IE <= 8) {
25280											if (propertyValue.split(" ").length === 4) {
25281												propertyValue = propertyValue.split(/\s+/).slice(0, 3).join(" ");
25282											}
25283											/* Otherwise, add a fourth (alpha) component if it's missing and default it to 1 (visible). */
25284										} else if (propertyValue.split(" ").length === 3) {
25285											propertyValue += " 1";
25286										}
25287
25288										/* Re-insert the browser-appropriate wrapper("rgb/rgba()"), insert commas, and strip off decimal units
25289										 on all values but the fourth (R, G, and B only accept whole numbers). */
25290										return (IE <= 8 ? "rgb" : "rgba") + "(" + propertyValue.replace(/\s+/g, ",").replace(/\.(\d)+(?=,)/g, "") + ")";
25291								}
25292							};
25293						})();
25294					}
25295
25296					/**************
25297					 Dimensions
25298					 **************/
25299					function augmentDimension(name, element, wantInner) {
25300						var isBorderBox = CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() === "border-box";
25301
25302						if (isBorderBox === (wantInner || false)) {
25303							/* in box-sizing mode, the CSS width / height accessors already give the outerWidth / outerHeight. */
25304							var i,
25305									value,
25306									augment = 0,
25307									sides = name === "width" ? ["Left", "Right"] : ["Top", "Bottom"],
25308									fields = ["padding" + sides[0], "padding" + sides[1], "border" + sides[0] + "Width", "border" + sides[1] + "Width"];
25309
25310							for (i = 0; i < fields.length; i++) {
25311								value = parseFloat(CSS.getPropertyValue(element, fields[i]));
25312								if (!isNaN(value)) {
25313									augment += value;
25314								}
25315							}
25316							return wantInner ? -augment : augment;
25317						}
25318						return 0;
25319					}
25320					function getDimension(name, wantInner) {
25321						return function(type, element, propertyValue) {
25322							switch (type) {
25323								case "name":
25324									return name;
25325								case "extract":
25326									return parseFloat(propertyValue) + augmentDimension(name, element, wantInner);
25327								case "inject":
25328									return (parseFloat(propertyValue) - augmentDimension(name, element, wantInner)) + "px";
25329							}
25330						};
25331					}
25332					CSS.Normalizations.registered.innerWidth = getDimension("width", true);
25333					CSS.Normalizations.registered.innerHeight = getDimension("height", true);
25334					CSS.Normalizations.registered.outerWidth = getDimension("width");
25335					CSS.Normalizations.registered.outerHeight = getDimension("height");
25336				}
25337			},
25338			/************************
25339			 CSS Property Names
25340			 ************************/
25341
25342			Names: {
25343				/* Camelcase a property name into its JavaScript notation (e.g. "background-color" ==> "backgroundColor").
25344				 Camelcasing is used to normalize property names between and across calls. */
25345				camelCase: function(property) {
25346					return property.replace(/-(\w)/g, function(match, subMatch) {
25347						return subMatch.toUpperCase();
25348					});
25349				},
25350				/* For SVG elements, some properties (namely, dimensional ones) are GET/SET via the element's HTML attributes (instead of via CSS styles). */
25351				SVGAttribute: function(property) {
25352					var SVGAttributes = "width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";
25353
25354					/* Certain browsers require an SVG transform to be applied as an attribute. (Otherwise, application via CSS is preferable due to 3D support.) */
25355					if (IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) {
25356						SVGAttributes += "|transform";
25357					}
25358
25359					return new RegExp("^(" + SVGAttributes + ")$", "i").test(property);
25360				},
25361				/* Determine whether a property should be set with a vendor prefix. */
25362				/* If a prefixed version of the property exists, return it. Otherwise, return the original property name.
25363				 If the property is not at all supported by the browser, return a false flag. */
25364				prefixCheck: function(property) {
25365					/* If this property has already been checked, return the cached value. */
25366					if (Velocity.State.prefixMatches[property]) {
25367						return [Velocity.State.prefixMatches[property], true];
25368					} else {
25369						var vendors = ["", "Webkit", "Moz", "ms", "O"];
25370
25371						for (var i = 0, vendorsLength = vendors.length; i < vendorsLength; i++) {
25372							var propertyPrefixed;
25373
25374							if (i === 0) {
25375								propertyPrefixed = property;
25376							} else {
25377								/* Capitalize the first letter of the property to conform to JavaScript vendor prefix notation (e.g. webkitFilter). */
25378								propertyPrefixed = vendors[i] + property.replace(/^\w/, function(match) {
25379									return match.toUpperCase();
25380								});
25381							}
25382
25383							/* Check if the browser supports this property as prefixed. */
25384							if (Type.isString(Velocity.State.prefixElement.style[propertyPrefixed])) {
25385								/* Cache the match. */
25386								Velocity.State.prefixMatches[property] = propertyPrefixed;
25387
25388								return [propertyPrefixed, true];
25389							}
25390						}
25391
25392						/* If the browser doesn't support this property in any form, include a false flag so that the caller can decide how to proceed. */
25393						return [property, false];
25394					}
25395				}
25396			},
25397			/************************
25398			 CSS Property Values
25399			 ************************/
25400
25401			Values: {
25402				/* Hex to RGB conversion. Copyright Tim Down: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb */
25403				hexToRgb: function(hex) {
25404					var shortformRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i,
25405							longformRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,
25406							rgbParts;
25407
25408					hex = hex.replace(shortformRegex, function(m, r, g, b) {
25409						return r + r + g + g + b + b;
25410					});
25411
25412					rgbParts = longformRegex.exec(hex);
25413
25414					return rgbParts ? [parseInt(rgbParts[1], 16), parseInt(rgbParts[2], 16), parseInt(rgbParts[3], 16)] : [0, 0, 0];
25415				},
25416				isCSSNullValue: function(value) {
25417					/* The browser defaults CSS values that have not been set to either 0 or one of several possible null-value strings.
25418					 Thus, we check for both falsiness and these special strings. */
25419					/* Null-value checking is performed to default the special strings to 0 (for the sake of tweening) or their hook
25420					 templates as defined as CSS.Hooks (for the sake of hook injection/extraction). */
25421					/* Note: Chrome returns "rgba(0, 0, 0, 0)" for an undefined color whereas IE returns "transparent". */
25422					return (!value || /^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(value));
25423				},
25424				/* Retrieve a property's default unit type. Used for assigning a unit type when one is not supplied by the user. */
25425				getUnitType: function(property) {
25426					if (/^(rotate|skew)/i.test(property)) {
25427						return "deg";
25428					} else if (/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(property)) {
25429						/* The above properties are unitless. */
25430						return "";
25431					} else {
25432						/* Default to px for all other properties. */
25433						return "px";
25434					}
25435				},
25436				/* HTML elements default to an associated display type when they're not set to display:none. */
25437				/* Note: This function is used for correctly setting the non-"none" display value in certain Velocity redirects, such as fadeIn/Out. */
25438				getDisplayType: function(element) {
25439					var tagName = element && element.tagName.toString().toLowerCase();
25440
25441					if (/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(tagName)) {
25442						return "inline";
25443					} else if (/^(li)$/i.test(tagName)) {
25444						return "list-item";
25445					} else if (/^(tr)$/i.test(tagName)) {
25446						return "table-row";
25447					} else if (/^(table)$/i.test(tagName)) {
25448						return "table";
25449					} else if (/^(tbody)$/i.test(tagName)) {
25450						return "table-row-group";
25451						/* Default to "block" when no match is found. */
25452					} else {
25453						return "block";
25454					}
25455				},
25456				/* The class add/remove functions are used to temporarily apply a "velocity-animating" class to elements while they're animating. */
25457				addClass: function(element, className) {
25458					if (element) {
25459						if (element.classList) {
25460							element.classList.add(className);
25461						} else if (Type.isString(element.className)) {
25462							// Element.className is around 15% faster then set/getAttribute
25463							element.className += (element.className.length ? " " : "") + className;
25464						} else {
25465							// Work around for IE strict mode animating SVG - and anything else that doesn't behave correctly - the same way jQuery does it
25466							var currentClass = element.getAttribute(IE <= 7 ? "className" : "class") || "";
25467
25468							element.setAttribute("class", currentClass + (currentClass ? " " : "") + className);
25469						}
25470					}
25471				},
25472				removeClass: function(element, className) {
25473					if (element) {
25474						if (element.classList) {
25475							element.classList.remove(className);
25476						} else if (Type.isString(element.className)) {
25477							// Element.className is around 15% faster then set/getAttribute
25478							// TODO: Need some jsperf tests on performance - can we get rid of the regex and maybe use split / array manipulation?
25479							element.className = element.className.toString().replace(new RegExp("(^|\\s)" + className.split(" ").join("|") + "(\\s|$)", "gi"), " ");
25480						} else {
25481							// Work around for IE strict mode animating SVG - and anything else that doesn't behave correctly - the same way jQuery does it
25482							var currentClass = element.getAttribute(IE <= 7 ? "className" : "class") || "";
25483
25484							element.setAttribute("class", currentClass.replace(new RegExp("(^|\s)" + className.split(" ").join("|") + "(\s|$)", "gi"), " "));
25485						}
25486					}
25487				}
25488			},
25489			/****************************
25490			 Style Getting & Setting
25491			 ****************************/
25492
25493			/* The singular getPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */
25494			getPropertyValue: function(element, property, rootPropertyValue, forceStyleLookup) {
25495				/* Get an element's computed property value. */
25496				/* Note: Retrieving the value of a CSS property cannot simply be performed by checking an element's
25497				 style attribute (which only reflects user-defined values). Instead, the browser must be queried for a property's
25498				 *computed* value. You can read more about getComputedStyle here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */
25499				function computePropertyValue(element, property) {
25500					/* When box-sizing isn't set to border-box, height and width style values are incorrectly computed when an
25501					 element's scrollbars are visible (which expands the element's dimensions). Thus, we defer to the more accurate
25502					 offsetHeight/Width property, which includes the total dimensions for interior, border, padding, and scrollbar.
25503					 We subtract border and padding to get the sum of interior + scrollbar. */
25504					var computedValue = 0;
25505
25506					/* IE<=8 doesn't support window.getComputedStyle, thus we defer to jQuery, which has an extensive array
25507					 of hacks to accurately retrieve IE8 property values. Re-implementing that logic here is not worth bloating the
25508					 codebase for a dying browser. The performance repercussions of using jQuery here are minimal since
25509					 Velocity is optimized to rarely (and sometimes never) query the DOM. Further, the $.css() codepath isn't that slow. */
25510					if (IE <= 8) {
25511						computedValue = $.css(element, property); /* GET */
25512						/* All other browsers support getComputedStyle. The returned live object reference is cached onto its
25513						 associated element so that it does not need to be refetched upon every GET. */
25514					} else {
25515						/* Browsers do not return height and width values for elements that are set to display:"none". Thus, we temporarily
25516						 toggle display to the element type's default value. */
25517						var toggleDisplay = false;
25518
25519						if (/^(width|height)$/.test(property) && CSS.getPropertyValue(element, "display") === 0) {
25520							toggleDisplay = true;
25521							CSS.setPropertyValue(element, "display", CSS.Values.getDisplayType(element));
25522						}
25523
25524						var revertDisplay = function() {
25525							if (toggleDisplay) {
25526								CSS.setPropertyValue(element, "display", "none");
25527							}
25528						};
25529
25530						if (!forceStyleLookup) {
25531							if (property === "height" && CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() !== "border-box") {
25532								var contentBoxHeight = element.offsetHeight - (parseFloat(CSS.getPropertyValue(element, "borderTopWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "borderBottomWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingTop")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingBottom")) || 0);
25533								revertDisplay();
25534
25535								return contentBoxHeight;
25536							} else if (property === "width" && CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() !== "border-box") {
25537								var contentBoxWidth = element.offsetWidth - (parseFloat(CSS.getPropertyValue(element, "borderLeftWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "borderRightWidth")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingLeft")) || 0) - (parseFloat(CSS.getPropertyValue(element, "paddingRight")) || 0);
25538								revertDisplay();
25539
25540								return contentBoxWidth;
25541							}
25542						}
25543
25544						var computedStyle;
25545
25546						/* For elements that Velocity hasn't been called on directly (e.g. when Velocity queries the DOM on behalf
25547						 of a parent of an element its animating), perform a direct getComputedStyle lookup since the object isn't cached. */
25548						if (Data(element) === undefined) {
25549							computedStyle = window.getComputedStyle(element, null); /* GET */
25550							/* If the computedStyle object has yet to be cached, do so now. */
25551						} else if (!Data(element).computedStyle) {
25552							computedStyle = Data(element).computedStyle = window.getComputedStyle(element, null); /* GET */
25553							/* If computedStyle is cached, use it. */
25554						} else {
25555							computedStyle = Data(element).computedStyle;
25556						}
25557
25558						/* IE and Firefox do not return a value for the generic borderColor -- they only return individual values for each border side's color.
25559						 Also, in all browsers, when border colors aren't all the same, a compound value is returned that Velocity isn't setup to parse.
25560						 So, as a polyfill for querying individual border side colors, we just return the top border's color and animate all borders from that value. */
25561						if (property === "borderColor") {
25562							property = "borderTopColor";
25563						}
25564
25565						/* IE9 has a bug in which the "filter" property must be accessed from computedStyle using the getPropertyValue method
25566						 instead of a direct property lookup. The getPropertyValue method is slower than a direct lookup, which is why we avoid it by default. */
25567						if (IE === 9 && property === "filter") {
25568							computedValue = computedStyle.getPropertyValue(property); /* GET */
25569						} else {
25570							computedValue = computedStyle[property];
25571						}
25572
25573						/* Fall back to the property's style value (if defined) when computedValue returns nothing,
25574						 which can happen when the element hasn't been painted. */
25575						if (computedValue === "" || computedValue === null) {
25576							computedValue = element.style[property];
25577						}
25578
25579						revertDisplay();
25580					}
25581
25582					/* For top, right, bottom, and left (TRBL) values that are set to "auto" on elements of "fixed" or "absolute" position,
25583					 defer to jQuery for converting "auto" to a numeric value. (For elements with a "static" or "relative" position, "auto" has the same
25584					 effect as being set to 0, so no conversion is necessary.) */
25585					/* An example of why numeric conversion is necessary: When an element with "position:absolute" has an untouched "left"
25586					 property, which reverts to "auto", left's value is 0 relative to its parent element, but is often non-zero relative
25587					 to its *containing* (not parent) element, which is the nearest "position:relative" ancestor or the viewport (and always the viewport in the case of "position:fixed"). */
25588					if (computedValue === "auto" && /^(top|right|bottom|left)$/i.test(property)) {
25589						var position = computePropertyValue(element, "position"); /* GET */
25590
25591						/* For absolute positioning, jQuery's $.position() only returns values for top and left;
25592						 right and bottom will have their "auto" value reverted to 0. */
25593						/* Note: A jQuery object must be created here since jQuery doesn't have a low-level alias for $.position().
25594						 Not a big deal since we're currently in a GET batch anyway. */
25595						if (position === "fixed" || (position === "absolute" && /top|left/i.test(property))) {
25596							/* Note: jQuery strips the pixel unit from its returned values; we re-add it here to conform with computePropertyValue's behavior. */
25597							computedValue = $(element).position()[property] + "px"; /* GET */
25598						}
25599					}
25600
25601					return computedValue;
25602				}
25603
25604				var propertyValue;
25605
25606				/* If this is a hooked property (e.g. "clipLeft" instead of the root property of "clip"),
25607				 extract the hook's value from a normalized rootPropertyValue using CSS.Hooks.extractValue(). */
25608				if (CSS.Hooks.registered[property]) {
25609					var hook = property,
25610							hookRoot = CSS.Hooks.getRoot(hook);
25611
25612					/* If a cached rootPropertyValue wasn't passed in (which Velocity always attempts to do in order to avoid requerying the DOM),
25613					 query the DOM for the root property's value. */
25614					if (rootPropertyValue === undefined) {
25615						/* Since the browser is now being directly queried, use the official post-prefixing property name for this lookup. */
25616						rootPropertyValue = CSS.getPropertyValue(element, CSS.Names.prefixCheck(hookRoot)[0]); /* GET */
25617					}
25618
25619					/* If this root has a normalization registered, peform the associated normalization extraction. */
25620					if (CSS.Normalizations.registered[hookRoot]) {
25621						rootPropertyValue = CSS.Normalizations.registered[hookRoot]("extract", element, rootPropertyValue);
25622					}
25623
25624					/* Extract the hook's value. */
25625					propertyValue = CSS.Hooks.extractValue(hook, rootPropertyValue);
25626
25627					/* If this is a normalized property (e.g. "opacity" becomes "filter" in <=IE8) or "translateX" becomes "transform"),
25628					 normalize the property's name and value, and handle the special case of transforms. */
25629					/* Note: Normalizing a property is mutually exclusive from hooking a property since hook-extracted values are strictly
25630					 numerical and therefore do not require normalization extraction. */
25631				} else if (CSS.Normalizations.registered[property]) {
25632					var normalizedPropertyName,
25633							normalizedPropertyValue;
25634
25635					normalizedPropertyName = CSS.Normalizations.registered[property]("name", element);
25636
25637					/* Transform values are calculated via normalization extraction (see below), which checks against the element's transformCache.
25638					 At no point do transform GETs ever actually query the DOM; initial stylesheet values are never processed.
25639					 This is because parsing 3D transform matrices is not always accurate and would bloat our codebase;
25640					 thus, normalization extraction defaults initial transform values to their zero-values (e.g. 1 for scaleX and 0 for translateX). */
25641					if (normalizedPropertyName !== "transform") {
25642						normalizedPropertyValue = computePropertyValue(element, CSS.Names.prefixCheck(normalizedPropertyName)[0]); /* GET */
25643
25644						/* If the value is a CSS null-value and this property has a hook template, use that zero-value template so that hooks can be extracted from it. */
25645						if (CSS.Values.isCSSNullValue(normalizedPropertyValue) && CSS.Hooks.templates[property]) {
25646							normalizedPropertyValue = CSS.Hooks.templates[property][1];
25647						}
25648					}
25649
25650					propertyValue = CSS.Normalizations.registered[property]("extract", element, normalizedPropertyValue);
25651				}
25652
25653				/* If a (numeric) value wasn't produced via hook extraction or normalization, query the DOM. */
25654				if (!/^[\d-]/.test(propertyValue)) {
25655					/* For SVG elements, dimensional properties (which SVGAttribute() detects) are tweened via
25656					 their HTML attribute values instead of their CSS style values. */
25657					var data = Data(element);
25658
25659					if (data && data.isSVG && CSS.Names.SVGAttribute(property)) {
25660						/* Since the height/width attribute values must be set manually, they don't reflect computed values.
25661						 Thus, we use use getBBox() to ensure we always get values for elements with undefined height/width attributes. */
25662						if (/^(height|width)$/i.test(property)) {
25663							/* Firefox throws an error if .getBBox() is called on an SVG that isn't attached to the DOM. */
25664							try {
25665								propertyValue = element.getBBox()[property];
25666							} catch (error) {
25667								propertyValue = 0;
25668							}
25669							/* Otherwise, access the attribute value directly. */
25670						} else {
25671							propertyValue = element.getAttribute(property);
25672						}
25673					} else {
25674						propertyValue = computePropertyValue(element, CSS.Names.prefixCheck(property)[0]); /* GET */
25675					}
25676				}
25677
25678				/* Since property lookups are for animation purposes (which entails computing the numeric delta between start and end values),
25679				 convert CSS null-values to an integer of value 0. */
25680				if (CSS.Values.isCSSNullValue(propertyValue)) {
25681					propertyValue = 0;
25682				}
25683
25684				if (Velocity.debug >= 2) {
25685					console.log("Get " + property + ": " + propertyValue);
25686				}
25687
25688				return propertyValue;
25689			},
25690			/* The singular setPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */
25691			setPropertyValue: function(element, property, propertyValue, rootPropertyValue, scrollData) {
25692				var propertyName = property;
25693
25694				/* In order to be subjected to call options and element queueing, scroll animation is routed through Velocity as if it were a standard CSS property. */
25695				if (property === "scroll") {
25696					/* If a container option is present, scroll the container instead of the browser window. */
25697					if (scrollData.container) {
25698						scrollData.container["scroll" + scrollData.direction] = propertyValue;
25699						/* Otherwise, Velocity defaults to scrolling the browser window. */
25700					} else {
25701						if (scrollData.direction === "Left") {
25702							window.scrollTo(propertyValue, scrollData.alternateValue);
25703						} else {
25704							window.scrollTo(scrollData.alternateValue, propertyValue);
25705						}
25706					}
25707				} else {
25708					/* Transforms (translateX, rotateZ, etc.) are applied to a per-element transformCache object, which is manually flushed via flushTransformCache().
25709					 Thus, for now, we merely cache transforms being SET. */
25710					if (CSS.Normalizations.registered[property] && CSS.Normalizations.registered[property]("name", element) === "transform") {
25711						/* Perform a normalization injection. */
25712						/* Note: The normalization logic handles the transformCache updating. */
25713						CSS.Normalizations.registered[property]("inject", element, propertyValue);
25714
25715						propertyName = "transform";
25716						propertyValue = Data(element).transformCache[property];
25717					} else {
25718						/* Inject hooks. */
25719						if (CSS.Hooks.registered[property]) {
25720							var hookName = property,
25721									hookRoot = CSS.Hooks.getRoot(property);
25722
25723							/* If a cached rootPropertyValue was not provided, query the DOM for the hookRoot's current value. */
25724							rootPropertyValue = rootPropertyValue || CSS.getPropertyValue(element, hookRoot); /* GET */
25725
25726							propertyValue = CSS.Hooks.injectValue(hookName, propertyValue, rootPropertyValue);
25727							property = hookRoot;
25728						}
25729
25730						/* Normalize names and values. */
25731						if (CSS.Normalizations.registered[property]) {
25732							propertyValue = CSS.Normalizations.registered[property]("inject", element, propertyValue);
25733							property = CSS.Normalizations.registered[property]("name", element);
25734						}
25735
25736						/* Assign the appropriate vendor prefix before performing an official style update. */
25737						propertyName = CSS.Names.prefixCheck(property)[0];
25738
25739						/* A try/catch is used for IE<=8, which throws an error when "invalid" CSS values are set, e.g. a negative width.
25740						 Try/catch is avoided for other browsers since it incurs a performance overhead. */
25741						if (IE <= 8) {
25742							try {
25743								element.style[propertyName] = propertyValue;
25744							} catch (error) {
25745								if (Velocity.debug) {
25746									console.log("Browser does not support [" + propertyValue + "] for [" + propertyName + "]");
25747								}
25748							}
25749							/* SVG elements have their dimensional properties (width, height, x, y, cx, etc.) applied directly as attributes instead of as styles. */
25750							/* Note: IE8 does not support SVG elements, so it's okay that we skip it for SVG animation. */
25751						} else {
25752							var data = Data(element);
25753
25754							if (data && data.isSVG && CSS.Names.SVGAttribute(property)) {
25755								/* Note: For SVG attributes, vendor-prefixed property names are never used. */
25756								/* Note: Not all CSS properties can be animated via attributes, but the browser won't throw an error for unsupported properties. */
25757								element.setAttribute(property, propertyValue);
25758							} else {
25759								element.style[propertyName] = propertyValue;
25760							}
25761						}
25762
25763						if (Velocity.debug >= 2) {
25764							console.log("Set " + property + " (" + propertyName + "): " + propertyValue);
25765						}
25766					}
25767				}
25768
25769				/* Return the normalized property name and value in case the caller wants to know how these values were modified before being applied to the DOM. */
25770				return [propertyName, propertyValue];
25771			},
25772			/* To increase performance by batching transform updates into a single SET, transforms are not directly applied to an element until flushTransformCache() is called. */
25773			/* Note: Velocity applies transform properties in the same order that they are chronogically introduced to the element's CSS styles. */
25774			flushTransformCache: function(element) {
25775				var transformString = "",
25776						data = Data(element);
25777
25778				/* Certain browsers require that SVG transforms be applied as an attribute. However, the SVG transform attribute takes a modified version of CSS's transform string
25779				 (units are dropped and, except for skewX/Y, subproperties are merged into their master property -- e.g. scaleX and scaleY are merged into scale(X Y). */
25780				if ((IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) && data && data.isSVG) {
25781					/* Since transform values are stored in their parentheses-wrapped form, we use a helper function to strip out their numeric values.
25782					 Further, SVG transform properties only take unitless (representing pixels) values, so it's okay that parseFloat() strips the unit suffixed to the float value. */
25783					var getTransformFloat = function(transformProperty) {
25784						return parseFloat(CSS.getPropertyValue(element, transformProperty));
25785					};
25786
25787					/* Create an object to organize all the transforms that we'll apply to the SVG element. To keep the logic simple,
25788					 we process *all* transform properties -- even those that may not be explicitly applied (since they default to their zero-values anyway). */
25789					var SVGTransforms = {
25790						translate: [getTransformFloat("translateX"), getTransformFloat("translateY")],
25791						skewX: [getTransformFloat("skewX")], skewY: [getTransformFloat("skewY")],
25792						/* If the scale property is set (non-1), use that value for the scaleX and scaleY values
25793						 (this behavior mimics the result of animating all these properties at once on HTML elements). */
25794						scale: getTransformFloat("scale") !== 1 ? [getTransformFloat("scale"), getTransformFloat("scale")] : [getTransformFloat("scaleX"), getTransformFloat("scaleY")],
25795						/* Note: SVG's rotate transform takes three values: rotation degrees followed by the X and Y values
25796						 defining the rotation's origin point. We ignore the origin values (default them to 0). */
25797						rotate: [getTransformFloat("rotateZ"), 0, 0]
25798					};
25799
25800					/* Iterate through the transform properties in the user-defined property map order.
25801					 (This mimics the behavior of non-SVG transform animation.) */
25802					$.each(Data(element).transformCache, function(transformName) {
25803						/* Except for with skewX/Y, revert the axis-specific transform subproperties to their axis-free master
25804						 properties so that they match up with SVG's accepted transform properties. */
25805						if (/^translate/i.test(transformName)) {
25806							transformName = "translate";
25807						} else if (/^scale/i.test(transformName)) {
25808							transformName = "scale";
25809						} else if (/^rotate/i.test(transformName)) {
25810							transformName = "rotate";
25811						}
25812
25813						/* Check that we haven't yet deleted the property from the SVGTransforms container. */
25814						if (SVGTransforms[transformName]) {
25815							/* Append the transform property in the SVG-supported transform format. As per the spec, surround the space-delimited values in parentheses. */
25816							transformString += transformName + "(" + SVGTransforms[transformName].join(" ") + ")" + " ";
25817
25818							/* After processing an SVG transform property, delete it from the SVGTransforms container so we don't
25819							 re-insert the same master property if we encounter another one of its axis-specific properties. */
25820							delete SVGTransforms[transformName];
25821						}
25822					});
25823				} else {
25824					var transformValue,
25825							perspective;
25826
25827					/* Transform properties are stored as members of the transformCache object. Concatenate all the members into a string. */
25828					$.each(Data(element).transformCache, function(transformName) {
25829						transformValue = Data(element).transformCache[transformName];
25830
25831						/* Transform's perspective subproperty must be set first in order to take effect. Store it temporarily. */
25832						if (transformName === "transformPerspective") {
25833							perspective = transformValue;
25834							return true;
25835						}
25836
25837						/* IE9 only supports one rotation type, rotateZ, which it refers to as "rotate". */
25838						if (IE === 9 && transformName === "rotateZ") {
25839							transformName = "rotate";
25840						}
25841
25842						transformString += transformName + transformValue + " ";
25843					});
25844
25845					/* If present, set the perspective subproperty first. */
25846					if (perspective) {
25847						transformString = "perspective" + perspective + " " + transformString;
25848					}
25849				}
25850
25851				CSS.setPropertyValue(element, "transform", transformString);
25852			}
25853		};
25854
25855		/* Register hooks and normalizations. */
25856		CSS.Hooks.register();
25857		CSS.Normalizations.register();
25858
25859		/* Allow hook setting in the same fashion as jQuery's $.css(). */
25860		Velocity.hook = function(elements, arg2, arg3) {
25861			var value;
25862
25863			elements = sanitizeElements(elements);
25864
25865			$.each(elements, function(i, element) {
25866				/* Initialize Velocity's per-element data cache if this element hasn't previously been animated. */
25867				if (Data(element) === undefined) {
25868					Velocity.init(element);
25869				}
25870
25871				/* Get property value. If an element set was passed in, only return the value for the first element. */
25872				if (arg3 === undefined) {
25873					if (value === undefined) {
25874						value = CSS.getPropertyValue(element, arg2);
25875					}
25876					/* Set property value. */
25877				} else {
25878					/* sPV returns an array of the normalized propertyName/propertyValue pair used to update the DOM. */
25879					var adjustedSet = CSS.setPropertyValue(element, arg2, arg3);
25880
25881					/* Transform properties don't automatically set. They have to be flushed to the DOM. */
25882					if (adjustedSet[0] === "transform") {
25883						Velocity.CSS.flushTransformCache(element);
25884					}
25885
25886					value = adjustedSet;
25887				}
25888			});
25889
25890			return value;
25891		};
25892
25893		/*****************
25894		 Animation
25895		 *****************/
25896
25897		var animate = function() {
25898			var opts;
25899
25900			/******************
25901			 Call Chain
25902			 ******************/
25903
25904			/* Logic for determining what to return to the call stack when exiting out of Velocity. */
25905			function getChain() {
25906				/* If we are using the utility function, attempt to return this call's promise. If no promise library was detected,
25907				 default to null instead of returning the targeted elements so that utility function's return value is standardized. */
25908				if (isUtility) {
25909					return promiseData.promise || null;
25910					/* Otherwise, if we're using $.fn, return the jQuery-/Zepto-wrapped element set. */
25911				} else {
25912					return elementsWrapped;
25913				}
25914			}
25915
25916			/*************************
25917			 Arguments Assignment
25918			 *************************/
25919
25920			/* To allow for expressive CoffeeScript code, Velocity supports an alternative syntax in which "elements" (or "e"), "properties" (or "p"), and "options" (or "o")
25921			 objects are defined on a container object that's passed in as Velocity's sole argument. */
25922			/* Note: Some browsers automatically populate arguments with a "properties" object. We detect it by checking for its default "names" property. */
25923			var syntacticSugar = (arguments[0] && (arguments[0].p || (($.isPlainObject(arguments[0].properties) && !arguments[0].properties.names) || Type.isString(arguments[0].properties)))),
25924					/* Whether Velocity was called via the utility function (as opposed to on a jQuery/Zepto object). */
25925					isUtility,
25926					/* When Velocity is called via the utility function ($.Velocity()/Velocity()), elements are explicitly
25927					 passed in as the first parameter. Thus, argument positioning varies. We normalize them here. */
25928					elementsWrapped,
25929					argumentIndex;
25930
25931			var elements,
25932					propertiesMap,
25933					options;
25934
25935			/* Detect jQuery/Zepto elements being animated via the $.fn method. */
25936			if (Type.isWrapped(this)) {
25937				isUtility = false;
25938
25939				argumentIndex = 0;
25940				elements = this;
25941				elementsWrapped = this;
25942				/* Otherwise, raw elements are being animated via the utility function. */
25943			} else {
25944				isUtility = true;
25945
25946				argumentIndex = 1;
25947				elements = syntacticSugar ? (arguments[0].elements || arguments[0].e) : arguments[0];
25948			}
25949
25950			/***************
25951			 Promises
25952			 ***************/
25953
25954			var promiseData = {
25955				promise: null,
25956				resolver: null,
25957				rejecter: null
25958			};
25959
25960			/* If this call was made via the utility function (which is the default method of invocation when jQuery/Zepto are not being used), and if
25961			 promise support was detected, create a promise object for this call and store references to its resolver and rejecter methods. The resolve
25962			 method is used when a call completes naturally or is prematurely stopped by the user. In both cases, completeCall() handles the associated
25963			 call cleanup and promise resolving logic. The reject method is used when an invalid set of arguments is passed into a Velocity call. */
25964			/* Note: Velocity employs a call-based queueing architecture, which means that stopping an animating element actually stops the full call that
25965			 triggered it -- not that one element exclusively. Similarly, there is one promise per call, and all elements targeted by a Velocity call are
25966			 grouped together for the purposes of resolving and rejecting a promise. */
25967			if (isUtility && Velocity.Promise) {
25968				promiseData.promise = new Velocity.Promise(function(resolve, reject) {
25969					promiseData.resolver = resolve;
25970					promiseData.rejecter = reject;
25971				});
25972			}
25973
25974			if (syntacticSugar) {
25975				propertiesMap = arguments[0].properties || arguments[0].p;
25976				options = arguments[0].options || arguments[0].o;
25977			} else {
25978				propertiesMap = arguments[argumentIndex];
25979				options = arguments[argumentIndex + 1];
25980			}
25981
25982			elements = sanitizeElements(elements);
25983
25984			if (!elements) {
25985				if (promiseData.promise) {
25986					if (!propertiesMap || !options || options.promiseRejectEmpty !== false) {
25987						promiseData.rejecter();
25988					} else {
25989						promiseData.resolver();
25990					}
25991				}
25992				return;
25993			}
25994
25995			/* The length of the element set (in the form of a nodeList or an array of elements) is defaulted to 1 in case a
25996			 single raw DOM element is passed in (which doesn't contain a length property). */
25997			var elementsLength = elements.length,
25998					elementsIndex = 0;
25999
26000			/***************************
26001			 Argument Overloading
26002			 ***************************/
26003
26004			/* Support is included for jQuery's argument overloading: $.animate(propertyMap [, duration] [, easing] [, complete]).
26005			 Overloading is detected by checking for the absence of an object being passed into options. */
26006			/* Note: The stop/finish/pause/resume actions do not accept animation options, and are therefore excluded from this check. */
26007			if (!/^(stop|finish|finishAll|pause|resume)$/i.test(propertiesMap) && !$.isPlainObject(options)) {
26008				/* The utility function shifts all arguments one position to the right, so we adjust for that offset. */
26009				var startingArgumentPosition = argumentIndex + 1;
26010
26011				options = {};
26012
26013				/* Iterate through all options arguments */
26014				for (var i = startingArgumentPosition; i < arguments.length; i++) {
26015					/* Treat a number as a duration. Parse it out. */
26016					/* Note: The following RegEx will return true if passed an array with a number as its first item.
26017					 Thus, arrays are skipped from this check. */
26018					if (!Type.isArray(arguments[i]) && (/^(fast|normal|slow)$/i.test(arguments[i]) || /^\d/.test(arguments[i]))) {
26019						options.duration = arguments[i];
26020						/* Treat strings and arrays as easings. */
26021					} else if (Type.isString(arguments[i]) || Type.isArray(arguments[i])) {
26022						options.easing = arguments[i];
26023						/* Treat a function as a complete callback. */
26024					} else if (Type.isFunction(arguments[i])) {
26025						options.complete = arguments[i];
26026					}
26027				}
26028			}
26029
26030			/*********************
26031			 Action Detection
26032			 *********************/
26033
26034			/* Velocity's behavior is categorized into "actions": Elements can either be specially scrolled into view,
26035			 or they can be started, stopped, paused, resumed, or reversed . If a literal or referenced properties map is passed in as Velocity's
26036			 first argument, the associated action is "start". Alternatively, "scroll", "reverse", "pause", "resume" or "stop" can be passed in 
26037			 instead of a properties map. */
26038			var action;
26039
26040			switch (propertiesMap) {
26041				case "scroll":
26042					action = "scroll";
26043					break;
26044
26045				case "reverse":
26046					action = "reverse";
26047					break;
26048
26049				case "pause":
26050
26051					/*******************
26052					 Action: Pause
26053					 *******************/
26054
26055					var currentTime = (new Date()).getTime();
26056
26057					/* Handle delay timers */
26058					$.each(elements, function(i, element) {
26059						pauseDelayOnElement(element, currentTime);
26060					});
26061
26062					/* Pause and Resume are call-wide (not on a per element basis). Thus, calling pause or resume on a 
26063					 single element will cause any calls that containt tweens for that element to be paused/resumed
26064					 as well. */
26065
26066					/* Iterate through all calls and pause any that contain any of our elements */
26067					$.each(Velocity.State.calls, function(i, activeCall) {
26068
26069						var found = false;
26070						/* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
26071						if (activeCall) {
26072							/* Iterate through the active call's targeted elements. */
26073							$.each(activeCall[1], function(k, activeElement) {
26074								var queueName = (options === undefined) ? "" : options;
26075
26076								if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {
26077									return true;
26078								}
26079
26080								/* Iterate through the calls targeted by the stop command. */
26081								$.each(elements, function(l, element) {
26082									/* Check that this call was applied to the target element. */
26083									if (element === activeElement) {
26084
26085										/* Set call to paused */
26086										activeCall[5] = {
26087											resume: false
26088										};
26089
26090										/* Once we match an element, we can bounce out to the next call entirely */
26091										found = true;
26092										return false;
26093									}
26094								});
26095
26096								/* Proceed to check next call if we have already matched */
26097								if (found) {
26098									return false;
26099								}
26100							});
26101						}
26102
26103					});
26104
26105					/* Since pause creates no new tweens, exit out of Velocity. */
26106					return getChain();
26107
26108				case "resume":
26109
26110					/*******************
26111					 Action: Resume
26112					 *******************/
26113
26114					/* Handle delay timers */
26115					$.each(elements, function(i, element) {
26116						resumeDelayOnElement(element, currentTime);
26117					});
26118
26119					/* Pause and Resume are call-wide (not on a per elemnt basis). Thus, calling pause or resume on a 
26120					 single element will cause any calls that containt tweens for that element to be paused/resumed
26121					 as well. */
26122
26123					/* Iterate through all calls and pause any that contain any of our elements */
26124					$.each(Velocity.State.calls, function(i, activeCall) {
26125						var found = false;
26126						/* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
26127						if (activeCall) {
26128							/* Iterate through the active call's targeted elements. */
26129							$.each(activeCall[1], function(k, activeElement) {
26130								var queueName = (options === undefined) ? "" : options;
26131
26132								if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {
26133									return true;
26134								}
26135
26136								/* Skip any calls that have never been paused */
26137								if (!activeCall[5]) {
26138									return true;
26139								}
26140
26141								/* Iterate through the calls targeted by the stop command. */
26142								$.each(elements, function(l, element) {
26143									/* Check that this call was applied to the target element. */
26144									if (element === activeElement) {
26145
26146										/* Flag a pause object to be resumed, which will occur during the next tick. In
26147										 addition, the pause object will at that time be deleted */
26148										activeCall[5].resume = true;
26149
26150										/* Once we match an element, we can bounce out to the next call entirely */
26151										found = true;
26152										return false;
26153									}
26154								});
26155
26156								/* Proceed to check next call if we have already matched */
26157								if (found) {
26158									return false;
26159								}
26160							});
26161						}
26162
26163					});
26164
26165					/* Since resume creates no new tweens, exit out of Velocity. */
26166					return getChain();
26167
26168				case "finish":
26169				case "finishAll":
26170				case "stop":
26171					/*******************
26172					 Action: Stop
26173					 *******************/
26174
26175					/* Clear the currently-active delay on each targeted element. */
26176					$.each(elements, function(i, element) {
26177						if (Data(element) && Data(element).delayTimer) {
26178							/* Stop the timer from triggering its cached next() function. */
26179							clearTimeout(Data(element).delayTimer.setTimeout);
26180
26181							/* Manually call the next() function so that the subsequent queue items can progress. */
26182							if (Data(element).delayTimer.next) {
26183								Data(element).delayTimer.next();
26184							}
26185
26186							delete Data(element).delayTimer;
26187						}
26188
26189						/* If we want to finish everything in the queue, we have to iterate through it
26190						 and call each function. This will make them active calls below, which will
26191						 cause them to be applied via the duration setting. */
26192						if (propertiesMap === "finishAll" && (options === true || Type.isString(options))) {
26193							/* Iterate through the items in the element's queue. */
26194							$.each($.queue(element, Type.isString(options) ? options : ""), function(_, item) {
26195								/* The queue array can contain an "inprogress" string, which we skip. */
26196								if (Type.isFunction(item)) {
26197									item();
26198								}
26199							});
26200
26201							/* Clearing the $.queue() array is achieved by resetting it to []. */
26202							$.queue(element, Type.isString(options) ? options : "", []);
26203						}
26204					});
26205
26206					var callsToStop = [];
26207
26208					/* When the stop action is triggered, the elements' currently active call is immediately stopped. The active call might have
26209					 been applied to multiple elements, in which case all of the call's elements will be stopped. When an element
26210					 is stopped, the next item in its animation queue is immediately triggered. */
26211					/* An additional argument may be passed in to clear an element's remaining queued calls. Either true (which defaults to the "fx" queue)
26212					 or a custom queue string can be passed in. */
26213					/* Note: The stop command runs prior to Velocity's Queueing phase since its behavior is intended to take effect *immediately*,
26214					 regardless of the element's current queue state. */
26215
26216					/* Iterate through every active call. */
26217					$.each(Velocity.State.calls, function(i, activeCall) {
26218						/* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
26219						if (activeCall) {
26220							/* Iterate through the active call's targeted elements. */
26221							$.each(activeCall[1], function(k, activeElement) {
26222								/* If true was passed in as a secondary argument, clear absolutely all calls on this element. Otherwise, only
26223								 clear calls associated with the relevant queue. */
26224								/* Call stopping logic works as follows:
26225								 - options === true --> stop current default queue calls (and queue:false calls), including remaining queued ones.
26226								 - options === undefined --> stop current queue:"" call and all queue:false calls.
26227								 - options === false --> stop only queue:false calls.
26228								 - options === "custom" --> stop current queue:"custom" call, including remaining queued ones (there is no functionality to only clear the currently-running queue:"custom" call). */
26229								var queueName = (options === undefined) ? "" : options;
26230
26231								if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {
26232									return true;
26233								}
26234
26235								/* Iterate through the calls targeted by the stop command. */
26236								$.each(elements, function(l, element) {
26237									/* Check that this call was applied to the target element. */
26238									if (element === activeElement) {
26239										/* Optionally clear the remaining queued calls. If we're doing "finishAll" this won't find anything,
26240										 due to the queue-clearing above. */
26241										if (options === true || Type.isString(options)) {
26242											/* Iterate through the items in the element's queue. */
26243											$.each($.queue(element, Type.isString(options) ? options : ""), function(_, item) {
26244												/* The queue array can contain an "inprogress" string, which we skip. */
26245												if (Type.isFunction(item)) {
26246													/* Pass the item's callback a flag indicating that we want to abort from the queue call.
26247													 (Specifically, the queue will resolve the call's associated promise then abort.)  */
26248													item(null, true);
26249												}
26250											});
26251
26252											/* Clearing the $.queue() array is achieved by resetting it to []. */
26253											$.queue(element, Type.isString(options) ? options : "", []);
26254										}
26255
26256										if (propertiesMap === "stop") {
26257											/* Since "reverse" uses cached start values (the previous call's endValues), these values must be
26258											 changed to reflect the final value that the elements were actually tweened to. */
26259											/* Note: If only queue:false animations are currently running on an element, it won't have a tweensContainer
26260											 object. Also, queue:false animations can't be reversed. */
26261											var data = Data(element);
26262											if (data && data.tweensContainer && queueName !== false) {
26263												$.each(data.tweensContainer, function(m, activeTween) {
26264													activeTween.endValue = activeTween.currentValue;
26265												});
26266											}
26267
26268											callsToStop.push(i);
26269										} else if (propertiesMap === "finish" || propertiesMap === "finishAll") {
26270											/* To get active tweens to finish immediately, we forcefully shorten their durations to 1ms so that
26271											 they finish upon the next rAf tick then proceed with normal call completion logic. */
26272											activeCall[2].duration = 1;
26273										}
26274									}
26275								});
26276							});
26277						}
26278					});
26279
26280					/* Prematurely call completeCall() on each matched active call. Pass an additional flag for "stop" to indicate
26281					 that the complete callback and display:none setting should be skipped since we're completing prematurely. */
26282					if (propertiesMap === "stop") {
26283						$.each(callsToStop, function(i, j) {
26284							completeCall(j, true);
26285						});
26286
26287						if (promiseData.promise) {
26288							/* Immediately resolve the promise associated with this stop call since stop runs synchronously. */
26289							promiseData.resolver(elements);
26290						}
26291					}
26292
26293					/* Since we're stopping, and not proceeding with queueing, exit out of Velocity. */
26294					return getChain();
26295
26296				default:
26297					/* Treat a non-empty plain object as a literal properties map. */
26298					if ($.isPlainObject(propertiesMap) && !Type.isEmptyObject(propertiesMap)) {
26299						action = "start";
26300
26301						/****************
26302						 Redirects
26303						 ****************/
26304
26305						/* Check if a string matches a registered redirect (see Redirects above). */
26306					} else if (Type.isString(propertiesMap) && Velocity.Redirects[propertiesMap]) {
26307						opts = $.extend({}, options);
26308
26309						var durationOriginal = opts.duration,
26310								delayOriginal = opts.delay || 0;
26311
26312						/* If the backwards option was passed in, reverse the element set so that elements animate from the last to the first. */
26313						if (opts.backwards === true) {
26314							elements = $.extend(true, [], elements).reverse();
26315						}
26316
26317						/* Individually trigger the redirect for each element in the set to prevent users from having to handle iteration logic in their redirect. */
26318						$.each(elements, function(elementIndex, element) {
26319							/* If the stagger option was passed in, successively delay each element by the stagger value (in ms). Retain the original delay value. */
26320							if (parseFloat(opts.stagger)) {
26321								opts.delay = delayOriginal + (parseFloat(opts.stagger) * elementIndex);
26322							} else if (Type.isFunction(opts.stagger)) {
26323								opts.delay = delayOriginal + opts.stagger.call(element, elementIndex, elementsLength);
26324							}
26325
26326							/* If the drag option was passed in, successively increase/decrease (depending on the presense of opts.backwards)
26327							 the duration of each element's animation, using floors to prevent producing very short durations. */
26328							if (opts.drag) {
26329								/* Default the duration of UI pack effects (callouts and transitions) to 1000ms instead of the usual default duration of 400ms. */
26330								opts.duration = parseFloat(durationOriginal) || (/^(callout|transition)/.test(propertiesMap) ? 1000 : DURATION_DEFAULT);
26331
26332								/* For each element, take the greater duration of: A) animation completion percentage relative to the original duration,
26333								 B) 75% of the original duration, or C) a 200ms fallback (in case duration is already set to a low value).
26334								 The end result is a baseline of 75% of the redirect's duration that increases/decreases as the end of the element set is approached. */
26335								opts.duration = Math.max(opts.duration * (opts.backwards ? 1 - elementIndex / elementsLength : (elementIndex + 1) / elementsLength), opts.duration * 0.75, 200);
26336							}
26337
26338							/* Pass in the call's opts object so that the redirect can optionally extend it. It defaults to an empty object instead of null to
26339							 reduce the opts checking logic required inside the redirect. */
26340							Velocity.Redirects[propertiesMap].call(element, element, opts || {}, elementIndex, elementsLength, elements, promiseData.promise ? promiseData : undefined);
26341						});
26342
26343						/* Since the animation logic resides within the redirect's own code, abort the remainder of this call.
26344						 (The performance overhead up to this point is virtually non-existant.) */
26345						/* Note: The jQuery call chain is kept intact by returning the complete element set. */
26346						return getChain();
26347					} else {
26348						var abortError = "Velocity: First argument (" + propertiesMap + ") was not a property map, a known action, or a registered redirect. Aborting.";
26349
26350						if (promiseData.promise) {
26351							promiseData.rejecter(new Error(abortError));
26352						} else {
26353							console.log(abortError);
26354						}
26355
26356						return getChain();
26357					}
26358			}
26359
26360			/**************************
26361			 Call-Wide Variables
26362			 **************************/
26363
26364			/* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements
26365			 being animated in a single Velocity call. Calculating unit ratios necessitates DOM querying and updating, and is therefore
26366			 avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale
26367			 conversion metrics across Velocity animations that are not immediately consecutively chained. */
26368			var callUnitConversionData = {
26369				lastParent: null,
26370				lastPosition: null,
26371				lastFontSize: null,
26372				lastPercentToPxWidth: null,
26373				lastPercentToPxHeight: null,
26374				lastEmToPx: null,
26375				remToPx: null,
26376				vwToPx: null,
26377				vhToPx: null
26378			};
26379
26380			/* A container for all the ensuing tween data and metadata associated with this call. This container gets pushed to the page-wide
26381			 Velocity.State.calls array that is processed during animation ticking. */
26382			var call = [];
26383
26384			/************************
26385			 Element Processing
26386			 ************************/
26387
26388			/* Element processing consists of three parts -- data processing that cannot go stale and data processing that *can* go stale (i.e. third-party style modifications):
26389			 1) Pre-Queueing: Element-wide variables, including the element's data storage, are instantiated. Call options are prepared. If triggered, the Stop action is executed.
26390			 2) Queueing: The logic that runs once this call has reached its point of execution in the element's $.queue() stack. Most logic is placed here to avoid risking it becoming stale.
26391			 3) Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.
26392			 `elementArrayIndex` allows passing index of the element in the original array to value functions.
26393			 If `elementsIndex` were used instead the index would be determined by the elements' per-element queue.
26394			 */
26395			function processElement(element, elementArrayIndex) {
26396
26397				/*************************
26398				 Part I: Pre-Queueing
26399				 *************************/
26400
26401				/***************************
26402				 Element-Wide Variables
26403				 ***************************/
26404
26405				var /* The runtime opts object is the extension of the current call's options and Velocity's page-wide option defaults. */
26406						opts = $.extend({}, Velocity.defaults, options),
26407						/* A container for the processed data associated with each property in the propertyMap.
26408						 (Each property in the map produces its own "tween".) */
26409						tweensContainer = {},
26410						elementUnitConversionData;
26411
26412				/******************
26413				 Element Init
26414				 ******************/
26415
26416				if (Data(element) === undefined) {
26417					Velocity.init(element);
26418				}
26419
26420				/******************
26421				 Option: Delay
26422				 ******************/
26423
26424				/* Since queue:false doesn't respect the item's existing queue, we avoid injecting its delay here (it's set later on). */
26425				/* Note: Velocity rolls its own delay function since jQuery doesn't have a utility alias for $.fn.delay()
26426				 (and thus requires jQuery element creation, which we avoid since its overhead includes DOM querying). */
26427				if (parseFloat(opts.delay) && opts.queue !== false) {
26428					$.queue(element, opts.queue, function(next) {
26429						/* This is a flag used to indicate to the upcoming completeCall() function that this queue entry was initiated by Velocity. See completeCall() for further details. */
26430						Velocity.velocityQueueEntryFlag = true;
26431
26432						/* The ensuing queue item (which is assigned to the "next" argument that $.queue() automatically passes in) will be triggered after a setTimeout delay.
26433						 The setTimeout is stored so that it can be subjected to clearTimeout() if this animation is prematurely stopped via Velocity's "stop" command, and
26434						 delayBegin/delayTime is used to ensure we can "pause" and "resume" a tween that is still mid-delay. */
26435
26436						/* Temporarily store delayed elements to facilite access for global pause/resume */
26437						var callIndex = Velocity.State.delayedElements.count++;
26438						Velocity.State.delayedElements[callIndex] = element;
26439
26440						var delayComplete = (function(index) {
26441							return function() {
26442								/* Clear the temporary element */
26443								Velocity.State.delayedElements[index] = false;
26444
26445								/* Finally, issue the call */
26446								next();
26447							};
26448						})(callIndex);
26449
26450
26451						Data(element).delayBegin = (new Date()).getTime();
26452						Data(element).delay = parseFloat(opts.delay);
26453						Data(element).delayTimer = {
26454							setTimeout: setTimeout(next, parseFloat(opts.delay)),
26455							next: delayComplete
26456						};
26457					});
26458				}
26459
26460				/*********************
26461				 Option: Duration
26462				 *********************/
26463
26464				/* Support for jQuery's named durations. */
26465				switch (opts.duration.toString().toLowerCase()) {
26466					case "fast":
26467						opts.duration = 200;
26468						break;
26469
26470					case "normal":
26471						opts.duration = DURATION_DEFAULT;
26472						break;
26473
26474					case "slow":
26475						opts.duration = 600;
26476						break;
26477
26478					default:
26479						/* Remove the potential "ms" suffix and default to 1 if the user is attempting to set a duration of 0 (in order to produce an immediate style change). */
26480						opts.duration = parseFloat(opts.duration) || 1;
26481				}
26482
26483				/************************
26484				 Global Option: Mock
26485				 ************************/
26486
26487				if (Velocity.mock !== false) {
26488					/* In mock mode, all animations are forced to 1ms so that they occur immediately upon the next rAF tick.
26489					 Alternatively, a multiplier can be passed in to time remap all delays and durations. */
26490					if (Velocity.mock === true) {
26491						opts.duration = opts.delay = 1;
26492					} else {
26493						opts.duration *= parseFloat(Velocity.mock) || 1;
26494						opts.delay *= parseFloat(Velocity.mock) || 1;
26495					}
26496				}
26497
26498				/*******************
26499				 Option: Easing
26500				 *******************/
26501
26502				opts.easing = getEasing(opts.easing, opts.duration);
26503
26504				/**********************
26505				 Option: Callbacks
26506				 **********************/
26507
26508				/* Callbacks must functions. Otherwise, default to null. */
26509				if (opts.begin && !Type.isFunction(opts.begin)) {
26510					opts.begin = null;
26511				}
26512
26513				if (opts.progress && !Type.isFunction(opts.progress)) {
26514					opts.progress = null;
26515				}
26516
26517				if (opts.complete && !Type.isFunction(opts.complete)) {
26518					opts.complete = null;
26519				}
26520
26521				/*********************************
26522				 Option: Display & Visibility
26523				 *********************************/
26524
26525				/* Refer to Velocity's documentation (VelocityJS.org/#displayAndVisibility) for a description of the display and visibility options' behavior. */
26526				/* Note: We strictly check for undefined instead of falsiness because display accepts an empty string value. */
26527				if (opts.display !== undefined && opts.display !== null) {
26528					opts.display = opts.display.toString().toLowerCase();
26529
26530					/* Users can pass in a special "auto" value to instruct Velocity to set the element to its default display value. */
26531					if (opts.display === "auto") {
26532						opts.display = Velocity.CSS.Values.getDisplayType(element);
26533					}
26534				}
26535
26536				if (opts.visibility !== undefined && opts.visibility !== null) {
26537					opts.visibility = opts.visibility.toString().toLowerCase();
26538				}
26539
26540				/**********************
26541				 Option: mobileHA
26542				 **********************/
26543
26544				/* When set to true, and if this is a mobile device, mobileHA automatically enables hardware acceleration (via a null transform hack)
26545				 on animating elements. HA is removed from the element at the completion of its animation. */
26546				/* Note: Android Gingerbread doesn't support HA. If a null transform hack (mobileHA) is in fact set, it will prevent other tranform subproperties from taking effect. */
26547				/* Note: You can read more about the use of mobileHA in Velocity's documentation: VelocityJS.org/#mobileHA. */
26548				opts.mobileHA = (opts.mobileHA && Velocity.State.isMobile && !Velocity.State.isGingerbread);
26549
26550				/***********************
26551				 Part II: Queueing
26552				 ***********************/
26553
26554				/* When a set of elements is targeted by a Velocity call, the set is broken up and each element has the current Velocity call individually queued onto it.
26555				 In this way, each element's existing queue is respected; some elements may already be animating and accordingly should not have this current Velocity call triggered immediately. */
26556				/* In each queue, tween data is processed for each animating property then pushed onto the call-wide calls array. When the last element in the set has had its tweens processed,
26557				 the call array is pushed to Velocity.State.calls for live processing by the requestAnimationFrame tick. */
26558				function buildQueue(next) {
26559					var data, lastTweensContainer;
26560
26561					/*******************
26562					 Option: Begin
26563					 *******************/
26564
26565					/* The begin callback is fired once per call -- not once per elemenet -- and is passed the full raw DOM element set as both its context and its first argument. */
26566					if (opts.begin && elementsIndex === 0) {
26567						/* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */
26568						try {
26569							opts.begin.call(elements, elements);
26570						} catch (error) {
26571							setTimeout(function() {
26572								throw error;
26573							}, 1);
26574						}
26575					}
26576
26577					/*****************************************
26578					 Tween Data Construction (for Scroll)
26579					 *****************************************/
26580
26581					/* Note: In order to be subjected to chaining and animation options, scroll's tweening is routed through Velocity as if it were a standard CSS property animation. */
26582					if (action === "scroll") {
26583						/* The scroll action uniquely takes an optional "offset" option -- specified in pixels -- that offsets the targeted scroll position. */
26584						var scrollDirection = (/^x$/i.test(opts.axis) ? "Left" : "Top"),
26585								scrollOffset = parseFloat(opts.offset) || 0,
26586								scrollPositionCurrent,
26587								scrollPositionCurrentAlternate,
26588								scrollPositionEnd;
26589
26590						/* Scroll also uniquely takes an optional "container" option, which indicates the parent element that should be scrolled --
26591						 as opposed to the browser window itself. This is useful for scrolling toward an element that's inside an overflowing parent element. */
26592						if (opts.container) {
26593							/* Ensure that either a jQuery object or a raw DOM element was passed in. */
26594							if (Type.isWrapped(opts.container) || Type.isNode(opts.container)) {
26595								/* Extract the raw DOM element from the jQuery wrapper. */
26596								opts.container = opts.container[0] || opts.container;
26597								/* Note: Unlike other properties in Velocity, the browser's scroll position is never cached since it so frequently changes
26598								 (due to the user's natural interaction with the page). */
26599								scrollPositionCurrent = opts.container["scroll" + scrollDirection]; /* GET */
26600
26601								/* $.position() values are relative to the container's currently viewable area (without taking into account the container's true dimensions
26602								 -- say, for example, if the container was not overflowing). Thus, the scroll end value is the sum of the child element's position *and*
26603								 the scroll container's current scroll position. */
26604								scrollPositionEnd = (scrollPositionCurrent + $(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; /* GET */
26605								/* If a value other than a jQuery object or a raw DOM element was passed in, default to null so that this option is ignored. */
26606							} else {
26607								opts.container = null;
26608							}
26609						} else {
26610							/* If the window itself is being scrolled -- not a containing element -- perform a live scroll position lookup using
26611							 the appropriate cached property names (which differ based on browser type). */
26612							scrollPositionCurrent = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + scrollDirection]]; /* GET */
26613							/* When scrolling the browser window, cache the alternate axis's current value since window.scrollTo() doesn't let us change only one value at a time. */
26614							scrollPositionCurrentAlternate = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + (scrollDirection === "Left" ? "Top" : "Left")]]; /* GET */
26615
26616							/* Unlike $.position(), $.offset() values are relative to the browser window's true dimensions -- not merely its currently viewable area --
26617							 and therefore end values do not need to be compounded onto current values. */
26618							scrollPositionEnd = $(element).offset()[scrollDirection.toLowerCase()] + scrollOffset; /* GET */
26619						}
26620
26621						/* Since there's only one format that scroll's associated tweensContainer can take, we create it manually. */
26622						tweensContainer = {
26623							scroll: {
26624								rootPropertyValue: false,
26625								startValue: scrollPositionCurrent,
26626								currentValue: scrollPositionCurrent,
26627								endValue: scrollPositionEnd,
26628								unitType: "",
26629								easing: opts.easing,
26630								scrollData: {
26631									container: opts.container,
26632									direction: scrollDirection,
26633									alternateValue: scrollPositionCurrentAlternate
26634								}
26635							},
26636							element: element
26637						};
26638
26639						if (Velocity.debug) {
26640							console.log("tweensContainer (scroll): ", tweensContainer.scroll, element);
26641						}
26642
26643						/******************************************
26644						 Tween Data Construction (for Reverse)
26645						 ******************************************/
26646
26647						/* Reverse acts like a "start" action in that a property map is animated toward. The only difference is
26648						 that the property map used for reverse is the inverse of the map used in the previous call. Thus, we manipulate
26649						 the previous call to construct our new map: use the previous map's end values as our new map's start values. Copy over all other data. */
26650						/* Note: Reverse can be directly called via the "reverse" parameter, or it can be indirectly triggered via the loop option. (Loops are composed of multiple reverses.) */
26651						/* Note: Reverse calls do not need to be consecutively chained onto a currently-animating element in order to operate on cached values;
26652						 there is no harm to reverse being called on a potentially stale data cache since reverse's behavior is simply defined
26653						 as reverting to the element's values as they were prior to the previous *Velocity* call. */
26654					} else if (action === "reverse") {
26655						data = Data(element);
26656
26657						/* Abort if there is no prior animation data to reverse to. */
26658						if (!data) {
26659							return;
26660						}
26661
26662						if (!data.tweensContainer) {
26663							/* Dequeue the element so that this queue entry releases itself immediately, allowing subsequent queue entries to run. */
26664							$.dequeue(element, opts.queue);
26665
26666							return;
26667						} else {
26668							/*********************
26669							 Options Parsing
26670							 *********************/
26671
26672							/* If the element was hidden via the display option in the previous call,
26673							 revert display to "auto" prior to reversal so that the element is visible again. */
26674							if (data.opts.display === "none") {
26675								data.opts.display = "auto";
26676							}
26677
26678							if (data.opts.visibility === "hidden") {
26679								data.opts.visibility = "visible";
26680							}
26681
26682							/* If the loop option was set in the previous call, disable it so that "reverse" calls aren't recursively generated.
26683							 Further, remove the previous call's callback options; typically, users do not want these to be refired. */
26684							data.opts.loop = false;
26685							data.opts.begin = null;
26686							data.opts.complete = null;
26687
26688							/* Since we're extending an opts object that has already been extended with the defaults options object,
26689							 we remove non-explicitly-defined properties that are auto-assigned values. */
26690							if (!options.easing) {
26691								delete opts.easing;
26692							}
26693
26694							if (!options.duration) {
26695								delete opts.duration;
26696							}
26697
26698							/* The opts object used for reversal is an extension of the options object optionally passed into this
26699							 reverse call plus the options used in the previous Velocity call. */
26700							opts = $.extend({}, data.opts, opts);
26701
26702							/*************************************
26703							 Tweens Container Reconstruction
26704							 *************************************/
26705
26706							/* Create a deepy copy (indicated via the true flag) of the previous call's tweensContainer. */
26707							lastTweensContainer = $.extend(true, {}, data ? data.tweensContainer : null);
26708
26709							/* Manipulate the previous tweensContainer by replacing its end values and currentValues with its start values. */
26710							for (var lastTween in lastTweensContainer) {
26711								/* In addition to tween data, tweensContainers contain an element property that we ignore here. */
26712								if (lastTweensContainer.hasOwnProperty(lastTween) && lastTween !== "element") {
26713									var lastStartValue = lastTweensContainer[lastTween].startValue;
26714
26715									lastTweensContainer[lastTween].startValue = lastTweensContainer[lastTween].currentValue = lastTweensContainer[lastTween].endValue;
26716									lastTweensContainer[lastTween].endValue = lastStartValue;
26717
26718									/* Easing is the only option that embeds into the individual tween data (since it can be defined on a per-property basis).
26719									 Accordingly, every property's easing value must be updated when an options object is passed in with a reverse call.
26720									 The side effect of this extensibility is that all per-property easing values are forcefully reset to the new value. */
26721									if (!Type.isEmptyObject(options)) {
26722										lastTweensContainer[lastTween].easing = opts.easing;
26723									}
26724
26725									if (Velocity.debug) {
26726										console.log("reverse tweensContainer (" + lastTween + "): " + JSON.stringify(lastTweensContainer[lastTween]), element);
26727									}
26728								}
26729							}
26730
26731							tweensContainer = lastTweensContainer;
26732						}
26733
26734						/*****************************************
26735						 Tween Data Construction (for Start)
26736						 *****************************************/
26737
26738					} else if (action === "start") {
26739
26740						/*************************
26741						 Value Transferring
26742						 *************************/
26743
26744						/* If this queue entry follows a previous Velocity-initiated queue entry *and* if this entry was created
26745						 while the element was in the process of being animated by Velocity, then this current call is safe to use
26746						 the end values from the prior call as its start values. Velocity attempts to perform this value transfer
26747						 process whenever possible in order to avoid requerying the DOM. */
26748						/* If values aren't transferred from a prior call and start values were not forcefed by the user (more on this below),
26749						 then the DOM is queried for the element's current values as a last resort. */
26750						/* Note: Conversely, animation reversal (and looping) *always* perform inter-call value transfers; they never requery the DOM. */
26751
26752						data = Data(element);
26753
26754						/* The per-element isAnimating flag is used to indicate whether it's safe (i.e. the data isn't stale)
26755						 to transfer over end values to use as start values. If it's set to true and there is a previous
26756						 Velocity call to pull values from, do so. */
26757						if (data && data.tweensContainer && data.isAnimating === true) {
26758							lastTweensContainer = data.tweensContainer;
26759						}
26760
26761						/***************************
26762						 Tween Data Calculation
26763						 ***************************/
26764
26765						/* This function parses property data and defaults endValue, easing, and startValue as appropriate. */
26766						/* Property map values can either take the form of 1) a single value representing the end value,
26767						 or 2) an array in the form of [ endValue, [, easing] [, startValue] ].
26768						 The optional third parameter is a forcefed startValue to be used instead of querying the DOM for
26769						 the element's current value. Read Velocity's docmentation to learn more about forcefeeding: VelocityJS.org/#forcefeeding */
26770						var parsePropertyValue = function(valueData, skipResolvingEasing) {
26771							var endValue, easing, startValue;
26772
26773							/* If we have a function as the main argument then resolve it first, in case it returns an array that needs to be split */
26774							if (Type.isFunction(valueData)) {
26775								valueData = valueData.call(element, elementArrayIndex, elementsLength);
26776							}
26777
26778							/* Handle the array format, which can be structured as one of three potential overloads:
26779							 A) [ endValue, easing, startValue ], B) [ endValue, easing ], or C) [ endValue, startValue ] */
26780							if (Type.isArray(valueData)) {
26781								/* endValue is always the first item in the array. Don't bother validating endValue's value now
26782								 since the ensuing property cycling logic does that. */
26783								endValue = valueData[0];
26784
26785								/* Two-item array format: If the second item is a number, function, or hex string, treat it as a
26786								 start value since easings can only be non-hex strings or arrays. */
26787								if ((!Type.isArray(valueData[1]) && /^[\d-]/.test(valueData[1])) || Type.isFunction(valueData[1]) || CSS.RegEx.isHex.test(valueData[1])) {
26788									startValue = valueData[1];
26789									/* Two or three-item array: If the second item is a non-hex string easing name or an array, treat it as an easing. */
26790								} else if ((Type.isString(valueData[1]) && !CSS.RegEx.isHex.test(valueData[1]) && Velocity.Easings[valueData[1]]) || Type.isArray(valueData[1])) {
26791									easing = skipResolvingEasing ? valueData[1] : getEasing(valueData[1], opts.duration);
26792
26793									/* Don't bother validating startValue's value now since the ensuing property cycling logic inherently does that. */
26794									startValue = valueData[2];
26795								} else {
26796									startValue = valueData[1] || valueData[2];
26797								}
26798								/* Handle the single-value format. */
26799							} else {
26800								endValue = valueData;
26801							}
26802
26803							/* Default to the call's easing if a per-property easing type was not defined. */
26804							if (!skipResolvingEasing) {
26805								easing = easing || opts.easing;
26806							}
26807
26808							/* If functions were passed in as values, pass the function the current element as its context,
26809							 plus the element's index and the element set's size as arguments. Then, assign the returned value. */
26810							if (Type.isFunction(endValue)) {
26811								endValue = endValue.call(element, elementArrayIndex, elementsLength);
26812							}
26813
26814							if (Type.isFunction(startValue)) {
26815								startValue = startValue.call(element, elementArrayIndex, elementsLength);
26816							}
26817
26818							/* Allow startValue to be left as undefined to indicate to the ensuing code that its value was not forcefed. */
26819							return [endValue || 0, easing, startValue];
26820						};
26821
26822						var fixPropertyValue = function(property, valueData) {
26823							/* In case this property is a hook, there are circumstances where we will intend to work on the hook's root property and not the hooked subproperty. */
26824							var rootProperty = CSS.Hooks.getRoot(property),
26825									rootPropertyValue = false,
26826									/* Parse out endValue, easing, and startValue from the property's data. */
26827									endValue = valueData[0],
26828									easing = valueData[1],
26829									startValue = valueData[2],
26830									pattern;
26831
26832							/**************************
26833							 Start Value Sourcing
26834							 **************************/
26835
26836							/* Other than for the dummy tween property, properties that are not supported by the browser (and do not have an associated normalization) will
26837							 inherently produce no style changes when set, so they are skipped in order to decrease animation tick overhead.
26838							 Property support is determined via prefixCheck(), which returns a false flag when no supported is detected. */
26839							/* Note: Since SVG elements have some of their properties directly applied as HTML attributes,
26840							 there is no way to check for their explicit browser support, and so we skip skip this check for them. */
26841							if ((!data || !data.isSVG) && rootProperty !== "tween" && CSS.Names.prefixCheck(rootProperty)[1] === false && CSS.Normalizations.registered[rootProperty] === undefined) {
26842								if (Velocity.debug) {
26843									console.log("Skipping [" + rootProperty + "] due to a lack of browser support.");
26844								}
26845								return;
26846							}
26847
26848							/* If the display option is being set to a non-"none" (e.g. "block") and opacity (filter on IE<=8) is being
26849							 animated to an endValue of non-zero, the user's intention is to fade in from invisible, thus we forcefeed opacity
26850							 a startValue of 0 if its startValue hasn't already been sourced by value transferring or prior forcefeeding. */
26851							if (((opts.display !== undefined && opts.display !== null && opts.display !== "none") || (opts.visibility !== undefined && opts.visibility !== "hidden")) && /opacity|filter/.test(property) && !startValue && endValue !== 0) {
26852								startValue = 0;
26853							}
26854
26855							/* If values have been transferred from the previous Velocity call, extract the endValue and rootPropertyValue
26856							 for all of the current call's properties that were *also* animated in the previous call. */
26857							/* Note: Value transferring can optionally be disabled by the user via the _cacheValues option. */
26858							if (opts._cacheValues && lastTweensContainer && lastTweensContainer[property]) {
26859								if (startValue === undefined) {
26860									startValue = lastTweensContainer[property].endValue + lastTweensContainer[property].unitType;
26861								}
26862
26863								/* The previous call's rootPropertyValue is extracted from the element's data cache since that's the
26864								 instance of rootPropertyValue that gets freshly updated by the tweening process, whereas the rootPropertyValue
26865								 attached to the incoming lastTweensContainer is equal to the root property's value prior to any tweening. */
26866								rootPropertyValue = data.rootPropertyValueCache[rootProperty];
26867								/* If values were not transferred from a previous Velocity call, query the DOM as needed. */
26868							} else {
26869								/* Handle hooked properties. */
26870								if (CSS.Hooks.registered[property]) {
26871									if (startValue === undefined) {
26872										rootPropertyValue = CSS.getPropertyValue(element, rootProperty); /* GET */
26873										/* Note: The following getPropertyValue() call does not actually trigger a DOM query;
26874										 getPropertyValue() will extract the hook from rootPropertyValue. */
26875										startValue = CSS.getPropertyValue(element, property, rootPropertyValue);
26876										/* If startValue is already defined via forcefeeding, do not query the DOM for the root property's value;
26877										 just grab rootProperty's zero-value template from CSS.Hooks. This overwrites the element's actual
26878										 root property value (if one is set), but this is acceptable since the primary reason users forcefeed is
26879										 to avoid DOM queries, and thus we likewise avoid querying the DOM for the root property's value. */
26880									} else {
26881										/* Grab this hook's zero-value template, e.g. "0px 0px 0px black". */
26882										rootPropertyValue = CSS.Hooks.templates[rootProperty][1];
26883									}
26884									/* Handle non-hooked properties that haven't already been defined via forcefeeding. */
26885								} else if (startValue === undefined) {
26886									startValue = CSS.getPropertyValue(element, property); /* GET */
26887								}
26888							}
26889
26890							/**************************
26891							 Value Data Extraction
26892							 **************************/
26893
26894							var separatedValue,
26895									endValueUnitType,
26896									startValueUnitType,
26897									operator = false;
26898
26899							/* Separates a property value into its numeric value and its unit type. */
26900							var separateValue = function(property, value) {
26901								var unitType,
26902										numericValue;
26903
26904								numericValue = (value || "0")
26905										.toString()
26906										.toLowerCase()
26907										/* Match the unit type at the end of the value. */
26908										.replace(/[%A-z]+$/, function(match) {
26909											/* Grab the unit type. */
26910											unitType = match;
26911
26912											/* Strip the unit type off of value. */
26913											return "";
26914										});
26915
26916								/* If no unit type was supplied, assign one that is appropriate for this property (e.g. "deg" for rotateZ or "px" for width). */
26917								if (!unitType) {
26918									unitType = CSS.Values.getUnitType(property);
26919								}
26920
26921								return [numericValue, unitType];
26922							};
26923
26924							if (startValue !== endValue && Type.isString(startValue) && Type.isString(endValue)) {
26925								pattern = "";
26926								var iStart = 0, // index in startValue
26927										iEnd = 0, // index in endValue
26928										aStart = [], // array of startValue numbers
26929										aEnd = [], // array of endValue numbers
26930										inCalc = 0, // Keep track of being inside a "calc()" so we don't duplicate it
26931										inRGB = 0, // Keep track of being inside an RGB as we can't use fractional values
26932										inRGBA = 0; // Keep track of being inside an RGBA as we must pass fractional for the alpha channel
26933
26934								startValue = CSS.Hooks.fixColors(startValue);
26935								endValue = CSS.Hooks.fixColors(endValue);
26936								while (iStart < startValue.length && iEnd < endValue.length) {
26937									var cStart = startValue[iStart],
26938											cEnd = endValue[iEnd];
26939
26940									if (/[\d\.]/.test(cStart) && /[\d\.]/.test(cEnd)) {
26941										var tStart = cStart, // temporary character buffer
26942												tEnd = cEnd, // temporary character buffer
26943												dotStart = ".", // Make sure we can only ever match a single dot in a decimal
26944												dotEnd = "."; // Make sure we can only ever match a single dot in a decimal
26945
26946										while (++iStart < startValue.length) {
26947											cStart = startValue[iStart];
26948											if (cStart === dotStart) {
26949												dotStart = ".."; // Can never match two characters
26950											} else if (!/\d/.test(cStart)) {
26951												break;
26952											}
26953											tStart += cStart;
26954										}
26955										while (++iEnd < endValue.length) {
26956											cEnd = endValue[iEnd];
26957											if (cEnd === dotEnd) {
26958												dotEnd = ".."; // Can never match two characters
26959											} else if (!/\d/.test(cEnd)) {
26960												break;
26961											}
26962											tEnd += cEnd;
26963										}
26964										var uStart = CSS.Hooks.getUnit(startValue, iStart), // temporary unit type
26965												uEnd = CSS.Hooks.getUnit(endValue, iEnd); // temporary unit type
26966
26967										iStart += uStart.length;
26968										iEnd += uEnd.length;
26969										if (uStart === uEnd) {
26970											// Same units
26971											if (tStart === tEnd) {
26972												// Same numbers, so just copy over
26973												pattern += tStart + uStart;
26974											} else {
26975												// Different numbers, so store them
26976												pattern += "{" + aStart.length + (inRGB ? "!" : "") + "}" + uStart;
26977												aStart.push(parseFloat(tStart));
26978												aEnd.push(parseFloat(tEnd));
26979											}
26980										} else {
26981											// Different units, so put into a "calc(from + to)" and animate each side to/from zero
26982											var nStart = parseFloat(tStart),
26983													nEnd = parseFloat(tEnd);
26984
26985											pattern += (inCalc < 5 ? "calc" : "") + "("
26986													+ (nStart ? "{" + aStart.length + (inRGB ? "!" : "") + "}" : "0") + uStart
26987													+ " + "
26988													+ (nEnd ? "{" + (aStart.length + 1) + (inRGB ? "!" : "") + "}" : "0") + uEnd
26989													+ ")";
26990											if (nStart) {
26991												aStart.push(parseFloat(tStart));
26992												aStart.push(parseFloat(0));
26993											}
26994											if (nEnd) {
26995												aEnd.push(parseFloat(0));
26996												aEnd.push(parseFloat(tEnd));
26997											}
26998										}
26999									} else if (cStart === cEnd) {
27000										pattern += cStart;
27001										iStart++;
27002										iEnd++;
27003										// Keep track of being inside a calc()
27004										if (inCalc === 0 && cStart === "c"
27005												|| inCalc === 1 && cStart === "a"
27006												|| inCalc === 2 && cStart === "l"
27007												|| inCalc === 3 && cStart === "c"
27008												|| inCalc >= 4 && cStart === "("
27009												) {
27010											inCalc++;
27011										} else if ((inCalc && inCalc < 5)
27012												|| inCalc >= 4 && cStart === ")" && --inCalc < 5) {
27013											inCalc = 0;
27014										}
27015										// Keep track of being inside an rgb() / rgba()
27016										if (inRGB === 0 && cStart === "r"
27017												|| inRGB === 1 && cStart === "g"
27018												|| inRGB === 2 && cStart === "b"
27019												|| inRGB === 3 && cStart === "a"
27020												|| inRGB >= 3 && cStart === "("
27021												) {
27022											if (inRGB === 3 && cStart === "a") {
27023												inRGBA = 1;
27024											}
27025											inRGB++;
27026										} else if (inRGBA && cStart === ",") {
27027											if (++inRGBA > 3) {
27028												inRGB = inRGBA = 0;
27029											}
27030										} else if ((inRGBA && inRGB < (inRGBA ? 5 : 4))
27031												|| inRGB >= (inRGBA ? 4 : 3) && cStart === ")" && --inRGB < (inRGBA ? 5 : 4)) {
27032											inRGB = inRGBA = 0;
27033										}
27034									} else {
27035										inCalc = 0;
27036										// TODO: changing units, fixing colours
27037										break;
27038									}
27039								}
27040								if (iStart !== startValue.length || iEnd !== endValue.length) {
27041									if (Velocity.debug) {
27042										console.error("Trying to pattern match mis-matched strings [\"" + endValue + "\", \"" + startValue + "\"]");
27043									}
27044									pattern = undefined;
27045								}
27046								if (pattern) {
27047									if (aStart.length) {
27048										if (Velocity.debug) {
27049											console.log("Pattern found \"" + pattern + "\" -> ", aStart, aEnd, "[" + startValue + "," + endValue + "]");
27050										}
27051										startValue = aStart;
27052										endValue = aEnd;
27053										endValueUnitType = startValueUnitType = "";
27054									} else {
27055										pattern = undefined;
27056									}
27057								}
27058							}
27059
27060							if (!pattern) {
27061								/* Separate startValue. */
27062								separatedValue = separateValue(property, startValue);
27063								startValue = separatedValue[0];
27064								startValueUnitType = separatedValue[1];
27065
27066								/* Separate endValue, and extract a value operator (e.g. "+=", "-=") if one exists. */
27067								separatedValue = separateValue(property, endValue);
27068								endValue = separatedValue[0].replace(/^([+-\/*])=/, function(match, subMatch) {
27069									operator = subMatch;
27070
27071									/* Strip the operator off of the value. */
27072									return "";
27073								});
27074								endValueUnitType = separatedValue[1];
27075
27076								/* Parse float values from endValue and startValue. Default to 0 if NaN is returned. */
27077								startValue = parseFloat(startValue) || 0;
27078								endValue = parseFloat(endValue) || 0;
27079
27080								/***************************************
27081								 Property-Specific Value Conversion
27082								 ***************************************/
27083
27084								/* Custom support for properties that don't actually accept the % unit type, but where pollyfilling is trivial and relatively foolproof. */
27085								if (endValueUnitType === "%") {
27086									/* A %-value fontSize/lineHeight is relative to the parent's fontSize (as opposed to the parent's dimensions),
27087									 which is identical to the em unit's behavior, so we piggyback off of that. */
27088									if (/^(fontSize|lineHeight)$/.test(property)) {
27089										/* Convert % into an em decimal value. */
27090										endValue = endValue / 100;
27091										endValueUnitType = "em";
27092										/* For scaleX and scaleY, convert the value into its decimal format and strip off the unit type. */
27093									} else if (/^scale/.test(property)) {
27094										endValue = endValue / 100;
27095										endValueUnitType = "";
27096										/* For RGB components, take the defined percentage of 255 and strip off the unit type. */
27097									} else if (/(Red|Green|Blue)$/i.test(property)) {
27098										endValue = (endValue / 100) * 255;
27099										endValueUnitType = "";
27100									}
27101								}
27102							}
27103
27104							/***************************
27105							 Unit Ratio Calculation
27106							 ***************************/
27107
27108							/* When queried, the browser returns (most) CSS property values in pixels. Therefore, if an endValue with a unit type of
27109							 %, em, or rem is animated toward, startValue must be converted from pixels into the same unit type as endValue in order
27110							 for value manipulation logic (increment/decrement) to proceed. Further, if the startValue was forcefed or transferred
27111							 from a previous call, startValue may also not be in pixels. Unit conversion logic therefore consists of two steps:
27112							 1) Calculating the ratio of %/em/rem/vh/vw relative to pixels
27113							 2) Converting startValue into the same unit of measurement as endValue based on these ratios. */
27114							/* Unit conversion ratios are calculated by inserting a sibling node next to the target node, copying over its position property,
27115							 setting values with the target unit type then comparing the returned pixel value. */
27116							/* Note: Even if only one of these unit types is being animated, all unit ratios are calculated at once since the overhead
27117							 of batching the SETs and GETs together upfront outweights the potential overhead
27118							 of layout thrashing caused by re-querying for uncalculated ratios for subsequently-processed properties. */
27119							/* Todo: Shift this logic into the calls' first tick instance so that it's synced with RAF. */
27120							var calculateUnitRatios = function() {
27121
27122								/************************
27123								 Same Ratio Checks
27124								 ************************/
27125
27126								/* The properties below are used to determine whether the element differs sufficiently from this call's
27127								 previously iterated element to also differ in its unit conversion ratios. If the properties match up with those
27128								 of the prior element, the prior element's conversion ratios are used. Like most optimizations in Velocity,
27129								 this is done to minimize DOM querying. */
27130								var sameRatioIndicators = {
27131									myParent: element.parentNode || document.body, /* GET */
27132									position: CSS.getPropertyValue(element, "position"), /* GET */
27133									fontSize: CSS.getPropertyValue(element, "fontSize") /* GET */
27134								},
27135										/* Determine if the same % ratio can be used. % is based on the element's position value and its parent's width and height dimensions. */
27136										samePercentRatio = ((sameRatioIndicators.position === callUnitConversionData.lastPosition) && (sameRatioIndicators.myParent === callUnitConversionData.lastParent)),
27137										/* Determine if the same em ratio can be used. em is relative to the element's fontSize. */
27138										sameEmRatio = (sameRatioIndicators.fontSize === callUnitConversionData.lastFontSize);
27139
27140								/* Store these ratio indicators call-wide for the next element to compare against. */
27141								callUnitConversionData.lastParent = sameRatioIndicators.myParent;
27142								callUnitConversionData.lastPosition = sameRatioIndicators.position;
27143								callUnitConversionData.lastFontSize = sameRatioIndicators.fontSize;
27144
27145								/***************************
27146								 Element-Specific Units
27147								 ***************************/
27148
27149								/* Note: IE8 rounds to the nearest pixel when returning CSS values, thus we perform conversions using a measurement
27150								 of 100 (instead of 1) to give our ratios a precision of at least 2 decimal values. */
27151								var measurement = 100,
27152										unitRatios = {};
27153
27154								if (!sameEmRatio || !samePercentRatio) {
27155									var dummy = data && data.isSVG ? document.createElementNS("http://www.w3.org/2000/svg", "rect") : document.createElement("div");
27156
27157									Velocity.init(dummy);
27158									sameRatioIndicators.myParent.appendChild(dummy);
27159
27160									/* To accurately and consistently calculate conversion ratios, the element's cascaded overflow and box-sizing are stripped.
27161									 Similarly, since width/height can be artificially constrained by their min-/max- equivalents, these are controlled for as well. */
27162									/* Note: Overflow must be also be controlled for per-axis since the overflow property overwrites its per-axis values. */
27163									$.each(["overflow", "overflowX", "overflowY"], function(i, property) {
27164										Velocity.CSS.setPropertyValue(dummy, property, "hidden");
27165									});
27166									Velocity.CSS.setPropertyValue(dummy, "position", sameRatioIndicators.position);
27167									Velocity.CSS.setPropertyValue(dummy, "fontSize", sameRatioIndicators.fontSize);
27168									Velocity.CSS.setPropertyValue(dummy, "boxSizing", "content-box");
27169
27170									/* width and height act as our proxy properties for measuring the horizontal and vertical % ratios. */
27171									$.each(["minWidth", "maxWidth", "width", "minHeight", "maxHeight", "height"], function(i, property) {
27172										Velocity.CSS.setPropertyValue(dummy, property, measurement + "%");
27173									});
27174									/* paddingLeft arbitrarily acts as our proxy property for the em ratio. */
27175									Velocity.CSS.setPropertyValue(dummy, "paddingLeft", measurement + "em");
27176
27177									/* Divide the returned value by the measurement to get the ratio between 1% and 1px. Default to 1 since working with 0 can produce Infinite. */
27178									unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth = (parseFloat(CSS.getPropertyValue(dummy, "width", null, true)) || 1) / measurement; /* GET */
27179									unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight = (parseFloat(CSS.getPropertyValue(dummy, "height", null, true)) || 1) / measurement; /* GET */
27180									unitRatios.emToPx = callUnitConversionData.lastEmToPx = (parseFloat(CSS.getPropertyValue(dummy, "paddingLeft")) || 1) / measurement; /* GET */
27181
27182									sameRatioIndicators.myParent.removeChild(dummy);
27183								} else {
27184									unitRatios.emToPx = callUnitConversionData.lastEmToPx;
27185									unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth;
27186									unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight;
27187								}
27188
27189								/***************************
27190								 Element-Agnostic Units
27191								 ***************************/
27192
27193								/* Whereas % and em ratios are determined on a per-element basis, the rem unit only needs to be checked
27194								 once per call since it's exclusively dependant upon document.body's fontSize. If this is the first time
27195								 that calculateUnitRatios() is being run during this call, remToPx will still be set to its default value of null,
27196								 so we calculate it now. */
27197								if (callUnitConversionData.remToPx === null) {
27198									/* Default to browsers' default fontSize of 16px in the case of 0. */
27199									callUnitConversionData.remToPx = parseFloat(CSS.getPropertyValue(document.body, "fontSize")) || 16; /* GET */
27200								}
27201
27202								/* Similarly, viewport units are %-relative to the window's inner dimensions. */
27203								if (callUnitConversionData.vwToPx === null) {
27204									callUnitConversionData.vwToPx = parseFloat(window.innerWidth) / 100; /* GET */
27205									callUnitConversionData.vhToPx = parseFloat(window.innerHeight) / 100; /* GET */
27206								}
27207
27208								unitRatios.remToPx = callUnitConversionData.remToPx;
27209								unitRatios.vwToPx = callUnitConversionData.vwToPx;
27210								unitRatios.vhToPx = callUnitConversionData.vhToPx;
27211
27212								if (Velocity.debug >= 1) {
27213									console.log("Unit ratios: " + JSON.stringify(unitRatios), element);
27214								}
27215								return unitRatios;
27216							};
27217
27218							/********************
27219							 Unit Conversion
27220							 ********************/
27221
27222							/* The * and / operators, which are not passed in with an associated unit, inherently use startValue's unit. Skip value and unit conversion. */
27223							if (/[\/*]/.test(operator)) {
27224								endValueUnitType = startValueUnitType;
27225								/* If startValue and endValue differ in unit type, convert startValue into the same unit type as endValue so that if endValueUnitType
27226								 is a relative unit (%, em, rem), the values set during tweening will continue to be accurately relative even if the metrics they depend
27227								 on are dynamically changing during the course of the animation. Conversely, if we always normalized into px and used px for setting values, the px ratio
27228								 would become stale if the original unit being animated toward was relative and the underlying metrics change during the animation. */
27229								/* Since 0 is 0 in any unit type, no conversion is necessary when startValue is 0 -- we just start at 0 with endValueUnitType. */
27230							} else if ((startValueUnitType !== endValueUnitType) && startValue !== 0) {
27231								/* Unit conversion is also skipped when endValue is 0, but *startValueUnitType* must be used for tween values to remain accurate. */
27232								/* Note: Skipping unit conversion here means that if endValueUnitType was originally a relative unit, the animation won't relatively
27233								 match the underlying metrics if they change, but this is acceptable since we're animating toward invisibility instead of toward visibility,
27234								 which remains past the point of the animation's completion. */
27235								if (endValue === 0) {
27236									endValueUnitType = startValueUnitType;
27237								} else {
27238									/* By this point, we cannot avoid unit conversion (it's undesirable since it causes layout thrashing).
27239									 If we haven't already, we trigger calculateUnitRatios(), which runs once per element per call. */
27240									elementUnitConversionData = elementUnitConversionData || calculateUnitRatios();
27241
27242									/* The following RegEx matches CSS properties that have their % values measured relative to the x-axis. */
27243									/* Note: W3C spec mandates that all of margin and padding's properties (even top and bottom) are %-relative to the *width* of the parent element. */
27244									var axis = (/margin|padding|left|right|width|text|word|letter/i.test(property) || /X$/.test(property) || property === "x") ? "x" : "y";
27245
27246									/* In order to avoid generating n^2 bespoke conversion functions, unit conversion is a two-step process:
27247									 1) Convert startValue into pixels. 2) Convert this new pixel value into endValue's unit type. */
27248									switch (startValueUnitType) {
27249										case "%":
27250											/* Note: translateX and translateY are the only properties that are %-relative to an element's own dimensions -- not its parent's dimensions.
27251											 Velocity does not include a special conversion process to account for this behavior. Therefore, animating translateX/Y from a % value
27252											 to a non-% value will produce an incorrect start value. Fortunately, this sort of cross-unit conversion is rarely done by users in practice. */
27253											startValue *= (axis === "x" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);
27254											break;
27255
27256										case "px":
27257											/* px acts as our midpoint in the unit conversion process; do nothing. */
27258											break;
27259
27260										default:
27261											startValue *= elementUnitConversionData[startValueUnitType + "ToPx"];
27262									}
27263
27264									/* Invert the px ratios to convert into to the target unit. */
27265									switch (endValueUnitType) {
27266										case "%":
27267											startValue *= 1 / (axis === "x" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);
27268											break;
27269
27270										case "px":
27271											/* startValue is already in px, do nothing; we're done. */
27272											break;
27273
27274										default:
27275											startValue *= 1 / elementUnitConversionData[endValueUnitType + "ToPx"];
27276									}
27277								}
27278							}
27279
27280							/*********************
27281							 Relative Values
27282							 *********************/
27283
27284							/* Operator logic must be performed last since it requires unit-normalized start and end values. */
27285							/* Note: Relative *percent values* do not behave how most people think; while one would expect "+=50%"
27286							 to increase the property 1.5x its current value, it in fact increases the percent units in absolute terms:
27287							 50 points is added on top of the current % value. */
27288							switch (operator) {
27289								case "+":
27290									endValue = startValue + endValue;
27291									break;
27292
27293								case "-":
27294									endValue = startValue - endValue;
27295									break;
27296
27297								case "*":
27298									endValue = startValue * endValue;
27299									break;
27300
27301								case "/":
27302									endValue = startValue / endValue;
27303									break;
27304							}
27305
27306							/**************************
27307							 tweensContainer Push
27308							 **************************/
27309
27310							/* Construct the per-property tween object, and push it to the element's tweensContainer. */
27311							tweensContainer[property] = {
27312								rootPropertyValue: rootPropertyValue,
27313								startValue: startValue,
27314								currentValue: startValue,
27315								endValue: endValue,
27316								unitType: endValueUnitType,
27317								easing: easing
27318							};
27319							if (pattern) {
27320								tweensContainer[property].pattern = pattern;
27321							}
27322
27323							if (Velocity.debug) {
27324								console.log("tweensContainer (" + property + "): " + JSON.stringify(tweensContainer[property]), element);
27325							}
27326						};
27327
27328						/* Create a tween out of each property, and append its associated data to tweensContainer. */
27329						for (var property in propertiesMap) {
27330
27331							if (!propertiesMap.hasOwnProperty(property)) {
27332								continue;
27333							}
27334							/* The original property name's format must be used for the parsePropertyValue() lookup,
27335							 but we then use its camelCase styling to normalize it for manipulation. */
27336							var propertyName = CSS.Names.camelCase(property),
27337									valueData = parsePropertyValue(propertiesMap[property]);
27338
27339							/* Find shorthand color properties that have been passed a hex string. */
27340							/* Would be quicker to use CSS.Lists.colors.includes() if possible */
27341							if (CSS.Lists.colors.indexOf(propertyName) >= 0) {
27342								/* Parse the value data for each shorthand. */
27343								var endValue = valueData[0],
27344										easing = valueData[1],
27345										startValue = valueData[2];
27346
27347								if (CSS.RegEx.isHex.test(endValue)) {
27348									/* Convert the hex strings into their RGB component arrays. */
27349									var colorComponents = ["Red", "Green", "Blue"],
27350											endValueRGB = CSS.Values.hexToRgb(endValue),
27351											startValueRGB = startValue ? CSS.Values.hexToRgb(startValue) : undefined;
27352
27353									/* Inject the RGB component tweens into propertiesMap. */
27354									for (var i = 0; i < colorComponents.length; i++) {
27355										var dataArray = [endValueRGB[i]];
27356
27357										if (easing) {
27358											dataArray.push(easing);
27359										}
27360
27361										if (startValueRGB !== undefined) {
27362											dataArray.push(startValueRGB[i]);
27363										}
27364
27365										fixPropertyValue(propertyName + colorComponents[i], dataArray);
27366									}
27367									/* If we have replaced a shortcut color value then don't update the standard property name */
27368									continue;
27369								}
27370							}
27371							fixPropertyValue(propertyName, valueData);
27372						}
27373
27374						/* Along with its property data, store a reference to the element itself onto tweensContainer. */
27375						tweensContainer.element = element;
27376					}
27377
27378					/*****************
27379					 Call Push
27380					 *****************/
27381
27382					/* Note: tweensContainer can be empty if all of the properties in this call's property map were skipped due to not
27383					 being supported by the browser. The element property is used for checking that the tweensContainer has been appended to. */
27384					if (tweensContainer.element) {
27385						/* Apply the "velocity-animating" indicator class. */
27386						CSS.Values.addClass(element, "velocity-animating");
27387
27388						/* The call array houses the tweensContainers for each element being animated in the current call. */
27389						call.push(tweensContainer);
27390
27391						data = Data(element);
27392
27393						if (data) {
27394							/* Store the tweensContainer and options if we're working on the default effects queue, so that they can be used by the reverse command. */
27395							if (opts.queue === "") {
27396
27397								data.tweensContainer = tweensContainer;
27398								data.opts = opts;
27399							}
27400
27401							/* Switch on the element's animating flag. */
27402							data.isAnimating = true;
27403						}
27404
27405						/* Once the final element in this call's element set has been processed, push the call array onto
27406						 Velocity.State.calls for the animation tick to immediately begin processing. */
27407						if (elementsIndex === elementsLength - 1) {
27408							/* Add the current call plus its associated metadata (the element set and the call's options) onto the global call container.
27409							 Anything on this call container is subjected to tick() processing. */
27410							Velocity.State.calls.push([call, elements, opts, null, promiseData.resolver, null, 0]);
27411
27412							/* If the animation tick isn't running, start it. (Velocity shuts it off when there are no active calls to process.) */
27413							if (Velocity.State.isTicking === false) {
27414								Velocity.State.isTicking = true;
27415
27416								/* Start the tick loop. */
27417								tick();
27418							}
27419						} else {
27420							elementsIndex++;
27421						}
27422					}
27423				}
27424
27425				/* When the queue option is set to false, the call skips the element's queue and fires immediately. */
27426				if (opts.queue === false) {
27427					/* Since this buildQueue call doesn't respect the element's existing queue (which is where a delay option would have been appended),
27428					 we manually inject the delay property here with an explicit setTimeout. */
27429					if (opts.delay) {
27430
27431						/* Temporarily store delayed elements to facilitate access for global pause/resume */
27432						var callIndex = Velocity.State.delayedElements.count++;
27433						Velocity.State.delayedElements[callIndex] = element;
27434
27435						var delayComplete = (function(index) {
27436							return function() {
27437								/* Clear the temporary element */
27438								Velocity.State.delayedElements[index] = false;
27439
27440								/* Finally, issue the call */
27441								buildQueue();
27442							};
27443						})(callIndex);
27444
27445						Data(element).delayBegin = (new Date()).getTime();
27446						Data(element).delay = parseFloat(opts.delay);
27447						Data(element).delayTimer = {
27448							setTimeout: setTimeout(buildQueue, parseFloat(opts.delay)),
27449							next: delayComplete
27450						};
27451					} else {
27452						buildQueue();
27453					}
27454					/* Otherwise, the call undergoes element queueing as normal. */
27455					/* Note: To interoperate with jQuery, Velocity uses jQuery's own $.queue() stack for queuing logic. */
27456				} else {
27457					$.queue(element, opts.queue, function(next, clearQueue) {
27458						/* If the clearQueue flag was passed in by the stop command, resolve this call's promise. (Promises can only be resolved once,
27459						 so it's fine if this is repeatedly triggered for each element in the associated call.) */
27460						if (clearQueue === true) {
27461							if (promiseData.promise) {
27462								promiseData.resolver(elements);
27463							}
27464
27465							/* Do not continue with animation queueing. */
27466							return true;
27467						}
27468
27469						/* This flag indicates to the upcoming completeCall() function that this queue entry was initiated by Velocity.
27470						 See completeCall() for further details. */
27471						Velocity.velocityQueueEntryFlag = true;
27472
27473						buildQueue(next);
27474					});
27475				}
27476
27477				/*********************
27478				 Auto-Dequeuing
27479				 *********************/
27480
27481				/* As per jQuery's $.queue() behavior, to fire the first non-custom-queue entry on an element, the element
27482				 must be dequeued if its queue stack consists *solely* of the current call. (This can be determined by checking
27483				 for the "inprogress" item that jQuery prepends to active queue stack arrays.) Regardless, whenever the element's
27484				 queue is further appended with additional items -- including $.delay()'s or even $.animate() calls, the queue's
27485				 first entry is automatically fired. This behavior contrasts that of custom queues, which never auto-fire. */
27486				/* Note: When an element set is being subjected to a non-parallel Velocity call, the animation will not begin until
27487				 each one of the elements in the set has reached the end of its individually pre-existing queue chain. */
27488				/* Note: Unfortunately, most people don't fully grasp jQuery's powerful, yet quirky, $.queue() function.
27489				 Lean more here: http://stackoverflow.com/questions/1058158/can-somebody-explain-jquery-queue-to-me */
27490				if ((opts.queue === "" || opts.queue === "fx") && $.queue(element)[0] !== "inprogress") {
27491					$.dequeue(element);
27492				}
27493			}
27494
27495			/**************************
27496			 Element Set Iteration
27497			 **************************/
27498
27499			/* If the "nodeType" property exists on the elements variable, we're animating a single element.
27500			 Place it in an array so that $.each() can iterate over it. */
27501			$.each(elements, function(i, element) {
27502				/* Ensure each element in a set has a nodeType (is a real element) to avoid throwing errors. */
27503				if (Type.isNode(element)) {
27504					processElement(element, i);
27505				}
27506			});
27507
27508			/******************
27509			 Option: Loop
27510			 ******************/
27511
27512			/* The loop option accepts an integer indicating how many times the element should loop between the values in the
27513			 current call's properties map and the element's property values prior to this call. */
27514			/* Note: The loop option's logic is performed here -- after element processing -- because the current call needs
27515			 to undergo its queue insertion prior to the loop option generating its series of constituent "reverse" calls,
27516			 which chain after the current call. Two reverse calls (two "alternations") constitute one loop. */
27517			opts = $.extend({}, Velocity.defaults, options);
27518			opts.loop = parseInt(opts.loop, 10);
27519			var reverseCallsCount = (opts.loop * 2) - 1;
27520
27521			if (opts.loop) {
27522				/* Double the loop count to convert it into its appropriate number of "reverse" calls.
27523				 Subtract 1 from the resulting value since the current call is included in the total alternation count. */
27524				for (var x = 0; x < reverseCallsCount; x++) {
27525					/* Since the logic for the reverse action occurs inside Queueing and therefore this call's options object
27526					 isn't parsed until then as well, the current call's delay option must be explicitly passed into the reverse
27527					 call so that the delay logic that occurs inside *Pre-Queueing* can process it. */
27528					var reverseOptions = {
27529						delay: opts.delay,
27530						progress: opts.progress
27531					};
27532
27533					/* If a complete callback was passed into this call, transfer it to the loop redirect's final "reverse" call
27534					 so that it's triggered when the entire redirect is complete (and not when the very first animation is complete). */
27535					if (x === reverseCallsCount - 1) {
27536						reverseOptions.display = opts.display;
27537						reverseOptions.visibility = opts.visibility;
27538						reverseOptions.complete = opts.complete;
27539					}
27540
27541					animate(elements, "reverse", reverseOptions);
27542				}
27543			}
27544
27545			/***************
27546			 Chaining
27547			 ***************/
27548
27549			/* Return the elements back to the call chain, with wrapped elements taking precedence in case Velocity was called via the $.fn. extension. */
27550			return getChain();
27551		};
27552
27553		/* Turn Velocity into the animation function, extended with the pre-existing Velocity object. */
27554		Velocity = $.extend(animate, Velocity);
27555		/* For legacy support, also expose the literal animate method. */
27556		Velocity.animate = animate;
27557
27558		/**************
27559		 Timing
27560		 **************/
27561
27562		/* Ticker function. */
27563		var ticker = window.requestAnimationFrame || rAFShim;
27564
27565		/* Inactive browser tabs pause rAF, which results in all active animations immediately sprinting to their completion states when the tab refocuses.
27566		 To get around this, we dynamically switch rAF to setTimeout (which the browser *doesn't* pause) when the tab loses focus. We skip this for mobile
27567		 devices to avoid wasting battery power on inactive tabs. */
27568		/* Note: Tab focus detection doesn't work on older versions of IE, but that's okay since they don't support rAF to begin with. */
27569		if (!Velocity.State.isMobile && document.hidden !== undefined) {
27570			var updateTicker = function() {
27571				/* Reassign the rAF function (which the global tick() function uses) based on the tab's focus state. */
27572				if (document.hidden) {
27573					ticker = function(callback) {
27574						/* The tick function needs a truthy first argument in order to pass its internal timestamp check. */
27575						return setTimeout(function() {
27576							callback(true);
27577						}, 16);
27578					};
27579
27580					/* The rAF loop has been paused by the browser, so we manually restart the tick. */
27581					tick();
27582				} else {
27583					ticker = window.requestAnimationFrame || rAFShim;
27584				}
27585			};
27586
27587			/* Page could be sitting in the background at this time (i.e. opened as new tab) so making sure we use correct ticker from the start */
27588			updateTicker();
27589
27590			/* And then run check again every time visibility changes */
27591			document.addEventListener("visibilitychange", updateTicker);
27592		}
27593
27594		/************
27595		 Tick
27596		 ************/
27597
27598		/* Note: All calls to Velocity are pushed to the Velocity.State.calls array, which is fully iterated through upon each tick. */
27599		function tick(timestamp) {
27600			/* An empty timestamp argument indicates that this is the first tick occurence since ticking was turned on.
27601			 We leverage this metadata to fully ignore the first tick pass since RAF's initial pass is fired whenever
27602			 the browser's next tick sync time occurs, which results in the first elements subjected to Velocity
27603			 calls being animated out of sync with any elements animated immediately thereafter. In short, we ignore
27604			 the first RAF tick pass so that elements being immediately consecutively animated -- instead of simultaneously animated
27605			 by the same Velocity call -- are properly batched into the same initial RAF tick and consequently remain in sync thereafter. */
27606			if (timestamp) {
27607				/* We normally use RAF's high resolution timestamp but as it can be significantly offset when the browser is
27608				 under high stress we give the option for choppiness over allowing the browser to drop huge chunks of frames.
27609				 We use performance.now() and shim it if it doesn't exist for when the tab is hidden. */
27610				var timeCurrent = Velocity.timestamp && timestamp !== true ? timestamp : performance.now();
27611
27612				/********************
27613				 Call Iteration
27614				 ********************/
27615
27616				var callsLength = Velocity.State.calls.length;
27617
27618				/* To speed up iterating over this array, it is compacted (falsey items -- calls that have completed -- are removed)
27619				 when its length has ballooned to a point that can impact tick performance. This only becomes necessary when animation
27620				 has been continuous with many elements over a long period of time; whenever all active calls are completed, completeCall() clears Velocity.State.calls. */
27621				if (callsLength > 10000) {
27622					Velocity.State.calls = compactSparseArray(Velocity.State.calls);
27623					callsLength = Velocity.State.calls.length;
27624				}
27625
27626				/* Iterate through each active call. */
27627				for (var i = 0; i < callsLength; i++) {
27628					/* When a Velocity call is completed, its Velocity.State.calls entry is set to false. Continue on to the next call. */
27629					if (!Velocity.State.calls[i]) {
27630						continue;
27631					}
27632
27633					/************************
27634					 Call-Wide Variables
27635					 ************************/
27636
27637					var callContainer = Velocity.State.calls[i],
27638							call = callContainer[0],
27639							opts = callContainer[2],
27640							timeStart = callContainer[3],
27641							firstTick = !!timeStart,
27642							tweenDummyValue = null,
27643							pauseObject = callContainer[5],
27644							millisecondsEllapsed = callContainer[6];
27645
27646
27647
27648					/* If timeStart is undefined, then this is the first time that this call has been processed by tick().
27649					 We assign timeStart now so that its value is as close to the real animation start time as possible.
27650					 (Conversely, had timeStart been defined when this call was added to Velocity.State.calls, the delay
27651					 between that time and now would cause the first few frames of the tween to be skipped since
27652					 percentComplete is calculated relative to timeStart.) */
27653					/* Further, subtract 16ms (the approximate resolution of RAF) from the current time value so that the
27654					 first tick iteration isn't wasted by animating at 0% tween completion, which would produce the
27655					 same style value as the element's current value. */
27656					if (!timeStart) {
27657						timeStart = Velocity.State.calls[i][3] = timeCurrent - 16;
27658					}
27659
27660					/* If a pause object is present, skip processing unless it has been set to resume */
27661					if (pauseObject) {
27662						if (pauseObject.resume === true) {
27663							/* Update the time start to accomodate the paused completion amount */
27664							timeStart = callContainer[3] = Math.round(timeCurrent - millisecondsEllapsed - 16);
27665
27666							/* Remove pause object after processing */
27667							callContainer[5] = null;
27668						} else {
27669							continue;
27670						}
27671					}
27672
27673					millisecondsEllapsed = callContainer[6] = timeCurrent - timeStart;
27674
27675					/* The tween's completion percentage is relative to the tween's start time, not the tween's start value
27676					 (which would result in unpredictable tween durations since JavaScript's timers are not particularly accurate).
27677					 Accordingly, we ensure that percentComplete does not exceed 1. */
27678					var percentComplete = Math.min((millisecondsEllapsed) / opts.duration, 1);
27679
27680					/**********************
27681					 Element Iteration
27682					 **********************/
27683
27684					/* For every call, iterate through each of the elements in its set. */
27685					for (var j = 0, callLength = call.length; j < callLength; j++) {
27686						var tweensContainer = call[j],
27687								element = tweensContainer.element;
27688
27689						/* Check to see if this element has been deleted midway through the animation by checking for the
27690						 continued existence of its data cache. If it's gone, or the element is currently paused, skip animating this element. */
27691						if (!Data(element)) {
27692							continue;
27693						}
27694
27695						var transformPropertyExists = false;
27696
27697						/**********************************
27698						 Display & Visibility Toggling
27699						 **********************************/
27700
27701						/* If the display option is set to non-"none", set it upfront so that the element can become visible before tweening begins.
27702						 (Otherwise, display's "none" value is set in completeCall() once the animation has completed.) */
27703						if (opts.display !== undefined && opts.display !== null && opts.display !== "none") {
27704							if (opts.display === "flex") {
27705								var flexValues = ["-webkit-box", "-moz-box", "-ms-flexbox", "-webkit-flex"];
27706
27707								$.each(flexValues, function(i, flexValue) {
27708									CSS.setPropertyValue(element, "display", flexValue);
27709								});
27710							}
27711
27712							CSS.setPropertyValue(element, "display", opts.display);
27713						}
27714
27715						/* Same goes with the visibility option, but its "none" equivalent is "hidden". */
27716						if (opts.visibility !== undefined && opts.visibility !== "hidden") {
27717							CSS.setPropertyValue(element, "visibility", opts.visibility);
27718						}
27719
27720						/************************
27721						 Property Iteration
27722						 ************************/
27723
27724						/* For every element, iterate through each property. */
27725						for (var property in tweensContainer) {
27726							/* Note: In addition to property tween data, tweensContainer contains a reference to its associated element. */
27727							if (tweensContainer.hasOwnProperty(property) && property !== "element") {
27728								var tween = tweensContainer[property],
27729										currentValue,
27730										/* Easing can either be a pre-genereated function or a string that references a pre-registered easing
27731										 on the Velocity.Easings object. In either case, return the appropriate easing *function*. */
27732										easing = Type.isString(tween.easing) ? Velocity.Easings[tween.easing] : tween.easing;
27733
27734								/******************************
27735								 Current Value Calculation
27736								 ******************************/
27737
27738								if (Type.isString(tween.pattern)) {
27739									var patternReplace = percentComplete === 1 ?
27740											function($0, index, round) {
27741												var result = tween.endValue[index];
27742
27743												return round ? Math.round(result) : result;
27744											} :
27745											function($0, index, round) {
27746												var startValue = tween.startValue[index],
27747														tweenDelta = tween.endValue[index] - startValue,
27748														result = startValue + (tweenDelta * easing(percentComplete, opts, tweenDelta));
27749
27750												return round ? Math.round(result) : result;
27751											};
27752
27753									currentValue = tween.pattern.replace(/{(\d+)(!)?}/g, patternReplace);
27754								} else if (percentComplete === 1) {
27755									/* If this is the last tick pass (if we've reached 100% completion for this tween),
27756									 ensure that currentValue is explicitly set to its target endValue so that it's not subjected to any rounding. */
27757									currentValue = tween.endValue;
27758								} else {
27759									/* Otherwise, calculate currentValue based on the current delta from startValue. */
27760									var tweenDelta = tween.endValue - tween.startValue;
27761
27762									currentValue = tween.startValue + (tweenDelta * easing(percentComplete, opts, tweenDelta));
27763									/* If no value change is occurring, don't proceed with DOM updating. */
27764								}
27765								if (!firstTick && (currentValue === tween.currentValue)) {
27766									continue;
27767								}
27768
27769								tween.currentValue = currentValue;
27770
27771								/* If we're tweening a fake 'tween' property in order to log transition values, update the one-per-call variable so that
27772								 it can be passed into the progress callback. */
27773								if (property === "tween") {
27774									tweenDummyValue = currentValue;
27775								} else {
27776									/******************
27777									 Hooks: Part I
27778									 ******************/
27779									var hookRoot;
27780
27781									/* For hooked properties, the newly-updated rootPropertyValueCache is cached onto the element so that it can be used
27782									 for subsequent hooks in this call that are associated with the same root property. If we didn't cache the updated
27783									 rootPropertyValue, each subsequent update to the root property in this tick pass would reset the previous hook's
27784									 updates to rootPropertyValue prior to injection. A nice performance byproduct of rootPropertyValue caching is that
27785									 subsequently chained animations using the same hookRoot but a different hook can use this cached rootPropertyValue. */
27786									if (CSS.Hooks.registered[property]) {
27787										hookRoot = CSS.Hooks.getRoot(property);
27788
27789										var rootPropertyValueCache = Data(element).rootPropertyValueCache[hookRoot];
27790
27791										if (rootPropertyValueCache) {
27792											tween.rootPropertyValue = rootPropertyValueCache;
27793										}
27794									}
27795
27796									/*****************
27797									 DOM Update
27798									 *****************/
27799
27800									/* setPropertyValue() returns an array of the property name and property value post any normalization that may have been performed. */
27801									/* Note: To solve an IE<=8 positioning bug, the unit type is dropped when setting a property value of 0. */
27802									var adjustedSetData = CSS.setPropertyValue(element, /* SET */
27803											property,
27804											tween.currentValue + (IE < 9 && parseFloat(currentValue) === 0 ? "" : tween.unitType),
27805											tween.rootPropertyValue,
27806											tween.scrollData);
27807
27808									/*******************
27809									 Hooks: Part II
27810									 *******************/
27811
27812									/* Now that we have the hook's updated rootPropertyValue (the post-processed value provided by adjustedSetData), cache it onto the element. */
27813									if (CSS.Hooks.registered[property]) {
27814										/* Since adjustedSetData contains normalized data ready for DOM updating, the rootPropertyValue needs to be re-extracted from its normalized form. ?? */
27815										if (CSS.Normalizations.registered[hookRoot]) {
27816											Data(element).rootPropertyValueCache[hookRoot] = CSS.Normalizations.registered[hookRoot]("extract", null, adjustedSetData[1]);
27817										} else {
27818											Data(element).rootPropertyValueCache[hookRoot] = adjustedSetData[1];
27819										}
27820									}
27821
27822									/***************
27823									 Transforms
27824									 ***************/
27825
27826									/* Flag whether a transform property is being animated so that flushTransformCache() can be triggered once this tick pass is complete. */
27827									if (adjustedSetData[0] === "transform") {
27828										transformPropertyExists = true;
27829									}
27830
27831								}
27832							}
27833						}
27834
27835						/****************
27836						 mobileHA
27837						 ****************/
27838
27839						/* If mobileHA is enabled, set the translate3d transform to null to force hardware acceleration.
27840						 It's safe to override this property since Velocity doesn't actually support its animation (hooks are used in its place). */
27841						if (opts.mobileHA) {
27842							/* Don't set the null transform hack if we've already done so. */
27843							if (Data(element).transformCache.translate3d === undefined) {
27844								/* All entries on the transformCache object are later concatenated into a single transform string via flushTransformCache(). */
27845								Data(element).transformCache.translate3d = "(0px, 0px, 0px)";
27846
27847								transformPropertyExists = true;
27848							}
27849						}
27850
27851						if (transformPropertyExists) {
27852							CSS.flushTransformCache(element);
27853						}
27854					}
27855
27856					/* The non-"none" display value is only applied to an element once -- when its associated call is first ticked through.
27857					 Accordingly, it's set to false so that it isn't re-processed by this call in the next tick. */
27858					if (opts.display !== undefined && opts.display !== "none") {
27859						Velocity.State.calls[i][2].display = false;
27860					}
27861					if (opts.visibility !== undefined && opts.visibility !== "hidden") {
27862						Velocity.State.calls[i][2].visibility = false;
27863					}
27864
27865					/* Pass the elements and the timing data (percentComplete, msRemaining, timeStart, tweenDummyValue) into the progress callback. */
27866					if (opts.progress) {
27867						opts.progress.call(callContainer[1],
27868								callContainer[1],
27869								percentComplete,
27870								Math.max(0, (timeStart + opts.duration) - timeCurrent),
27871								timeStart,
27872								tweenDummyValue);
27873					}
27874
27875					/* If this call has finished tweening, pass its index to completeCall() to handle call cleanup. */
27876					if (percentComplete === 1) {
27877						completeCall(i);
27878					}
27879				}
27880			}
27881
27882			/* Note: completeCall() sets the isTicking flag to false when the last call on Velocity.State.calls has completed. */
27883			if (Velocity.State.isTicking) {
27884				ticker(tick);
27885			}
27886		}
27887
27888		/**********************
27889		 Call Completion
27890		 **********************/
27891
27892		/* Note: Unlike tick(), which processes all active calls at once, call completion is handled on a per-call basis. */
27893		function completeCall(callIndex, isStopped) {
27894			/* Ensure the call exists. */
27895			if (!Velocity.State.calls[callIndex]) {
27896				return false;
27897			}
27898
27899			/* Pull the metadata from the call. */
27900			var call = Velocity.State.calls[callIndex][0],
27901					elements = Velocity.State.calls[callIndex][1],
27902					opts = Velocity.State.calls[callIndex][2],
27903					resolver = Velocity.State.calls[callIndex][4];
27904
27905			var remainingCallsExist = false;
27906
27907			/*************************
27908			 Element Finalization
27909			 *************************/
27910
27911			for (var i = 0, callLength = call.length; i < callLength; i++) {
27912				var element = call[i].element;
27913
27914				/* If the user set display to "none" (intending to hide the element), set it now that the animation has completed. */
27915				/* Note: display:none isn't set when calls are manually stopped (via Velocity("stop"). */
27916				/* Note: Display gets ignored with "reverse" calls and infinite loops, since this behavior would be undesirable. */
27917				if (!isStopped && !opts.loop) {
27918					if (opts.display === "none") {
27919						CSS.setPropertyValue(element, "display", opts.display);
27920					}
27921
27922					if (opts.visibility === "hidden") {
27923						CSS.setPropertyValue(element, "visibility", opts.visibility);
27924					}
27925				}
27926
27927				/* If the element's queue is empty (if only the "inprogress" item is left at position 0) or if its queue is about to run
27928				 a non-Velocity-initiated entry, turn off the isAnimating flag. A non-Velocity-initiatied queue entry's logic might alter
27929				 an element's CSS values and thereby cause Velocity's cached value data to go stale. To detect if a queue entry was initiated by Velocity,
27930				 we check for the existence of our special Velocity.queueEntryFlag declaration, which minifiers won't rename since the flag
27931				 is assigned to jQuery's global $ object and thus exists out of Velocity's own scope. */
27932				var data = Data(element);
27933
27934				if (opts.loop !== true && ($.queue(element)[1] === undefined || !/\.velocityQueueEntryFlag/i.test($.queue(element)[1]))) {
27935					/* The element may have been deleted. Ensure that its data cache still exists before acting on it. */
27936					if (data) {
27937						data.isAnimating = false;
27938						/* Clear the element's rootPropertyValueCache, which will become stale. */
27939						data.rootPropertyValueCache = {};
27940
27941						var transformHAPropertyExists = false;
27942						/* If any 3D transform subproperty is at its default value (regardless of unit type), remove it. */
27943						$.each(CSS.Lists.transforms3D, function(i, transformName) {
27944							var defaultValue = /^scale/.test(transformName) ? 1 : 0,
27945									currentValue = data.transformCache[transformName];
27946
27947							if (data.transformCache[transformName] !== undefined && new RegExp("^\\(" + defaultValue + "[^.]").test(currentValue)) {
27948								transformHAPropertyExists = true;
27949
27950								delete data.transformCache[transformName];
27951							}
27952						});
27953
27954						/* Mobile devices have hardware acceleration removed at the end of the animation in order to avoid hogging the GPU's memory. */
27955						if (opts.mobileHA) {
27956							transformHAPropertyExists = true;
27957							delete data.transformCache.translate3d;
27958						}
27959
27960						/* Flush the subproperty removals to the DOM. */
27961						if (transformHAPropertyExists) {
27962							CSS.flushTransformCache(element);
27963						}
27964
27965						/* Remove the "velocity-animating" indicator class. */
27966						CSS.Values.removeClass(element, "velocity-animating");
27967					}
27968				}
27969
27970				/*********************
27971				 Option: Complete
27972				 *********************/
27973
27974				/* Complete is fired once per call (not once per element) and is passed the full raw DOM element set as both its context and its first argument. */
27975				/* Note: Callbacks aren't fired when calls are manually stopped (via Velocity("stop"). */
27976				if (!isStopped && opts.complete && !opts.loop && (i === callLength - 1)) {
27977					/* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */
27978					try {
27979						opts.complete.call(elements, elements);
27980					} catch (error) {
27981						setTimeout(function() {
27982							throw error;
27983						}, 1);
27984					}
27985				}
27986
27987				/**********************
27988				 Promise Resolving
27989				 **********************/
27990
27991				/* Note: Infinite loops don't return promises. */
27992				if (resolver && opts.loop !== true) {
27993					resolver(elements);
27994				}
27995
27996				/****************************
27997				 Option: Loop (Infinite)
27998				 ****************************/
27999
28000				if (data && opts.loop === true && !isStopped) {
28001					/* If a rotateX/Y/Z property is being animated by 360 deg with loop:true, swap tween start/end values to enable
28002					 continuous iterative rotation looping. (Otherise, the element would just rotate back and forth.) */
28003					$.each(data.tweensContainer, function(propertyName, tweenContainer) {
28004						if (/^rotate/.test(propertyName) && ((parseFloat(tweenContainer.startValue) - parseFloat(tweenContainer.endValue)) % 360 === 0)) {
28005							var oldStartValue = tweenContainer.startValue;
28006
28007							tweenContainer.startValue = tweenContainer.endValue;
28008							tweenContainer.endValue = oldStartValue;
28009						}
28010
28011						if (/^backgroundPosition/.test(propertyName) && parseFloat(tweenContainer.endValue) === 100 && tweenContainer.unitType === "%") {
28012							tweenContainer.endValue = 0;
28013							tweenContainer.startValue = 100;
28014						}
28015					});
28016
28017					Velocity(element, "reverse", {loop: true, delay: opts.delay});
28018				}
28019
28020				/***************
28021				 Dequeueing
28022				 ***************/
28023
28024				/* Fire the next call in the queue so long as this call's queue wasn't set to false (to trigger a parallel animation),
28025				 which would have already caused the next call to fire. Note: Even if the end of the animation queue has been reached,
28026				 $.dequeue() must still be called in order to completely clear jQuery's animation queue. */
28027				if (opts.queue !== false) {
28028					$.dequeue(element, opts.queue);
28029				}
28030			}
28031
28032			/************************
28033			 Calls Array Cleanup
28034			 ************************/
28035
28036			/* Since this call is complete, set it to false so that the rAF tick skips it. This array is later compacted via compactSparseArray().
28037			 (For performance reasons, the call is set to false instead of being deleted from the array: http://www.html5rocks.com/en/tutorials/speed/v8/) */
28038			Velocity.State.calls[callIndex] = false;
28039
28040			/* Iterate through the calls array to determine if this was the final in-progress animation.
28041			 If so, set a flag to end ticking and clear the calls array. */
28042			for (var j = 0, callsLength = Velocity.State.calls.length; j < callsLength; j++) {
28043				if (Velocity.State.calls[j] !== false) {
28044					remainingCallsExist = true;
28045
28046					break;
28047				}
28048			}
28049
28050			if (remainingCallsExist === false) {
28051				/* tick() will detect this flag upon its next iteration and subsequently turn itself off. */
28052				Velocity.State.isTicking = false;
28053
28054				/* Clear the calls array so that its length is reset. */
28055				delete Velocity.State.calls;
28056				Velocity.State.calls = [];
28057			}
28058		}
28059
28060		/******************
28061		 Frameworks
28062		 ******************/
28063
28064		/* Both jQuery and Zepto allow their $.fn object to be extended to allow wrapped elements to be subjected to plugin calls.
28065		 If either framework is loaded, register a "velocity" extension pointing to Velocity's core animate() method.  Velocity
28066		 also registers itself onto a global container (window.jQuery || window.Zepto || window) so that certain features are
28067		 accessible beyond just a per-element scope. This master object contains an .animate() method, which is later assigned to $.fn
28068		 (if jQuery or Zepto are present). Accordingly, Velocity can both act on wrapped DOM elements and stand alone for targeting raw DOM elements. */
28069		global.Velocity = Velocity;
28070
28071		if (global !== window) {
28072			/* Assign the element function to Velocity's core animate() method. */
28073			global.fn.velocity = animate;
28074			/* Assign the object function's defaults to Velocity's global defaults object. */
28075			global.fn.velocity.defaults = Velocity.defaults;
28076		}
28077
28078		/***********************
28079		 Packaged Redirects
28080		 ***********************/
28081
28082		/* slideUp, slideDown */
28083		$.each(["Down", "Up"], function(i, direction) {
28084			Velocity.Redirects["slide" + direction] = function(element, options, elementsIndex, elementsSize, elements, promiseData) {
28085				var opts = $.extend({}, options),
28086						begin = opts.begin,
28087						complete = opts.complete,
28088						inlineValues = {},
28089						computedValues = {height: "", marginTop: "", marginBottom: "", paddingTop: "", paddingBottom: ""};
28090
28091				if (opts.display === undefined) {
28092					/* Show the element before slideDown begins and hide the element after slideUp completes. */
28093					/* Note: Inline elements cannot have dimensions animated, so they're reverted to inline-block. */
28094					opts.display = (direction === "Down" ? (Velocity.CSS.Values.getDisplayType(element) === "inline" ? "inline-block" : "block") : "none");
28095				}
28096
28097				opts.begin = function() {
28098					/* If the user passed in a begin callback, fire it now. */
28099					if (elementsIndex === 0 && begin) {
28100						begin.call(elements, elements);
28101					}
28102
28103					/* Cache the elements' original vertical dimensional property values so that we can animate back to them. */
28104					for (var property in computedValues) {
28105						if (!computedValues.hasOwnProperty(property)) {
28106							continue;
28107						}
28108						inlineValues[property] = element.style[property];
28109
28110						/* For slideDown, use forcefeeding to animate all vertical properties from 0. For slideUp,
28111						 use forcefeeding to start from computed values and animate down to 0. */
28112						var propertyValue = CSS.getPropertyValue(element, property);
28113						computedValues[property] = (direction === "Down") ? [propertyValue, 0] : [0, propertyValue];
28114					}
28115
28116					/* Force vertical overflow content to clip so that sliding works as expected. */
28117					inlineValues.overflow = element.style.overflow;
28118					element.style.overflow = "hidden";
28119				};
28120
28121				opts.complete = function() {
28122					/* Reset element to its pre-slide inline values once its slide animation is complete. */
28123					for (var property in inlineValues) {
28124						if (inlineValues.hasOwnProperty(property)) {
28125							element.style[property] = inlineValues[property];
28126						}
28127					}
28128
28129					/* If the user passed in a complete callback, fire it now. */
28130					if (elementsIndex === elementsSize - 1) {
28131						if (complete) {
28132							complete.call(elements, elements);
28133						}
28134						if (promiseData) {
28135							promiseData.resolver(elements);
28136						}
28137					}
28138				};
28139
28140				Velocity(element, computedValues, opts);
28141			};
28142		});
28143
28144		/* fadeIn, fadeOut */
28145		$.each(["In", "Out"], function(i, direction) {
28146			Velocity.Redirects["fade" + direction] = function(element, options, elementsIndex, elementsSize, elements, promiseData) {
28147				var opts = $.extend({}, options),
28148						complete = opts.complete,
28149						propertiesMap = {opacity: (direction === "In") ? 1 : 0};
28150
28151				/* Since redirects are triggered individually for each element in the animated set, avoid repeatedly triggering
28152				 callbacks by firing them only when the final element has been reached. */
28153				if (elementsIndex !== 0) {
28154					opts.begin = null;
28155				}
28156				if (elementsIndex !== elementsSize - 1) {
28157					opts.complete = null;
28158				} else {
28159					opts.complete = function() {
28160						if (complete) {
28161							complete.call(elements, elements);
28162						}
28163						if (promiseData) {
28164							promiseData.resolver(elements);
28165						}
28166					};
28167				}
28168
28169				/* If a display was passed in, use it. Otherwise, default to "none" for fadeOut or the element-specific default for fadeIn. */
28170				/* Note: We allow users to pass in "null" to skip display setting altogether. */
28171				if (opts.display === undefined) {
28172					opts.display = (direction === "In" ? "auto" : "none");
28173				}
28174
28175				Velocity(this, propertiesMap, opts);
28176			};
28177		});
28178
28179		return Velocity;
28180	}((window.jQuery || window.Zepto || window), window, (window ? window.document : undefined));
28181}));
28182
28183/******************
28184 Known Issues
28185 ******************/
28186
28187/* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent.
28188 Velocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties
28189 will produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */
28190
28191},{}],5:[function(require,module,exports){
28192(function (global){(function (){
28193'use strict';
28194
28195var moment = require('moment');
28196var _ = require('lodash');
28197var salvattore = require('salvattore');
28198
28199var current_page = null;
28200$('.load-posts').on('click', function (e) {
28201  e.preventDefault();
28202  var domain = window.location.protocol + '//' + window.location.host,
28203      $btn = $(this),
28204      load = {
28205    slug: $btn.data('url'),
28206    text: $btn.text(),
28207    width: $btn.width(),
28208    current: parseInt($btn.data('current-page')),
28209    total: parseInt($btn.data('total-pages'))
28210  };
28211
28212  if (!current_page) {
28213    current_page = load.current;
28214  }
28215
28216  if (current_page >= load.total) {
28217    return;
28218  }
28219
28220  $btn.addClass('loading').width(load.width).text('Loading Posts');
28221  $.ajax({
28222    url: domain + load.slug + '/page/' + (parseInt(current_page) + 1),
28223    method: 'GET',
28224    success: function success(response) {
28225      current_page++;
28226      var grid = document.querySelector('#posts-list');
28227      salvattore.appendElements(grid, $(response).find('#posts-list article'));
28228      if (current_page >= load.total) {
28229        $('.pagination').velocity('slideUp', 800, 'easeInOutExpo', function () {
28230          $btn.addClass('is-hidden');
28231        });
28232      } else {
28233        $btn.removeClass('loading').text(load.text).css('width', '');
28234      }
28235    }
28236  });
28237});
28238
28239$('.posts-list').each(function () {
28240
28241  var $blogList = $(this);
28242  var showImage = $blogList.data('show-image');
28243  var postCount = $blogList.data('count');
28244  var feedType = $blogList.data('type');
28245  var feedURL = $blogList.data('feed');
28246  var grid = this;
28247
28248  if (!global.suppress || !$blogList.parents('.editable').length) {
28249
28250    $.ajax({
28251      url: global.appUrl + '/feed_api?url=' + encodeURIComponent(feedType == 'internal' ? global.siteUrl + feedURL : feedURL),
28252      method: 'GET',
28253      timeout: 10000,
28254      success: function success(response) {
28255        $blogList.find('.loading').remove();
28256        if (response.length) {
28257          if (postCount) response = response.slice(0, postCount);
28258
28259          response.forEach(function (item) {
28260
28261            var categories = '';
28262            item.categories.forEach(function (category) {
28263              categories += '<span class="category">' + category + '</span>';
28264            });
28265
28266            if (categories.length) {
28267              categories = '<span class="bullet"></span> <span class="post-categories">' + categories + '</span>';
28268            }
28269
28270            var image = item.image.url && showImage ? '<figure class="post-thumbnail"><img src="' + item.image.url + '" alt="' + item.title + ' thumbnail"></figure>' : '';
28271            var excerpt = item.description ? '<div class="post-excerpt">' + item.description + '</div>' : '';
28272            var date = item.date ? '<time datetime="' + moment(item.date).format('YYYY-MM-DD') + '">' + moment(item.date).format('MMMM D, YYYY') + '</time>' : '';
28273
28274            var article = $('<article class="post-link">\n                              <a href="' + item.link + '">\n                                ' + image + '\n                                <header class="post-header">\n                                  <h3>' + item.title + '</h3>\n                                </header>\n                              </a>\n                              <div class="post-meta">\n                                ' + date + '\n                                ' + categories + '\n                              </div>\n                              ' + excerpt + '\n                           </article>\n                        ');
28275
28276            salvattore.appendElements(grid, article);
28277          });
28278        } else {
28279          $blogList.append('<p class="loading">No Posts Found</p>');
28280        }
28281      },
28282      error: function error(_error) {
28283        console.log(_error);
28284        $blogList.find('.loading').remove();
28285        $blogList.append('<p class="loading">' + _error + '</p>');
28286      }
28287
28288    });
28289  }
28290});
28291
28292}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
28293},{"lodash":1,"moment":2,"salvattore":3}],6:[function(require,module,exports){
28294"use strict";
28295
28296require("salvattore");
28297require("./blogs");
28298require("velocity-animate");
28299
28300function checkHeader() {
28301  window.requestAnimationFrame(function () {
28302    if ($(window).scrollTop() > 0) {
28303      $("#page-wrapper").removeClass("transparent-header");
28304    } else {
28305      $("#page-wrapper").addClass("transparent-header");
28306    }
28307  }.bind(this));
28308}
28309
28310function headerPush() {
28311  var height = document.getElementById("header").offsetHeight;
28312  document.getElementsByClassName("header-push")[0].style.height = height + "px";
28313}
28314
28315if ($(".has-fixed-header.transparent-header").length) {
28316  $(window).on("scroll", checkHeader);
28317}
28318
28319$(function () {
28320  if ($(".header-push").length) {
28321    headerPush();
28322    $(window).on("resize", headerPush);
28323  }
28324});
28325
28326$(".scroll-down").on("click", function (e) {
28327  e.preventDefault();
28328  var offset = $("#page-wrapper.has-fixed-header").length ? -$("#header").height() : 0;
28329  $(".content-wrapper").velocity("scroll", {
28330    offset: offset,
28331    duration: 800,
28332    easing: "easeInOutCubic"
28333  });
28334});
28335
28336//reveal mobile nav
28337$(".menu-toggle").on("click", function (e) {
28338  e.preventDefault();
28339  $("html").addClass("pull-out-open");
28340  $(".pull-out-overlay").velocity("fadeIn", { duration: 400 });
28341  $("#page-wrapper, .has-fixed-header #header").velocity({ right: "260px" }, 600, "ease", function () {
28342    $("html").addClass("pull-out-open");
28343  });
28344});
28345
28346//hide mobile nav
28347$(".pull-out-overlay, .close-menu").on("click", function (e) {
28348  e.preventDefault();
28349  $(".pull-out-overlay").velocity("fadeOut", { duration: 400 });
28350  $("#page-wrapper, .has-fixed-header #header").velocity({ right: 0 }, 600, "ease", function () {
28351    $("html").removeClass("pull-out-open");
28352  });
28353});
28354
28355// overlays
28356$(".open-overlay").on("click", function (e) {
28357  e.preventDefault();
28358  var modal = $(this).data("target");
28359  $("html").addClass("overlay-open");
28360  if (modal) {
28361    $("#" + modal).addClass("is-showing");
28362  } else {
28363    $(this).parent().find(".overlay-content").addClass("is-showing");
28364  }
28365});
28366
28367$(".close-overlay").on("click", function (e) {
28368  e.preventDefault();
28369  $("html").removeClass("overlay-open");
28370  $(".overlay-content").removeClass("is-showing");
28371});
28372
28373// accordions
28374$(".toggle-accordion").on("click", function (e) {
28375  e.preventDefault();
28376
28377  if (window.suppress) return;
28378
28379  var $accordion = $(this).parent().find(".accordion-content");
28380  if ($(this).hasClass("open")) {
28381    $accordion.velocity("slideUp", 500, "easeInOutExpo", function () {});
28382  } else {
28383    $accordion.velocity("slideDown", 500, "easeInOutExpo", function () {});
28384  }
28385  $(this).toggleClass("open");
28386});
28387
28388},{"./blogs":5,"salvattore":3,"velocity-animate":4}]},{},[6]);

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.