PageSourceSearch

https://forthrightwealth.com/assets/frameworks/themes/iris/3.0.0/assets/dist/js/main-3.0.0.js

js forthrightwealth.com collected 2026-09-28 08:27:44 UTC 947,575 bytes, 28,574 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){
22902/*! VelocityJS.org (1.4.0). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
22903
22904/*************************
22905 Velocity jQuery Shim
22906 *************************/
22907
vendor: 193,527 bytes, lines 22908-27447
22908/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */
22909
22910/* 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. */
22911/* These shimmed functions are only used if jQuery isn't present. If both this shim and jQuery are loaded, Velocity defaults to jQuery proper. */
22912/* Browser support: Using this shim instead of jQuery proper removes support for IE8. */
22913
22914(function(window) {
22915	"use strict";
22916	/***************
22917	 Setup
22918	 ***************/
22919
22920	/* If jQuery is already loaded, there's no point in loading this shim. */
22921	if (window.jQuery) {
22922		return;
22923	}
22924
22925	/* jQuery base. */
22926	var $ = function(selector, context) {
22927		return new $.fn.init(selector, context);
22928	};
22929
22930	/********************
22931	 Private Methods
22932	 ********************/
22933
22934	/* jQuery */
22935	$.isWindow = function(obj) {
22936		/* jshint eqeqeq: false */
22937		return obj && obj === obj.window;
22938	};
22939
22940	/* jQuery */
22941	$.type = function(obj) {
22942		if (!obj) {
22943			return obj + "";
22944		}
22945
22946		return typeof obj === "object" || typeof obj === "function" ?
22947				class2type[toString.call(obj)] || "object" :
22948				typeof obj;
22949	};
22950
22951	/* jQuery */
22952	$.isArray = Array.isArray || function(obj) {
22953		return $.type(obj) === "array";
22954	};
22955
22956	/* jQuery */
22957	function isArraylike(obj) {
22958		var length = obj.length,
22959				type = $.type(obj);
22960
22961		if (type === "function" || $.isWindow(obj)) {
22962			return false;
22963		}
22964
22965		if (obj.nodeType === 1 && length) {
22966			return true;
22967		}
22968
22969		return type === "array" || length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj;
22970	}
22971
22972	/***************
22973	 $ Methods
22974	 ***************/
22975
22976	/* jQuery: Support removed for IE<9. */
22977	$.isPlainObject = function(obj) {
22978		var key;
22979
22980		if (!obj || $.type(obj) !== "object" || obj.nodeType || $.isWindow(obj)) {
22981			return false;
22982		}
22983
22984		try {
22985			if (obj.constructor &&
22986					!hasOwn.call(obj, "constructor") &&
22987					!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
22988				return false;
22989			}
22990		} catch (e) {
22991			return false;
22992		}
22993
22994		for (key in obj) {
22995		}
22996
22997		return key === undefined || hasOwn.call(obj, key);
22998	};
22999
23000	/* jQuery */
23001	$.each = function(obj, callback, args) {
23002		var value,
23003				i = 0,
23004				length = obj.length,
23005				isArray = isArraylike(obj);
23006
23007		if (args) {
23008			if (isArray) {
23009				for (; i < length; i++) {
23010					value = callback.apply(obj[i], args);
23011
23012					if (value === false) {
23013						break;
23014					}
23015				}
23016			} else {
23017				for (i in obj) {
23018					if (!obj.hasOwnProperty(i)) {
23019						continue;
23020					}
23021					value = callback.apply(obj[i], args);
23022
23023					if (value === false) {
23024						break;
23025					}
23026				}
23027			}
23028
23029		} else {
23030			if (isArray) {
23031				for (; i < length; i++) {
23032					value = callback.call(obj[i], i, obj[i]);
23033
23034					if (value === false) {
23035						break;
23036					}
23037				}
23038			} else {
23039				for (i in obj) {
23040					if (!obj.hasOwnProperty(i)) {
23041						continue;
23042					}
23043					value = callback.call(obj[i], i, obj[i]);
23044
23045					if (value === false) {
23046						break;
23047					}
23048				}
23049			}
23050		}
23051
23052		return obj;
23053	};
23054
23055	/* Custom */
23056	$.data = function(node, key, value) {
23057		/* $.getData() */
23058		if (value === undefined) {
23059			var getId = node[$.expando],
23060					store = getId && cache[getId];
23061
23062			if (key === undefined) {
23063				return store;
23064			} else if (store) {
23065				if (key in store) {
23066					return store[key];
23067				}
23068			}
23069			/* $.setData() */
23070		} else if (key !== undefined) {
23071			var setId = node[$.expando] || (node[$.expando] = ++$.uuid);
23072
23073			cache[setId] = cache[setId] || {};
23074			cache[setId][key] = value;
23075
23076			return value;
23077		}
23078	};
23079
23080	/* Custom */
23081	$.removeData = function(node, keys) {
23082		var id = node[$.expando],
23083				store = id && cache[id];
23084
23085		if (store) {
23086			// Cleanup the entire store if no keys are provided.
23087			if (!keys) {
23088				delete cache[id];
23089			} else {
23090				$.each(keys, function(_, key) {
23091					delete store[key];
23092				});
23093			}
23094		}
23095	};
23096
23097	/* jQuery */
23098	$.extend = function() {
23099		var src, copyIsArray, copy, name, options, clone,
23100				target = arguments[0] || {},
23101				i = 1,
23102				length = arguments.length,
23103				deep = false;
23104
23105		if (typeof target === "boolean") {
23106			deep = target;
23107
23108			target = arguments[i] || {};
23109			i++;
23110		}
23111
23112		if (typeof target !== "object" && $.type(target) !== "function") {
23113			target = {};
23114		}
23115
23116		if (i === length) {
23117			target = this;
23118			i--;
23119		}
23120
23121		for (; i < length; i++) {
23122			if ((options = arguments[i])) {
23123				for (name in options) {
23124					if (!options.hasOwnProperty(name)) {
23125						continue;
23126					}
23127					src = target[name];
23128					copy = options[name];
23129
23130					if (target === copy) {
23131						continue;
23132					}
23133
23134					if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
23135						if (copyIsArray) {
23136							copyIsArray = false;
23137							clone = src && $.isArray(src) ? src : [];
23138
23139						} else {
23140							clone = src && $.isPlainObject(src) ? src : {};
23141						}
23142
23143						target[name] = $.extend(deep, clone, copy);
23144
23145					} else if (copy !== undefined) {
23146						target[name] = copy;
23147					}
23148				}
23149			}
23150		}
23151
23152		return target;
23153	};
23154
23155	/* jQuery 1.4.3 */
23156	$.queue = function(elem, type, data) {
23157		function $makeArray(arr, results) {
23158			var ret = results || [];
23159
23160			if (arr) {
23161				if (isArraylike(Object(arr))) {
23162					/* $.merge */
23163					(function(first, second) {
23164						var len = +second.length,
23165								j = 0,
23166								i = first.length;
23167
23168						while (j < len) {
23169							first[i++] = second[j++];
23170						}
23171
23172						if (len !== len) {
23173							while (second[j] !== undefined) {
23174								first[i++] = second[j++];
23175							}
23176						}
23177
23178						first.length = i;
23179
23180						return first;
23181					})(ret, typeof arr === "string" ? [arr] : arr);
23182				} else {
23183					[].push.call(ret, arr);
23184				}
23185			}
23186
23187			return ret;
23188		}
23189
23190		if (!elem) {
23191			return;
23192		}
23193
23194		type = (type || "fx") + "queue";
23195
23196		var q = $.data(elem, type);
23197
23198		if (!data) {
23199			return q || [];
23200		}
23201
23202		if (!q || $.isArray(data)) {
23203			q = $.data(elem, type, $makeArray(data));
23204		} else {
23205			q.push(data);
23206		}
23207
23208		return q;
23209	};
23210
23211	/* jQuery 1.4.3 */
23212	$.dequeue = function(elems, type) {
23213		/* Custom: Embed element iteration. */
23214		$.each(elems.nodeType ? [elems] : elems, function(i, elem) {
23215			type = type || "fx";
23216
23217			var queue = $.queue(elem, type),
23218					fn = queue.shift();
23219
23220			if (fn === "inprogress") {
23221				fn = queue.shift();
23222			}
23223
23224			if (fn) {
23225				if (type === "fx") {
23226					queue.unshift("inprogress");
23227				}
23228
23229				fn.call(elem, function() {
23230					$.dequeue(elem, type);
23231				});
23232			}
23233		});
23234	};
23235
23236	/******************
23237	 $.fn Methods
23238	 ******************/
23239
23240	/* jQuery */
23241	$.fn = $.prototype = {
23242		init: function(selector) {
23243			/* Just return the element wrapped inside an array; don't proceed with the actual jQuery node wrapping process. */
23244			if (selector.nodeType) {
23245				this[0] = selector;
23246
23247				return this;
23248			} else {
23249				throw new Error("Not a DOM node.");
23250			}
23251		},
23252		offset: function() {
23253			/* jQuery altered code: Dropped disconnected DOM node checking. */
23254			var box = this[0].getBoundingClientRect ? this[0].getBoundingClientRect() : {top: 0, left: 0};
23255
23256			return {
23257				top: box.top + (window.pageYOffset || document.scrollTop || 0) - (document.clientTop || 0),
23258				left: box.left + (window.pageXOffset || document.scrollLeft || 0) - (document.clientLeft || 0)
23259			};
23260		},
23261		position: function() {
23262			/* jQuery */
23263			function offsetParentFn(elem) {
23264				var offsetParent = elem.offsetParent;
23265
23266				while (offsetParent && offsetParent.nodeName.toLowerCase() !== "html" && offsetParent.style && offsetParent.style.position === "static") {
23267					offsetParent = offsetParent.offsetParent;
23268				}
23269
23270				return offsetParent || document;
23271			}
23272
23273			/* Zepto */
23274			var elem = this[0],
23275					offsetParent = offsetParentFn(elem),
23276					offset = this.offset(),
23277					parentOffset = /^(?:body|html)$/i.test(offsetParent.nodeName) ? {top: 0, left: 0} : $(offsetParent).offset();
23278
23279			offset.top -= parseFloat(elem.style.marginTop) || 0;
23280			offset.left -= parseFloat(elem.style.marginLeft) || 0;
23281
23282			if (offsetParent.style) {
23283				parentOffset.top += parseFloat(offsetParent.style.borderTopWidth) || 0;
23284				parentOffset.left += parseFloat(offsetParent.style.borderLeftWidth) || 0;
23285			}
23286
23287			return {
23288				top: offset.top - parentOffset.top,
23289				left: offset.left - parentOffset.left
23290			};
23291		}
23292	};
23293
23294	/**********************
23295	 Private Variables
23296	 **********************/
23297
23298	/* For $.data() */
23299	var cache = {};
23300	$.expando = "velocity" + (new Date().getTime());
23301	$.uuid = 0;
23302
23303	/* For $.queue() */
23304	var class2type = {},
23305			hasOwn = class2type.hasOwnProperty,
23306			toString = class2type.toString;
23307
23308	var types = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
23309	for (var i = 0; i < types.length; i++) {
23310		class2type["[object " + types[i] + "]"] = types[i].toLowerCase();
23311	}
23312
23313	/* Makes $(node) possible, without having to call init. */
23314	$.fn.init.prototype = $.fn;
23315
23316	/* Globalize Velocity onto the window, and assign its Utilities property. */
23317	window.Velocity = {Utilities: $};
23318})(window);
23319
23320/******************
23321 Velocity.js
23322 ******************/
23323
23324(function(factory) {
23325	"use strict";
23326	/* CommonJS module. */
23327	if (typeof module === "object" && typeof module.exports === "object") {
23328		module.exports = factory();
23329		/* AMD module. */
23330	} else if (typeof define === "function" && define.amd) {
23331		define(factory);
23332		/* Browser globals. */
23333	} else {
23334		factory();
23335	}
23336}(function() {
23337	"use strict";
23338	return function(global, window, document, undefined) {
23339
23340		/***************
23341		 Summary
23342		 ***************/
23343
23344		/*
23345		 - CSS: CSS stack that works independently from the rest of Velocity.
23346		 - animate(): Core animation method that iterates over the targeted elements and queues the incoming call onto each element individually.
23347		 - Pre-Queueing: Prepare the element for animation by instantiating its data cache and processing the call's options.
23348		 - Queueing: The logic that runs once the call has reached its point of execution in the element's $.queue() stack.
23349		 Most logic is placed here to avoid risking it becoming stale (if the element's properties have changed).
23350		 - Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.
23351		 - tick(): The single requestAnimationFrame loop responsible for tweening all in-progress calls.
23352		 - completeCall(): Handles the cleanup process for each Velocity call.
23353		 */
23354
23355		/*********************
23356		 Helper Functions
23357		 *********************/
23358
23359		/* IE detection. Gist: https://gist.github.com/julianshapiro/9098609 */
23360		var IE = (function() {
23361			if (document.documentMode) {
23362				return document.documentMode;
23363			} else {
23364				for (var i = 7; i > 4; i--) {
23365					var div = document.createElement("div");
23366
23367					div.innerHTML = "<!--[if IE " + i + "]><span></span><![endif]-->";
23368
23369					if (div.getElementsByTagName("span").length) {
23370						div = null;
23371
23372						return i;
23373					}
23374				}
23375			}
23376
23377			return undefined;
23378		})();
23379
23380		/* rAF shim. Gist: https://gist.github.com/julianshapiro/9497513 */
23381		var rAFShim = (function() {
23382			var timeLast = 0;
23383
23384			return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
23385				var timeCurrent = (new Date()).getTime(),
23386						timeDelta;
23387
23388				/* Dynamically set delay on a per-tick basis to match 60fps. */
23389				/* Technique by Erik Moller. MIT license: https://gist.github.com/paulirish/1579671 */
23390				timeDelta = Math.max(0, 16 - (timeCurrent - timeLast));
23391				timeLast = timeCurrent + timeDelta;
23392
23393				return setTimeout(function() {
23394					callback(timeCurrent + timeDelta);
23395				}, timeDelta);
23396			};
23397		})();
23398
23399		var performance = (function() {
23400			var perf = window.performance || {};
23401
23402			if (!perf.hasOwnProperty("now")) {
23403				var nowOffset = perf.timing && perf.timing.domComplete ? perf.timing.domComplete : (new Date()).getTime();
23404
23405				perf.now = function() {
23406					return (new Date()).getTime() - nowOffset;
23407				};
23408			}
23409			return perf;
23410		})();
23411
23412		/* Array compacting. Copyright Lo-Dash. MIT License: https://github.com/lodash/lodash/blob/master/LICENSE.txt */
23413		function compactSparseArray(array) {
23414			var index = -1,
23415					length = array ? array.length : 0,
23416					result = [];
23417
23418			while (++index < length) {
23419				var value = array[index];
23420
23421				if (value) {
23422					result.push(value);
23423				}
23424			}
23425
23426			return result;
23427		}
23428
23429		function sanitizeElements(elements) {
23430			/* Unwrap jQuery/Zepto objects. */
23431			if (Type.isWrapped(elements)) {
23432				elements = [].slice.call(elements);
23433				/* Wrap a single element in an array so that $.each() can iterate with the element instead of its node's children. */
23434			} else if (Type.isNode(elements)) {
23435				elements = [elements];
23436			}
23437
23438			return elements;
23439		}
23440
23441		var Type = {
23442			isNumber: function(variable) {
23443				return (typeof variable === "number");
23444			},
23445			isString: function(variable) {
23446				return (typeof variable === "string");
23447			},
23448			isArray: Array.isArray || function(variable) {
23449				return Object.prototype.toString.call(variable) === "[object Array]";
23450			},
23451			isFunction: function(variable) {
23452				return Object.prototype.toString.call(variable) === "[object Function]";
23453			},
23454			isNode: function(variable) {
23455				return variable && variable.nodeType;
23456			},
23457			/* Copyright Martin Bohm. MIT License: https://gist.github.com/Tomalak/818a78a226a0738eaade */
23458			isNodeList: function(variable) {
23459				return typeof variable === "object" &&
23460						/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(variable)) &&
23461						variable.length !== undefined &&
23462						(variable.length === 0 || (typeof variable[0] === "object" && variable[0].nodeType > 0));
23463			},
23464			/* Determine if variable is an array-like wrapped jQuery, Zepto or similar element. */
23465			isWrapped: function(variable) {
23466				return variable && (Type.isArray(variable) || (Type.isNumber(variable.length) && !Type.isString(variable) && !Type.isFunction(variable)));
23467			},
23468			isSVG: function(variable) {
23469				return window.SVGElement && (variable instanceof window.SVGElement);
23470			},
23471			isEmptyObject: function(variable) {
23472				for (var name in variable) {
23473					if (variable.hasOwnProperty(name)) {
23474						return false;
23475					}
23476				}
23477
23478				return true;
23479			}
23480		};
23481
23482		/*****************
23483		 Dependencies
23484		 *****************/
23485
23486		var $,
23487				isJQuery = false;
23488
23489		if (global.fn && global.fn.jquery) {
23490			$ = global;
23491			isJQuery = true;
23492		} else {
23493			$ = window.Velocity.Utilities;
23494		}
23495
23496		if (IE <= 8 && !isJQuery) {
23497			throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");
23498		} else if (IE <= 7) {
23499			/* Revert to jQuery's $.animate(), and lose Velocity's extra features. */
23500			jQuery.fn.velocity = jQuery.fn.animate;
23501
23502			/* Now that $.fn.velocity is aliased, abort this Velocity declaration. */
23503			return;
23504		}
23505
23506		/*****************
23507		 Constants
23508		 *****************/
23509
23510		var DURATION_DEFAULT = 400,
23511				EASING_DEFAULT = "swing";
23512
23513		/*************
23514		 State
23515		 *************/
23516
23517		var Velocity = {
23518			/* Container for page-wide Velocity state data. */
23519			State: {
23520				/* Detect mobile devices to determine if mobileHA should be turned on. */
23521				isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
23522				/* The mobileHA option's behavior changes on older Android devices (Gingerbread, versions 2.3.3-2.3.7). */
23523				isAndroid: /Android/i.test(navigator.userAgent),
23524				isGingerbread: /Android 2\.3\.[3-7]/i.test(navigator.userAgent),
23525				isChrome: window.chrome,
23526				isFirefox: /Firefox/i.test(navigator.userAgent),
23527				/* Create a cached element for re-use when checking for CSS property prefixes. */
23528				prefixElement: document.createElement("div"),
23529				/* Cache every prefix match to avoid repeating lookups. */
23530				prefixMatches: {},
23531				/* Cache the anchor used for animating window scrolling. */
23532				scrollAnchor: null,
23533				/* Cache the browser-specific property names associated with the scroll anchor. */
23534				scrollPropertyLeft: null,
23535				scrollPropertyTop: null,
23536				/* Keep track of whether our RAF tick is running. */
23537				isTicking: false,
23538				/* Container for every in-progress call to Velocity. */
23539				calls: [],
23540				delayedElements: {
23541					count: 0
23542				}
23543			},
23544			/* Velocity's custom CSS stack. Made global for unit testing. */
23545			CSS: {/* Defined below. */},
23546			/* A shim of the jQuery utility functions used by Velocity -- provided by Velocity's optional jQuery shim. */
23547			Utilities: $,
23548			/* Container for the user's custom animation redirects that are referenced by name in place of the properties map argument. */
23549			Redirects: {/* Manually registered by the user. */},
23550			Easings: {/* Defined below. */},
23551			/* Attempt to use ES6 Promises by default. Users can override this with a third-party promises library. */
23552			Promise: window.Promise,
23553			/* Velocity option defaults, which can be overriden by the user. */
23554			defaults: {
23555				queue: "",
23556				duration: DURATION_DEFAULT,
23557				easing: EASING_DEFAULT,
23558				begin: undefined,
23559				complete: undefined,
23560				progress: undefined,
23561				display: undefined,
23562				visibility: undefined,
23563				loop: false,
23564				delay: false,
23565				mobileHA: true,
23566				/* Advanced: Set to false to prevent property values from being cached between consecutive Velocity-initiated chain calls. */
23567				_cacheValues: true,
23568				/* Advanced: Set to false if the promise should always resolve on empty element lists. */
23569				promiseRejectEmpty: true
23570			},
23571			/* A design goal of Velocity is to cache data wherever possible in order to avoid DOM requerying. Accordingly, each element has a data cache. */
23572			init: function(element) {
23573				$.data(element, "velocity", {
23574					/* Store whether this is an SVG element, since its properties are retrieved and updated differently than standard HTML elements. */
23575					isSVG: Type.isSVG(element),
23576					/* Keep track of whether the element is currently being animated by Velocity.
23577					 This is used to ensure that property values are not transferred between non-consecutive (stale) calls. */
23578					isAnimating: false,
23579					/* A reference to the element's live computedStyle object. Learn more here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */
23580					computedStyle: null,
23581					/* Tween data is cached for each animation on the element so that data can be passed across calls --
23582					 in particular, end values are used as subsequent start values in consecutive Velocity calls. */
23583					tweensContainer: null,
23584					/* The full root property values of each CSS hook being animated on this element are cached so that:
23585					 1) Concurrently-animating hooks sharing the same root can have their root values' merged into one while tweening.
23586					 2) Post-hook-injection root values can be transferred over to consecutively chained Velocity calls as starting root values. */
23587					rootPropertyValueCache: {},
23588					/* A cache for transform updates, which must be manually flushed via CSS.flushTransformCache(). */
23589					transformCache: {}
23590				});
23591			},
23592			/* A parallel to jQuery's $.css(), used for getting/setting Velocity's hooked CSS properties. */
23593			hook: null, /* Defined below. */
23594			/* Velocity-wide animation time remapping for testing purposes. */
23595			mock: false,
23596			version: {major: 1, minor: 4, patch: 0},
23597			/* Set to 1 or 2 (most verbose) to output debug info to console. */
23598			debug: false,
23599			/* Use rAF high resolution timestamp when available */
23600			timestamp: true,
23601			/* Pause all animations */
23602			pauseAll: function(queueName) {
23603				var currentTime = (new Date()).getTime();
23604
23605				$.each(Velocity.State.calls, function(i, activeCall) {
23606
23607					if (activeCall) {
23608
23609						/* If we have a queueName and this call is not on that queue, skip */
23610						if (queueName !== undefined && ((activeCall[2].queue !== queueName) || (activeCall[2].queue === false))) {
23611							return true;
23612						}
23613
23614						/* Set call to paused */
23615						activeCall[5] = {
23616							resume: false
23617						};
23618					}
23619				});
23620
23621				/* Pause timers on any currently delayed calls */
23622				$.each(Velocity.State.delayedElements, function(k, element) {
23623					if (!element) {
23624						return;
23625					}
23626					pauseDelayOnElement(element, currentTime);
23627				});
23628			},
23629			/* Resume all animations */
23630			resumeAll: function(queueName) {
23631				var currentTime = (new Date()).getTime();
23632
23633				$.each(Velocity.State.calls, function(i, activeCall) {
23634
23635					if (activeCall) {
23636
23637						/* If we have a queueName and this call is not on that queue, skip */
23638						if (queueName !== undefined && ((activeCall[2].queue !== queueName) || (activeCall[2].queue === false))) {
23639							return true;
23640						}
23641
23642						/* Set call to resumed if it was paused */
23643						if (activeCall[5]) {
23644							activeCall[5].resume = true;
23645						}
23646					}
23647				});
23648				/* Resume timers on any currently delayed calls */
23649				$.each(Velocity.State.delayedElements, function(k, element) {
23650					if (!element) {
23651						return;
23652					}
23653					resumeDelayOnElement(element, currentTime);
23654				});
23655			}
23656		};
23657
23658		/* Retrieve the appropriate scroll anchor and property name for the browser: https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY */
23659		if (window.pageYOffset !== undefined) {
23660			Velocity.State.scrollAnchor = window;
23661			Velocity.State.scrollPropertyLeft = "pageXOffset";
23662			Velocity.State.scrollPropertyTop = "pageYOffset";
23663		} else {
23664			Velocity.State.scrollAnchor = document.documentElement || document.body.parentNode || document.body;
23665			Velocity.State.scrollPropertyLeft = "scrollLeft";
23666			Velocity.State.scrollPropertyTop = "scrollTop";
23667		}
23668
23669		/* Shorthand alias for jQuery's $.data() utility. */
23670		function Data(element) {
23671			/* Hardcode a reference to the plugin name. */
23672			var response = $.data(element, "velocity");
23673
23674			/* jQuery <=1.4.2 returns null instead of undefined when no match is found. We normalize this behavior. */
23675			return response === null ? undefined : response;
23676		}
23677
23678		/**************
23679		 Delay Timer
23680		 **************/
23681
23682		function pauseDelayOnElement(element, currentTime) {
23683			/* Check for any delay timers, and pause the set timeouts (while preserving time data)
23684			 to be resumed when the "resume" command is issued */
23685			var data = Data(element);
23686			if (data && data.delayTimer && !data.delayPaused) {
23687				data.delayRemaining = data.delay - currentTime + data.delayBegin;
23688				data.delayPaused = true;
23689				clearTimeout(data.delayTimer.setTimeout);
23690			}
23691		}
23692
23693		function resumeDelayOnElement(element, currentTime) {
23694			/* Check for any paused timers and resume */
23695			var data = Data(element);
23696			if (data && data.delayTimer && data.delayPaused) {
23697				/* If the element was mid-delay, re initiate the timeout with the remaining delay */
23698				data.delayPaused = false;
23699				data.delayTimer.setTimeout = setTimeout(data.delayTimer.next, data.delayRemaining);
23700			}
23701		}
23702
23703
23704
23705		/**************
23706		 Easing
23707		 **************/
23708
23709		/* Step easing generator. */
23710		function generateStep(steps) {
23711			return function(p) {
23712				return Math.round(p * steps) * (1 / steps);
23713			};
23714		}
23715
23716		/* Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */
23717		function generateBezier(mX1, mY1, mX2, mY2) {
23718			var NEWTON_ITERATIONS = 4,
23719					NEWTON_MIN_SLOPE = 0.001,
23720					SUBDIVISION_PRECISION = 0.0000001,
23721					SUBDIVISION_MAX_ITERATIONS = 10,
23722					kSplineTableSize = 11,
23723					kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),
23724					float32ArraySupported = "Float32Array" in window;
23725
23726			/* Must contain four arguments. */
23727			if (arguments.length !== 4) {
23728				return false;
23729			}
23730
23731			/* Arguments must be numbers. */
23732			for (var i = 0; i < 4; ++i) {
23733				if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) {
23734					return false;
23735				}
23736			}
23737
23738			/* X values must be in the [0, 1] range. */
23739			mX1 = Math.min(mX1, 1);
23740			mX2 = Math.min(mX2, 1);
23741			mX1 = Math.max(mX1, 0);
23742			mX2 = Math.max(mX2, 0);
23743
23744			var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
23745
23746			function A(aA1, aA2) {
23747				return 1.0 - 3.0 * aA2 + 3.0 * aA1;
23748			}
23749			function B(aA1, aA2) {
23750				return 3.0 * aA2 - 6.0 * aA1;
23751			}
23752			function C(aA1) {
23753				return 3.0 * aA1;
23754			}
23755
23756			function calcBezier(aT, aA1, aA2) {
23757				return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
23758			}
23759
23760			function getSlope(aT, aA1, aA2) {
23761				return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
23762			}
23763
23764			function newtonRaphsonIterate(aX, aGuessT) {
23765				for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
23766					var currentSlope = getSlope(aGuessT, mX1, mX2);
23767
23768					if (currentSlope === 0.0) {
23769						return aGuessT;
23770					}
23771
23772					var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
23773					aGuessT -= currentX / currentSlope;
23774				}
23775
23776				return aGuessT;
23777			}
23778
23779			function calcSampleValues() {
23780				for (var i = 0; i < kSplineTableSize; ++i) {
23781					mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
23782				}
23783			}
23784
23785			function binarySubdivide(aX, aA, aB) {
23786				var currentX, currentT, i = 0;
23787
23788				do {
23789					currentT = aA + (aB - aA) / 2.0;
23790					currentX = calcBezier(currentT, mX1, mX2) - aX;
23791					if (currentX > 0.0) {
23792						aB = currentT;
23793					} else {
23794						aA = currentT;
23795					}
23796				} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
23797
23798				return currentT;
23799			}
23800
23801			function getTForX(aX) {
23802				var intervalStart = 0.0,
23803						currentSample = 1,
23804						lastSample = kSplineTableSize - 1;
23805
23806				for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
23807					intervalStart += kSampleStepSize;
23808				}
23809
23810				--currentSample;
23811
23812				var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]),
23813						guessForT = intervalStart + dist * kSampleStepSize,
23814						initialSlope = getSlope(guessForT, mX1, mX2);
23815
23816				if (initialSlope >= NEWTON_MIN_SLOPE) {
23817					return newtonRaphsonIterate(aX, guessForT);
23818				} else if (initialSlope === 0.0) {
23819					return guessForT;
23820				} else {
23821					return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);
23822				}
23823			}
23824
23825			var _precomputed = false;
23826
23827			function precompute() {
23828				_precomputed = true;
23829				if (mX1 !== mY1 || mX2 !== mY2) {
23830					calcSampleValues();
23831				}
23832			}
23833
23834			var f = function(aX) {
23835				if (!_precomputed) {
23836					precompute();
23837				}
23838				if (mX1 === mY1 && mX2 === mY2) {
23839					return aX;
23840				}
23841				if (aX === 0) {
23842					return 0;
23843				}
23844				if (aX === 1) {
23845					return 1;
23846				}
23847
23848				return calcBezier(getTForX(aX), mY1, mY2);
23849			};
23850
23851			f.getControlPoints = function() {
23852				return [{x: mX1, y: mY1}, {x: mX2, y: mY2}];
23853			};
23854
23855			var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")";
23856			f.toString = function() {
23857				return str;
23858			};
23859
23860			return f;
23861		}
23862
23863		/* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */
23864		/* 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
23865		 then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */
23866		var generateSpringRK4 = (function() {
23867			function springAccelerationForState(state) {
23868				return (-state.tension * state.x) - (state.friction * state.v);
23869			}
23870
23871			function springEvaluateStateWithDerivative(initialState, dt, derivative) {
23872				var state = {
23873					x: initialState.x + derivative.dx * dt,
23874					v: initialState.v + derivative.dv * dt,
23875					tension: initialState.tension,
23876					friction: initialState.friction
23877				};
23878
23879				return {dx: state.v, dv: springAccelerationForState(state)};
23880			}
23881
23882			function springIntegrateState(state, dt) {
23883				var a = {
23884					dx: state.v,
23885					dv: springAccelerationForState(state)
23886				},
23887						b = springEvaluateStateWithDerivative(state, dt * 0.5, a),
23888						c = springEvaluateStateWithDerivative(state, dt * 0.5, b),
23889						d = springEvaluateStateWithDerivative(state, dt, c),
23890						dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),
23891						dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);
23892
23893				state.x = state.x + dxdt * dt;
23894				state.v = state.v + dvdt * dt;
23895
23896				return state;
23897			}
23898
23899			return function springRK4Factory(tension, friction, duration) {
23900
23901				var initState = {
23902					x: -1,
23903					v: 0,
23904					tension: null,
23905					friction: null
23906				},
23907						path = [0],
23908						time_lapsed = 0,
23909						tolerance = 1 / 10000,
23910						DT = 16 / 1000,
23911						have_duration, dt, last_state;
23912
23913				tension = parseFloat(tension) || 500;
23914				friction = parseFloat(friction) || 20;
23915				duration = duration || null;
23916
23917				initState.tension = tension;
23918				initState.friction = friction;
23919
23920				have_duration = duration !== null;
23921
23922				/* Calculate the actual time it takes for this animation to complete with the provided conditions. */
23923				if (have_duration) {
23924					/* Run the simulation without a duration. */
23925					time_lapsed = springRK4Factory(tension, friction);
23926					/* Compute the adjusted time delta. */
23927					dt = time_lapsed / duration * DT;
23928				} else {
23929					dt = DT;
23930				}
23931
23932				while (true) {
23933					/* Next/step function .*/
23934					last_state = springIntegrateState(last_state || initState, dt);
23935					/* Store the position. */
23936					path.push(1 + last_state.x);
23937					time_lapsed += 16;
23938					/* If the change threshold is reached, break. */
23939					if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {
23940						break;
23941					}
23942				}
23943
23944				/* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the
23945				 computed path and returns a snapshot of the position according to a given percentComplete. */
23946				return !have_duration ? time_lapsed : function(percentComplete) {
23947					return path[ (percentComplete * (path.length - 1)) | 0 ];
23948				};
23949			};
23950		}());
23951
23952		/* jQuery easings. */
23953		Velocity.Easings = {
23954			linear: function(p) {
23955				return p;
23956			},
23957			swing: function(p) {
23958				return 0.5 - Math.cos(p * Math.PI) / 2;
23959			},
23960			/* Bonus "spring" easing, which is a less exaggerated version of easeInOutElastic. */
23961			spring: function(p) {
23962				return 1 - (Math.cos(p * 4.5 * Math.PI) * Math.exp(-p * 6));
23963			}
23964		};
23965
23966		/* CSS3 and Robert Penner easings. */
23967		$.each(
23968				[
23969					["ease", [0.25, 0.1, 0.25, 1.0]],
23970					["ease-in", [0.42, 0.0, 1.00, 1.0]],
23971					["ease-out", [0.00, 0.0, 0.58, 1.0]],
23972					["ease-in-out", [0.42, 0.0, 0.58, 1.0]],
23973					["easeInSine", [0.47, 0, 0.745, 0.715]],
23974					["easeOutSine", [0.39, 0.575, 0.565, 1]],
23975					["easeInOutSine", [0.445, 0.05, 0.55, 0.95]],
23976					["easeInQuad", [0.55, 0.085, 0.68, 0.53]],
23977					["easeOutQuad", [0.25, 0.46, 0.45, 0.94]],
23978					["easeInOutQuad", [0.455, 0.03, 0.515, 0.955]],
23979					["easeInCubic", [0.55, 0.055, 0.675, 0.19]],
23980					["easeOutCubic", [0.215, 0.61, 0.355, 1]],
23981					["easeInOutCubic", [0.645, 0.045, 0.355, 1]],
23982					["easeInQuart", [0.895, 0.03, 0.685, 0.22]],
23983					["easeOutQuart", [0.165, 0.84, 0.44, 1]],
23984					["easeInOutQuart", [0.77, 0, 0.175, 1]],
23985					["easeInQuint", [0.755, 0.05, 0.855, 0.06]],
23986					["easeOutQuint", [0.23, 1, 0.32, 1]],
23987					["easeInOutQuint", [0.86, 0, 0.07, 1]],
23988					["easeInExpo", [0.95, 0.05, 0.795, 0.035]],
23989					["easeOutExpo", [0.19, 1, 0.22, 1]],
23990					["easeInOutExpo", [1, 0, 0, 1]],
23991					["easeInCirc", [0.6, 0.04, 0.98, 0.335]],
23992					["easeOutCirc", [0.075, 0.82, 0.165, 1]],
23993					["easeInOutCirc", [0.785, 0.135, 0.15, 0.86]]
23994				], function(i, easingArray) {
23995			Velocity.Easings[easingArray[0]] = generateBezier.apply(null, easingArray[1]);
23996		});
23997
23998		/* Determine the appropriate easing type given an easing input. */
23999		function getEasing(value, duration) {
24000			var easing = value;
24001
24002			/* The easing option can either be a string that references a pre-registered easing,
24003			 or it can be a two-/four-item array of integers to be converted into a bezier/spring function. */
24004			if (Type.isString(value)) {
24005				/* Ensure that the easing has been assigned to jQuery's Velocity.Easings object. */
24006				if (!Velocity.Easings[value]) {
24007					easing = false;
24008				}
24009			} else if (Type.isArray(value) && value.length === 1) {
24010				easing = generateStep.apply(null, value);
24011			} else if (Type.isArray(value) && value.length === 2) {
24012				/* springRK4 must be passed the animation's duration. */
24013				/* Note: If the springRK4 array contains non-numbers, generateSpringRK4() returns an easing
24014				 function generated with default tension and friction values. */
24015				easing = generateSpringRK4.apply(null, value.concat([duration]));
24016			} else if (Type.isArray(value) && value.length === 4) {
24017				/* Note: If the bezier array contains non-numbers, generateBezier() returns false. */
24018				easing = generateBezier.apply(null, value);
24019			} else {
24020				easing = false;
24021			}
24022
24023			/* Revert to the Velocity-wide default easing type, or fall back to "swing" (which is also jQuery's default)
24024			 if the Velocity-wide default has been incorrectly modified. */
24025			if (easing === false) {
24026				if (Velocity.Easings[Velocity.defaults.easing]) {
24027					easing = Velocity.defaults.easing;
24028				} else {
24029					easing = EASING_DEFAULT;
24030				}
24031			}
24032
24033			return easing;
24034		}
24035
24036		/*****************
24037		 CSS Stack
24038		 *****************/
24039
24040		/* The CSS object is a highly condensed and performant CSS stack that fully replaces jQuery's.
24041		 It handles the validation, getting, and setting of both standard CSS properties and CSS property hooks. */
24042		/* Note: A "CSS" shorthand is aliased so that our code is easier to read. */
24043		var CSS = Velocity.CSS = {
24044			/*************
24045			 RegEx
24046			 *************/
24047
24048			RegEx: {
24049				isHex: /^#([A-f\d]{3}){1,2}$/i,
24050				/* 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". */
24051				valueUnwrap: /^[A-z]+\((.*)\)$/i,
24052				wrappedValueAlreadyExtracted: /[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,
24053				/* 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" ]. */
24054				valueSplit: /([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/ig
24055			},
24056			/************
24057			 Lists
24058			 ************/
24059
24060			Lists: {
24061				colors: ["fill", "stroke", "stopColor", "color", "backgroundColor", "borderColor", "borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor", "outlineColor"],
24062				transformsBase: ["translateX", "translateY", "scale", "scaleX", "scaleY", "skewX", "skewY", "rotateZ"],
24063				transforms3D: ["transformPerspective", "translateZ", "scaleZ", "rotateX", "rotateY"],
24064				units: [
24065					"%", // relative
24066					"em", "ex", "ch", "rem", // font relative
24067					"vw", "vh", "vmin", "vmax", // viewport relative
24068					"cm", "mm", "Q", "in", "pc", "pt", "px", // absolute lengths
24069					"deg", "grad", "rad", "turn", // angles
24070					"s", "ms" // time
24071				],
24072				colorNames: {
24073					"aliceblue": "240,248,255",
24074					"antiquewhite": "250,235,215",
24075					"aquamarine": "127,255,212",
24076					"aqua": "0,255,255",
24077					"azure": "240,255,255",
24078					"beige": "245,245,220",
24079					"bisque": "255,228,196",
24080					"black": "0,0,0",
24081					"blanchedalmond": "255,235,205",
24082					"blueviolet": "138,43,226",
24083					"blue": "0,0,255",
24084					"brown": "165,42,42",
24085					"burlywood": "222,184,135",
24086					"cadetblue": "95,158,160",
24087					"chartreuse": "127,255,0",
24088					"chocolate": "210,105,30",
24089					"coral": "255,127,80",
24090					"cornflowerblue": "100,149,237",
24091					"cornsilk": "255,248,220",
24092					"crimson": "220,20,60",
24093					"cyan": "0,255,255",
24094					"darkblue": "0,0,139",
24095					"darkcyan": "0,139,139",
24096					"darkgoldenrod": "184,134,11",
24097					"darkgray": "169,169,169",
24098					"darkgrey": "169,169,169",
24099					"darkgreen": "0,100,0",
24100					"darkkhaki": "189,183,107",
24101					"darkmagenta": "139,0,139",
24102					"darkolivegreen": "85,107,47",
24103					"darkorange": "255,140,0",
24104					"darkorchid": "153,50,204",
24105					"darkred": "139,0,0",
24106					"darksalmon": "233,150,122",
24107					"darkseagreen": "143,188,143",
24108					"darkslateblue": "72,61,139",
24109					"darkslategray": "47,79,79",
24110					"darkturquoise": "0,206,209",
24111					"darkviolet": "148,0,211",
24112					"deeppink": "255,20,147",
24113					"deepskyblue": "0,191,255",
24114					"dimgray": "105,105,105",
24115					"dimgrey": "105,105,105",
24116					"dodgerblue": "30,144,255",
24117					"firebrick": "178,34,34",
24118					"floralwhite": "255,250,240",
24119					"forestgreen": "34,139,34",
24120					"fuchsia": "255,0,255",
24121					"gainsboro": "220,220,220",
24122					"ghostwhite": "248,248,255",
24123					"gold": "255,215,0",
24124					"goldenrod": "218,165,32",
24125					"gray": "128,128,128",
24126					"grey": "128,128,128",
24127					"greenyellow": "173,255,47",
24128					"green": "0,128,0",
24129					"honeydew": "240,255,240",
24130					"hotpink": "255,105,180",
24131					"indianred": "205,92,92",
24132					"indigo": "75,0,130",
24133					"ivory": "255,255,240",
24134					"khaki": "240,230,140",
24135					"lavenderblush": "255,240,245",
24136					"lavender": "230,230,250",
24137					"lawngreen": "124,252,0",
24138					"lemonchiffon": "255,250,205",
24139					"lightblue": "173,216,230",
24140					"lightcoral": "240,128,128",
24141					"lightcyan": "224,255,255",
24142					"lightgoldenrodyellow": "250,250,210",
24143					"lightgray": "211,211,211",
24144					"lightgrey": "211,211,211",
24145					"lightgreen": "144,238,144",
24146					"lightpink": "255,182,193",
24147					"lightsalmon": "255,160,122",
24148					"lightseagreen": "32,178,170",
24149					"lightskyblue": "135,206,250",
24150					"lightslategray": "119,136,153",
24151					"lightsteelblue": "176,196,222",
24152					"lightyellow": "255,255,224",
24153					"limegreen": "50,205,50",
24154					"lime": "0,255,0",
24155					"linen": "250,240,230",
24156					"magenta": "255,0,255",
24157					"maroon": "128,0,0",
24158					"mediumaquamarine": "102,205,170",
24159					"mediumblue": "0,0,205",
24160					"mediumorchid": "186,85,211",
24161					"mediumpurple": "147,112,219",
24162					"mediumseagreen": "60,179,113",
24163					"mediumslateblue": "123,104,238",
24164					"mediumspringgreen": "0,250,154",
24165					"mediumturquoise": "72,209,204",
24166					"mediumvioletred": "199,21,133",
24167					"midnightblue": "25,25,112",
24168					"mintcream": "245,255,250",
24169					"mistyrose": "255,228,225",
24170					"moccasin": "255,228,181",
24171					"navajowhite": "255,222,173",
24172					"navy": "0,0,128",
24173					"oldlace": "253,245,230",
24174					"olivedrab": "107,142,35",
24175					"olive": "128,128,0",
24176					"orangered": "255,69,0",
24177					"orange": "255,165,0",
24178					"orchid": "218,112,214",
24179					"palegoldenrod": "238,232,170",
24180					"palegreen": "152,251,152",
24181					"paleturquoise": "175,238,238",
24182					"palevioletred": "219,112,147",
24183					"papayawhip": "255,239,213",
24184					"peachpuff": "255,218,185",
24185					"peru": "205,133,63",
24186					"pink": "255,192,203",
24187					"plum": "221,160,221",
24188					"powderblue": "176,224,230",
24189					"purple": "128,0,128",
24190					"red": "255,0,0",
24191					"rosybrown": "188,143,143",
24192					"royalblue": "65,105,225",
24193					"saddlebrown": "139,69,19",
24194					"salmon": "250,128,114",
24195					"sandybrown": "244,164,96",
24196					"seagreen": "46,139,87",
24197					"seashell": "255,245,238",
24198					"sienna": "160,82,45",
24199					"silver": "192,192,192",
24200					"skyblue": "135,206,235",
24201					"slateblue": "106,90,205",
24202					"slategray": "112,128,144",
24203					"snow": "255,250,250",
24204					"springgreen": "0,255,127",
24205					"steelblue": "70,130,180",
24206					"tan": "210,180,140",
24207					"teal": "0,128,128",
24208					"thistle": "216,191,216",
24209					"tomato": "255,99,71",
24210					"turquoise": "64,224,208",
24211					"violet": "238,130,238",
24212					"wheat": "245,222,179",
24213					"whitesmoke": "245,245,245",
24214					"white": "255,255,255",
24215					"yellowgreen": "154,205,50",
24216					"yellow": "255,255,0"
24217				}
24218			},
24219			/************
24220			 Hooks
24221			 ************/
24222
24223			/* Hooks allow a subproperty (e.g. "boxShadowBlur") of a compound-value CSS property
24224			 (e.g. "boxShadow: X Y Blur Spread Color") to be animated as if it were a discrete property. */
24225			/* Note: Beyond enabling fine-grained property animation, hooking is necessary since Velocity only
24226			 tweens properties with single numeric values; unlike CSS transitions, Velocity does not interpolate compound-values. */
24227			Hooks: {
24228				/********************
24229				 Registration
24230				 ********************/
24231
24232				/* Templates are a concise way of indicating which subproperties must be individually registered for each compound-value CSS property. */
24233				/* Each template consists of the compound-value's base name, its constituent subproperty names, and those subproperties' default values. */
24234				templates: {
24235					"textShadow": ["Color X Y Blur", "black 0px 0px 0px"],
24236					"boxShadow": ["Color X Y Blur Spread", "black 0px 0px 0px 0px"],
24237					"clip": ["Top Right Bottom Left", "0px 0px 0px 0px"],
24238					"backgroundPosition": ["X Y", "0% 0%"],
24239					"transformOrigin": ["X Y Z", "50% 50% 0px"],
24240					"perspectiveOrigin": ["X Y", "50% 50%"]
24241				},
24242				/* A "registered" hook is one that has been converted from its template form into a live,
24243				 tweenable property. It contains data to associate it with its root property. */
24244				registered: {
24245					/* Note: A registered hook looks like this ==> textShadowBlur: [ "textShadow", 3 ],
24246					 which consists of the subproperty's name, the associated root property's name,
24247					 and the subproperty's position in the root's value. */
24248				},
24249				/* Convert the templates into individual hooks then append them to the registered object above. */
24250				register: function() {
24251					/* Color hooks registration: Colors are defaulted to white -- as opposed to black -- since colors that are
24252					 currently set to "transparent" default to their respective template below when color-animated,
24253					 and white is typically a closer match to transparent than black is. An exception is made for text ("color"),
24254					 which is almost always set closer to black than white. */
24255					for (var i = 0; i < CSS.Lists.colors.length; i++) {
24256						var rgbComponents = (CSS.Lists.colors[i] === "color") ? "0 0 0 1" : "255 255 255 1";
24257						CSS.Hooks.templates[CSS.Lists.colors[i]] = ["Red Green Blue Alpha", rgbComponents];
24258					}
24259
24260					var rootProperty,
24261							hookTemplate,
24262							hookNames;
24263
24264					/* In IE, color values inside compound-value properties are positioned at the end the value instead of at the beginning.
24265					 Thus, we re-arrange the templates accordingly. */
24266					if (IE) {
24267						for (rootProperty in CSS.Hooks.templates) {
24268							if (!CSS.Hooks.templates.hasOwnProperty(rootProperty)) {
24269								continue;
24270							}
24271							hookTemplate = CSS.Hooks.templates[rootProperty];
24272							hookNames = hookTemplate[0].split(" ");
24273
24274							var defaultValues = hookTemplate[1].match(CSS.RegEx.valueSplit);
24275
24276							if (hookNames[0] === "Color") {
24277								/* Reposition both the hook's name and its default value to the end of their respective strings. */
24278								hookNames.push(hookNames.shift());
24279								defaultValues.push(defaultValues.shift());
24280
24281								/* Replace the existing template for the hook's root property. */
24282								CSS.Hooks.templates[rootProperty] = [hookNames.join(" "), defaultValues.join(" ")];
24283							}
24284						}
24285					}
24286
24287					/* Hook registration. */
24288					for (rootProperty in CSS.Hooks.templates) {
24289						if (!CSS.Hooks.templates.hasOwnProperty(rootProperty)) {
24290							continue;
24291						}
24292						hookTemplate = CSS.Hooks.templates[rootProperty];
24293						hookNames = hookTemplate[0].split(" ");
24294
24295						for (var j in hookNames) {
24296							if (!hookNames.hasOwnProperty(j)) {
24297								continue;
24298							}
24299							var fullHookName = rootProperty + hookNames[j],
24300									hookPosition = j;
24301
24302							/* For each hook, register its full name (e.g. textShadowBlur) with its root property (e.g. textShadow)
24303							 and the hook's position in its template's default value string. */
24304							CSS.Hooks.registered[fullHookName] = [rootProperty, hookPosition];
24305						}
24306					}
24307				},
24308				/*****************************
24309				 Injection and Extraction
24310				 *****************************/
24311
24312				/* Look up the root property associated with the hook (e.g. return "textShadow" for "textShadowBlur"). */
24313				/* 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. */
24314				getRoot: function(property) {
24315					var hookData = CSS.Hooks.registered[property];
24316
24317					if (hookData) {
24318						return hookData[0];
24319					} else {
24320						/* If there was no hook match, return the property name untouched. */
24321						return property;
24322					}
24323				},
24324				getUnit: function(str, start) {
24325					var unit = (str.substr(start || 0, 5).match(/^[a-z%]+/) || [])[0] || "";
24326
24327					if (unit && CSS.Lists.units.indexOf(unit) >= 0) {
24328						return unit;
24329					}
24330					return "";
24331				},
24332				fixColors: function(str) {
24333					return str.replace(/(rgba?\(\s*)?(\b[a-z]+\b)/g, function($0, $1, $2) {
24334						if (CSS.Lists.colorNames.hasOwnProperty($2)) {
24335							return ($1 ? $1 : "rgba(") + CSS.Lists.colorNames[$2] + ($1 ? "" : ",1)");
24336						}
24337						return $1 + $2;
24338					});
24339				},
24340				/* Convert any rootPropertyValue, null or otherwise, into a space-delimited list of hook values so that
24341				 the targeted hook can be injected or extracted at its standard position. */
24342				cleanRootPropertyValue: function(rootProperty, rootPropertyValue) {
24343					/* If the rootPropertyValue is wrapped with "rgb()", "clip()", etc., remove the wrapping to normalize the value before manipulation. */
24344					if (CSS.RegEx.valueUnwrap.test(rootPropertyValue)) {
24345						rootPropertyValue = rootPropertyValue.match(CSS.RegEx.valueUnwrap)[1];
24346					}
24347
24348					/* If rootPropertyValue is a CSS null-value (from which there's inherently no hook value to extract),
24349					 default to the root's default value as defined in CSS.Hooks.templates. */
24350					/* Note: CSS null-values include "none", "auto", and "transparent". They must be converted into their
24351					 zero-values (e.g. textShadow: "none" ==> textShadow: "0px 0px 0px black") for hook manipulation to proceed. */
24352					if (CSS.Values.isCSSNullValue(rootPropertyValue)) {
24353						rootPropertyValue = CSS.Hooks.templates[rootProperty][1];
24354					}
24355
24356					return rootPropertyValue;
24357				},
24358				/* Extracted the hook's value from its root property's value. This is used to get the starting value of an animating hook. */
24359				extractValue: function(fullHookName, rootPropertyValue) {
24360					var hookData = CSS.Hooks.registered[fullHookName];
24361
24362					if (hookData) {
24363						var hookRoot = hookData[0],
24364								hookPosition = hookData[1];
24365
24366						rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);
24367
24368						/* Split rootPropertyValue into its constituent hook values then grab the desired hook at its standard position. */
24369						return rootPropertyValue.toString().match(CSS.RegEx.valueSplit)[hookPosition];
24370					} else {
24371						/* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */
24372						return rootPropertyValue;
24373					}
24374				},
24375				/* Inject the hook's value into its root property's value. This is used to piece back together the root property
24376				 once Velocity has updated one of its individually hooked values through tweening. */
24377				injectValue: function(fullHookName, hookValue, rootPropertyValue) {
24378					var hookData = CSS.Hooks.registered[fullHookName];
24379
24380					if (hookData) {
24381						var hookRoot = hookData[0],
24382								hookPosition = hookData[1],
24383								rootPropertyValueParts,
24384								rootPropertyValueUpdated;
24385
24386						rootPropertyValue = CSS.Hooks.cleanRootPropertyValue(hookRoot, rootPropertyValue);
24387
24388						/* Split rootPropertyValue into its individual hook values, replace the targeted value with hookValue,
24389						 then reconstruct the rootPropertyValue string. */
24390						rootPropertyValueParts = rootPropertyValue.toString().match(CSS.RegEx.valueSplit);
24391						rootPropertyValueParts[hookPosition] = hookValue;
24392						rootPropertyValueUpdated = rootPropertyValueParts.join(" ");
24393
24394						return rootPropertyValueUpdated;
24395					} else {
24396						/* If the provided fullHookName isn't a registered hook, return the rootPropertyValue that was passed in. */
24397						return rootPropertyValue;
24398					}
24399				}
24400			},
24401			/*******************
24402			 Normalizations
24403			 *******************/
24404
24405			/* Normalizations standardize CSS property manipulation by pollyfilling browser-specific implementations (e.g. opacity)
24406			 and reformatting special properties (e.g. clip, rgba) to look like standard ones. */
24407			Normalizations: {
24408				/* Normalizations are passed a normalization target (either the property's name, its extracted value, or its injected value),
24409				 the targeted element (which may need to be queried), and the targeted property value. */
24410				registered: {
24411					clip: function(type, element, propertyValue) {
24412						switch (type) {
24413							case "name":
24414								return "clip";
24415								/* Clip needs to be unwrapped and stripped of its commas during extraction. */
24416							case "extract":
24417								var extracted;
24418
24419								/* If Velocity also extracted this value, skip extraction. */
24420								if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {
24421									extracted = propertyValue;
24422								} else {
24423									/* Remove the "rect()" wrapper. */
24424									extracted = propertyValue.toString().match(CSS.RegEx.valueUnwrap);
24425
24426									/* Strip off commas. */
24427									extracted = extracted ? extracted[1].replace(/,(\s+)?/g, " ") : propertyValue;
24428								}
24429
24430								return extracted;
24431								/* Clip needs to be re-wrapped during injection. */
24432							case "inject":
24433								return "rect(" + propertyValue + ")";
24434						}
24435					},
24436					blur: function(type, element, propertyValue) {
24437						switch (type) {
24438							case "name":
24439								return Velocity.State.isFirefox ? "filter" : "-webkit-filter";
24440							case "extract":
24441								var extracted = parseFloat(propertyValue);
24442
24443								/* If extracted is NaN, meaning the value isn't already extracted. */
24444								if (!(extracted || extracted === 0)) {
24445									var blurComponent = propertyValue.toString().match(/blur\(([0-9]+[A-z]+)\)/i);
24446
24447									/* If the filter string had a blur component, return just the blur value and unit type. */
24448									if (blurComponent) {
24449										extracted = blurComponent[1];
24450										/* If the component doesn't exist, default blur to 0. */
24451									} else {
24452										extracted = 0;
24453									}
24454								}
24455
24456								return extracted;
24457								/* Blur needs to be re-wrapped during injection. */
24458							case "inject":
24459								/* For the blur effect to be fully de-applied, it needs to be set to "none" instead of 0. */
24460								if (!parseFloat(propertyValue)) {
24461									return "none";
24462								} else {
24463									return "blur(" + propertyValue + ")";
24464								}
24465						}
24466					},
24467					/* <=IE8 do not support the standard opacity property. They use filter:alpha(opacity=INT) instead. */
24468					opacity: function(type, element, propertyValue) {
24469						if (IE <= 8) {
24470							switch (type) {
24471								case "name":
24472									return "filter";
24473								case "extract":
24474									/* <=IE8 return a "filter" value of "alpha(opacity=\d{1,3})".
24475									 Extract the value and convert it to a decimal value to match the standard CSS opacity property's formatting. */
24476									var extracted = propertyValue.toString().match(/alpha\(opacity=(.*)\)/i);
24477
24478									if (extracted) {
24479										/* Convert to decimal value. */
24480										propertyValue = extracted[1] / 100;
24481									} else {
24482										/* When extracting opacity, default to 1 since a null value means opacity hasn't been set. */
24483										propertyValue = 1;
24484									}
24485
24486									return propertyValue;
24487								case "inject":
24488									/* Opacified elements are required to have their zoom property set to a non-zero value. */
24489									element.style.zoom = 1;
24490
24491									/* Setting the filter property on elements with certain font property combinations can result in a
24492									 highly unappealing ultra-bolding effect. There's no way to remedy this throughout a tween, but dropping the
24493									 value altogether (when opacity hits 1) at leasts ensures that the glitch is gone post-tweening. */
24494									if (parseFloat(propertyValue) >= 1) {
24495										return "";
24496									} else {
24497										/* As per the filter property's spec, convert the decimal value to a whole number and wrap the value. */
24498										return "alpha(opacity=" + parseInt(parseFloat(propertyValue) * 100, 10) + ")";
24499									}
24500							}
24501							/* With all other browsers, normalization is not required; return the same values that were passed in. */
24502						} else {
24503							switch (type) {
24504								case "name":
24505									return "opacity";
24506								case "extract":
24507									return propertyValue;
24508								case "inject":
24509									return propertyValue;
24510							}
24511						}
24512					}
24513				},
24514				/*****************************
24515				 Batched Registrations
24516				 *****************************/
24517
24518				/* Note: Batched normalizations extend the CSS.Normalizations.registered object. */
24519				register: function() {
24520
24521					/*****************
24522					 Transforms
24523					 *****************/
24524
24525					/* Transforms are the subproperties contained by the CSS "transform" property. Transforms must undergo normalization
24526					 so that they can be referenced in a properties map by their individual names. */
24527					/* Note: When transforms are "set", they are actually assigned to a per-element transformCache. When all transform
24528					 setting is complete complete, CSS.flushTransformCache() must be manually called to flush the values to the DOM.
24529					 Transform setting is batched in this way to improve performance: the transform style only needs to be updated
24530					 once when multiple transform subproperties are being animated simultaneously. */
24531					/* Note: IE9 and Android Gingerbread have support for 2D -- but not 3D -- transforms. Since animating unsupported
24532					 transform properties results in the browser ignoring the *entire* transform string, we prevent these 3D values
24533					 from being normalized for these browsers so that tweening skips these properties altogether
24534					 (since it will ignore them as being unsupported by the browser.) */
24535					if ((!IE || IE > 9) && !Velocity.State.isGingerbread) {
24536						/* Note: Since the standalone CSS "perspective" property and the CSS transform "perspective" subproperty
24537						 share the same name, the latter is given a unique token within Velocity: "transformPerspective". */
24538						CSS.Lists.transformsBase = CSS.Lists.transformsBase.concat(CSS.Lists.transforms3D);
24539					}
24540
24541					for (var i = 0; i < CSS.Lists.transformsBase.length; i++) {
24542						/* Wrap the dynamically generated normalization function in a new scope so that transformName's value is
24543						 paired with its respective function. (Otherwise, all functions would take the final for loop's transformName.) */
24544						(function() {
24545							var transformName = CSS.Lists.transformsBase[i];
24546
24547							CSS.Normalizations.registered[transformName] = function(type, element, propertyValue) {
24548								switch (type) {
24549									/* The normalized property name is the parent "transform" property -- the property that is actually set in CSS. */
24550									case "name":
24551										return "transform";
24552										/* Transform values are cached onto a per-element transformCache object. */
24553									case "extract":
24554										/* If this transform has yet to be assigned a value, return its null value. */
24555										if (Data(element) === undefined || Data(element).transformCache[transformName] === undefined) {
24556											/* Scale CSS.Lists.transformsBase default to 1 whereas all other transform properties default to 0. */
24557											return /^scale/i.test(transformName) ? 1 : 0;
24558											/* When transform values are set, they are wrapped in parentheses as per the CSS spec.
24559											 Thus, when extracting their values (for tween calculations), we strip off the parentheses. */
24560										}
24561										return Data(element).transformCache[transformName].replace(/[()]/g, "");
24562									case "inject":
24563										var invalid = false;
24564
24565										/* If an individual transform property contains an unsupported unit type, the browser ignores the *entire* transform property.
24566										 Thus, protect users from themselves by skipping setting for transform values supplied with invalid unit types. */
24567										/* Switch on the base transform type; ignore the axis by removing the last letter from the transform's name. */
24568										switch (transformName.substr(0, transformName.length - 1)) {
24569											/* Whitelist unit types for each transform. */
24570											case "translate":
24571												invalid = !/(%|px|em|rem|vw|vh|\d)$/i.test(propertyValue);
24572												break;
24573												/* 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. */
24574											case "scal":
24575											case "scale":
24576												/* Chrome on Android has a bug in which scaled elements blur if their initial scale
24577												 value is below 1 (which can happen with forcefeeding). Thus, we detect a yet-unset scale property
24578												 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 */
24579												if (Velocity.State.isAndroid && Data(element).transformCache[transformName] === undefined && propertyValue < 1) {
24580													propertyValue = 1;
24581												}
24582
24583												invalid = !/(\d)$/i.test(propertyValue);
24584												break;
24585											case "skew":
24586												invalid = !/(deg|\d)$/i.test(propertyValue);
24587												break;
24588											case "rotate":
24589												invalid = !/(deg|\d)$/i.test(propertyValue);
24590												break;
24591										}
24592
24593										if (!invalid) {
24594											/* As per the CSS spec, wrap the value in parentheses. */
24595											Data(element).transformCache[transformName] = "(" + propertyValue + ")";
24596										}
24597
24598										/* Although the value is set on the transformCache object, return the newly-updated value for the calling code to process as normal. */
24599										return Data(element).transformCache[transformName];
24600								}
24601							};
24602						})();
24603					}
24604
24605					/*************
24606					 Colors
24607					 *************/
24608
24609					/* Since Velocity only animates a single numeric value per property, color animation is achieved by hooking the individual RGBA components of CSS color properties.
24610					 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. */
24611					for (var j = 0; j < CSS.Lists.colors.length; j++) {
24612						/* Wrap the dynamically generated normalization function in a new scope so that colorName's value is paired with its respective function.
24613						 (Otherwise, all functions would take the final for loop's colorName.) */
24614						(function() {
24615							var colorName = CSS.Lists.colors[j];
24616
24617							/* Note: In IE<=8, which support rgb but not rgba, color properties are reverted to rgb by stripping off the alpha component. */
24618							CSS.Normalizations.registered[colorName] = function(type, element, propertyValue) {
24619								switch (type) {
24620									case "name":
24621										return colorName;
24622										/* Convert all color values into the rgb format. (Old IE can return hex values and color names instead of rgb/rgba.) */
24623									case "extract":
24624										var extracted;
24625
24626										/* If the color is already in its hookable form (e.g. "255 255 255 1") due to having been previously extracted, skip extraction. */
24627										if (CSS.RegEx.wrappedValueAlreadyExtracted.test(propertyValue)) {
24628											extracted = propertyValue;
24629										} else {
24630											var converted,
24631													colorNames = {
24632														black: "rgb(0, 0, 0)",
24633														blue: "rgb(0, 0, 255)",
24634														gray: "rgb(128, 128, 128)",
24635														green: "rgb(0, 128, 0)",
24636														red: "rgb(255, 0, 0)",
24637														white: "rgb(255, 255, 255)"
24638													};
24639
24640											/* Convert color names to rgb. */
24641											if (/^[A-z]+$/i.test(propertyValue)) {
24642												if (colorNames[propertyValue] !== undefined) {
24643													converted = colorNames[propertyValue];
24644												} else {
24645													/* If an unmatched color name is provided, default to black. */
24646													converted = colorNames.black;
24647												}
24648												/* Convert hex values to rgb. */
24649											} else if (CSS.RegEx.isHex.test(propertyValue)) {
24650												converted = "rgb(" + CSS.Values.hexToRgb(propertyValue).join(" ") + ")";
24651												/* If the provided color doesn't match any of the accepted color formats, default to black. */
24652											} else if (!(/^rgba?\(/i.test(propertyValue))) {
24653												converted = colorNames.black;
24654											}
24655
24656											/* Remove the surrounding "rgb/rgba()" string then replace commas with spaces and strip
24657											 repeated spaces (in case the value included spaces to begin with). */
24658											extracted = (converted || propertyValue).toString().match(CSS.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g, " ");
24659										}
24660
24661										/* So long as this isn't <=IE8, add a fourth (alpha) component if it's missing and default it to 1 (visible). */
24662										if ((!IE || IE > 8) && extracted.split(" ").length === 3) {
24663											extracted += " 1";
24664										}
24665
24666										return extracted;
24667									case "inject":
24668										/* If we have a pattern then it might already have the right values */
24669										if (/^rgb/.test(propertyValue)) {
24670											return propertyValue;
24671										}
24672
24673										/* If this is IE<=8 and an alpha component exists, strip it off. */
24674										if (IE <= 8) {
24675											if (propertyValue.split(" ").length === 4) {
24676												propertyValue = propertyValue.split(/\s+/).slice(0, 3).join(" ");
24677											}
24678											/* Otherwise, add a fourth (alpha) component if it's missing and default it to 1 (visible). */
24679										} else if (propertyValue.split(" ").length === 3) {
24680											propertyValue += " 1";
24681										}
24682
24683										/* Re-insert the browser-appropriate wrapper("rgb/rgba()"), insert commas, and strip off decimal units
24684										 on all values but the fourth (R, G, and B only accept whole numbers). */
24685										return (IE <= 8 ? "rgb" : "rgba") + "(" + propertyValue.replace(/\s+/g, ",").replace(/\.(\d)+(?=,)/g, "") + ")";
24686								}
24687							};
24688						})();
24689					}
24690
24691					/**************
24692					 Dimensions
24693					 **************/
24694					function augmentDimension(name, element, wantInner) {
24695						var isBorderBox = CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() === "border-box";
24696
24697						if (isBorderBox === (wantInner || false)) {
24698							/* in box-sizing mode, the CSS width / height accessors already give the outerWidth / outerHeight. */
24699							var i,
24700									value,
24701									augment = 0,
24702									sides = name === "width" ? ["Left", "Right"] : ["Top", "Bottom"],
24703									fields = ["padding" + sides[0], "padding" + sides[1], "border" + sides[0] + "Width", "border" + sides[1] + "Width"];
24704
24705							for (i = 0; i < fields.length; i++) {
24706								value = parseFloat(CSS.getPropertyValue(element, fields[i]));
24707								if (!isNaN(value)) {
24708									augment += value;
24709								}
24710							}
24711							return wantInner ? -augment : augment;
24712						}
24713						return 0;
24714					}
24715					function getDimension(name, wantInner) {
24716						return function(type, element, propertyValue) {
24717							switch (type) {
24718								case "name":
24719									return name;
24720								case "extract":
24721									return parseFloat(propertyValue) + augmentDimension(name, element, wantInner);
24722								case "inject":
24723									return (parseFloat(propertyValue) - augmentDimension(name, element, wantInner)) + "px";
24724							}
24725						};
24726					}
24727					CSS.Normalizations.registered.innerWidth = getDimension("width", true);
24728					CSS.Normalizations.registered.innerHeight = getDimension("height", true);
24729					CSS.Normalizations.registered.outerWidth = getDimension("width");
24730					CSS.Normalizations.registered.outerHeight = getDimension("height");
24731				}
24732			},
24733			/************************
24734			 CSS Property Names
24735			 ************************/
24736
24737			Names: {
24738				/* Camelcase a property name into its JavaScript notation (e.g. "background-color" ==> "backgroundColor").
24739				 Camelcasing is used to normalize property names between and across calls. */
24740				camelCase: function(property) {
24741					return property.replace(/-(\w)/g, function(match, subMatch) {
24742						return subMatch.toUpperCase();
24743					});
24744				},
24745				/* For SVG elements, some properties (namely, dimensional ones) are GET/SET via the element's HTML attributes (instead of via CSS styles). */
24746				SVGAttribute: function(property) {
24747					var SVGAttributes = "width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";
24748
24749					/* Certain browsers require an SVG transform to be applied as an attribute. (Otherwise, application via CSS is preferable due to 3D support.) */
24750					if (IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) {
24751						SVGAttributes += "|transform";
24752					}
24753
24754					return new RegExp("^(" + SVGAttributes + ")$", "i").test(property);
24755				},
24756				/* Determine whether a property should be set with a vendor prefix. */
24757				/* If a prefixed version of the property exists, return it. Otherwise, return the original property name.
24758				 If the property is not at all supported by the browser, return a false flag. */
24759				prefixCheck: function(property) {
24760					/* If this property has already been checked, return the cached value. */
24761					if (Velocity.State.prefixMatches[property]) {
24762						return [Velocity.State.prefixMatches[property], true];
24763					} else {
24764						var vendors = ["", "Webkit", "Moz", "ms", "O"];
24765
24766						for (var i = 0, vendorsLength = vendors.length; i < vendorsLength; i++) {
24767							var propertyPrefixed;
24768
24769							if (i === 0) {
24770								propertyPrefixed = property;
24771							} else {
24772								/* Capitalize the first letter of the property to conform to JavaScript vendor prefix notation (e.g. webkitFilter). */
24773								propertyPrefixed = vendors[i] + property.replace(/^\w/, function(match) {
24774									return match.toUpperCase();
24775								});
24776							}
24777
24778							/* Check if the browser supports this property as prefixed. */
24779							if (Type.isString(Velocity.State.prefixElement.style[propertyPrefixed])) {
24780								/* Cache the match. */
24781								Velocity.State.prefixMatches[property] = propertyPrefixed;
24782
24783								return [propertyPrefixed, true];
24784							}
24785						}
24786
24787						/* If the browser doesn't support this property in any form, include a false flag so that the caller can decide how to proceed. */
24788						return [property, false];
24789					}
24790				}
24791			},
24792			/************************
24793			 CSS Property Values
24794			 ************************/
24795
24796			Values: {
24797				/* Hex to RGB conversion. Copyright Tim Down: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb */
24798				hexToRgb: function(hex) {
24799					var shortformRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i,
24800							longformRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,
24801							rgbParts;
24802
24803					hex = hex.replace(shortformRegex, function(m, r, g, b) {
24804						return r + r + g + g + b + b;
24805					});
24806
24807					rgbParts = longformRegex.exec(hex);
24808
24809					return rgbParts ? [parseInt(rgbParts[1], 16), parseInt(rgbParts[2], 16), parseInt(rgbParts[3], 16)] : [0, 0, 0];
24810				},
24811				isCSSNullValue: function(value) {
24812					/* The browser defaults CSS values that have not been set to either 0 or one of several possible null-value strings.
24813					 Thus, we check for both falsiness and these special strings. */
24814					/* Null-value checking is performed to default the special strings to 0 (for the sake of tweening) or their hook
24815					 templates as defined as CSS.Hooks (for the sake of hook injection/extraction). */
24816					/* Note: Chrome returns "rgba(0, 0, 0, 0)" for an undefined color whereas IE returns "transparent". */
24817					return (!value || /^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(value));
24818				},
24819				/* Retrieve a property's default unit type. Used for assigning a unit type when one is not supplied by the user. */
24820				getUnitType: function(property) {
24821					if (/^(rotate|skew)/i.test(property)) {
24822						return "deg";
24823					} else if (/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(property)) {
24824						/* The above properties are unitless. */
24825						return "";
24826					} else {
24827						/* Default to px for all other properties. */
24828						return "px";
24829					}
24830				},
24831				/* HTML elements default to an associated display type when they're not set to display:none. */
24832				/* Note: This function is used for correctly setting the non-"none" display value in certain Velocity redirects, such as fadeIn/Out. */
24833				getDisplayType: function(element) {
24834					var tagName = element && element.tagName.toString().toLowerCase();
24835
24836					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)) {
24837						return "inline";
24838					} else if (/^(li)$/i.test(tagName)) {
24839						return "list-item";
24840					} else if (/^(tr)$/i.test(tagName)) {
24841						return "table-row";
24842					} else if (/^(table)$/i.test(tagName)) {
24843						return "table";
24844					} else if (/^(tbody)$/i.test(tagName)) {
24845						return "table-row-group";
24846						/* Default to "block" when no match is found. */
24847					} else {
24848						return "block";
24849					}
24850				},
24851				/* The class add/remove functions are used to temporarily apply a "velocity-animating" class to elements while they're animating. */
24852				addClass: function(element, className) {
24853					if (element) {
24854						if (element.classList) {
24855							element.classList.add(className);
24856						} else if (Type.isString(element.className)) {
24857							// Element.className is around 15% faster then set/getAttribute
24858							element.className += (element.className.length ? " " : "") + className;
24859						} else {
24860							// Work around for IE strict mode animating SVG - and anything else that doesn't behave correctly - the same way jQuery does it
24861							var currentClass = element.getAttribute(IE <= 7 ? "className" : "class") || "";
24862
24863							element.setAttribute("class", currentClass + (currentClass ? " " : "") + className);
24864						}
24865					}
24866				},
24867				removeClass: function(element, className) {
24868					if (element) {
24869						if (element.classList) {
24870							element.classList.remove(className);
24871						} else if (Type.isString(element.className)) {
24872							// Element.className is around 15% faster then set/getAttribute
24873							// TODO: Need some jsperf tests on performance - can we get rid of the regex and maybe use split / array manipulation?
24874							element.className = element.className.toString().replace(new RegExp("(^|\\s)" + className.split(" ").join("|") + "(\\s|$)", "gi"), " ");
24875						} else {
24876							// Work around for IE strict mode animating SVG - and anything else that doesn't behave correctly - the same way jQuery does it
24877							var currentClass = element.getAttribute(IE <= 7 ? "className" : "class") || "";
24878
24879							element.setAttribute("class", currentClass.replace(new RegExp("(^|\s)" + className.split(" ").join("|") + "(\s|$)", "gi"), " "));
24880						}
24881					}
24882				}
24883			},
24884			/****************************
24885			 Style Getting & Setting
24886			 ****************************/
24887
24888			/* The singular getPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */
24889			getPropertyValue: function(element, property, rootPropertyValue, forceStyleLookup) {
24890				/* Get an element's computed property value. */
24891				/* Note: Retrieving the value of a CSS property cannot simply be performed by checking an element's
24892				 style attribute (which only reflects user-defined values). Instead, the browser must be queried for a property's
24893				 *computed* value. You can read more about getComputedStyle here: https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle */
24894				function computePropertyValue(element, property) {
24895					/* When box-sizing isn't set to border-box, height and width style values are incorrectly computed when an
24896					 element's scrollbars are visible (which expands the element's dimensions). Thus, we defer to the more accurate
24897					 offsetHeight/Width property, which includes the total dimensions for interior, border, padding, and scrollbar.
24898					 We subtract border and padding to get the sum of interior + scrollbar. */
24899					var computedValue = 0;
24900
24901					/* IE<=8 doesn't support window.getComputedStyle, thus we defer to jQuery, which has an extensive array
24902					 of hacks to accurately retrieve IE8 property values. Re-implementing that logic here is not worth bloating the
24903					 codebase for a dying browser. The performance repercussions of using jQuery here are minimal since
24904					 Velocity is optimized to rarely (and sometimes never) query the DOM. Further, the $.css() codepath isn't that slow. */
24905					if (IE <= 8) {
24906						computedValue = $.css(element, property); /* GET */
24907						/* All other browsers support getComputedStyle. The returned live object reference is cached onto its
24908						 associated element so that it does not need to be refetched upon every GET. */
24909					} else {
24910						/* Browsers do not return height and width values for elements that are set to display:"none". Thus, we temporarily
24911						 toggle display to the element type's default value. */
24912						var toggleDisplay = false;
24913
24914						if (/^(width|height)$/.test(property) && CSS.getPropertyValue(element, "display") === 0) {
24915							toggleDisplay = true;
24916							CSS.setPropertyValue(element, "display", CSS.Values.getDisplayType(element));
24917						}
24918
24919						var revertDisplay = function() {
24920							if (toggleDisplay) {
24921								CSS.setPropertyValue(element, "display", "none");
24922							}
24923						};
24924
24925						if (!forceStyleLookup) {
24926							if (property === "height" && CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() !== "border-box") {
24927								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);
24928								revertDisplay();
24929
24930								return contentBoxHeight;
24931							} else if (property === "width" && CSS.getPropertyValue(element, "boxSizing").toString().toLowerCase() !== "border-box") {
24932								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);
24933								revertDisplay();
24934
24935								return contentBoxWidth;
24936							}
24937						}
24938
24939						var computedStyle;
24940
24941						/* For elements that Velocity hasn't been called on directly (e.g. when Velocity queries the DOM on behalf
24942						 of a parent of an element its animating), perform a direct getComputedStyle lookup since the object isn't cached. */
24943						if (Data(element) === undefined) {
24944							computedStyle = window.getComputedStyle(element, null); /* GET */
24945							/* If the computedStyle object has yet to be cached, do so now. */
24946						} else if (!Data(element).computedStyle) {
24947							computedStyle = Data(element).computedStyle = window.getComputedStyle(element, null); /* GET */
24948							/* If computedStyle is cached, use it. */
24949						} else {
24950							computedStyle = Data(element).computedStyle;
24951						}
24952
24953						/* IE and Firefox do not return a value for the generic borderColor -- they only return individual values for each border side's color.
24954						 Also, in all browsers, when border colors aren't all the same, a compound value is returned that Velocity isn't setup to parse.
24955						 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. */
24956						if (property === "borderColor") {
24957							property = "borderTopColor";
24958						}
24959
24960						/* IE9 has a bug in which the "filter" property must be accessed from computedStyle using the getPropertyValue method
24961						 instead of a direct property lookup. The getPropertyValue method is slower than a direct lookup, which is why we avoid it by default. */
24962						if (IE === 9 && property === "filter") {
24963							computedValue = computedStyle.getPropertyValue(property); /* GET */
24964						} else {
24965							computedValue = computedStyle[property];
24966						}
24967
24968						/* Fall back to the property's style value (if defined) when computedValue returns nothing,
24969						 which can happen when the element hasn't been painted. */
24970						if (computedValue === "" || computedValue === null) {
24971							computedValue = element.style[property];
24972						}
24973
24974						revertDisplay();
24975					}
24976
24977					/* For top, right, bottom, and left (TRBL) values that are set to "auto" on elements of "fixed" or "absolute" position,
24978					 defer to jQuery for converting "auto" to a numeric value. (For elements with a "static" or "relative" position, "auto" has the same
24979					 effect as being set to 0, so no conversion is necessary.) */
24980					/* An example of why numeric conversion is necessary: When an element with "position:absolute" has an untouched "left"
24981					 property, which reverts to "auto", left's value is 0 relative to its parent element, but is often non-zero relative
24982					 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"). */
24983					if (computedValue === "auto" && /^(top|right|bottom|left)$/i.test(property)) {
24984						var position = computePropertyValue(element, "position"); /* GET */
24985
24986						/* For absolute positioning, jQuery's $.position() only returns values for top and left;
24987						 right and bottom will have their "auto" value reverted to 0. */
24988						/* Note: A jQuery object must be created here since jQuery doesn't have a low-level alias for $.position().
24989						 Not a big deal since we're currently in a GET batch anyway. */
24990						if (position === "fixed" || (position === "absolute" && /top|left/i.test(property))) {
24991							/* Note: jQuery strips the pixel unit from its returned values; we re-add it here to conform with computePropertyValue's behavior. */
24992							computedValue = $(element).position()[property] + "px"; /* GET */
24993						}
24994					}
24995
24996					return computedValue;
24997				}
24998
24999				var propertyValue;
25000
25001				/* If this is a hooked property (e.g. "clipLeft" instead of the root property of "clip"),
25002				 extract the hook's value from a normalized rootPropertyValue using CSS.Hooks.extractValue(). */
25003				if (CSS.Hooks.registered[property]) {
25004					var hook = property,
25005							hookRoot = CSS.Hooks.getRoot(hook);
25006
25007					/* If a cached rootPropertyValue wasn't passed in (which Velocity always attempts to do in order to avoid requerying the DOM),
25008					 query the DOM for the root property's value. */
25009					if (rootPropertyValue === undefined) {
25010						/* Since the browser is now being directly queried, use the official post-prefixing property name for this lookup. */
25011						rootPropertyValue = CSS.getPropertyValue(element, CSS.Names.prefixCheck(hookRoot)[0]); /* GET */
25012					}
25013
25014					/* If this root has a normalization registered, peform the associated normalization extraction. */
25015					if (CSS.Normalizations.registered[hookRoot]) {
25016						rootPropertyValue = CSS.Normalizations.registered[hookRoot]("extract", element, rootPropertyValue);
25017					}
25018
25019					/* Extract the hook's value. */
25020					propertyValue = CSS.Hooks.extractValue(hook, rootPropertyValue);
25021
25022					/* If this is a normalized property (e.g. "opacity" becomes "filter" in <=IE8) or "translateX" becomes "transform"),
25023					 normalize the property's name and value, and handle the special case of transforms. */
25024					/* Note: Normalizing a property is mutually exclusive from hooking a property since hook-extracted values are strictly
25025					 numerical and therefore do not require normalization extraction. */
25026				} else if (CSS.Normalizations.registered[property]) {
25027					var normalizedPropertyName,
25028							normalizedPropertyValue;
25029
25030					normalizedPropertyName = CSS.Normalizations.registered[property]("name", element);
25031
25032					/* Transform values are calculated via normalization extraction (see below), which checks against the element's transformCache.
25033					 At no point do transform GETs ever actually query the DOM; initial stylesheet values are never processed.
25034					 This is because parsing 3D transform matrices is not always accurate and would bloat our codebase;
25035					 thus, normalization extraction defaults initial transform values to their zero-values (e.g. 1 for scaleX and 0 for translateX). */
25036					if (normalizedPropertyName !== "transform") {
25037						normalizedPropertyValue = computePropertyValue(element, CSS.Names.prefixCheck(normalizedPropertyName)[0]); /* GET */
25038
25039						/* 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. */
25040						if (CSS.Values.isCSSNullValue(normalizedPropertyValue) && CSS.Hooks.templates[property]) {
25041							normalizedPropertyValue = CSS.Hooks.templates[property][1];
25042						}
25043					}
25044
25045					propertyValue = CSS.Normalizations.registered[property]("extract", element, normalizedPropertyValue);
25046				}
25047
25048				/* If a (numeric) value wasn't produced via hook extraction or normalization, query the DOM. */
25049				if (!/^[\d-]/.test(propertyValue)) {
25050					/* For SVG elements, dimensional properties (which SVGAttribute() detects) are tweened via
25051					 their HTML attribute values instead of their CSS style values. */
25052					var data = Data(element);
25053
25054					if (data && data.isSVG && CSS.Names.SVGAttribute(property)) {
25055						/* Since the height/width attribute values must be set manually, they don't reflect computed values.
25056						 Thus, we use use getBBox() to ensure we always get values for elements with undefined height/width attributes. */
25057						if (/^(height|width)$/i.test(property)) {
25058							/* Firefox throws an error if .getBBox() is called on an SVG that isn't attached to the DOM. */
25059							try {
25060								propertyValue = element.getBBox()[property];
25061							} catch (error) {
25062								propertyValue = 0;
25063							}
25064							/* Otherwise, access the attribute value directly. */
25065						} else {
25066							propertyValue = element.getAttribute(property);
25067						}
25068					} else {
25069						propertyValue = computePropertyValue(element, CSS.Names.prefixCheck(property)[0]); /* GET */
25070					}
25071				}
25072
25073				/* Since property lookups are for animation purposes (which entails computing the numeric delta between start and end values),
25074				 convert CSS null-values to an integer of value 0. */
25075				if (CSS.Values.isCSSNullValue(propertyValue)) {
25076					propertyValue = 0;
25077				}
25078
25079				if (Velocity.debug >= 2) {
25080					console.log("Get " + property + ": " + propertyValue);
25081				}
25082
25083				return propertyValue;
25084			},
25085			/* The singular setPropertyValue, which routes the logic for all normalizations, hooks, and standard CSS properties. */
25086			setPropertyValue: function(element, property, propertyValue, rootPropertyValue, scrollData) {
25087				var propertyName = property;
25088
25089				/* 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. */
25090				if (property === "scroll") {
25091					/* If a container option is present, scroll the container instead of the browser window. */
25092					if (scrollData.container) {
25093						scrollData.container["scroll" + scrollData.direction] = propertyValue;
25094						/* Otherwise, Velocity defaults to scrolling the browser window. */
25095					} else {
25096						if (scrollData.direction === "Left") {
25097							window.scrollTo(propertyValue, scrollData.alternateValue);
25098						} else {
25099							window.scrollTo(scrollData.alternateValue, propertyValue);
25100						}
25101					}
25102				} else {
25103					/* Transforms (translateX, rotateZ, etc.) are applied to a per-element transformCache object, which is manually flushed via flushTransformCache().
25104					 Thus, for now, we merely cache transforms being SET. */
25105					if (CSS.Normalizations.registered[property] && CSS.Normalizations.registered[property]("name", element) === "transform") {
25106						/* Perform a normalization injection. */
25107						/* Note: The normalization logic handles the transformCache updating. */
25108						CSS.Normalizations.registered[property]("inject", element, propertyValue);
25109
25110						propertyName = "transform";
25111						propertyValue = Data(element).transformCache[property];
25112					} else {
25113						/* Inject hooks. */
25114						if (CSS.Hooks.registered[property]) {
25115							var hookName = property,
25116									hookRoot = CSS.Hooks.getRoot(property);
25117
25118							/* If a cached rootPropertyValue was not provided, query the DOM for the hookRoot's current value. */
25119							rootPropertyValue = rootPropertyValue || CSS.getPropertyValue(element, hookRoot); /* GET */
25120
25121							propertyValue = CSS.Hooks.injectValue(hookName, propertyValue, rootPropertyValue);
25122							property = hookRoot;
25123						}
25124
25125						/* Normalize names and values. */
25126						if (CSS.Normalizations.registered[property]) {
25127							propertyValue = CSS.Normalizations.registered[property]("inject", element, propertyValue);
25128							property = CSS.Normalizations.registered[property]("name", element);
25129						}
25130
25131						/* Assign the appropriate vendor prefix before performing an official style update. */
25132						propertyName = CSS.Names.prefixCheck(property)[0];
25133
25134						/* A try/catch is used for IE<=8, which throws an error when "invalid" CSS values are set, e.g. a negative width.
25135						 Try/catch is avoided for other browsers since it incurs a performance overhead. */
25136						if (IE <= 8) {
25137							try {
25138								element.style[propertyName] = propertyValue;
25139							} catch (error) {
25140								if (Velocity.debug) {
25141									console.log("Browser does not support [" + propertyValue + "] for [" + propertyName + "]");
25142								}
25143							}
25144							/* SVG elements have their dimensional properties (width, height, x, y, cx, etc.) applied directly as attributes instead of as styles. */
25145							/* Note: IE8 does not support SVG elements, so it's okay that we skip it for SVG animation. */
25146						} else {
25147							var data = Data(element);
25148
25149							if (data && data.isSVG && CSS.Names.SVGAttribute(property)) {
25150								/* Note: For SVG attributes, vendor-prefixed property names are never used. */
25151								/* Note: Not all CSS properties can be animated via attributes, but the browser won't throw an error for unsupported properties. */
25152								element.setAttribute(property, propertyValue);
25153							} else {
25154								element.style[propertyName] = propertyValue;
25155							}
25156						}
25157
25158						if (Velocity.debug >= 2) {
25159							console.log("Set " + property + " (" + propertyName + "): " + propertyValue);
25160						}
25161					}
25162				}
25163
25164				/* 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. */
25165				return [propertyName, propertyValue];
25166			},
25167			/* To increase performance by batching transform updates into a single SET, transforms are not directly applied to an element until flushTransformCache() is called. */
25168			/* Note: Velocity applies transform properties in the same order that they are chronogically introduced to the element's CSS styles. */
25169			flushTransformCache: function(element) {
25170				var transformString = "",
25171						data = Data(element);
25172
25173				/* 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
25174				 (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). */
25175				if ((IE || (Velocity.State.isAndroid && !Velocity.State.isChrome)) && data && data.isSVG) {
25176					/* Since transform values are stored in their parentheses-wrapped form, we use a helper function to strip out their numeric values.
25177					 Further, SVG transform properties only take unitless (representing pixels) values, so it's okay that parseFloat() strips the unit suffixed to the float value. */
25178					var getTransformFloat = function(transformProperty) {
25179						return parseFloat(CSS.getPropertyValue(element, transformProperty));
25180					};
25181
25182					/* Create an object to organize all the transforms that we'll apply to the SVG element. To keep the logic simple,
25183					 we process *all* transform properties -- even those that may not be explicitly applied (since they default to their zero-values anyway). */
25184					var SVGTransforms = {
25185						translate: [getTransformFloat("translateX"), getTransformFloat("translateY")],
25186						skewX: [getTransformFloat("skewX")], skewY: [getTransformFloat("skewY")],
25187						/* If the scale property is set (non-1), use that value for the scaleX and scaleY values
25188						 (this behavior mimics the result of animating all these properties at once on HTML elements). */
25189						scale: getTransformFloat("scale") !== 1 ? [getTransformFloat("scale"), getTransformFloat("scale")] : [getTransformFloat("scaleX"), getTransformFloat("scaleY")],
25190						/* Note: SVG's rotate transform takes three values: rotation degrees followed by the X and Y values
25191						 defining the rotation's origin point. We ignore the origin values (default them to 0). */
25192						rotate: [getTransformFloat("rotateZ"), 0, 0]
25193					};
25194
25195					/* Iterate through the transform properties in the user-defined property map order.
25196					 (This mimics the behavior of non-SVG transform animation.) */
25197					$.each(Data(element).transformCache, function(transformName) {
25198						/* Except for with skewX/Y, revert the axis-specific transform subproperties to their axis-free master
25199						 properties so that they match up with SVG's accepted transform properties. */
25200						if (/^translate/i.test(transformName)) {
25201							transformName = "translate";
25202						} else if (/^scale/i.test(transformName)) {
25203							transformName = "scale";
25204						} else if (/^rotate/i.test(transformName)) {
25205							transformName = "rotate";
25206						}
25207
25208						/* Check that we haven't yet deleted the property from the SVGTransforms container. */
25209						if (SVGTransforms[transformName]) {
25210							/* Append the transform property in the SVG-supported transform format. As per the spec, surround the space-delimited values in parentheses. */
25211							transformString += transformName + "(" + SVGTransforms[transformName].join(" ") + ")" + " ";
25212
25213							/* After processing an SVG transform property, delete it from the SVGTransforms container so we don't
25214							 re-insert the same master property if we encounter another one of its axis-specific properties. */
25215							delete SVGTransforms[transformName];
25216						}
25217					});
25218				} else {
25219					var transformValue,
25220							perspective;
25221
25222					/* Transform properties are stored as members of the transformCache object. Concatenate all the members into a string. */
25223					$.each(Data(element).transformCache, function(transformName) {
25224						transformValue = Data(element).transformCache[transformName];
25225
25226						/* Transform's perspective subproperty must be set first in order to take effect. Store it temporarily. */
25227						if (transformName === "transformPerspective") {
25228							perspective = transformValue;
25229							return true;
25230						}
25231
25232						/* IE9 only supports one rotation type, rotateZ, which it refers to as "rotate". */
25233						if (IE === 9 && transformName === "rotateZ") {
25234							transformName = "rotate";
25235						}
25236
25237						transformString += transformName + transformValue + " ";
25238					});
25239
25240					/* If present, set the perspective subproperty first. */
25241					if (perspective) {
25242						transformString = "perspective" + perspective + " " + transformString;
25243					}
25244				}
25245
25246				CSS.setPropertyValue(element, "transform", transformString);
25247			}
25248		};
25249
25250		/* Register hooks and normalizations. */
25251		CSS.Hooks.register();
25252		CSS.Normalizations.register();
25253
25254		/* Allow hook setting in the same fashion as jQuery's $.css(). */
25255		Velocity.hook = function(elements, arg2, arg3) {
25256			var value;
25257
25258			elements = sanitizeElements(elements);
25259
25260			$.each(elements, function(i, element) {
25261				/* Initialize Velocity's per-element data cache if this element hasn't previously been animated. */
25262				if (Data(element) === undefined) {
25263					Velocity.init(element);
25264				}
25265
25266				/* Get property value. If an element set was passed in, only return the value for the first element. */
25267				if (arg3 === undefined) {
25268					if (value === undefined) {
25269						value = CSS.getPropertyValue(element, arg2);
25270					}
25271					/* Set property value. */
25272				} else {
25273					/* sPV returns an array of the normalized propertyName/propertyValue pair used to update the DOM. */
25274					var adjustedSet = CSS.setPropertyValue(element, arg2, arg3);
25275
25276					/* Transform properties don't automatically set. They have to be flushed to the DOM. */
25277					if (adjustedSet[0] === "transform") {
25278						Velocity.CSS.flushTransformCache(element);
25279					}
25280
25281					value = adjustedSet;
25282				}
25283			});
25284
25285			return value;
25286		};
25287
25288		/*****************
25289		 Animation
25290		 *****************/
25291
25292		var animate = function() {
25293			var opts;
25294
25295			/******************
25296			 Call Chain
25297			 ******************/
25298
25299			/* Logic for determining what to return to the call stack when exiting out of Velocity. */
25300			function getChain() {
25301				/* If we are using the utility function, attempt to return this call's promise. If no promise library was detected,
25302				 default to null instead of returning the targeted elements so that utility function's return value is standardized. */
25303				if (isUtility) {
25304					return promiseData.promise || null;
25305					/* Otherwise, if we're using $.fn, return the jQuery-/Zepto-wrapped element set. */
25306				} else {
25307					return elementsWrapped;
25308				}
25309			}
25310
25311			/*************************
25312			 Arguments Assignment
25313			 *************************/
25314
25315			/* To allow for expressive CoffeeScript code, Velocity supports an alternative syntax in which "elements" (or "e"), "properties" (or "p"), and "options" (or "o")
25316			 objects are defined on a container object that's passed in as Velocity's sole argument. */
25317			/* Note: Some browsers automatically populate arguments with a "properties" object. We detect it by checking for its default "names" property. */
25318			var syntacticSugar = (arguments[0] && (arguments[0].p || (($.isPlainObject(arguments[0].properties) && !arguments[0].properties.names) || Type.isString(arguments[0].properties)))),
25319					/* Whether Velocity was called via the utility function (as opposed to on a jQuery/Zepto object). */
25320					isUtility,
25321					/* When Velocity is called via the utility function ($.Velocity()/Velocity()), elements are explicitly
25322					 passed in as the first parameter. Thus, argument positioning varies. We normalize them here. */
25323					elementsWrapped,
25324					argumentIndex;
25325
25326			var elements,
25327					propertiesMap,
25328					options;
25329
25330			/* Detect jQuery/Zepto elements being animated via the $.fn method. */
25331			if (Type.isWrapped(this)) {
25332				isUtility = false;
25333
25334				argumentIndex = 0;
25335				elements = this;
25336				elementsWrapped = this;
25337				/* Otherwise, raw elements are being animated via the utility function. */
25338			} else {
25339				isUtility = true;
25340
25341				argumentIndex = 1;
25342				elements = syntacticSugar ? (arguments[0].elements || arguments[0].e) : arguments[0];
25343			}
25344
25345			/***************
25346			 Promises
25347			 ***************/
25348
25349			var promiseData = {
25350				promise: null,
25351				resolver: null,
25352				rejecter: null
25353			};
25354
25355			/* 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
25356			 promise support was detected, create a promise object for this call and store references to its resolver and rejecter methods. The resolve
25357			 method is used when a call completes naturally or is prematurely stopped by the user. In both cases, completeCall() handles the associated
25358			 call cleanup and promise resolving logic. The reject method is used when an invalid set of arguments is passed into a Velocity call. */
25359			/* Note: Velocity employs a call-based queueing architecture, which means that stopping an animating element actually stops the full call that
25360			 triggered it -- not that one element exclusively. Similarly, there is one promise per call, and all elements targeted by a Velocity call are
25361			 grouped together for the purposes of resolving and rejecting a promise. */
25362			if (isUtility && Velocity.Promise) {
25363				promiseData.promise = new Velocity.Promise(function(resolve, reject) {
25364					promiseData.resolver = resolve;
25365					promiseData.rejecter = reject;
25366				});
25367			}
25368
25369			if (syntacticSugar) {
25370				propertiesMap = arguments[0].properties || arguments[0].p;
25371				options = arguments[0].options || arguments[0].o;
25372			} else {
25373				propertiesMap = arguments[argumentIndex];
25374				options = arguments[argumentIndex + 1];
25375			}
25376
25377			elements = sanitizeElements(elements);
25378
25379			if (!elements) {
25380				if (promiseData.promise) {
25381					if (!propertiesMap || !options || options.promiseRejectEmpty !== false) {
25382						promiseData.rejecter();
25383					} else {
25384						promiseData.resolver();
25385					}
25386				}
25387				return;
25388			}
25389
25390			/* The length of the element set (in the form of a nodeList or an array of elements) is defaulted to 1 in case a
25391			 single raw DOM element is passed in (which doesn't contain a length property). */
25392			var elementsLength = elements.length,
25393					elementsIndex = 0;
25394
25395			/***************************
25396			 Argument Overloading
25397			 ***************************/
25398
25399			/* Support is included for jQuery's argument overloading: $.animate(propertyMap [, duration] [, easing] [, complete]).
25400			 Overloading is detected by checking for the absence of an object being passed into options. */
25401			/* Note: The stop/finish/pause/resume actions do not accept animation options, and are therefore excluded from this check. */
25402			if (!/^(stop|finish|finishAll|pause|resume)$/i.test(propertiesMap) && !$.isPlainObject(options)) {
25403				/* The utility function shifts all arguments one position to the right, so we adjust for that offset. */
25404				var startingArgumentPosition = argumentIndex + 1;
25405
25406				options = {};
25407
25408				/* Iterate through all options arguments */
25409				for (var i = startingArgumentPosition; i < arguments.length; i++) {
25410					/* Treat a number as a duration. Parse it out. */
25411					/* Note: The following RegEx will return true if passed an array with a number as its first item.
25412					 Thus, arrays are skipped from this check. */
25413					if (!Type.isArray(arguments[i]) && (/^(fast|normal|slow)$/i.test(arguments[i]) || /^\d/.test(arguments[i]))) {
25414						options.duration = arguments[i];
25415						/* Treat strings and arrays as easings. */
25416					} else if (Type.isString(arguments[i]) || Type.isArray(arguments[i])) {
25417						options.easing = arguments[i];
25418						/* Treat a function as a complete callback. */
25419					} else if (Type.isFunction(arguments[i])) {
25420						options.complete = arguments[i];
25421					}
25422				}
25423			}
25424
25425			/*********************
25426			 Action Detection
25427			 *********************/
25428
25429			/* Velocity's behavior is categorized into "actions": Elements can either be specially scrolled into view,
25430			 or they can be started, stopped, paused, resumed, or reversed . If a literal or referenced properties map is passed in as Velocity's
25431			 first argument, the associated action is "start". Alternatively, "scroll", "reverse", "pause", "resume" or "stop" can be passed in 
25432			 instead of a properties map. */
25433			var action;
25434
25435			switch (propertiesMap) {
25436				case "scroll":
25437					action = "scroll";
25438					break;
25439
25440				case "reverse":
25441					action = "reverse";
25442					break;
25443
25444				case "pause":
25445
25446					/*******************
25447					 Action: Pause
25448					 *******************/
25449
25450					var currentTime = (new Date()).getTime();
25451
25452					/* Handle delay timers */
25453					$.each(elements, function(i, element) {
25454						pauseDelayOnElement(element, currentTime);
25455					});
25456
25457					/* Pause and Resume are call-wide (not on a per element basis). Thus, calling pause or resume on a 
25458					 single element will cause any calls that containt tweens for that element to be paused/resumed
25459					 as well. */
25460
25461					/* Iterate through all calls and pause any that contain any of our elements */
25462					$.each(Velocity.State.calls, function(i, activeCall) {
25463
25464						var found = false;
25465						/* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
25466						if (activeCall) {
25467							/* Iterate through the active call's targeted elements. */
25468							$.each(activeCall[1], function(k, activeElement) {
25469								var queueName = (options === undefined) ? "" : options;
25470
25471								if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {
25472									return true;
25473								}
25474
25475								/* Iterate through the calls targeted by the stop command. */
25476								$.each(elements, function(l, element) {
25477									/* Check that this call was applied to the target element. */
25478									if (element === activeElement) {
25479
25480										/* Set call to paused */
25481										activeCall[5] = {
25482											resume: false
25483										};
25484
25485										/* Once we match an element, we can bounce out to the next call entirely */
25486										found = true;
25487										return false;
25488									}
25489								});
25490
25491								/* Proceed to check next call if we have already matched */
25492								if (found) {
25493									return false;
25494								}
25495							});
25496						}
25497
25498					});
25499
25500					/* Since pause creates no new tweens, exit out of Velocity. */
25501					return getChain();
25502
25503				case "resume":
25504
25505					/*******************
25506					 Action: Resume
25507					 *******************/
25508
25509					/* Handle delay timers */
25510					$.each(elements, function(i, element) {
25511						resumeDelayOnElement(element, currentTime);
25512					});
25513
25514					/* Pause and Resume are call-wide (not on a per elemnt basis). Thus, calling pause or resume on a 
25515					 single element will cause any calls that containt tweens for that element to be paused/resumed
25516					 as well. */
25517
25518					/* Iterate through all calls and pause any that contain any of our elements */
25519					$.each(Velocity.State.calls, function(i, activeCall) {
25520						var found = false;
25521						/* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
25522						if (activeCall) {
25523							/* Iterate through the active call's targeted elements. */
25524							$.each(activeCall[1], function(k, activeElement) {
25525								var queueName = (options === undefined) ? "" : options;
25526
25527								if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {
25528									return true;
25529								}
25530
25531								/* Skip any calls that have never been paused */
25532								if (!activeCall[5]) {
25533									return true;
25534								}
25535
25536								/* Iterate through the calls targeted by the stop command. */
25537								$.each(elements, function(l, element) {
25538									/* Check that this call was applied to the target element. */
25539									if (element === activeElement) {
25540
25541										/* Flag a pause object to be resumed, which will occur during the next tick. In
25542										 addition, the pause object will at that time be deleted */
25543										activeCall[5].resume = true;
25544
25545										/* Once we match an element, we can bounce out to the next call entirely */
25546										found = true;
25547										return false;
25548									}
25549								});
25550
25551								/* Proceed to check next call if we have already matched */
25552								if (found) {
25553									return false;
25554								}
25555							});
25556						}
25557
25558					});
25559
25560					/* Since resume creates no new tweens, exit out of Velocity. */
25561					return getChain();
25562
25563				case "finish":
25564				case "finishAll":
25565				case "stop":
25566					/*******************
25567					 Action: Stop
25568					 *******************/
25569
25570					/* Clear the currently-active delay on each targeted element. */
25571					$.each(elements, function(i, element) {
25572						if (Data(element) && Data(element).delayTimer) {
25573							/* Stop the timer from triggering its cached next() function. */
25574							clearTimeout(Data(element).delayTimer.setTimeout);
25575
25576							/* Manually call the next() function so that the subsequent queue items can progress. */
25577							if (Data(element).delayTimer.next) {
25578								Data(element).delayTimer.next();
25579							}
25580
25581							delete Data(element).delayTimer;
25582						}
25583
25584						/* If we want to finish everything in the queue, we have to iterate through it
25585						 and call each function. This will make them active calls below, which will
25586						 cause them to be applied via the duration setting. */
25587						if (propertiesMap === "finishAll" && (options === true || Type.isString(options))) {
25588							/* Iterate through the items in the element's queue. */
25589							$.each($.queue(element, Type.isString(options) ? options : ""), function(_, item) {
25590								/* The queue array can contain an "inprogress" string, which we skip. */
25591								if (Type.isFunction(item)) {
25592									item();
25593								}
25594							});
25595
25596							/* Clearing the $.queue() array is achieved by resetting it to []. */
25597							$.queue(element, Type.isString(options) ? options : "", []);
25598						}
25599					});
25600
25601					var callsToStop = [];
25602
25603					/* When the stop action is triggered, the elements' currently active call is immediately stopped. The active call might have
25604					 been applied to multiple elements, in which case all of the call's elements will be stopped. When an element
25605					 is stopped, the next item in its animation queue is immediately triggered. */
25606					/* An additional argument may be passed in to clear an element's remaining queued calls. Either true (which defaults to the "fx" queue)
25607					 or a custom queue string can be passed in. */
25608					/* Note: The stop command runs prior to Velocity's Queueing phase since its behavior is intended to take effect *immediately*,
25609					 regardless of the element's current queue state. */
25610
25611					/* Iterate through every active call. */
25612					$.each(Velocity.State.calls, function(i, activeCall) {
25613						/* Inactive calls are set to false by the logic inside completeCall(). Skip them. */
25614						if (activeCall) {
25615							/* Iterate through the active call's targeted elements. */
25616							$.each(activeCall[1], function(k, activeElement) {
25617								/* If true was passed in as a secondary argument, clear absolutely all calls on this element. Otherwise, only
25618								 clear calls associated with the relevant queue. */
25619								/* Call stopping logic works as follows:
25620								 - options === true --> stop current default queue calls (and queue:false calls), including remaining queued ones.
25621								 - options === undefined --> stop current queue:"" call and all queue:false calls.
25622								 - options === false --> stop only queue:false calls.
25623								 - options === "custom" --> stop current queue:"custom" call, including remaining queued ones (there is no functionality to only clear the currently-running queue:"custom" call). */
25624								var queueName = (options === undefined) ? "" : options;
25625
25626								if (queueName !== true && (activeCall[2].queue !== queueName) && !(options === undefined && activeCall[2].queue === false)) {
25627									return true;
25628								}
25629
25630								/* Iterate through the calls targeted by the stop command. */
25631								$.each(elements, function(l, element) {
25632									/* Check that this call was applied to the target element. */
25633									if (element === activeElement) {
25634										/* Optionally clear the remaining queued calls. If we're doing "finishAll" this won't find anything,
25635										 due to the queue-clearing above. */
25636										if (options === true || Type.isString(options)) {
25637											/* Iterate through the items in the element's queue. */
25638											$.each($.queue(element, Type.isString(options) ? options : ""), function(_, item) {
25639												/* The queue array can contain an "inprogress" string, which we skip. */
25640												if (Type.isFunction(item)) {
25641													/* Pass the item's callback a flag indicating that we want to abort from the queue call.
25642													 (Specifically, the queue will resolve the call's associated promise then abort.)  */
25643													item(null, true);
25644												}
25645											});
25646
25647											/* Clearing the $.queue() array is achieved by resetting it to []. */
25648											$.queue(element, Type.isString(options) ? options : "", []);
25649										}
25650
25651										if (propertiesMap === "stop") {
25652											/* Since "reverse" uses cached start values (the previous call's endValues), these values must be
25653											 changed to reflect the final value that the elements were actually tweened to. */
25654											/* Note: If only queue:false animations are currently running on an element, it won't have a tweensContainer
25655											 object. Also, queue:false animations can't be reversed. */
25656											var data = Data(element);
25657											if (data && data.tweensContainer && queueName !== false) {
25658												$.each(data.tweensContainer, function(m, activeTween) {
25659													activeTween.endValue = activeTween.currentValue;
25660												});
25661											}
25662
25663											callsToStop.push(i);
25664										} else if (propertiesMap === "finish" || propertiesMap === "finishAll") {
25665											/* To get active tweens to finish immediately, we forcefully shorten their durations to 1ms so that
25666											 they finish upon the next rAf tick then proceed with normal call completion logic. */
25667											activeCall[2].duration = 1;
25668										}
25669									}
25670								});
25671							});
25672						}
25673					});
25674
25675					/* Prematurely call completeCall() on each matched active call. Pass an additional flag for "stop" to indicate
25676					 that the complete callback and display:none setting should be skipped since we're completing prematurely. */
25677					if (propertiesMap === "stop") {
25678						$.each(callsToStop, function(i, j) {
25679							completeCall(j, true);
25680						});
25681
25682						if (promiseData.promise) {
25683							/* Immediately resolve the promise associated with this stop call since stop runs synchronously. */
25684							promiseData.resolver(elements);
25685						}
25686					}
25687
25688					/* Since we're stopping, and not proceeding with queueing, exit out of Velocity. */
25689					return getChain();
25690
25691				default:
25692					/* Treat a non-empty plain object as a literal properties map. */
25693					if ($.isPlainObject(propertiesMap) && !Type.isEmptyObject(propertiesMap)) {
25694						action = "start";
25695
25696						/****************
25697						 Redirects
25698						 ****************/
25699
25700						/* Check if a string matches a registered redirect (see Redirects above). */
25701					} else if (Type.isString(propertiesMap) && Velocity.Redirects[propertiesMap]) {
25702						opts = $.extend({}, options);
25703
25704						var durationOriginal = opts.duration,
25705								delayOriginal = opts.delay || 0;
25706
25707						/* If the backwards option was passed in, reverse the element set so that elements animate from the last to the first. */
25708						if (opts.backwards === true) {
25709							elements = $.extend(true, [], elements).reverse();
25710						}
25711
25712						/* Individually trigger the redirect for each element in the set to prevent users from having to handle iteration logic in their redirect. */
25713						$.each(elements, function(elementIndex, element) {
25714							/* If the stagger option was passed in, successively delay each element by the stagger value (in ms). Retain the original delay value. */
25715							if (parseFloat(opts.stagger)) {
25716								opts.delay = delayOriginal + (parseFloat(opts.stagger) * elementIndex);
25717							} else if (Type.isFunction(opts.stagger)) {
25718								opts.delay = delayOriginal + opts.stagger.call(element, elementIndex, elementsLength);
25719							}
25720
25721							/* If the drag option was passed in, successively increase/decrease (depending on the presense of opts.backwards)
25722							 the duration of each element's animation, using floors to prevent producing very short durations. */
25723							if (opts.drag) {
25724								/* Default the duration of UI pack effects (callouts and transitions) to 1000ms instead of the usual default duration of 400ms. */
25725								opts.duration = parseFloat(durationOriginal) || (/^(callout|transition)/.test(propertiesMap) ? 1000 : DURATION_DEFAULT);
25726
25727								/* For each element, take the greater duration of: A) animation completion percentage relative to the original duration,
25728								 B) 75% of the original duration, or C) a 200ms fallback (in case duration is already set to a low value).
25729								 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. */
25730								opts.duration = Math.max(opts.duration * (opts.backwards ? 1 - elementIndex / elementsLength : (elementIndex + 1) / elementsLength), opts.duration * 0.75, 200);
25731							}
25732
25733							/* 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
25734							 reduce the opts checking logic required inside the redirect. */
25735							Velocity.Redirects[propertiesMap].call(element, element, opts || {}, elementIndex, elementsLength, elements, promiseData.promise ? promiseData : undefined);
25736						});
25737
25738						/* Since the animation logic resides within the redirect's own code, abort the remainder of this call.
25739						 (The performance overhead up to this point is virtually non-existant.) */
25740						/* Note: The jQuery call chain is kept intact by returning the complete element set. */
25741						return getChain();
25742					} else {
25743						var abortError = "Velocity: First argument (" + propertiesMap + ") was not a property map, a known action, or a registered redirect. Aborting.";
25744
25745						if (promiseData.promise) {
25746							promiseData.rejecter(new Error(abortError));
25747						} else {
25748							console.log(abortError);
25749						}
25750
25751						return getChain();
25752					}
25753			}
25754
25755			/**************************
25756			 Call-Wide Variables
25757			 **************************/
25758
25759			/* A container for CSS unit conversion ratios (e.g. %, rem, and em ==> px) that is used to cache ratios across all elements
25760			 being animated in a single Velocity call. Calculating unit ratios necessitates DOM querying and updating, and is therefore
25761			 avoided (via caching) wherever possible. This container is call-wide instead of page-wide to avoid the risk of using stale
25762			 conversion metrics across Velocity animations that are not immediately consecutively chained. */
25763			var callUnitConversionData = {
25764				lastParent: null,
25765				lastPosition: null,
25766				lastFontSize: null,
25767				lastPercentToPxWidth: null,
25768				lastPercentToPxHeight: null,
25769				lastEmToPx: null,
25770				remToPx: null,
25771				vwToPx: null,
25772				vhToPx: null
25773			};
25774
25775			/* A container for all the ensuing tween data and metadata associated with this call. This container gets pushed to the page-wide
25776			 Velocity.State.calls array that is processed during animation ticking. */
25777			var call = [];
25778
25779			/************************
25780			 Element Processing
25781			 ************************/
25782
25783			/* 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):
25784			 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.
25785			 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.
25786			 3) Pushing: Consolidation of the tween data followed by its push onto the global in-progress calls container.
25787			 `elementArrayIndex` allows passing index of the element in the original array to value functions.
25788			 If `elementsIndex` were used instead the index would be determined by the elements' per-element queue.
25789			 */
25790			function processElement(element, elementArrayIndex) {
25791
25792				/*************************
25793				 Part I: Pre-Queueing
25794				 *************************/
25795
25796				/***************************
25797				 Element-Wide Variables
25798				 ***************************/
25799
25800				var /* The runtime opts object is the extension of the current call's options and Velocity's page-wide option defaults. */
25801						opts = $.extend({}, Velocity.defaults, options),
25802						/* A container for the processed data associated with each property in the propertyMap.
25803						 (Each property in the map produces its own "tween".) */
25804						tweensContainer = {},
25805						elementUnitConversionData;
25806
25807				/******************
25808				 Element Init
25809				 ******************/
25810
25811				if (Data(element) === undefined) {
25812					Velocity.init(element);
25813				}
25814
25815				/******************
25816				 Option: Delay
25817				 ******************/
25818
25819				/* Since queue:false doesn't respect the item's existing queue, we avoid injecting its delay here (it's set later on). */
25820				/* Note: Velocity rolls its own delay function since jQuery doesn't have a utility alias for $.fn.delay()
25821				 (and thus requires jQuery element creation, which we avoid since its overhead includes DOM querying). */
25822				if (parseFloat(opts.delay) && opts.queue !== false) {
25823					$.queue(element, opts.queue, function(next) {
25824						/* 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. */
25825						Velocity.velocityQueueEntryFlag = true;
25826
25827						/* The ensuing queue item (which is assigned to the "next" argument that $.queue() automatically passes in) will be triggered after a setTimeout delay.
25828						 The setTimeout is stored so that it can be subjected to clearTimeout() if this animation is prematurely stopped via Velocity's "stop" command, and
25829						 delayBegin/delayTime is used to ensure we can "pause" and "resume" a tween that is still mid-delay. */
25830
25831						/* Temporarily store delayed elements to facilite access for global pause/resume */
25832						var callIndex = Velocity.State.delayedElements.count++;
25833						Velocity.State.delayedElements[callIndex] = element;
25834
25835						var delayComplete = (function(index) {
25836							return function() {
25837								/* Clear the temporary element */
25838								Velocity.State.delayedElements[index] = false;
25839
25840								/* Finally, issue the call */
25841								next();
25842							};
25843						})(callIndex);
25844
25845
25846						Data(element).delayBegin = (new Date()).getTime();
25847						Data(element).delay = parseFloat(opts.delay);
25848						Data(element).delayTimer = {
25849							setTimeout: setTimeout(next, parseFloat(opts.delay)),
25850							next: delayComplete
25851						};
25852					});
25853				}
25854
25855				/*********************
25856				 Option: Duration
25857				 *********************/
25858
25859				/* Support for jQuery's named durations. */
25860				switch (opts.duration.toString().toLowerCase()) {
25861					case "fast":
25862						opts.duration = 200;
25863						break;
25864
25865					case "normal":
25866						opts.duration = DURATION_DEFAULT;
25867						break;
25868
25869					case "slow":
25870						opts.duration = 600;
25871						break;
25872
25873					default:
25874						/* 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). */
25875						opts.duration = parseFloat(opts.duration) || 1;
25876				}
25877
25878				/************************
25879				 Global Option: Mock
25880				 ************************/
25881
25882				if (Velocity.mock !== false) {
25883					/* In mock mode, all animations are forced to 1ms so that they occur immediately upon the next rAF tick.
25884					 Alternatively, a multiplier can be passed in to time remap all delays and durations. */
25885					if (Velocity.mock === true) {
25886						opts.duration = opts.delay = 1;
25887					} else {
25888						opts.duration *= parseFloat(Velocity.mock) || 1;
25889						opts.delay *= parseFloat(Velocity.mock) || 1;
25890					}
25891				}
25892
25893				/*******************
25894				 Option: Easing
25895				 *******************/
25896
25897				opts.easing = getEasing(opts.easing, opts.duration);
25898
25899				/**********************
25900				 Option: Callbacks
25901				 **********************/
25902
25903				/* Callbacks must functions. Otherwise, default to null. */
25904				if (opts.begin && !Type.isFunction(opts.begin)) {
25905					opts.begin = null;
25906				}
25907
25908				if (opts.progress && !Type.isFunction(opts.progress)) {
25909					opts.progress = null;
25910				}
25911
25912				if (opts.complete && !Type.isFunction(opts.complete)) {
25913					opts.complete = null;
25914				}
25915
25916				/*********************************
25917				 Option: Display & Visibility
25918				 *********************************/
25919
25920				/* Refer to Velocity's documentation (VelocityJS.org/#displayAndVisibility) for a description of the display and visibility options' behavior. */
25921				/* Note: We strictly check for undefined instead of falsiness because display accepts an empty string value. */
25922				if (opts.display !== undefined && opts.display !== null) {
25923					opts.display = opts.display.toString().toLowerCase();
25924
25925					/* Users can pass in a special "auto" value to instruct Velocity to set the element to its default display value. */
25926					if (opts.display === "auto") {
25927						opts.display = Velocity.CSS.Values.getDisplayType(element);
25928					}
25929				}
25930
25931				if (opts.visibility !== undefined && opts.visibility !== null) {
25932					opts.visibility = opts.visibility.toString().toLowerCase();
25933				}
25934
25935				/**********************
25936				 Option: mobileHA
25937				 **********************/
25938
25939				/* When set to true, and if this is a mobile device, mobileHA automatically enables hardware acceleration (via a null transform hack)
25940				 on animating elements. HA is removed from the element at the completion of its animation. */
25941				/* 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. */
25942				/* Note: You can read more about the use of mobileHA in Velocity's documentation: VelocityJS.org/#mobileHA. */
25943				opts.mobileHA = (opts.mobileHA && Velocity.State.isMobile && !Velocity.State.isGingerbread);
25944
25945				/***********************
25946				 Part II: Queueing
25947				 ***********************/
25948
25949				/* 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.
25950				 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. */
25951				/* 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,
25952				 the call array is pushed to Velocity.State.calls for live processing by the requestAnimationFrame tick. */
25953				function buildQueue(next) {
25954					var data, lastTweensContainer;
25955
25956					/*******************
25957					 Option: Begin
25958					 *******************/
25959
25960					/* 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. */
25961					if (opts.begin && elementsIndex === 0) {
25962						/* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */
25963						try {
25964							opts.begin.call(elements, elements);
25965						} catch (error) {
25966							setTimeout(function() {
25967								throw error;
25968							}, 1);
25969						}
25970					}
25971
25972					/*****************************************
25973					 Tween Data Construction (for Scroll)
25974					 *****************************************/
25975
25976					/* 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. */
25977					if (action === "scroll") {
25978						/* The scroll action uniquely takes an optional "offset" option -- specified in pixels -- that offsets the targeted scroll position. */
25979						var scrollDirection = (/^x$/i.test(opts.axis) ? "Left" : "Top"),
25980								scrollOffset = parseFloat(opts.offset) || 0,
25981								scrollPositionCurrent,
25982								scrollPositionCurrentAlternate,
25983								scrollPositionEnd;
25984
25985						/* Scroll also uniquely takes an optional "container" option, which indicates the parent element that should be scrolled --
25986						 as opposed to the browser window itself. This is useful for scrolling toward an element that's inside an overflowing parent element. */
25987						if (opts.container) {
25988							/* Ensure that either a jQuery object or a raw DOM element was passed in. */
25989							if (Type.isWrapped(opts.container) || Type.isNode(opts.container)) {
25990								/* Extract the raw DOM element from the jQuery wrapper. */
25991								opts.container = opts.container[0] || opts.container;
25992								/* Note: Unlike other properties in Velocity, the browser's scroll position is never cached since it so frequently changes
25993								 (due to the user's natural interaction with the page). */
25994								scrollPositionCurrent = opts.container["scroll" + scrollDirection]; /* GET */
25995
25996								/* $.position() values are relative to the container's currently viewable area (without taking into account the container's true dimensions
25997								 -- say, for example, if the container was not overflowing). Thus, the scroll end value is the sum of the child element's position *and*
25998								 the scroll container's current scroll position. */
25999								scrollPositionEnd = (scrollPositionCurrent + $(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; /* GET */
26000								/* 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. */
26001							} else {
26002								opts.container = null;
26003							}
26004						} else {
26005							/* If the window itself is being scrolled -- not a containing element -- perform a live scroll position lookup using
26006							 the appropriate cached property names (which differ based on browser type). */
26007							scrollPositionCurrent = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + scrollDirection]]; /* GET */
26008							/* 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. */
26009							scrollPositionCurrentAlternate = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + (scrollDirection === "Left" ? "Top" : "Left")]]; /* GET */
26010
26011							/* Unlike $.position(), $.offset() values are relative to the browser window's true dimensions -- not merely its currently viewable area --
26012							 and therefore end values do not need to be compounded onto current values. */
26013							scrollPositionEnd = $(element).offset()[scrollDirection.toLowerCase()] + scrollOffset; /* GET */
26014						}
26015
26016						/* Since there's only one format that scroll's associated tweensContainer can take, we create it manually. */
26017						tweensContainer = {
26018							scroll: {
26019								rootPropertyValue: false,
26020								startValue: scrollPositionCurrent,
26021								currentValue: scrollPositionCurrent,
26022								endValue: scrollPositionEnd,
26023								unitType: "",
26024								easing: opts.easing,
26025								scrollData: {
26026									container: opts.container,
26027									direction: scrollDirection,
26028									alternateValue: scrollPositionCurrentAlternate
26029								}
26030							},
26031							element: element
26032						};
26033
26034						if (Velocity.debug) {
26035							console.log("tweensContainer (scroll): ", tweensContainer.scroll, element);
26036						}
26037
26038						/******************************************
26039						 Tween Data Construction (for Reverse)
26040						 ******************************************/
26041
26042						/* Reverse acts like a "start" action in that a property map is animated toward. The only difference is
26043						 that the property map used for reverse is the inverse of the map used in the previous call. Thus, we manipulate
26044						 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. */
26045						/* 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.) */
26046						/* Note: Reverse calls do not need to be consecutively chained onto a currently-animating element in order to operate on cached values;
26047						 there is no harm to reverse being called on a potentially stale data cache since reverse's behavior is simply defined
26048						 as reverting to the element's values as they were prior to the previous *Velocity* call. */
26049					} else if (action === "reverse") {
26050						data = Data(element);
26051
26052						/* Abort if there is no prior animation data to reverse to. */
26053						if (!data) {
26054							return;
26055						}
26056
26057						if (!data.tweensContainer) {
26058							/* Dequeue the element so that this queue entry releases itself immediately, allowing subsequent queue entries to run. */
26059							$.dequeue(element, opts.queue);
26060
26061							return;
26062						} else {
26063							/*********************
26064							 Options Parsing
26065							 *********************/
26066
26067							/* If the element was hidden via the display option in the previous call,
26068							 revert display to "auto" prior to reversal so that the element is visible again. */
26069							if (data.opts.display === "none") {
26070								data.opts.display = "auto";
26071							}
26072
26073							if (data.opts.visibility === "hidden") {
26074								data.opts.visibility = "visible";
26075							}
26076
26077							/* If the loop option was set in the previous call, disable it so that "reverse" calls aren't recursively generated.
26078							 Further, remove the previous call's callback options; typically, users do not want these to be refired. */
26079							data.opts.loop = false;
26080							data.opts.begin = null;
26081							data.opts.complete = null;
26082
26083							/* Since we're extending an opts object that has already been extended with the defaults options object,
26084							 we remove non-explicitly-defined properties that are auto-assigned values. */
26085							if (!options.easing) {
26086								delete opts.easing;
26087							}
26088
26089							if (!options.duration) {
26090								delete opts.duration;
26091							}
26092
26093							/* The opts object used for reversal is an extension of the options object optionally passed into this
26094							 reverse call plus the options used in the previous Velocity call. */
26095							opts = $.extend({}, data.opts, opts);
26096
26097							/*************************************
26098							 Tweens Container Reconstruction
26099							 *************************************/
26100
26101							/* Create a deepy copy (indicated via the true flag) of the previous call's tweensContainer. */
26102							lastTweensContainer = $.extend(true, {}, data ? data.tweensContainer : null);
26103
26104							/* Manipulate the previous tweensContainer by replacing its end values and currentValues with its start values. */
26105							for (var lastTween in lastTweensContainer) {
26106								/* In addition to tween data, tweensContainers contain an element property that we ignore here. */
26107								if (lastTweensContainer.hasOwnProperty(lastTween) && lastTween !== "element") {
26108									var lastStartValue = lastTweensContainer[lastTween].startValue;
26109
26110									lastTweensContainer[lastTween].startValue = lastTweensContainer[lastTween].currentValue = lastTweensContainer[lastTween].endValue;
26111									lastTweensContainer[lastTween].endValue = lastStartValue;
26112
26113									/* Easing is the only option that embeds into the individual tween data (since it can be defined on a per-property basis).
26114									 Accordingly, every property's easing value must be updated when an options object is passed in with a reverse call.
26115									 The side effect of this extensibility is that all per-property easing values are forcefully reset to the new value. */
26116									if (!Type.isEmptyObject(options)) {
26117										lastTweensContainer[lastTween].easing = opts.easing;
26118									}
26119
26120									if (Velocity.debug) {
26121										console.log("reverse tweensContainer (" + lastTween + "): " + JSON.stringify(lastTweensContainer[lastTween]), element);
26122									}
26123								}
26124							}
26125
26126							tweensContainer = lastTweensContainer;
26127						}
26128
26129						/*****************************************
26130						 Tween Data Construction (for Start)
26131						 *****************************************/
26132
26133					} else if (action === "start") {
26134
26135						/*************************
26136						 Value Transferring
26137						 *************************/
26138
26139						/* If this queue entry follows a previous Velocity-initiated queue entry *and* if this entry was created
26140						 while the element was in the process of being animated by Velocity, then this current call is safe to use
26141						 the end values from the prior call as its start values. Velocity attempts to perform this value transfer
26142						 process whenever possible in order to avoid requerying the DOM. */
26143						/* If values aren't transferred from a prior call and start values were not forcefed by the user (more on this below),
26144						 then the DOM is queried for the element's current values as a last resort. */
26145						/* Note: Conversely, animation reversal (and looping) *always* perform inter-call value transfers; they never requery the DOM. */
26146
26147						data = Data(element);
26148
26149						/* The per-element isAnimating flag is used to indicate whether it's safe (i.e. the data isn't stale)
26150						 to transfer over end values to use as start values. If it's set to true and there is a previous
26151						 Velocity call to pull values from, do so. */
26152						if (data && data.tweensContainer && data.isAnimating === true) {
26153							lastTweensContainer = data.tweensContainer;
26154						}
26155
26156						/***************************
26157						 Tween Data Calculation
26158						 ***************************/
26159
26160						/* This function parses property data and defaults endValue, easing, and startValue as appropriate. */
26161						/* Property map values can either take the form of 1) a single value representing the end value,
26162						 or 2) an array in the form of [ endValue, [, easing] [, startValue] ].
26163						 The optional third parameter is a forcefed startValue to be used instead of querying the DOM for
26164						 the element's current value. Read Velocity's docmentation to learn more about forcefeeding: VelocityJS.org/#forcefeeding */
26165						var parsePropertyValue = function(valueData, skipResolvingEasing) {
26166							var endValue, easing, startValue;
26167
26168							/* If we have a function as the main argument then resolve it first, in case it returns an array that needs to be split */
26169							if (Type.isFunction(valueData)) {
26170								valueData = valueData.call(element, elementArrayIndex, elementsLength);
26171							}
26172
26173							/* Handle the array format, which can be structured as one of three potential overloads:
26174							 A) [ endValue, easing, startValue ], B) [ endValue, easing ], or C) [ endValue, startValue ] */
26175							if (Type.isArray(valueData)) {
26176								/* endValue is always the first item in the array. Don't bother validating endValue's value now
26177								 since the ensuing property cycling logic does that. */
26178								endValue = valueData[0];
26179
26180								/* Two-item array format: If the second item is a number, function, or hex string, treat it as a
26181								 start value since easings can only be non-hex strings or arrays. */
26182								if ((!Type.isArray(valueData[1]) && /^[\d-]/.test(valueData[1])) || Type.isFunction(valueData[1]) || CSS.RegEx.isHex.test(valueData[1])) {
26183									startValue = valueData[1];
26184									/* Two or three-item array: If the second item is a non-hex string easing name or an array, treat it as an easing. */
26185								} else if ((Type.isString(valueData[1]) && !CSS.RegEx.isHex.test(valueData[1]) && Velocity.Easings[valueData[1]]) || Type.isArray(valueData[1])) {
26186									easing = skipResolvingEasing ? valueData[1] : getEasing(valueData[1], opts.duration);
26187
26188									/* Don't bother validating startValue's value now since the ensuing property cycling logic inherently does that. */
26189									startValue = valueData[2];
26190								} else {
26191									startValue = valueData[1] || valueData[2];
26192								}
26193								/* Handle the single-value format. */
26194							} else {
26195								endValue = valueData;
26196							}
26197
26198							/* Default to the call's easing if a per-property easing type was not defined. */
26199							if (!skipResolvingEasing) {
26200								easing = easing || opts.easing;
26201							}
26202
26203							/* If functions were passed in as values, pass the function the current element as its context,
26204							 plus the element's index and the element set's size as arguments. Then, assign the returned value. */
26205							if (Type.isFunction(endValue)) {
26206								endValue = endValue.call(element, elementArrayIndex, elementsLength);
26207							}
26208
26209							if (Type.isFunction(startValue)) {
26210								startValue = startValue.call(element, elementArrayIndex, elementsLength);
26211							}
26212
26213							/* Allow startValue to be left as undefined to indicate to the ensuing code that its value was not forcefed. */
26214							return [endValue || 0, easing, startValue];
26215						};
26216
26217						var fixPropertyValue = function(property, valueData) {
26218							/* 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. */
26219							var rootProperty = CSS.Hooks.getRoot(property),
26220									rootPropertyValue = false,
26221									/* Parse out endValue, easing, and startValue from the property's data. */
26222									endValue = valueData[0],
26223									easing = valueData[1],
26224									startValue = valueData[2],
26225									pattern;
26226
26227							/**************************
26228							 Start Value Sourcing
26229							 **************************/
26230
26231							/* Other than for the dummy tween property, properties that are not supported by the browser (and do not have an associated normalization) will
26232							 inherently produce no style changes when set, so they are skipped in order to decrease animation tick overhead.
26233							 Property support is determined via prefixCheck(), which returns a false flag when no supported is detected. */
26234							/* Note: Since SVG elements have some of their properties directly applied as HTML attributes,
26235							 there is no way to check for their explicit browser support, and so we skip skip this check for them. */
26236							if ((!data || !data.isSVG) && rootProperty !== "tween" && CSS.Names.prefixCheck(rootProperty)[1] === false && CSS.Normalizations.registered[rootProperty] === undefined) {
26237								if (Velocity.debug) {
26238									console.log("Skipping [" + rootProperty + "] due to a lack of browser support.");
26239								}
26240								return;
26241							}
26242
26243							/* If the display option is being set to a non-"none" (e.g. "block") and opacity (filter on IE<=8) is being
26244							 animated to an endValue of non-zero, the user's intention is to fade in from invisible, thus we forcefeed opacity
26245							 a startValue of 0 if its startValue hasn't already been sourced by value transferring or prior forcefeeding. */
26246							if (((opts.display !== undefined && opts.display !== null && opts.display !== "none") || (opts.visibility !== undefined && opts.visibility !== "hidden")) && /opacity|filter/.test(property) && !startValue && endValue !== 0) {
26247								startValue = 0;
26248							}
26249
26250							/* If values have been transferred from the previous Velocity call, extract the endValue and rootPropertyValue
26251							 for all of the current call's properties that were *also* animated in the previous call. */
26252							/* Note: Value transferring can optionally be disabled by the user via the _cacheValues option. */
26253							if (opts._cacheValues && lastTweensContainer && lastTweensContainer[property]) {
26254								if (startValue === undefined) {
26255									startValue = lastTweensContainer[property].endValue + lastTweensContainer[property].unitType;
26256								}
26257
26258								/* The previous call's rootPropertyValue is extracted from the element's data cache since that's the
26259								 instance of rootPropertyValue that gets freshly updated by the tweening process, whereas the rootPropertyValue
26260								 attached to the incoming lastTweensContainer is equal to the root property's value prior to any tweening. */
26261								rootPropertyValue = data.rootPropertyValueCache[rootProperty];
26262								/* If values were not transferred from a previous Velocity call, query the DOM as needed. */
26263							} else {
26264								/* Handle hooked properties. */
26265								if (CSS.Hooks.registered[property]) {
26266									if (startValue === undefined) {
26267										rootPropertyValue = CSS.getPropertyValue(element, rootProperty); /* GET */
26268										/* Note: The following getPropertyValue() call does not actually trigger a DOM query;
26269										 getPropertyValue() will extract the hook from rootPropertyValue. */
26270										startValue = CSS.getPropertyValue(element, property, rootPropertyValue);
26271										/* If startValue is already defined via forcefeeding, do not query the DOM for the root property's value;
26272										 just grab rootProperty's zero-value template from CSS.Hooks. This overwrites the element's actual
26273										 root property value (if one is set), but this is acceptable since the primary reason users forcefeed is
26274										 to avoid DOM queries, and thus we likewise avoid querying the DOM for the root property's value. */
26275									} else {
26276										/* Grab this hook's zero-value template, e.g. "0px 0px 0px black". */
26277										rootPropertyValue = CSS.Hooks.templates[rootProperty][1];
26278									}
26279									/* Handle non-hooked properties that haven't already been defined via forcefeeding. */
26280								} else if (startValue === undefined) {
26281									startValue = CSS.getPropertyValue(element, property); /* GET */
26282								}
26283							}
26284
26285							/**************************
26286							 Value Data Extraction
26287							 **************************/
26288
26289							var separatedValue,
26290									endValueUnitType,
26291									startValueUnitType,
26292									operator = false;
26293
26294							/* Separates a property value into its numeric value and its unit type. */
26295							var separateValue = function(property, value) {
26296								var unitType,
26297										numericValue;
26298
26299								numericValue = (value || "0")
26300										.toString()
26301										.toLowerCase()
26302										/* Match the unit type at the end of the value. */
26303										.replace(/[%A-z]+$/, function(match) {
26304											/* Grab the unit type. */
26305											unitType = match;
26306
26307											/* Strip the unit type off of value. */
26308											return "";
26309										});
26310
26311								/* If no unit type was supplied, assign one that is appropriate for this property (e.g. "deg" for rotateZ or "px" for width). */
26312								if (!unitType) {
26313									unitType = CSS.Values.getUnitType(property);
26314								}
26315
26316								return [numericValue, unitType];
26317							};
26318
26319							if (startValue !== endValue && Type.isString(startValue) && Type.isString(endValue)) {
26320								pattern = "";
26321								var iStart = 0, // index in startValue
26322										iEnd = 0, // index in endValue
26323										aStart = [], // array of startValue numbers
26324										aEnd = [], // array of endValue numbers
26325										inCalc = 0, // Keep track of being inside a "calc()" so we don't duplicate it
26326										inRGB = 0, // Keep track of being inside an RGB as we can't use fractional values
26327										inRGBA = 0; // Keep track of being inside an RGBA as we must pass fractional for the alpha channel
26328
26329								startValue = CSS.Hooks.fixColors(startValue);
26330								endValue = CSS.Hooks.fixColors(endValue);
26331								while (iStart < startValue.length && iEnd < endValue.length) {
26332									var cStart = startValue[iStart],
26333											cEnd = endValue[iEnd];
26334
26335									if (/[\d\.]/.test(cStart) && /[\d\.]/.test(cEnd)) {
26336										var tStart = cStart, // temporary character buffer
26337												tEnd = cEnd, // temporary character buffer
26338												dotStart = ".", // Make sure we can only ever match a single dot in a decimal
26339												dotEnd = "."; // Make sure we can only ever match a single dot in a decimal
26340
26341										while (++iStart < startValue.length) {
26342											cStart = startValue[iStart];
26343											if (cStart === dotStart) {
26344												dotStart = ".."; // Can never match two characters
26345											} else if (!/\d/.test(cStart)) {
26346												break;
26347											}
26348											tStart += cStart;
26349										}
26350										while (++iEnd < endValue.length) {
26351											cEnd = endValue[iEnd];
26352											if (cEnd === dotEnd) {
26353												dotEnd = ".."; // Can never match two characters
26354											} else if (!/\d/.test(cEnd)) {
26355												break;
26356											}
26357											tEnd += cEnd;
26358										}
26359										var uStart = CSS.Hooks.getUnit(startValue, iStart), // temporary unit type
26360												uEnd = CSS.Hooks.getUnit(endValue, iEnd); // temporary unit type
26361
26362										iStart += uStart.length;
26363										iEnd += uEnd.length;
26364										if (uStart === uEnd) {
26365											// Same units
26366											if (tStart === tEnd) {
26367												// Same numbers, so just copy over
26368												pattern += tStart + uStart;
26369											} else {
26370												// Different numbers, so store them
26371												pattern += "{" + aStart.length + (inRGB ? "!" : "") + "}" + uStart;
26372												aStart.push(parseFloat(tStart));
26373												aEnd.push(parseFloat(tEnd));
26374											}
26375										} else {
26376											// Different units, so put into a "calc(from + to)" and animate each side to/from zero
26377											var nStart = parseFloat(tStart),
26378													nEnd = parseFloat(tEnd);
26379
26380											pattern += (inCalc < 5 ? "calc" : "") + "("
26381													+ (nStart ? "{" + aStart.length + (inRGB ? "!" : "") + "}" : "0") + uStart
26382													+ " + "
26383													+ (nEnd ? "{" + (aStart.length + 1) + (inRGB ? "!" : "") + "}" : "0") + uEnd
26384													+ ")";
26385											if (nStart) {
26386												aStart.push(parseFloat(tStart));
26387												aStart.push(parseFloat(0));
26388											}
26389											if (nEnd) {
26390												aEnd.push(parseFloat(0));
26391												aEnd.push(parseFloat(tEnd));
26392											}
26393										}
26394									} else if (cStart === cEnd) {
26395										pattern += cStart;
26396										iStart++;
26397										iEnd++;
26398										// Keep track of being inside a calc()
26399										if (inCalc === 0 && cStart === "c"
26400												|| inCalc === 1 && cStart === "a"
26401												|| inCalc === 2 && cStart === "l"
26402												|| inCalc === 3 && cStart === "c"
26403												|| inCalc >= 4 && cStart === "("
26404												) {
26405											inCalc++;
26406										} else if ((inCalc && inCalc < 5)
26407												|| inCalc >= 4 && cStart === ")" && --inCalc < 5) {
26408											inCalc = 0;
26409										}
26410										// Keep track of being inside an rgb() / rgba()
26411										if (inRGB === 0 && cStart === "r"
26412												|| inRGB === 1 && cStart === "g"
26413												|| inRGB === 2 && cStart === "b"
26414												|| inRGB === 3 && cStart === "a"
26415												|| inRGB >= 3 && cStart === "("
26416												) {
26417											if (inRGB === 3 && cStart === "a") {
26418												inRGBA = 1;
26419											}
26420											inRGB++;
26421										} else if (inRGBA && cStart === ",") {
26422											if (++inRGBA > 3) {
26423												inRGB = inRGBA = 0;
26424											}
26425										} else if ((inRGBA && inRGB < (inRGBA ? 5 : 4))
26426												|| inRGB >= (inRGBA ? 4 : 3) && cStart === ")" && --inRGB < (inRGBA ? 5 : 4)) {
26427											inRGB = inRGBA = 0;
26428										}
26429									} else {
26430										inCalc = 0;
26431										// TODO: changing units, fixing colours
26432										break;
26433									}
26434								}
26435								if (iStart !== startValue.length || iEnd !== endValue.length) {
26436									if (Velocity.debug) {
26437										console.error("Trying to pattern match mis-matched strings [\"" + endValue + "\", \"" + startValue + "\"]");
26438									}
26439									pattern = undefined;
26440								}
26441								if (pattern) {
26442									if (aStart.length) {
26443										if (Velocity.debug) {
26444											console.log("Pattern found \"" + pattern + "\" -> ", aStart, aEnd, "[" + startValue + "," + endValue + "]");
26445										}
26446										startValue = aStart;
26447										endValue = aEnd;
26448										endValueUnitType = startValueUnitType = "";
26449									} else {
26450										pattern = undefined;
26451									}
26452								}
26453							}
26454
26455							if (!pattern) {
26456								/* Separate startValue. */
26457								separatedValue = separateValue(property, startValue);
26458								startValue = separatedValue[0];
26459								startValueUnitType = separatedValue[1];
26460
26461								/* Separate endValue, and extract a value operator (e.g. "+=", "-=") if one exists. */
26462								separatedValue = separateValue(property, endValue);
26463								endValue = separatedValue[0].replace(/^([+-\/*])=/, function(match, subMatch) {
26464									operator = subMatch;
26465
26466									/* Strip the operator off of the value. */
26467									return "";
26468								});
26469								endValueUnitType = separatedValue[1];
26470
26471								/* Parse float values from endValue and startValue. Default to 0 if NaN is returned. */
26472								startValue = parseFloat(startValue) || 0;
26473								endValue = parseFloat(endValue) || 0;
26474
26475								/***************************************
26476								 Property-Specific Value Conversion
26477								 ***************************************/
26478
26479								/* Custom support for properties that don't actually accept the % unit type, but where pollyfilling is trivial and relatively foolproof. */
26480								if (endValueUnitType === "%") {
26481									/* A %-value fontSize/lineHeight is relative to the parent's fontSize (as opposed to the parent's dimensions),
26482									 which is identical to the em unit's behavior, so we piggyback off of that. */
26483									if (/^(fontSize|lineHeight)$/.test(property)) {
26484										/* Convert % into an em decimal value. */
26485										endValue = endValue / 100;
26486										endValueUnitType = "em";
26487										/* For scaleX and scaleY, convert the value into its decimal format and strip off the unit type. */
26488									} else if (/^scale/.test(property)) {
26489										endValue = endValue / 100;
26490										endValueUnitType = "";
26491										/* For RGB components, take the defined percentage of 255 and strip off the unit type. */
26492									} else if (/(Red|Green|Blue)$/i.test(property)) {
26493										endValue = (endValue / 100) * 255;
26494										endValueUnitType = "";
26495									}
26496								}
26497							}
26498
26499							/***************************
26500							 Unit Ratio Calculation
26501							 ***************************/
26502
26503							/* When queried, the browser returns (most) CSS property values in pixels. Therefore, if an endValue with a unit type of
26504							 %, em, or rem is animated toward, startValue must be converted from pixels into the same unit type as endValue in order
26505							 for value manipulation logic (increment/decrement) to proceed. Further, if the startValue was forcefed or transferred
26506							 from a previous call, startValue may also not be in pixels. Unit conversion logic therefore consists of two steps:
26507							 1) Calculating the ratio of %/em/rem/vh/vw relative to pixels
26508							 2) Converting startValue into the same unit of measurement as endValue based on these ratios. */
26509							/* Unit conversion ratios are calculated by inserting a sibling node next to the target node, copying over its position property,
26510							 setting values with the target unit type then comparing the returned pixel value. */
26511							/* Note: Even if only one of these unit types is being animated, all unit ratios are calculated at once since the overhead
26512							 of batching the SETs and GETs together upfront outweights the potential overhead
26513							 of layout thrashing caused by re-querying for uncalculated ratios for subsequently-processed properties. */
26514							/* Todo: Shift this logic into the calls' first tick instance so that it's synced with RAF. */
26515							var calculateUnitRatios = function() {
26516
26517								/************************
26518								 Same Ratio Checks
26519								 ************************/
26520
26521								/* The properties below are used to determine whether the element differs sufficiently from this call's
26522								 previously iterated element to also differ in its unit conversion ratios. If the properties match up with those
26523								 of the prior element, the prior element's conversion ratios are used. Like most optimizations in Velocity,
26524								 this is done to minimize DOM querying. */
26525								var sameRatioIndicators = {
26526									myParent: element.parentNode || document.body, /* GET */
26527									position: CSS.getPropertyValue(element, "position"), /* GET */
26528									fontSize: CSS.getPropertyValue(element, "fontSize") /* GET */
26529								},
26530										/* Determine if the same % ratio can be used. % is based on the element's position value and its parent's width and height dimensions. */
26531										samePercentRatio = ((sameRatioIndicators.position === callUnitConversionData.lastPosition) && (sameRatioIndicators.myParent === callUnitConversionData.lastParent)),
26532										/* Determine if the same em ratio can be used. em is relative to the element's fontSize. */
26533										sameEmRatio = (sameRatioIndicators.fontSize === callUnitConversionData.lastFontSize);
26534
26535								/* Store these ratio indicators call-wide for the next element to compare against. */
26536								callUnitConversionData.lastParent = sameRatioIndicators.myParent;
26537								callUnitConversionData.lastPosition = sameRatioIndicators.position;
26538								callUnitConversionData.lastFontSize = sameRatioIndicators.fontSize;
26539
26540								/***************************
26541								 Element-Specific Units
26542								 ***************************/
26543
26544								/* Note: IE8 rounds to the nearest pixel when returning CSS values, thus we perform conversions using a measurement
26545								 of 100 (instead of 1) to give our ratios a precision of at least 2 decimal values. */
26546								var measurement = 100,
26547										unitRatios = {};
26548
26549								if (!sameEmRatio || !samePercentRatio) {
26550									var dummy = data && data.isSVG ? document.createElementNS("http://www.w3.org/2000/svg", "rect") : document.createElement("div");
26551
26552									Velocity.init(dummy);
26553									sameRatioIndicators.myParent.appendChild(dummy);
26554
26555									/* To accurately and consistently calculate conversion ratios, the element's cascaded overflow and box-sizing are stripped.
26556									 Similarly, since width/height can be artificially constrained by their min-/max- equivalents, these are controlled for as well. */
26557									/* Note: Overflow must be also be controlled for per-axis since the overflow property overwrites its per-axis values. */
26558									$.each(["overflow", "overflowX", "overflowY"], function(i, property) {
26559										Velocity.CSS.setPropertyValue(dummy, property, "hidden");
26560									});
26561									Velocity.CSS.setPropertyValue(dummy, "position", sameRatioIndicators.position);
26562									Velocity.CSS.setPropertyValue(dummy, "fontSize", sameRatioIndicators.fontSize);
26563									Velocity.CSS.setPropertyValue(dummy, "boxSizing", "content-box");
26564
26565									/* width and height act as our proxy properties for measuring the horizontal and vertical % ratios. */
26566									$.each(["minWidth", "maxWidth", "width", "minHeight", "maxHeight", "height"], function(i, property) {
26567										Velocity.CSS.setPropertyValue(dummy, property, measurement + "%");
26568									});
26569									/* paddingLeft arbitrarily acts as our proxy property for the em ratio. */
26570									Velocity.CSS.setPropertyValue(dummy, "paddingLeft", measurement + "em");
26571
26572									/* 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. */
26573									unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth = (parseFloat(CSS.getPropertyValue(dummy, "width", null, true)) || 1) / measurement; /* GET */
26574									unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight = (parseFloat(CSS.getPropertyValue(dummy, "height", null, true)) || 1) / measurement; /* GET */
26575									unitRatios.emToPx = callUnitConversionData.lastEmToPx = (parseFloat(CSS.getPropertyValue(dummy, "paddingLeft")) || 1) / measurement; /* GET */
26576
26577									sameRatioIndicators.myParent.removeChild(dummy);
26578								} else {
26579									unitRatios.emToPx = callUnitConversionData.lastEmToPx;
26580									unitRatios.percentToPxWidth = callUnitConversionData.lastPercentToPxWidth;
26581									unitRatios.percentToPxHeight = callUnitConversionData.lastPercentToPxHeight;
26582								}
26583
26584								/***************************
26585								 Element-Agnostic Units
26586								 ***************************/
26587
26588								/* Whereas % and em ratios are determined on a per-element basis, the rem unit only needs to be checked
26589								 once per call since it's exclusively dependant upon document.body's fontSize. If this is the first time
26590								 that calculateUnitRatios() is being run during this call, remToPx will still be set to its default value of null,
26591								 so we calculate it now. */
26592								if (callUnitConversionData.remToPx === null) {
26593									/* Default to browsers' default fontSize of 16px in the case of 0. */
26594									callUnitConversionData.remToPx = parseFloat(CSS.getPropertyValue(document.body, "fontSize")) || 16; /* GET */
26595								}
26596
26597								/* Similarly, viewport units are %-relative to the window's inner dimensions. */
26598								if (callUnitConversionData.vwToPx === null) {
26599									callUnitConversionData.vwToPx = parseFloat(window.innerWidth) / 100; /* GET */
26600									callUnitConversionData.vhToPx = parseFloat(window.innerHeight) / 100; /* GET */
26601								}
26602
26603								unitRatios.remToPx = callUnitConversionData.remToPx;
26604								unitRatios.vwToPx = callUnitConversionData.vwToPx;
26605								unitRatios.vhToPx = callUnitConversionData.vhToPx;
26606
26607								if (Velocity.debug >= 1) {
26608									console.log("Unit ratios: " + JSON.stringify(unitRatios), element);
26609								}
26610								return unitRatios;
26611							};
26612
26613							/********************
26614							 Unit Conversion
26615							 ********************/
26616
26617							/* The * and / operators, which are not passed in with an associated unit, inherently use startValue's unit. Skip value and unit conversion. */
26618							if (/[\/*]/.test(operator)) {
26619								endValueUnitType = startValueUnitType;
26620								/* If startValue and endValue differ in unit type, convert startValue into the same unit type as endValue so that if endValueUnitType
26621								 is a relative unit (%, em, rem), the values set during tweening will continue to be accurately relative even if the metrics they depend
26622								 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
26623								 would become stale if the original unit being animated toward was relative and the underlying metrics change during the animation. */
26624								/* Since 0 is 0 in any unit type, no conversion is necessary when startValue is 0 -- we just start at 0 with endValueUnitType. */
26625							} else if ((startValueUnitType !== endValueUnitType) && startValue !== 0) {
26626								/* Unit conversion is also skipped when endValue is 0, but *startValueUnitType* must be used for tween values to remain accurate. */
26627								/* Note: Skipping unit conversion here means that if endValueUnitType was originally a relative unit, the animation won't relatively
26628								 match the underlying metrics if they change, but this is acceptable since we're animating toward invisibility instead of toward visibility,
26629								 which remains past the point of the animation's completion. */
26630								if (endValue === 0) {
26631									endValueUnitType = startValueUnitType;
26632								} else {
26633									/* By this point, we cannot avoid unit conversion (it's undesirable since it causes layout thrashing).
26634									 If we haven't already, we trigger calculateUnitRatios(), which runs once per element per call. */
26635									elementUnitConversionData = elementUnitConversionData || calculateUnitRatios();
26636
26637									/* The following RegEx matches CSS properties that have their % values measured relative to the x-axis. */
26638									/* 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. */
26639									var axis = (/margin|padding|left|right|width|text|word|letter/i.test(property) || /X$/.test(property) || property === "x") ? "x" : "y";
26640
26641									/* In order to avoid generating n^2 bespoke conversion functions, unit conversion is a two-step process:
26642									 1) Convert startValue into pixels. 2) Convert this new pixel value into endValue's unit type. */
26643									switch (startValueUnitType) {
26644										case "%":
26645											/* Note: translateX and translateY are the only properties that are %-relative to an element's own dimensions -- not its parent's dimensions.
26646											 Velocity does not include a special conversion process to account for this behavior. Therefore, animating translateX/Y from a % value
26647											 to a non-% value will produce an incorrect start value. Fortunately, this sort of cross-unit conversion is rarely done by users in practice. */
26648											startValue *= (axis === "x" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);
26649											break;
26650
26651										case "px":
26652											/* px acts as our midpoint in the unit conversion process; do nothing. */
26653											break;
26654
26655										default:
26656											startValue *= elementUnitConversionData[startValueUnitType + "ToPx"];
26657									}
26658
26659									/* Invert the px ratios to convert into to the target unit. */
26660									switch (endValueUnitType) {
26661										case "%":
26662											startValue *= 1 / (axis === "x" ? elementUnitConversionData.percentToPxWidth : elementUnitConversionData.percentToPxHeight);
26663											break;
26664
26665										case "px":
26666											/* startValue is already in px, do nothing; we're done. */
26667											break;
26668
26669										default:
26670											startValue *= 1 / elementUnitConversionData[endValueUnitType + "ToPx"];
26671									}
26672								}
26673							}
26674
26675							/*********************
26676							 Relative Values
26677							 *********************/
26678
26679							/* Operator logic must be performed last since it requires unit-normalized start and end values. */
26680							/* Note: Relative *percent values* do not behave how most people think; while one would expect "+=50%"
26681							 to increase the property 1.5x its current value, it in fact increases the percent units in absolute terms:
26682							 50 points is added on top of the current % value. */
26683							switch (operator) {
26684								case "+":
26685									endValue = startValue + endValue;
26686									break;
26687
26688								case "-":
26689									endValue = startValue - endValue;
26690									break;
26691
26692								case "*":
26693									endValue = startValue * endValue;
26694									break;
26695
26696								case "/":
26697									endValue = startValue / endValue;
26698									break;
26699							}
26700
26701							/**************************
26702							 tweensContainer Push
26703							 **************************/
26704
26705							/* Construct the per-property tween object, and push it to the element's tweensContainer. */
26706							tweensContainer[property] = {
26707								rootPropertyValue: rootPropertyValue,
26708								startValue: startValue,
26709								currentValue: startValue,
26710								endValue: endValue,
26711								unitType: endValueUnitType,
26712								easing: easing
26713							};
26714							if (pattern) {
26715								tweensContainer[property].pattern = pattern;
26716							}
26717
26718							if (Velocity.debug) {
26719								console.log("tweensContainer (" + property + "): " + JSON.stringify(tweensContainer[property]), element);
26720							}
26721						};
26722
26723						/* Create a tween out of each property, and append its associated data to tweensContainer. */
26724						for (var property in propertiesMap) {
26725
26726							if (!propertiesMap.hasOwnProperty(property)) {
26727								continue;
26728							}
26729							/* The original property name's format must be used for the parsePropertyValue() lookup,
26730							 but we then use its camelCase styling to normalize it for manipulation. */
26731							var propertyName = CSS.Names.camelCase(property),
26732									valueData = parsePropertyValue(propertiesMap[property]);
26733
26734							/* Find shorthand color properties that have been passed a hex string. */
26735							/* Would be quicker to use CSS.Lists.colors.includes() if possible */
26736							if (CSS.Lists.colors.indexOf(propertyName) >= 0) {
26737								/* Parse the value data for each shorthand. */
26738								var endValue = valueData[0],
26739										easing = valueData[1],
26740										startValue = valueData[2];
26741
26742								if (CSS.RegEx.isHex.test(endValue)) {
26743									/* Convert the hex strings into their RGB component arrays. */
26744									var colorComponents = ["Red", "Green", "Blue"],
26745											endValueRGB = CSS.Values.hexToRgb(endValue),
26746											startValueRGB = startValue ? CSS.Values.hexToRgb(startValue) : undefined;
26747
26748									/* Inject the RGB component tweens into propertiesMap. */
26749									for (var i = 0; i < colorComponents.length; i++) {
26750										var dataArray = [endValueRGB[i]];
26751
26752										if (easing) {
26753											dataArray.push(easing);
26754										}
26755
26756										if (startValueRGB !== undefined) {
26757											dataArray.push(startValueRGB[i]);
26758										}
26759
26760										fixPropertyValue(propertyName + colorComponents[i], dataArray);
26761									}
26762									/* If we have replaced a shortcut color value then don't update the standard property name */
26763									continue;
26764								}
26765							}
26766							fixPropertyValue(propertyName, valueData);
26767						}
26768
26769						/* Along with its property data, store a reference to the element itself onto tweensContainer. */
26770						tweensContainer.element = element;
26771					}
26772
26773					/*****************
26774					 Call Push
26775					 *****************/
26776
26777					/* Note: tweensContainer can be empty if all of the properties in this call's property map were skipped due to not
26778					 being supported by the browser. The element property is used for checking that the tweensContainer has been appended to. */
26779					if (tweensContainer.element) {
26780						/* Apply the "velocity-animating" indicator class. */
26781						CSS.Values.addClass(element, "velocity-animating");
26782
26783						/* The call array houses the tweensContainers for each element being animated in the current call. */
26784						call.push(tweensContainer);
26785
26786						data = Data(element);
26787
26788						if (data) {
26789							/* Store the tweensContainer and options if we're working on the default effects queue, so that they can be used by the reverse command. */
26790							if (opts.queue === "") {
26791
26792								data.tweensContainer = tweensContainer;
26793								data.opts = opts;
26794							}
26795
26796							/* Switch on the element's animating flag. */
26797							data.isAnimating = true;
26798						}
26799
26800						/* Once the final element in this call's element set has been processed, push the call array onto
26801						 Velocity.State.calls for the animation tick to immediately begin processing. */
26802						if (elementsIndex === elementsLength - 1) {
26803							/* Add the current call plus its associated metadata (the element set and the call's options) onto the global call container.
26804							 Anything on this call container is subjected to tick() processing. */
26805							Velocity.State.calls.push([call, elements, opts, null, promiseData.resolver, null, 0]);
26806
26807							/* If the animation tick isn't running, start it. (Velocity shuts it off when there are no active calls to process.) */
26808							if (Velocity.State.isTicking === false) {
26809								Velocity.State.isTicking = true;
26810
26811								/* Start the tick loop. */
26812								tick();
26813							}
26814						} else {
26815							elementsIndex++;
26816						}
26817					}
26818				}
26819
26820				/* When the queue option is set to false, the call skips the element's queue and fires immediately. */
26821				if (opts.queue === false) {
26822					/* Since this buildQueue call doesn't respect the element's existing queue (which is where a delay option would have been appended),
26823					 we manually inject the delay property here with an explicit setTimeout. */
26824					if (opts.delay) {
26825
26826						/* Temporarily store delayed elements to facilitate access for global pause/resume */
26827						var callIndex = Velocity.State.delayedElements.count++;
26828						Velocity.State.delayedElements[callIndex] = element;
26829
26830						var delayComplete = (function(index) {
26831							return function() {
26832								/* Clear the temporary element */
26833								Velocity.State.delayedElements[index] = false;
26834
26835								/* Finally, issue the call */
26836								buildQueue();
26837							};
26838						})(callIndex);
26839
26840						Data(element).delayBegin = (new Date()).getTime();
26841						Data(element).delay = parseFloat(opts.delay);
26842						Data(element).delayTimer = {
26843							setTimeout: setTimeout(buildQueue, parseFloat(opts.delay)),
26844							next: delayComplete
26845						};
26846					} else {
26847						buildQueue();
26848					}
26849					/* Otherwise, the call undergoes element queueing as normal. */
26850					/* Note: To interoperate with jQuery, Velocity uses jQuery's own $.queue() stack for queuing logic. */
26851				} else {
26852					$.queue(element, opts.queue, function(next, clearQueue) {
26853						/* If the clearQueue flag was passed in by the stop command, resolve this call's promise. (Promises can only be resolved once,
26854						 so it's fine if this is repeatedly triggered for each element in the associated call.) */
26855						if (clearQueue === true) {
26856							if (promiseData.promise) {
26857								promiseData.resolver(elements);
26858							}
26859
26860							/* Do not continue with animation queueing. */
26861							return true;
26862						}
26863
26864						/* This flag indicates to the upcoming completeCall() function that this queue entry was initiated by Velocity.
26865						 See completeCall() for further details. */
26866						Velocity.velocityQueueEntryFlag = true;
26867
26868						buildQueue(next);
26869					});
26870				}
26871
26872				/*********************
26873				 Auto-Dequeuing
26874				 *********************/
26875
26876				/* As per jQuery's $.queue() behavior, to fire the first non-custom-queue entry on an element, the element
26877				 must be dequeued if its queue stack consists *solely* of the current call. (This can be determined by checking
26878				 for the "inprogress" item that jQuery prepends to active queue stack arrays.) Regardless, whenever the element's
26879				 queue is further appended with additional items -- including $.delay()'s or even $.animate() calls, the queue's
26880				 first entry is automatically fired. This behavior contrasts that of custom queues, which never auto-fire. */
26881				/* Note: When an element set is being subjected to a non-parallel Velocity call, the animation will not begin until
26882				 each one of the elements in the set has reached the end of its individually pre-existing queue chain. */
26883				/* Note: Unfortunately, most people don't fully grasp jQuery's powerful, yet quirky, $.queue() function.
26884				 Lean more here: http://stackoverflow.com/questions/1058158/can-somebody-explain-jquery-queue-to-me */
26885				if ((opts.queue === "" || opts.queue === "fx") && $.queue(element)[0] !== "inprogress") {
26886					$.dequeue(element);
26887				}
26888			}
26889
26890			/**************************
26891			 Element Set Iteration
26892			 **************************/
26893
26894			/* If the "nodeType" property exists on the elements variable, we're animating a single element.
26895			 Place it in an array so that $.each() can iterate over it. */
26896			$.each(elements, function(i, element) {
26897				/* Ensure each element in a set has a nodeType (is a real element) to avoid throwing errors. */
26898				if (Type.isNode(element)) {
26899					processElement(element, i);
26900				}
26901			});
26902
26903			/******************
26904			 Option: Loop
26905			 ******************/
26906
26907			/* The loop option accepts an integer indicating how many times the element should loop between the values in the
26908			 current call's properties map and the element's property values prior to this call. */
26909			/* Note: The loop option's logic is performed here -- after element processing -- because the current call needs
26910			 to undergo its queue insertion prior to the loop option generating its series of constituent "reverse" calls,
26911			 which chain after the current call. Two reverse calls (two "alternations") constitute one loop. */
26912			opts = $.extend({}, Velocity.defaults, options);
26913			opts.loop = parseInt(opts.loop, 10);
26914			var reverseCallsCount = (opts.loop * 2) - 1;
26915
26916			if (opts.loop) {
26917				/* Double the loop count to convert it into its appropriate number of "reverse" calls.
26918				 Subtract 1 from the resulting value since the current call is included in the total alternation count. */
26919				for (var x = 0; x < reverseCallsCount; x++) {
26920					/* Since the logic for the reverse action occurs inside Queueing and therefore this call's options object
26921					 isn't parsed until then as well, the current call's delay option must be explicitly passed into the reverse
26922					 call so that the delay logic that occurs inside *Pre-Queueing* can process it. */
26923					var reverseOptions = {
26924						delay: opts.delay,
26925						progress: opts.progress
26926					};
26927
26928					/* If a complete callback was passed into this call, transfer it to the loop redirect's final "reverse" call
26929					 so that it's triggered when the entire redirect is complete (and not when the very first animation is complete). */
26930					if (x === reverseCallsCount - 1) {
26931						reverseOptions.display = opts.display;
26932						reverseOptions.visibility = opts.visibility;
26933						reverseOptions.complete = opts.complete;
26934					}
26935
26936					animate(elements, "reverse", reverseOptions);
26937				}
26938			}
26939
26940			/***************
26941			 Chaining
26942			 ***************/
26943
26944			/* Return the elements back to the call chain, with wrapped elements taking precedence in case Velocity was called via the $.fn. extension. */
26945			return getChain();
26946		};
26947
26948		/* Turn Velocity into the animation function, extended with the pre-existing Velocity object. */
26949		Velocity = $.extend(animate, Velocity);
26950		/* For legacy support, also expose the literal animate method. */
26951		Velocity.animate = animate;
26952
26953		/**************
26954		 Timing
26955		 **************/
26956
26957		/* Ticker function. */
26958		var ticker = window.requestAnimationFrame || rAFShim;
26959
26960		/* Inactive browser tabs pause rAF, which results in all active animations immediately sprinting to their completion states when the tab refocuses.
26961		 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
26962		 devices to avoid wasting battery power on inactive tabs. */
26963		/* 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. */
26964		if (!Velocity.State.isMobile && document.hidden !== undefined) {
26965			var updateTicker = function() {
26966				/* Reassign the rAF function (which the global tick() function uses) based on the tab's focus state. */
26967				if (document.hidden) {
26968					ticker = function(callback) {
26969						/* The tick function needs a truthy first argument in order to pass its internal timestamp check. */
26970						return setTimeout(function() {
26971							callback(true);
26972						}, 16);
26973					};
26974
26975					/* The rAF loop has been paused by the browser, so we manually restart the tick. */
26976					tick();
26977				} else {
26978					ticker = window.requestAnimationFrame || rAFShim;
26979				}
26980			};
26981
26982			/* 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 */
26983			updateTicker();
26984
26985			/* And then run check again every time visibility changes */
26986			document.addEventListener("visibilitychange", updateTicker);
26987		}
26988
26989		/************
26990		 Tick
26991		 ************/
26992
26993		/* Note: All calls to Velocity are pushed to the Velocity.State.calls array, which is fully iterated through upon each tick. */
26994		function tick(timestamp) {
26995			/* An empty timestamp argument indicates that this is the first tick occurence since ticking was turned on.
26996			 We leverage this metadata to fully ignore the first tick pass since RAF's initial pass is fired whenever
26997			 the browser's next tick sync time occurs, which results in the first elements subjected to Velocity
26998			 calls being animated out of sync with any elements animated immediately thereafter. In short, we ignore
26999			 the first RAF tick pass so that elements being immediately consecutively animated -- instead of simultaneously animated
27000			 by the same Velocity call -- are properly batched into the same initial RAF tick and consequently remain in sync thereafter. */
27001			if (timestamp) {
27002				/* We normally use RAF's high resolution timestamp but as it can be significantly offset when the browser is
27003				 under high stress we give the option for choppiness over allowing the browser to drop huge chunks of frames.
27004				 We use performance.now() and shim it if it doesn't exist for when the tab is hidden. */
27005				var timeCurrent = Velocity.timestamp && timestamp !== true ? timestamp : performance.now();
27006
27007				/********************
27008				 Call Iteration
27009				 ********************/
27010
27011				var callsLength = Velocity.State.calls.length;
27012
27013				/* To speed up iterating over this array, it is compacted (falsey items -- calls that have completed -- are removed)
27014				 when its length has ballooned to a point that can impact tick performance. This only becomes necessary when animation
27015				 has been continuous with many elements over a long period of time; whenever all active calls are completed, completeCall() clears Velocity.State.calls. */
27016				if (callsLength > 10000) {
27017					Velocity.State.calls = compactSparseArray(Velocity.State.calls);
27018					callsLength = Velocity.State.calls.length;
27019				}
27020
27021				/* Iterate through each active call. */
27022				for (var i = 0; i < callsLength; i++) {
27023					/* When a Velocity call is completed, its Velocity.State.calls entry is set to false. Continue on to the next call. */
27024					if (!Velocity.State.calls[i]) {
27025						continue;
27026					}
27027
27028					/************************
27029					 Call-Wide Variables
27030					 ************************/
27031
27032					var callContainer = Velocity.State.calls[i],
27033							call = callContainer[0],
27034							opts = callContainer[2],
27035							timeStart = callContainer[3],
27036							firstTick = !!timeStart,
27037							tweenDummyValue = null,
27038							pauseObject = callContainer[5],
27039							millisecondsEllapsed = callContainer[6];
27040
27041
27042
27043					/* If timeStart is undefined, then this is the first time that this call has been processed by tick().
27044					 We assign timeStart now so that its value is as close to the real animation start time as possible.
27045					 (Conversely, had timeStart been defined when this call was added to Velocity.State.calls, the delay
27046					 between that time and now would cause the first few frames of the tween to be skipped since
27047					 percentComplete is calculated relative to timeStart.) */
27048					/* Further, subtract 16ms (the approximate resolution of RAF) from the current time value so that the
27049					 first tick iteration isn't wasted by animating at 0% tween completion, which would produce the
27050					 same style value as the element's current value. */
27051					if (!timeStart) {
27052						timeStart = Velocity.State.calls[i][3] = timeCurrent - 16;
27053					}
27054
27055					/* If a pause object is present, skip processing unless it has been set to resume */
27056					if (pauseObject) {
27057						if (pauseObject.resume === true) {
27058							/* Update the time start to accomodate the paused completion amount */
27059							timeStart = callContainer[3] = Math.round(timeCurrent - millisecondsEllapsed - 16);
27060
27061							/* Remove pause object after processing */
27062							callContainer[5] = null;
27063						} else {
27064							continue;
27065						}
27066					}
27067
27068					millisecondsEllapsed = callContainer[6] = timeCurrent - timeStart;
27069
27070					/* The tween's completion percentage is relative to the tween's start time, not the tween's start value
27071					 (which would result in unpredictable tween durations since JavaScript's timers are not particularly accurate).
27072					 Accordingly, we ensure that percentComplete does not exceed 1. */
27073					var percentComplete = Math.min((millisecondsEllapsed) / opts.duration, 1);
27074
27075					/**********************
27076					 Element Iteration
27077					 **********************/
27078
27079					/* For every call, iterate through each of the elements in its set. */
27080					for (var j = 0, callLength = call.length; j < callLength; j++) {
27081						var tweensContainer = call[j],
27082								element = tweensContainer.element;
27083
27084						/* Check to see if this element has been deleted midway through the animation by checking for the
27085						 continued existence of its data cache. If it's gone, or the element is currently paused, skip animating this element. */
27086						if (!Data(element)) {
27087							continue;
27088						}
27089
27090						var transformPropertyExists = false;
27091
27092						/**********************************
27093						 Display & Visibility Toggling
27094						 **********************************/
27095
27096						/* If the display option is set to non-"none", set it upfront so that the element can become visible before tweening begins.
27097						 (Otherwise, display's "none" value is set in completeCall() once the animation has completed.) */
27098						if (opts.display !== undefined && opts.display !== null && opts.display !== "none") {
27099							if (opts.display === "flex") {
27100								var flexValues = ["-webkit-box", "-moz-box", "-ms-flexbox", "-webkit-flex"];
27101
27102								$.each(flexValues, function(i, flexValue) {
27103									CSS.setPropertyValue(element, "display", flexValue);
27104								});
27105							}
27106
27107							CSS.setPropertyValue(element, "display", opts.display);
27108						}
27109
27110						/* Same goes with the visibility option, but its "none" equivalent is "hidden". */
27111						if (opts.visibility !== undefined && opts.visibility !== "hidden") {
27112							CSS.setPropertyValue(element, "visibility", opts.visibility);
27113						}
27114
27115						/************************
27116						 Property Iteration
27117						 ************************/
27118
27119						/* For every element, iterate through each property. */
27120						for (var property in tweensContainer) {
27121							/* Note: In addition to property tween data, tweensContainer contains a reference to its associated element. */
27122							if (tweensContainer.hasOwnProperty(property) && property !== "element") {
27123								var tween = tweensContainer[property],
27124										currentValue,
27125										/* Easing can either be a pre-genereated function or a string that references a pre-registered easing
27126										 on the Velocity.Easings object. In either case, return the appropriate easing *function*. */
27127										easing = Type.isString(tween.easing) ? Velocity.Easings[tween.easing] : tween.easing;
27128
27129								/******************************
27130								 Current Value Calculation
27131								 ******************************/
27132
27133								if (Type.isString(tween.pattern)) {
27134									var patternReplace = percentComplete === 1 ?
27135											function($0, index, round) {
27136												var result = tween.endValue[index];
27137
27138												return round ? Math.round(result) : result;
27139											} :
27140											function($0, index, round) {
27141												var startValue = tween.startValue[index],
27142														tweenDelta = tween.endValue[index] - startValue,
27143														result = startValue + (tweenDelta * easing(percentComplete, opts, tweenDelta));
27144
27145												return round ? Math.round(result) : result;
27146											};
27147
27148									currentValue = tween.pattern.replace(/{(\d+)(!)?}/g, patternReplace);
27149								} else if (percentComplete === 1) {
27150									/* If this is the last tick pass (if we've reached 100% completion for this tween),
27151									 ensure that currentValue is explicitly set to its target endValue so that it's not subjected to any rounding. */
27152									currentValue = tween.endValue;
27153								} else {
27154									/* Otherwise, calculate currentValue based on the current delta from startValue. */
27155									var tweenDelta = tween.endValue - tween.startValue;
27156
27157									currentValue = tween.startValue + (tweenDelta * easing(percentComplete, opts, tweenDelta));
27158									/* If no value change is occurring, don't proceed with DOM updating. */
27159								}
27160								if (!firstTick && (currentValue === tween.currentValue)) {
27161									continue;
27162								}
27163
27164								tween.currentValue = currentValue;
27165
27166								/* If we're tweening a fake 'tween' property in order to log transition values, update the one-per-call variable so that
27167								 it can be passed into the progress callback. */
27168								if (property === "tween") {
27169									tweenDummyValue = currentValue;
27170								} else {
27171									/******************
27172									 Hooks: Part I
27173									 ******************/
27174									var hookRoot;
27175
27176									/* For hooked properties, the newly-updated rootPropertyValueCache is cached onto the element so that it can be used
27177									 for subsequent hooks in this call that are associated with the same root property. If we didn't cache the updated
27178									 rootPropertyValue, each subsequent update to the root property in this tick pass would reset the previous hook's
27179									 updates to rootPropertyValue prior to injection. A nice performance byproduct of rootPropertyValue caching is that
27180									 subsequently chained animations using the same hookRoot but a different hook can use this cached rootPropertyValue. */
27181									if (CSS.Hooks.registered[property]) {
27182										hookRoot = CSS.Hooks.getRoot(property);
27183
27184										var rootPropertyValueCache = Data(element).rootPropertyValueCache[hookRoot];
27185
27186										if (rootPropertyValueCache) {
27187											tween.rootPropertyValue = rootPropertyValueCache;
27188										}
27189									}
27190
27191									/*****************
27192									 DOM Update
27193									 *****************/
27194
27195									/* setPropertyValue() returns an array of the property name and property value post any normalization that may have been performed. */
27196									/* Note: To solve an IE<=8 positioning bug, the unit type is dropped when setting a property value of 0. */
27197									var adjustedSetData = CSS.setPropertyValue(element, /* SET */
27198											property,
27199											tween.currentValue + (IE < 9 && parseFloat(currentValue) === 0 ? "" : tween.unitType),
27200											tween.rootPropertyValue,
27201											tween.scrollData);
27202
27203									/*******************
27204									 Hooks: Part II
27205									 *******************/
27206
27207									/* Now that we have the hook's updated rootPropertyValue (the post-processed value provided by adjustedSetData), cache it onto the element. */
27208									if (CSS.Hooks.registered[property]) {
27209										/* Since adjustedSetData contains normalized data ready for DOM updating, the rootPropertyValue needs to be re-extracted from its normalized form. ?? */
27210										if (CSS.Normalizations.registered[hookRoot]) {
27211											Data(element).rootPropertyValueCache[hookRoot] = CSS.Normalizations.registered[hookRoot]("extract", null, adjustedSetData[1]);
27212										} else {
27213											Data(element).rootPropertyValueCache[hookRoot] = adjustedSetData[1];
27214										}
27215									}
27216
27217									/***************
27218									 Transforms
27219									 ***************/
27220
27221									/* Flag whether a transform property is being animated so that flushTransformCache() can be triggered once this tick pass is complete. */
27222									if (adjustedSetData[0] === "transform") {
27223										transformPropertyExists = true;
27224									}
27225
27226								}
27227							}
27228						}
27229
27230						/****************
27231						 mobileHA
27232						 ****************/
27233
27234						/* If mobileHA is enabled, set the translate3d transform to null to force hardware acceleration.
27235						 It's safe to override this property since Velocity doesn't actually support its animation (hooks are used in its place). */
27236						if (opts.mobileHA) {
27237							/* Don't set the null transform hack if we've already done so. */
27238							if (Data(element).transformCache.translate3d === undefined) {
27239								/* All entries on the transformCache object are later concatenated into a single transform string via flushTransformCache(). */
27240								Data(element).transformCache.translate3d = "(0px, 0px, 0px)";
27241
27242								transformPropertyExists = true;
27243							}
27244						}
27245
27246						if (transformPropertyExists) {
27247							CSS.flushTransformCache(element);
27248						}
27249					}
27250
27251					/* The non-"none" display value is only applied to an element once -- when its associated call is first ticked through.
27252					 Accordingly, it's set to false so that it isn't re-processed by this call in the next tick. */
27253					if (opts.display !== undefined && opts.display !== "none") {
27254						Velocity.State.calls[i][2].display = false;
27255					}
27256					if (opts.visibility !== undefined && opts.visibility !== "hidden") {
27257						Velocity.State.calls[i][2].visibility = false;
27258					}
27259
27260					/* Pass the elements and the timing data (percentComplete, msRemaining, timeStart, tweenDummyValue) into the progress callback. */
27261					if (opts.progress) {
27262						opts.progress.call(callContainer[1],
27263								callContainer[1],
27264								percentComplete,
27265								Math.max(0, (timeStart + opts.duration) - timeCurrent),
27266								timeStart,
27267								tweenDummyValue);
27268					}
27269
27270					/* If this call has finished tweening, pass its index to completeCall() to handle call cleanup. */
27271					if (percentComplete === 1) {
27272						completeCall(i);
27273					}
27274				}
27275			}
27276
27277			/* Note: completeCall() sets the isTicking flag to false when the last call on Velocity.State.calls has completed. */
27278			if (Velocity.State.isTicking) {
27279				ticker(tick);
27280			}
27281		}
27282
27283		/**********************
27284		 Call Completion
27285		 **********************/
27286
27287		/* Note: Unlike tick(), which processes all active calls at once, call completion is handled on a per-call basis. */
27288		function completeCall(callIndex, isStopped) {
27289			/* Ensure the call exists. */
27290			if (!Velocity.State.calls[callIndex]) {
27291				return false;
27292			}
27293
27294			/* Pull the metadata from the call. */
27295			var call = Velocity.State.calls[callIndex][0],
27296					elements = Velocity.State.calls[callIndex][1],
27297					opts = Velocity.State.calls[callIndex][2],
27298					resolver = Velocity.State.calls[callIndex][4];
27299
27300			var remainingCallsExist = false;
27301
27302			/*************************
27303			 Element Finalization
27304			 *************************/
27305
27306			for (var i = 0, callLength = call.length; i < callLength; i++) {
27307				var element = call[i].element;
27308
27309				/* If the user set display to "none" (intending to hide the element), set it now that the animation has completed. */
27310				/* Note: display:none isn't set when calls are manually stopped (via Velocity("stop"). */
27311				/* Note: Display gets ignored with "reverse" calls and infinite loops, since this behavior would be undesirable. */
27312				if (!isStopped && !opts.loop) {
27313					if (opts.display === "none") {
27314						CSS.setPropertyValue(element, "display", opts.display);
27315					}
27316
27317					if (opts.visibility === "hidden") {
27318						CSS.setPropertyValue(element, "visibility", opts.visibility);
27319					}
27320				}
27321
27322				/* 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
27323				 a non-Velocity-initiated entry, turn off the isAnimating flag. A non-Velocity-initiatied queue entry's logic might alter
27324				 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,
27325				 we check for the existence of our special Velocity.queueEntryFlag declaration, which minifiers won't rename since the flag
27326				 is assigned to jQuery's global $ object and thus exists out of Velocity's own scope. */
27327				var data = Data(element);
27328
27329				if (opts.loop !== true && ($.queue(element)[1] === undefined || !/\.velocityQueueEntryFlag/i.test($.queue(element)[1]))) {
27330					/* The element may have been deleted. Ensure that its data cache still exists before acting on it. */
27331					if (data) {
27332						data.isAnimating = false;
27333						/* Clear the element's rootPropertyValueCache, which will become stale. */
27334						data.rootPropertyValueCache = {};
27335
27336						var transformHAPropertyExists = false;
27337						/* If any 3D transform subproperty is at its default value (regardless of unit type), remove it. */
27338						$.each(CSS.Lists.transforms3D, function(i, transformName) {
27339							var defaultValue = /^scale/.test(transformName) ? 1 : 0,
27340									currentValue = data.transformCache[transformName];
27341
27342							if (data.transformCache[transformName] !== undefined && new RegExp("^\\(" + defaultValue + "[^.]").test(currentValue)) {
27343								transformHAPropertyExists = true;
27344
27345								delete data.transformCache[transformName];
27346							}
27347						});
27348
27349						/* Mobile devices have hardware acceleration removed at the end of the animation in order to avoid hogging the GPU's memory. */
27350						if (opts.mobileHA) {
27351							transformHAPropertyExists = true;
27352							delete data.transformCache.translate3d;
27353						}
27354
27355						/* Flush the subproperty removals to the DOM. */
27356						if (transformHAPropertyExists) {
27357							CSS.flushTransformCache(element);
27358						}
27359
27360						/* Remove the "velocity-animating" indicator class. */
27361						CSS.Values.removeClass(element, "velocity-animating");
27362					}
27363				}
27364
27365				/*********************
27366				 Option: Complete
27367				 *********************/
27368
27369				/* 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. */
27370				/* Note: Callbacks aren't fired when calls are manually stopped (via Velocity("stop"). */
27371				if (!isStopped && opts.complete && !opts.loop && (i === callLength - 1)) {
27372					/* We throw callbacks in a setTimeout so that thrown errors don't halt the execution of Velocity itself. */
27373					try {
27374						opts.complete.call(elements, elements);
27375					} catch (error) {
27376						setTimeout(function() {
27377							throw error;
27378						}, 1);
27379					}
27380				}
27381
27382				/**********************
27383				 Promise Resolving
27384				 **********************/
27385
27386				/* Note: Infinite loops don't return promises. */
27387				if (resolver && opts.loop !== true) {
27388					resolver(elements);
27389				}
27390
27391				/****************************
27392				 Option: Loop (Infinite)
27393				 ****************************/
27394
27395				if (data && opts.loop === true && !isStopped) {
27396					/* If a rotateX/Y/Z property is being animated by 360 deg with loop:true, swap tween start/end values to enable
27397					 continuous iterative rotation looping. (Otherise, the element would just rotate back and forth.) */
27398					$.each(data.tweensContainer, function(propertyName, tweenContainer) {
27399						if (/^rotate/.test(propertyName) && ((parseFloat(tweenContainer.startValue) - parseFloat(tweenContainer.endValue)) % 360 === 0)) {
27400							var oldStartValue = tweenContainer.startValue;
27401
27402							tweenContainer.startValue = tweenContainer.endValue;
27403							tweenContainer.endValue = oldStartValue;
27404						}
27405
27406						if (/^backgroundPosition/.test(propertyName) && parseFloat(tweenContainer.endValue) === 100 && tweenContainer.unitType === "%") {
27407							tweenContainer.endValue = 0;
27408							tweenContainer.startValue = 100;
27409						}
27410					});
27411
27412					Velocity(element, "reverse", {loop: true, delay: opts.delay});
27413				}
27414
27415				/***************
27416				 Dequeueing
27417				 ***************/
27418
27419				/* Fire the next call in the queue so long as this call's queue wasn't set to false (to trigger a parallel animation),
27420				 which would have already caused the next call to fire. Note: Even if the end of the animation queue has been reached,
27421				 $.dequeue() must still be called in order to completely clear jQuery's animation queue. */
27422				if (opts.queue !== false) {
27423					$.dequeue(element, opts.queue);
27424				}
27425			}
27426
27427			/************************
27428			 Calls Array Cleanup
27429			 ************************/
27430
27431			/* Since this call is complete, set it to false so that the rAF tick skips it. This array is later compacted via compactSparseArray().
27432			 (For performance reasons, the call is set to false instead of being deleted from the array: http://www.html5rocks.com/en/tutorials/speed/v8/) */
27433			Velocity.State.calls[callIndex] = false;
27434
27435			/* Iterate through the calls array to determine if this was the final in-progress animation.
27436			 If so, set a flag to end ticking and clear the calls array. */
27437			for (var j = 0, callsLength = Velocity.State.calls.length; j < callsLength; j++) {
27438				if (Velocity.State.calls[j] !== false) {
27439					remainingCallsExist = true;
27440
27441					break;
27442				}
27443			}
27444
27445			if (remainingCallsExist === false) {
27446				/* tick() will detect this flag upon its next iteration and subsequently turn itself off. */
27447				Velocity.State.isTicking = false;
27448
27449				/* Clear the calls array so that its length is reset. */
27450				delete Velocity.State.calls;
27451				Velocity.State.calls = [];
27452			}
27453		}
27454
27455		/******************
27456		 Frameworks
27457		 ******************/
27458
27459		/* Both jQuery and Zepto allow their $.fn object to be extended to allow wrapped elements to be subjected to plugin calls.
27460		 If either framework is loaded, register a "velocity" extension pointing to Velocity's core animate() method.  Velocity
27461		 also registers itself onto a global container (window.jQuery || window.Zepto || window) so that certain features are
27462		 accessible beyond just a per-element scope. This master object contains an .animate() method, which is later assigned to $.fn
27463		 (if jQuery or Zepto are present). Accordingly, Velocity can both act on wrapped DOM elements and stand alone for targeting raw DOM elements. */
27464		global.Velocity = Velocity;
27465
27466		if (global !== window) {
27467			/* Assign the element function to Velocity's core animate() method. */
27468			global.fn.velocity = animate;
27469			/* Assign the object function's defaults to Velocity's global defaults object. */
27470			global.fn.velocity.defaults = Velocity.defaults;
27471		}
27472
27473		/***********************
27474		 Packaged Redirects
27475		 ***********************/
27476
27477		/* slideUp, slideDown */
27478		$.each(["Down", "Up"], function(i, direction) {
27479			Velocity.Redirects["slide" + direction] = function(element, options, elementsIndex, elementsSize, elements, promiseData) {
27480				var opts = $.extend({}, options),
27481						begin = opts.begin,
27482						complete = opts.complete,
27483						inlineValues = {},
27484						computedValues = {height: "", marginTop: "", marginBottom: "", paddingTop: "", paddingBottom: ""};
27485
27486				if (opts.display === undefined) {
27487					/* Show the element before slideDown begins and hide the element after slideUp completes. */
27488					/* Note: Inline elements cannot have dimensions animated, so they're reverted to inline-block. */
27489					opts.display = (direction === "Down" ? (Velocity.CSS.Values.getDisplayType(element) === "inline" ? "inline-block" : "block") : "none");
27490				}
27491
27492				opts.begin = function() {
27493					/* If the user passed in a begin callback, fire it now. */
27494					if (elementsIndex === 0 && begin) {
27495						begin.call(elements, elements);
27496					}
27497
27498					/* Cache the elements' original vertical dimensional property values so that we can animate back to them. */
27499					for (var property in computedValues) {
27500						if (!computedValues.hasOwnProperty(property)) {
27501							continue;
27502						}
27503						inlineValues[property] = element.style[property];
27504
27505						/* For slideDown, use forcefeeding to animate all vertical properties from 0. For slideUp,
27506						 use forcefeeding to start from computed values and animate down to 0. */
27507						var propertyValue = CSS.getPropertyValue(element, property);
27508						computedValues[property] = (direction === "Down") ? [propertyValue, 0] : [0, propertyValue];
27509					}
27510
27511					/* Force vertical overflow content to clip so that sliding works as expected. */
27512					inlineValues.overflow = element.style.overflow;
27513					element.style.overflow = "hidden";
27514				};
27515
27516				opts.complete = function() {
27517					/* Reset element to its pre-slide inline values once its slide animation is complete. */
27518					for (var property in inlineValues) {
27519						if (inlineValues.hasOwnProperty(property)) {
27520							element.style[property] = inlineValues[property];
27521						}
27522					}
27523
27524					/* If the user passed in a complete callback, fire it now. */
27525					if (elementsIndex === elementsSize - 1) {
27526						if (complete) {
27527							complete.call(elements, elements);
27528						}
27529						if (promiseData) {
27530							promiseData.resolver(elements);
27531						}
27532					}
27533				};
27534
27535				Velocity(element, computedValues, opts);
27536			};
27537		});
27538
27539		/* fadeIn, fadeOut */
27540		$.each(["In", "Out"], function(i, direction) {
27541			Velocity.Redirects["fade" + direction] = function(element, options, elementsIndex, elementsSize, elements, promiseData) {
27542				var opts = $.extend({}, options),
27543						complete = opts.complete,
27544						propertiesMap = {opacity: (direction === "In") ? 1 : 0};
27545
27546				/* Since redirects are triggered individually for each element in the animated set, avoid repeatedly triggering
27547				 callbacks by firing them only when the final element has been reached. */
27548				if (elementsIndex !== 0) {
27549					opts.begin = null;
27550				}
27551				if (elementsIndex !== elementsSize - 1) {
27552					opts.complete = null;
27553				} else {
27554					opts.complete = function() {
27555						if (complete) {
27556							complete.call(elements, elements);
27557						}
27558						if (promiseData) {
27559							promiseData.resolver(elements);
27560						}
27561					};
27562				}
27563
27564				/* If a display was passed in, use it. Otherwise, default to "none" for fadeOut or the element-specific default for fadeIn. */
27565				/* Note: We allow users to pass in "null" to skip display setting altogether. */
27566				if (opts.display === undefined) {
27567					opts.display = (direction === "In" ? "auto" : "none");
27568				}
27569
27570				Velocity(this, propertiesMap, opts);
27571			};
27572		});
27573
27574		return Velocity;
27575	}((window.jQuery || window.Zepto || window), window, (window ? window.document : undefined));
27576}));
27577
27578/******************
27579 Known Issues
27580 ******************/
27581
27582/* The CSS spec mandates that the translateX/Y/Z transforms are %-relative to the element itself -- not its parent.
27583 Velocity, however, doesn't make this distinction. Thus, converting to or from the % unit with these subproperties
27584 will produce an inaccurate conversion value. The same issue exists with the cx/cy attributes of SVG circles and ellipses. */
27585
27586},{}],4:[function(require,module,exports){
27587/*!
27588Waypoints - 4.0.1
27589Copyright © 2011-2016 Caleb Troughton
27590Licensed under the MIT license.
27591https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
27592*/
27593(function() {
27594  'use strict'
27595
27596  var keyCounter = 0
27597  var allWaypoints = {}
27598
27599  /* http://imakewebthings.com/waypoints/api/waypoint */
27600  function Waypoint(options) {
27601    if (!options) {
27602      throw new Error('No options passed to Waypoint constructor')
27603    }
27604    if (!options.element) {
27605      throw new Error('No element option passed to Waypoint constructor')
27606    }
27607    if (!options.handler) {
27608      throw new Error('No handler option passed to Waypoint constructor')
27609    }
27610
27611    this.key = 'waypoint-' + keyCounter
27612    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
27613    this.element = this.options.element
27614    this.adapter = new Waypoint.Adapter(this.element)
27615    this.callback = options.handler
27616    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
27617    this.enabled = this.options.enabled
27618    this.triggerPoint = null
27619    this.group = Waypoint.Group.findOrCreate({
27620      name: this.options.group,
27621      axis: this.axis
27622    })
27623    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
27624
27625    if (Waypoint.offsetAliases[this.options.offset]) {
27626      this.options.offset = Waypoint.offsetAliases[this.options.offset]
27627    }
27628    this.group.add(this)
27629    this.context.add(this)
27630    allWaypoints[this.key] = this
27631    keyCounter += 1
27632  }
27633
27634  /* Private */
27635  Waypoint.prototype.queueTrigger = function(direction) {
27636    this.group.queueTrigger(this, direction)
27637  }
27638
27639  /* Private */
27640  Waypoint.prototype.trigger = function(args) {
27641    if (!this.enabled) {
27642      return
27643    }
27644    if (this.callback) {
27645      this.callback.apply(this, args)
27646    }
27647  }
27648
27649  /* Public */
27650  /* http://imakewebthings.com/waypoints/api/destroy */
27651  Waypoint.prototype.destroy = function() {
27652    this.context.remove(this)
27653    this.group.remove(this)
27654    delete allWaypoints[this.key]
27655  }
27656
27657  /* Public */
27658  /* http://imakewebthings.com/waypoints/api/disable */
27659  Waypoint.prototype.disable = function() {
27660    this.enabled = false
27661    return this
27662  }
27663
27664  /* Public */
27665  /* http://imakewebthings.com/waypoints/api/enable */
27666  Waypoint.prototype.enable = function() {
27667    this.context.refresh()
27668    this.enabled = true
27669    return this
27670  }
27671
27672  /* Public */
27673  /* http://imakewebthings.com/waypoints/api/next */
27674  Waypoint.prototype.next = function() {
27675    return this.group.next(this)
27676  }
27677
27678  /* Public */
27679  /* http://imakewebthings.com/waypoints/api/previous */
27680  Waypoint.prototype.previous = function() {
27681    return this.group.previous(this)
27682  }
27683
27684  /* Private */
27685  Waypoint.invokeAll = function(method) {
27686    var allWaypointsArray = []
27687    for (var waypointKey in allWaypoints) {
27688      allWaypointsArray.push(allWaypoints[waypointKey])
27689    }
27690    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
27691      allWaypointsArray[i][method]()
27692    }
27693  }
27694
27695  /* Public */
27696  /* http://imakewebthings.com/waypoints/api/destroy-all */
27697  Waypoint.destroyAll = function() {
27698    Waypoint.invokeAll('destroy')
27699  }
27700
27701  /* Public */
27702  /* http://imakewebthings.com/waypoints/api/disable-all */
27703  Waypoint.disableAll = function() {
27704    Waypoint.invokeAll('disable')
27705  }
27706
27707  /* Public */
27708  /* http://imakewebthings.com/waypoints/api/enable-all */
27709  Waypoint.enableAll = function() {
27710    Waypoint.Context.refreshAll()
27711    for (var waypointKey in allWaypoints) {
27712      allWaypoints[waypointKey].enabled = true
27713    }
27714    return this
27715  }
27716
27717  /* Public */
27718  /* http://imakewebthings.com/waypoints/api/refresh-all */
27719  Waypoint.refreshAll = function() {
27720    Waypoint.Context.refreshAll()
27721  }
27722
27723  /* Public */
27724  /* http://imakewebthings.com/waypoints/api/viewport-height */
27725  Waypoint.viewportHeight = function() {
27726    return window.innerHeight || document.documentElement.clientHeight
27727  }
27728
27729  /* Public */
27730  /* http://imakewebthings.com/waypoints/api/viewport-width */
27731  Waypoint.viewportWidth = function() {
27732    return document.documentElement.clientWidth
27733  }
27734
27735  Waypoint.adapters = []
27736
27737  Waypoint.defaults = {
27738    context: window,
27739    continuous: true,
27740    enabled: true,
27741    group: 'default',
27742    horizontal: false,
27743    offset: 0
27744  }
27745
27746  Waypoint.offsetAliases = {
27747    'bottom-in-view': function() {
27748      return this.context.innerHeight() - this.adapter.outerHeight()
27749    },
27750    'right-in-view': function() {
27751      return this.context.innerWidth() - this.adapter.outerWidth()
27752    }
27753  }
27754
27755  window.Waypoint = Waypoint
27756}())
27757;(function() {
27758  'use strict'
27759
27760  function requestAnimationFrameShim(callback) {
27761    window.setTimeout(callback, 1000 / 60)
27762  }
27763
27764  var keyCounter = 0
27765  var contexts = {}
27766  var Waypoint = window.Waypoint
27767  var oldWindowLoad = window.onload
27768
27769  /* http://imakewebthings.com/waypoints/api/context */
27770  function Context(element) {
27771    this.element = element
27772    this.Adapter = Waypoint.Adapter
27773    this.adapter = new this.Adapter(element)
27774    this.key = 'waypoint-context-' + keyCounter
27775    this.didScroll = false
27776    this.didResize = false
27777    this.oldScroll = {
27778      x: this.adapter.scrollLeft(),
27779      y: this.adapter.scrollTop()
27780    }
27781    this.waypoints = {
27782      vertical: {},
27783      horizontal: {}
27784    }
27785
27786    element.waypointContextKey = this.key
27787    contexts[element.waypointContextKey] = this
27788    keyCounter += 1
27789    if (!Waypoint.windowContext) {
27790      Waypoint.windowContext = true
27791      Waypoint.windowContext = new Context(window)
27792    }
27793
27794    this.createThrottledScrollHandler()
27795    this.createThrottledResizeHandler()
27796  }
27797
27798  /* Private */
27799  Context.prototype.add = function(waypoint) {
27800    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
27801    this.waypoints[axis][waypoint.key] = waypoint
27802    this.refresh()
27803  }
27804
27805  /* Private */
27806  Context.prototype.checkEmpty = function() {
27807    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
27808    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
27809    var isWindow = this.element == this.element.window
27810    if (horizontalEmpty && verticalEmpty && !isWindow) {
27811      this.adapter.off('.waypoints')
27812      delete contexts[this.key]
27813    }
27814  }
27815
27816  /* Private */
27817  Context.prototype.createThrottledResizeHandler = function() {
27818    var self = this
27819
27820    function resizeHandler() {
27821      self.handleResize()
27822      self.didResize = false
27823    }
27824
27825    this.adapter.on('resize.waypoints', function() {
27826      if (!self.didResize) {
27827        self.didResize = true
27828        Waypoint.requestAnimationFrame(resizeHandler)
27829      }
27830    })
27831  }
27832
27833  /* Private */
27834  Context.prototype.createThrottledScrollHandler = function() {
27835    var self = this
27836    function scrollHandler() {
27837      self.handleScroll()
27838      self.didScroll = false
27839    }
27840
27841    this.adapter.on('scroll.waypoints', function() {
27842      if (!self.didScroll || Waypoint.isTouch) {
27843        self.didScroll = true
27844        Waypoint.requestAnimationFrame(scrollHandler)
27845      }
27846    })
27847  }
27848
27849  /* Private */
27850  Context.prototype.handleResize = function() {
27851    Waypoint.Context.refreshAll()
27852  }
27853
27854  /* Private */
27855  Context.prototype.handleScroll = function() {
27856    var triggeredGroups = {}
27857    var axes = {
27858      horizontal: {
27859        newScroll: this.adapter.scrollLeft(),
27860        oldScroll: this.oldScroll.x,
27861        forward: 'right',
27862        backward: 'left'
27863      },
27864      vertical: {
27865        newScroll: this.adapter.scrollTop(),
27866        oldScroll: this.oldScroll.y,
27867        forward: 'down',
27868        backward: 'up'
27869      }
27870    }
27871
27872    for (var axisKey in axes) {
27873      var axis = axes[axisKey]
27874      var isForward = axis.newScroll > axis.oldScroll
27875      var direction = isForward ? axis.forward : axis.backward
27876
27877      for (var waypointKey in this.waypoints[axisKey]) {
27878        var waypoint = this.waypoints[axisKey][waypointKey]
27879        if (waypoint.triggerPoint === null) {
27880          continue
27881        }
27882        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
27883        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
27884        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
27885        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
27886        if (crossedForward || crossedBackward) {
27887          waypoint.queueTrigger(direction)
27888          triggeredGroups[waypoint.group.id] = waypoint.group
27889        }
27890      }
27891    }
27892
27893    for (var groupKey in triggeredGroups) {
27894      triggeredGroups[groupKey].flushTriggers()
27895    }
27896
27897    this.oldScroll = {
27898      x: axes.horizontal.newScroll,
27899      y: axes.vertical.newScroll
27900    }
27901  }
27902
27903  /* Private */
27904  Context.prototype.innerHeight = function() {
27905    /*eslint-disable eqeqeq */
27906    if (this.element == this.element.window) {
27907      return Waypoint.viewportHeight()
27908    }
27909    /*eslint-enable eqeqeq */
27910    return this.adapter.innerHeight()
27911  }
27912
27913  /* Private */
27914  Context.prototype.remove = function(waypoint) {
27915    delete this.waypoints[waypoint.axis][waypoint.key]
27916    this.checkEmpty()
27917  }
27918
27919  /* Private */
27920  Context.prototype.innerWidth = function() {
27921    /*eslint-disable eqeqeq */
27922    if (this.element == this.element.window) {
27923      return Waypoint.viewportWidth()
27924    }
27925    /*eslint-enable eqeqeq */
27926    return this.adapter.innerWidth()
27927  }
27928
27929  /* Public */
27930  /* http://imakewebthings.com/waypoints/api/context-destroy */
27931  Context.prototype.destroy = function() {
27932    var allWaypoints = []
27933    for (var axis in this.waypoints) {
27934      for (var waypointKey in this.waypoints[axis]) {
27935        allWaypoints.push(this.waypoints[axis][waypointKey])
27936      }
27937    }
27938    for (var i = 0, end = allWaypoints.length; i < end; i++) {
27939      allWaypoints[i].destroy()
27940    }
27941  }
27942
27943  /* Public */
27944  /* http://imakewebthings.com/waypoints/api/context-refresh */
27945  Context.prototype.refresh = function() {
27946    /*eslint-disable eqeqeq */
27947    var isWindow = this.element == this.element.window
27948    /*eslint-enable eqeqeq */
27949    var contextOffset = isWindow ? undefined : this.adapter.offset()
27950    var triggeredGroups = {}
27951    var axes
27952
27953    this.handleScroll()
27954    axes = {
27955      horizontal: {
27956        contextOffset: isWindow ? 0 : contextOffset.left,
27957        contextScroll: isWindow ? 0 : this.oldScroll.x,
27958        contextDimension: this.innerWidth(),
27959        oldScroll: this.oldScroll.x,
27960        forward: 'right',
27961        backward: 'left',
27962        offsetProp: 'left'
27963      },
27964      vertical: {
27965        contextOffset: isWindow ? 0 : contextOffset.top,
27966        contextScroll: isWindow ? 0 : this.oldScroll.y,
27967        contextDimension: this.innerHeight(),
27968        oldScroll: this.oldScroll.y,
27969        forward: 'down',
27970        backward: 'up',
27971        offsetProp: 'top'
27972      }
27973    }
27974
27975    for (var axisKey in axes) {
27976      var axis = axes[axisKey]
27977      for (var waypointKey in this.waypoints[axisKey]) {
27978        var waypoint = this.waypoints[axisKey][waypointKey]
27979        var adjustment = waypoint.options.offset
27980        var oldTriggerPoint = waypoint.triggerPoint
27981        var elementOffset = 0
27982        var freshWaypoint = oldTriggerPoint == null
27983        var contextModifier, wasBeforeScroll, nowAfterScroll
27984        var triggeredBackward, triggeredForward
27985
27986        if (waypoint.element !== waypoint.element.window) {
27987          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
27988        }
27989
27990        if (typeof adjustment === 'function') {
27991          adjustment = adjustment.apply(waypoint)
27992        }
27993        else if (typeof adjustment === 'string') {
27994          adjustment = parseFloat(adjustment)
27995          if (waypoint.options.offset.indexOf('%') > - 1) {
27996            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
27997          }
27998        }
27999
28000        contextModifier = axis.contextScroll - axis.contextOffset
28001        waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
28002        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
28003        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
28004        triggeredBackward = wasBeforeScroll && nowAfterScroll
28005        triggeredForward = !wasBeforeScroll && !nowAfterScroll
28006
28007        if (!freshWaypoint && triggeredBackward) {
28008          waypoint.queueTrigger(axis.backward)
28009          triggeredGroups[waypoint.group.id] = waypoint.group
28010        }
28011        else if (!freshWaypoint && triggeredForward) {
28012          waypoint.queueTrigger(axis.forward)
28013          triggeredGroups[waypoint.group.id] = waypoint.group
28014        }
28015        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
28016          waypoint.queueTrigger(axis.forward)
28017          triggeredGroups[waypoint.group.id] = waypoint.group
28018        }
28019      }
28020    }
28021
28022    Waypoint.requestAnimationFrame(function() {
28023      for (var groupKey in triggeredGroups) {
28024        triggeredGroups[groupKey].flushTriggers()
28025      }
28026    })
28027
28028    return this
28029  }
28030
28031  /* Private */
28032  Context.findOrCreateByElement = function(element) {
28033    return Context.findByElement(element) || new Context(element)
28034  }
28035
28036  /* Private */
28037  Context.refreshAll = function() {
28038    for (var contextId in contexts) {
28039      contexts[contextId].refresh()
28040    }
28041  }
28042
28043  /* Public */
28044  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
28045  Context.findByElement = function(element) {
28046    return contexts[element.waypointContextKey]
28047  }
28048
28049  window.onload = function() {
28050    if (oldWindowLoad) {
28051      oldWindowLoad()
28052    }
28053    Context.refreshAll()
28054  }
28055
28056
28057  Waypoint.requestAnimationFrame = function(callback) {
28058    var requestFn = window.requestAnimationFrame ||
28059      window.mozRequestAnimationFrame ||
28060      window.webkitRequestAnimationFrame ||
28061      requestAnimationFrameShim
28062    requestFn.call(window, callback)
28063  }
28064  Waypoint.Context = Context
28065}())
28066;(function() {
28067  'use strict'
28068
28069  function byTriggerPoint(a, b) {
28070    return a.triggerPoint - b.triggerPoint
28071  }
28072
28073  function byReverseTriggerPoint(a, b) {
28074    return b.triggerPoint - a.triggerPoint
28075  }
28076
28077  var groups = {
28078    vertical: {},
28079    horizontal: {}
28080  }
28081  var Waypoint = window.Waypoint
28082
28083  /* http://imakewebthings.com/waypoints/api/group */
28084  function Group(options) {
28085    this.name = options.name
28086    this.axis = options.axis
28087    this.id = this.name + '-' + this.axis
28088    this.waypoints = []
28089    this.clearTriggerQueues()
28090    groups[this.axis][this.name] = this
28091  }
28092
28093  /* Private */
28094  Group.prototype.add = function(waypoint) {
28095    this.waypoints.push(waypoint)
28096  }
28097
28098  /* Private */
28099  Group.prototype.clearTriggerQueues = function() {
28100    this.triggerQueues = {
28101      up: [],
28102      down: [],
28103      left: [],
28104      right: []
28105    }
28106  }
28107
28108  /* Private */
28109  Group.prototype.flushTriggers = function() {
28110    for (var direction in this.triggerQueues) {
28111      var waypoints = this.triggerQueues[direction]
28112      var reverse = direction === 'up' || direction === 'left'
28113      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
28114      for (var i = 0, end = waypoints.length; i < end; i += 1) {
28115        var waypoint = waypoints[i]
28116        if (waypoint.options.continuous || i === waypoints.length - 1) {
28117          waypoint.trigger([direction])
28118        }
28119      }
28120    }
28121    this.clearTriggerQueues()
28122  }
28123
28124  /* Private */
28125  Group.prototype.next = function(waypoint) {
28126    this.waypoints.sort(byTriggerPoint)
28127    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
28128    var isLast = index === this.waypoints.length - 1
28129    return isLast ? null : this.waypoints[index + 1]
28130  }
28131
28132  /* Private */
28133  Group.prototype.previous = function(waypoint) {
28134    this.waypoints.sort(byTriggerPoint)
28135    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
28136    return index ? this.waypoints[index - 1] : null
28137  }
28138
28139  /* Private */
28140  Group.prototype.queueTrigger = function(waypoint, direction) {
28141    this.triggerQueues[direction].push(waypoint)
28142  }
28143
28144  /* Private */
28145  Group.prototype.remove = function(waypoint) {
28146    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
28147    if (index > -1) {
28148      this.waypoints.splice(index, 1)
28149    }
28150  }
28151
28152  /* Public */
28153  /* http://imakewebthings.com/waypoints/api/first */
28154  Group.prototype.first = function() {
28155    return this.waypoints[0]
28156  }
28157
28158  /* Public */
28159  /* http://imakewebthings.com/waypoints/api/last */
28160  Group.prototype.last = function() {
28161    return this.waypoints[this.waypoints.length - 1]
28162  }
28163
28164  /* Private */
28165  Group.findOrCreate = function(options) {
28166    return groups[options.axis][options.name] || new Group(options)
28167  }
28168
28169  Waypoint.Group = Group
28170}())
28171;(function() {
28172  'use strict'
28173
28174  var $ = window.jQuery
28175  var Waypoint = window.Waypoint
28176
28177  function JQueryAdapter(element) {
28178    this.$element = $(element)
28179  }
28180
28181  $.each([
28182    'innerHeight',
28183    'innerWidth',
28184    'off',
28185    'offset',
28186    'on',
28187    'outerHeight',
28188    'outerWidth',
28189    'scrollLeft',
28190    'scrollTop'
28191  ], function(i, method) {
28192    JQueryAdapter.prototype[method] = function() {
28193      var args = Array.prototype.slice.call(arguments)
28194      return this.$element[method].apply(this.$element, args)
28195    }
28196  })
28197
28198  $.each([
28199    'extend',
28200    'inArray',
28201    'isEmptyObject'
28202  ], function(i, method) {
28203    JQueryAdapter[method] = $[method]
28204  })
28205
28206  Waypoint.adapters.push({
28207    name: 'jquery',
28208    Adapter: JQueryAdapter
28209  })
28210  Waypoint.Adapter = JQueryAdapter
28211}())
28212;(function() {
28213  'use strict'
28214
28215  var Waypoint = window.Waypoint
28216
28217  function createExtension(framework) {
28218    return function() {
28219      var waypoints = []
28220      var overrides = arguments[0]
28221
28222      if (framework.isFunction(arguments[0])) {
28223        overrides = framework.extend({}, arguments[1])
28224        overrides.handler = arguments[0]
28225      }
28226
28227      this.each(function() {
28228        var options = framework.extend({}, overrides, {
28229          element: this
28230        })
28231        if (typeof options.context === 'string') {
28232          options.context = framework(this).closest(options.context)[0]
28233        }
28234        waypoints.push(new Waypoint(options))
28235      })
28236
28237      return waypoints
28238    }
28239  }
28240
28241  if (window.jQuery) {
28242    window.jQuery.fn.waypoint = createExtension(window.jQuery)
28243  }
28244  if (window.Zepto) {
28245    window.Zepto.fn.waypoint = createExtension(window.Zepto)
28246  }
28247}())
28248;
28249},{}],5:[function(require,module,exports){
28250(function (global){(function (){
28251'use strict';
28252
28253var moment = require('moment');
28254var _ = require('lodash');
28255
28256var current_page = null;
28257$('.load-posts').on('click', function (e) {
28258  e.preventDefault();
28259  var domain = window.location.protocol + '//' + window.location.host,
28260      $btn = $(this),
28261      load = {
28262    slug: $btn.data('url'),
28263    text: $btn.text(),
28264    width: $btn.width(),
28265    current: parseInt($btn.data('current-page')),
28266    total: parseInt($btn.data('total-pages'))
28267  };
28268
28269  if (!current_page) {
28270    current_page = load.current;
28271  }
28272
28273  if (current_page >= load.total) {
28274    return;
28275  }
28276
28277  $btn.addClass('loading').width(load.width).text('Loading Posts');
28278  $.ajax({
28279    url: domain + load.slug + '/page/' + (parseInt(current_page) + 1),
28280    method: 'GET',
28281    success: function success(response) {
28282      current_page++;
28283      var grid = $('#posts-list');
28284      grid.append($(response).find('#posts-list article'));
28285      if (current_page >= load.total) {
28286        $('.pagination').velocity('slideUp', 800, 'easeInOutExpo', function () {
28287          $btn.addClass('is-hidden');
28288        });
28289      } else {
28290        $btn.removeClass('loading').text(load.text).css('width', '');
28291      }
28292    }
28293  });
28294});
28295
28296$('.posts-list').each(function () {
28297
28298  var $blogList = $(this);
28299  var feedType = $blogList.data('type');
28300  var feedURL = $blogList.data('feed');
28301  var showImage = $blogList.data('show-image');
28302  var postCount = $blogList.data('count');
28303
28304  if (!global.suppress || !$blogList.parents('.editable').length) {
28305    $.ajax({
28306      url: global.appUrl + '/feed_api?url=' + encodeURIComponent(feedType == 'internal' ? global.siteUrl + feedURL : feedURL),
28307      method: 'GET',
28308      timeout: 10000,
28309      success: function success(response) {
28310
28311        if (response.length) {
28312          var $injectArea = $blogList.find('.posts-wrapper');
28313          $injectArea.find('.loading').hide();
28314          if (postCount) response = response.slice(0, postCount);
28315
28316          response.forEach(function (item) {
28317
28318            var categories = '';
28319            item.categories.forEach(function (category) {
28320              categories += '<span class="category">' + category + '</span> ';
28321            });
28322
28323            if (categories.length) {
28324              categories = '<span class="post-categories">' + categories + '</span>';
28325            }
28326
28327            var image = item.image.url && showImage ? '<figure class="post-thumbnail"><img src="' + item.image.url + '" alt="' + item.title + ' thumbnail"></figure>' : '';
28328            var excerpt = item.description ? '<div class="post-excerpt">' + item.description + '</div>' : '';
28329            var date = item.date ? '<time datetime="' + moment(item.date).format('YYYY-MM-DD') + '">' + moment(item.date).format('MMMM D, YYYY') + '</time>' : '';
28330
28331            var article = '<article class="post-link">\n                              <a href="' + item.link + '">
28331\n                                ' + image + '\n                                <header class="post-header">\n                                  <div class="post-meta">\n                                    ' + date + '\n                                  </div>\n                                  <h3>' + item.title + '</h3>\n                                </header>\n                              </a>\n                              ' + excerpt + '\n                              ' + categories + '\n                           </article>\n                        ';
28332
28333            $injectArea.append(article);
28334          });
28335        } else {
28336          var $injectArea = $blogList.find('.posts-wrapper');
28337          $injectArea.find('.loading').text('No Posts Found');
28338        }
28339      },
28340      error: function error(_error) {
28341        console.log(_error);
28342        var $injectArea = $blogList.find('.posts-wrapper');
28343        $injectArea.find('.loading').text(_error);
28344      }
28345    });
28346  }
28347});
28348
28349}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
28350},{"lodash":1,"moment":2}],6:[function(require,module,exports){
28351'use strict';
28352
28353require('./navigation');
28354require('./blogs');
28355require('velocity-animate');
28356
28357function checkHeader() {
28358  window.requestAnimationFrame(function () {
28359    if ($(window).scrollTop() > 0) {
28360      $('body').removeClass('transparent-header');
28361    } else {
28362      $('body').addClass('transparent-header');
28363    }
28364  }.bind(this));
28365}
28366
28367function headerPush() {
28368  var height = document.getElementById('header').offsetHeight;
28369  document.getElementsByClassName('header-push')[0].style.height = height + 'px';
28370}
28371
28372if ($('.has-fixed-header.transparent-header').length) {
28373  $(window).on('scroll', checkHeader);
28374}
28375
28376$(function () {
28377  if ($('.header-push').length) {
28378    headerPush();
28379    $(window).on('resize', headerPush);
28380  }
28381});
28382
28383$('.menu-toggle').on('click', function (e) {
28384  e.preventDefault();
28385
28386  if ($(this).hasClass('open')) {
28387    $('#main-navigation').velocity('slideUp', 500, 'easeOutExpo');
28388  } else {
28389    $('#main-navigation').velocity('slideDown', 500, 'easeOutExpo');
28390  }
28391
28392  $(this).toggleClass('open');
28393});
28394
28395// tabs
28396$('.tabs-nav a[data-tab]').on('click', function (e) {
28397  e.preventDefault();
28398
28399  var $tab = $(this),
28400      tabHref = $tab.data('tab'),
28401      $tabsNav = $tab.closest('.section-tabs').find('.tabs-nav li'),
28402      $tabsWrapper = $tab.closest('.section-tabs').find('.tabs-content'),
28403      newTabHeight = $tabsWrapper.find('.tab-pane[data-tab="' + tabHref + '"]').outerHeight();
28404
28405  $tabsNav.removeClass('active');
28406  $tab.parent().addClass('active');
28407
28408  history.pushState({ slug: tabHref }, null, '/' + tabHref);
28409
28410  $tabsWrapper.css('height', $tabsWrapper.find('.tab-pane.active').outerHeight());
28411  $tabsWrapper.find('.tab-pane').removeClass('active');
28412
28413  $tabsWrapper.velocity({
28414    height: newTabHeight
28415  }, 400, 'easeInOutExpo', function () {
28416    $tabsWrapper.find('.tab-pane[data-tab="' + tabHref + '"]').addClass('active');
28417    $tabsWrapper.removeAttr('style');
28418  });
28419});
28420
28421// overlays
28422$('.open-overlay').on('click', function (e) {
28423  e.preventDefault();
28424  if (!window.suppress || $(this).parents('.members-list').length) {
28425    // disable while editing unless team bio
28426    var modal = $(this).data('target');
28427    $('html').addClass('overlay-open');
28428    if (modal) {
28429      $('#' + modal).addClass('is-showing');
28430    } else {
28431      $(this).parent().find('.overlay-content').addClass('is-showing');
28432    }
28433  }
28434});
28435
28436$('.close-overlay').on('click', function (e) {
28437  e.preventDefault();
28438  $('html').removeClass('overlay-open');
28439  $('.overlay-content').removeClass('is-showing');
28440});
28441
28442// accordions
28443$('.toggle-accordion').on('click', function (e) {
28444  e.preventDefault();
28445  var $accordion = $(this).parent().find('.accordion-content');
28446  if ($(this).hasClass('open')) {
28447    $accordion.velocity('slideUp', 500, 'easeInOutExpo', function () {});
28448  } else {
28449    $accordion.velocity('slideDown', 500, 'easeInOutExpo', function () {});
28450  }
28451  $(this).toggleClass('open');
28452});
28453
28454},{"./blogs":5,"./navigation":7,"velocity-animate":3}],7:[function(require,module,exports){
28455"use strict";
28456
28457require("velocity-animate");
28458var Waypoint = require("waypoints");
28459
28460function scrollToSection(slug) {
28461  var headerHeight = $("#header").hasClass("overlay") ? "" : $("#header").outerHeight(),
28462      scrollSettings = {
28463    duration: 900,
28464    easing: "easeInOutQuint",
28465    offset: -headerHeight
28466  };
28467
28468  if (slug) {
28469    if ($("#section-" + slug + " .main-content-wrapper").length && slug !== "home") {
28470      $("#section-" + slug + " .main-content-wrapper").velocity("scroll", scrollSettings);
28471    } else if ($("#section-" + slug).length) {
28472      $("#section-" + slug).velocity("scroll", scrollSettings);
28473    } else {
28474      if ($('.tabs-nav a[data-tab="' + slug + '"]').closest(".main-content-wrapper").length) {
28475        $('.tabs-nav a[data-tab="' + slug + '"]').closest(".main-content-wrapper").velocity("scroll", scrollSettings);
28476      } else {
28477        $('.tabs-nav a[data-tab="' + slug + '"]').closest(".section").velocity("scroll", scrollSettings);
28478      }
28479    }
28480  }
28481}
28482
28483function navigation() {
28484  var currentSlug = window.location.pathname.substring(1).split("/")[0];
28485
28486  // scroll onLoad
28487  $(document).ready(function () {
28488    scrollToSection(currentSlug);
28489  });
28490
28491  $(window).on("load", function () {
28492    scrollToSection(currentSlug);
28493  });
28494
28495  $("a[data-section]").on("click", function (e) {
28496    e.preventDefault();
28497
28498    var slug = $(this).data("section");
28499
28500    if ($("#section-" + slug).length) {
28501      $("#main-navigation li").removeClass("active");
28502      $(this).parent("li").addClass("active");
28503      history.pushState({ slug: slug }, null, "/" + (slug === "home" ? "" : slug));
28504
28505      scrollToSection(slug);
28506    } else {
28507      window.location = "/" + slug;
28508    }
28509
28510    if ($(".menu-toggle").is(":visible")) {
28511      $(".menu-toggle.open").trigger("click");
28512    }
28513  });
28514
28515  window.addEventListener("popstate", function (e) {
28516    if (!e.state) return;
28517
28518    var slug = e.state.slug;
28519
28520    $("#main-navigation li").removeClass("active");
28521    $('#main-navigation a[data-section="' + slug.split("/")[0] + '"]').parent("li").addClass("active");
28522    scrollToSection(slug.split("/")[0]);
28523
28524    if (slug.split("/")[1]) {
28525      var $tab = $('.tabs-nav a[data-tab="' + slug + '"]'),
28526          tabHref = $tab.data("tab"),
28527          $tabsWrapper = $tab.closest(".section-tabs").find(".tabs-content"),
28528          newTabHeight = $tabsWrapper.find('.tab-pane[data-tab="' + tabHref + '"]').outerHeight();
28529
28530      $(".tabs-nav li").removeClass("active");
28531      $tab.parent().addClass("active");
28532
28533      $tabsWrapper.css("height", $tabsWrapper.find(".tab-pane.active").outerHeight());
28534      $tabsWrapper.find(".tab-pane").removeClass("active");
28535
28536      $tabsWrapper.velocity({
28537        height: newTabHeight
28538      }, 400, "easeInOutExpo", function () {
28539        $tabsWrapper.find('.tab-pane[data-tab="' + tabHref + '"]').addClass("active");
28540        $tabsWrapper.removeAttr("style");
28541      });
28542    }
28543  });
28544
28545  var waypointsDown = $(".section").waypoint({
28546    offset: function offset() {
28547      return $("#header").height();
28548    },
28549    handler: function handler(direction) {
28550      if (direction === "down") {
28551        var slug = this.element.id.replace("section-", "");
28552        $("#main-navigation li").removeClass("active");
28553        $('#main-navigation a[data-section="' + slug + '"]').parent("li").addClass("active");
28554      }
28555    }
28556  });
28557
28558  var waypointsUp = $(".section").waypoint({
28559    offset: function offset() {
28560      return -this.element.clientHeight + $("#header").height();
28561    },
28562    handler: function handler(direction) {
28563      if (direction === "up") {
28564        var slug = this.element.id.replace("section-", "");
28565        $("#main-navigation li").removeClass("active");
28566        $('#main-navigation a[data-section="' + slug + '"]').parent("li").addClass("active");
28567      }
28568    }
28569  });
28570}
28571
28572module.exports = new navigation();
28573
28574},{"velocity-animate":3,"waypoints":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.