PageSourceSearch

https://catalog.kuzcolighting.com/assets/application-ecat-e0cf6dc9…4a1d3b7737045ef8d73a7b50d693b32cfba0c6ea.js

js kuzcolighting.com collected 2026-09-30 15:23:19 UTC 1,697,828 bytes, 53,680 lines download raw bytes

vendor: 6,429 bytes, lines 1-185
1/**
2 * @license
3 * Lodash <https://lodash.com/>
4 * Copyright JS Foundation and other contributors <https://js.foundation/>
5 * Released under MIT license <https://lodash.com/license>
6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8 */
9
10;(function() {
11
12  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
13  var undefined;
14
15  /** Used as the semantic version number. */
16  var VERSION = '4.17.4';
17
18  /** Used as the size to enable large array optimizations. */
19  var LARGE_ARRAY_SIZE = 200;
20
21  /** Error message constants. */
22  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
23      FUNC_ERROR_TEXT = 'Expected a function';
24
25  /** Used to stand-in for `undefined` hash values. */
26  var HASH_UNDEFINED = '__lodash_hash_undefined__';
27
28  /** Used as the maximum memoize cache size. */
29  var MAX_MEMOIZE_SIZE = 500;
30
31  /** Used as the internal argument placeholder. */
32  var PLACEHOLDER = '__lodash_placeholder__';
33
34  /** Used to compose bitmasks for cloning. */
35  var CLONE_DEEP_FLAG = 1,
36      CLONE_FLAT_FLAG = 2,
37      CLONE_SYMBOLS_FLAG = 4;
38
39  /** Used to compose bitmasks for value comparisons. */
40  var COMPARE_PARTIAL_FLAG = 1,
41      COMPARE_UNORDERED_FLAG = 2;
42
43  /** Used to compose bitmasks for function metadata. */
44  var WRAP_BIND_FLAG = 1,
45      WRAP_BIND_KEY_FLAG = 2,
46      WRAP_CURRY_BOUND_FLAG = 4,
47      WRAP_CURRY_FLAG = 8,
48      WRAP_CURRY_RIGHT_FLAG = 16,
49      WRAP_PARTIAL_FLAG = 32,
50      WRAP_PARTIAL_RIGHT_FLAG = 64,
51      WRAP_ARY_FLAG = 128,
52      WRAP_REARG_FLAG = 256,
53      WRAP_FLIP_FLAG = 512;
54
55  /** Used as default options for `_.truncate`. */
56  var DEFAULT_TRUNC_LENGTH = 30,
57      DEFAULT_TRUNC_OMISSION = '...';
58
59  /** Used to detect hot functions by number of calls within a span of milliseconds. */
60  var HOT_COUNT = 800,
61      HOT_SPAN = 16;
62
63  /** Used to indicate the type of lazy iteratees. */
64  var LAZY_FILTER_FLAG = 1,
65      LAZY_MAP_FLAG = 2,
66      LAZY_WHILE_FLAG = 3;
67
68  /** Used as references for various `Number` constants. */
69  var INFINITY = 1 / 0,
70      MAX_SAFE_INTEGER = 9007199254740991,
71      MAX_INTEGER = 1.7976931348623157e+308,
72      NAN = 0 / 0;
73
74  /** Used as references for the maximum length and index of an array. */
75  var MAX_ARRAY_LENGTH = 4294967295,
76      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
77      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
78
79  /** Used to associate wrap methods with their bit flags. */
80  var wrapFlags = [
81    ['ary', WRAP_ARY_FLAG],
82    ['bind', WRAP_BIND_FLAG],
83    ['bindKey', WRAP_BIND_KEY_FLAG],
84    ['curry', WRAP_CURRY_FLAG],
85    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
86    ['flip', WRAP_FLIP_FLAG],
87    ['partial', WRAP_PARTIAL_FLAG],
88    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
89    ['rearg', WRAP_REARG_FLAG]
90  ];
91
92  /** `Object#toString` result references. */
93  var argsTag = '[object Arguments]',
94      arrayTag = '[object Array]',
95      asyncTag = '[object AsyncFunction]',
96      boolTag = '[object Boolean]',
97      dateTag = '[object Date]',
98      domExcTag = '[object DOMException]',
99      errorTag = '[object Error]',
100      funcTag = '[object Function]',
101      genTag = '[object GeneratorFunction]',
102      mapTag = '[object Map]',
103      numberTag = '[object Number]',
104      nullTag = '[object Null]',
105      objectTag = '[object Object]',
106      promiseTag = '[object Promise]',
107      proxyTag = '[object Proxy]',
108      regexpTag = '[object RegExp]',
109      setTag = '[object Set]',
110      stringTag = '[object String]',
111      symbolTag = '[object Symbol]',
112      undefinedTag = '[object Undefined]',
113      weakMapTag = '[object WeakMap]',
114      weakSetTag = '[object WeakSet]';
115
116  var arrayBufferTag = '[object ArrayBuffer]',
117      dataViewTag = '[object DataView]',
118      float32Tag = '[object Float32Array]',
119      float64Tag = '[object Float64Array]',
120      int8Tag = '[object Int8Array]',
121      int16Tag = '[object Int16Array]',
122      int32Tag = '[object Int32Array]',
123      uint8Tag = '[object Uint8Array]',
124      uint8ClampedTag = '[object Uint8ClampedArray]',
125      uint16Tag = '[object Uint16Array]',
126      uint32Tag = '[object Uint32Array]';
127
128  /** Used to match empty string literals in compiled template source. */
129  var reEmptyStringLeading = /\b__p \+= '';/g,
130      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
131      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
132
133  /** Used to match HTML entities and HTML characters. */
134  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
135      reUnescapedHtml = /[&<>"']/g,
136      reHasEscapedHtml = RegExp(reEscapedHtml.source),
137      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
138
139  /** Used to match template delimiters. */
140  var reEscape = /<%-([\s\S]+?)%>/g,
141      reEvaluate = /<%([\s\S]+?)%>/g,
142      reInterpolate = /<%=([\s\S]+?)%>/g;
143
144  /** Used to match property names within property paths. */
145  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
146      reIsPlainProp = /^\w*$/,
147      reLeadingDot = /^\./,
148      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
149
150  /**
151   * Used to match `RegExp`
152   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
153   */
154  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
155      reHasRegExpChar = RegExp(reRegExpChar.source);
156
157  /** Used to match leading and trailing whitespace. */
158  var reTrim = /^\s+|\s+$/g,
159      reTrimStart = /^\s+/,
160      reTrimEnd = /\s+$/;
161
162  /** Used to match wrap detail comments. */
163  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
164      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
165      reSplitDetails = /,? & /;
166
167  /** Used to match words composed of alphanumeric characters. */
168  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
169
170  /** Used to match backslashes in property paths. */
171  var reEscapeChar = /\\(\\)?/g;
172
173  /**
174   * Used to match
175   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
176   */
177  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
178
179  /** Used to match `RegExp` flags from their coerced string values. */
180  var reFlags = /\w*$/;
181
182  /** Used to detect bad signed hexadecimal string values. */
183  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
184
185  /** Used to detect binary string values. */
vendor: 4,600 bytes, lines 186-281
186  var reIsBinary = /^0b[01]+$/i;
187
188  /** Used to detect host constructors (Safari). */
189  var reIsHostCtor = /^\[object .+?Constructor\]$/;
190
191  /** Used to detect octal string values. */
192  var reIsOctal = /^0o[0-7]+$/i;
193
194  /** Used to detect unsigned integer values. */
195  var reIsUint = /^(?:0|[1-9]\d*)$/;
196
197  /** Used to match Latin Unicode letters (excluding mathematical operators). */
198  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
199
200  /** Used to ensure capturing order of template delimiters. */
201  var reNoMatch = /($^)/;
202
203  /** Used to match unescaped characters in compiled string literals. */
204  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
205
206  /** Used to compose unicode character classes. */
207  var rsAstralRange = '\\ud800-\\udfff',
208      rsComboMarksRange = '\\u0300-\\u036f',
209      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
210      rsComboSymbolsRange = '\\u20d0-\\u20ff',
211      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
212      rsDingbatRange = '\\u2700-\\u27bf',
213      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
214      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
215      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
216      rsPunctuationRange = '\\u2000-\\u206f',
217      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',
218      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
219      rsVarRange = '\\ufe0e\\ufe0f',
220      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
221
222  /** Used to compose unicode capture groups. */
223  var rsApos = "['\u2019]",
224      rsAstral = '[' + rsAstralRange + ']',
225      rsBreak = '[' + rsBreakRange + ']',
226      rsCombo = '[' + rsComboRange + ']',
227      rsDigits = '\\d+',
228      rsDingbat = '[' + rsDingbatRange + ']',
229      rsLower = '[' + rsLowerRange + ']',
230      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
231      rsFitz = '\\ud83c[\\udffb-\\udfff]',
232      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
233      rsNonAstral = '[^' + rsAstralRange + ']',
234      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
235      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
236      rsUpper = '[' + rsUpperRange + ']',
237      rsZWJ = '\\u200d';
238
239  /** Used to compose unicode regexes. */
240  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
241      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
242      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
243      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
244      reOptMod = rsModifier + '?',
245      rsOptVar = '[' + rsVarRange + ']?',
246      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
247      rsOrdLower = '\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)',
248      rsOrdUpper = '\\d*(?:(?:1ST|2ND|3RD|(?![123])\\dTH)\\b)',
249      rsSeq = rsOptVar + reOptMod + rsOptJoin,
250      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
251      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
252
253  /** Used to match apostrophes. */
254  var reApos = RegExp(rsApos, 'g');
255
256  /**
257   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
258   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
259   */
260  var reComboMark = RegExp(rsCombo, 'g');
261
262  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
263  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
264
265  /** Used to match complex or compound words. */
266  var reUnicodeWord = RegExp([
267    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
268    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
269    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
270    rsUpper + '+' + rsOptContrUpper,
271    rsOrdUpper,
272    rsOrdLower,
273    rsDigits,
274    rsEmoji
275  ].join('|'), 'g');
276
277  /** 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/). */
278  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
279
280  /** Used to detect strings that need a more robust regexp to match words. */
281  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,
vendor: 7,054 bytes, lines 281-441
281}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
282
283  /** Used to assign default `context` object properties. */
284  var contextProps = [
285    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
286    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
287    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
288    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
289    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
290  ];
291
292  /** Used to make template sourceURLs easier to identify. */
293  var templateCounter = -1;
294
295  /** Used to identify `toStringTag` values of typed arrays. */
296  var typedArrayTags = {};
297  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
298  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
299  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
300  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
301  typedArrayTags[uint32Tag] = true;
302  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
303  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
304  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
305  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
306  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
307  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
308  typedArrayTags[setTag] = typedArrayTags[stringTag] =
309  typedArrayTags[weakMapTag] = false;
310
311  /** Used to identify `toStringTag` values supported by `_.clone`. */
312  var cloneableTags = {};
313  cloneableTags[argsTag] = cloneableTags[arrayTag] =
314  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
315  cloneableTags[boolTag] = cloneableTags[dateTag] =
316  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
317  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
318  cloneableTags[int32Tag] = cloneableTags[mapTag] =
319  cloneableTags[numberTag] = cloneableTags[objectTag] =
320  cloneableTags[regexpTag] = cloneableTags[setTag] =
321  cloneableTags[stringTag] = cloneableTags[symbolTag] =
322  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
323  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
324  cloneableTags[errorTag] = cloneableTags[funcTag] =
325  cloneableTags[weakMapTag] = false;
326
327  /** Used to map Latin Unicode letters to basic Latin letters. */
328  var deburredLetters = {
329    // Latin-1 Supplement block.
330    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
331    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
332    '\xc7': 'C',  '\xe7': 'c',
333    '\xd0': 'D',  '\xf0': 'd',
334    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
335    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
336    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
337    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
338    '\xd1': 'N',  '\xf1': 'n',
339    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
340    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
341    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
342    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
343    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
344    '\xc6': 'Ae', '\xe6': 'ae',
345    '\xde': 'Th', '\xfe': 'th',
346    '\xdf': 'ss',
347    // Latin Extended-A block.
348    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
349    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
350    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
351    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
352    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
353    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
354    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
355    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
356    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
357    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
358    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
359    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
360    '\u0134': 'J',  '\u0135': 'j',
361    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
362    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
363    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
364    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
365    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
366    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
367    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
368    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
369    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
370    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
371    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
372    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
373    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
374    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
375    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
376    '\u0174': 'W',  '\u0175': 'w',
377    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
378    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
379    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
380    '\u0132': 'IJ', '\u0133': 'ij',
381    '\u0152': 'Oe', '\u0153': 'oe',
382    '\u0149': "'n", '\u017f': 's'
383  };
384
385  /** Used to map characters to HTML entities. */
386  var htmlEscapes = {
387    '&': '&amp;',
388    '<': '&lt;',
389    '>': '&gt;',
390    '"': '&quot;',
391    "'": '&#39;'
392  };
393
394  /** Used to map HTML entities to characters. */
395  var htmlUnescapes = {
396    '&amp;': '&',
397    '&lt;': '<',
398    '&gt;': '>',
399    '&quot;': '"',
400    '&#39;': "'"
401  };
402
403  /** Used to escape characters for inclusion in compiled string literals. */
404  var stringEscapes = {
405    '\\': '\\',
406    "'": "'",
407    '\n': 'n',
408    '\r': 'r',
409    '\u2028': 'u2028',
410    '\u2029': 'u2029'
411  };
412
413  /** Built-in method references without a dependency on `root`. */
414  var freeParseFloat = parseFloat,
415      freeParseInt = parseInt;
416
417  /** Detect free variable `global` from Node.js. */
418  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
419
420  /** Detect free variable `self`. */
421  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
422
423  /** Used as a reference to the global object. */
424  var root = freeGlobal || freeSelf || Function('return this')();
425
426  /** Detect free variable `exports`. */
427  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
428
429  /** Detect free variable `module`. */
430  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
431
432  /** Detect the popular CommonJS extension `module.exports`. */
433  var moduleExports = freeModule && freeModule.exports === freeExports;
434
435  /** Detect free variable `process` from Node.js. */
436  var freeProcess = moduleExports && freeGlobal.process;
437
438  /** Used to access faster Node.js helpers. */
439  var nodeUtil = (function() {
440    try {
441      
441return freeProcess && freeProcess.binding && freeProcess.binding('util');
442    } catch (e) {}
443  }());
444
445  /* Node.js helper references. */
446  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
447      nodeIsDate = nodeUtil && nodeUtil.isDate,
448      nodeIsMap = nodeUtil && nodeUtil.isMap,
449      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
450      nodeIsSet = nodeUtil && nodeUtil.isSet,
451      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
452
453  /*--------------------------------------------------------------------------*/
454
455  /**
456   * Adds the key-value `pair` to `map`.
457   *
458   * @private
459   * @param {Object} map The map to modify.
460   * @param {Array} pair The key-value pair to add.
461   * @returns {Object} Returns `map`.
462   */
463  function addMapEntry(map, pair) {
464    // Don't return `map.set` because it's not chainable in IE 11.
465    map.set(pair[0], pair[1]);
466    return map;
467  }
468
469  /**
470   * Adds `value` to `set`.
471   *
472   * @private
473   * @param {Object} set The set to modify.
474   * @param {*} value The value to add.
475   * @returns {Object} Returns `set`.
476   */
477  function addSetEntry(set, value) {
478    // Don't return `set.add` because it's not chainable in IE 11.
479    set.add(value);
480    return set;
481  }
vendor: 15,023 bytes, lines 481-984
481
482
483  /**
484   * A faster alternative to `Function#apply`, this function invokes `func`
485   * with the `this` binding of `thisArg` and the arguments of `args`.
486   *
487   * @private
488   * @param {Function} func The function to invoke.
489   * @param {*} thisArg The `this` binding of `func`.
490   * @param {Array} args The arguments to invoke `func` with.
491   * @returns {*} Returns the result of `func`.
492   */
493  function apply(func, thisArg, args) {
494    switch (args.length) {
495      case 0: return func.call(thisArg);
496      case 1: return func.call(thisArg, args[0]);
497      case 2: return func.call(thisArg, args[0], args[1]);
498      case 3: return func.call(thisArg, args[0], args[1], args[2]);
499    }
500    return func.apply(thisArg, args);
501  }
502
503  /**
504   * A specialized version of `baseAggregator` for arrays.
505   *
506   * @private
507   * @param {Array} [array] The array to iterate over.
508   * @param {Function} setter The function to set `accumulator` values.
509   * @param {Function} iteratee The iteratee to transform keys.
510   * @param {Object} accumulator The initial aggregated object.
511   * @returns {Function} Returns `accumulator`.
512   */
513  function arrayAggregator(array, setter, iteratee, accumulator) {
514    var index = -1,
515        length = array == null ? 0 : array.length;
516
517    while (++index < length) {
518      var value = array[index];
519      setter(accumulator, value, iteratee(value), array);
520    }
521    return accumulator;
522  }
523
524  /**
525   * A specialized version of `_.forEach` for arrays without support for
526   * iteratee shorthands.
527   *
528   * @private
529   * @param {Array} [array] The array to iterate over.
530   * @param {Function} iteratee The function invoked per iteration.
531   * @returns {Array} Returns `array`.
532   */
533  function arrayEach(array, iteratee) {
534    var index = -1,
535        length = array == null ? 0 : array.length;
536
537    while (++index < length) {
538      if (iteratee(array[index], index, array) === false) {
539        break;
540      }
541    }
542    return array;
543  }
544
545  /**
546   * A specialized version of `_.forEachRight` for arrays without support for
547   * iteratee shorthands.
548   *
549   * @private
550   * @param {Array} [array] The array to iterate over.
551   * @param {Function} iteratee The function invoked per iteration.
552   * @returns {Array} Returns `array`.
553   */
554  function arrayEachRight(array, iteratee) {
555    var length = array == null ? 0 : array.length;
556
557    while (length--) {
558      if (iteratee(array[length], length, array) === false) {
559        break;
560      }
561    }
562    return array;
563  }
564
565  /**
566   * A specialized version of `_.every` for arrays without support for
567   * iteratee shorthands.
568   *
569   * @private
570   * @param {Array} [array] The array to iterate over.
571   * @param {Function} predicate The function invoked per iteration.
572   * @returns {boolean} Returns `true` if all elements pass the predicate check,
573   *  else `false`.
574   */
575  function arrayEvery(array, predicate) {
576    var index = -1,
577        length = array == null ? 0 : array.length;
578
579    while (++index < length) {
580      if (!predicate(array[index], index, array)) {
581        return false;
582      }
583    }
584    return true;
585  }
586
587  /**
588   * A specialized version of `_.filter` for arrays without support for
589   * iteratee shorthands.
590   *
591   * @private
592   * @param {Array} [array] The array to iterate over.
593   * @param {Function} predicate The function invoked per iteration.
594   * @returns {Array} Returns the new filtered array.
595   */
596  function arrayFilter(array, predicate) {
597    var index = -1,
598        length = array == null ? 0 : array.length,
599        resIndex = 0,
600        result = [];
601
602    while (++index < length) {
603      var value = array[index];
604      if (predicate(value, index, array)) {
605        result[resIndex++] = value;
606      }
607    }
608    return result;
609  }
610
611  /**
612   * A specialized version of `_.includes` for arrays without support for
613   * specifying an index to search from.
614   *
615   * @private
616   * @param {Array} [array] The array to inspect.
617   * @param {*} target The value to search for.
618   * @returns {boolean} Returns `true` if `target` is found, else `false`.
619   */
620  function arrayIncludes(array, value) {
621    var length = array == null ? 0 : array.length;
622    return !!length && baseIndexOf(array, value, 0) > -1;
623  }
624
625  /**
626   * This function is like `arrayIncludes` except that it accepts a comparator.
627   *
628   * @private
629   * @param {Array} [array] The array to inspect.
630   * @param {*} target The value to search for.
631   * @param {Function} comparator The comparator invoked per element.
632   * @returns {boolean} Returns `true` if `target` is found, else `false`.
633   */
634  function arrayIncludesWith(array, value, comparator) {
635    var index = -1,
636        length = array == null ? 0 : array.length;
637
638    while (++index < length) {
639      if (comparator(value, array[index])) {
640        return true;
641      }
642    }
643    return false;
644  }
645
646  /**
647   * A specialized version of `_.map` for arrays without support for iteratee
648   * shorthands.
649   *
650   * @private
651   * @param {Array} [array] The array to iterate over.
652   * @param {Function} iteratee The function invoked per iteration.
653   * @returns {Array} Returns the new mapped array.
654   */
655  function arrayMap(array, iteratee) {
656    var index = -1,
657        length = array == null ? 0 : array.length,
658        result = Array(length);
659
660    while (++index < length) {
661      result[index] = iteratee(array[index], index, array);
662    }
663    return result;
664  }
665
666  /**
667   * Appends the elements of `values` to `array`.
668   *
669   * @private
670   * @param {Array} array The array to modify.
671   * @param {Array} values The values to append.
672   * @returns {Array} Returns `array`.
673   */
674  function arrayPush(array, values) {
675    var index = -1,
676        length = values.length,
677        offset = array.length;
678
679    while (++index < length) {
680      array[offset + index] = values[index];
681    }
682    return array;
683  }
684
685  /**
686   * A specialized version of `_.reduce` for arrays without support for
687   * iteratee shorthands.
688   *
689   * @private
690   * @param {Array} [array] The array to iterate over.
691   * @param {Function} iteratee The function invoked per iteration.
692   * @param {*} [accumulator] The initial value.
693   * @param {boolean} [initAccum] Specify using the first element of `array` as
694   *  the initial value.
695   * @returns {*} Returns the accumulated value.
696   */
697  function arrayReduce(array, iteratee, accumulator, initAccum) {
698    var index = -1,
699        length = array == null ? 0 : array.length;
700
701    if (initAccum && length) {
702      accumulator = array[++index];
703    }
704    while (++index < length) {
705      accumulator = iteratee(accumulator, array[index], index, array);
706    }
707    return accumulator;
708  }
709
710  /**
711   * A specialized version of `_.reduceRight` for arrays without support for
712   * iteratee shorthands.
713   *
714   * @private
715   * @param {Array} [array] The array to iterate over.
716   * @param {Function} iteratee The function invoked per iteration.
717   * @param {*} [accumulator] The initial value.
718   * @param {boolean} [initAccum] Specify using the last element of `array` as
719   *  the initial value.
720   * @returns {*} Returns the accumulated value.
721   */
722  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
723    var length = array == null ? 0 : array.length;
724    if (initAccum && length) {
725      accumulator = array[--length];
726    }
727    while (length--) {
728      accumulator = iteratee(accumulator, array[length], length, array);
729    }
730    return accumulator;
731  }
732
733  /**
734   * A specialized version of `_.some` for arrays without support for iteratee
735   * shorthands.
736   *
737   * @private
738   * @param {Array} [array] The array to iterate over.
739   * @param {Function} predicate The function invoked per iteration.
740   * @returns {boolean} Returns `true` if any element passes the predicate check,
741   *  else `false`.
742   */
743  function arraySome(array, predicate) {
744    var index = -1,
745        length = array == null ? 0 : array.length;
746
747    while (++index < length) {
748      if (predicate(array[index], index, array)) {
749        return true;
750      }
751    }
752    return false;
753  }
754
755  /**
756   * Gets the size of an ASCII `string`.
757   *
758   * @private
759   * @param {string} string The string inspect.
760   * @returns {number} Returns the string size.
761   */
762  var asciiSize = baseProperty('length');
763
764  /**
765   * Converts an ASCII `string` to an array.
766   *
767   * @private
768   * @param {string} string The string to convert.
769   * @returns {Array} Returns the converted array.
770   */
771  function asciiToArray(string) {
772    return string.split('');
773  }
774
775  /**
776   * Splits an ASCII `string` into an array of its words.
777   *
778   * @private
779   * @param {string} The string to inspect.
780   * @returns {Array} Returns the words of `string`.
781   */
782  function asciiWords(string) {
783    return string.match(reAsciiWord) || [];
784  }
785
786  /**
787   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
788   * without support for iteratee shorthands, which iterates over `collection`
789   * using `eachFunc`.
790   *
791   * @private
792   * @param {Array|Object} collection The collection to inspect.
793   * @param {Function} predicate The function invoked per iteration.
794   * @param {Function} eachFunc The function to iterate over `collection`.
795   * @returns {*} Returns the found element or its key, else `undefined`.
796   */
797  function baseFindKey(collection, predicate, eachFunc) {
798    var result;
799    eachFunc(collection, function(value, key, collection) {
800      if (predicate(value, key, collection)) {
801        result = key;
802        return false;
803      }
804    });
805    return result;
806  }
807
808  /**
809   * The base implementation of `_.findIndex` and `_.findLastIndex` without
810   * support for iteratee shorthands.
811   *
812   * @private
813   * @param {Array} array The array to inspect.
814   * @param {Function} predicate The function invoked per iteration.
815   * @param {number} fromIndex The index to search from.
816   * @param {boolean} [fromRight] Specify iterating from right to left.
817   * @returns {number} Returns the index of the matched value, else `-1`.
818   */
819  function baseFindIndex(array, predicate, fromIndex, fromRight) {
820    var length = array.length,
821        index = fromIndex + (fromRight ? 1 : -1);
822
823    while ((fromRight ? index-- : ++index < length)) {
824      if (predicate(array[index], index, array)) {
825        return index;
826      }
827    }
828    return -1;
829  }
830
831  /**
832   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
833   *
834   * @private
835   * @param {Array} array The array to inspect.
836   * @param {*} value The value to search for.
837   * @param {number} fromIndex The index to search from.
838   * @returns {number} Returns the index of the matched value, else `-1`.
839   */
840  function baseIndexOf(array, value, fromIndex) {
841    return value === value
842      ? strictIndexOf(array, value, fromIndex)
843      : baseFindIndex(array, baseIsNaN, fromIndex);
844  }
845
846  /**
847   * This function is like `baseIndexOf` except that it accepts a comparator.
848   *
849   * @private
850   * @param {Array} array The array to inspect.
851   * @param {*} value The value to search for.
852   * @param {number} fromIndex The index to search from.
853   * @param {Function} comparator The comparator invoked per element.
854   * @returns {number} Returns the index of the matched value, else `-1`.
855   */
856  function baseIndexOfWith(array, value, fromIndex, comparator) {
857    var index = fromIndex - 1,
858        length = array.length;
859
860    while (++index < length) {
861      if (comparator(array[index], value)) {
862        return index;
863      }
864    }
865    return -1;
866  }
867
868  /**
869   * The base implementation of `_.isNaN` without support for number objects.
870   *
871   * @private
872   * @param {*} value The value to check.
873   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
874   */
875  function baseIsNaN(value) {
876    return value !== value;
877  }
878
879  /**
880   * The base implementation of `_.mean` and `_.meanBy` without support for
881   * iteratee shorthands.
882   *
883   * @private
884   * @param {Array} array The array to iterate over.
885   * @param {Function} iteratee The function invoked per iteration.
886   * @returns {number} Returns the mean.
887   */
888  function baseMean(array, iteratee) {
889    var length = array == null ? 0 : array.length;
890    return length ? (baseSum(array, iteratee) / length) : NAN;
891  }
892
893  /**
894   * The base implementation of `_.property` without support for deep paths.
895   *
896   * @private
897   * @param {string} key The key of the property to get.
898   * @returns {Function} Returns the new accessor function.
899   */
900  function baseProperty(key) {
901    return function(object) {
902      return object == null ? undefined : object[key];
903    };
904  }
905
906  /**
907   * The base implementation of `_.propertyOf` without support for deep paths.
908   *
909   * @private
910   * @param {Object} object The object to query.
911   * @returns {Function} Returns the new accessor function.
912   */
913  function basePropertyOf(object) {
914    return function(key) {
915      return object == null ? undefined : object[key];
916    };
917  }
918
919  /**
920   * The base implementation of `_.reduce` and `_.reduceRight`, without support
921   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
922   *
923   * @private
924   * @param {Array|Object} collection The collection to iterate over.
925   * @param {Function} iteratee The function invoked per iteration.
926   * @param {*} accumulator The initial value.
927   * @param {boolean} initAccum Specify using the first or last element of
928   *  `collection` as the initial value.
929   * @param {Function} eachFunc The function to iterate over `collection`.
930   * @returns {*} Returns the accumulated value.
931   */
932  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
933    eachFunc(collection, function(value, index, collection) {
934      accumulator = initAccum
935        ? (initAccum = false, value)
936        : iteratee(accumulator, value, index, collection);
937    });
938    return accumulator;
939  }
940
941  /**
942   * The base implementation of `_.sortBy` which uses `comparer` to define the
943   * sort order of `array` and replaces criteria objects with their corresponding
944   * values.
945   *
946   * @private
947   * @param {Array} array The array to sort.
948   * @param {Function} comparer The function to define sort order.
949   * @returns {Array} Returns `array`.
950   */
951  function baseSortBy(array, comparer) {
952    var length = array.length;
953
954    array.sort(comparer);
955    while (length--) {
956      array[length] = array[length].value;
957    }
958    return array;
959  }
960
961  /**
962   * The base implementation of `_.sum` and `_.sumBy` without support for
963   * iteratee shorthands.
964   *
965   * @private
966   * @param {Array} array The array to iterate over.
967   * @param {Function} iteratee The function invoked per iteration.
968   * @returns {number} Returns the sum.
969   */
970  function baseSum(array, iteratee) {
971    var result,
972        index = -1,
973        length = array.length;
974
975    while (++index < length) {
976      var current = iteratee(array[index]);
977      if (current !== undefined) {
978        result = result === undefined ? current : (result + current);
979      }
980    }
981    return result;
982  }
983
984  /**
vendor: 5,596 bytes, lines 985-1177
985   * The base implementation of `_.times` without support for iteratee shorthands
986   * or max array length checks.
987   *
988   * @private
989   * @param {number} n The number of times to invoke `iteratee`.
990   * @param {Function} iteratee The function invoked per iteration.
991   * @returns {Array} Returns the array of results.
992   */
993  function baseTimes(n, iteratee) {
994    var index = -1,
995        result = Array(n);
996
997    while (++index < n) {
998      result[index] = iteratee(index);
999    }
1000    return result;
1001  }
1002
1003  /**
1004   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
1005   * of key-value pairs for `object` corresponding to the property names of `props`.
1006   *
1007   * @private
1008   * @param {Object} object The object to query.
1009   * @param {Array} props The property names to get values for.
1010   * @returns {Object} Returns the key-value pairs.
1011   */
1012  function baseToPairs(object, props) {
1013    return arrayMap(props, function(key) {
1014      return [key, object[key]];
1015    });
1016  }
1017
1018  /**
1019   * The base implementation of `_.unary` without support for storing metadata.
1020   *
1021   * @private
1022   * @param {Function} func The function to cap arguments for.
1023   * @returns {Function} Returns the new capped function.
1024   */
1025  function baseUnary(func) {
1026    return function(value) {
1027      return func(value);
1028    };
1029  }
1030
1031  /**
1032   * The base implementation of `_.values` and `_.valuesIn` which creates an
1033   * array of `object` property values corresponding to the property names
1034   * of `props`.
1035   *
1036   * @private
1037   * @param {Object} object The object to query.
1038   * @param {Array} props The property names to get values for.
1039   * @returns {Object} Returns the array of property values.
1040   */
1041  function baseValues(object, props) {
1042    return arrayMap(props, function(key) {
1043      return object[key];
1044    });
1045  }
1046
1047  /**
1048   * Checks if a `cache` value for `key` exists.
1049   *
1050   * @private
1051   * @param {Object} cache The cache to query.
1052   * @param {string} key The key of the entry to check.
1053   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1054   */
1055  function cacheHas(cache, key) {
1056    return cache.has(key);
1057  }
1058
1059  /**
1060   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
1061   * that is not found in the character symbols.
1062   *
1063   * @private
1064   * @param {Array} strSymbols The string symbols to inspect.
1065   * @param {Array} chrSymbols The character symbols to find.
1066   * @returns {number} Returns the index of the first unmatched string symbol.
1067   */
1068  function charsStartIndex(strSymbols, chrSymbols) {
1069    var index = -1,
1070        length = strSymbols.length;
1071
1072    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1073    return index;
1074  }
1075
1076  /**
1077   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
1078   * that is not found in the character symbols.
1079   *
1080   * @private
1081   * @param {Array} strSymbols The string symbols to inspect.
1082   * @param {Array} chrSymbols The character symbols to find.
1083   * @returns {number} Returns the index of the last unmatched string symbol.
1084   */
1085  function charsEndIndex(strSymbols, chrSymbols) {
1086    var index = strSymbols.length;
1087
1088    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
1089    return index;
1090  }
1091
1092  /**
1093   * Gets the number of `placeholder` occurrences in `array`.
1094   *
1095   * @private
1096   * @param {Array} array The array to inspect.
1097   * @param {*} placeholder The placeholder to search for.
1098   * @returns {number} Returns the placeholder count.
1099   */
1100  function countHolders(array, placeholder) {
1101    var length = array.length,
1102        result = 0;
1103
1104    while (length--) {
1105      if (array[length] === placeholder) {
1106        ++result;
1107      }
1108    }
1109    return result;
1110  }
1111
1112  /**
1113   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
1114   * letters to basic Latin letters.
1115   *
1116   * @private
1117   * @param {string} letter The matched letter to deburr.
1118   * @returns {string} Returns the deburred letter.
1119   */
1120  var deburrLetter = basePropertyOf(deburredLetters);
1121
1122  /**
1123   * Used by `_.escape` to convert characters to HTML entities.
1124   *
1125   * @private
1126   * @param {string} chr The matched character to escape.
1127   * @returns {string} Returns the escaped character.
1128   */
1129  var escapeHtmlChar = basePropertyOf(htmlEscapes);
1130
1131  /**
1132   * Used by `_.template` to escape characters for inclusion in compiled string literals.
1133   *
1134   * @private
1135   * @param {string} chr The matched character to escape.
1136   * @returns {string} Returns the escaped character.
1137   */
1138  function escapeStringChar(chr) {
1139    return '\\' + stringEscapes[chr];
1140  }
1141
1142  /**
1143   * Gets the value at `key` of `object`.
1144   *
1145   * @private
1146   * @param {Object} [object] The object to query.
1147   * @param {string} key The key of the property to get.
1148   * @returns {*} Returns the property value.
1149   */
1150  function getValue(object, key) {
1151    return object == null ? undefined : object[key];
1152  }
1153
1154  /**
1155   * Checks if `string` contains Unicode symbols.
1156   *
1157   * @private
1158   * @param {string} string The string to inspect.
1159   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
1160   */
1161  function hasUnicode(string) {
1162    return reHasUnicode.test(string);
1163  }
1164
1165  /**
1166   * Checks if `string` contains a word composed of Unicode symbols.
1167   *
1168   * @private
1169   * @param {string} string The string to inspect.
1170   * @returns {boolean} Returns `true` if a word is found, else `false`.
1171   */
1172  function hasUnicodeWord(string) {
1173    return reHasUnicodeWord.test(string);
1174  }
1175
1176  /**
1177   * Converts `iterator` to an array.
vendor: 4,118 bytes, lines 1178-1343
1178   *
1179   * @private
1180   * @param {Object} iterator The iterator to convert.
1181   * @returns {Array} Returns the converted array.
1182   */
1183  function iteratorToArray(iterator) {
1184    var data,
1185        result = [];
1186
1187    while (!(data = iterator.next()).done) {
1188      result.push(data.value);
1189    }
1190    return result;
1191  }
1192
1193  /**
1194   * Converts `map` to its key-value pairs.
1195   *
1196   * @private
1197   * @param {Object} map The map to convert.
1198   * @returns {Array} Returns the key-value pairs.
1199   */
1200  function mapToArray(map) {
1201    var index = -1,
1202        result = Array(map.size);
1203
1204    map.forEach(function(value, key) {
1205      result[++index] = [key, value];
1206    });
1207    return result;
1208  }
1209
1210  /**
1211   * Creates a unary function that invokes `func` with its argument transformed.
1212   *
1213   * @private
1214   * @param {Function} func The function to wrap.
1215   * @param {Function} transform The argument transform.
1216   * @returns {Function} Returns the new function.
1217   */
1218  function overArg(func, transform) {
1219    return function(arg) {
1220      return func(transform(arg));
1221    };
1222  }
1223
1224  /**
1225   * Replaces all `placeholder` elements in `array` with an internal placeholder
1226   * and returns an array of their indexes.
1227   *
1228   * @private
1229   * @param {Array} array The array to modify.
1230   * @param {*} placeholder The placeholder to replace.
1231   * @returns {Array} Returns the new array of placeholder indexes.
1232   */
1233  function replaceHolders(array, placeholder) {
1234    var index = -1,
1235        length = array.length,
1236        resIndex = 0,
1237        result = [];
1238
1239    while (++index < length) {
1240      var value = array[index];
1241      if (value === placeholder || value === PLACEHOLDER) {
1242        array[index] = PLACEHOLDER;
1243        result[resIndex++] = index;
1244      }
1245    }
1246    return result;
1247  }
1248
1249  /**
1250   * Converts `set` to an array of its values.
1251   *
1252   * @private
1253   * @param {Object} set The set to convert.
1254   * @returns {Array} Returns the values.
1255   */
1256  function setToArray(set) {
1257    var index = -1,
1258        result = Array(set.size);
1259
1260    set.forEach(function(value) {
1261      result[++index] = value;
1262    });
1263    return result;
1264  }
1265
1266  /**
1267   * Converts `set` to its value-value pairs.
1268   *
1269   * @private
1270   * @param {Object} set The set to convert.
1271   * @returns {Array} Returns the value-value pairs.
1272   */
1273  function setToPairs(set) {
1274    var index = -1,
1275        result = Array(set.size);
1276
1277    set.forEach(function(value) {
1278      result[++index] = [value, value];
1279    });
1280    return result;
1281  }
1282
1283  /**
1284   * A specialized version of `_.indexOf` which performs strict equality
1285   * comparisons of values, i.e. `===`.
1286   *
1287   * @private
1288   * @param {Array} array The array to inspect.
1289   * @param {*} value The value to search for.
1290   * @param {number} fromIndex The index to search from.
1291   * @returns {number} Returns the index of the matched value, else `-1`.
1292   */
1293  function strictIndexOf(array, value, fromIndex) {
1294    var index = fromIndex - 1,
1295        length = array.length;
1296
1297    while (++index < length) {
1298      if (array[index] === value) {
1299        return index;
1300      }
1301    }
1302    return -1;
1303  }
1304
1305  /**
1306   * A specialized version of `_.lastIndexOf` which performs strict equality
1307   * comparisons of values, i.e. `===`.
1308   *
1309   * @private
1310   * @param {Array} array The array to inspect.
1311   * @param {*} value The value to search for.
1312   * @param {number} fromIndex The index to search from.
1313   * @returns {number} Returns the index of the matched value, else `-1`.
1314   */
1315  function strictLastIndexOf(array, value, fromIndex) {
1316    var index = fromIndex + 1;
1317    while (index--) {
1318      if (array[index] === value) {
1319        return index;
1320      }
1321    }
1322    return index;
1323  }
1324
1325  /**
1326   * Gets the number of symbols in `string`.
1327   *
1328   * @private
1329   * @param {string} string The string to inspect.
1330   * @returns {number} Returns the string size.
1331   */
1332  function stringSize(string) {
1333    return hasUnicode(string)
1334      ? unicodeSize(string)
1335      : asciiSize(string);
1336  }
1337
1338  /**
1339   * Converts `string` to an array.
1340   *
1341   * @private
1342   * @param {string} string The string to convert.
1343   * @returns {Array} Returns the converted array.
vendor: 10,876 bytes, lines 1344-1617
1344   */
1345  function stringToArray(string) {
1346    return hasUnicode(string)
1347      ? unicodeToArray(string)
1348      : asciiToArray(string);
1349  }
1350
1351  /**
1352   * Used by `_.unescape` to convert HTML entities to characters.
1353   *
1354   * @private
1355   * @param {string} chr The matched character to unescape.
1356   * @returns {string} Returns the unescaped character.
1357   */
1358  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
1359
1360  /**
1361   * Gets the size of a Unicode `string`.
1362   *
1363   * @private
1364   * @param {string} string The string inspect.
1365   * @returns {number} Returns the string size.
1366   */
1367  function unicodeSize(string) {
1368    var result = reUnicode.lastIndex = 0;
1369    while (reUnicode.test(string)) {
1370      ++result;
1371    }
1372    return result;
1373  }
1374
1375  /**
1376   * Converts a Unicode `string` to an array.
1377   *
1378   * @private
1379   * @param {string} string The string to convert.
1380   * @returns {Array} Returns the converted array.
1381   */
1382  function unicodeToArray(string) {
1383    return string.match(reUnicode) || [];
1384  }
1385
1386  /**
1387   * Splits a Unicode `string` into an array of its words.
1388   *
1389   * @private
1390   * @param {string} The string to inspect.
1391   * @returns {Array} Returns the words of `string`.
1392   */
1393  function unicodeWords(string) {
1394    return string.match(reUnicodeWord) || [];
1395  }
1396
1397  /*--------------------------------------------------------------------------*/
1398
1399  /**
1400   * Create a new pristine `lodash` function using the `context` object.
1401   *
1402   * @static
1403   * @memberOf _
1404   * @since 1.1.0
1405   * @category Util
1406   * @param {Object} [context=root] The context object.
1407   * @returns {Function} Returns a new `lodash` function.
1408   * @example
1409   *
1410   * _.mixin({ 'foo': _.constant('foo') });
1411   *
1412   * var lodash = _.runInContext();
1413   * lodash.mixin({ 'bar': lodash.constant('bar') });
1414   *
1415   * _.isFunction(_.foo);
1416   * // => true
1417   * _.isFunction(_.bar);
1418   * // => false
1419   *
1420   * lodash.isFunction(lodash.foo);
1421   * // => false
1422   * lodash.isFunction(lodash.bar);
1423   * // => true
1424   *
1425   * // Create a suped-up `defer` in Node.js.
1426   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1427   */
1428  var runInContext = (function runInContext(context) {
1429    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
1430
1431    /** Built-in constructor references. */
1432    var Array = context.Array,
1433        Date = context.Date,
1434        Error = context.Error,
1435        Function = context.Function,
1436        Math = context.Math,
1437        Object = context.Object,
1438        RegExp = context.RegExp,
1439        String = context.String,
1440        TypeError = context.TypeError;
1441
1442    /** Used for built-in method references. */
1443    var arrayProto = Array.prototype,
1444        funcProto = Function.prototype,
1445        objectProto = Object.prototype;
1446
1447    /** Used to detect overreaching core-js shims. */
1448    var coreJsData = context['__core-js_shared__'];
1449
1450    /** Used to resolve the decompiled source of functions. */
1451    var funcToString = funcProto.toString;
1452
1453    /** Used to check objects for own properties. */
1454    var hasOwnProperty = objectProto.hasOwnProperty;
1455
1456    /** Used to generate unique IDs. */
1457    var idCounter = 0;
1458
1459    /** Used to detect methods masquerading as native. */
1460    var maskSrcKey = (function() {
1461      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1462      return uid ? ('Symbol(src)_1.' + uid) : '';
1463    }());
1464
1465    /**
1466     * Used to resolve the
1467     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1468     * of values.
1469     */
1470    var nativeObjectToString = objectProto.toString;
1471
1472    /** Used to infer the `Object` constructor. */
1473    var objectCtorString = funcToString.call(Object);
1474
1475    /** Used to restore the original `_` reference in `_.noConflict`. */
1476    var oldDash = root._;
1477
1478    /** Used to detect if a method is native. */
1479    var reIsNative = RegExp('^' +
1480      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1481      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1482    );
1483
1484    /** Built-in value references. */
1485    var Buffer = moduleExports ? context.Buffer : undefined,
1486        Symbol = context.Symbol,
1487        Uint8Array = context.Uint8Array,
1488        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
1489        getPrototype = overArg(Object.getPrototypeOf, Object),
1490        objectCreate = Object.create,
1491        propertyIsEnumerable = objectProto.propertyIsEnumerable,
1492        splice = arrayProto.splice,
1493        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
1494        symIterator = Symbol ? Symbol.iterator : undefined,
1495        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1496
1497    var defineProperty = (function() {
1498      try {
1499        var func = getNative(Object, 'defineProperty');
1500        func({}, '', {});
1501        return func;
1502      } catch (e) {}
1503    }());
1504
1505    /** Mocked built-ins. */
1506    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
1507        ctxNow = Date && Date.now !== root.Date.now && Date.now,
1508        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1509
1510    /* Built-in method references for those with the same name as other `lodash` methods. */
1511    var nativeCeil = Math.ceil,
1512        nativeFloor = Math.floor,
1513        nativeGetSymbols = Object.getOwnPropertySymbols,
1514        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1515        nativeIsFinite = context.isFinite,
1516        nativeJoin = arrayProto.join,
1517        nativeKeys = overArg(Object.keys, Object),
1518        nativeMax = Math.max,
1519        nativeMin = Math.min,
1520        nativeNow = Date.now,
1521        nativeParseInt = context.parseInt,
1522        nativeRandom = Math.random,
1523        nativeReverse = arrayProto.reverse;
1524
1525    /* Built-in method references that are verified to be native. */
1526    var DataView = getNative(context, 'DataView'),
1527        Map = getNative(context, 'Map'),
1528        Promise = getNative(context, 'Promise'),
1529        Set = getNative(context, 'Set'),
1530        WeakMap = getNative(context, 'WeakMap'),
1531        nativeCreate = getNative(Object, 'create');
1532
1533    /** Used to store function metadata. */
1534    var metaMap = WeakMap && new WeakMap;
1535
1536    /** Used to lookup unminified function names. */
1537    var realNames = {};
1538
1539    /** Used to detect maps, sets, and weakmaps. */
1540    var dataViewCtorString = toSource(DataView),
1541        mapCtorString = toSource(Map),
1542        promiseCtorString = toSource(Promise),
1543        setCtorString = toSource(Set),
1544        weakMapCtorString = toSource(WeakMap);
1545
1546    /** Used to convert symbols to primitives and strings. */
1547    var symbolProto = Symbol ? Symbol.prototype : undefined,
1548        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1549        symbolToString = symbolProto ? symbolProto.toString : undefined;
1550
1551    /*------------------------------------------------------------------------*/
1552
1553    /**
1554     * Creates a `lodash` object which wraps `value` to enable implicit method
1555     * chain sequences. Methods that operate on and return arrays, collections,
1556     * and functions can be chained together. Methods that retrieve a single value
1557     * or may return a primitive value will automatically end the chain sequence
1558     * and return the unwrapped value. Otherwise, the value must be unwrapped
1559     * with `_#value`.
1560     *
1561     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1562     * enabled using `_.chain`.
1563     *
1564     * The execution of chained methods is lazy, that is, it's deferred until
1565     * `_#value` is implicitly or explicitly called.
1566     *
1567     * Lazy evaluation allows several methods to support shortcut fusion.
1568     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1569     * the creation of intermediate arrays and can greatly reduce the number of
1570     * iteratee executions. Sections of a chain sequence qualify for shortcut
1571     * fusion if the section is applied to an array and iteratees accept only
1572     * one argument. The heuristic for whether a section qualifies for shortcut
1573     * fusion is subject to change.
1574     *
1575     * Chaining is supported in custom builds as long as the `_#value` method is
1576     * directly or indirectly included in the build.
1577     *
1578     * In addition to lodash methods, wrappers have `Array` and `String` methods.
1579     *
1580     * The wrapper `Array` methods are:
1581     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1582     *
1583     * The wrapper `String` methods are:
1584     * `replace` and `split`
1585     *
1586     * The wrapper methods that support shortcut fusion are:
1587     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1588     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1589     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1590     *
1591     * The chainable wrapper methods are:
1592     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1593     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1594     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1595     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1596     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1597     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1598     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1599     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1600     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1601     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1602     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1603     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1604     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1605     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1606     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1607     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1608     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1609     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1610     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1611     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1612     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1613     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1614     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1615     * `zipObject`, `zipObjectDeep`, and `zipWith`
1616     *
1617     * The wrapper methods that are **not** chainable by default are:
vendor: 18,450 bytes, lines 1618-2270
1618     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1619     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
1620     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
1621     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
1622     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
1623     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
1624     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
1625     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
1626     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
1627     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
1628     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1629     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1630     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1631     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1632     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1633     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1634     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1635     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1636     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1637     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1638     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1639     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1640     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1641     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1642     * `upperFirst`, `value`, and `words`
1643     *
1644     * @name _
1645     * @constructor
1646     * @category Seq
1647     * @param {*} value The value to wrap in a `lodash` instance.
1648     * @returns {Object} Returns the new `lodash` wrapper instance.
1649     * @example
1650     *
1651     * function square(n) {
1652     *   return n * n;
1653     * }
1654     *
1655     * var wrapped = _([1, 2, 3]);
1656     *
1657     * // Returns an unwrapped value.
1658     * wrapped.reduce(_.add);
1659     * // => 6
1660     *
1661     * // Returns a wrapped value.
1662     * var squares = wrapped.map(square);
1663     *
1664     * _.isArray(squares);
1665     * // => false
1666     *
1667     * _.isArray(squares.value());
1668     * // => true
1669     */
1670    function lodash(value) {
1671      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1672        if (value instanceof LodashWrapper) {
1673          return value;
1674        }
1675        if (hasOwnProperty.call(value, '__wrapped__')) {
1676          return wrapperClone(value);
1677        }
1678      }
1679      return new LodashWrapper(value);
1680    }
1681
1682    /**
1683     * The base implementation of `_.create` without support for assigning
1684     * properties to the created object.
1685     *
1686     * @private
1687     * @param {Object} proto The object to inherit from.
1688     * @returns {Object} Returns the new object.
1689     */
1690    var baseCreate = (function() {
1691      function object() {}
1692      return function(proto) {
1693        if (!isObject(proto)) {
1694          return {};
1695        }
1696        if (objectCreate) {
1697          return objectCreate(proto);
1698        }
1699        object.prototype = proto;
1700        var result = new object;
1701        object.prototype = undefined;
1702        return result;
1703      };
1704    }());
1705
1706    /**
1707     * The function whose prototype chain sequence wrappers inherit from.
1708     *
1709     * @private
1710     */
1711    function baseLodash() {
1712      // No operation performed.
1713    }
1714
1715    /**
1716     * The base constructor for creating `lodash` wrapper objects.
1717     *
1718     * @private
1719     * @param {*} value The value to wrap.
1720     * @param {boolean} [chainAll] Enable explicit method chain sequences.
1721     */
1722    function LodashWrapper(value, chainAll) {
1723      this.__wrapped__ = value;
1724      this.__actions__ = [];
1725      this.__chain__ = !!chainAll;
1726      this.__index__ = 0;
1727      this.__values__ = undefined;
1728    }
1729
1730    /**
1731     * By default, the template delimiters used by lodash are like those in
1732     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
1733     * following template settings to use alternative delimiters.
1734     *
1735     * @static
1736     * @memberOf _
1737     * @type {Object}
1738     */
1739    lodash.templateSettings = {
1740
1741      /**
1742       * Used to detect `data` property values to be HTML-escaped.
1743       *
1744       * @memberOf _.templateSettings
1745       * @type {RegExp}
1746       */
1747      'escape': reEscape,
1748
1749      /**
1750       * Used to detect code to be evaluated.
1751       *
1752       * @memberOf _.templateSettings
1753       * @type {RegExp}
1754       */
1755      'evaluate': reEvaluate,
1756
1757      /**
1758       * Used to detect `data` property values to inject.
1759       *
1760       * @memberOf _.templateSettings
1761       * @type {RegExp}
1762       */
1763      'interpolate': reInterpolate,
1764
1765      /**
1766       * Used to reference the data object in the template text.
1767       *
1768       * @memberOf _.templateSettings
1769       * @type {string}
1770       */
1771      'variable': '',
1772
1773      /**
1774       * Used to import variables into the compiled template.
1775       *
1776       * @memberOf _.templateSettings
1777       * @type {Object}
1778       */
1779      'imports': {
1780
1781        /**
1782         * A reference to the `lodash` function.
1783         *
1784         * @memberOf _.templateSettings.imports
1785         * @type {Function}
1786         */
1787        '_': lodash
1788      }
1789    };
1790
1791    // Ensure wrappers are instances of `baseLodash`.
1792    lodash.prototype = baseLodash.prototype;
1793    lodash.prototype.constructor = lodash;
1794
1795    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1796    LodashWrapper.prototype.constructor = LodashWrapper;
1797
1798    /*------------------------------------------------------------------------*/
1799
1800    /**
1801     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1802     *
1803     * @private
1804     * @constructor
1805     * @param {*} value The value to wrap.
1806     */
1807    function LazyWrapper(value) {
1808      this.__wrapped__ = value;
1809      this.__actions__ = [];
1810      this.__dir__ = 1;
1811      this.__filtered__ = false;
1812      this.__iteratees__ = [];
1813      this.__takeCount__ = MAX_ARRAY_LENGTH;
1814      this.__views__ = [];
1815    }
1816
1817    /**
1818     * Creates a clone of the lazy wrapper object.
1819     *
1820     * @private
1821     * @name clone
1822     * @memberOf LazyWrapper
1823     * @returns {Object} Returns the cloned `LazyWrapper` object.
1824     */
1825    function lazyClone() {
1826      var result = new LazyWrapper(this.__wrapped__);
1827      result.__actions__ = copyArray(this.__actions__);
1828      result.__dir__ = this.__dir__;
1829      result.__filtered__ = this.__filtered__;
1830      result.__iteratees__ = copyArray(this.__iteratees__);
1831      result.__takeCount__ = this.__takeCount__;
1832      result.__views__ = copyArray(this.__views__);
1833      return result;
1834    }
1835
1836    /**
1837     * Reverses the direction of lazy iteration.
1838     *
1839     * @private
1840     * @name reverse
1841     * @memberOf LazyWrapper
1842     * @returns {Object} Returns the new reversed `LazyWrapper` object.
1843     */
1844    function lazyReverse() {
1845      if (this.__filtered__) {
1846        var result = new LazyWrapper(this);
1847        result.__dir__ = -1;
1848        result.__filtered__ = true;
1849      } else {
1850        result = this.clone();
1851        result.__dir__ *= -1;
1852      }
1853      return result;
1854    }
1855
1856    /**
1857     * Extracts the unwrapped value from its lazy wrapper.
1858     *
1859     * @private
1860     * @name value
1861     * @memberOf LazyWrapper
1862     * @returns {*} Returns the unwrapped value.
1863     */
1864    function lazyValue() {
1865      var array = this.__wrapped__.value(),
1866          dir = this.__dir__,
1867          isArr = isArray(array),
1868          isRight = dir < 0,
1869          arrLength = isArr ? array.length : 0,
1870          view = getView(0, arrLength, this.__views__),
1871          start = view.start,
1872          end = view.end,
1873          length = end - start,
1874          index = isRight ? end : (start - 1),
1875          iteratees = this.__iteratees__,
1876          iterLength = iteratees.length,
1877          resIndex = 0,
1878          takeCount = nativeMin(length, this.__takeCount__);
1879
1880      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
1881        return baseWrapperValue(array, this.__actions__);
1882      }
1883      var result = [];
1884
1885      outer:
1886      while (length-- && resIndex < takeCount) {
1887        index += dir;
1888
1889        var iterIndex = -1,
1890            value = array[index];
1891
1892        while (++iterIndex < iterLength) {
1893          var data = iteratees[iterIndex],
1894              iteratee = data.iteratee,
1895              type = data.type,
1896              computed = iteratee(value);
1897
1898          if (type == LAZY_MAP_FLAG) {
1899            value = computed;
1900          } else if (!computed) {
1901            if (type == LAZY_FILTER_FLAG) {
1902              continue outer;
1903            } else {
1904              break outer;
1905            }
1906          }
1907        }
1908        result[resIndex++] = value;
1909      }
1910      return result;
1911    }
1912
1913    // Ensure `LazyWrapper` is an instance of `baseLodash`.
1914    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1915    LazyWrapper.prototype.constructor = LazyWrapper;
1916
1917    /*------------------------------------------------------------------------*/
1918
1919    /**
1920     * Creates a hash object.
1921     *
1922     * @private
1923     * @constructor
1924     * @param {Array} [entries] The key-value pairs to cache.
1925     */
1926    function Hash(entries) {
1927      var index = -1,
1928          length = entries == null ? 0 : entries.length;
1929
1930      this.clear();
1931      while (++index < length) {
1932        var entry = entries[index];
1933        this.set(entry[0], entry[1]);
1934      }
1935    }
1936
1937    /**
1938     * Removes all key-value entries from the hash.
1939     *
1940     * @private
1941     * @name clear
1942     * @memberOf Hash
1943     */
1944    function hashClear() {
1945      this.__data__ = nativeCreate ? nativeCreate(null) : {};
1946      this.size = 0;
1947    }
1948
1949    /**
1950     * Removes `key` and its value from the hash.
1951     *
1952     * @private
1953     * @name delete
1954     * @memberOf Hash
1955     * @param {Object} hash The hash to modify.
1956     * @param {string} key The key of the value to remove.
1957     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1958     */
1959    function hashDelete(key) {
1960      var result = this.has(key) && delete this.__data__[key];
1961      this.size -= result ? 1 : 0;
1962      return result;
1963    }
1964
1965    /**
1966     * Gets the hash value for `key`.
1967     *
1968     * @private
1969     * @name get
1970     * @memberOf Hash
1971     * @param {string} key The key of the value to get.
1972     * @returns {*} Returns the entry value.
1973     */
1974    function hashGet(key) {
1975      var data = this.__data__;
1976      if (nativeCreate) {
1977        var result = data[key];
1978        return result === HASH_UNDEFINED ? undefined : result;
1979      }
1980      return hasOwnProperty.call(data, key) ? data[key] : undefined;
1981    }
1982
1983    /**
1984     * Checks if a hash value for `key` exists.
1985     *
1986     * @private
1987     * @name has
1988     * @memberOf Hash
1989     * @param {string} key The key of the entry to check.
1990     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1991     */
1992    function hashHas(key) {
1993      var data = this.__data__;
1994      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
1995    }
1996
1997    /**
1998     * Sets the hash `key` to `value`.
1999     *
2000     * @private
2001     * @name set
2002     * @memberOf Hash
2003     * @param {string} key The key of the value to set.
2004     * @param {*} value The value to set.
2005     * @returns {Object} Returns the hash instance.
2006     */
2007    function hashSet(key, value) {
2008      var data = this.__data__;
2009      this.size += this.has(key) ? 0 : 1;
2010      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
2011      return this;
2012    }
2013
2014    // Add methods to `Hash`.
2015    Hash.prototype.clear = hashClear;
2016    Hash.prototype['delete'] = hashDelete;
2017    Hash.prototype.get = hashGet;
2018    Hash.prototype.has = hashHas;
2019    Hash.prototype.set = hashSet;
2020
2021    /*------------------------------------------------------------------------*/
2022
2023    /**
2024     * Creates an list cache object.
2025     *
2026     * @private
2027     * @constructor
2028     * @param {Array} [entries] The key-value pairs to cache.
2029     */
2030    function ListCache(entries) {
2031      var index = -1,
2032          length = entries == null ? 0 : entries.length;
2033
2034      this.clear();
2035      while (++index < length) {
2036        var entry = entries[index];
2037        this.set(entry[0], entry[1]);
2038      }
2039    }
2040
2041    /**
2042     * Removes all key-value entries from the list cache.
2043     *
2044     * @private
2045     * @name clear
2046     * @memberOf ListCache
2047     */
2048    function listCacheClear() {
2049      this.__data__ = [];
2050      this.size = 0;
2051    }
2052
2053    /**
2054     * Removes `key` and its value from the list cache.
2055     *
2056     * @private
2057     * @name delete
2058     * @memberOf ListCache
2059     * @param {string} key The key of the value to remove.
2060     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2061     */
2062    function listCacheDelete(key) {
2063      var data = this.__data__,
2064          index = assocIndexOf(data, key);
2065
2066      if (index < 0) {
2067        return false;
2068      }
2069      var lastIndex = data.length - 1;
2070      if (index == lastIndex) {
2071        data.pop();
2072      } else {
2073        splice.call(data, index, 1);
2074      }
2075      --this.size;
2076      return true;
2077    }
2078
2079    /**
2080     * Gets the list cache value for `key`.
2081     *
2082     * @private
2083     * @name get
2084     * @memberOf ListCache
2085     * @param {string} key The key of the value to get.
2086     * @returns {*} Returns the entry value.
2087     */
2088    function listCacheGet(key) {
2089      var data = this.__data__,
2090          index = assocIndexOf(data, key);
2091
2092      return index < 0 ? undefined : data[index][1];
2093    }
2094
2095    /**
2096     * Checks if a list cache value for `key` exists.
2097     *
2098     * @private
2099     * @name has
2100     * @memberOf ListCache
2101     * @param {string} key The key of the entry to check.
2102     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2103     */
2104    function listCacheHas(key) {
2105      return assocIndexOf(this.__data__, key) > -1;
2106    }
2107
2108    /**
2109     * Sets the list cache `key` to `value`.
2110     *
2111     * @private
2112     * @name set
2113     * @memberOf ListCache
2114     * @param {string} key The key of the value to set.
2115     * @param {*} value The value to set.
2116     * @returns {Object} Returns the list cache instance.
2117     */
2118    function listCacheSet(key, value) {
2119      var data = this.__data__,
2120          index = assocIndexOf(data, key);
2121
2122      if (index < 0) {
2123        ++this.size;
2124        data.push([key, value]);
2125      } else {
2126        data[index][1] = value;
2127      }
2128      return this;
2129    }
2130
2131    // Add methods to `ListCache`.
2132    ListCache.prototype.clear = listCacheClear;
2133    ListCache.prototype['delete'] = listCacheDelete;
2134    ListCache.prototype.get = listCacheGet;
2135    ListCache.prototype.has = listCacheHas;
2136    ListCache.prototype.set = listCacheSet;
2137
2138    /*------------------------------------------------------------------------*/
2139
2140    /**
2141     * Creates a map cache object to store key-value pairs.
2142     *
2143     * @private
2144     * @constructor
2145     * @param {Array} [entries] The key-value pairs to cache.
2146     */
2147    function MapCache(entries) {
2148      var index = -1,
2149          length = entries == null ? 0 : entries.length;
2150
2151      this.clear();
2152      while (++index < length) {
2153        var entry = entries[index];
2154        this.set(entry[0], entry[1]);
2155      }
2156    }
2157
2158    /**
2159     * Removes all key-value entries from the map.
2160     *
2161     * @private
2162     * @name clear
2163     * @memberOf MapCache
2164     */
2165    function mapCacheClear() {
2166      this.size = 0;
2167      this.__data__ = {
2168        'hash': new Hash,
2169        'map': new (Map || ListCache),
2170        'string': new Hash
2171      };
2172    }
2173
2174    /**
2175     * Removes `key` and its value from the map.
2176     *
2177     * @private
2178     * @name delete
2179     * @memberOf MapCache
2180     * @param {string} key The key of the value to remove.
2181     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2182     */
2183    function mapCacheDelete(key) {
2184      var result = getMapData(this, key)['delete'](key);
2185      this.size -= result ? 1 : 0;
2186      return result;
2187    }
2188
2189    /**
2190     * Gets the map value for `key`.
2191     *
2192     * @private
2193     * @name get
2194     * @memberOf MapCache
2195     * @param {string} key The key of the value to get.
2196     * @returns {*} Returns the entry value.
2197     */
2198    function mapCacheGet(key) {
2199      return getMapData(this, key).get(key);
2200    }
2201
2202    /**
2203     * Checks if a map value for `key` exists.
2204     *
2205     * @private
2206     * @name has
2207     * @memberOf MapCache
2208     * @param {string} key The key of the entry to check.
2209     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2210     */
2211    function mapCacheHas(key) {
2212      return getMapData(this, key).has(key);
2213    }
2214
2215    /**
2216     * Sets the map `key` to `value`.
2217     *
2218     * @private
2219     * @name set
2220     * @memberOf MapCache
2221     * @param {string} key The key of the value to set.
2222     * @param {*} value The value to set.
2223     * @returns {Object} Returns the map cache instance.
2224     */
2225    function mapCacheSet(key, value) {
2226      var data = getMapData(this, key),
2227          size = data.size;
2228
2229      data.set(key, value);
2230      this.size += data.size == size ? 0 : 1;
2231      return this;
2232    }
2233
2234    // Add methods to `MapCache`.
2235    MapCache.prototype.clear = mapCacheClear;
2236    MapCache.prototype['delete'] = mapCacheDelete;
2237    MapCache.prototype.get = mapCacheGet;
2238    MapCache.prototype.has = mapCacheHas;
2239    MapCache.prototype.set = mapCacheSet;
2240
2241    /*------------------------------------------------------------------------*/
2242
2243    /**
2244     *
2245     * Creates an array cache object to store unique values.
2246     *
2247     * @private
2248     * @constructor
2249     * @param {Array} [values] The values to cache.
2250     */
2251    function SetCache(values) {
2252      var index = -1,
2253          length = values == null ? 0 : values.length;
2254
2255      this.__data__ = new MapCache;
2256      while (++index < length) {
2257        this.add(values[index]);
2258      }
2259    }
2260
2261    /**
2262     * Adds `value` to the array cache.
2263     *
2264     * @private
2265     * @name add
2266     * @memberOf SetCache
2267     * @alias push
2268     * @param {*} value The value to cache.
2269     * @returns {Object} Returns the cache instance.
2270     */
vendor: 3,741 bytes, lines 2271-2407
2271    function setCacheAdd(value) {
2272      this.__data__.set(value, HASH_UNDEFINED);
2273      return this;
2274    }
2275
2276    /**
2277     * Checks if `value` is in the array cache.
2278     *
2279     * @private
2280     * @name has
2281     * @memberOf SetCache
2282     * @param {*} value The value to search for.
2283     * @returns {number} Returns `true` if `value` is found, else `false`.
2284     */
2285    function setCacheHas(value) {
2286      return this.__data__.has(value);
2287    }
2288
2289    // Add methods to `SetCache`.
2290    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2291    SetCache.prototype.has = setCacheHas;
2292
2293    /*------------------------------------------------------------------------*/
2294
2295    /**
2296     * Creates a stack cache object to store key-value pairs.
2297     *
2298     * @private
2299     * @constructor
2300     * @param {Array} [entries] The key-value pairs to cache.
2301     */
2302    function Stack(entries) {
2303      var data = this.__data__ = new ListCache(entries);
2304      this.size = data.size;
2305    }
2306
2307    /**
2308     * Removes all key-value entries from the stack.
2309     *
2310     * @private
2311     * @name clear
2312     * @memberOf Stack
2313     */
2314    function stackClear() {
2315      this.__data__ = new ListCache;
2316      this.size = 0;
2317    }
2318
2319    /**
2320     * Removes `key` and its value from the stack.
2321     *
2322     * @private
2323     * @name delete
2324     * @memberOf Stack
2325     * @param {string} key The key of the value to remove.
2326     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2327     */
2328    function stackDelete(key) {
2329      var data = this.__data__,
2330          result = data['delete'](key);
2331
2332      this.size = data.size;
2333      return result;
2334    }
2335
2336    /**
2337     * Gets the stack value for `key`.
2338     *
2339     * @private
2340     * @name get
2341     * @memberOf Stack
2342     * @param {string} key The key of the value to get.
2343     * @returns {*} Returns the entry value.
2344     */
2345    function stackGet(key) {
2346      return this.__data__.get(key);
2347    }
2348
2349    /**
2350     * Checks if a stack value for `key` exists.
2351     *
2352     * @private
2353     * @name has
2354     * @memberOf Stack
2355     * @param {string} key The key of the entry to check.
2356     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2357     */
2358    function stackHas(key) {
2359      return this.__data__.has(key);
2360    }
2361
2362    /**
2363     * Sets the stack `key` to `value`.
2364     *
2365     * @private
2366     * @name set
2367     * @memberOf Stack
2368     * @param {string} key The key of the value to set.
2369     * @param {*} value The value to set.
2370     * @returns {Object} Returns the stack cache instance.
2371     */
2372    function stackSet(key, value) {
2373      var data = this.__data__;
2374      if (data instanceof ListCache) {
2375        var pairs = data.__data__;
2376        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2377          pairs.push([key, value]);
2378          this.size = ++data.size;
2379          return this;
2380        }
2381        data = this.__data__ = new MapCache(pairs);
2382      }
2383      data.set(key, value);
2384      this.size = data.size;
2385      return this;
2386    }
2387
2388    // Add methods to `Stack`.
2389    Stack.prototype.clear = stackClear;
2390    Stack.prototype['delete'] = stackDelete;
2391    Stack.prototype.get = stackGet;
2392    Stack.prototype.has = stackHas;
2393    Stack.prototype.set = stackSet;
2394
2395    /*------------------------------------------------------------------------*/
2396
2397    /**
2398     * Creates an array of the enumerable property names of the array-like `value`.
2399     *
2400     * @private
2401     * @param {*} value The value to query.
2402     * @param {boolean} inherited Specify returning inherited property names.
2403     * @returns {Array} Returns the array of property names.
2404     */
2405    function arrayLikeKeys(value, inherited) {
2406      var isArr = isArray(value),
2407          isArg = !isArr && isArguments(value),
vendor: 9,093 bytes, lines 2408-2681
2408          isBuff = !isArr && !isArg && isBuffer(value),
2409          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2410          skipIndexes = isArr || isArg || isBuff || isType,
2411          result = skipIndexes ? baseTimes(value.length, String) : [],
2412          length = result.length;
2413
2414      for (var key in value) {
2415        if ((inherited || hasOwnProperty.call(value, key)) &&
2416            !(skipIndexes && (
2417               // Safari 9 has enumerable `arguments.length` in strict mode.
2418               key == 'length' ||
2419               // Node.js 0.10 has enumerable non-index properties on buffers.
2420               (isBuff && (key == 'offset' || key == 'parent')) ||
2421               // PhantomJS 2 has enumerable non-index properties on typed arrays.
2422               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2423               // Skip index properties.
2424               isIndex(key, length)
2425            ))) {
2426          result.push(key);
2427        }
2428      }
2429      return result;
2430    }
2431
2432    /**
2433     * A specialized version of `_.sample` for arrays.
2434     *
2435     * @private
2436     * @param {Array} array The array to sample.
2437     * @returns {*} Returns the random element.
2438     */
2439    function arraySample(array) {
2440      var length = array.length;
2441      return length ? array[baseRandom(0, length - 1)] : undefined;
2442    }
2443
2444    /**
2445     * A specialized version of `_.sampleSize` for arrays.
2446     *
2447     * @private
2448     * @param {Array} array The array to sample.
2449     * @param {number} n The number of elements to sample.
2450     * @returns {Array} Returns the random elements.
2451     */
2452    function arraySampleSize(array, n) {
2453      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
2454    }
2455
2456    /**
2457     * A specialized version of `_.shuffle` for arrays.
2458     *
2459     * @private
2460     * @param {Array} array The array to shuffle.
2461     * @returns {Array} Returns the new shuffled array.
2462     */
2463    function arrayShuffle(array) {
2464      return shuffleSelf(copyArray(array));
2465    }
2466
2467    /**
2468     * This function is like `assignValue` except that it doesn't assign
2469     * `undefined` values.
2470     *
2471     * @private
2472     * @param {Object} object The object to modify.
2473     * @param {string} key The key of the property to assign.
2474     * @param {*} value The value to assign.
2475     */
2476    function assignMergeValue(object, key, value) {
2477      if ((value !== undefined && !eq(object[key], value)) ||
2478          (value === undefined && !(key in object))) {
2479        baseAssignValue(object, key, value);
2480      }
2481    }
2482
2483    /**
2484     * Assigns `value` to `key` of `object` if the existing value is not equivalent
2485     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
2486     * for equality comparisons.
2487     *
2488     * @private
2489     * @param {Object} object The object to modify.
2490     * @param {string} key The key of the property to assign.
2491     * @param {*} value The value to assign.
2492     */
2493    function assignValue(object, key, value) {
2494      var objValue = object[key];
2495      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2496          (value === undefined && !(key in object))) {
2497        baseAssignValue(object, key, value);
2498      }
2499    }
2500
2501    /**
2502     * Gets the index at which the `key` is found in `array` of key-value pairs.
2503     *
2504     * @private
2505     * @param {Array} array The array to inspect.
2506     * @param {*} key The key to search for.
2507     * @returns {number} Returns the index of the matched value, else `-1`.
2508     */
2509    function assocIndexOf(array, key) {
2510      var length = array.length;
2511      while (length--) {
2512        if (eq(array[length][0], key)) {
2513          return length;
2514        }
2515      }
2516      return -1;
2517    }
2518
2519    /**
2520     * Aggregates elements of `collection` on `accumulator` with keys transformed
2521     * by `iteratee` and values set by `setter`.
2522     *
2523     * @private
2524     * @param {Array|Object} collection The collection to iterate over.
2525     * @param {Function} setter The function to set `accumulator` values.
2526     * @param {Function} iteratee The iteratee to transform keys.
2527     * @param {Object} accumulator The initial aggregated object.
2528     * @returns {Function} Returns `accumulator`.
2529     */
2530    function baseAggregator(collection, setter, iteratee, accumulator) {
2531      baseEach(collection, function(value, key, collection) {
2532        setter(accumulator, value, iteratee(value), collection);
2533      });
2534      return accumulator;
2535    }
2536
2537    /**
2538     * The base implementation of `_.assign` without support for multiple sources
2539     * or `customizer` functions.
2540     *
2541     * @private
2542     * @param {Object} object The destination object.
2543     * @param {Object} source The source object.
2544     * @returns {Object} Returns `object`.
2545     */
2546    function baseAssign(object, source) {
2547      return object && copyObject(source, keys(source), object);
2548    }
2549
2550    /**
2551     * The base implementation of `_.assignIn` without support for multiple sources
2552     * or `customizer` functions.
2553     *
2554     * @private
2555     * @param {Object} object The destination object.
2556     * @param {Object} source The source object.
2557     * @returns {Object} Returns `object`.
2558     */
2559    function baseAssignIn(object, source) {
2560      return object && copyObject(source, keysIn(source), object);
2561    }
2562
2563    /**
2564     * The base implementation of `assignValue` and `assignMergeValue` without
2565     * value checks.
2566     *
2567     * @private
2568     * @param {Object} object The object to modify.
2569     * @param {string} key The key of the property to assign.
2570     * @param {*} value The value to assign.
2571     */
2572    function baseAssignValue(object, key, value) {
2573      if (key == '__proto__' && defineProperty) {
2574        defineProperty(object, key, {
2575          'configurable': true,
2576          'enumerable': true,
2577          'value': value,
2578          'writable': true
2579        });
2580      } else {
2581        object[key] = value;
2582      }
2583    }
2584
2585    /**
2586     * The base implementation of `_.at` without support for individual paths.
2587     *
2588     * @private
2589     * @param {Object} object The object to iterate over.
2590     * @param {string[]} paths The property paths to pick.
2591     * @returns {Array} Returns the picked elements.
2592     */
2593    function baseAt(object, paths) {
2594      var index = -1,
2595          length = paths.length,
2596          result = Array(length),
2597          skip = object == null;
2598
2599      while (++index < length) {
2600        result[index] = skip ? undefined : get(object, paths[index]);
2601      }
2602      return result;
2603    }
2604
2605    /**
2606     * The base implementation of `_.clamp` which doesn't coerce arguments.
2607     *
2608     * @private
2609     * @param {number} number The number to clamp.
2610     * @param {number} [lower] The lower bound.
2611     * @param {number} upper The upper bound.
2612     * @returns {number} Returns the clamped number.
2613     */
2614    function baseClamp(number, lower, upper) {
2615      if (number === number) {
2616        if (upper !== undefined) {
2617          number = number <= upper ? number : upper;
2618        }
2619        if (lower !== undefined) {
2620          number = number >= lower ? number : lower;
2621        }
2622      }
2623      return number;
2624    }
2625
2626    /**
2627     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2628     * traversed objects.
2629     *
2630     * @private
2631     * @param {*} value The value to clone.
2632     * @param {boolean} bitmask The bitmask flags.
2633     *  1 - Deep clone
2634     *  2 - Flatten inherited properties
2635     *  4 - Clone symbols
2636     * @param {Function} [customizer] The function to customize cloning.
2637     * @param {string} [key] The key of `value`.
2638     * @param {Object} [object] The parent object of `value`.
2639     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2640     * @returns {*} Returns the cloned value.
2641     */
2642    function baseClone(value, bitmask, customizer, key, object, stack) {
2643      var result,
2644          isDeep = bitmask & CLONE_DEEP_FLAG,
2645          isFlat = bitmask & CLONE_FLAT_FLAG,
2646          isFull = bitmask & CLONE_SYMBOLS_FLAG;
2647
2648      if (customizer) {
2649        result = object ? customizer(value, key, object, stack) : customizer(value);
2650      }
2651      if (result !== undefined) {
2652        return result;
2653      }
2654      if (!isObject(value)) {
2655        return value;
2656      }
2657      var isArr = isArray(value);
2658      if (isArr) {
2659        result = initCloneArray(value);
2660        if (!isDeep) {
2661          return copyArray(value, result);
2662        }
2663      } else {
2664        var tag = getTag(value),
2665            isFunc = tag == funcTag || tag == genTag;
2666
2667        if (isBuffer(value)) {
2668          return cloneBuffer(value, isDeep);
2669        }
2670        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2671          result = (isFlat || isFunc) ? {} : initCloneObject(value);
2672          if (!isDeep) {
2673            return isFlat
2674              ? copySymbolsIn(value, baseAssignIn(result, value))
2675              : copySymbols(value, baseAssign(result, value));
2676          }
2677        } else {
2678          if (!cloneableTags[tag]) {
2679            return object ? value : {};
2680          }
2681          result = initCloneByTag(value, tag, 
2681baseClone, isDeep);
2682        }
2683      }
2684      // Check for circular references and return its corresponding clone.
2685      stack || (stack = new Stack);
2686      var stacked = stack.get(value);
2687      if (stacked) {
2688        return stacked;
2689      }
2690      stack.set(value, result);
vendor: 31,223 bytes, lines 2690-3613
2690
2691
2692      var keysFunc = isFull
2693        ? (isFlat ? getAllKeysIn : getAllKeys)
2694        : (isFlat ? keysIn : keys);
2695
2696      var props = isArr ? undefined : keysFunc(value);
2697      arrayEach(props || value, function(subValue, key) {
2698        if (props) {
2699          key = subValue;
2700          subValue = value[key];
2701        }
2702        // Recursively populate clone (susceptible to call stack limits).
2703        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
2704      });
2705      return result;
2706    }
2707
2708    /**
2709     * The base implementation of `_.conforms` which doesn't clone `source`.
2710     *
2711     * @private
2712     * @param {Object} source The object of property predicates to conform to.
2713     * @returns {Function} Returns the new spec function.
2714     */
2715    function baseConforms(source) {
2716      var props = keys(source);
2717      return function(object) {
2718        return baseConformsTo(object, source, props);
2719      };
2720    }
2721
2722    /**
2723     * The base implementation of `_.conformsTo` which accepts `props` to check.
2724     *
2725     * @private
2726     * @param {Object} object The object to inspect.
2727     * @param {Object} source The object of property predicates to conform to.
2728     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
2729     */
2730    function baseConformsTo(object, source, props) {
2731      var length = props.length;
2732      if (object == null) {
2733        return !length;
2734      }
2735      object = Object(object);
2736      while (length--) {
2737        var key = props[length],
2738            predicate = source[key],
2739            value = object[key];
2740
2741        if ((value === undefined && !(key in object)) || !predicate(value)) {
2742          return false;
2743        }
2744      }
2745      return true;
2746    }
2747
2748    /**
2749     * The base implementation of `_.delay` and `_.defer` which accepts `args`
2750     * to provide to `func`.
2751     *
2752     * @private
2753     * @param {Function} func The function to delay.
2754     * @param {number} wait The number of milliseconds to delay invocation.
2755     * @param {Array} args The arguments to provide to `func`.
2756     * @returns {number|Object} Returns the timer id or timeout object.
2757     */
2758    function baseDelay(func, wait, args) {
2759      if (typeof func != 'function') {
2760        throw new TypeError(FUNC_ERROR_TEXT);
2761      }
2762      return setTimeout(function() { func.apply(undefined, args); }, wait);
2763    }
2764
2765    /**
2766     * The base implementation of methods like `_.difference` without support
2767     * for excluding multiple arrays or iteratee shorthands.
2768     *
2769     * @private
2770     * @param {Array} array The array to inspect.
2771     * @param {Array} values The values to exclude.
2772     * @param {Function} [iteratee] The iteratee invoked per element.
2773     * @param {Function} [comparator] The comparator invoked per element.
2774     * @returns {Array} Returns the new array of filtered values.
2775     */
2776    function baseDifference(array, values, iteratee, comparator) {
2777      var index = -1,
2778          includes = arrayIncludes,
2779          isCommon = true,
2780          length = array.length,
2781          result = [],
2782          valuesLength = values.length;
2783
2784      if (!length) {
2785        return result;
2786      }
2787      if (iteratee) {
2788        values = arrayMap(values, baseUnary(iteratee));
2789      }
2790      if (comparator) {
2791        includes = arrayIncludesWith;
2792        isCommon = false;
2793      }
2794      else if (values.length >= LARGE_ARRAY_SIZE) {
2795        includes = cacheHas;
2796        isCommon = false;
2797        values = new SetCache(values);
2798      }
2799      outer:
2800      while (++index < length) {
2801        var value = array[index],
2802            computed = iteratee == null ? value : iteratee(value);
2803
2804        value = (comparator || value !== 0) ? value : 0;
2805        if (isCommon && computed === computed) {
2806          var valuesIndex = valuesLength;
2807          while (valuesIndex--) {
2808            if (values[valuesIndex] === computed) {
2809              continue outer;
2810            }
2811          }
2812          result.push(value);
2813        }
2814        else if (!includes(values, computed, comparator)) {
2815          result.push(value);
2816        }
2817      }
2818      return result;
2819    }
2820
2821    /**
2822     * The base implementation of `_.forEach` without support for iteratee shorthands.
2823     *
2824     * @private
2825     * @param {Array|Object} collection The collection to iterate over.
2826     * @param {Function} iteratee The function invoked per iteration.
2827     * @returns {Array|Object} Returns `collection`.
2828     */
2829    var baseEach = createBaseEach(baseForOwn);
2830
2831    /**
2832     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2833     *
2834     * @private
2835     * @param {Array|Object} collection The collection to iterate over.
2836     * @param {Function} iteratee The function invoked per iteration.
2837     * @returns {Array|Object} Returns `collection`.
2838     */
2839    var baseEachRight = createBaseEach(baseForOwnRight, true);
2840
2841    /**
2842     * The base implementation of `_.every` without support for iteratee shorthands.
2843     *
2844     * @private
2845     * @param {Array|Object} collection The collection to iterate over.
2846     * @param {Function} predicate The function invoked per iteration.
2847     * @returns {boolean} Returns `true` if all elements pass the predicate check,
2848     *  else `false`
2849     */
2850    function baseEvery(collection, predicate) {
2851      var result = true;
2852      baseEach(collection, function(value, index, collection) {
2853        result = !!predicate(value, index, collection);
2854        return result;
2855      });
2856      return result;
2857    }
2858
2859    /**
2860     * The base implementation of methods like `_.max` and `_.min` which accepts a
2861     * `comparator` to determine the extremum value.
2862     *
2863     * @private
2864     * @param {Array} array The array to iterate over.
2865     * @param {Function} iteratee The iteratee invoked per iteration.
2866     * @param {Function} comparator The comparator used to compare values.
2867     * @returns {*} Returns the extremum value.
2868     */
2869    function baseExtremum(array, iteratee, comparator) {
2870      var index = -1,
2871          length = array.length;
2872
2873      while (++index < length) {
2874        var value = array[index],
2875            current = iteratee(value);
2876
2877        if (current != null && (computed === undefined
2878              ? (current === current && !isSymbol(current))
2879              : comparator(current, computed)
2880            )) {
2881          var computed = current,
2882              result = value;
2883        }
2884      }
2885      return result;
2886    }
2887
2888    /**
2889     * The base implementation of `_.fill` without an iteratee call guard.
2890     *
2891     * @private
2892     * @param {Array} array The array to fill.
2893     * @param {*} value The value to fill `array` with.
2894     * @param {number} [start=0] The start position.
2895     * @param {number} [end=array.length] The end position.
2896     * @returns {Array} Returns `array`.
2897     */
2898    function baseFill(array, value, start, end) {
2899      var length = array.length;
2900
2901      start = toInteger(start);
2902      if (start < 0) {
2903        start = -start > length ? 0 : (length + start);
2904      }
2905      end = (end === undefined || end > length) ? length : toInteger(end);
2906      if (end < 0) {
2907        end += length;
2908      }
2909      end = start > end ? 0 : toLength(end);
2910      while (start < end) {
2911        array[start++] = value;
2912      }
2913      return array;
2914    }
2915
2916    /**
2917     * The base implementation of `_.filter` without support for iteratee shorthands.
2918     *
2919     * @private
2920     * @param {Array|Object} collection The collection to iterate over.
2921     * @param {Function} predicate The function invoked per iteration.
2922     * @returns {Array} Returns the new filtered array.
2923     */
2924    function baseFilter(collection, predicate) {
2925      var result = [];
2926      baseEach(collection, function(value, index, collection) {
2927        if (predicate(value, index, collection)) {
2928          result.push(value);
2929        }
2930      });
2931      return result;
2932    }
2933
2934    /**
2935     * The base implementation of `_.flatten` with support for restricting flattening.
2936     *
2937     * @private
2938     * @param {Array} array The array to flatten.
2939     * @param {number} depth The maximum recursion depth.
2940     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2941     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2942     * @param {Array} [result=[]] The initial result value.
2943     * @returns {Array} Returns the new flattened array.
2944     */
2945    function baseFlatten(array, depth, predicate, isStrict, result) {
2946      var index = -1,
2947          length = array.length;
2948
2949      predicate || (predicate = isFlattenable);
2950      result || (result = []);
2951
2952      while (++index < length) {
2953        var value = array[index];
2954        if (depth > 0 && predicate(value)) {
2955          if (depth > 1) {
2956            // Recursively flatten arrays (susceptible to call stack limits).
2957            baseFlatten(value, depth - 1, predicate, isStrict, result);
2958          } else {
2959            arrayPush(result, value);
2960          }
2961        } else if (!isStrict) {
2962          result[result.length] = value;
2963        }
2964      }
2965      return result;
2966    }
2967
2968    /**
2969     * The base implementation of `baseForOwn` which iterates over `object`
2970     * properties returned by `keysFunc` and invokes `iteratee` for each property.
2971     * Iteratee functions may exit iteration early by explicitly returning `false`.
2972     *
2973     * @private
2974     * @param {Object} object The object to iterate over.
2975     * @param {Function} iteratee The function invoked per iteration.
2976     * @param {Function} keysFunc The function to get the keys of `object`.
2977     * @returns {Object} Returns `object`.
2978     */
2979    var baseFor = createBaseFor();
2980
2981    /**
2982     * This function is like `baseFor` except that it iterates over properties
2983     * in the opposite order.
2984     *
2985     * @private
2986     * @param {Object} object The object to iterate over.
2987     * @param {Function} iteratee The function invoked per iteration.
2988     * @param {Function} keysFunc The function to get the keys of `object`.
2989     * @returns {Object} Returns `object`.
2990     */
2991    var baseForRight = createBaseFor(true);
2992
2993    /**
2994     * The base implementation of `_.forOwn` without support for iteratee shorthands.
2995     *
2996     * @private
2997     * @param {Object} object The object to iterate over.
2998     * @param {Function} iteratee The function invoked per iteration.
2999     * @returns {Object} Returns `object`.
3000     */
3001    function baseForOwn(object, iteratee) {
3002      return object && baseFor(object, iteratee, keys);
3003    }
3004
3005    /**
3006     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
3007     *
3008     * @private
3009     * @param {Object} object The object to iterate over.
3010     * @param {Function} iteratee The function invoked per iteration.
3011     * @returns {Object} Returns `object`.
3012     */
3013    function baseForOwnRight(object, iteratee) {
3014      return object && baseForRight(object, iteratee, keys);
3015    }
3016
3017    /**
3018     * The base implementation of `_.functions` which creates an array of
3019     * `object` function property names filtered from `props`.
3020     *
3021     * @private
3022     * @param {Object} object The object to inspect.
3023     * @param {Array} props The property names to filter.
3024     * @returns {Array} Returns the function names.
3025     */
3026    function baseFunctions(object, props) {
3027      return arrayFilter(props, function(key) {
3028        return isFunction(object[key]);
3029      });
3030    }
3031
3032    /**
3033     * The base implementation of `_.get` without support for default values.
3034     *
3035     * @private
3036     * @param {Object} object The object to query.
3037     * @param {Array|string} path The path of the property to get.
3038     * @returns {*} Returns the resolved value.
3039     */
3040    function baseGet(object, path) {
3041      path = castPath(path, object);
3042
3043      var index = 0,
3044          length = path.length;
3045
3046      while (object != null && index < length) {
3047        object = object[toKey(path[index++])];
3048      }
3049      return (index && index == length) ? object : undefined;
3050    }
3051
3052    /**
3053     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
3054     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
3055     * symbols of `object`.
3056     *
3057     * @private
3058     * @param {Object} object The object to query.
3059     * @param {Function} keysFunc The function to get the keys of `object`.
3060     * @param {Function} symbolsFunc The function to get the symbols of `object`.
3061     * @returns {Array} Returns the array of property names and symbols.
3062     */
3063    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
3064      var result = keysFunc(object);
3065      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
3066    }
3067
3068    /**
3069     * The base implementation of `getTag` without fallbacks for buggy environments.
3070     *
3071     * @private
3072     * @param {*} value The value to query.
3073     * @returns {string} Returns the `toStringTag`.
3074     */
3075    function baseGetTag(value) {
3076      if (value == null) {
3077        return value === undefined ? undefinedTag : nullTag;
3078      }
3079      return (symToStringTag && symToStringTag in Object(value))
3080        ? getRawTag(value)
3081        : objectToString(value);
3082    }
3083
3084    /**
3085     * The base implementation of `_.gt` which doesn't coerce arguments.
3086     *
3087     * @private
3088     * @param {*} value The value to compare.
3089     * @param {*} other The other value to compare.
3090     * @returns {boolean} Returns `true` if `value` is greater than `other`,
3091     *  else `false`.
3092     */
3093    function baseGt(value, other) {
3094      return value > other;
3095    }
3096
3097    /**
3098     * The base implementation of `_.has` without support for deep paths.
3099     *
3100     * @private
3101     * @param {Object} [object] The object to query.
3102     * @param {Array|string} key The key to check.
3103     * @returns {boolean} Returns `true` if `key` exists, else `false`.
3104     */
3105    function baseHas(object, key) {
3106      return object != null && hasOwnProperty.call(object, key);
3107    }
3108
3109    /**
3110     * The base implementation of `_.hasIn` without support for deep paths.
3111     *
3112     * @private
3113     * @param {Object} [object] The object to query.
3114     * @param {Array|string} key The key to check.
3115     * @returns {boolean} Returns `true` if `key` exists, else `false`.
3116     */
3117    function baseHasIn(object, key) {
3118      return object != null && key in Object(object);
3119    }
3120
3121    /**
3122     * The base implementation of `_.inRange` which doesn't coerce arguments.
3123     *
3124     * @private
3125     * @param {number} number The number to check.
3126     * @param {number} start The start of the range.
3127     * @param {number} end The end of the range.
3128     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
3129     */
3130    function baseInRange(number, start, end) {
3131      return number >= nativeMin(start, end) && number < nativeMax(start, end);
3132    }
3133
3134    /**
3135     * The base implementation of methods like `_.intersection`, without support
3136     * for iteratee shorthands, that accepts an array of arrays to inspect.
3137     *
3138     * @private
3139     * @param {Array} arrays The arrays to inspect.
3140     * @param {Function} [iteratee] The iteratee invoked per element.
3141     * @param {Function} [comparator] The comparator invoked per element.
3142     * @returns {Array} Returns the new array of shared values.
3143     */
3144    function baseIntersection(arrays, iteratee, comparator) {
3145      var includes = comparator ? arrayIncludesWith : arrayIncludes,
3146          length = arrays[0].length,
3147          othLength = arrays.length,
3148          othIndex = othLength,
3149          caches = Array(othLength),
3150          maxLength = Infinity,
3151          result = [];
3152
3153      while (othIndex--) {
3154        var array = arrays[othIndex];
3155        if (othIndex && iteratee) {
3156          array = arrayMap(array, baseUnary(iteratee));
3157        }
3158        maxLength = nativeMin(array.length, maxLength);
3159        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
3160          ? new SetCache(othIndex && array)
3161          : undefined;
3162      }
3163      array = arrays[0];
3164
3165      var index = -1,
3166          seen = caches[0];
3167
3168      outer:
3169      while (++index < length && result.length < maxLength) {
3170        var value = array[index],
3171            computed = iteratee ? iteratee(value) : value;
3172
3173        value = (comparator || value !== 0) ? value : 0;
3174        if (!(seen
3175              ? cacheHas(seen, computed)
3176              : includes(result, computed, comparator)
3177            )) {
3178          othIndex = othLength;
3179          while (--othIndex) {
3180            var cache = caches[othIndex];
3181            if (!(cache
3182                  ? cacheHas(cache, computed)
3183                  : includes(arrays[othIndex], computed, comparator))
3184                ) {
3185              continue outer;
3186            }
3187          }
3188          if (seen) {
3189            seen.push(computed);
3190          }
3191          result.push(value);
3192        }
3193      }
3194      return result;
3195    }
3196
3197    /**
3198     * The base implementation of `_.invert` and `_.invertBy` which inverts
3199     * `object` with values transformed by `iteratee` and set by `setter`.
3200     *
3201     * @private
3202     * @param {Object} object The object to iterate over.
3203     * @param {Function} setter The function to set `accumulator` values.
3204     * @param {Function} iteratee The iteratee to transform values.
3205     * @param {Object} accumulator The initial inverted object.
3206     * @returns {Function} Returns `accumulator`.
3207     */
3208    function baseInverter(object, setter, iteratee, accumulator) {
3209      baseForOwn(object, function(value, key, object) {
3210        setter(accumulator, iteratee(value), key, object);
3211      });
3212      return accumulator;
3213    }
3214
3215    /**
3216     * The base implementation of `_.invoke` without support for individual
3217     * method arguments.
3218     *
3219     * @private
3220     * @param {Object} object The object to query.
3221     * @param {Array|string} path The path of the method to invoke.
3222     * @param {Array} args The arguments to invoke the method with.
3223     * @returns {*} Returns the result of the invoked method.
3224     */
3225    function baseInvoke(object, path, args) {
3226      path = castPath(path, object);
3227      object = parent(object, path);
3228      var func = object == null ? object : object[toKey(last(path))];
3229      return func == null ? undefined : apply(func, object, args);
3230    }
3231
3232    /**
3233     * The base implementation of `_.isArguments`.
3234     *
3235     * @private
3236     * @param {*} value The value to check.
3237     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3238     */
3239    function baseIsArguments(value) {
3240      return isObjectLike(value) && baseGetTag(value) == argsTag;
3241    }
3242
3243    /**
3244     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
3245     *
3246     * @private
3247     * @param {*} value The value to check.
3248     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
3249     */
3250    function baseIsArrayBuffer(value) {
3251      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
3252    }
3253
3254    /**
3255     * The base implementation of `_.isDate` without Node.js optimizations.
3256     *
3257     * @private
3258     * @param {*} value The value to check.
3259     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
3260     */
3261    function baseIsDate(value) {
3262      return isObjectLike(value) && baseGetTag(value) == dateTag;
3263    }
3264
3265    /**
3266     * The base implementation of `_.isEqual` which supports partial comparisons
3267     * and tracks traversed objects.
3268     *
3269     * @private
3270     * @param {*} value The value to compare.
3271     * @param {*} other The other value to compare.
3272     * @param {boolean} bitmask The bitmask flags.
3273     *  1 - Unordered comparison
3274     *  2 - Partial comparison
3275     * @param {Function} [customizer] The function to customize comparisons.
3276     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
3277     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3278     */
3279    function baseIsEqual(value, other, bitmask, customizer, stack) {
3280      if (value === other) {
3281        return true;
3282      }
3283      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
3284        return value !== value && other !== other;
3285      }
3286      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
3287    }
3288
3289    /**
3290     * A specialized version of `baseIsEqual` for arrays and objects which performs
3291     * deep comparisons and tracks traversed objects enabling objects with circular
3292     * references to be compared.
3293     *
3294     * @private
3295     * @param {Object} object The object to compare.
3296     * @param {Object} other The other object to compare.
3297     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
3298     * @param {Function} customizer The function to customize comparisons.
3299     * @param {Function} equalFunc The function to determine equivalents of values.
3300     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
3301     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
3302     */
3303    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
3304      var objIsArr = isArray(object),
3305          othIsArr = isArray(other),
3306          objTag = objIsArr ? arrayTag : getTag(object),
3307          othTag = othIsArr ? arrayTag : getTag(other);
3308
3309      objTag = objTag == argsTag ? objectTag : objTag;
3310      othTag = othTag == argsTag ? objectTag : othTag;
3311
3312      var objIsObj = objTag == objectTag,
3313          othIsObj = othTag == objectTag,
3314          isSameTag = objTag == othTag;
3315
3316      if (isSameTag && isBuffer(object)) {
3317        if (!isBuffer(other)) {
3318          return false;
3319        }
3320        objIsArr = true;
3321        objIsObj = false;
3322      }
3323      if (isSameTag && !objIsObj) {
3324        stack || (stack = new Stack);
3325        return (objIsArr || isTypedArray(object))
3326          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
3327          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
3328      }
3329      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
3330        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
3331            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
3332
3333        if (objIsWrapped || othIsWrapped) {
3334          var objUnwrapped = objIsWrapped ? object.value() : object,
3335              othUnwrapped = othIsWrapped ? other.value() : other;
3336
3337          stack || (stack = new Stack);
3338          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
3339        }
3340      }
3341      if (!isSameTag) {
3342        return false;
3343      }
3344      stack || (stack = new Stack);
3345      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
3346    }
3347
3348    /**
3349     * The base implementation of `_.isMap` without Node.js optimizations.
3350     *
3351     * @private
3352     * @param {*} value The value to check.
3353     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
3354     */
3355    function baseIsMap(value) {
3356      return isObjectLike(value) && getTag(value) == mapTag;
3357    }
3358
3359    /**
3360     * The base implementation of `_.isMatch` without support for iteratee shorthands.
3361     *
3362     * @private
3363     * @param {Object} object The object to inspect.
3364     * @param {Object} source The object of property values to match.
3365     * @param {Array} matchData The property names, values, and compare flags to match.
3366     * @param {Function} [customizer] The function to customize comparisons.
3367     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
3368     */
3369    function baseIsMatch(object, source, matchData, customizer) {
3370      var index = matchData.length,
3371          length = index,
3372          noCustomizer = !customizer;
3373
3374      if (object == null) {
3375        return !length;
3376      }
3377      object = Object(object);
3378      while (index--) {
3379        var data = matchData[index];
3380        if ((noCustomizer && data[2])
3381              ? data[1] !== object[data[0]]
3382              : !(data[0] in object)
3383            ) {
3384          return false;
3385        }
3386      }
3387      while (++index < length) {
3388        data = matchData[index];
3389        var key = data[0],
3390            objValue = object[key],
3391            srcValue = data[1];
3392
3393        if (noCustomizer && data[2]) {
3394          if (objValue === undefined && !(key in object)) {
3395            return false;
3396          }
3397        } else {
3398          var stack = new Stack;
3399          if (customizer) {
3400            var result = customizer(objValue, srcValue, key, object, source, stack);
3401          }
3402          if (!(result === undefined
3403                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
3404                : result
3405              )) {
3406            return false;
3407          }
3408        }
3409      }
3410      return true;
3411    }
3412
3413    /**
3414     * The base implementation of `_.isNative` without bad shim checks.
3415     *
3416     * @private
3417     * @param {*} value The value to check.
3418     * @returns {boolean} Returns `true` if `value` is a native function,
3419     *  else `false`.
3420     */
3421    function baseIsNative(value) {
3422      if (!isObject(value) || isMasked(value)) {
3423        return false;
3424      }
3425      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3426      return pattern.test(toSource(value));
3427    }
3428
3429    /**
3430     * The base implementation of `_.isRegExp` without Node.js optimizations.
3431     *
3432     * @private
3433     * @param {*} value The value to check.
3434     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
3435     */
3436    function baseIsRegExp(value) {
3437      return isObjectLike(value) && baseGetTag(value) == regexpTag;
3438    }
3439
3440    /**
3441     * The base implementation of `_.isSet` without Node.js optimizations.
3442     *
3443     * @private
3444     * @param {*} value The value to check.
3445     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
3446     */
3447    function baseIsSet(value) {
3448      return isObjectLike(value) && getTag(value) == setTag;
3449    }
3450
3451    /**
3452     * The base implementation of `_.isTypedArray` without Node.js optimizations.
3453     *
3454     * @private
3455     * @param {*} value The value to check.
3456     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3457     */
3458    function baseIsTypedArray(value) {
3459      return isObjectLike(value) &&
3460        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
3461    }
3462
3463    /**
3464     * The base implementation of `_.iteratee`.
3465     *
3466     * @private
3467     * @param {*} [value=_.identity] The value to convert to an iteratee.
3468     * @returns {Function} Returns the iteratee.
3469     */
3470    function baseIteratee(value) {
3471      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3472      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3473      if (typeof value == 'function') {
3474        return value;
3475      }
3476      if (value == null) {
3477        return identity;
3478      }
3479      if (typeof value == 'object') {
3480        return isArray(value)
3481          ? baseMatchesProperty(value[0], value[1])
3482          : baseMatches(value);
3483      }
3484      return property(value);
3485    }
3486
3487    /**
3488     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
3489     *
3490     * @private
3491     * @param {Object} object The object to query.
3492     * @returns {Array} Returns the array of property names.
3493     */
3494    function baseKeys(object) {
3495      if (!isPrototype(object)) {
3496        return nativeKeys(object);
3497      }
3498      var result = [];
3499      for (var key in Object(object)) {
3500        if (hasOwnProperty.call(object, key) && key != 'constructor') {
3501          result.push(key);
3502        }
3503      }
3504      return result;
3505    }
3506
3507    /**
3508     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
3509     *
3510     * @private
3511     * @param {Object} object The object to query.
3512     * @returns {Array} Returns the array of property names.
3513     */
3514    function baseKeysIn(object) {
3515      if (!isObject(object)) {
3516        return nativeKeysIn(object);
3517      }
3518      var isProto = isPrototype(object),
3519          result = [];
3520
3521      for (var key in object) {
3522        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3523          result.push(key);
3524        }
3525      }
3526      return result;
3527    }
3528
3529    /**
3530     * The base implementation of `_.lt` which doesn't coerce arguments.
3531     *
3532     * @private
3533     * @param {*} value The value to compare.
3534     * @param {*} other The other value to compare.
3535     * @returns {boolean} Returns `true` if `value` is less than `other`,
3536     *  else `false`.
3537     */
3538    function baseLt(value, other) {
3539      return value < other;
3540    }
3541
3542    /**
3543     * The base implementation of `_.map` without support for iteratee shorthands.
3544     *
3545     * @private
3546     * @param {Array|Object} collection The collection to iterate over.
3547     * @param {Function} iteratee The function invoked per iteration.
3548     * @returns {Array} Returns the new mapped array.
3549     */
3550    function baseMap(collection, iteratee) {
3551      var index = -1,
3552          result = isArrayLike(collection) ? Array(collection.length) : [];
3553
3554      baseEach(collection, function(value, key, collection) {
3555        result[++index] = iteratee(value, key, collection);
3556      });
3557      return result;
3558    }
3559
3560    /**
3561     * The base implementation of `_.matches` which doesn't clone `source`.
3562     *
3563     * @private
3564     * @param {Object} source The object of property values to match.
3565     * @returns {Function} Returns the new spec function.
3566     */
3567    function baseMatches(source) {
3568      var matchData = getMatchData(source);
3569      if (matchData.length == 1 && matchData[0][2]) {
3570        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3571      }
3572      return function(object) {
3573        return object === source || baseIsMatch(object, source, matchData);
3574      };
3575    }
3576
3577    /**
3578     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3579     *
3580     * @private
3581     * @param {string} path The path of the property to get.
3582     * @param {*} srcValue The value to match.
3583     * @returns {Function} Returns the new spec function.
3584     */
3585    function baseMatchesProperty(path, srcValue) {
3586      if (isKey(path) && isStrictComparable(srcValue)) {
3587        return matchesStrictComparable(toKey(path), srcValue);
3588      }
3589      return function(object) {
3590        var objValue = get(object, path);
3591        return (objValue === undefined && objValue === srcValue)
3592          ? hasIn(object, path)
3593          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
3594      };
3595    }
3596
3597    /**
3598     * The base implementation of `_.merge` without support for multiple sources.
3599     *
3600     * @private
3601     * @param {Object} object The destination object.
3602     * @param {Object} source The source object.
3603     * @param {number} srcIndex The index of `source`.
3604     * @param {Function} [customizer] The function to customize merged values.
3605     * @param {Object} [stack] Tracks traversed source values and their merged
3606     *  counterparts.
3607     */
3608    function baseMerge(object, source, srcIndex, customizer, stack) {
3609      if (object === source) {
3610        return;
3611      }
3612      baseFor(source, function(srcValue, key) {
3613        
vendor: 2,153 bytes, lines 3613-3674
3613if (isObject(srcValue)) {
3614          stack || (stack = new Stack);
3615          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3616        }
3617        else {
3618          var newValue = customizer
3619            ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3620            : undefined;
3621
3622          if (newValue === undefined) {
3623            newValue = srcValue;
3624          }
3625          assignMergeValue(object, key, newValue);
3626        }
3627      }, keysIn);
3628    }
3629
3630    /**
3631     * A specialized version of `baseMerge` for arrays and objects which performs
3632     * deep merges and tracks traversed objects enabling objects with circular
3633     * references to be merged.
3634     *
3635     * @private
3636     * @param {Object} object The destination object.
3637     * @param {Object} source The source object.
3638     * @param {string} key The key of the value to merge.
3639     * @param {number} srcIndex The index of `source`.
3640     * @param {Function} mergeFunc The function to merge values.
3641     * @param {Function} [customizer] The function to customize assigned values.
3642     * @param {Object} [stack] Tracks traversed source values and their merged
3643     *  counterparts.
3644     */
3645    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3646      var objValue = object[key],
3647          srcValue = source[key],
3648          stacked = stack.get(srcValue);
3649
3650      if (stacked) {
3651        assignMergeValue(object, key, stacked);
3652        return;
3653      }
3654      var newValue = customizer
3655        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3656        : undefined;
3657
3658      var isCommon = newValue === undefined;
3659
3660      if (isCommon) {
3661        var isArr = isArray(srcValue),
3662            isBuff = !isArr && isBuffer(srcValue),
3663            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
3664
3665        newValue = srcValue;
3666        if (isArr || isBuff || isTyped) {
3667          if (isArray(objValue)) {
3668            newValue = objValue;
3669          }
3670          else if (isArrayLikeObject(objValue)) {
3671            newValue = copyArray(objValue);
3672          }
3673          else if (isBuff) {
3674            isCommon = false;
3675            newValue = cloneBuffer(srcValue, true);
3676          }
3677          else if (isTyped) {
3678            isCommon = false;
3679            newValue = cloneTypedArray(srcValue, true);
3680          }
3681          else {
3682            newValue = [];
3683          }
3684        }
3685        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3686          newValue = objValue;
3687          if (isArguments(objValue)) {
3688            newValue = toPlainObject(objValue);
3689          }
3690          else if (!isObject(objValue) || (srcIndex && isFunction(objValue)
vendor: 14,715 bytes, lines 3690-4153
3690)) {
3691            newValue = initCloneObject(srcValue);
3692          }
3693        }
3694        else {
3695          isCommon = false;
3696        }
3697      }
3698      if (isCommon) {
3699        // Recursively merge objects and arrays (susceptible to call stack limits).
3700        stack.set(srcValue, newValue);
3701        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3702        stack['delete'](srcValue);
3703      }
3704      assignMergeValue(object, key, newValue);
3705    }
3706
3707    /**
3708     * The base implementation of `_.nth` which doesn't coerce arguments.
3709     *
3710     * @private
3711     * @param {Array} array The array to query.
3712     * @param {number} n The index of the element to return.
3713     * @returns {*} Returns the nth element of `array`.
3714     */
3715    function baseNth(array, n) {
3716      var length = array.length;
3717      if (!length) {
3718        return;
3719      }
3720      n += n < 0 ? length : 0;
3721      return isIndex(n, length) ? array[n] : undefined;
3722    }
3723
3724    /**
3725     * The base implementation of `_.orderBy` without param guards.
3726     *
3727     * @private
3728     * @param {Array|Object} collection The collection to iterate over.
3729     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3730     * @param {string[]} orders The sort orders of `iteratees`.
3731     * @returns {Array} Returns the new sorted array.
3732     */
3733    function baseOrderBy(collection, iteratees, orders) {
3734      var index = -1;
3735      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3736
3737      var result = baseMap(collection, function(value, key, collection) {
3738        var criteria = arrayMap(iteratees, function(iteratee) {
3739          return iteratee(value);
3740        });
3741        return { 'criteria': criteria, 'index': ++index, 'value': value };
3742      });
3743
3744      return baseSortBy(result, function(object, other) {
3745        return compareMultiple(object, other, orders);
3746      });
3747    }
3748
3749    /**
3750     * The base implementation of `_.pick` without support for individual
3751     * property identifiers.
3752     *
3753     * @private
3754     * @param {Object} object The source object.
3755     * @param {string[]} paths The property paths to pick.
3756     * @returns {Object} Returns the new object.
3757     */
3758    function basePick(object, paths) {
3759      return basePickBy(object, paths, function(value, path) {
3760        return hasIn(object, path);
3761      });
3762    }
3763
3764    /**
3765     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3766     *
3767     * @private
3768     * @param {Object} object The source object.
3769     * @param {string[]} paths The property paths to pick.
3770     * @param {Function} predicate The function invoked per property.
3771     * @returns {Object} Returns the new object.
3772     */
3773    function basePickBy(object, paths, predicate) {
3774      var index = -1,
3775          length = paths.length,
3776          result = {};
3777
3778      while (++index < length) {
3779        var path = paths[index],
3780            value = baseGet(object, path);
3781
3782        if (predicate(value, path)) {
3783          baseSet(result, castPath(path, object), value);
3784        }
3785      }
3786      return result;
3787    }
3788
3789    /**
3790     * A specialized version of `baseProperty` which supports deep paths.
3791     *
3792     * @private
3793     * @param {Array|string} path The path of the property to get.
3794     * @returns {Function} Returns the new accessor function.
3795     */
3796    function basePropertyDeep(path) {
3797      return function(object) {
3798        return baseGet(object, path);
3799      };
3800    }
3801
3802    /**
3803     * The base implementation of `_.pullAllBy` without support for iteratee
3804     * shorthands.
3805     *
3806     * @private
3807     * @param {Array} array The array to modify.
3808     * @param {Array} values The values to remove.
3809     * @param {Function} [iteratee] The iteratee invoked per element.
3810     * @param {Function} [comparator] The comparator invoked per element.
3811     * @returns {Array} Returns `array`.
3812     */
3813    function basePullAll(array, values, iteratee, comparator) {
3814      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3815          index = -1,
3816          length = values.length,
3817          seen = array;
3818
3819      if (array === values) {
3820        values = copyArray(values);
3821      }
3822      if (iteratee) {
3823        seen = arrayMap(array, baseUnary(iteratee));
3824      }
3825      while (++index < length) {
3826        var fromIndex = 0,
3827            value = values[index],
3828            computed = iteratee ? iteratee(value) : value;
3829
3830        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3831          if (seen !== array) {
3832            splice.call(seen, fromIndex, 1);
3833          }
3834          splice.call(array, fromIndex, 1);
3835        }
3836      }
3837      return array;
3838    }
3839
3840    /**
3841     * The base implementation of `_.pullAt` without support for individual
3842     * indexes or capturing the removed elements.
3843     *
3844     * @private
3845     * @param {Array} array The array to modify.
3846     * @param {number[]} indexes The indexes of elements to remove.
3847     * @returns {Array} Returns `array`.
3848     */
3849    function basePullAt(array, indexes) {
3850      var length = array ? indexes.length : 0,
3851          lastIndex = length - 1;
3852
3853      while (length--) {
3854        var index = indexes[length];
3855        if (length == lastIndex || index !== previous) {
3856          var previous = index;
3857          if (isIndex(index)) {
3858            splice.call(array, index, 1);
3859          } else {
3860            baseUnset(array, index);
3861          }
3862        }
3863      }
3864      return array;
3865    }
3866
3867    /**
3868     * The base implementation of `_.random` without support for returning
3869     * floating-point numbers.
3870     *
3871     * @private
3872     * @param {number} lower The lower bound.
3873     * @param {number} upper The upper bound.
3874     * @returns {number} Returns the random number.
3875     */
3876    function baseRandom(lower, upper) {
3877      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3878    }
3879
3880    /**
3881     * The base implementation of `_.range` and `_.rangeRight` which doesn't
3882     * coerce arguments.
3883     *
3884     * @private
3885     * @param {number} start The start of the range.
3886     * @param {number} end The end of the range.
3887     * @param {number} step The value to increment or decrement by.
3888     * @param {boolean} [fromRight] Specify iterating from right to left.
3889     * @returns {Array} Returns the range of numbers.
3890     */
3891    function baseRange(start, end, step, fromRight) {
3892      var index = -1,
3893          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3894          result = Array(length);
3895
3896      while (length--) {
3897        result[fromRight ? length : ++index] = start;
3898        start += step;
3899      }
3900      return result;
3901    }
3902
3903    /**
3904     * The base implementation of `_.repeat` which doesn't coerce arguments.
3905     *
3906     * @private
3907     * @param {string} string The string to repeat.
3908     * @param {number} n The number of times to repeat the string.
3909     * @returns {string} Returns the repeated string.
3910     */
3911    function baseRepeat(string, n) {
3912      var result = '';
3913      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3914        return result;
3915      }
3916      // Leverage the exponentiation by squaring algorithm for a faster repeat.
3917      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3918      do {
3919        if (n % 2) {
3920          result += string;
3921        }
3922        n = nativeFloor(n / 2);
3923        if (n) {
3924          string += string;
3925        }
3926      } while (n);
3927
3928      return result;
3929    }
3930
3931    /**
3932     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
3933     *
3934     * @private
3935     * @param {Function} func The function to apply a rest parameter to.
3936     * @param {number} [start=func.length-1] The start position of the rest parameter.
3937     * @returns {Function} Returns the new function.
3938     */
3939    function baseRest(func, start) {
3940      return setToString(overRest(func, start, identity), func + '');
3941    }
3942
3943    /**
3944     * The base implementation of `_.sample`.
3945     *
3946     * @private
3947     * @param {Array|Object} collection The collection to sample.
3948     * @returns {*} Returns the random element.
3949     */
3950    function baseSample(collection) {
3951      return arraySample(values(collection));
3952    }
3953
3954    /**
3955     * The base implementation of `_.sampleSize` without param guards.
3956     *
3957     * @private
3958     * @param {Array|Object} collection The collection to sample.
3959     * @param {number} n The number of elements to sample.
3960     * @returns {Array} Returns the random elements.
3961     */
3962    function baseSampleSize(collection, n) {
3963      var array = values(collection);
3964      return shuffleSelf(array, baseClamp(n, 0, array.length));
3965    }
3966
3967    /**
3968     * The base implementation of `_.set`.
3969     *
3970     * @private
3971     * @param {Object} object The object to modify.
3972     * @param {Array|string} path The path of the property to set.
3973     * @param {*} value The value to set.
3974     * @param {Function} [customizer] The function to customize path creation.
3975     * @returns {Object} Returns `object`.
3976     */
3977    function baseSet(object, path, value, customizer) {
3978      if (!isObject(object)) {
3979        return object;
3980      }
3981      path = castPath(path, object);
3982
3983      var index = -1,
3984          length = path.length,
3985          lastIndex = length - 1,
3986          nested = object;
3987
3988      while (nested != null && ++index < length) {
3989        var key = toKey(path[index]),
3990            newValue = value;
3991
3992        if (index != lastIndex) {
3993          var objValue = nested[key];
3994          newValue = customizer ? customizer(objValue, key, nested) : undefined;
3995          if (newValue === undefined) {
3996            newValue = isObject(objValue)
3997              ? objValue
3998              : (isIndex(path[index + 1]) ? [] : {});
3999          }
4000        }
4001        assignValue(nested, key, newValue);
4002        nested = nested[key];
4003      }
4004      return object;
4005    }
4006
4007    /**
4008     * The base implementation of `setData` without support for hot loop shorting.
4009     *
4010     * @private
4011     * @param {Function} func The function to associate metadata with.
4012     * @param {*} data The metadata.
4013     * @returns {Function} Returns `func`.
4014     */
4015    var baseSetData = !metaMap ? identity : function(func, data) {
4016      metaMap.set(func, data);
4017      return func;
4018    };
4019
4020    /**
4021     * The base implementation of `setToString` without support for hot loop shorting.
4022     *
4023     * @private
4024     * @param {Function} func The function to modify.
4025     * @param {Function} string The `toString` result.
4026     * @returns {Function} Returns `func`.
4027     */
4028    var baseSetToString = !defineProperty ? identity : function(func, string) {
4029      return defineProperty(func, 'toString', {
4030        'configurable': true,
4031        'enumerable': false,
4032        'value': constant(string),
4033        'writable': true
4034      });
4035    };
4036
4037    /**
4038     * The base implementation of `_.shuffle`.
4039     *
4040     * @private
4041     * @param {Array|Object} collection The collection to shuffle.
4042     * @returns {Array} Returns the new shuffled array.
4043     */
4044    function baseShuffle(collection) {
4045      return shuffleSelf(values(collection));
4046    }
4047
4048    /**
4049     * The base implementation of `_.slice` without an iteratee call guard.
4050     *
4051     * @private
4052     * @param {Array} array The array to slice.
4053     * @param {number} [start=0] The start position.
4054     * @param {number} [end=array.length] The end position.
4055     * @returns {Array} Returns the slice of `array`.
4056     */
4057    function baseSlice(array, start, end) {
4058      var index = -1,
4059          length = array.length;
4060
4061      if (start < 0) {
4062        start = -start > length ? 0 : (length + start);
4063      }
4064      end = end > length ? length : end;
4065      if (end < 0) {
4066        end += length;
4067      }
4068      length = start > end ? 0 : ((end - start) >>> 0);
4069      start >>>= 0;
4070
4071      var result = Array(length);
4072      while (++index < length) {
4073        result[index] = array[index + start];
4074      }
4075      return result;
4076    }
4077
4078    /**
4079     * The base implementation of `_.some` without support for iteratee shorthands.
4080     *
4081     * @private
4082     * @param {Array|Object} collection The collection to iterate over.
4083     * @param {Function} predicate The function invoked per iteration.
4084     * @returns {boolean} Returns `true` if any element passes the predicate check,
4085     *  else `false`.
4086     */
4087    function baseSome(collection, predicate) {
4088      var result;
4089
4090      baseEach(collection, function(value, index, collection) {
4091        result = predicate(value, index, collection);
4092        return !result;
4093      });
4094      return !!result;
4095    }
4096
4097    /**
4098     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
4099     * performs a binary search of `array` to determine the index at which `value`
4100     * should be inserted into `array` in order to maintain its sort order.
4101     *
4102     * @private
4103     * @param {Array} array The sorted array to inspect.
4104     * @param {*} value The value to evaluate.
4105     * @param {boolean} [retHighest] Specify returning the highest qualified index.
4106     * @returns {number} Returns the index at which `value` should be inserted
4107     *  into `array`.
4108     */
4109    function baseSortedIndex(array, value, retHighest) {
4110      var low = 0,
4111          high = array == null ? low : array.length;
4112
4113      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
4114        while (low < high) {
4115          var mid = (low + high) >>> 1,
4116              computed = array[mid];
4117
4118          if (computed !== null && !isSymbol(computed) &&
4119              (retHighest ? (computed <= value) : (computed < value))) {
4120            low = mid + 1;
4121          } else {
4122            high = mid;
4123          }
4124        }
4125        return high;
4126      }
4127      return baseSortedIndexBy(array, value, identity, retHighest);
4128    }
4129
4130    /**
4131     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
4132     * which invokes `iteratee` for `value` and each element of `array` to compute
4133     * their sort ranking. The iteratee is invoked with one argument; (value).
4134     *
4135     * @private
4136     * @param {Array} array The sorted array to inspect.
4137     * @param {*} value The value to evaluate.
4138     * @param {Function} iteratee The iteratee invoked per element.
4139     * @param {boolean} [retHighest] Specify returning the highest qualified index.
4140     * @returns {number} Returns the index at which `value` should be inserted
4141     *  into `array`.
4142     */
4143    function baseSortedIndexBy(array, value, iteratee, retHighest) {
4144      value = iteratee(value);
4145
4146      var low = 0,
4147          high = array == null ? 0 : array.length,
4148          valIsNaN = value !== value,
4149          valIsNull = value === null,
4150          valIsSymbol = isSymbol(value),
4151          valIsUndefined = value === undefined;
4152
4153      while (low < high) {
vendor: 12,977 bytes, lines 4154-4556
4154        var mid = nativeFloor((low + high) / 2),
4155            computed = iteratee(array[mid]),
4156            othIsDefined = computed !== undefined,
4157            othIsNull = computed === null,
4158            othIsReflexive = computed === computed,
4159            othIsSymbol = isSymbol(computed);
4160
4161        if (valIsNaN) {
4162          var setLow = retHighest || othIsReflexive;
4163        } else if (valIsUndefined) {
4164          setLow = othIsReflexive && (retHighest || othIsDefined);
4165        } else if (valIsNull) {
4166          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
4167        } else if (valIsSymbol) {
4168          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
4169        } else if (othIsNull || othIsSymbol) {
4170          setLow = false;
4171        } else {
4172          setLow = retHighest ? (computed <= value) : (computed < value);
4173        }
4174        if (setLow) {
4175          low = mid + 1;
4176        } else {
4177          high = mid;
4178        }
4179      }
4180      return nativeMin(high, MAX_ARRAY_INDEX);
4181    }
4182
4183    /**
4184     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
4185     * support for iteratee shorthands.
4186     *
4187     * @private
4188     * @param {Array} array The array to inspect.
4189     * @param {Function} [iteratee] The iteratee invoked per element.
4190     * @returns {Array} Returns the new duplicate free array.
4191     */
4192    function baseSortedUniq(array, iteratee) {
4193      var index = -1,
4194          length = array.length,
4195          resIndex = 0,
4196          result = [];
4197
4198      while (++index < length) {
4199        var value = array[index],
4200            computed = iteratee ? iteratee(value) : value;
4201
4202        if (!index || !eq(computed, seen)) {
4203          var seen = computed;
4204          result[resIndex++] = value === 0 ? 0 : value;
4205        }
4206      }
4207      return result;
4208    }
4209
4210    /**
4211     * The base implementation of `_.toNumber` which doesn't ensure correct
4212     * conversions of binary, hexadecimal, or octal string values.
4213     *
4214     * @private
4215     * @param {*} value The value to process.
4216     * @returns {number} Returns the number.
4217     */
4218    function baseToNumber(value) {
4219      if (typeof value == 'number') {
4220        return value;
4221      }
4222      if (isSymbol(value)) {
4223        return NAN;
4224      }
4225      return +value;
4226    }
4227
4228    /**
4229     * The base implementation of `_.toString` which doesn't convert nullish
4230     * values to empty strings.
4231     *
4232     * @private
4233     * @param {*} value The value to process.
4234     * @returns {string} Returns the string.
4235     */
4236    function baseToString(value) {
4237      // Exit early for strings to avoid a performance hit in some environments.
4238      if (typeof value == 'string') {
4239        return value;
4240      }
4241      if (isArray(value)) {
4242        // Recursively convert values (susceptible to call stack limits).
4243        return arrayMap(value, baseToString) + '';
4244      }
4245      if (isSymbol(value)) {
4246        return symbolToString ? symbolToString.call(value) : '';
4247      }
4248      var result = (value + '');
4249      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
4250    }
4251
4252    /**
4253     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
4254     *
4255     * @private
4256     * @param {Array} array The array to inspect.
4257     * @param {Function} [iteratee] The iteratee invoked per element.
4258     * @param {Function} [comparator] The comparator invoked per element.
4259     * @returns {Array} Returns the new duplicate free array.
4260     */
4261    function baseUniq(array, iteratee, comparator) {
4262      var index = -1,
4263          includes = arrayIncludes,
4264          length = array.length,
4265          isCommon = true,
4266          result = [],
4267          seen = result;
4268
4269      if (comparator) {
4270        isCommon = false;
4271        includes = arrayIncludesWith;
4272      }
4273      else if (length >= LARGE_ARRAY_SIZE) {
4274        var set = iteratee ? null : createSet(array);
4275        if (set) {
4276          return setToArray(set);
4277        }
4278        isCommon = false;
4279        includes = cacheHas;
4280        seen = new SetCache;
4281      }
4282      else {
4283        seen = iteratee ? [] : result;
4284      }
4285      outer:
4286      while (++index < length) {
4287        var value = array[index],
4288            computed = iteratee ? iteratee(value) : value;
4289
4290        value = (comparator || value !== 0) ? value : 0;
4291        if (isCommon && computed === computed) {
4292          var seenIndex = seen.length;
4293          while (seenIndex--) {
4294            if (seen[seenIndex] === computed) {
4295              continue outer;
4296            }
4297          }
4298          if (iteratee) {
4299            seen.push(computed);
4300          }
4301          result.push(value);
4302        }
4303        else if (!includes(seen, computed, comparator)) {
4304          if (seen !== result) {
4305            seen.push(computed);
4306          }
4307          result.push(value);
4308        }
4309      }
4310      return result;
4311    }
4312
4313    /**
4314     * The base implementation of `_.unset`.
4315     *
4316     * @private
4317     * @param {Object} object The object to modify.
4318     * @param {Array|string} path The property path to unset.
4319     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
4320     */
4321    function baseUnset(object, path) {
4322      path = castPath(path, object);
4323      object = parent(object, path);
4324      return object == null || delete object[toKey(last(path))];
4325    }
4326
4327    /**
4328     * The base implementation of `_.update`.
4329     *
4330     * @private
4331     * @param {Object} object The object to modify.
4332     * @param {Array|string} path The path of the property to update.
4333     * @param {Function} updater The function to produce the updated value.
4334     * @param {Function} [customizer] The function to customize path creation.
4335     * @returns {Object} Returns `object`.
4336     */
4337    function baseUpdate(object, path, updater, customizer) {
4338      return baseSet(object, path, updater(baseGet(object, path)), customizer);
4339    }
4340
4341    /**
4342     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
4343     * without support for iteratee shorthands.
4344     *
4345     * @private
4346     * @param {Array} array The array to query.
4347     * @param {Function} predicate The function invoked per iteration.
4348     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
4349     * @param {boolean} [fromRight] Specify iterating from right to left.
4350     * @returns {Array} Returns the slice of `array`.
4351     */
4352    function baseWhile(array, predicate, isDrop, fromRight) {
4353      var length = array.length,
4354          index = fromRight ? length : -1;
4355
4356      while ((fromRight ? index-- : ++index < length) &&
4357        predicate(array[index], index, array)) {}
4358
4359      return isDrop
4360        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
4361        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
4362    }
4363
4364    /**
4365     * The base implementation of `wrapperValue` which returns the result of
4366     * performing a sequence of actions on the unwrapped `value`, where each
4367     * successive action is supplied the return value of the previous.
4368     *
4369     * @private
4370     * @param {*} value The unwrapped value.
4371     * @param {Array} actions Actions to perform to resolve the unwrapped value.
4372     * @returns {*} Returns the resolved value.
4373     */
4374    function baseWrapperValue(value, actions) {
4375      var result = value;
4376      if (result instanceof LazyWrapper) {
4377        result = result.value();
4378      }
4379      return arrayReduce(actions, function(result, action) {
4380        return action.func.apply(action.thisArg, arrayPush([result], action.args));
4381      }, result);
4382    }
4383
4384    /**
4385     * The base implementation of methods like `_.xor`, without support for
4386     * iteratee shorthands, that accepts an array of arrays to inspect.
4387     *
4388     * @private
4389     * @param {Array} arrays The arrays to inspect.
4390     * @param {Function} [iteratee] The iteratee invoked per element.
4391     * @param {Function} [comparator] The comparator invoked per element.
4392     * @returns {Array} Returns the new array of values.
4393     */
4394    function baseXor(arrays, iteratee, comparator) {
4395      var length = arrays.length;
4396      if (length < 2) {
4397        return length ? baseUniq(arrays[0]) : [];
4398      }
4399      var index = -1,
4400          result = Array(length);
4401
4402      while (++index < length) {
4403        var array = arrays[index],
4404            othIndex = -1;
4405
4406        while (++othIndex < length) {
4407          if (othIndex != index) {
4408            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
4409          }
4410        }
4411      }
4412      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
4413    }
4414
4415    /**
4416     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
4417     *
4418     * @private
4419     * @param {Array} props The property identifiers.
4420     * @param {Array} values The property values.
4421     * @param {Function} assignFunc The function to assign values.
4422     * @returns {Object} Returns the new object.
4423     */
4424    function baseZipObject(props, values, assignFunc) {
4425      var index = -1,
4426          length = props.length,
4427          valsLength = values.length,
4428          result = {};
4429
4430      while (++index < length) {
4431        var value = index < valsLength ? values[index] : undefined;
4432        assignFunc(result, props[index], value);
4433      }
4434      return result;
4435    }
4436
4437    /**
4438     * Casts `value` to an empty array if it's not an array like object.
4439     *
4440     * @private
4441     * @param {*} value The value to inspect.
4442     * @returns {Array|Object} Returns the cast array-like object.
4443     */
4444    function castArrayLikeObject(value) {
4445      return isArrayLikeObject(value) ? value : [];
4446    }
4447
4448    /**
4449     * Casts `value` to `identity` if it's not a function.
4450     *
4451     * @private
4452     * @param {*} value The value to inspect.
4453     * @returns {Function} Returns cast function.
4454     */
4455    function castFunction(value) {
4456      return typeof value == 'function' ? value : identity;
4457    }
4458
4459    /**
4460     * Casts `value` to a path array if it's not one.
4461     *
4462     * @private
4463     * @param {*} value The value to inspect.
4464     * @param {Object} [object] The object to query keys on.
4465     * @returns {Array} Returns the cast property path array.
4466     */
4467    function castPath(value, object) {
4468      if (isArray(value)) {
4469        return value;
4470      }
4471      return isKey(value, object) ? [value] : stringToPath(toString(value));
4472    }
4473
4474    /**
4475     * A `baseRest` alias which can be replaced with `identity` by module
4476     * replacement plugins.
4477     *
4478     * @private
4479     * @type {Function}
4480     * @param {Function} func The function to apply a rest parameter to.
4481     * @returns {Function} Returns the new function.
4482     */
4483    var castRest = baseRest;
4484
4485    /**
4486     * Casts `array` to a slice if it's needed.
4487     *
4488     * @private
4489     * @param {Array} array The array to inspect.
4490     * @param {number} start The start position.
4491     * @param {number} [end=array.length] The end position.
4492     * @returns {Array} Returns the cast slice.
4493     */
4494    function castSlice(array, start, end) {
4495      var length = array.length;
4496      end = end === undefined ? length : end;
4497      return (!start && end >= length) ? array : baseSlice(array, start, end);
4498    }
4499
4500    /**
4501     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
4502     *
4503     * @private
4504     * @param {number|Object} id The timer id or timeout object of the timer to clear.
4505     */
4506    var clearTimeout = ctxClearTimeout || function(id) {
4507      return root.clearTimeout(id);
4508    };
4509
4510    /**
4511     * Creates a clone of  `buffer`.
4512     *
4513     * @private
4514     * @param {Buffer} buffer The buffer to clone.
4515     * @param {boolean} [isDeep] Specify a deep clone.
4516     * @returns {Buffer} Returns the cloned buffer.
4517     */
4518    function cloneBuffer(buffer, isDeep) {
4519      if (isDeep) {
4520        return buffer.slice();
4521      }
4522      var length = buffer.length,
4523          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
4524
4525      buffer.copy(result);
4526      return result;
4527    }
4528
4529    /**
4530     * Creates a clone of `arrayBuffer`.
4531     *
4532     * @private
4533     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4534     * @returns {ArrayBuffer} Returns the cloned array buffer.
4535     */
4536    function cloneArrayBuffer(arrayBuffer) {
4537      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4538      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4539      return result;
4540    }
4541
4542    /**
4543     * Creates a clone of `dataView`.
4544     *
4545     * @private
4546     * @param {Object} dataView The data view to clone.
4547     * @param {boolean} [isDeep] Specify a deep clone.
4548     * @returns {Object} Returns the cloned data view.
4549     */
4550    function cloneDataView(dataView, isDeep) {
4551      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4552      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4553    }
4554
4555    /**
4556     * Creates a clone of `
4556map`.
4557     *
4558     * @private
4559     * @param {Object} map The map to clone.
4560     * @param {Function} cloneFunc The function to clone values.
4561     * @param {boolean} [isDeep] Specify a deep clone.
4562     * @returns {Object} Returns the cloned map.
4563     */
4564    function cloneMap(map, isDeep, cloneFunc) {
4565      var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
4566      return arrayReduce(array, addMapEntry, new map.constructor);
4567    }
4568
4569    /**
4570     * Creates a clone of `regexp`.
4571     *
4572     * @private
4573     * @param {Object} regexp The regexp to clone.
4574     * @returns {Object} Returns the cloned regexp.
4575     */
4576    function cloneRegExp(regexp) {
4577      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4578      result.lastIndex = regexp.lastIndex;
4579      return result;
4580    }
4581
4582    /**
4583     * Creates a clone of `set`.
4584     *
4585     * @private
4586     * @param {Object} set The set to clone.
4587     * @param {Function} cloneFunc The function to clone values.
4588     * @param {boolean} [isDeep] Specify a deep clone.
4589     * @returns {Object} Returns the cloned set.
4590     */
4591    function cloneSet(set, isDeep, cloneFunc) {
4592      var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
4593      return arrayReduce(array, addSetEntry, new set.constructor)
vendor: 37,974 bytes, lines 4593-5659
4593;
4594    }
4595
4596    /**
4597     * Creates a clone of the `symbol` object.
4598     *
4599     * @private
4600     * @param {Object} symbol The symbol object to clone.
4601     * @returns {Object} Returns the cloned symbol object.
4602     */
4603    function cloneSymbol(symbol) {
4604      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4605    }
4606
4607    /**
4608     * Creates a clone of `typedArray`.
4609     *
4610     * @private
4611     * @param {Object} typedArray The typed array to clone.
4612     * @param {boolean} [isDeep] Specify a deep clone.
4613     * @returns {Object} Returns the cloned typed array.
4614     */
4615    function cloneTypedArray(typedArray, isDeep) {
4616      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4617      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4618    }
4619
4620    /**
4621     * Compares values to sort them in ascending order.
4622     *
4623     * @private
4624     * @param {*} value The value to compare.
4625     * @param {*} other The other value to compare.
4626     * @returns {number} Returns the sort order indicator for `value`.
4627     */
4628    function compareAscending(value, other) {
4629      if (value !== other) {
4630        var valIsDefined = value !== undefined,
4631            valIsNull = value === null,
4632            valIsReflexive = value === value,
4633            valIsSymbol = isSymbol(value);
4634
4635        var othIsDefined = other !== undefined,
4636            othIsNull = other === null,
4637            othIsReflexive = other === other,
4638            othIsSymbol = isSymbol(other);
4639
4640        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4641            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4642            (valIsNull && othIsDefined && othIsReflexive) ||
4643            (!valIsDefined && othIsReflexive) ||
4644            !valIsReflexive) {
4645          return 1;
4646        }
4647        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4648            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4649            (othIsNull && valIsDefined && valIsReflexive) ||
4650            (!othIsDefined && valIsReflexive) ||
4651            !othIsReflexive) {
4652          return -1;
4653        }
4654      }
4655      return 0;
4656    }
4657
4658    /**
4659     * Used by `_.orderBy` to compare multiple properties of a value to another
4660     * and stable sort them.
4661     *
4662     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4663     * specify an order of "desc" for descending or "asc" for ascending sort order
4664     * of corresponding values.
4665     *
4666     * @private
4667     * @param {Object} object The object to compare.
4668     * @param {Object} other The other object to compare.
4669     * @param {boolean[]|string[]} orders The order to sort by for each property.
4670     * @returns {number} Returns the sort order indicator for `object`.
4671     */
4672    function compareMultiple(object, other, orders) {
4673      var index = -1,
4674          objCriteria = object.criteria,
4675          othCriteria = other.criteria,
4676          length = objCriteria.length,
4677          ordersLength = orders.length;
4678
4679      while (++index < length) {
4680        var result = compareAscending(objCriteria[index], othCriteria[index]);
4681        if (result) {
4682          if (index >= ordersLength) {
4683            return result;
4684          }
4685          var order = orders[index];
4686          return result * (order == 'desc' ? -1 : 1);
4687        }
4688      }
4689      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4690      // that causes it, under certain circumstances, to provide the same value for
4691      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4692      // for more details.
4693      //
4694      // This also ensures a stable sort in V8 and other engines.
4695      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4696      return object.index - other.index;
4697    }
4698
4699    /**
4700     * Creates an array that is the composition of partially applied arguments,
4701     * placeholders, and provided arguments into a single array of arguments.
4702     *
4703     * @private
4704     * @param {Array} args The provided arguments.
4705     * @param {Array} partials The arguments to prepend to those provided.
4706     * @param {Array} holders The `partials` placeholder indexes.
4707     * @params {boolean} [isCurried] Specify composing for a curried function.
4708     * @returns {Array} Returns the new array of composed arguments.
4709     */
4710    function composeArgs(args, partials, holders, isCurried) {
4711      var argsIndex = -1,
4712          argsLength = args.length,
4713          holdersLength = holders.length,
4714          leftIndex = -1,
4715          leftLength = partials.length,
4716          rangeLength = nativeMax(argsLength - holdersLength, 0),
4717          result = Array(leftLength + rangeLength),
4718          isUncurried = !isCurried;
4719
4720      while (++leftIndex < leftLength) {
4721        result[leftIndex] = partials[leftIndex];
4722      }
4723      while (++argsIndex < holdersLength) {
4724        if (isUncurried || argsIndex < argsLength) {
4725          result[holders[argsIndex]] = args[argsIndex];
4726        }
4727      }
4728      while (rangeLength--) {
4729        result[leftIndex++] = args[argsIndex++];
4730      }
4731      return result;
4732    }
4733
4734    /**
4735     * This function is like `composeArgs` except that the arguments composition
4736     * is tailored for `_.partialRight`.
4737     *
4738     * @private
4739     * @param {Array} args The provided arguments.
4740     * @param {Array} partials The arguments to append to those provided.
4741     * @param {Array} holders The `partials` placeholder indexes.
4742     * @params {boolean} [isCurried] Specify composing for a curried function.
4743     * @returns {Array} Returns the new array of composed arguments.
4744     */
4745    function composeArgsRight(args, partials, holders, isCurried) {
4746      var argsIndex = -1,
4747          argsLength = args.length,
4748          holdersIndex = -1,
4749          holdersLength = holders.length,
4750          rightIndex = -1,
4751          rightLength = partials.length,
4752          rangeLength = nativeMax(argsLength - holdersLength, 0),
4753          result = Array(rangeLength + rightLength),
4754          isUncurried = !isCurried;
4755
4756      while (++argsIndex < rangeLength) {
4757        result[argsIndex] = args[argsIndex];
4758      }
4759      var offset = argsIndex;
4760      while (++rightIndex < rightLength) {
4761        result[offset + rightIndex] = partials[rightIndex];
4762      }
4763      while (++holdersIndex < holdersLength) {
4764        if (isUncurried || argsIndex < argsLength) {
4765          result[offset + holders[holdersIndex]] = args[argsIndex++];
4766        }
4767      }
4768      return result;
4769    }
4770
4771    /**
4772     * Copies the values of `source` to `array`.
4773     *
4774     * @private
4775     * @param {Array} source The array to copy values from.
4776     * @param {Array} [array=[]] The array to copy values to.
4777     * @returns {Array} Returns `array`.
4778     */
4779    function copyArray(source, array) {
4780      var index = -1,
4781          length = source.length;
4782
4783      array || (array = Array(length));
4784      while (++index < length) {
4785        array[index] = source[index];
4786      }
4787      return array;
4788    }
4789
4790    /**
4791     * Copies properties of `source` to `object`.
4792     *
4793     * @private
4794     * @param {Object} source The object to copy properties from.
4795     * @param {Array} props The property identifiers to copy.
4796     * @param {Object} [object={}] The object to copy properties to.
4797     * @param {Function} [customizer] The function to customize copied values.
4798     * @returns {Object} Returns `object`.
4799     */
4800    function copyObject(source, props, object, customizer) {
4801      var isNew = !object;
4802      object || (object = {});
4803
4804      var index = -1,
4805          length = props.length;
4806
4807      while (++index < length) {
4808        var key = props[index];
4809
4810        var newValue = customizer
4811          ? customizer(object[key], source[key], key, object, source)
4812          : undefined;
4813
4814        if (newValue === undefined) {
4815          newValue = source[key];
4816        }
4817        if (isNew) {
4818          baseAssignValue(object, key, newValue);
4819        } else {
4820          assignValue(object, key, newValue);
4821        }
4822      }
4823      return object;
4824    }
4825
4826    /**
4827     * Copies own symbols of `source` to `object`.
4828     *
4829     * @private
4830     * @param {Object} source The object to copy symbols from.
4831     * @param {Object} [object={}] The object to copy symbols to.
4832     * @returns {Object} Returns `object`.
4833     */
4834    function copySymbols(source, object) {
4835      return copyObject(source, getSymbols(source), object);
4836    }
4837
4838    /**
4839     * Copies own and inherited symbols of `source` to `object`.
4840     *
4841     * @private
4842     * @param {Object} source The object to copy symbols from.
4843     * @param {Object} [object={}] The object to copy symbols to.
4844     * @returns {Object} Returns `object`.
4845     */
4846    function copySymbolsIn(source, object) {
4847      return copyObject(source, getSymbolsIn(source), object);
4848    }
4849
4850    /**
4851     * Creates a function like `_.groupBy`.
4852     *
4853     * @private
4854     * @param {Function} setter The function to set accumulator values.
4855     * @param {Function} [initializer] The accumulator object initializer.
4856     * @returns {Function} Returns the new aggregator function.
4857     */
4858    function createAggregator(setter, initializer) {
4859      return function(collection, iteratee) {
4860        var func = isArray(collection) ? arrayAggregator : baseAggregator,
4861            accumulator = initializer ? initializer() : {};
4862
4863        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
4864      };
4865    }
4866
4867    /**
4868     * Creates a function like `_.assign`.
4869     *
4870     * @private
4871     * @param {Function} assigner The function to assign values.
4872     * @returns {Function} Returns the new assigner function.
4873     */
4874    function createAssigner(assigner) {
4875      return baseRest(function(object, sources) {
4876        var index = -1,
4877            length = sources.length,
4878            customizer = length > 1 ? sources[length - 1] : undefined,
4879            guard = length > 2 ? sources[2] : undefined;
4880
4881        customizer = (assigner.length > 3 && typeof customizer == 'function')
4882          ? (length--, customizer)
4883          : undefined;
4884
4885        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4886          customizer = length < 3 ? undefined : customizer;
4887          length = 1;
4888        }
4889        object = Object(object);
4890        while (++index < length) {
4891          var source = sources[index];
4892          if (source) {
4893            assigner(object, source, index, customizer);
4894          }
4895        }
4896        return object;
4897      });
4898    }
4899
4900    /**
4901     * Creates a `baseEach` or `baseEachRight` function.
4902     *
4903     * @private
4904     * @param {Function} eachFunc The function to iterate over a collection.
4905     * @param {boolean} [fromRight] Specify iterating from right to left.
4906     * @returns {Function} Returns the new base function.
4907     */
4908    function createBaseEach(eachFunc, fromRight) {
4909      return function(collection, iteratee) {
4910        if (collection == null) {
4911          return collection;
4912        }
4913        if (!isArrayLike(collection)) {
4914          return eachFunc(collection, iteratee);
4915        }
4916        var length = collection.length,
4917            index = fromRight ? length : -1,
4918            iterable = Object(collection);
4919
4920        while ((fromRight ? index-- : ++index < length)) {
4921          if (iteratee(iterable[index], index, iterable) === false) {
4922            break;
4923          }
4924        }
4925        return collection;
4926      };
4927    }
4928
4929    /**
4930     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4931     *
4932     * @private
4933     * @param {boolean} [fromRight] Specify iterating from right to left.
4934     * @returns {Function} Returns the new base function.
4935     */
4936    function createBaseFor(fromRight) {
4937      return function(object, iteratee, keysFunc) {
4938        var index = -1,
4939            iterable = Object(object),
4940            props = keysFunc(object),
4941            length = props.length;
4942
4943        while (length--) {
4944          var key = props[fromRight ? length : ++index];
4945          if (iteratee(iterable[key], key, iterable) === false) {
4946            break;
4947          }
4948        }
4949        return object;
4950      };
4951    }
4952
4953    /**
4954     * Creates a function that wraps `func` to invoke it with the optional `this`
4955     * binding of `thisArg`.
4956     *
4957     * @private
4958     * @param {Function} func The function to wrap.
4959     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
4960     * @param {*} [thisArg] The `this` binding of `func`.
4961     * @returns {Function} Returns the new wrapped function.
4962     */
4963    function createBind(func, bitmask, thisArg) {
4964      var isBind = bitmask & WRAP_BIND_FLAG,
4965          Ctor = createCtor(func);
4966
4967      function wrapper() {
4968        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4969        return fn.apply(isBind ? thisArg : this, arguments);
4970      }
4971      return wrapper;
4972    }
4973
4974    /**
4975     * Creates a function like `_.lowerFirst`.
4976     *
4977     * @private
4978     * @param {string} methodName The name of the `String` case method to use.
4979     * @returns {Function} Returns the new case function.
4980     */
4981    function createCaseFirst(methodName) {
4982      return function(string) {
4983        string = toString(string);
4984
4985        var strSymbols = hasUnicode(string)
4986          ? stringToArray(string)
4987          : undefined;
4988
4989        var chr = strSymbols
4990          ? strSymbols[0]
4991          : string.charAt(0);
4992
4993        var trailing = strSymbols
4994          ? castSlice(strSymbols, 1).join('')
4995          : string.slice(1);
4996
4997        return chr[methodName]() + trailing;
4998      };
4999    }
5000
5001    /**
5002     * Creates a function like `_.camelCase`.
5003     *
5004     * @private
5005     * @param {Function} callback The function to combine each word.
5006     * @returns {Function} Returns the new compounder function.
5007     */
5008    function createCompounder(callback) {
5009      return function(string) {
5010        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
5011      };
5012    }
5013
5014    /**
5015     * Creates a function that produces an instance of `Ctor` regardless of
5016     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5017     *
5018     * @private
5019     * @param {Function} Ctor The constructor to wrap.
5020     * @returns {Function} Returns the new wrapped function.
5021     */
5022    function createCtor(Ctor) {
5023      return function() {
5024        // Use a `switch` statement to work with class constructors. See
5025        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5026        // for more details.
5027        var args = arguments;
5028        switch (args.length) {
5029          case 0: return new Ctor;
5030          case 1: return new Ctor(args[0]);
5031          case 2: return new Ctor(args[0], args[1]);
5032          case 3: return new Ctor(args[0], args[1], args[2]);
5033          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5034          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5035          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5036          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5037        }
5038        var thisBinding = baseCreate(Ctor.prototype),
5039            result = Ctor.apply(thisBinding, args);
5040
5041        // Mimic the constructor's `return` behavior.
5042        // See https://es5.github.io/#x13.2.2 for more details.
5043        return isObject(result) ? result : thisBinding;
5044      };
5045    }
5046
5047    /**
5048     * Creates a function that wraps `func` to enable currying.
5049     *
5050     * @private
5051     * @param {Function} func The function to wrap.
5052     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5053     * @param {number} arity The arity of `func`.
5054     * @returns {Function} Returns the new wrapped function.
5055     */
5056    function createCurry(func, bitmask, arity) {
5057      var Ctor = createCtor(func);
5058
5059      function wrapper() {
5060        var length = arguments.length,
5061            args = Array(length),
5062            index = length,
5063            placeholder = getHolder(wrapper);
5064
5065        while (index--) {
5066          args[index] = arguments[index];
5067        }
5068        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5069          ? []
5070          : replaceHolders(args, placeholder);
5071
5072        length -= holders.length;
5073        if (length < arity) {
5074          return createRecurry(
5075            func, bitmask, createHybrid, wrapper.placeholder, undefined,
5076            args, holders, undefined, undefined, arity - length);
5077        }
5078        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5079        return apply(fn, this, args);
5080      }
5081      return wrapper;
5082    }
5083
5084    /**
5085     * Creates a `_.find` or `_.findLast` function.
5086     *
5087     * @private
5088     * @param {Function} findIndexFunc The function to find the collection index.
5089     * @returns {Function} Returns the new find function.
5090     */
5091    function createFind(findIndexFunc) {
5092      return function(collection, predicate, fromIndex) {
5093        var iterable = Object(collection);
5094        if (!isArrayLike(collection)) {
5095          var iteratee = getIteratee(predicate, 3);
5096          collection = keys(collection);
5097          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
5098        }
5099        var index = findIndexFunc(collection, predicate, fromIndex);
5100        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
5101      };
5102    }
5103
5104    /**
5105     * Creates a `_.flow` or `_.flowRight` function.
5106     *
5107     * @private
5108     * @param {boolean} [fromRight] Specify iterating from right to left.
5109     * @returns {Function} Returns the new flow function.
5110     */
5111    function createFlow(fromRight) {
5112      return flatRest(function(funcs) {
5113        var length = funcs.length,
5114            index = length,
5115            prereq = LodashWrapper.prototype.thru;
5116
5117        if (fromRight) {
5118          funcs.reverse();
5119        }
5120        while (index--) {
5121          var func = funcs[index];
5122          if (typeof func != 'function') {
5123            throw new TypeError(FUNC_ERROR_TEXT);
5124          }
5125          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
5126            var wrapper = new LodashWrapper([], true);
5127          }
5128        }
5129        index = wrapper ? index : length;
5130        while (++index < length) {
5131          func = funcs[index];
5132
5133          var funcName = getFuncName(func),
5134              data = funcName == 'wrapper' ? getData(func) : undefined;
5135
5136          if (data && isLaziable(data[0]) &&
5137                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
5138                !data[4].length && data[9] == 1
5139              ) {
5140            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
5141          } else {
5142            wrapper = (func.length == 1 && isLaziable(func))
5143              ? wrapper[funcName]()
5144              : wrapper.thru(func);
5145          }
5146        }
5147        return function() {
5148          var args = arguments,
5149              value = args[0];
5150
5151          if (wrapper && args.length == 1 && isArray(value)) {
5152            return wrapper.plant(value).value();
5153          }
5154          var index = 0,
5155              result = length ? funcs[index].apply(this, args) : value;
5156
5157          while (++index < length) {
5158            result = funcs[index].call(this, result);
5159          }
5160          return result;
5161        };
5162      });
5163    }
5164
5165    /**
5166     * Creates a function that wraps `func` to invoke it with optional `this`
5167     * binding of `thisArg`, partial application, and currying.
5168     *
5169     * @private
5170     * @param {Function|string} func The function or method name to wrap.
5171     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5172     * @param {*} [thisArg] The `this` binding of `func`.
5173     * @param {Array} [partials] The arguments to prepend to those provided to
5174     *  the new function.
5175     * @param {Array} [holders] The `partials` placeholder indexes.
5176     * @param {Array} [partialsRight] The arguments to append to those provided
5177     *  to the new function.
5178     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5179     * @param {Array} [argPos] The argument positions of the new function.
5180     * @param {number} [ary] The arity cap of `func`.
5181     * @param {number} [arity] The arity of `func`.
5182     * @returns {Function} Returns the new wrapped function.
5183     */
5184    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5185      var isAry = bitmask & WRAP_ARY_FLAG,
5186          isBind = bitmask & WRAP_BIND_FLAG,
5187          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
5188          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
5189          isFlip = bitmask & WRAP_FLIP_FLAG,
5190          Ctor = isBindKey ? undefined : createCtor(func);
5191
5192      function wrapper() {
5193        var length = arguments.length,
5194            args = Array(length),
5195            index = length;
5196
5197        while (index--) {
5198          args[index] = arguments[index];
5199        }
5200        if (isCurried) {
5201          var placeholder = getHolder(wrapper),
5202              holdersCount = countHolders(args, placeholder);
5203        }
5204        if (partials) {
5205          args = composeArgs(args, partials, holders, isCurried);
5206        }
5207        if (partialsRight) {
5208          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
5209        }
5210        length -= holdersCount;
5211        if (isCurried && length < arity) {
5212          var newHolders = replaceHolders(args, placeholder);
5213          return createRecurry(
5214            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
5215            args, newHolders, argPos, ary, arity - length
5216          );
5217        }
5218        var thisBinding = isBind ? thisArg : this,
5219            fn = isBindKey ? thisBinding[func] : func;
5220
5221        length = args.length;
5222        if (argPos) {
5223          args = reorder(args, argPos);
5224        } else if (isFlip && length > 1) {
5225          args.reverse();
5226        }
5227        if (isAry && ary < length) {
5228          args.length = ary;
5229        }
5230        if (this && this !== root && this instanceof wrapper) {
5231          fn = Ctor || createCtor(fn);
5232        }
5233        return fn.apply(thisBinding, args);
5234      }
5235      return wrapper;
5236    }
5237
5238    /**
5239     * Creates a function like `_.invertBy`.
5240     *
5241     * @private
5242     * @param {Function} setter The function to set accumulator values.
5243     * @param {Function} toIteratee The function to resolve iteratees.
5244     * @returns {Function} Returns the new inverter function.
5245     */
5246    function createInverter(setter, toIteratee) {
5247      return function(object, iteratee) {
5248        return baseInverter(object, setter, toIteratee(iteratee), {});
5249      };
5250    }
5251
5252    /**
5253     * Creates a function that performs a mathematical operation on two values.
5254     *
5255     * @private
5256     * @param {Function} operator The function to perform the operation.
5257     * @param {number} [defaultValue] The value used for `undefined` arguments.
5258     * @returns {Function} Returns the new mathematical operation function.
5259     */
5260    function createMathOperation(operator, defaultValue) {
5261      return function(value, other) {
5262        var result;
5263        if (value === undefined && other === undefined) {
5264          return defaultValue;
5265        }
5266        if (value !== undefined) {
5267          result = value;
5268        }
5269        if (other !== undefined) {
5270          if (result === undefined) {
5271            return other;
5272          }
5273          if (typeof value == 'string' || typeof other == 'string') {
5274            value = baseToString(value);
5275            other = baseToString(other);
5276          } else {
5277            value = baseToNumber(value);
5278            other = baseToNumber(other);
5279          }
5280          result = operator(value, other);
5281        }
5282        return result;
5283      };
5284    }
5285
5286    /**
5287     * Creates a function like `_.over`.
5288     *
5289     * @private
5290     * @param {Function} arrayFunc The function to iterate over iteratees.
5291     * @returns {Function} Returns the new over function.
5292     */
5293    function createOver(arrayFunc) {
5294      return flatRest(function(iteratees) {
5295        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
5296        return baseRest(function(args) {
5297          var thisArg = this;
5298          return arrayFunc(iteratees, function(iteratee) {
5299            return apply(iteratee, thisArg, args);
5300          });
5301        });
5302      });
5303    }
5304
5305    /**
5306     * Creates the padding for `string` based on `length`. The `chars` string
5307     * is truncated if the number of characters exceeds `length`.
5308     *
5309     * @private
5310     * @param {number} length The padding length.
5311     * @param {string} [chars=' '] The string used as padding.
5312     * @returns {string} Returns the padding for `string`.
5313     */
5314    function createPadding(length, chars) {
5315      chars = chars === undefined ? ' ' : baseToString(chars);
5316
5317      var charsLength = chars.length;
5318      if (charsLength < 2) {
5319        return charsLength ? baseRepeat(chars, length) : chars;
5320      }
5321      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
5322      return hasUnicode(chars)
5323        ? castSlice(stringToArray(result), 0, length).join('')
5324        : result.slice(0, length);
5325    }
5326
5327    /**
5328     * Creates a function that wraps `func` to invoke it with the `this` binding
5329     * of `thisArg` and `partials` prepended to the arguments it receives.
5330     *
5331     * @private
5332     * @param {Function} func The function to wrap.
5333     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5334     * @param {*} thisArg The `this` binding of `func`.
5335     * @param {Array} partials The arguments to prepend to those provided to
5336     *  the new function.
5337     * @returns {Function} Returns the new wrapped function.
5338     */
5339    function createPartial(func, bitmask, thisArg, partials) {
5340      var isBind = bitmask & WRAP_BIND_FLAG,
5341          Ctor = createCtor(func);
5342
5343      function wrapper() {
5344        var argsIndex = -1,
5345            argsLength = arguments.length,
5346            leftIndex = -1,
5347            leftLength = partials.length,
5348            args = Array(leftLength + argsLength),
5349            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5350
5351        while (++leftIndex < leftLength) {
5352          args[leftIndex] = partials[leftIndex];
5353        }
5354        while (argsLength--) {
5355          args[leftIndex++] = arguments[++argsIndex];
5356        }
5357        return apply(fn, isBind ? thisArg : this, args);
5358      }
5359      return wrapper;
5360    }
5361
5362    /**
5363     * Creates a `_.range` or `_.rangeRight` function.
5364     *
5365     * @private
5366     * @param {boolean} [fromRight] Specify iterating from right to left.
5367     * @returns {Function} Returns the new range function.
5368     */
5369    function createRange(fromRight) {
5370      return function(start, end, step) {
5371        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
5372          end = step = undefined;
5373        }
5374        // Ensure the sign of `-0` is preserved.
5375        start = toFinite(start);
5376        if (end === undefined) {
5377          end = start;
5378          start = 0;
5379        } else {
5380          end = toFinite(end);
5381        }
5382        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
5383        return baseRange(start, end, step, fromRight);
5384      };
5385    }
5386
5387    /**
5388     * Creates a function that performs a relational operation on two values.
5389     *
5390     * @private
5391     * @param {Function} operator The function to perform the operation.
5392     * @returns {Function} Returns the new relational operation function.
5393     */
5394    function createRelationalOperation(operator) {
5395      return function(value, other) {
5396        if (!(typeof value == 'string' && typeof other == 'string')) {
5397          value = toNumber(value);
5398          other = toNumber(other);
5399        }
5400        return operator(value, other);
5401      };
5402    }
5403
5404    /**
5405     * Creates a function that wraps `func` to continue currying.
5406     *
5407     * @private
5408     * @param {Function} func The function to wrap.
5409     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
5410     * @param {Function} wrapFunc The function to create the `func` wrapper.
5411     * @param {*} placeholder The placeholder value.
5412     * @param {*} [thisArg] The `this` binding of `func`.
5413     * @param {Array} [partials] The arguments to prepend to those provided to
5414     *  the new function.
5415     * @param {Array} [holders] The `partials` placeholder indexes.
5416     * @param {Array} [argPos] The argument positions of the new function.
5417     * @param {number} [ary] The arity cap of `func`.
5418     * @param {number} [arity] The arity of `func`.
5419     * @returns {Function} Returns the new wrapped function.
5420     */
5421    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5422      var isCurry = bitmask & WRAP_CURRY_FLAG,
5423          newHolders = isCurry ? holders : undefined,
5424          newHoldersRight = isCurry ? undefined : holders,
5425          newPartials = isCurry ? partials : undefined,
5426          newPartialsRight = isCurry ? undefined : partials;
5427
5428      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
5429      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
5430
5431      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
5432        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
5433      }
5434      var newData = [
5435        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
5436        newHoldersRight, argPos, ary, arity
5437      ];
5438
5439      var result = wrapFunc.apply(undefined, newData);
5440      if (isLaziable(func)) {
5441        setData(result, newData);
5442      }
5443      result.placeholder = placeholder;
5444      return setWrapToString(result, func, bitmask);
5445    }
5446
5447    /**
5448     * Creates a function like `_.round`.
5449     *
5450     * @private
5451     * @param {string} methodName The name of the `Math` method to use when rounding.
5452     * @returns {Function} Returns the new round function.
5453     */
5454    function createRound(methodName) {
5455      var func = Math[methodName];
5456      return function(number, precision) {
5457        number = toNumber(number);
5458        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
5459        if (precision) {
5460          // Shift with exponential notation to avoid floating-point issues.
5461          // See [MDN](https://mdn.io/round#Examples) for more details.
5462          var pair = (toString(number) + 'e').split('e'),
5463              value = func(pair[0] + 'e' + (+pair[1] + precision));
5464
5465          pair = (toString(value) + 'e').split('e');
5466          return +(pair[0] + 'e' + (+pair[1] - precision));
5467        }
5468        return func(number);
5469      };
5470    }
5471
5472    /**
5473     * Creates a set object of `values`.
5474     *
5475     * @private
5476     * @param {Array} values The values to add to the set.
5477     * @returns {Object} Returns the new set.
5478     */
5479    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
5480      return new Set(values);
5481    };
5482
5483    /**
5484     * Creates a `_.toPairs` or `_.toPairsIn` function.
5485     *
5486     * @private
5487     * @param {Function} keysFunc The function to get the keys of a given object.
5488     * @returns {Function} Returns the new pairs function.
5489     */
5490    function createToPairs(keysFunc) {
5491      return function(object) {
5492        var tag = getTag(object);
5493        if (tag == mapTag) {
5494          return mapToArray(object);
5495        }
5496        if (tag == setTag) {
5497          return setToPairs(object);
5498        }
5499        return baseToPairs(object, keysFunc(object));
5500      };
5501    }
5502
5503    /**
5504     * Creates a function that either curries or invokes `func` with optional
5505     * `this` binding and partially applied arguments.
5506     *
5507     * @private
5508     * @param {Function|string} func The function or method name to wrap.
5509     * @param {number} bitmask The bitmask flags.
5510     *    1 - `_.bind`
5511     *    2 - `_.bindKey`
5512     *    4 - `_.curry` or `_.curryRight` of a bound function
5513     *    8 - `_.curry`
5514     *   16 - `_.curryRight`
5515     *   32 - `_.partial`
5516     *   64 - `_.partialRight`
5517     *  128 - `_.rearg`
5518     *  256 - `_.ary`
5519     *  512 - `_.flip`
5520     * @param {*} [thisArg] The `this` binding of `func`.
5521     * @param {Array} [partials] The arguments to be partially applied.
5522     * @param {Array} [holders] The `partials` placeholder indexes.
5523     * @param {Array} [argPos] The argument positions of the new function.
5524     * @param {number} [ary] The arity cap of `func`.
5525     * @param {number} [arity] The arity of `func`.
5526     * @returns {Function} Returns the new wrapped function.
5527     */
5528    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5529      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
5530      if (!isBindKey && typeof func != 'function') {
5531        throw new TypeError(FUNC_ERROR_TEXT);
5532      }
5533      var length = partials ? partials.length : 0;
5534      if (!length) {
5535        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
5536        partials = holders = undefined;
5537      }
5538      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5539      arity = arity === undefined ? arity : toInteger(arity);
5540      length -= holders ? holders.length : 0;
5541
5542      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
5543        var partialsRight = partials,
5544            holdersRight = holders;
5545
5546        partials = holders = undefined;
5547      }
5548      var data = isBindKey ? undefined : getData(func);
5549
5550      var newData = [
5551        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5552        argPos, ary, arity
5553      ];
5554
5555      if (data) {
5556        mergeData(newData, data);
5557      }
5558      func = newData[0];
5559      bitmask = newData[1];
5560      thisArg = newData[2];
5561      partials = newData[3];
5562      holders = newData[4];
5563      arity = newData[9] = newData[9] === undefined
5564        ? (isBindKey ? 0 : func.length)
5565        : nativeMax(newData[9] - length, 0);
5566
5567      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
5568        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
5569      }
5570      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
5571        var result = createBind(func, bitmask, thisArg);
5572      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
5573        result = createCurry(func, bitmask, arity);
5574      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
5575        result = createPartial(func, bitmask, thisArg, partials);
5576      } else {
5577        result = createHybrid.apply(undefined, newData);
5578      }
5579      var setter = data ? baseSetData : setData;
5580      return setWrapToString(setter(result, newData), func, bitmask);
5581    }
5582
5583    /**
5584     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
5585     * of source objects to the destination object for all destination properties
5586     * that resolve to `undefined`.
5587     *
5588     * @private
5589     * @param {*} objValue The destination value.
5590     * @param {*} srcValue The source value.
5591     * @param {string} key The key of the property to assign.
5592     * @param {Object} object The parent object of `objValue`.
5593     * @returns {*} Returns the value to assign.
5594     */
5595    function customDefaultsAssignIn(objValue, srcValue, key, object) {
5596      if (objValue === undefined ||
5597          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
5598        return srcValue;
5599      }
5600      return objValue;
5601    }
5602
5603    /**
5604     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
5605     * objects into destination objects that are passed thru.
5606     *
5607     * @private
5608     * @param {*} objValue The destination value.
5609     * @param {*} srcValue The source value.
5610     * @param {string} key The key of the property to merge.
5611     * @param {Object} object The parent object of `objValue`.
5612     * @param {Object} source The parent object of `srcValue`.
5613     * @param {Object} [stack] Tracks traversed source values and their merged
5614     *  counterparts.
5615     * @returns {*} Returns the value to assign.
5616     */
5617    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
5618      if (isObject(objValue) && isObject(srcValue)) {
5619        // Recursively merge objects and arrays (susceptible to call stack limits).
5620        stack.set(srcValue, objValue);
5621        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
5622        stack['delete'](srcValue);
5623      }
5624      return objValue;
5625    }
5626
5627    /**
5628     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
5629     * objects.
5630     *
5631     * @private
5632     * @param {*} value The value to inspect.
5633     * @param {string} key The key of the property to inspect.
5634     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
5635     */
5636    function customOmitClone(value) {
5637      return isPlainObject(value) ? undefined : value;
5638    }
5639
5640    /**
5641     * A specialized version of `baseIsEqualDeep` for arrays with support for
5642     * partial deep comparisons.
5643     *
5644     * @private
5645     * @param {Array} array The array to compare.
5646     * @param {Array} other The other array to compare.
5647     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5648     * @param {Function} customizer The function to customize comparisons.
5649     * @param {Function} equalFunc The function to determine equivalents of values.
5650     * @param {Object} stack Tracks traversed `array` and `other` objects.
5651     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5652     */
5653    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
5654      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
5655          arrLength = array.length,
5656          othLength = other.length;
5657
5658      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5659        return false;
vendor: 1,304 bytes, lines 5660-5698
5660      }
5661      // Assume cyclic values are equal.
5662      var stacked = stack.get(array);
5663      if (stacked && stack.get(other)) {
5664        return stacked == other;
5665      }
5666      var index = -1,
5667          result = true,
5668          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
5669
5670      stack.set(array, other);
5671      stack.set(other, array);
5672
5673      // Ignore non-index properties.
5674      while (++index < arrLength) {
5675        var arrValue = array[index],
5676            othValue = other[index];
5677
5678        if (customizer) {
5679          var compared = isPartial
5680            ? customizer(othValue, arrValue, index, other, array, stack)
5681            : customizer(arrValue, othValue, index, array, other, stack);
5682        }
5683        if (compared !== undefined) {
5684          if (compared) {
5685            continue;
5686          }
5687          result = false;
5688          break;
5689        }
5690        // Recursively compare arrays (susceptible to call stack limits).
5691        if (seen) {
5692          if (!arraySome(other, function(othValue, othIndex) {
5693                if (!cacheHas(seen, othIndex) &&
5694                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
5695                  return seen.push(othIndex);
5696                }
5697              })) {
5698            result = false;
vendor: 4,179 bytes, lines 5699-5810
5699            break;
5700          }
5701        } else if (!(
5702              arrValue === othValue ||
5703                equalFunc(arrValue, othValue, bitmask, customizer, stack)
5704            )) {
5705          result = false;
5706          break;
5707        }
5708      }
5709      stack['delete'](array);
5710      stack['delete'](other);
5711      return result;
5712    }
5713
5714    /**
5715     * A specialized version of `baseIsEqualDeep` for comparing objects of
5716     * the same `toStringTag`.
5717     *
5718     * **Note:** This function only supports comparing values with tags of
5719     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5720     *
5721     * @private
5722     * @param {Object} object The object to compare.
5723     * @param {Object} other The other object to compare.
5724     * @param {string} tag The `toStringTag` of the objects to compare.
5725     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5726     * @param {Function} customizer The function to customize comparisons.
5727     * @param {Function} equalFunc The function to determine equivalents of values.
5728     * @param {Object} stack Tracks traversed `object` and `other` objects.
5729     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5730     */
5731    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
5732      switch (tag) {
5733        case dataViewTag:
5734          if ((object.byteLength != other.byteLength) ||
5735              (object.byteOffset != other.byteOffset)) {
5736            return false;
5737          }
5738          object = object.buffer;
5739          other = other.buffer;
5740
5741        case arrayBufferTag:
5742          if ((object.byteLength != other.byteLength) ||
5743              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5744            return false;
5745          }
5746          return true;
5747
5748        case boolTag:
5749        case dateTag:
5750        case numberTag:
5751          // Coerce booleans to `1` or `0` and dates to milliseconds.
5752          // Invalid dates are coerced to `NaN`.
5753          return eq(+object, +other);
5754
5755        case errorTag:
5756          return object.name == other.name && object.message == other.message;
5757
5758        case regexpTag:
5759        case stringTag:
5760          // Coerce regexes to strings and treat strings, primitives and objects,
5761          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
5762          // for more details.
5763          return object == (other + '');
5764
5765        case mapTag:
5766          var convert = mapToArray;
5767
5768        case setTag:
5769          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
5770          convert || (convert = setToArray);
5771
5772          if (object.size != other.size && !isPartial) {
5773            return false;
5774          }
5775          // Assume cyclic values are equal.
5776          var stacked = stack.get(object);
5777          if (stacked) {
5778            return stacked == other;
5779          }
5780          bitmask |= COMPARE_UNORDERED_FLAG;
5781
5782          // Recursively compare objects (susceptible to call stack limits).
5783          stack.set(object, other);
5784          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
5785          stack['delete'](object);
5786          return result;
5787
5788        case symbolTag:
5789          if (symbolValueOf) {
5790            return symbolValueOf.call(object) == symbolValueOf.call(other);
5791          }
5792      }
5793      return false;
5794    }
5795
5796    /**
5797     * A specialized version of `baseIsEqualDeep` for objects with support for
5798     * partial deep comparisons.
5799     *
5800     * @private
5801     * @param {Object} object The object to compare.
5802     * @param {Object} other The other object to compare.
5803     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
5804     * @param {Function} customizer The function to customize comparisons.
5805     * @param {Function} equalFunc The function to determine equivalents of values.
5806     * @param {Object} stack Tracks traversed `object` and `other` objects.
5807     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5808     */
5809    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
5810      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
vendor: 1,367 bytes, lines 5811-5851
5811          objProps = getAllKeys(object),
5812          objLength = objProps.length,
5813          othProps = getAllKeys(other),
5814          othLength = othProps.length;
5815
5816      if (objLength != othLength && !isPartial) {
5817        return false;
5818      }
5819      var index = objLength;
5820      while (index--) {
5821        var key = objProps[index];
5822        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
5823          return false;
5824        }
5825      }
5826      // Assume cyclic values are equal.
5827      var stacked = stack.get(object);
5828      if (stacked && stack.get(other)) {
5829        return stacked == other;
5830      }
5831      var result = true;
5832      stack.set(object, other);
5833      stack.set(other, object);
5834
5835      var skipCtor = isPartial;
5836      while (++index < objLength) {
5837        key = objProps[index];
5838        var objValue = object[key],
5839            othValue = other[key];
5840
5841        if (customizer) {
5842          var compared = isPartial
5843            ? customizer(othValue, objValue, key, other, object, stack)
5844            : customizer(objValue, othValue, key, object, other, stack);
5845        }
5846        // Recursively compare objects (susceptible to call stack limits).
5847        if (!(compared === undefined
5848              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
5849              : compared
5850            )) {
5851          result = false;
vendor: 8,175 bytes, lines 5852-6117
5852          break;
5853        }
5854        skipCtor || (skipCtor = key == 'constructor');
5855      }
5856      if (result && !skipCtor) {
5857        var objCtor = object.constructor,
5858            othCtor = other.constructor;
5859
5860        // Non `Object` object instances with different constructors are not equal.
5861        if (objCtor != othCtor &&
5862            ('constructor' in object && 'constructor' in other) &&
5863            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5864              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5865          result = false;
5866        }
5867      }
5868      stack['delete'](object);
5869      stack['delete'](other);
5870      return result;
5871    }
5872
5873    /**
5874     * A specialized version of `baseRest` which flattens the rest array.
5875     *
5876     * @private
5877     * @param {Function} func The function to apply a rest parameter to.
5878     * @returns {Function} Returns the new function.
5879     */
5880    function flatRest(func) {
5881      return setToString(overRest(func, undefined, flatten), func + '');
5882    }
5883
5884    /**
5885     * Creates an array of own enumerable property names and symbols of `object`.
5886     *
5887     * @private
5888     * @param {Object} object The object to query.
5889     * @returns {Array} Returns the array of property names and symbols.
5890     */
5891    function getAllKeys(object) {
5892      return baseGetAllKeys(object, keys, getSymbols);
5893    }
5894
5895    /**
5896     * Creates an array of own and inherited enumerable property names and
5897     * symbols of `object`.
5898     *
5899     * @private
5900     * @param {Object} object The object to query.
5901     * @returns {Array} Returns the array of property names and symbols.
5902     */
5903    function getAllKeysIn(object) {
5904      return baseGetAllKeys(object, keysIn, getSymbolsIn);
5905    }
5906
5907    /**
5908     * Gets metadata for `func`.
5909     *
5910     * @private
5911     * @param {Function} func The function to query.
5912     * @returns {*} Returns the metadata for `func`.
5913     */
5914    var getData = !metaMap ? noop : function(func) {
5915      return metaMap.get(func);
5916    };
5917
5918    /**
5919     * Gets the name of `func`.
5920     *
5921     * @private
5922     * @param {Function} func The function to query.
5923     * @returns {string} Returns the function name.
5924     */
5925    function getFuncName(func) {
5926      var result = (func.name + ''),
5927          array = realNames[result],
5928          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5929
5930      while (length--) {
5931        var data = array[length],
5932            otherFunc = data.func;
5933        if (otherFunc == null || otherFunc == func) {
5934          return data.name;
5935        }
5936      }
5937      return result;
5938    }
5939
5940    /**
5941     * Gets the argument placeholder value for `func`.
5942     *
5943     * @private
5944     * @param {Function} func The function to inspect.
5945     * @returns {*} Returns the placeholder value.
5946     */
5947    function getHolder(func) {
5948      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5949      return object.placeholder;
5950    }
5951
5952    /**
5953     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5954     * this function returns the custom method, otherwise it returns `baseIteratee`.
5955     * If arguments are provided, the chosen function is invoked with them and
5956     * its result is returned.
5957     *
5958     * @private
5959     * @param {*} [value] The value to convert to an iteratee.
5960     * @param {number} [arity] The arity of the created iteratee.
5961     * @returns {Function} Returns the chosen function or its result.
5962     */
5963    function getIteratee() {
5964      var result = lodash.iteratee || iteratee;
5965      result = result === iteratee ? baseIteratee : result;
5966      return arguments.length ? result(arguments[0], arguments[1]) : result;
5967    }
5968
5969    /**
5970     * Gets the data for `map`.
5971     *
5972     * @private
5973     * @param {Object} map The map to query.
5974     * @param {string} key The reference key.
5975     * @returns {*} Returns the map data.
5976     */
5977    function getMapData(map, key) {
5978      var data = map.__data__;
5979      return isKeyable(key)
5980        ? data[typeof key == 'string' ? 'string' : 'hash']
5981        : data.map;
5982    }
5983
5984    /**
5985     * Gets the property names, values, and compare flags of `object`.
5986     *
5987     * @private
5988     * @param {Object} object The object to query.
5989     * @returns {Array} Returns the match data of `object`.
5990     */
5991    function getMatchData(object) {
5992      var result = keys(object),
5993          length = result.length;
5994
5995      while (length--) {
5996        var key = result[length],
5997            value = object[key];
5998
5999        result[length] = [key, value, isStrictComparable(value)];
6000      }
6001      return result;
6002    }
6003
6004    /**
6005     * Gets the native function at `key` of `object`.
6006     *
6007     * @private
6008     * @param {Object} object The object to query.
6009     * @param {string} key The key of the method to get.
6010     * @returns {*} Returns the function if it's native, else `undefined`.
6011     */
6012    function getNative(object, key) {
6013      var value = getValue(object, key);
6014      return baseIsNative(value) ? value : undefined;
6015    }
6016
6017    /**
6018     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6019     *
6020     * @private
6021     * @param {*} value The value to query.
6022     * @returns {string} Returns the raw `toStringTag`.
6023     */
6024    function getRawTag(value) {
6025      var isOwn = hasOwnProperty.call(value, symToStringTag),
6026          tag = value[symToStringTag];
6027
6028      try {
6029        value[symToStringTag] = undefined;
6030        var unmasked = true;
6031      } catch (e) {}
6032
6033      var result = nativeObjectToString.call(value);
6034      if (unmasked) {
6035        if (isOwn) {
6036          value[symToStringTag] = tag;
6037        } else {
6038          delete value[symToStringTag];
6039        }
6040      }
6041      return result;
6042    }
6043
6044    /**
6045     * Creates an array of the own enumerable symbols of `object`.
6046     *
6047     * @private
6048     * @param {Object} object The object to query.
6049     * @returns {Array} Returns the array of symbols.
6050     */
6051    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
6052      if (object == null) {
6053        return [];
6054      }
6055      object = Object(object);
6056      return arrayFilter(nativeGetSymbols(object), function(symbol) {
6057        return propertyIsEnumerable.call(object, symbol);
6058      });
6059    };
6060
6061    /**
6062     * Creates an array of the own and inherited enumerable symbols of `object`.
6063     *
6064     * @private
6065     * @param {Object} object The object to query.
6066     * @returns {Array} Returns the array of symbols.
6067     */
6068    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
6069      var result = [];
6070      while (object) {
6071        arrayPush(result, getSymbols(object));
6072        object = getPrototype(object);
6073      }
6074      return result;
6075    };
6076
6077    /**
6078     * Gets the `toStringTag` of `value`.
6079     *
6080     * @private
6081     * @param {*} value The value to query.
6082     * @returns {string} Returns the `toStringTag`.
6083     */
6084    var getTag = baseGetTag;
6085
6086    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
6087    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
6088        (Map && getTag(new Map) != mapTag) ||
6089        (Promise && getTag(Promise.resolve()) != promiseTag) ||
6090        (Set && getTag(new Set) != setTag) ||
6091        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
6092      getTag = function(value) {
6093        var result = baseGetTag(value),
6094            Ctor = result == objectTag ? value.constructor : undefined,
6095            ctorString = Ctor ? toSource(Ctor) : '';
6096
6097        if (ctorString) {
6098          switch (ctorString) {
6099            case dataViewCtorString: return dataViewTag;
6100            case mapCtorString: return mapTag;
6101            case promiseCtorString: return promiseTag;
6102            case setCtorString: return setTag;
6103            case weakMapCtorString: return weakMapTag;
6104          }
6105        }
6106        return result;
6107      };
6108    }
6109
6110    /**
6111     * Gets the view, applying any `transforms` to the `start` and `end` positions.
6112     *
6113     * @private
6114     * @param {number} start The start of the view.
6115     * @param {number} end The end of the view.
6116     * @param {Array} transforms The transformations to apply to the view.
6117     * @returns {Object}
vendor: 2,210 bytes, lines 6117-6190
6117 Returns an object containing the `start` and `end`
6118     *  positions of the view.
6119     */
6120    function getView(start, end, transforms) {
6121      var index = -1,
6122          length = transforms.length;
6123
6124      while (++index < length) {
6125        var data = transforms[index],
6126            size = data.size;
6127
6128        switch (data.type) {
6129          case 'drop':      start += size; break;
6130          case 'dropRight': end -= size; break;
6131          case 'take':      end = nativeMin(end, start + size); break;
6132          case 'takeRight': start = nativeMax(start, end - size); break;
6133        }
6134      }
6135      return { 'start': start, 'end': end };
6136    }
6137
6138    /**
6139     * Extracts wrapper details from the `source` body comment.
6140     *
6141     * @private
6142     * @param {string} source The source to inspect.
6143     * @returns {Array} Returns the wrapper details.
6144     */
6145    function getWrapDetails(source) {
6146      var match = source.match(reWrapDetails);
6147      return match ? match[1].split(reSplitDetails) : [];
6148    }
6149
6150    /**
6151     * Checks if `path` exists on `object`.
6152     *
6153     * @private
6154     * @param {Object} object The object to query.
6155     * @param {Array|string} path The path to check.
6156     * @param {Function} hasFunc The function to check properties.
6157     * @returns {boolean} Returns `true` if `path` exists, else `false`.
6158     */
6159    function hasPath(object, path, hasFunc) {
6160      path = castPath(path, object);
6161
6162      var index = -1,
6163          length = path.length,
6164          result = false;
6165
6166      while (++index < length) {
6167        var key = toKey(path[index]);
6168        if (!(result = object != null && hasFunc(object, key))) {
6169          break;
6170        }
6171        object = object[key];
6172      }
6173      if (result || ++index != length) {
6174        return result;
6175      }
6176      length = object == null ? 0 : object.length;
6177      return !!length && isLength(length) && isIndex(key, length) &&
6178        (isArray(object) || isArguments(object));
6179    }
6180
6181    /**
6182     * Initializes an array clone.
6183     *
6184     * @private
6185     * @param {Array} array The array to clone.
6186     * @returns {Array} Returns the initialized clone.
6187     */
6188    function initCloneArray(array) {
6189      var length = array.length,
6190          result = 
vendor: 3,696 bytes, lines 6190-6304
6190array.constructor(length);
6191
6192      // Add properties assigned by `RegExp#exec`.
6193      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
6194        result.index = array.index;
6195        result.input = array.input;
6196      }
6197      return result;
6198    }
6199
6200    /**
6201     * Initializes an object clone.
6202     *
6203     * @private
6204     * @param {Object} object The object to clone.
6205     * @returns {Object} Returns the initialized clone.
6206     */
6207    function initCloneObject(object) {
6208      return (typeof object.constructor == 'function' && !isPrototype(object))
6209        ? baseCreate(getPrototype(object))
6210        : {};
6211    }
6212
6213    /**
6214     * Initializes an object clone based on its `toStringTag`.
6215     *
6216     * **Note:** This function only supports cloning values with tags of
6217     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6218     *
6219     * @private
6220     * @param {Object} object The object to clone.
6221     * @param {string} tag The `toStringTag` of the object to clone.
6222     * @param {Function} cloneFunc The function to clone values.
6223     * @param {boolean} [isDeep] Specify a deep clone.
6224     * @returns {Object} Returns the initialized clone.
6225     */
6226    function initCloneByTag(object, tag, cloneFunc, isDeep) {
6227      var Ctor = object.constructor;
6228      switch (tag) {
6229        case arrayBufferTag:
6230          return cloneArrayBuffer(object);
6231
6232        case boolTag:
6233        case dateTag:
6234          return new Ctor(+object);
6235
6236        case dataViewTag:
6237          return cloneDataView(object, isDeep);
6238
6239        case float32Tag: case float64Tag:
6240        case int8Tag: case int16Tag: case int32Tag:
6241        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
6242          return cloneTypedArray(object, isDeep);
6243
6244        case mapTag:
6245          return cloneMap(object, isDeep, cloneFunc);
6246
6247        case numberTag:
6248        case stringTag:
6249          return new Ctor(object);
6250
6251        case regexpTag:
6252          return cloneRegExp(object);
6253
6254        case setTag:
6255          return cloneSet(object, isDeep, cloneFunc);
6256
6257        case symbolTag:
6258          return cloneSymbol(object);
6259      }
6260    }
6261
6262    /**
6263     * Inserts wrapper `details` in a comment at the top of the `source` body.
6264     *
6265     * @private
6266     * @param {string} source The source to modify.
6267     * @returns {Array} details The details to insert.
6268     * @returns {string} Returns the modified source.
6269     */
6270    function insertWrapDetails(source, details) {
6271      var length = details.length;
6272      if (!length) {
6273        return source;
6274      }
6275      var lastIndex = length - 1;
6276      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
6277      details = details.join(length > 2 ? ', ' : ' ');
6278      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
6279    }
6280
6281    /**
6282     * Checks if `value` is a flattenable `arguments` object or array.
6283     *
6284     * @private
6285     * @param {*} value The value to check.
6286     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
6287     */
6288    function isFlattenable(value) {
6289      return isArray(value) || isArguments(value) ||
6290        !!(spreadableSymbol && value && value[spreadableSymbol]);
6291    }
6292
6293    /**
6294     * Checks if `value` is a valid array-like index.
6295     *
6296     * @private
6297     * @param {*} value The value to check.
6298     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
6299     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
6300     */
6301    function isIndex(value, length) {
6302      length = length == null ? MAX_SAFE_INTEGER : length;
6303      return !!length &&
6304        (typeof value == 'number' || reIsUint.test(value)) &&
vendor: 10,952 bytes, lines 6305-6640
6305        (value > -1 && value % 1 == 0 && value < length);
6306    }
6307
6308    /**
6309     * Checks if the given arguments are from an iteratee call.
6310     *
6311     * @private
6312     * @param {*} value The potential iteratee value argument.
6313     * @param {*} index The potential iteratee index or key argument.
6314     * @param {*} object The potential iteratee object argument.
6315     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
6316     *  else `false`.
6317     */
6318    function isIterateeCall(value, index, object) {
6319      if (!isObject(object)) {
6320        return false;
6321      }
6322      var type = typeof index;
6323      if (type == 'number'
6324            ? (isArrayLike(object) && isIndex(index, object.length))
6325            : (type == 'string' && index in object)
6326          ) {
6327        return eq(object[index], value);
6328      }
6329      return false;
6330    }
6331
6332    /**
6333     * Checks if `value` is a property name and not a property path.
6334     *
6335     * @private
6336     * @param {*} value The value to check.
6337     * @param {Object} [object] The object to query keys on.
6338     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
6339     */
6340    function isKey(value, object) {
6341      if (isArray(value)) {
6342        return false;
6343      }
6344      var type = typeof value;
6345      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
6346          value == null || isSymbol(value)) {
6347        return true;
6348      }
6349      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
6350        (object != null && value in Object(object));
6351    }
6352
6353    /**
6354     * Checks if `value` is suitable for use as unique object key.
6355     *
6356     * @private
6357     * @param {*} value The value to check.
6358     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
6359     */
6360    function isKeyable(value) {
6361      var type = typeof value;
6362      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
6363        ? (value !== '__proto__')
6364        : (value === null);
6365    }
6366
6367    /**
6368     * Checks if `func` has a lazy counterpart.
6369     *
6370     * @private
6371     * @param {Function} func The function to check.
6372     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
6373     *  else `false`.
6374     */
6375    function isLaziable(func) {
6376      var funcName = getFuncName(func),
6377          other = lodash[funcName];
6378
6379      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
6380        return false;
6381      }
6382      if (func === other) {
6383        return true;
6384      }
6385      var data = getData(other);
6386      return !!data && func === data[0];
6387    }
6388
6389    /**
6390     * Checks if `func` has its source masked.
6391     *
6392     * @private
6393     * @param {Function} func The function to check.
6394     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
6395     */
6396    function isMasked(func) {
6397      return !!maskSrcKey && (maskSrcKey in func);
6398    }
6399
6400    /**
6401     * Checks if `func` is capable of being masked.
6402     *
6403     * @private
6404     * @param {*} value The value to check.
6405     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
6406     */
6407    var isMaskable = coreJsData ? isFunction : stubFalse;
6408
6409    /**
6410     * Checks if `value` is likely a prototype object.
6411     *
6412     * @private
6413     * @param {*} value The value to check.
6414     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
6415     */
6416    function isPrototype(value) {
6417      var Ctor = value && value.constructor,
6418          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
6419
6420      return value === proto;
6421    }
6422
6423    /**
6424     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
6425     *
6426     * @private
6427     * @param {*} value The value to check.
6428     * @returns {boolean} Returns `true` if `value` if suitable for strict
6429     *  equality comparisons, else `false`.
6430     */
6431    function isStrictComparable(value) {
6432      return value === value && !isObject(value);
6433    }
6434
6435    /**
6436     * A specialized version of `matchesProperty` for source values suitable
6437     * for strict equality comparisons, i.e. `===`.
6438     *
6439     * @private
6440     * @param {string} key The key of the property to get.
6441     * @param {*} srcValue The value to match.
6442     * @returns {Function} Returns the new spec function.
6443     */
6444    function matchesStrictComparable(key, srcValue) {
6445      return function(object) {
6446        if (object == null) {
6447          return false;
6448        }
6449        return object[key] === srcValue &&
6450          (srcValue !== undefined || (key in Object(object)));
6451      };
6452    }
6453
6454    /**
6455     * A specialized version of `_.memoize` which clears the memoized function's
6456     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
6457     *
6458     * @private
6459     * @param {Function} func The function to have its output memoized.
6460     * @returns {Function} Returns the new memoized function.
6461     */
6462    function memoizeCapped(func) {
6463      var result = memoize(func, function(key) {
6464        if (cache.size === MAX_MEMOIZE_SIZE) {
6465          cache.clear();
6466        }
6467        return key;
6468      });
6469
6470      var cache = result.cache;
6471      return result;
6472    }
6473
6474    /**
6475     * Merges the function metadata of `source` into `data`.
6476     *
6477     * Merging metadata reduces the number of wrappers used to invoke a function.
6478     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
6479     * may be applied regardless of execution order. Methods like `_.ary` and
6480     * `_.rearg` modify function arguments, making the order in which they are
6481     * executed important, preventing the merging of metadata. However, we make
6482     * an exception for a safe combined case where curried functions have `_.ary`
6483     * and or `_.rearg` applied.
6484     *
6485     * @private
6486     * @param {Array} data The destination metadata.
6487     * @param {Array} source The source metadata.
6488     * @returns {Array} Returns `data`.
6489     */
6490    function mergeData(data, source) {
6491      var bitmask = data[1],
6492          srcBitmask = source[1],
6493          newBitmask = bitmask | srcBitmask,
6494          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
6495
6496      var isCombo =
6497        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
6498        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
6499        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
6500
6501      // Exit early if metadata can't be merged.
6502      if (!(isCommon || isCombo)) {
6503        return data;
6504      }
6505      // Use source `thisArg` if available.
6506      if (srcBitmask & WRAP_BIND_FLAG) {
6507        data[2] = source[2];
6508        // Set when currying a bound function.
6509        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
6510      }
6511      // Compose partial arguments.
6512      var value = source[3];
6513      if (value) {
6514        var partials = data[3];
6515        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
6516        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
6517      }
6518      // Compose partial right arguments.
6519      value = source[5];
6520      if (value) {
6521        partials = data[5];
6522        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
6523        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
6524      }
6525      // Use source `argPos` if available.
6526      value = source[7];
6527      if (value) {
6528        data[7] = value;
6529      }
6530      // Use source `ary` if it's smaller.
6531      if (srcBitmask & WRAP_ARY_FLAG) {
6532        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
6533      }
6534      // Use source `arity` if one is not provided.
6535      if (data[9] == null) {
6536        data[9] = source[9];
6537      }
6538      // Use source `func` and merge bitmasks.
6539      data[0] = source[0];
6540      data[1] = newBitmask;
6541
6542      return data;
6543    }
6544
6545    /**
6546     * This function is like
6547     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
6548     * except that it includes inherited enumerable properties.
6549     *
6550     * @private
6551     * @param {Object} object The object to query.
6552     * @returns {Array} Returns the array of property names.
6553     */
6554    function nativeKeysIn(object) {
6555      var result = [];
6556      if (object != null) {
6557        for (var key in Object(object)) {
6558          result.push(key);
6559        }
6560      }
6561      return result;
6562    }
6563
6564    /**
6565     * Converts `value` to a string using `Object.prototype.toString`.
6566     *
6567     * @private
6568     * @param {*} value The value to convert.
6569     * @returns {string} Returns the converted string.
6570     */
6571    function objectToString(value) {
6572      return nativeObjectToString.call(value);
6573    }
6574
6575    /**
6576     * A specialized version of `baseRest` which transforms the rest array.
6577     *
6578     * @private
6579     * @param {Function} func The function to apply a rest parameter to.
6580     * @param {number} [start=func.length-1] The start position of the rest parameter.
6581     * @param {Function} transform The rest array transform.
6582     * @returns {Function} Returns the new function.
6583     */
6584    function overRest(func, start, transform) {
6585      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
6586      return function() {
6587        var args = arguments,
6588            index = -1,
6589            length = nativeMax(args.length - start, 0),
6590            array = Array(length);
6591
6592        while (++index < length) {
6593          array[index] = args[start + index];
6594        }
6595        index = -1;
6596        var otherArgs = Array(start + 1);
6597        while (++index < start) {
6598          otherArgs[index] = args[index];
6599        }
6600        otherArgs[start] = transform(array);
6601        return apply(func, this, otherArgs);
6602      };
6603    }
6604
6605    /**
6606     * Gets the parent value at `path` of `object`.
6607     *
6608     * @private
6609     * @param {Object} object The object to query.
6610     * @param {Array} path The path to get the parent value of.
6611     * @returns {*} Returns the parent value.
6612     */
6613    function parent(object, path) {
6614      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
6615    }
6616
6617    /**
6618     * Reorder `array` according to the specified indexes where the element at
6619     * the first index is assigned as the first element, the element at
6620     * the second index is assigned as the second element, and so on.
6621     *
6622     * @private
6623     * @param {Array} array The array to reorder.
6624     * @param {Array} indexes The arranged array indexes.
6625     * @returns {Array} Returns `array`.
6626     */
6627    function reorder(array, indexes) {
6628      var arrLength = array.length,
6629          length = nativeMin(indexes.length, arrLength),
6630          oldArray = copyArray(array);
6631
6632      while (length--) {
6633        var index = indexes[length];
6634        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
6635      }
6636      return array;
6637    }
6638
6639    /**
6640     * 
6640Sets metadata for `func`.
6641     *
6642     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
6643     * period of time, it will trip its breaker and transition to an identity
6644     * function to avoid garbage collection pauses in V8. See
6645     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6646     * for more details.
6647     *
6648     * @private
6649     * @param {Function} func The function to associate metadata with.
6650     * @param {*} data The metadata.
6651     * @returns {Function} Returns `func`.
6652     */
6653    var setData = shortOut(baseSetData);
6654
6655    /**
6656     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
6657     *
6658     * @private
6659     * @param {Function} func The function to delay.
6660     * @param {number} wait The number of milliseconds to delay invocation.
6661     * @returns {number|Object} Returns the timer id or timeout object.
6662     */
6663    var setTimeout = ctxSetTimeout || function(func, wait) {
6664      return root.setTimeout(func, wait);
6665    };
6666
6667    /**
6668     * Sets the `toString` method of `func` to return `string`.
6669     *
6670     * @private
6671     * @param {Function} func The function to modify.
6672     * @param {Function} string The `toString` result.
6673     * @returns {Function} Returns `func`.
6674     */
6675    var setToString = shortOut(baseSetToString);
6676
6677    /**
6678     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
6679     * with wrapper details in a comment at the top of the source body.
6680     *
6681     * @private
6682     * @param {Function} wrapper The function to modify.
6683     * @param {Function} reference The reference function.
6684     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6685     * @returns {Function} Returns `wrapper`.
6686     */
6687    function setWrapToString(wrapper, reference, bitmask) {
6688      var source = (reference + '');
6689      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
6690    }
6691
6692    /**
6693     * Creates a function that'll short out and invoke `identity` instead
6694     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
6695     * milliseconds.
6696     *
6697     * @private
6698     * @param {Function} func The function to restrict.
6699     * @returns {Function} Returns the new shortable function.
6700     */
6701    function shortOut(func) {
6702      var count = 0,
6703          lastCalled = 0;
6704
6705      return function() {
6706        var stamp = nativeNow(),
6707            remaining = HOT_SPAN - (stamp - lastCalled);
6708
6709        lastCalled = stamp;
6710        if (remaining > 0) {
6711          if (++count >= HOT_COUNT) {
6712            return arguments[0];
6713          }
6714        } else {
6715          count = 0;
6716        }
6717        return func.apply(undefined, arguments);
6718      };
6719    }
6720
6721    /**
6722     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
6723     *
6724     * @private
6725     * @param {Array} array The array to shuffle.
6726     * @param {number} [size=array.length] The size of `array`.
6727     * @returns {Array} Returns `array`.
6728     */
6729    function shuffleSelf(array, size) {
6730      var index = -1,
6731          length = array.length,
6732          lastIndex = length - 1;
6733
6734      size = size === undefined ? length : size;
6735      while (++index < size) {
6736        var rand = baseRandom(index, lastIndex),
6737            value = array[rand];
6738
6739        array[rand] = array[index];
6740        array[index] = value;
6741      }
6742      array.length = size;
6743      return array;
6744    }
6745
6746    /**
6747     * Converts `string` to a property path array.
6748     *
6749     * @private
6750     * @param {string} string The string to convert.
6751     * @returns {Array} Returns the property path array.
6752     */
6753    var stringToPath = memoizeCapped(function(string) {
6754      var result = [];
6755      if (reLeadingDot.test(string)) {
6756        result.push('');
6757      }
6758      string.replace(rePropName, function(match, number, quote, string) {
6759        result.push(quote ? s
vendor: 70,687 bytes, lines 6759-9073
6759tring.replace(reEscapeChar, '$1') : (number || match));
6760      });
6761      return result;
6762    });
6763
6764    /**
6765     * Converts `value` to a string key if it's not a string or symbol.
6766     *
6767     * @private
6768     * @param {*} value The value to inspect.
6769     * @returns {string|symbol} Returns the key.
6770     */
6771    function toKey(value) {
6772      if (typeof value == 'string' || isSymbol(value)) {
6773        return value;
6774      }
6775      var result = (value + '');
6776      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6777    }
6778
6779    /**
6780     * Converts `func` to its source code.
6781     *
6782     * @private
6783     * @param {Function} func The function to convert.
6784     * @returns {string} Returns the source code.
6785     */
6786    function toSource(func) {
6787      if (func != null) {
6788        try {
6789          return funcToString.call(func);
6790        } catch (e) {}
6791        try {
6792          return (func + '');
6793        } catch (e) {}
6794      }
6795      return '';
6796    }
6797
6798    /**
6799     * Updates wrapper `details` based on `bitmask` flags.
6800     *
6801     * @private
6802     * @returns {Array} details The details to modify.
6803     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6804     * @returns {Array} Returns `details`.
6805     */
6806    function updateWrapDetails(details, bitmask) {
6807      arrayEach(wrapFlags, function(pair) {
6808        var value = '_.' + pair[0];
6809        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
6810          details.push(value);
6811        }
6812      });
6813      return details.sort();
6814    }
6815
6816    /**
6817     * Creates a clone of `wrapper`.
6818     *
6819     * @private
6820     * @param {Object} wrapper The wrapper to clone.
6821     * @returns {Object} Returns the cloned wrapper.
6822     */
6823    function wrapperClone(wrapper) {
6824      if (wrapper instanceof LazyWrapper) {
6825        return wrapper.clone();
6826      }
6827      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6828      result.__actions__ = copyArray(wrapper.__actions__);
6829      result.__index__  = wrapper.__index__;
6830      result.__values__ = wrapper.__values__;
6831      return result;
6832    }
6833
6834    /*------------------------------------------------------------------------*/
6835
6836    /**
6837     * Creates an array of elements split into groups the length of `size`.
6838     * If `array` can't be split evenly, the final chunk will be the remaining
6839     * elements.
6840     *
6841     * @static
6842     * @memberOf _
6843     * @since 3.0.0
6844     * @category Array
6845     * @param {Array} array The array to process.
6846     * @param {number} [size=1] The length of each chunk
6847     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6848     * @returns {Array} Returns the new array of chunks.
6849     * @example
6850     *
6851     * _.chunk(['a', 'b', 'c', 'd'], 2);
6852     * // => [['a', 'b'], ['c', 'd']]
6853     *
6854     * _.chunk(['a', 'b', 'c', 'd'], 3);
6855     * // => [['a', 'b', 'c'], ['d']]
6856     */
6857    function chunk(array, size, guard) {
6858      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6859        size = 1;
6860      } else {
6861        size = nativeMax(toInteger(size), 0);
6862      }
6863      var length = array == null ? 0 : array.length;
6864      if (!length || size < 1) {
6865        return [];
6866      }
6867      var index = 0,
6868          resIndex = 0,
6869          result = Array(nativeCeil(length / size));
6870
6871      while (index < length) {
6872        result[resIndex++] = baseSlice(array, index, (index += size));
6873      }
6874      return result;
6875    }
6876
6877    /**
6878     * Creates an array with all falsey values removed. The values `false`, `null`,
6879     * `0`, `""`, `undefined`, and `NaN` are falsey.
6880     *
6881     * @static
6882     * @memberOf _
6883     * @since 0.1.0
6884     * @category Array
6885     * @param {Array} array The array to compact.
6886     * @returns {Array} Returns the new array of filtered values.
6887     * @example
6888     *
6889     * _.compact([0, 1, false, 2, '', 3]);
6890     * // => [1, 2, 3]
6891     */
6892    function compact(array) {
6893      var index = -1,
6894          length = array == null ? 0 : array.length,
6895          resIndex = 0,
6896          result = [];
6897
6898      while (++index < length) {
6899        var value = array[index];
6900        if (value) {
6901          result[resIndex++] = value;
6902        }
6903      }
6904      return result;
6905    }
6906
6907    /**
6908     * Creates a new array concatenating `array` with any additional arrays
6909     * and/or values.
6910     *
6911     * @static
6912     * @memberOf _
6913     * @since 4.0.0
6914     * @category Array
6915     * @param {Array} array The array to concatenate.
6916     * @param {...*} [values] The values to concatenate.
6917     * @returns {Array} Returns the new concatenated array.
6918     * @example
6919     *
6920     * var array = [1];
6921     * var other = _.concat(array, 2, [3], [[4]]);
6922     *
6923     * console.log(other);
6924     * // => [1, 2, 3, [4]]
6925     *
6926     * console.log(array);
6927     * // => [1]
6928     */
6929    function concat() {
6930      var length = arguments.length;
6931      if (!length) {
6932        return [];
6933      }
6934      var args = Array(length - 1),
6935          array = arguments[0],
6936          index = length;
6937
6938      while (index--) {
6939        args[index - 1] = arguments[index];
6940      }
6941      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
6942    }
6943
6944    /**
6945     * Creates an array of `array` values not included in the other given arrays
6946     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
6947     * for equality comparisons. The order and references of result values are
6948     * determined by the first array.
6949     *
6950     * **Note:** Unlike `_.pullAll`, this method returns a new array.
6951     *
6952     * @static
6953     * @memberOf _
6954     * @since 0.1.0
6955     * @category Array
6956     * @param {Array} array The array to inspect.
6957     * @param {...Array} [values] The values to exclude.
6958     * @returns {Array} Returns the new array of filtered values.
6959     * @see _.without, _.xor
6960     * @example
6961     *
6962     * _.difference([2, 1], [2, 3]);
6963     * // => [1]
6964     */
6965    var difference = baseRest(function(array, values) {
6966      return isArrayLikeObject(array)
6967        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6968        : [];
6969    });
6970
6971    /**
6972     * This method is like `_.difference` except that it accepts `iteratee` which
6973     * is invoked for each element of `array` and `values` to generate the criterion
6974     * by which they're compared. The order and references of result values are
6975     * determined by the first array. The iteratee is invoked with one argument:
6976     * (value).
6977     *
6978     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
6979     *
6980     * @static
6981     * @memberOf _
6982     * @since 4.0.0
6983     * @category Array
6984     * @param {Array} array The array to inspect.
6985     * @param {...Array} [values] The values to exclude.
6986     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
6987     * @returns {Array} Returns the new array of filtered values.
6988     * @example
6989     *
6990     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
6991     * // => [1.2]
6992     *
6993     * // The `_.property` iteratee shorthand.
6994     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
6995     * // => [{ 'x': 2 }]
6996     */
6997    var differenceBy = baseRest(function(array, values) {
6998      var iteratee = last(values);
6999      if (isArrayLikeObject(iteratee)) {
7000        iteratee = undefined;
7001      }
7002      return isArrayLikeObject(array)
7003        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
7004        : [];
7005    });
7006
7007    /**
7008     * This method is like `_.difference` except that it accepts `comparator`
7009     * which is invoked to compare elements of `array` to `values`. The order and
7010     * references of result values are determined by the first array. The comparator
7011     * is invoked with two arguments: (arrVal, othVal).
7012     *
7013     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
7014     *
7015     * @static
7016     * @memberOf _
7017     * @since 4.0.0
7018     * @category Array
7019     * @param {Array} array The array to inspect.
7020     * @param {...Array} [values] The values to exclude.
7021     * @param {Function} [comparator] The comparator invoked per element.
7022     * @returns {Array} Returns the new array of filtered values.
7023     * @example
7024     *
7025     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7026     *
7027     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
7028     * // => [{ 'x': 2, 'y': 1 }]
7029     */
7030    var differenceWith = baseRest(function(array, values) {
7031      var comparator = last(values);
7032      if (isArrayLikeObject(comparator)) {
7033        comparator = undefined;
7034      }
7035      return isArrayLikeObject(array)
7036        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
7037        : [];
7038    });
7039
7040    /**
7041     * Creates a slice of `array` with `n` elements dropped from the beginning.
7042     *
7043     * @static
7044     * @memberOf _
7045     * @since 0.5.0
7046     * @category Array
7047     * @param {Array} array The array to query.
7048     * @param {number} [n=1] The number of elements to drop.
7049     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7050     * @returns {Array} Returns the slice of `array`.
7051     * @example
7052     *
7053     * _.drop([1, 2, 3]);
7054     * // => [2, 3]
7055     *
7056     * _.drop([1, 2, 3], 2);
7057     * // => [3]
7058     *
7059     * _.drop([1, 2, 3], 5);
7060     * // => []
7061     *
7062     * _.drop([1, 2, 3], 0);
7063     * // => [1, 2, 3]
7064     */
7065    function drop(array, n, guard) {
7066      var length = array == null ? 0 : array.length;
7067      if (!length) {
7068        return [];
7069      }
7070      n = (guard || n === undefined) ? 1 : toInteger(n);
7071      return baseSlice(array, n < 0 ? 0 : n, length);
7072    }
7073
7074    /**
7075     * Creates a slice of `array` with `n` elements dropped from the end.
7076     *
7077     * @static
7078     * @memberOf _
7079     * @since 3.0.0
7080     * @category Array
7081     * @param {Array} array The array to query.
7082     * @param {number} [n=1] The number of elements to drop.
7083     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7084     * @returns {Array} Returns the slice of `array`.
7085     * @example
7086     *
7087     * _.dropRight([1, 2, 3]);
7088     * // => [1, 2]
7089     *
7090     * _.dropRight([1, 2, 3], 2);
7091     * // => [1]
7092     *
7093     * _.dropRight([1, 2, 3], 5);
7094     * // => []
7095     *
7096     * _.dropRight([1, 2, 3], 0);
7097     * // => [1, 2, 3]
7098     */
7099    function dropRight(array, n, guard) {
7100      var length = array == null ? 0 : array.length;
7101      if (!length) {
7102        return [];
7103      }
7104      n = (guard || n === undefined) ? 1 : toInteger(n);
7105      n = length - n;
7106      return baseSlice(array, 0, n < 0 ? 0 : n);
7107    }
7108
7109    /**
7110     * Creates a slice of `array` excluding elements dropped from the end.
7111     * Elements are dropped until `predicate` returns falsey. The predicate is
7112     * invoked with three arguments: (value, index, array).
7113     *
7114     * @static
7115     * @memberOf _
7116     * @since 3.0.0
7117     * @category Array
7118     * @param {Array} array The array to query.
7119     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7120     * @returns {Array} Returns the slice of `array`.
7121     * @example
7122     *
7123     * var users = [
7124     *   { 'user': 'barney',  'active': true },
7125     *   { 'user': 'fred',    'active': false },
7126     *   { 'user': 'pebbles', 'active': false }
7127     * ];
7128     *
7129     * _.dropRightWhile(users, function(o) { return !o.active; });
7130     * // => objects for ['barney']
7131     *
7132     * // The `_.matches` iteratee shorthand.
7133     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
7134     * // => objects for ['barney', 'fred']
7135     *
7136     * // The `_.matchesProperty` iteratee shorthand.
7137     * _.dropRightWhile(users, ['active', false]);
7138     * // => objects for ['barney']
7139     *
7140     * // The `_.property` iteratee shorthand.
7141     * _.dropRightWhile(users, 'active');
7142     * // => objects for ['barney', 'fred', 'pebbles']
7143     */
7144    function dropRightWhile(array, predicate) {
7145      return (array && array.length)
7146        ? baseWhile(array, getIteratee(predicate, 3), true, true)
7147        : [];
7148    }
7149
7150    /**
7151     * Creates a slice of `array` excluding elements dropped from the beginning.
7152     * Elements are dropped until `predicate` returns falsey. The predicate is
7153     * invoked with three arguments: (value, index, array).
7154     *
7155     * @static
7156     * @memberOf _
7157     * @since 3.0.0
7158     * @category Array
7159     * @param {Array} array The array to query.
7160     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7161     * @returns {Array} Returns the slice of `array`.
7162     * @example
7163     *
7164     * var users = [
7165     *   { 'user': 'barney',  'active': false },
7166     *   { 'user': 'fred',    'active': false },
7167     *   { 'user': 'pebbles', 'active': true }
7168     * ];
7169     *
7170     * _.dropWhile(users, function(o) { return !o.active; });
7171     * // => objects for ['pebbles']
7172     *
7173     * // The `_.matches` iteratee shorthand.
7174     * _.dropWhile(users, { 'user': 'barney', 'active': false });
7175     * // => objects for ['fred', 'pebbles']
7176     *
7177     * // The `_.matchesProperty` iteratee shorthand.
7178     * _.dropWhile(users, ['active', false]);
7179     * // => objects for ['pebbles']
7180     *
7181     * // The `_.property` iteratee shorthand.
7182     * _.dropWhile(users, 'active');
7183     * // => objects for ['barney', 'fred', 'pebbles']
7184     */
7185    function dropWhile(array, predicate) {
7186      return (array && array.length)
7187        ? baseWhile(array, getIteratee(predicate, 3), true)
7188        : [];
7189    }
7190
7191    /**
7192     * Fills elements of `array` with `value` from `start` up to, but not
7193     * including, `end`.
7194     *
7195     * **Note:** This method mutates `array`.
7196     *
7197     * @static
7198     * @memberOf _
7199     * @since 3.2.0
7200     * @category Array
7201     * @param {Array} array The array to fill.
7202     * @param {*} value The value to fill `array` with.
7203     * @param {number} [start=0] The start position.
7204     * @param {number} [end=array.length] The end position.
7205     * @returns {Array} Returns `array`.
7206     * @example
7207     *
7208     * var array = [1, 2, 3];
7209     *
7210     * _.fill(array, 'a');
7211     * console.log(array);
7212     * // => ['a', 'a', 'a']
7213     *
7214     * _.fill(Array(3), 2);
7215     * // => [2, 2, 2]
7216     *
7217     * _.fill([4, 6, 8, 10], '*', 1, 3);
7218     * // => [4, '*', '*', 10]
7219     */
7220    function fill(array, value, start, end) {
7221      var length = array == null ? 0 : array.length;
7222      if (!length) {
7223        return [];
7224      }
7225      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
7226        start = 0;
7227        end = length;
7228      }
7229      return baseFill(array, value, start, end);
7230    }
7231
7232    /**
7233     * This method is like `_.find` except that it returns the index of the first
7234     * element `predicate` returns truthy for instead of the element itself.
7235     *
7236     * @static
7237     * @memberOf _
7238     * @since 1.1.0
7239     * @category Array
7240     * @param {Array} array The array to inspect.
7241     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7242     * @param {number} [fromIndex=0] The index to search from.
7243     * @returns {number} Returns the index of the found element, else `-1`.
7244     * @example
7245     *
7246     * var users = [
7247     *   { 'user': 'barney',  'active': false },
7248     *   { 'user': 'fred',    'active': false },
7249     *   { 'user': 'pebbles', 'active': true }
7250     * ];
7251     *
7252     * _.findIndex(users, function(o) { return o.user == 'barney'; });
7253     * // => 0
7254     *
7255     * // The `_.matches` iteratee shorthand.
7256     * _.findIndex(users, { 'user': 'fred', 'active': false });
7257     * // => 1
7258     *
7259     * // The `_.matchesProperty` iteratee shorthand.
7260     * _.findIndex(users, ['active', false]);
7261     * // => 0
7262     *
7263     * // The `_.property` iteratee shorthand.
7264     * _.findIndex(users, 'active');
7265     * // => 2
7266     */
7267    function findIndex(array, predicate, fromIndex) {
7268      var length = array == null ? 0 : array.length;
7269      if (!length) {
7270        return -1;
7271      }
7272      var index = fromIndex == null ? 0 : toInteger(fromIndex);
7273      if (index < 0) {
7274        index = nativeMax(length + index, 0);
7275      }
7276      return baseFindIndex(array, getIteratee(predicate, 3), index);
7277    }
7278
7279    /**
7280     * This method is like `_.findIndex` except that it iterates over elements
7281     * of `collection` from right to left.
7282     *
7283     * @static
7284     * @memberOf _
7285     * @since 2.0.0
7286     * @category Array
7287     * @param {Array} array The array to inspect.
7288     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7289     * @param {number} [fromIndex=array.length-1] The index to search from.
7290     * @returns {number} Returns the index of the found element, else `-1`.
7291     * @example
7292     *
7293     * var users = [
7294     *   { 'user': 'barney',  'active': true },
7295     *   { 'user': 'fred',    'active': false },
7296     *   { 'user': 'pebbles', 'active': false }
7297     * ];
7298     *
7299     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
7300     * // => 2
7301     *
7302     * // The `_.matches` iteratee shorthand.
7303     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
7304     * // => 0
7305     *
7306     * // The `_.matchesProperty` iteratee shorthand.
7307     * _.findLastIndex(users, ['active', false]);
7308     * // => 2
7309     *
7310     * // The `_.property` iteratee shorthand.
7311     * _.findLastIndex(users, 'active');
7312     * // => 0
7313     */
7314    function findLastIndex(array, predicate, fromIndex) {
7315      var length = array == null ? 0 : array.length;
7316      if (!length) {
7317        return -1;
7318      }
7319      var index = length - 1;
7320      if (fromIndex !== undefined) {
7321        index = toInteger(fromIndex);
7322        index = fromIndex < 0
7323          ? nativeMax(length + index, 0)
7324          : nativeMin(index, length - 1);
7325      }
7326      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
7327    }
7328
7329    /**
7330     * Flattens `array` a single level deep.
7331     *
7332     * @static
7333     * @memberOf _
7334     * @since 0.1.0
7335     * @category Array
7336     * @param {Array} array The array to flatten.
7337     * @returns {Array} Returns the new flattened array.
7338     * @example
7339     *
7340     * _.flatten([1, [2, [3, [4]], 5]]);
7341     * // => [1, 2, [3, [4]], 5]
7342     */
7343    function flatten(array) {
7344      var length = array == null ? 0 : array.length;
7345      return length ? baseFlatten(array, 1) : [];
7346    }
7347
7348    /**
7349     * Recursively flattens `array`.
7350     *
7351     * @static
7352     * @memberOf _
7353     * @since 3.0.0
7354     * @category Array
7355     * @param {Array} array The array to flatten.
7356     * @returns {Array} Returns the new flattened array.
7357     * @example
7358     *
7359     * _.flattenDeep([1, [2, [3, [4]], 5]]);
7360     * // => [1, 2, 3, 4, 5]
7361     */
7362    function flattenDeep(array) {
7363      var length = array == null ? 0 : array.length;
7364      return length ? baseFlatten(array, INFINITY) : [];
7365    }
7366
7367    /**
7368     * Recursively flatten `array` up to `depth` times.
7369     *
7370     * @static
7371     * @memberOf _
7372     * @since 4.4.0
7373     * @category Array
7374     * @param {Array} array The array to flatten.
7375     * @param {number} [depth=1] The maximum recursion depth.
7376     * @returns {Array} Returns the new flattened array.
7377     * @example
7378     *
7379     * var array = [1, [2, [3, [4]], 5]];
7380     *
7381     * _.flattenDepth(array, 1);
7382     * // => [1, 2, [3, [4]], 5]
7383     *
7384     * _.flattenDepth(array, 2);
7385     * // => [1, 2, 3, [4], 5]
7386     */
7387    function flattenDepth(array, depth) {
7388      var length = array == null ? 0 : array.length;
7389      if (!length) {
7390        return [];
7391      }
7392      depth = depth === undefined ? 1 : toInteger(depth);
7393      return baseFlatten(array, depth);
7394    }
7395
7396    /**
7397     * The inverse of `_.toPairs`; this method returns an object composed
7398     * from key-value `pairs`.
7399     *
7400     * @static
7401     * @memberOf _
7402     * @since 4.0.0
7403     * @category Array
7404     * @param {Array} pairs The key-value pairs.
7405     * @returns {Object} Returns the new object.
7406     * @example
7407     *
7408     * _.fromPairs([['a', 1], ['b', 2]]);
7409     * // => { 'a': 1, 'b': 2 }
7410     */
7411    function fromPairs(pairs) {
7412      var index = -1,
7413          length = pairs == null ? 0 : pairs.length,
7414          result = {};
7415
7416      while (++index < length) {
7417        var pair = pairs[index];
7418        result[pair[0]] = pair[1];
7419      }
7420      return result;
7421    }
7422
7423    /**
7424     * Gets the first element of `array`.
7425     *
7426     * @static
7427     * @memberOf _
7428     * @since 0.1.0
7429     * @alias first
7430     * @category Array
7431     * @param {Array} array The array to query.
7432     * @returns {*} Returns the first element of `array`.
7433     * @example
7434     *
7435     * _.head([1, 2, 3]);
7436     * // => 1
7437     *
7438     * _.head([]);
7439     * // => undefined
7440     */
7441    function head(array) {
7442      return (array && array.length) ? array[0] : undefined;
7443    }
7444
7445    /**
7446     * Gets the index at which the first occurrence of `value` is found in `array`
7447     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7448     * for equality comparisons. If `fromIndex` is negative, it's used as the
7449     * offset from the end of `array`.
7450     *
7451     * @static
7452     * @memberOf _
7453     * @since 0.1.0
7454     * @category Array
7455     * @param {Array} array The array to inspect.
7456     * @param {*} value The value to search for.
7457     * @param {number} [fromIndex=0] The index to search from.
7458     * @returns {number} Returns the index of the matched value, else `-1`.
7459     * @example
7460     *
7461     * _.indexOf([1, 2, 1, 2], 2);
7462     * // => 1
7463     *
7464     * // Search from the `fromIndex`.
7465     * _.indexOf([1, 2, 1, 2], 2, 2);
7466     * // => 3
7467     */
7468    function indexOf(array, value, fromIndex) {
7469      var length = array == null ? 0 : array.length;
7470      if (!length) {
7471        return -1;
7472      }
7473      var index = fromIndex == null ? 0 : toInteger(fromIndex);
7474      if (index < 0) {
7475        index = nativeMax(length + index, 0);
7476      }
7477      return baseIndexOf(array, value, index);
7478    }
7479
7480    /**
7481     * Gets all but the last element of `array`.
7482     *
7483     * @static
7484     * @memberOf _
7485     * @since 0.1.0
7486     * @category Array
7487     * @param {Array} array The array to query.
7488     * @returns {Array} Returns the slice of `array`.
7489     * @example
7490     *
7491     * _.initial([1, 2, 3]);
7492     * // => [1, 2]
7493     */
7494    function initial(array) {
7495      var length = array == null ? 0 : array.length;
7496      return length ? baseSlice(array, 0, -1) : [];
7497    }
7498
7499    /**
7500     * Creates an array of unique values that are included in all given arrays
7501     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7502     * for equality comparisons. The order and references of result values are
7503     * determined by the first array.
7504     *
7505     * @static
7506     * @memberOf _
7507     * @since 0.1.0
7508     * @category Array
7509     * @param {...Array} [arrays] The arrays to inspect.
7510     * @returns {Array} Returns the new array of intersecting values.
7511     * @example
7512     *
7513     * _.intersection([2, 1], [2, 3]);
7514     * // => [2]
7515     */
7516    var intersection = baseRest(function(arrays) {
7517      var mapped = arrayMap(arrays, castArrayLikeObject);
7518      return (mapped.length && mapped[0] === arrays[0])
7519        ? baseIntersection(mapped)
7520        : [];
7521    });
7522
7523    /**
7524     * This method is like `_.intersection` except that it accepts `iteratee`
7525     * which is invoked for each element of each `arrays` to generate the criterion
7526     * by which they're compared. The order and references of result values are
7527     * determined by the first array. The iteratee is invoked with one argument:
7528     * (value).
7529     *
7530     * @static
7531     * @memberOf _
7532     * @since 4.0.0
7533     * @category Array
7534     * @param {...Array} [arrays] The arrays to inspect.
7535     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7536     * @returns {Array} Returns the new array of intersecting values.
7537     * @example
7538     *
7539     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7540     * // => [2.1]
7541     *
7542     * // The `_.property` iteratee shorthand.
7543     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7544     * // => [{ 'x': 1 }]
7545     */
7546    var intersectionBy = baseRest(function(arrays) {
7547      var iteratee = last(arrays),
7548          mapped = arrayMap(arrays, castArrayLikeObject);
7549
7550      if (iteratee === last(mapped)) {
7551        iteratee = undefined;
7552      } else {
7553        mapped.pop();
7554      }
7555      return (mapped.length && mapped[0] === arrays[0])
7556        ? baseIntersection(mapped, getIteratee(iteratee, 2))
7557        : [];
7558    });
7559
7560    /**
7561     * This method is like `_.intersection` except that it accepts `comparator`
7562     * which is invoked to compare elements of `arrays`. The order and references
7563     * of result values are determined by the first array. The comparator is
7564     * invoked with two arguments: (arrVal, othVal).
7565     *
7566     * @static
7567     * @memberOf _
7568     * @since 4.0.0
7569     * @category Array
7570     * @param {...Array} [arrays] The arrays to inspect.
7571     * @param {Function} [comparator] The comparator invoked per element.
7572     * @returns {Array} Returns the new array of intersecting values.
7573     * @example
7574     *
7575     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7576     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7577     *
7578     * _.intersectionWith(objects, others, _.isEqual);
7579     * // => [{ 'x': 1, 'y': 2 }]
7580     */
7581    var intersectionWith = baseRest(function(arrays) {
7582      var comparator = last(arrays),
7583          mapped = arrayMap(arrays, castArrayLikeObject);
7584
7585      comparator = typeof comparator == 'function' ? comparator : undefined;
7586      if (comparator) {
7587        mapped.pop();
7588      }
7589      return (mapped.length && mapped[0] === arrays[0])
7590        ? baseIntersection(mapped, undefined, comparator)
7591        : [];
7592    });
7593
7594    /**
7595     * Converts all elements in `array` into a string separated by `separator`.
7596     *
7597     * @static
7598     * @memberOf _
7599     * @since 4.0.0
7600     * @category Array
7601     * @param {Array} array The array to convert.
7602     * @param {string} [separator=','] The element separator.
7603     * @returns {string} Returns the joined string.
7604     * @example
7605     *
7606     * _.join(['a', 'b', 'c'], '~');
7607     * // => 'a~b~c'
7608     */
7609    function join(array, separator) {
7610      return array == null ? '' : nativeJoin.call(array, separator);
7611    }
7612
7613    /**
7614     * Gets the last element of `array`.
7615     *
7616     * @static
7617     * @memberOf _
7618     * @since 0.1.0
7619     * @category Array
7620     * @param {Array} array The array to query.
7621     * @returns {*} Returns the last element of `array`.
7622     * @example
7623     *
7624     * _.last([1, 2, 3]);
7625     * // => 3
7626     */
7627    function last(array) {
7628      var length = array == null ? 0 : array.length;
7629      return length ? array[length - 1] : undefined;
7630    }
7631
7632    /**
7633     * This method is like `_.indexOf` except that it iterates over elements of
7634     * `array` from right to left.
7635     *
7636     * @static
7637     * @memberOf _
7638     * @since 0.1.0
7639     * @category Array
7640     * @param {Array} array The array to inspect.
7641     * @param {*} value The value to search for.
7642     * @param {number} [fromIndex=array.length-1] The index to search from.
7643     * @returns {number} Returns the index of the matched value, else `-1`.
7644     * @example
7645     *
7646     * _.lastIndexOf([1, 2, 1, 2], 2);
7647     * // => 3
7648     *
7649     * // Search from the `fromIndex`.
7650     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
7651     * // => 1
7652     */
7653    function lastIndexOf(array, value, fromIndex) {
7654      var length = array == null ? 0 : array.length;
7655      if (!length) {
7656        return -1;
7657      }
7658      var index = length;
7659      if (fromIndex !== undefined) {
7660        index = toInteger(fromIndex);
7661        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
7662      }
7663      return value === value
7664        ? strictLastIndexOf(array, value, index)
7665        : baseFindIndex(array, baseIsNaN, index, true);
7666    }
7667
7668    /**
7669     * Gets the element at index `n` of `array`. If `n` is negative, the nth
7670     * element from the end is returned.
7671     *
7672     * @static
7673     * @memberOf _
7674     * @since 4.11.0
7675     * @category Array
7676     * @param {Array} array The array to query.
7677     * @param {number} [n=0] The index of the element to return.
7678     * @returns {*} Returns the nth element of `array`.
7679     * @example
7680     *
7681     * var array = ['a', 'b', 'c', 'd'];
7682     *
7683     * _.nth(array, 1);
7684     * // => 'b'
7685     *
7686     * _.nth(array, -2);
7687     * // => 'c';
7688     */
7689    function nth(array, n) {
7690      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
7691    }
7692
7693    /**
7694     * Removes all given values from `array` using
7695     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
7696     * for equality comparisons.
7697     *
7698     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
7699     * to remove elements from an array by predicate.
7700     *
7701     * @static
7702     * @memberOf _
7703     * @since 2.0.0
7704     * @category Array
7705     * @param {Array} array The array to modify.
7706     * @param {...*} [values] The values to remove.
7707     * @returns {Array} Returns `array`.
7708     * @example
7709     *
7710     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7711     *
7712     * _.pull(array, 'a', 'c');
7713     * console.log(array);
7714     * // => ['b', 'b']
7715     */
7716    var pull = baseRest(pullAll);
7717
7718    /**
7719     * This method is like `_.pull` except that it accepts an array of values to remove.
7720     *
7721     * **Note:** Unlike `_.difference`, this method mutates `array`.
7722     *
7723     * @static
7724     * @memberOf _
7725     * @since 4.0.0
7726     * @category Array
7727     * @param {Array} array The array to modify.
7728     * @param {Array} values The values to remove.
7729     * @returns {Array} Returns `array`.
7730     * @example
7731     *
7732     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7733     *
7734     * _.pullAll(array, ['a', 'c']);
7735     * console.log(array);
7736     * // => ['b', 'b']
7737     */
7738    function pullAll(array, values) {
7739      return (array && array.length && values && values.length)
7740        ? basePullAll(array, values)
7741        : array;
7742    }
7743
7744    /**
7745     * This method is like `_.pullAll` except that it accepts `iteratee` which is
7746     * invoked for each element of `array` and `values` to generate the criterion
7747     * by which they're compared. The iteratee is invoked with one argument: (value).
7748     *
7749     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7750     *
7751     * @static
7752     * @memberOf _
7753     * @since 4.0.0
7754     * @category Array
7755     * @param {Array} array The array to modify.
7756     * @param {Array} values The values to remove.
7757     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7758     * @returns {Array} Returns `array`.
7759     * @example
7760     *
7761     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7762     *
7763     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7764     * console.log(array);
7765     * // => [{ 'x': 2 }]
7766     */
7767    function pullAllBy(array, values, iteratee) {
7768      return (array && array.length && values && values.length)
7769        ? basePullAll(array, values, getIteratee(iteratee, 2))
7770        : array;
7771    }
7772
7773    /**
7774     * This method is like `_.pullAll` except that it accepts `comparator` which
7775     * is invoked to compare elements of `array` to `values`. The comparator is
7776     * invoked with two arguments: (arrVal, othVal).
7777     *
7778     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7779     *
7780     * @static
7781     * @memberOf _
7782     * @since 4.6.0
7783     * @category Array
7784     * @param {Array} array The array to modify.
7785     * @param {Array} values The values to remove.
7786     * @param {Function} [comparator] The comparator invoked per element.
7787     * @returns {Array} Returns `array`.
7788     * @example
7789     *
7790     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7791     *
7792     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7793     * console.log(array);
7794     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7795     */
7796    function pullAllWith(array, values, comparator) {
7797      return (array && array.length && values && values.length)
7798        ? basePullAll(array, values, undefined, comparator)
7799        : array;
7800    }
7801
7802    /**
7803     * Removes elements from `array` corresponding to `indexes` and returns an
7804     * array of removed elements.
7805     *
7806     * **Note:** Unlike `_.at`, this method mutates `array`.
7807     *
7808     * @static
7809     * @memberOf _
7810     * @since 3.0.0
7811     * @category Array
7812     * @param {Array} array The array to modify.
7813     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7814     * @returns {Array} Returns the new array of removed elements.
7815     * @example
7816     *
7817     * var array = ['a', 'b', 'c', 'd'];
7818     * var pulled = _.pullAt(array, [1, 3]);
7819     *
7820     * console.log(array);
7821     * // => ['a', 'c']
7822     *
7823     * console.log(pulled);
7824     * // => ['b', 'd']
7825     */
7826    var pullAt = flatRest(function(array, indexes) {
7827      var length = array == null ? 0 : array.length,
7828          result = baseAt(array, indexes);
7829
7830      basePullAt(array, arrayMap(indexes, function(index) {
7831        return isIndex(index, length) ? +index : index;
7832      }).sort(compareAscending));
7833
7834      return result;
7835    });
7836
7837    /**
7838     * Removes all elements from `array` that `predicate` returns truthy for
7839     * and returns an array of the removed elements. The predicate is invoked
7840     * with three arguments: (value, index, array).
7841     *
7842     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7843     * to pull elements from an array by value.
7844     *
7845     * @static
7846     * @memberOf _
7847     * @since 2.0.0
7848     * @category Array
7849     * @param {Array} array The array to modify.
7850     * @param {Function} [predicate=_.identity] The function invoked per iteration.
7851     * @returns {Array} Returns the new array of removed elements.
7852     * @example
7853     *
7854     * var array = [1, 2, 3, 4];
7855     * var evens = _.remove(array, function(n) {
7856     *   return n % 2 == 0;
7857     * });
7858     *
7859     * console.log(array);
7860     * // => [1, 3]
7861     *
7862     * console.log(evens);
7863     * // => [2, 4]
7864     */
7865    function remove(array, predicate) {
7866      var result = [];
7867      if (!(array && array.length)) {
7868        return result;
7869      }
7870      var index = -1,
7871          indexes = [],
7872          length = array.length;
7873
7874      predicate = getIteratee(predicate, 3);
7875      while (++index < length) {
7876        var value = array[index];
7877        if (predicate(value, index, array)) {
7878          result.push(value);
7879          indexes.push(index);
7880        }
7881      }
7882      basePullAt(array, indexes);
7883      return result;
7884    }
7885
7886    /**
7887     * Reverses `array` so that the first element becomes the last, the second
7888     * element becomes the second to last, and so on.
7889     *
7890     * **Note:** This method mutates `array` and is based on
7891     * [`Array#reverse`](https://mdn.io/Array/reverse).
7892     *
7893     * @static
7894     * @memberOf _
7895     * @since 4.0.0
7896     * @category Array
7897     * @param {Array} array The array to modify.
7898     * @returns {Array} Returns `array`.
7899     * @example
7900     *
7901     * var array = [1, 2, 3];
7902     *
7903     * _.reverse(array);
7904     * // => [3, 2, 1]
7905     *
7906     * console.log(array);
7907     * // => [3, 2, 1]
7908     */
7909    function reverse(array) {
7910      return array == null ? array : nativeReverse.call(array);
7911    }
7912
7913    /**
7914     * Creates a slice of `array` from `start` up to, but not including, `end`.
7915     *
7916     * **Note:** This method is used instead of
7917     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7918     * returned.
7919     *
7920     * @static
7921     * @memberOf _
7922     * @since 3.0.0
7923     * @category Array
7924     * @param {Array} array The array to slice.
7925     * @param {number} [start=0] The start position.
7926     * @param {number} [end=array.length] The end position.
7927     * @returns {Array} Returns the slice of `array`.
7928     */
7929    function slice(array, start, end) {
7930      var length = array == null ? 0 : array.length;
7931      if (!length) {
7932        return [];
7933      }
7934      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7935        start = 0;
7936        end = length;
7937      }
7938      else {
7939        start = start == null ? 0 : toInteger(start);
7940        end = end === undefined ? length : toInteger(end);
7941      }
7942      return baseSlice(array, start, end);
7943    }
7944
7945    /**
7946     * Uses a binary search to determine the lowest index at which `value`
7947     * should be inserted into `array` in order to maintain its sort order.
7948     *
7949     * @static
7950     * @memberOf _
7951     * @since 0.1.0
7952     * @category Array
7953     * @param {Array} array The sorted array to inspect.
7954     * @param {*} value The value to evaluate.
7955     * @returns {number} Returns the index at which `value` should be inserted
7956     *  into `array`.
7957     * @example
7958     *
7959     * _.sortedIndex([30, 50], 40);
7960     * // => 1
7961     */
7962    function sortedIndex(array, value) {
7963      return baseSortedIndex(array, value);
7964    }
7965
7966    /**
7967     * This method is like `_.sortedIndex` except that it accepts `iteratee`
7968     * which is invoked for `value` and each element of `array` to compute their
7969     * sort ranking. The iteratee is invoked with one argument: (value).
7970     *
7971     * @static
7972     * @memberOf _
7973     * @since 4.0.0
7974     * @category Array
7975     * @param {Array} array The sorted array to inspect.
7976     * @param {*} value The value to evaluate.
7977     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
7978     * @returns {number} Returns the index at which `value` should be inserted
7979     *  into `array`.
7980     * @example
7981     *
7982     * var objects = [{ 'x': 4 }, { 'x': 5 }];
7983     *
7984     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
7985     * // => 0
7986     *
7987     * // The `_.property` iteratee shorthand.
7988     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
7989     * // => 0
7990     */
7991    function sortedIndexBy(array, value, iteratee) {
7992      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
7993    }
7994
7995    /**
7996     * This method is like `_.indexOf` except that it performs a binary
7997     * search on a sorted `array`.
7998     *
7999     * @static
8000     * @memberOf _
8001     * @since 4.0.0
8002     * @category Array
8003     * @param {Array} array The array to inspect.
8004     * @param {*} value The value to search for.
8005     * @returns {number} Returns the index of the matched value, else `-1`.
8006     * @example
8007     *
8008     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
8009     * // => 1
8010     */
8011    function sortedIndexOf(array, value) {
8012      var length = array == null ? 0 : array.length;
8013      if (length) {
8014        var index = baseSortedIndex(array, value);
8015        if (index < length && eq(array[index], value)) {
8016          return index;
8017        }
8018      }
8019      return -1;
8020    }
8021
8022    /**
8023     * This method is like `_.sortedIndex` except that it returns the highest
8024     * index at which `value` should be inserted into `array` in order to
8025     * maintain its sort order.
8026     *
8027     * @static
8028     * @memberOf _
8029     * @since 3.0.0
8030     * @category Array
8031     * @param {Array} array The sorted array to inspect.
8032     * @param {*} value The value to evaluate.
8033     * @returns {number} Returns the index at which `value` should be inserted
8034     *  into `array`.
8035     * @example
8036     *
8037     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
8038     * // => 4
8039     */
8040    function sortedLastIndex(array, value) {
8041      return baseSortedIndex(array, value, true);
8042    }
8043
8044    /**
8045     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
8046     * which is invoked for `value` and each element of `array` to compute their
8047     * sort ranking. The iteratee is invoked with one argument: (value).
8048     *
8049     * @static
8050     * @memberOf _
8051     * @since 4.0.0
8052     * @category Array
8053     * @param {Array} array The sorted array to inspect.
8054     * @param {*} value The value to evaluate.
8055     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8056     * @returns {number} Returns the index at which `value` should be inserted
8057     *  into `array`.
8058     * @example
8059     *
8060     * var objects = [{ 'x': 4 }, { 'x': 5 }];
8061     *
8062     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
8063     * // => 1
8064     *
8065     * // The `_.property` iteratee shorthand.
8066     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
8067     * // => 1
8068     */
8069    function sortedLastIndexBy(array, value, iteratee) {
8070      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
8071    }
8072
8073    /**
8074     * This method is like `_.lastIndexOf` except that it performs a binary
8075     * search on a sorted `array`.
8076     *
8077     * @static
8078     * @memberOf _
8079     * @since 4.0.0
8080     * @category Array
8081     * @param {Array} array The array to inspect.
8082     * @param {*} value The value to search for.
8083     * @returns {number} Returns the index of the matched value, else `-1`.
8084     * @example
8085     *
8086     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
8087     * // => 3
8088     */
8089    function sortedLastIndexOf(array, value) {
8090      var length = array == null ? 0 : array.length;
8091      if (length) {
8092        var index = baseSortedIndex(array, value, true) - 1;
8093        if (eq(array[index], value)) {
8094          return index;
8095        }
8096      }
8097      return -1;
8098    }
8099
8100    /**
8101     * This method is like `_.uniq` except that it's designed and optimized
8102     * for sorted arrays.
8103     *
8104     * @static
8105     * @memberOf _
8106     * @since 4.0.0
8107     * @category Array
8108     * @param {Array} array The array to inspect.
8109     * @returns {Array} Returns the new duplicate free array.
8110     * @example
8111     *
8112     * _.sortedUniq([1, 1, 2]);
8113     * // => [1, 2]
8114     */
8115    function sortedUniq(array) {
8116      return (array && array.length)
8117        ? baseSortedUniq(array)
8118        : [];
8119    }
8120
8121    /**
8122     * This method is like `_.uniqBy` except that it's designed and optimized
8123     * for sorted arrays.
8124     *
8125     * @static
8126     * @memberOf _
8127     * @since 4.0.0
8128     * @category Array
8129     * @param {Array} array The array to inspect.
8130     * @param {Function} [iteratee] The iteratee invoked per element.
8131     * @returns {Array} Returns the new duplicate free array.
8132     * @example
8133     *
8134     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
8135     * // => [1.1, 2.3]
8136     */
8137    function sortedUniqBy(array, iteratee) {
8138      return (array && array.length)
8139        ? baseSortedUniq(array, getIteratee(iteratee, 2))
8140        : [];
8141    }
8142
8143    /**
8144     * Gets all but the first element of `array`.
8145     *
8146     * @static
8147     * @memberOf _
8148     * @since 4.0.0
8149     * @category Array
8150     * @param {Array} array The array to query.
8151     * @returns {Array} Returns the slice of `array`.
8152     * @example
8153     *
8154     * _.tail([1, 2, 3]);
8155     * // => [2, 3]
8156     */
8157    function tail(array) {
8158      var length = array == null ? 0 : array.length;
8159      return length ? baseSlice(array, 1, length) : [];
8160    }
8161
8162    /**
8163     * Creates a slice of `array` with `n` elements taken from the beginning.
8164     *
8165     * @static
8166     * @memberOf _
8167     * @since 0.1.0
8168     * @category Array
8169     * @param {Array} array The array to query.
8170     * @param {number} [n=1] The number of elements to take.
8171     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8172     * @returns {Array} Returns the slice of `array`.
8173     * @example
8174     *
8175     * _.take([1, 2, 3]);
8176     * // => [1]
8177     *
8178     * _.take([1, 2, 3], 2);
8179     * // => [1, 2]
8180     *
8181     * _.take([1, 2, 3], 5);
8182     * // => [1, 2, 3]
8183     *
8184     * _.take([1, 2, 3], 0);
8185     * // => []
8186     */
8187    function take(array, n, guard) {
8188      if (!(array && array.length)) {
8189        return [];
8190      }
8191      n = (guard || n === undefined) ? 1 : toInteger(n);
8192      return baseSlice(array, 0, n < 0 ? 0 : n);
8193    }
8194
8195    /**
8196     * Creates a slice of `array` with `n` elements taken from the end.
8197     *
8198     * @static
8199     * @memberOf _
8200     * @since 3.0.0
8201     * @category Array
8202     * @param {Array} array The array to query.
8203     * @param {number} [n=1] The number of elements to take.
8204     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8205     * @returns {Array} Returns the slice of `array`.
8206     * @example
8207     *
8208     * _.takeRight([1, 2, 3]);
8209     * // => [3]
8210     *
8211     * _.takeRight([1, 2, 3], 2);
8212     * // => [2, 3]
8213     *
8214     * _.takeRight([1, 2, 3], 5);
8215     * // => [1, 2, 3]
8216     *
8217     * _.takeRight([1, 2, 3], 0);
8218     * // => []
8219     */
8220    function takeRight(array, n, guard) {
8221      var length = array == null ? 0 : array.length;
8222      if (!length) {
8223        return [];
8224      }
8225      n = (guard || n === undefined) ? 1 : toInteger(n);
8226      n = length - n;
8227      return baseSlice(array, n < 0 ? 0 : n, length);
8228    }
8229
8230    /**
8231     * Creates a slice of `array` with elements taken from the end. Elements are
8232     * taken until `predicate` returns falsey. The predicate is invoked with
8233     * three arguments: (value, index, array).
8234     *
8235     * @static
8236     * @memberOf _
8237     * @since 3.0.0
8238     * @category Array
8239     * @param {Array} array The array to query.
8240     * @param {Function} [predicate=_.identity] The function invoked per iteration.
8241     * @returns {Array} Returns the slice of `array`.
8242     * @example
8243     *
8244     * var users = [
8245     *   { 'user': 'barney',  'active': true },
8246     *   { 'user': 'fred',    'active': false },
8247     *   { 'user': 'pebbles', 'active': false }
8248     * ];
8249     *
8250     * _.takeRightWhile(users, function(o) { return !o.active; });
8251     * // => objects for ['fred', 'pebbles']
8252     *
8253     * // The `_.matches` iteratee shorthand.
8254     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
8255     * // => objects for ['pebbles']
8256     *
8257     * // The `_.matchesProperty` iteratee shorthand.
8258     * _.takeRightWhile(users, ['active', false]);
8259     * // => objects for ['fred', 'pebbles']
8260     *
8261     * // The `_.property` iteratee shorthand.
8262     * _.takeRightWhile(users, 'active');
8263     * // => []
8264     */
8265    function takeRightWhile(array, predicate) {
8266      return (array && array.length)
8267        ? baseWhile(array, getIteratee(predicate, 3), false, true)
8268        : [];
8269    }
8270
8271    /**
8272     * Creates a slice of `array` with elements taken from the beginning. Elements
8273     * are taken until `predicate` returns falsey. The predicate is invoked with
8274     * three arguments: (value, index, array).
8275     *
8276     * @static
8277     * @memberOf _
8278     * @since 3.0.0
8279     * @category Array
8280     * @param {Array} array The array to query.
8281     * @param {Function} [predicate=_.identity] The function invoked per iteration.
8282     * @returns {Array} Returns the slice of `array`.
8283     * @example
8284     *
8285     * var users = [
8286     *   { 'user': 'barney',  'active': false },
8287     *   { 'user': 'fred',    'active': false },
8288     *   { 'user': 'pebbles', 'active': true }
8289     * ];
8290     *
8291     * _.takeWhile(users, function(o) { return !o.active; });
8292     * // => objects for ['barney', 'fred']
8293     *
8294     * // The `_.matches` iteratee shorthand.
8295     * _.takeWhile(users, { 'user': 'barney', 'active': false });
8296     * // => objects for ['barney']
8297     *
8298     * // The `_.matchesProperty` iteratee shorthand.
8299     * _.takeWhile(users, ['active', false]);
8300     * // => objects for ['barney', 'fred']
8301     *
8302     * // The `_.property` iteratee shorthand.
8303     * _.takeWhile(users, 'active');
8304     * // => []
8305     */
8306    function takeWhile(array, predicate) {
8307      return (array && array.length)
8308        ? baseWhile(array, getIteratee(predicate, 3))
8309        : [];
8310    }
8311
8312    /**
8313     * Creates an array of unique values, in order, from all given arrays using
8314     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8315     * for equality comparisons.
8316     *
8317     * @static
8318     * @memberOf _
8319     * @since 0.1.0
8320     * @category Array
8321     * @param {...Array} [arrays] The arrays to inspect.
8322     * @returns {Array} Returns the new array of combined values.
8323     * @example
8324     *
8325     * _.union([2], [1, 2]);
8326     * // => [2, 1]
8327     */
8328    var union = baseRest(function(arrays) {
8329      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
8330    });
8331
8332    /**
8333     * This method is like `_.union` except that it accepts `iteratee` which is
8334     * invoked for each element of each `arrays` to generate the criterion by
8335     * which uniqueness is computed. Result values are chosen from the first
8336     * array in which the value occurs. The iteratee is invoked with one argument:
8337     * (value).
8338     *
8339     * @static
8340     * @memberOf _
8341     * @since 4.0.0
8342     * @category Array
8343     * @param {...Array} [arrays] The arrays to inspect.
8344     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8345     * @returns {Array} Returns the new array of combined values.
8346     * @example
8347     *
8348     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
8349     * // => [2.1, 1.2]
8350     *
8351     * // The `_.property` iteratee shorthand.
8352     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8353     * // => [{ 'x': 1 }, { 'x': 2 }]
8354     */
8355    var unionBy = baseRest(function(arrays) {
8356      var iteratee = last(arrays);
8357      if (isArrayLikeObject(iteratee)) {
8358        iteratee = undefined;
8359      }
8360      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
8361    });
8362
8363    /**
8364     * This method is like `_.union` except that it accepts `comparator` which
8365     * is invoked to compare elements of `arrays`. Result values are chosen from
8366     * the first array in which the value occurs. The comparator is invoked
8367     * with two arguments: (arrVal, othVal).
8368     *
8369     * @static
8370     * @memberOf _
8371     * @since 4.0.0
8372     * @category Array
8373     * @param {...Array} [arrays] The arrays to inspect.
8374     * @param {Function} [comparator] The comparator invoked per element.
8375     * @returns {Array} Returns the new array of combined values.
8376     * @example
8377     *
8378     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8379     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8380     *
8381     * _.unionWith(objects, others, _.isEqual);
8382     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8383     */
8384    var unionWith = baseRest(function(arrays) {
8385      var comparator = last(arrays);
8386      comparator = typeof comparator == 'function' ? comparator : undefined;
8387      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
8388    });
8389
8390    /**
8391     * Creates a duplicate-free version of an array, using
8392     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8393     * for equality comparisons, in which only the first occurrence of each element
8394     * is kept. The order of result values is determined by the order they occur
8395     * in the array.
8396     *
8397     * @static
8398     * @memberOf _
8399     * @since 0.1.0
8400     * @category Array
8401     * @param {Array} array The array to inspect.
8402     * @returns {Array} Returns the new duplicate free array.
8403     * @example
8404     *
8405     * _.uniq([2, 1, 2]);
8406     * // => [2, 1]
8407     */
8408    function uniq(array) {
8409      return (array && array.length) ? baseUniq(array) : [];
8410    }
8411
8412    /**
8413     * This method is like `_.uniq` except that it accepts `iteratee` which is
8414     * invoked for each element in `array` to generate the criterion by which
8415     * uniqueness is computed. The order of result values is determined by the
8416     * order they occur in the array. The iteratee is invoked with one argument:
8417     * (value).
8418     *
8419     * @static
8420     * @memberOf _
8421     * @since 4.0.0
8422     * @category Array
8423     * @param {Array} array The array to inspect.
8424     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8425     * @returns {Array} Returns the new duplicate free array.
8426     * @example
8427     *
8428     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
8429     * // => [2.1, 1.2]
8430     *
8431     * // The `_.property` iteratee shorthand.
8432     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
8433     * // => [{ 'x': 1 }, { 'x': 2 }]
8434     */
8435    function uniqBy(array, iteratee) {
8436      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
8437    }
8438
8439    /**
8440     * This method is like `_.uniq` except that it accepts `comparator` which
8441     * is invoked to compare elements of `array`. The order of result values is
8442     * determined by the order they occur in the array.The comparator is invoked
8443     * with two arguments: (arrVal, othVal).
8444     *
8445     * @static
8446     * @memberOf _
8447     * @since 4.0.0
8448     * @category Array
8449     * @param {Array} array The array to inspect.
8450     * @param {Function} [comparator] The comparator invoked per element.
8451     * @returns {Array} Returns the new duplicate free array.
8452     * @example
8453     *
8454     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
8455     *
8456     * _.uniqWith(objects, _.isEqual);
8457     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
8458     */
8459    function uniqWith(array, comparator) {
8460      comparator = typeof comparator == 'function' ? comparator : undefined;
8461      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
8462    }
8463
8464    /**
8465     * This method is like `_.zip` except that it accepts an array of grouped
8466     * elements and creates an array regrouping the elements to their pre-zip
8467     * configuration.
8468     *
8469     * @static
8470     * @memberOf _
8471     * @since 1.2.0
8472     * @category Array
8473     * @param {Array} array The array of grouped elements to process.
8474     * @returns {Array} Returns the new array of regrouped elements.
8475     * @example
8476     *
8477     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
8478     * // => [['a', 1, true], ['b', 2, false]]
8479     *
8480     * _.unzip(zipped);
8481     * // => [['a', 'b'], [1, 2], [true, false]]
8482     */
8483    function unzip(array) {
8484      if (!(array && array.length)) {
8485        return [];
8486      }
8487      var length = 0;
8488      array = arrayFilter(array, function(group) {
8489        if (isArrayLikeObject(group)) {
8490          length = nativeMax(group.length, length);
8491          return true;
8492        }
8493      });
8494      return baseTimes(length, function(index) {
8495        return arrayMap(array, baseProperty(index));
8496      });
8497    }
8498
8499    /**
8500     * This method is like `_.unzip` except that it accepts `iteratee` to specify
8501     * how regrouped values should be combined. The iteratee is invoked with the
8502     * elements of each group: (...group).
8503     *
8504     * @static
8505     * @memberOf _
8506     * @since 3.8.0
8507     * @category Array
8508     * @param {Array} array The array of grouped elements to process.
8509     * @param {Function} [iteratee=_.identity] The function to combine
8510     *  regrouped values.
8511     * @returns {Array} Returns the new array of regrouped elements.
8512     * @example
8513     *
8514     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
8515     * // => [[1, 10, 100], [2, 20, 200]]
8516     *
8517     * _.unzipWith(zipped, _.add);
8518     * // => [3, 30, 300]
8519     */
8520    function unzipWith(array, iteratee) {
8521      if (!(array && array.length)) {
8522        return [];
8523      }
8524      var result = unzip(array);
8525      if (iteratee == null) {
8526        return result;
8527      }
8528      return arrayMap(result, function(group) {
8529        return apply(iteratee, undefined, group);
8530      });
8531    }
8532
8533    /**
8534     * Creates an array excluding all given values using
8535     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8536     * for equality comparisons.
8537     *
8538     * **Note:** Unlike `_.pull`, this method returns a new array.
8539     *
8540     * @static
8541     * @memberOf _
8542     * @since 0.1.0
8543     * @category Array
8544     * @param {Array} array The array to inspect.
8545     * @param {...*} [values] The values to exclude.
8546     * @returns {Array} Returns the new array of filtered values.
8547     * @see _.difference, _.xor
8548     * @example
8549     *
8550     * _.without([2, 1, 2, 3], 1, 2);
8551     * // => [3]
8552     */
8553    var without = baseRest(function(array, values) {
8554      return isArrayLikeObject(array)
8555        ? baseDifference(array, values)
8556        : [];
8557    });
8558
8559    /**
8560     * Creates an array of unique values that is the
8561     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
8562     * of the given arrays. The order of result values is determined by the order
8563     * they occur in the arrays.
8564     *
8565     * @static
8566     * @memberOf _
8567     * @since 2.4.0
8568     * @category Array
8569     * @param {...Array} [arrays] The arrays to inspect.
8570     * @returns {Array} Returns the new array of filtered values.
8571     * @see _.difference, _.without
8572     * @example
8573     *
8574     * _.xor([2, 1], [2, 3]);
8575     * // => [1, 3]
8576     */
8577    var xor = baseRest(function(arrays) {
8578      return baseXor(arrayFilter(arrays, isArrayLikeObject));
8579    });
8580
8581    /**
8582     * This method is like `_.xor` except that it accepts `iteratee` which is
8583     * invoked for each element of each `arrays` to generate the criterion by
8584     * which by which they're compared. The order of result values is determined
8585     * by the order they occur in the arrays. The iteratee is invoked with one
8586     * argument: (value).
8587     *
8588     * @static
8589     * @memberOf _
8590     * @since 4.0.0
8591     * @category Array
8592     * @param {...Array} [arrays] The arrays to inspect.
8593     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8594     * @returns {Array} Returns the new array of filtered values.
8595     * @example
8596     *
8597     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8598     * // => [1.2, 3.4]
8599     *
8600     * // The `_.property` iteratee shorthand.
8601     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8602     * // => [{ 'x': 2 }]
8603     */
8604    var xorBy = baseRest(function(arrays) {
8605      var iteratee = last(arrays);
8606      if (isArrayLikeObject(iteratee)) {
8607        iteratee = undefined;
8608      }
8609      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
8610    });
8611
8612    /**
8613     * This method is like `_.xor` except that it accepts `comparator` which is
8614     * invoked to compare elements of `arrays`. The order of result values is
8615     * determined by the order they occur in the arrays. The comparator is invoked
8616     * with two arguments: (arrVal, othVal).
8617     *
8618     * @static
8619     * @memberOf _
8620     * @since 4.0.0
8621     * @category Array
8622     * @param {...Array} [arrays] The arrays to inspect.
8623     * @param {Function} [comparator] The comparator invoked per element.
8624     * @returns {Array} Returns the new array of filtered values.
8625     * @example
8626     *
8627     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8628     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8629     *
8630     * _.xorWith(objects, others, _.isEqual);
8631     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
8632     */
8633    var xorWith = baseRest(function(arrays) {
8634      var comparator = last(arrays);
8635      comparator = typeof comparator == 'function' ? comparator : undefined;
8636      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
8637    });
8638
8639    /**
8640     * Creates an array of grouped elements, the first of which contains the
8641     * first elements of the given arrays, the second of which contains the
8642     * second elements of the given arrays, and so on.
8643     *
8644     * @static
8645     * @memberOf _
8646     * @since 0.1.0
8647     * @category Array
8648     * @param {...Array} [arrays] The arrays to process.
8649     * @returns {Array} Returns the new array of grouped elements.
8650     * @example
8651     *
8652     * _.zip(['a', 'b'], [1, 2], [true, false]);
8653     * // => [['a', 1, true], ['b', 2, false]]
8654     */
8655    var zip = baseRest(unzip);
8656
8657    /**
8658     * This method is like `_.fromPairs` except that it accepts two arrays,
8659     * one of property identifiers and one of corresponding values.
8660     *
8661     * @static
8662     * @memberOf _
8663     * @since 0.4.0
8664     * @category Array
8665     * @param {Array} [props=[]] The property identifiers.
8666     * @param {Array} [values=[]] The property values.
8667     * @returns {Object} Returns the new object.
8668     * @example
8669     *
8670     * _.zipObject(['a', 'b'], [1, 2]);
8671     * // => { 'a': 1, 'b': 2 }
8672     */
8673    function zipObject(props, values) {
8674      return baseZipObject(props || [], values || [], assignValue);
8675    }
8676
8677    /**
8678     * This method is like `_.zipObject` except that it supports property paths.
8679     *
8680     * @static
8681     * @memberOf _
8682     * @since 4.1.0
8683     * @category Array
8684     * @param {Array} [props=[]] The property identifiers.
8685     * @param {Array} [values=[]] The property values.
8686     * @returns {Object} Returns the new object.
8687     * @example
8688     *
8689     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
8690     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
8691     */
8692    function zipObjectDeep(props, values) {
8693      return baseZipObject(props || [], values || [], baseSet);
8694    }
8695
8696    /**
8697     * This method is like `_.zip` except that it accepts `iteratee` to specify
8698     * how grouped values should be combined. The iteratee is invoked with the
8699     * elements of each group: (...group).
8700     *
8701     * @static
8702     * @memberOf _
8703     * @since 3.8.0
8704     * @category Array
8705     * @param {...Array} [arrays] The arrays to process.
8706     * @param {Function} [iteratee=_.identity] The function to combine
8707     *  grouped values.
8708     * @returns {Array} Returns the new array of grouped elements.
8709     * @example
8710     *
8711     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
8712     *   return a + b + c;
8713     * });
8714     * // => [111, 222]
8715     */
8716    var zipWith = baseRest(function(arrays) {
8717      var length = arrays.length,
8718          iteratee = length > 1 ? arrays[length - 1] : undefined;
8719
8720      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
8721      return unzipWith(arrays, iteratee);
8722    });
8723
8724    /*------------------------------------------------------------------------*/
8725
8726    /**
8727     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8728     * chain sequences enabled. The result of such sequences must be unwrapped
8729     * with `_#value`.
8730     *
8731     * @static
8732     * @memberOf _
8733     * @since 1.3.0
8734     * @category Seq
8735     * @param {*} value The value to wrap.
8736     * @returns {Object} Returns the new `lodash` wrapper instance.
8737     * @example
8738     *
8739     * var users = [
8740     *   { 'user': 'barney',  'age': 36 },
8741     *   { 'user': 'fred',    'age': 40 },
8742     *   { 'user': 'pebbles', 'age': 1 }
8743     * ];
8744     *
8745     * var youngest = _
8746     *   .chain(users)
8747     *   .sortBy('age')
8748     *   .map(function(o) {
8749     *     return o.user + ' is ' + o.age;
8750     *   })
8751     *   .head()
8752     *   .value();
8753     * // => 'pebbles is 1'
8754     */
8755    function chain(value) {
8756      var result = lodash(value);
8757      result.__chain__ = true;
8758      return result;
8759    }
8760
8761    /**
8762     * This method invokes `interceptor` and returns `value`. The interceptor
8763     * is invoked with one argument; (value). The purpose of this method is to
8764     * "tap into" a method chain sequence in order to modify intermediate results.
8765     *
8766     * @static
8767     * @memberOf _
8768     * @since 0.1.0
8769     * @category Seq
8770     * @param {*} value The value to provide to `interceptor`.
8771     * @param {Function} interceptor The function to invoke.
8772     * @returns {*} Returns `value`.
8773     * @example
8774     *
8775     * _([1, 2, 3])
8776     *  .tap(function(array) {
8777     *    // Mutate input array.
8778     *    array.pop();
8779     *  })
8780     *  .reverse()
8781     *  .value();
8782     * // => [2, 1]
8783     */
8784    function tap(value, interceptor) {
8785      interceptor(value);
8786      return value;
8787    }
8788
8789    /**
8790     * This method is like `_.tap` except that it returns the result of `interceptor`.
8791     * The purpose of this method is to "pass thru" values replacing intermediate
8792     * results in a method chain sequence.
8793     *
8794     * @static
8795     * @memberOf _
8796     * @since 3.0.0
8797     * @category Seq
8798     * @param {*} value The value to provide to `interceptor`.
8799     * @param {Function} interceptor The function to invoke.
8800     * @returns {*} Returns the result of `interceptor`.
8801     * @example
8802     *
8803     * _('  abc  ')
8804     *  .chain()
8805     *  .trim()
8806     *  .thru(function(value) {
8807     *    return [value];
8808     *  })
8809     *  .value();
8810     * // => ['abc']
8811     */
8812    function thru(value, interceptor) {
8813      return interceptor(value);
8814    }
8815
8816    /**
8817     * This method is the wrapper version of `_.at`.
8818     *
8819     * @name at
8820     * @memberOf _
8821     * @since 1.0.0
8822     * @category Seq
8823     * @param {...(string|string[])} [paths] The property paths to pick.
8824     * @returns {Object} Returns the new `lodash` wrapper instance.
8825     * @example
8826     *
8827     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8828     *
8829     * _(object).at(['a[0].b.c', 'a[1]']).value();
8830     * // => [3, 4]
8831     */
8832    var wrapperAt = flatRest(function(paths) {
8833      var length = paths.length,
8834          start = length ? paths[0] : 0,
8835          value = this.__wrapped__,
8836          interceptor = function(object) { return baseAt(object, paths); };
8837
8838      if (length > 1 || this.__actions__.length ||
8839          !(value instanceof LazyWrapper) || !isIndex(start)) {
8840        return this.thru(interceptor);
8841      }
8842      value = value.slice(start, +start + (length ? 1 : 0));
8843      value.__actions__.push({
8844        'func': thru,
8845        'args': [interceptor],
8846        'thisArg': undefined
8847      });
8848      return new LodashWrapper(value, this.__chain__).thru(function(array) {
8849        if (length && !array.length) {
8850          array.push(undefined);
8851        }
8852        return array;
8853      });
8854    });
8855
8856    /**
8857     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8858     *
8859     * @name chain
8860     * @memberOf _
8861     * @since 0.1.0
8862     * @category Seq
8863     * @returns {Object} Returns the new `lodash` wrapper instance.
8864     * @example
8865     *
8866     * var users = [
8867     *   { 'user': 'barney', 'age': 36 },
8868     *   { 'user': 'fred',   'age': 40 }
8869     * ];
8870     *
8871     * // A sequence without explicit chaining.
8872     * _(users).head();
8873     * // => { 'user': 'barney', 'age': 36 }
8874     *
8875     * // A sequence with explicit chaining.
8876     * _(users)
8877     *   .chain()
8878     *   .head()
8879     *   .pick('user')
8880     *   .value();
8881     * // => { 'user': 'barney' }
8882     */
8883    function wrapperChain() {
8884      return chain(this);
8885    }
8886
8887    /**
8888     * Executes the chain sequence and returns the wrapped result.
8889     *
8890     * @name commit
8891     * @memberOf _
8892     * @since 3.2.0
8893     * @category Seq
8894     * @returns {Object} Returns the new `lodash` wrapper instance.
8895     * @example
8896     *
8897     * var array = [1, 2];
8898     * var wrapped = _(array).push(3);
8899     *
8900     * console.log(array);
8901     * // => [1, 2]
8902     *
8903     * wrapped = wrapped.commit();
8904     * console.log(array);
8905     * // => [1, 2, 3]
8906     *
8907     * wrapped.last();
8908     * // => 3
8909     *
8910     * console.log(array);
8911     * // => [1, 2, 3]
8912     */
8913    function wrapperCommit() {
8914      return new LodashWrapper(this.value(), this.__chain__);
8915    }
8916
8917    /**
8918     * Gets the next value on a wrapped object following the
8919     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8920     *
8921     * @name next
8922     * @memberOf _
8923     * @since 4.0.0
8924     * @category Seq
8925     * @returns {Object} Returns the next iterator value.
8926     * @example
8927     *
8928     * var wrapped = _([1, 2]);
8929     *
8930     * wrapped.next();
8931     * // => { 'done': false, 'value': 1 }
8932     *
8933     * wrapped.next();
8934     * // => { 'done': false, 'value': 2 }
8935     *
8936     * wrapped.next();
8937     * // => { 'done': true, 'value': undefined }
8938     */
8939    function wrapperNext() {
8940      if (this.__values__ === undefined) {
8941        this.__values__ = toArray(this.value());
8942      }
8943      var done = this.__index__ >= this.__values__.length,
8944          value = done ? undefined : this.__values__[this.__index__++];
8945
8946      return { 'done': done, 'value': value };
8947    }
8948
8949    /**
8950     * Enables the wrapper to be iterable.
8951     *
8952     * @name Symbol.iterator
8953     * @memberOf _
8954     * @since 4.0.0
8955     * @category Seq
8956     * @returns {Object} Returns the wrapper object.
8957     * @example
8958     *
8959     * var wrapped = _([1, 2]);
8960     *
8961     * wrapped[Symbol.iterator]() === wrapped;
8962     * // => true
8963     *
8964     * Array.from(wrapped);
8965     * // => [1, 2]
8966     */
8967    function wrapperToIterator() {
8968      return this;
8969    }
8970
8971    /**
8972     * Creates a clone of the chain sequence planting `value` as the wrapped value.
8973     *
8974     * @name plant
8975     * @memberOf _
8976     * @since 3.2.0
8977     * @category Seq
8978     * @param {*} value The value to plant.
8979     * @returns {Object} Returns the new `lodash` wrapper instance.
8980     * @example
8981     *
8982     * function square(n) {
8983     *   return n * n;
8984     * }
8985     *
8986     * var wrapped = _([1, 2]).map(square);
8987     * var other = wrapped.plant([3, 4]);
8988     *
8989     * other.value();
8990     * // => [9, 16]
8991     *
8992     * wrapped.value();
8993     * // => [1, 4]
8994     */
8995    function wrapperPlant(value) {
8996      var result,
8997          parent = this;
8998
8999      while (parent instanceof baseLodash) {
9000        var clone = wrapperClone(parent);
9001        clone.__index__ = 0;
9002        clone.__values__ = undefined;
9003        if (result) {
9004          previous.__wrapped__ = clone;
9005        } else {
9006          result = clone;
9007        }
9008        var previous = clone;
9009        parent = parent.__wrapped__;
9010      }
9011      previous.__wrapped__ = value;
9012      return result;
9013    }
9014
9015    /**
9016     * This method is the wrapper version of `_.reverse`.
9017     *
9018     * **Note:** This method mutates the wrapped array.
9019     *
9020     * @name reverse
9021     * @memberOf _
9022     * @since 0.1.0
9023     * @category Seq
9024     * @returns {Object} Returns the new `lodash` wrapper instance.
9025     * @example
9026     *
9027     * var array = [1, 2, 3];
9028     *
9029     * _(array).reverse().value()
9030     * // => [3, 2, 1]
9031     *
9032     * console.log(array);
9033     * // => [3, 2, 1]
9034     */
9035    function wrapperReverse() {
9036      var value = this.__wrapped__;
9037      if (value instanceof LazyWrapper) {
9038        var wrapped = value;
9039        if (this.__actions__.length) {
9040          wrapped = new LazyWrapper(this);
9041        }
9042        wrapped = wrapped.reverse();
9043        wrapped.__actions__.push({
9044          'func': thru,
9045          'args': [reverse],
9046          'thisArg': undefined
9047        });
9048        return new LodashWrapper(wrapped, this.__chain__);
9049      }
9050      return this.thru(reverse);
9051    }
9052
9053    /**
9054     * Executes the chain sequence to resolve the unwrapped value.
9055     *
9056     * @name value
9057     * @memberOf _
9058     * @since 0.1.0
9059     * @alias toJSON, valueOf
9060     * @category Seq
9061     * @returns {*} Returns the resolved unwrapped value.
9062     * @example
9063     *
9064     * _([1, 2, 3]).value();
9065     * // => [1, 2, 3]
9066     */
9067    function wrapperValue() {
9068      return baseWrapperValue(this.__wrapped__, this.__actions__);
9069    }
9070
9071    /*------------------------------------------------------------------------*/
9072
9073    /**
vendor: 6,915 bytes, lines 9074-9264
9074     * Creates an object composed of keys generated from the results of running
9075     * each element of `collection` thru `iteratee`. The corresponding value of
9076     * each key is the number of times the key was returned by `iteratee`. The
9077     * iteratee is invoked with one argument: (value).
9078     *
9079     * @static
9080     * @memberOf _
9081     * @since 0.5.0
9082     * @category Collection
9083     * @param {Array|Object} collection The collection to iterate over.
9084     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9085     * @returns {Object} Returns the composed aggregate object.
9086     * @example
9087     *
9088     * _.countBy([6.1, 4.2, 6.3], Math.floor);
9089     * // => { '4': 1, '6': 2 }
9090     *
9091     * // The `_.property` iteratee shorthand.
9092     * _.countBy(['one', 'two', 'three'], 'length');
9093     * // => { '3': 2, '5': 1 }
9094     */
9095    var countBy = createAggregator(function(result, value, key) {
9096      if (hasOwnProperty.call(result, key)) {
9097        ++result[key];
9098      } else {
9099        baseAssignValue(result, key, 1);
9100      }
9101    });
9102
9103    /**
9104     * Checks if `predicate` returns truthy for **all** elements of `collection`.
9105     * Iteration is stopped once `predicate` returns falsey. The predicate is
9106     * invoked with three arguments: (value, index|key, collection).
9107     *
9108     * **Note:** This method returns `true` for
9109     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
9110     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
9111     * elements of empty collections.
9112     *
9113     * @static
9114     * @memberOf _
9115     * @since 0.1.0
9116     * @category Collection
9117     * @param {Array|Object} collection The collection to iterate over.
9118     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9119     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9120     * @returns {boolean} Returns `true` if all elements pass the predicate check,
9121     *  else `false`.
9122     * @example
9123     *
9124     * _.every([true, 1, null, 'yes'], Boolean);
9125     * // => false
9126     *
9127     * var users = [
9128     *   { 'user': 'barney', 'age': 36, 'active': false },
9129     *   { 'user': 'fred',   'age': 40, 'active': false }
9130     * ];
9131     *
9132     * // The `_.matches` iteratee shorthand.
9133     * _.every(users, { 'user': 'barney', 'active': false });
9134     * // => false
9135     *
9136     * // The `_.matchesProperty` iteratee shorthand.
9137     * _.every(users, ['active', false]);
9138     * // => true
9139     *
9140     * // The `_.property` iteratee shorthand.
9141     * _.every(users, 'active');
9142     * // => false
9143     */
9144    function every(collection, predicate, guard) {
9145      var func = isArray(collection) ? arrayEvery : baseEvery;
9146      if (guard && isIterateeCall(collection, predicate, guard)) {
9147        predicate = undefined;
9148      }
9149      return func(collection, getIteratee(predicate, 3));
9150    }
9151
9152    /**
9153     * Iterates over elements of `collection`, returning an array of all elements
9154     * `predicate` returns truthy for. The predicate is invoked with three
9155     * arguments: (value, index|key, collection).
9156     *
9157     * **Note:** Unlike `_.remove`, this method returns a new array.
9158     *
9159     * @static
9160     * @memberOf _
9161     * @since 0.1.0
9162     * @category Collection
9163     * @param {Array|Object} collection The collection to iterate over.
9164     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9165     * @returns {Array} Returns the new filtered array.
9166     * @see _.reject
9167     * @example
9168     *
9169     * var users = [
9170     *   { 'user': 'barney', 'age': 36, 'active': true },
9171     *   { 'user': 'fred',   'age': 40, 'active': false }
9172     * ];
9173     *
9174     * _.filter(users, function(o) { return !o.active; });
9175     * // => objects for ['fred']
9176     *
9177     * // The `_.matches` iteratee shorthand.
9178     * _.filter(users, { 'age': 36, 'active': true });
9179     * // => objects for ['barney']
9180     *
9181     * // The `_.matchesProperty` iteratee shorthand.
9182     * _.filter(users, ['active', false]);
9183     * // => objects for ['fred']
9184     *
9185     * // The `_.property` iteratee shorthand.
9186     * _.filter(users, 'active');
9187     * // => objects for ['barney']
9188     */
9189    function filter(collection, predicate) {
9190      var func = isArray(collection) ? arrayFilter : baseFilter;
9191      return func(collection, getIteratee(predicate, 3));
9192    }
9193
9194    /**
9195     * Iterates over elements of `collection`, returning the first element
9196     * `predicate` returns truthy for. The predicate is invoked with three
9197     * arguments: (value, index|key, collection).
9198     *
9199     * @static
9200     * @memberOf _
9201     * @since 0.1.0
9202     * @category Collection
9203     * @param {Array|Object} collection The collection to inspect.
9204     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9205     * @param {number} [fromIndex=0] The index to search from.
9206     * @returns {*} Returns the matched element, else `undefined`.
9207     * @example
9208     *
9209     * var users = [
9210     *   { 'user': 'barney',  'age': 36, 'active': true },
9211     *   { 'user': 'fred',    'age': 40, 'active': false },
9212     *   { 'user': 'pebbles', 'age': 1,  'active': true }
9213     * ];
9214     *
9215     * _.find(users, function(o) { return o.age < 40; });
9216     * // => object for 'barney'
9217     *
9218     * // The `_.matches` iteratee shorthand.
9219     * _.find(users, { 'age': 1, 'active': true });
9220     * // => object for 'pebbles'
9221     *
9222     * // The `_.matchesProperty` iteratee shorthand.
9223     * _.find(users, ['active', false]);
9224     * // => object for 'fred'
9225     *
9226     * // The `_.property` iteratee shorthand.
9227     * _.find(users, 'active');
9228     * // => object for 'barney'
9229     */
9230    var find = createFind(findIndex);
9231
9232    /**
9233     * This method is like `_.find` except that it iterates over elements of
9234     * `collection` from right to left.
9235     *
9236     * @static
9237     * @memberOf _
9238     * @since 2.0.0
9239     * @category Collection
9240     * @param {Array|Object} collection The collection to inspect.
9241     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9242     * @param {number} [fromIndex=collection.length-1] The index to search from.
9243     * @returns {*} Returns the matched element, else `undefined`.
9244     * @example
9245     *
9246     * _.findLast([1, 2, 3, 4], function(n) {
9247     *   return n % 2 == 1;
9248     * });
9249     * // => 3
9250     */
9251    var findLast = createFind(findLastIndex);
9252
9253    /**
9254     * Creates a flattened array of values by running each element in `collection`
9255     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
9256     * with three arguments: (value, index|key, collection).
9257     *
9258     * @static
9259     * @memberOf _
9260     * @since 4.0.0
9261     * @category Collection
9262     * @param {Array|Object} collection The collection to iterate over.
9263     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9264     * @returns {Array} Returns the new flattened array.
vendor: 3,950 bytes, lines 9265-9388
9265     * @example
9266     *
9267     * function duplicate(n) {
9268     *   return [n, n];
9269     * }
9270     *
9271     * _.flatMap([1, 2], duplicate);
9272     * // => [1, 1, 2, 2]
9273     */
9274    function flatMap(collection, iteratee) {
9275      return baseFlatten(map(collection, iteratee), 1);
9276    }
9277
9278    /**
9279     * This method is like `_.flatMap` except that it recursively flattens the
9280     * mapped results.
9281     *
9282     * @static
9283     * @memberOf _
9284     * @since 4.7.0
9285     * @category Collection
9286     * @param {Array|Object} collection The collection to iterate over.
9287     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9288     * @returns {Array} Returns the new flattened array.
9289     * @example
9290     *
9291     * function duplicate(n) {
9292     *   return [[[n, n]]];
9293     * }
9294     *
9295     * _.flatMapDeep([1, 2], duplicate);
9296     * // => [1, 1, 2, 2]
9297     */
9298    function flatMapDeep(collection, iteratee) {
9299      return baseFlatten(map(collection, iteratee), INFINITY);
9300    }
9301
9302    /**
9303     * This method is like `_.flatMap` except that it recursively flattens the
9304     * mapped results up to `depth` times.
9305     *
9306     * @static
9307     * @memberOf _
9308     * @since 4.7.0
9309     * @category Collection
9310     * @param {Array|Object} collection The collection to iterate over.
9311     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9312     * @param {number} [depth=1] The maximum recursion depth.
9313     * @returns {Array} Returns the new flattened array.
9314     * @example
9315     *
9316     * function duplicate(n) {
9317     *   return [[[n, n]]];
9318     * }
9319     *
9320     * _.flatMapDepth([1, 2], duplicate, 2);
9321     * // => [[1, 1], [2, 2]]
9322     */
9323    function flatMapDepth(collection, iteratee, depth) {
9324      depth = depth === undefined ? 1 : toInteger(depth);
9325      return baseFlatten(map(collection, iteratee), depth);
9326    }
9327
9328    /**
9329     * Iterates over elements of `collection` and invokes `iteratee` for each element.
9330     * The iteratee is invoked with three arguments: (value, index|key, collection).
9331     * Iteratee functions may exit iteration early by explicitly returning `false`.
9332     *
9333     * **Note:** As with other "Collections" methods, objects with a "length"
9334     * property are iterated like arrays. To avoid this behavior use `_.forIn`
9335     * or `_.forOwn` for object iteration.
9336     *
9337     * @static
9338     * @memberOf _
9339     * @since 0.1.0
9340     * @alias each
9341     * @category Collection
9342     * @param {Array|Object} collection The collection to iterate over.
9343     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9344     * @returns {Array|Object} Returns `collection`.
9345     * @see _.forEachRight
9346     * @example
9347     *
9348     * _.forEach([1, 2], function(value) {
9349     *   console.log(value);
9350     * });
9351     * // => Logs `1` then `2`.
9352     *
9353     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
9354     *   console.log(key);
9355     * });
9356     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
9357     */
9358    function forEach(collection, iteratee) {
9359      var func = isArray(collection) ? arrayEach : baseEach;
9360      return func(collection, getIteratee(iteratee, 3));
9361    }
9362
9363    /**
9364     * This method is like `_.forEach` except that it iterates over elements of
9365     * `collection` from right to left.
9366     *
9367     * @static
9368     * @memberOf _
9369     * @since 2.0.0
9370     * @alias eachRight
9371     * @category Collection
9372     * @param {Array|Object} collection The collection to iterate over.
9373     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9374     * @returns {Array|Object} Returns `collection`.
9375     * @see _.forEach
9376     * @example
9377     *
9378     * _.forEachRight([1, 2], function(value) {
9379     *   console.log(value);
9380     * });
9381     * // => Logs `2` then `1`.
9382     */
9383    function forEachRight(collection, iteratee) {
9384      var func = isArray(collection) ? arrayEachRight : baseEachRight;
9385      return func(collection, getIteratee(iteratee, 3));
9386    }
9387
9388    /**
vendor: 4,136 bytes, lines 9389-9496
9389     * Creates an object composed of keys generated from the results of running
9390     * each element of `collection` thru `iteratee`. The order of grouped values
9391     * is determined by the order they occur in `collection`. The corresponding
9392     * value of each key is an array of elements responsible for generating the
9393     * key. The iteratee is invoked with one argument: (value).
9394     *
9395     * @static
9396     * @memberOf _
9397     * @since 0.1.0
9398     * @category Collection
9399     * @param {Array|Object} collection The collection to iterate over.
9400     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9401     * @returns {Object} Returns the composed aggregate object.
9402     * @example
9403     *
9404     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
9405     * // => { '4': [4.2], '6': [6.1, 6.3] }
9406     *
9407     * // The `_.property` iteratee shorthand.
9408     * _.groupBy(['one', 'two', 'three'], 'length');
9409     * // => { '3': ['one', 'two'], '5': ['three'] }
9410     */
9411    var groupBy = createAggregator(function(result, value, key) {
9412      if (hasOwnProperty.call(result, key)) {
9413        result[key].push(value);
9414      } else {
9415        baseAssignValue(result, key, [value]);
9416      }
9417    });
9418
9419    /**
9420     * Checks if `value` is in `collection`. If `collection` is a string, it's
9421     * checked for a substring of `value`, otherwise
9422     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9423     * is used for equality comparisons. If `fromIndex` is negative, it's used as
9424     * the offset from the end of `collection`.
9425     *
9426     * @static
9427     * @memberOf _
9428     * @since 0.1.0
9429     * @category Collection
9430     * @param {Array|Object|string} collection The collection to inspect.
9431     * @param {*} value The value to search for.
9432     * @param {number} [fromIndex=0] The index to search from.
9433     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9434     * @returns {boolean} Returns `true` if `value` is found, else `false`.
9435     * @example
9436     *
9437     * _.includes([1, 2, 3], 1);
9438     * // => true
9439     *
9440     * _.includes([1, 2, 3], 1, 2);
9441     * // => false
9442     *
9443     * _.includes({ 'a': 1, 'b': 2 }, 1);
9444     * // => true
9445     *
9446     * _.includes('abcd', 'bc');
9447     * // => true
9448     */
9449    function includes(collection, value, fromIndex, guard) {
9450      collection = isArrayLike(collection) ? collection : values(collection);
9451      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
9452
9453      var length = collection.length;
9454      if (fromIndex < 0) {
9455        fromIndex = nativeMax(length + fromIndex, 0);
9456      }
9457      return isString(collection)
9458        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
9459        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
9460    }
9461
9462    /**
9463     * Invokes the method at `path` of each element in `collection`, returning
9464     * an array of the results of each invoked method. Any additional arguments
9465     * are provided to each invoked method. If `path` is a function, it's invoked
9466     * for, and `this` bound to, each element in `collection`.
9467     *
9468     * @static
9469     * @memberOf _
9470     * @since 4.0.0
9471     * @category Collection
9472     * @param {Array|Object} collection The collection to iterate over.
9473     * @param {Array|Function|string} path The path of the method to invoke or
9474     *  the function invoked per iteration.
9475     * @param {...*} [args] The arguments to invoke each method with.
9476     * @returns {Array} Returns the array of results.
9477     * @example
9478     *
9479     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
9480     * // => [[1, 5, 7], [1, 2, 3]]
9481     *
9482     * _.invokeMap([123, 456], String.prototype.split, '');
9483     * // => [['1', '2', '3'], ['4', '5', '6']]
9484     */
9485    var invokeMap = baseRest(function(collection, path, args) {
9486      var index = -1,
9487          isFunc = typeof path == 'function',
9488          result = isArrayLike(collection) ? Array(collection.length) : [];
9489
9490      baseEach(collection, function(value) {
9491        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
9492      });
9493      return result;
9494    });
9495
9496    /**
vendor: 15,265 bytes, lines 9497-9931
9497     * Creates an object composed of keys generated from the results of running
9498     * each element of `collection` thru `iteratee`. The corresponding value of
9499     * each key is the last element responsible for generating the key. The
9500     * iteratee is invoked with one argument: (value).
9501     *
9502     * @static
9503     * @memberOf _
9504     * @since 4.0.0
9505     * @category Collection
9506     * @param {Array|Object} collection The collection to iterate over.
9507     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
9508     * @returns {Object} Returns the composed aggregate object.
9509     * @example
9510     *
9511     * var array = [
9512     *   { 'dir': 'left', 'code': 97 },
9513     *   { 'dir': 'right', 'code': 100 }
9514     * ];
9515     *
9516     * _.keyBy(array, function(o) {
9517     *   return String.fromCharCode(o.code);
9518     * });
9519     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
9520     *
9521     * _.keyBy(array, 'dir');
9522     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
9523     */
9524    var keyBy = createAggregator(function(result, value, key) {
9525      baseAssignValue(result, key, value);
9526    });
9527
9528    /**
9529     * Creates an array of values by running each element in `collection` thru
9530     * `iteratee`. The iteratee is invoked with three arguments:
9531     * (value, index|key, collection).
9532     *
9533     * Many lodash methods are guarded to work as iteratees for methods like
9534     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
9535     *
9536     * The guarded methods are:
9537     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
9538     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
9539     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
9540     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
9541     *
9542     * @static
9543     * @memberOf _
9544     * @since 0.1.0
9545     * @category Collection
9546     * @param {Array|Object} collection The collection to iterate over.
9547     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9548     * @returns {Array} Returns the new mapped array.
9549     * @example
9550     *
9551     * function square(n) {
9552     *   return n * n;
9553     * }
9554     *
9555     * _.map([4, 8], square);
9556     * // => [16, 64]
9557     *
9558     * _.map({ 'a': 4, 'b': 8 }, square);
9559     * // => [16, 64] (iteration order is not guaranteed)
9560     *
9561     * var users = [
9562     *   { 'user': 'barney' },
9563     *   { 'user': 'fred' }
9564     * ];
9565     *
9566     * // The `_.property` iteratee shorthand.
9567     * _.map(users, 'user');
9568     * // => ['barney', 'fred']
9569     */
9570    function map(collection, iteratee) {
9571      var func = isArray(collection) ? arrayMap : baseMap;
9572      return func(collection, getIteratee(iteratee, 3));
9573    }
9574
9575    /**
9576     * This method is like `_.sortBy` except that it allows specifying the sort
9577     * orders of the iteratees to sort by. If `orders` is unspecified, all values
9578     * are sorted in ascending order. Otherwise, specify an order of "desc" for
9579     * descending or "asc" for ascending sort order of corresponding values.
9580     *
9581     * @static
9582     * @memberOf _
9583     * @since 4.0.0
9584     * @category Collection
9585     * @param {Array|Object} collection The collection to iterate over.
9586     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
9587     *  The iteratees to sort by.
9588     * @param {string[]} [orders] The sort orders of `iteratees`.
9589     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
9590     * @returns {Array} Returns the new sorted array.
9591     * @example
9592     *
9593     * var users = [
9594     *   { 'user': 'fred',   'age': 48 },
9595     *   { 'user': 'barney', 'age': 34 },
9596     *   { 'user': 'fred',   'age': 40 },
9597     *   { 'user': 'barney', 'age': 36 }
9598     * ];
9599     *
9600     * // Sort by `user` in ascending order and by `age` in descending order.
9601     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
9602     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9603     */
9604    function orderBy(collection, iteratees, orders, guard) {
9605      if (collection == null) {
9606        return [];
9607      }
9608      if (!isArray(iteratees)) {
9609        iteratees = iteratees == null ? [] : [iteratees];
9610      }
9611      orders = guard ? undefined : orders;
9612      if (!isArray(orders)) {
9613        orders = orders == null ? [] : [orders];
9614      }
9615      return baseOrderBy(collection, iteratees, orders);
9616    }
9617
9618    /**
9619     * Creates an array of elements split into two groups, the first of which
9620     * contains elements `predicate` returns truthy for, the second of which
9621     * contains elements `predicate` returns falsey for. The predicate is
9622     * invoked with one argument: (value).
9623     *
9624     * @static
9625     * @memberOf _
9626     * @since 3.0.0
9627     * @category Collection
9628     * @param {Array|Object} collection The collection to iterate over.
9629     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9630     * @returns {Array} Returns the array of grouped elements.
9631     * @example
9632     *
9633     * var users = [
9634     *   { 'user': 'barney',  'age': 36, 'active': false },
9635     *   { 'user': 'fred',    'age': 40, 'active': true },
9636     *   { 'user': 'pebbles', 'age': 1,  'active': false }
9637     * ];
9638     *
9639     * _.partition(users, function(o) { return o.active; });
9640     * // => objects for [['fred'], ['barney', 'pebbles']]
9641     *
9642     * // The `_.matches` iteratee shorthand.
9643     * _.partition(users, { 'age': 1, 'active': false });
9644     * // => objects for [['pebbles'], ['barney', 'fred']]
9645     *
9646     * // The `_.matchesProperty` iteratee shorthand.
9647     * _.partition(users, ['active', false]);
9648     * // => objects for [['barney', 'pebbles'], ['fred']]
9649     *
9650     * // The `_.property` iteratee shorthand.
9651     * _.partition(users, 'active');
9652     * // => objects for [['fred'], ['barney', 'pebbles']]
9653     */
9654    var partition = createAggregator(function(result, value, key) {
9655      result[key ? 0 : 1].push(value);
9656    }, function() { return [[], []]; });
9657
9658    /**
9659     * Reduces `collection` to a value which is the accumulated result of running
9660     * each element in `collection` thru `iteratee`, where each successive
9661     * invocation is supplied the return value of the previous. If `accumulator`
9662     * is not given, the first element of `collection` is used as the initial
9663     * value. The iteratee is invoked with four arguments:
9664     * (accumulator, value, index|key, collection).
9665     *
9666     * Many lodash methods are guarded to work as iteratees for methods like
9667     * `_.reduce`, `_.reduceRight`, and `_.transform`.
9668     *
9669     * The guarded methods are:
9670     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
9671     * and `sortBy`
9672     *
9673     * @static
9674     * @memberOf _
9675     * @since 0.1.0
9676     * @category Collection
9677     * @param {Array|Object} collection The collection to iterate over.
9678     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9679     * @param {*} [accumulator] The initial value.
9680     * @returns {*} Returns the accumulated value.
9681     * @see _.reduceRight
9682     * @example
9683     *
9684     * _.reduce([1, 2], function(sum, n) {
9685     *   return sum + n;
9686     * }, 0);
9687     * // => 3
9688     *
9689     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
9690     *   (result[value] || (result[value] = [])).push(key);
9691     *   return result;
9692     * }, {});
9693     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
9694     */
9695    function reduce(collection, iteratee, accumulator) {
9696      var func = isArray(collection) ? arrayReduce : baseReduce,
9697          initAccum = arguments.length < 3;
9698
9699      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
9700    }
9701
9702    /**
9703     * This method is like `_.reduce` except that it iterates over elements of
9704     * `collection` from right to left.
9705     *
9706     * @static
9707     * @memberOf _
9708     * @since 0.1.0
9709     * @category Collection
9710     * @param {Array|Object} collection The collection to iterate over.
9711     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
9712     * @param {*} [accumulator] The initial value.
9713     * @returns {*} Returns the accumulated value.
9714     * @see _.reduce
9715     * @example
9716     *
9717     * var array = [[0, 1], [2, 3], [4, 5]];
9718     *
9719     * _.reduceRight(array, function(flattened, other) {
9720     *   return flattened.concat(other);
9721     * }, []);
9722     * // => [4, 5, 2, 3, 0, 1]
9723     */
9724    function reduceRight(collection, iteratee, accumulator) {
9725      var func = isArray(collection) ? arrayReduceRight : baseReduce,
9726          initAccum = arguments.length < 3;
9727
9728      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9729    }
9730
9731    /**
9732     * The opposite of `_.filter`; this method returns the elements of `collection`
9733     * that `predicate` does **not** return truthy for.
9734     *
9735     * @static
9736     * @memberOf _
9737     * @since 0.1.0
9738     * @category Collection
9739     * @param {Array|Object} collection The collection to iterate over.
9740     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9741     * @returns {Array} Returns the new filtered array.
9742     * @see _.filter
9743     * @example
9744     *
9745     * var users = [
9746     *   { 'user': 'barney', 'age': 36, 'active': false },
9747     *   { 'user': 'fred',   'age': 40, 'active': true }
9748     * ];
9749     *
9750     * _.reject(users, function(o) { return !o.active; });
9751     * // => objects for ['fred']
9752     *
9753     * // The `_.matches` iteratee shorthand.
9754     * _.reject(users, { 'age': 40, 'active': true });
9755     * // => objects for ['barney']
9756     *
9757     * // The `_.matchesProperty` iteratee shorthand.
9758     * _.reject(users, ['active', false]);
9759     * // => objects for ['fred']
9760     *
9761     * // The `_.property` iteratee shorthand.
9762     * _.reject(users, 'active');
9763     * // => objects for ['barney']
9764     */
9765    function reject(collection, predicate) {
9766      var func = isArray(collection) ? arrayFilter : baseFilter;
9767      return func(collection, negate(getIteratee(predicate, 3)));
9768    }
9769
9770    /**
9771     * Gets a random element from `collection`.
9772     *
9773     * @static
9774     * @memberOf _
9775     * @since 2.0.0
9776     * @category Collection
9777     * @param {Array|Object} collection The collection to sample.
9778     * @returns {*} Returns the random element.
9779     * @example
9780     *
9781     * _.sample([1, 2, 3, 4]);
9782     * // => 2
9783     */
9784    function sample(collection) {
9785      var func = isArray(collection) ? arraySample : baseSample;
9786      return func(collection);
9787    }
9788
9789    /**
9790     * Gets `n` random elements at unique keys from `collection` up to the
9791     * size of `collection`.
9792     *
9793     * @static
9794     * @memberOf _
9795     * @since 4.0.0
9796     * @category Collection
9797     * @param {Array|Object} collection The collection to sample.
9798     * @param {number} [n=1] The number of elements to sample.
9799     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9800     * @returns {Array} Returns the random elements.
9801     * @example
9802     *
9803     * _.sampleSize([1, 2, 3], 2);
9804     * // => [3, 1]
9805     *
9806     * _.sampleSize([1, 2, 3], 4);
9807     * // => [2, 3, 1]
9808     */
9809    function sampleSize(collection, n, guard) {
9810      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9811        n = 1;
9812      } else {
9813        n = toInteger(n);
9814      }
9815      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
9816      return func(collection, n);
9817    }
9818
9819    /**
9820     * Creates an array of shuffled values, using a version of the
9821     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9822     *
9823     * @static
9824     * @memberOf _
9825     * @since 0.1.0
9826     * @category Collection
9827     * @param {Array|Object} collection The collection to shuffle.
9828     * @returns {Array} Returns the new shuffled array.
9829     * @example
9830     *
9831     * _.shuffle([1, 2, 3, 4]);
9832     * // => [4, 1, 3, 2]
9833     */
9834    function shuffle(collection) {
9835      var func = isArray(collection) ? arrayShuffle : baseShuffle;
9836      return func(collection);
9837    }
9838
9839    /**
9840     * Gets the size of `collection` by returning its length for array-like
9841     * values or the number of own enumerable string keyed properties for objects.
9842     *
9843     * @static
9844     * @memberOf _
9845     * @since 0.1.0
9846     * @category Collection
9847     * @param {Array|Object|string} collection The collection to inspect.
9848     * @returns {number} Returns the collection size.
9849     * @example
9850     *
9851     * _.size([1, 2, 3]);
9852     * // => 3
9853     *
9854     * _.size({ 'a': 1, 'b': 2 });
9855     * // => 2
9856     *
9857     * _.size('pebbles');
9858     * // => 7
9859     */
9860    function size(collection) {
9861      if (collection == null) {
9862        return 0;
9863      }
9864      if (isArrayLike(collection)) {
9865        return isString(collection) ? stringSize(collection) : collection.length;
9866      }
9867      var tag = getTag(collection);
9868      if (tag == mapTag || tag == setTag) {
9869        return collection.size;
9870      }
9871      return baseKeys(collection).length;
9872    }
9873
9874    /**
9875     * Checks if `predicate` returns truthy for **any** element of `collection`.
9876     * Iteration is stopped once `predicate` returns truthy. The predicate is
9877     * invoked with three arguments: (value, index|key, collection).
9878     *
9879     * @static
9880     * @memberOf _
9881     * @since 0.1.0
9882     * @category Collection
9883     * @param {Array|Object} collection The collection to iterate over.
9884     * @param {Function} [predicate=_.identity] The function invoked per iteration.
9885     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9886     * @returns {boolean} Returns `true` if any element passes the predicate check,
9887     *  else `false`.
9888     * @example
9889     *
9890     * _.some([null, 0, 'yes', false], Boolean);
9891     * // => true
9892     *
9893     * var users = [
9894     *   { 'user': 'barney', 'active': true },
9895     *   { 'user': 'fred',   'active': false }
9896     * ];
9897     *
9898     * // The `_.matches` iteratee shorthand.
9899     * _.some(users, { 'user': 'barney', 'active': false });
9900     * // => false
9901     *
9902     * // The `_.matchesProperty` iteratee shorthand.
9903     * _.some(users, ['active', false]);
9904     * // => true
9905     *
9906     * // The `_.property` iteratee shorthand.
9907     * _.some(users, 'active');
9908     * // => true
9909     */
9910    function some(collection, predicate, guard) {
9911      var func = isArray(collection) ? arraySome : baseSome;
9912      if (guard && isIterateeCall(collection, predicate, guard)) {
9913        predicate = undefined;
9914      }
9915      return func(collection, getIteratee(predicate, 3));
9916    }
9917
9918    /**
9919     * Creates an array of elements, sorted in ascending order by the results of
9920     * running each element in a collection thru each iteratee. This method
9921     * performs a stable sort, that is, it preserves the original sort order of
9922     * equal elements. The iteratees are invoked with one argument: (value).
9923     *
9924     * @static
9925     * @memberOf _
9926     * @since 0.1.0
9927     * @category Collection
9928     * @param {Array|Object} collection The collection to iterate over.
9929     * @param {...(Function|Function[])} [iteratees=[_.identity]]
9930     *  The iteratees to sort by.
9931     * @returns {Array} Returns the new sorted array.
vendor: 6,758 bytes, lines 9932-10134
9932     * @example
9933     *
9934     * var users = [
9935     *   { 'user': 'fred',   'age': 48 },
9936     *   { 'user': 'barney', 'age': 36 },
9937     *   { 'user': 'fred',   'age': 40 },
9938     *   { 'user': 'barney', 'age': 34 }
9939     * ];
9940     *
9941     * _.sortBy(users, [function(o) { return o.user; }]);
9942     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9943     *
9944     * _.sortBy(users, ['user', 'age']);
9945     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9946     */
9947    var sortBy = baseRest(function(collection, iteratees) {
9948      if (collection == null) {
9949        return [];
9950      }
9951      var length = iteratees.length;
9952      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9953        iteratees = [];
9954      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9955        iteratees = [iteratees[0]];
9956      }
9957      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
9958    });
9959
9960    /*------------------------------------------------------------------------*/
9961
9962    /**
9963     * Gets the timestamp of the number of milliseconds that have elapsed since
9964     * the Unix epoch (1 January 1970 00:00:00 UTC).
9965     *
9966     * @static
9967     * @memberOf _
9968     * @since 2.4.0
9969     * @category Date
9970     * @returns {number} Returns the timestamp.
9971     * @example
9972     *
9973     * _.defer(function(stamp) {
9974     *   console.log(_.now() - stamp);
9975     * }, _.now());
9976     * // => Logs the number of milliseconds it took for the deferred invocation.
9977     */
9978    var now = ctxNow || function() {
9979      return root.Date.now();
9980    };
9981
9982    /*------------------------------------------------------------------------*/
9983
9984    /**
9985     * The opposite of `_.before`; this method creates a function that invokes
9986     * `func` once it's called `n` or more times.
9987     *
9988     * @static
9989     * @memberOf _
9990     * @since 0.1.0
9991     * @category Function
9992     * @param {number} n The number of calls before `func` is invoked.
9993     * @param {Function} func The function to restrict.
9994     * @returns {Function} Returns the new restricted function.
9995     * @example
9996     *
9997     * var saves = ['profile', 'settings'];
9998     *
9999     * var done = _.after(saves.length, function() {
10000     *   console.log('done saving!');
10001     * });
10002     *
10003     * _.forEach(saves, function(type) {
10004     *   asyncSave({ 'type': type, 'complete': done });
10005     * });
10006     * // => Logs 'done saving!' after the two async saves have completed.
10007     */
10008    function after(n, func) {
10009      if (typeof func != 'function') {
10010        throw new TypeError(FUNC_ERROR_TEXT);
10011      }
10012      n = toInteger(n);
10013      return function() {
10014        if (--n < 1) {
10015          return func.apply(this, arguments);
10016        }
10017      };
10018    }
10019
10020    /**
10021     * Creates a function that invokes `func`, with up to `n` arguments,
10022     * ignoring any additional arguments.
10023     *
10024     * @static
10025     * @memberOf _
10026     * @since 3.0.0
10027     * @category Function
10028     * @param {Function} func The function to cap arguments for.
10029     * @param {number} [n=func.length] The arity cap.
10030     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10031     * @returns {Function} Returns the new capped function.
10032     * @example
10033     *
10034     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
10035     * // => [6, 8, 10]
10036     */
10037    function ary(func, n, guard) {
10038      n = guard ? undefined : n;
10039      n = (func && n == null) ? func.length : n;
10040      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
10041    }
10042
10043    /**
10044     * Creates a function that invokes `func`, with the `this` binding and arguments
10045     * of the created function, while it's called less than `n` times. Subsequent
10046     * calls to the created function return the result of the last `func` invocation.
10047     *
10048     * @static
10049     * @memberOf _
10050     * @since 3.0.0
10051     * @category Function
10052     * @param {number} n The number of calls at which `func` is no longer invoked.
10053     * @param {Function} func The function to restrict.
10054     * @returns {Function} Returns the new restricted function.
10055     * @example
10056     *
10057     * jQuery(element).on('click', _.before(5, addContactToList));
10058     * // => Allows adding up to 4 contacts to the list.
10059     */
10060    function before(n, func) {
10061      var result;
10062      if (typeof func != 'function') {
10063        throw new TypeError(FUNC_ERROR_TEXT);
10064      }
10065      n = toInteger(n);
10066      return function() {
10067        if (--n > 0) {
10068          result = func.apply(this, arguments);
10069        }
10070        if (n <= 1) {
10071          func = undefined;
10072        }
10073        return result;
10074      };
10075    }
10076
10077    /**
10078     * Creates a function that invokes `func` with the `this` binding of `thisArg`
10079     * and `partials` prepended to the arguments it receives.
10080     *
10081     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
10082     * may be used as a placeholder for partially applied arguments.
10083     *
10084     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
10085     * property of bound functions.
10086     *
10087     * @static
10088     * @memberOf _
10089     * @since 0.1.0
10090     * @category Function
10091     * @param {Function} func The function to bind.
10092     * @param {*} thisArg The `this` binding of `func`.
10093     * @param {...*} [partials] The arguments to be partially applied.
10094     * @returns {Function} Returns the new bound function.
10095     * @example
10096     *
10097     * function greet(greeting, punctuation) {
10098     *   return greeting + ' ' + this.user + punctuation;
10099     * }
10100     *
10101     * var object = { 'user': 'fred' };
10102     *
10103     * var bound = _.bind(greet, object, 'hi');
10104     * bound('!');
10105     * // => 'hi fred!'
10106     *
10107     * // Bound with placeholders.
10108     * var bound = _.bind(greet, object, _, '!');
10109     * bound('hi');
10110     * // => 'hi fred!'
10111     */
10112    var bind = baseRest(function(func, thisArg, partials) {
10113      var bitmask = WRAP_BIND_FLAG;
10114      if (partials.length) {
10115        var holders = replaceHolders(partials, getHolder(bind));
10116        bitmask |= WRAP_PARTIAL_FLAG;
10117      }
10118      return createWrap(func, bitmask, thisArg, partials, holders);
10119    });
10120
10121    /**
10122     * Creates a function that invokes the method at `object[key]` with `partials`
10123     * prepended to the arguments it receives.
10124     *
10125     * This method differs from `_.bind` by allowing bound functions to reference
10126     * methods that may be redefined or don't yet exist. See
10127     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
10128     * for more details.
10129     *
10130     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
10131     * builds, may be used as a placeholder for partially applied arguments.
10132     *
10133     * @static
10134     * @memberOf _
vendor: 8,388 bytes, lines 10135-10367
10135     * @since 0.10.0
10136     * @category Function
10137     * @param {Object} object The object to invoke the method on.
10138     * @param {string} key The key of the method.
10139     * @param {...*} [partials] The arguments to be partially applied.
10140     * @returns {Function} Returns the new bound function.
10141     * @example
10142     *
10143     * var object = {
10144     *   'user': 'fred',
10145     *   'greet': function(greeting, punctuation) {
10146     *     return greeting + ' ' + this.user + punctuation;
10147     *   }
10148     * };
10149     *
10150     * var bound = _.bindKey(object, 'greet', 'hi');
10151     * bound('!');
10152     * // => 'hi fred!'
10153     *
10154     * object.greet = function(greeting, punctuation) {
10155     *   return greeting + 'ya ' + this.user + punctuation;
10156     * };
10157     *
10158     * bound('!');
10159     * // => 'hiya fred!'
10160     *
10161     * // Bound with placeholders.
10162     * var bound = _.bindKey(object, 'greet', _, '!');
10163     * bound('hi');
10164     * // => 'hiya fred!'
10165     */
10166    var bindKey = baseRest(function(object, key, partials) {
10167      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
10168      if (partials.length) {
10169        var holders = replaceHolders(partials, getHolder(bindKey));
10170        bitmask |= WRAP_PARTIAL_FLAG;
10171      }
10172      return createWrap(key, bitmask, object, partials, holders);
10173    });
10174
10175    /**
10176     * Creates a function that accepts arguments of `func` and either invokes
10177     * `func` returning its result, if at least `arity` number of arguments have
10178     * been provided, or returns a function that accepts the remaining `func`
10179     * arguments, and so on. The arity of `func` may be specified if `func.length`
10180     * is not sufficient.
10181     *
10182     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
10183     * may be used as a placeholder for provided arguments.
10184     *
10185     * **Note:** This method doesn't set the "length" property of curried functions.
10186     *
10187     * @static
10188     * @memberOf _
10189     * @since 2.0.0
10190     * @category Function
10191     * @param {Function} func The function to curry.
10192     * @param {number} [arity=func.length] The arity of `func`.
10193     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10194     * @returns {Function} Returns the new curried function.
10195     * @example
10196     *
10197     * var abc = function(a, b, c) {
10198     *   return [a, b, c];
10199     * };
10200     *
10201     * var curried = _.curry(abc);
10202     *
10203     * curried(1)(2)(3);
10204     * // => [1, 2, 3]
10205     *
10206     * curried(1, 2)(3);
10207     * // => [1, 2, 3]
10208     *
10209     * curried(1, 2, 3);
10210     * // => [1, 2, 3]
10211     *
10212     * // Curried with placeholders.
10213     * curried(1)(_, 3)(2);
10214     * // => [1, 2, 3]
10215     */
10216    function curry(func, arity, guard) {
10217      arity = guard ? undefined : arity;
10218      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10219      result.placeholder = curry.placeholder;
10220      return result;
10221    }
10222
10223    /**
10224     * This method is like `_.curry` except that arguments are applied to `func`
10225     * in the manner of `_.partialRight` instead of `_.partial`.
10226     *
10227     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
10228     * builds, may be used as a placeholder for provided arguments.
10229     *
10230     * **Note:** This method doesn't set the "length" property of curried functions.
10231     *
10232     * @static
10233     * @memberOf _
10234     * @since 3.0.0
10235     * @category Function
10236     * @param {Function} func The function to curry.
10237     * @param {number} [arity=func.length] The arity of `func`.
10238     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10239     * @returns {Function} Returns the new curried function.
10240     * @example
10241     *
10242     * var abc = function(a, b, c) {
10243     *   return [a, b, c];
10244     * };
10245     *
10246     * var curried = _.curryRight(abc);
10247     *
10248     * curried(3)(2)(1);
10249     * // => [1, 2, 3]
10250     *
10251     * curried(2, 3)(1);
10252     * // => [1, 2, 3]
10253     *
10254     * curried(1, 2, 3);
10255     * // => [1, 2, 3]
10256     *
10257     * // Curried with placeholders.
10258     * curried(3)(1, _)(2);
10259     * // => [1, 2, 3]
10260     */
10261    function curryRight(func, arity, guard) {
10262      arity = guard ? undefined : arity;
10263      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
10264      result.placeholder = curryRight.placeholder;
10265      return result;
10266    }
10267
10268    /**
10269     * Creates a debounced function that delays invoking `func` until after `wait`
10270     * milliseconds have elapsed since the last time the debounced function was
10271     * invoked. The debounced function comes with a `cancel` method to cancel
10272     * delayed `func` invocations and a `flush` method to immediately invoke them.
10273     * Provide `options` to indicate whether `func` should be invoked on the
10274     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
10275     * with the last arguments provided to the debounced function. Subsequent
10276     * calls to the debounced function return the result of the last `func`
10277     * invocation.
10278     *
10279     * **Note:** If `leading` and `trailing` options are `true`, `func` is
10280     * invoked on the trailing edge of the timeout only if the debounced function
10281     * is invoked more than once during the `wait` timeout.
10282     *
10283     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10284     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10285     *
10286     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10287     * for details over the differences between `_.debounce` and `_.throttle`.
10288     *
10289     * @static
10290     * @memberOf _
10291     * @since 0.1.0
10292     * @category Function
10293     * @param {Function} func The function to debounce.
10294     * @param {number} [wait=0] The number of milliseconds to delay.
10295     * @param {Object} [options={}] The options object.
10296     * @param {boolean} [options.leading=false]
10297     *  Specify invoking on the leading edge of the timeout.
10298     * @param {number} [options.maxWait]
10299     *  The maximum time `func` is allowed to be delayed before it's invoked.
10300     * @param {boolean} [options.trailing=true]
10301     *  Specify invoking on the trailing edge of the timeout.
10302     * @returns {Function} Returns the new debounced function.
10303     * @example
10304     *
10305     * // Avoid costly calculations while the window size is in flux.
10306     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
10307     *
10308     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
10309     * jQuery(element).on('click', _.debounce(sendMail, 300, {
10310     *   'leading': true,
10311     *   'trailing': false
10312     * }));
10313     *
10314     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
10315     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
10316     * var source = new EventSource('/stream');
10317     * jQuery(source).on('message', debounced);
10318     *
10319     * // Cancel the trailing debounced invocation.
10320     * jQuery(window).on('popstate', debounced.cancel);
10321     */
10322    function debounce(func, wait, options) {
10323      var lastArgs,
10324          lastThis,
10325          maxWait,
10326          result,
10327          timerId,
10328          lastCallTime,
10329          lastInvokeTime = 0,
10330          leading = false,
10331          maxing = false,
10332          trailing = true;
10333
10334      if (typeof func != 'function') {
10335        throw new TypeError(FUNC_ERROR_TEXT);
10336      }
10337      wait = toNumber(wait) || 0;
10338      if (isObject(options)) {
10339        leading = !!options.leading;
10340        maxing = 'maxWait' in options;
10341        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
10342        trailing = 'trailing' in options ? !!options.trailing : trailing;
10343      }
10344
10345      function invokeFunc(time) {
10346        var args = lastArgs,
10347            thisArg = lastThis;
10348
10349        lastArgs = lastThis = undefined;
10350        lastInvokeTime = time;
10351        result = func.apply(thisArg, args);
10352        return result;
10353      }
10354
10355      function leadingEdge(time) {
10356        // Reset any `maxWait` timer.
10357        lastInvokeTime = time;
10358        // Start the timer for the trailing edge.
10359        timerId = setTimeout(timerExpired, wait);
10360        // Invoke the leading edge.
10361        return leading ? invokeFunc(time) : result;
10362      }
10363
10364      function remainingWait(time) {
10365        var timeSinceLastCall = time - lastCallTime,
10366            timeSinceLastInvoke = time - lastInvokeTime,
10367            
vendor: 1,940 bytes, lines 10367-10429
10367result = wait - timeSinceLastCall;
10368
10369        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
10370      }
10371
10372      function shouldInvoke(time) {
10373        var timeSinceLastCall = time - lastCallTime,
10374            timeSinceLastInvoke = time - lastInvokeTime;
10375
10376        // Either this is the first call, activity has stopped and we're at the
10377        // trailing edge, the system time has gone backwards and we're treating
10378        // it as the trailing edge, or we've hit the `maxWait` limit.
10379        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
10380          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
10381      }
10382
10383      function timerExpired() {
10384        var time = now();
10385        if (shouldInvoke(time)) {
10386          return trailingEdge(time);
10387        }
10388        // Restart the timer.
10389        timerId = setTimeout(timerExpired, remainingWait(time));
10390      }
10391
10392      function trailingEdge(time) {
10393        timerId = undefined;
10394
10395        // Only invoke if we have `lastArgs` which means `func` has been
10396        // debounced at least once.
10397        if (trailing && lastArgs) {
10398          return invokeFunc(time);
10399        }
10400        lastArgs = lastThis = undefined;
10401        return result;
10402      }
10403
10404      function cancel() {
10405        if (timerId !== undefined) {
10406          clearTimeout(timerId);
10407        }
10408        lastInvokeTime = 0;
10409        lastArgs = lastCallTime = lastThis = timerId = undefined;
10410      }
10411
10412      function flush() {
10413        return timerId === undefined ? result : trailingEdge(now());
10414      }
10415
10416      function debounced() {
10417        var time = now(),
10418            isInvoking = shouldInvoke(time);
10419
10420        lastArgs = arguments;
10421        lastThis = this;
10422        lastCallTime = time;
10423
10424        if (isInvoking) {
10425          if (timerId === undefined) {
10426            return leadingEdge(lastCallTime);
10427          }
10428          if (maxing) {
10429            // Handle invocations in a tight loop.
vendor: 36,079 bytes, lines 10429-11608
10429
10430            timerId = setTimeout(timerExpired, wait);
10431            return invokeFunc(lastCallTime);
10432          }
10433        }
10434        if (timerId === undefined) {
10435          timerId = setTimeout(timerExpired, wait);
10436        }
10437        return result;
10438      }
10439      debounced.cancel = cancel;
10440      debounced.flush = flush;
10441      return debounced;
10442    }
10443
10444    /**
10445     * Defers invoking the `func` until the current call stack has cleared. Any
10446     * additional arguments are provided to `func` when it's invoked.
10447     *
10448     * @static
10449     * @memberOf _
10450     * @since 0.1.0
10451     * @category Function
10452     * @param {Function} func The function to defer.
10453     * @param {...*} [args] The arguments to invoke `func` with.
10454     * @returns {number} Returns the timer id.
10455     * @example
10456     *
10457     * _.defer(function(text) {
10458     *   console.log(text);
10459     * }, 'deferred');
10460     * // => Logs 'deferred' after one millisecond.
10461     */
10462    var defer = baseRest(function(func, args) {
10463      return baseDelay(func, 1, args);
10464    });
10465
10466    /**
10467     * Invokes `func` after `wait` milliseconds. Any additional arguments are
10468     * provided to `func` when it's invoked.
10469     *
10470     * @static
10471     * @memberOf _
10472     * @since 0.1.0
10473     * @category Function
10474     * @param {Function} func The function to delay.
10475     * @param {number} wait The number of milliseconds to delay invocation.
10476     * @param {...*} [args] The arguments to invoke `func` with.
10477     * @returns {number} Returns the timer id.
10478     * @example
10479     *
10480     * _.delay(function(text) {
10481     *   console.log(text);
10482     * }, 1000, 'later');
10483     * // => Logs 'later' after one second.
10484     */
10485    var delay = baseRest(function(func, wait, args) {
10486      return baseDelay(func, toNumber(wait) || 0, args);
10487    });
10488
10489    /**
10490     * Creates a function that invokes `func` with arguments reversed.
10491     *
10492     * @static
10493     * @memberOf _
10494     * @since 4.0.0
10495     * @category Function
10496     * @param {Function} func The function to flip arguments for.
10497     * @returns {Function} Returns the new flipped function.
10498     * @example
10499     *
10500     * var flipped = _.flip(function() {
10501     *   return _.toArray(arguments);
10502     * });
10503     *
10504     * flipped('a', 'b', 'c', 'd');
10505     * // => ['d', 'c', 'b', 'a']
10506     */
10507    function flip(func) {
10508      return createWrap(func, WRAP_FLIP_FLAG);
10509    }
10510
10511    /**
10512     * Creates a function that memoizes the result of `func`. If `resolver` is
10513     * provided, it determines the cache key for storing the result based on the
10514     * arguments provided to the memoized function. By default, the first argument
10515     * provided to the memoized function is used as the map cache key. The `func`
10516     * is invoked with the `this` binding of the memoized function.
10517     *
10518     * **Note:** The cache is exposed as the `cache` property on the memoized
10519     * function. Its creation may be customized by replacing the `_.memoize.Cache`
10520     * constructor with one whose instances implement the
10521     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
10522     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
10523     *
10524     * @static
10525     * @memberOf _
10526     * @since 0.1.0
10527     * @category Function
10528     * @param {Function} func The function to have its output memoized.
10529     * @param {Function} [resolver] The function to resolve the cache key.
10530     * @returns {Function} Returns the new memoized function.
10531     * @example
10532     *
10533     * var object = { 'a': 1, 'b': 2 };
10534     * var other = { 'c': 3, 'd': 4 };
10535     *
10536     * var values = _.memoize(_.values);
10537     * values(object);
10538     * // => [1, 2]
10539     *
10540     * values(other);
10541     * // => [3, 4]
10542     *
10543     * object.a = 2;
10544     * values(object);
10545     * // => [1, 2]
10546     *
10547     * // Modify the result cache.
10548     * values.cache.set(object, ['a', 'b']);
10549     * values(object);
10550     * // => ['a', 'b']
10551     *
10552     * // Replace `_.memoize.Cache`.
10553     * _.memoize.Cache = WeakMap;
10554     */
10555    function memoize(func, resolver) {
10556      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
10557        throw new TypeError(FUNC_ERROR_TEXT);
10558      }
10559      var memoized = function() {
10560        var args = arguments,
10561            key = resolver ? resolver.apply(this, args) : args[0],
10562            cache = memoized.cache;
10563
10564        if (cache.has(key)) {
10565          return cache.get(key);
10566        }
10567        var result = func.apply(this, args);
10568        memoized.cache = cache.set(key, result) || cache;
10569        return result;
10570      };
10571      memoized.cache = new (memoize.Cache || MapCache);
10572      return memoized;
10573    }
10574
10575    // Expose `MapCache`.
10576    memoize.Cache = MapCache;
10577
10578    /**
10579     * Creates a function that negates the result of the predicate `func`. The
10580     * `func` predicate is invoked with the `this` binding and arguments of the
10581     * created function.
10582     *
10583     * @static
10584     * @memberOf _
10585     * @since 3.0.0
10586     * @category Function
10587     * @param {Function} predicate The predicate to negate.
10588     * @returns {Function} Returns the new negated function.
10589     * @example
10590     *
10591     * function isEven(n) {
10592     *   return n % 2 == 0;
10593     * }
10594     *
10595     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
10596     * // => [1, 3, 5]
10597     */
10598    function negate(predicate) {
10599      if (typeof predicate != 'function') {
10600        throw new TypeError(FUNC_ERROR_TEXT);
10601      }
10602      return function() {
10603        var args = arguments;
10604        switch (args.length) {
10605          case 0: return !predicate.call(this);
10606          case 1: return !predicate.call(this, args[0]);
10607          case 2: return !predicate.call(this, args[0], args[1]);
10608          case 3: return !predicate.call(this, args[0], args[1], args[2]);
10609        }
10610        return !predicate.apply(this, args);
10611      };
10612    }
10613
10614    /**
10615     * Creates a function that is restricted to invoking `func` once. Repeat calls
10616     * to the function return the value of the first invocation. The `func` is
10617     * invoked with the `this` binding and arguments of the created function.
10618     *
10619     * @static
10620     * @memberOf _
10621     * @since 0.1.0
10622     * @category Function
10623     * @param {Function} func The function to restrict.
10624     * @returns {Function} Returns the new restricted function.
10625     * @example
10626     *
10627     * var initialize = _.once(createApplication);
10628     * initialize();
10629     * initialize();
10630     * // => `createApplication` is invoked once
10631     */
10632    function once(func) {
10633      return before(2, func);
10634    }
10635
10636    /**
10637     * Creates a function that invokes `func` with its arguments transformed.
10638     *
10639     * @static
10640     * @since 4.0.0
10641     * @memberOf _
10642     * @category Function
10643     * @param {Function} func The function to wrap.
10644     * @param {...(Function|Function[])} [transforms=[_.identity]]
10645     *  The argument transforms.
10646     * @returns {Function} Returns the new function.
10647     * @example
10648     *
10649     * function doubled(n) {
10650     *   return n * 2;
10651     * }
10652     *
10653     * function square(n) {
10654     *   return n * n;
10655     * }
10656     *
10657     * var func = _.overArgs(function(x, y) {
10658     *   return [x, y];
10659     * }, [square, doubled]);
10660     *
10661     * func(9, 3);
10662     * // => [81, 6]
10663     *
10664     * func(10, 5);
10665     * // => [100, 10]
10666     */
10667    var overArgs = castRest(function(func, transforms) {
10668      transforms = (transforms.length == 1 && isArray(transforms[0]))
10669        ? arrayMap(transforms[0], baseUnary(getIteratee()))
10670        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
10671
10672      var funcsLength = transforms.length;
10673      return baseRest(function(args) {
10674        var index = -1,
10675            length = nativeMin(args.length, funcsLength);
10676
10677        while (++index < length) {
10678          args[index] = transforms[index].call(this, args[index]);
10679        }
10680        return apply(func, this, args);
10681      });
10682    });
10683
10684    /**
10685     * Creates a function that invokes `func` with `partials` prepended to the
10686     * arguments it receives. This method is like `_.bind` except it does **not**
10687     * alter the `this` binding.
10688     *
10689     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
10690     * builds, may be used as a placeholder for partially applied arguments.
10691     *
10692     * **Note:** This method doesn't set the "length" property of partially
10693     * applied functions.
10694     *
10695     * @static
10696     * @memberOf _
10697     * @since 0.2.0
10698     * @category Function
10699     * @param {Function} func The function to partially apply arguments to.
10700     * @param {...*} [partials] The arguments to be partially applied.
10701     * @returns {Function} Returns the new partially applied function.
10702     * @example
10703     *
10704     * function greet(greeting, name) {
10705     *   return greeting + ' ' + name;
10706     * }
10707     *
10708     * var sayHelloTo = _.partial(greet, 'hello');
10709     * sayHelloTo('fred');
10710     * // => 'hello fred'
10711     *
10712     * // Partially applied with placeholders.
10713     * var greetFred = _.partial(greet, _, 'fred');
10714     * greetFred('hi');
10715     * // => 'hi fred'
10716     */
10717    var partial = baseRest(function(func, partials) {
10718      var holders = replaceHolders(partials, getHolder(partial));
10719      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
10720    });
10721
10722    /**
10723     * This method is like `_.partial` except that partially applied arguments
10724     * are appended to the arguments it receives.
10725     *
10726     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10727     * builds, may be used as a placeholder for partially applied arguments.
10728     *
10729     * **Note:** This method doesn't set the "length" property of partially
10730     * applied functions.
10731     *
10732     * @static
10733     * @memberOf _
10734     * @since 1.0.0
10735     * @category Function
10736     * @param {Function} func The function to partially apply arguments to.
10737     * @param {...*} [partials] The arguments to be partially applied.
10738     * @returns {Function} Returns the new partially applied function.
10739     * @example
10740     *
10741     * function greet(greeting, name) {
10742     *   return greeting + ' ' + name;
10743     * }
10744     *
10745     * var greetFred = _.partialRight(greet, 'fred');
10746     * greetFred('hi');
10747     * // => 'hi fred'
10748     *
10749     * // Partially applied with placeholders.
10750     * var sayHelloTo = _.partialRight(greet, 'hello', _);
10751     * sayHelloTo('fred');
10752     * // => 'hello fred'
10753     */
10754    var partialRight = baseRest(function(func, partials) {
10755      var holders = replaceHolders(partials, getHolder(partialRight));
10756      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10757    });
10758
10759    /**
10760     * Creates a function that invokes `func` with arguments arranged according
10761     * to the specified `indexes` where the argument value at the first index is
10762     * provided as the first argument, the argument value at the second index is
10763     * provided as the second argument, and so on.
10764     *
10765     * @static
10766     * @memberOf _
10767     * @since 3.0.0
10768     * @category Function
10769     * @param {Function} func The function to rearrange arguments for.
10770     * @param {...(number|number[])} indexes The arranged argument indexes.
10771     * @returns {Function} Returns the new function.
10772     * @example
10773     *
10774     * var rearged = _.rearg(function(a, b, c) {
10775     *   return [a, b, c];
10776     * }, [2, 0, 1]);
10777     *
10778     * rearged('b', 'c', 'a')
10779     * // => ['a', 'b', 'c']
10780     */
10781    var rearg = flatRest(function(func, indexes) {
10782      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
10783    });
10784
10785    /**
10786     * Creates a function that invokes `func` with the `this` binding of the
10787     * created function and arguments from `start` and beyond provided as
10788     * an array.
10789     *
10790     * **Note:** This method is based on the
10791     * [rest parameter](https://mdn.io/rest_parameters).
10792     *
10793     * @static
10794     * @memberOf _
10795     * @since 4.0.0
10796     * @category Function
10797     * @param {Function} func The function to apply a rest parameter to.
10798     * @param {number} [start=func.length-1] The start position of the rest parameter.
10799     * @returns {Function} Returns the new function.
10800     * @example
10801     *
10802     * var say = _.rest(function(what, names) {
10803     *   return what + ' ' + _.initial(names).join(', ') +
10804     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10805     * });
10806     *
10807     * say('hello', 'fred', 'barney', 'pebbles');
10808     * // => 'hello fred, barney, & pebbles'
10809     */
10810    function rest(func, start) {
10811      if (typeof func != 'function') {
10812        throw new TypeError(FUNC_ERROR_TEXT);
10813      }
10814      start = start === undefined ? start : toInteger(start);
10815      return baseRest(func, start);
10816    }
10817
10818    /**
10819     * Creates a function that invokes `func` with the `this` binding of the
10820     * create function and an array of arguments much like
10821     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
10822     *
10823     * **Note:** This method is based on the
10824     * [spread operator](https://mdn.io/spread_operator).
10825     *
10826     * @static
10827     * @memberOf _
10828     * @since 3.2.0
10829     * @category Function
10830     * @param {Function} func The function to spread arguments over.
10831     * @param {number} [start=0] The start position of the spread.
10832     * @returns {Function} Returns the new function.
10833     * @example
10834     *
10835     * var say = _.spread(function(who, what) {
10836     *   return who + ' says ' + what;
10837     * });
10838     *
10839     * say(['fred', 'hello']);
10840     * // => 'fred says hello'
10841     *
10842     * var numbers = Promise.all([
10843     *   Promise.resolve(40),
10844     *   Promise.resolve(36)
10845     * ]);
10846     *
10847     * numbers.then(_.spread(function(x, y) {
10848     *   return x + y;
10849     * }));
10850     * // => a Promise of 76
10851     */
10852    function spread(func, start) {
10853      if (typeof func != 'function') {
10854        throw new TypeError(FUNC_ERROR_TEXT);
10855      }
10856      start = start == null ? 0 : nativeMax(toInteger(start), 0);
10857      return baseRest(function(args) {
10858        var array = args[start],
10859            otherArgs = castSlice(args, 0, start);
10860
10861        if (array) {
10862          arrayPush(otherArgs, array);
10863        }
10864        return apply(func, this, otherArgs);
10865      });
10866    }
10867
10868    /**
10869     * Creates a throttled function that only invokes `func` at most once per
10870     * every `wait` milliseconds. The throttled function comes with a `cancel`
10871     * method to cancel delayed `func` invocations and a `flush` method to
10872     * immediately invoke them. Provide `options` to indicate whether `func`
10873     * should be invoked on the leading and/or trailing edge of the `wait`
10874     * timeout. The `func` is invoked with the last arguments provided to the
10875     * throttled function. Subsequent calls to the throttled function return the
10876     * result of the last `func` invocation.
10877     *
10878     * **Note:** If `leading` and `trailing` options are `true`, `func` is
10879     * invoked on the trailing edge of the timeout only if the throttled function
10880     * is invoked more than once during the `wait` timeout.
10881     *
10882     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
10883     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
10884     *
10885     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10886     * for details over the differences between `_.throttle` and `_.debounce`.
10887     *
10888     * @static
10889     * @memberOf _
10890     * @since 0.1.0
10891     * @category Function
10892     * @param {Function} func The function to throttle.
10893     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10894     * @param {Object} [options={}] The options object.
10895     * @param {boolean} [options.leading=true]
10896     *  Specify invoking on the leading edge of the timeout.
10897     * @param {boolean} [options.trailing=true]
10898     *  Specify invoking on the trailing edge of the timeout.
10899     * @returns {Function} Returns the new throttled function.
10900     * @example
10901     *
10902     * // Avoid excessively updating the position while scrolling.
10903     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10904     *
10905     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10906     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10907     * jQuery(element).on('click', throttled);
10908     *
10909     * // Cancel the trailing throttled invocation.
10910     * jQuery(window).on('popstate', throttled.cancel);
10911     */
10912    function throttle(func, wait, options) {
10913      var leading = true,
10914          trailing = true;
10915
10916      if (typeof func != 'function') {
10917        throw new TypeError(FUNC_ERROR_TEXT);
10918      }
10919      if (isObject(options)) {
10920        leading = 'leading' in options ? !!options.leading : leading;
10921        trailing = 'trailing' in options ? !!options.trailing : trailing;
10922      }
10923      return debounce(func, wait, {
10924        'leading': leading,
10925        'maxWait': wait,
10926        'trailing': trailing
10927      });
10928    }
10929
10930    /**
10931     * Creates a function that accepts up to one argument, ignoring any
10932     * additional arguments.
10933     *
10934     * @static
10935     * @memberOf _
10936     * @since 4.0.0
10937     * @category Function
10938     * @param {Function} func The function to cap arguments for.
10939     * @returns {Function} Returns the new capped function.
10940     * @example
10941     *
10942     * _.map(['6', '8', '10'], _.unary(parseInt));
10943     * // => [6, 8, 10]
10944     */
10945    function unary(func) {
10946      return ary(func, 1);
10947    }
10948
10949    /**
10950     * Creates a function that provides `value` to `wrapper` as its first
10951     * argument. Any additional arguments provided to the function are appended
10952     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
10953     * binding of the created function.
10954     *
10955     * @static
10956     * @memberOf _
10957     * @since 0.1.0
10958     * @category Function
10959     * @param {*} value The value to wrap.
10960     * @param {Function} [wrapper=identity] The wrapper function.
10961     * @returns {Function} Returns the new function.
10962     * @example
10963     *
10964     * var p = _.wrap(_.escape, function(func, text) {
10965     *   return '<p>' + func(text) + '</p>';
10966     * });
10967     *
10968     * p('fred, barney, & pebbles');
10969     * // => '<p>fred, barney, &amp; pebbles</p>'
10970     */
10971    function wrap(value, wrapper) {
10972      return partial(castFunction(wrapper), value);
10973    }
10974
10975    /*------------------------------------------------------------------------*/
10976
10977    /**
10978     * Casts `value` as an array if it's not one.
10979     *
10980     * @static
10981     * @memberOf _
10982     * @since 4.4.0
10983     * @category Lang
10984     * @param {*} value The value to inspect.
10985     * @returns {Array} Returns the cast array.
10986     * @example
10987     *
10988     * _.castArray(1);
10989     * // => [1]
10990     *
10991     * _.castArray({ 'a': 1 });
10992     * // => [{ 'a': 1 }]
10993     *
10994     * _.castArray('abc');
10995     * // => ['abc']
10996     *
10997     * _.castArray(null);
10998     * // => [null]
10999     *
11000     * _.castArray(undefined);
11001     * // => [undefined]
11002     *
11003     * _.castArray();
11004     * // => []
11005     *
11006     * var array = [1, 2, 3];
11007     * console.log(_.castArray(array) === array);
11008     * // => true
11009     */
11010    function castArray() {
11011      if (!arguments.length) {
11012        return [];
11013      }
11014      var value = arguments[0];
11015      return isArray(value) ? value : [value];
11016    }
11017
11018    /**
11019     * Creates a shallow clone of `value`.
11020     *
11021     * **Note:** This method is loosely based on the
11022     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
11023     * and supports cloning arrays, array buffers, booleans, date objects, maps,
11024     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
11025     * arrays. The own enumerable properties of `arguments` objects are cloned
11026     * as plain objects. An empty object is returned for uncloneable values such
11027     * as error objects, functions, DOM nodes, and WeakMaps.
11028     *
11029     * @static
11030     * @memberOf _
11031     * @since 0.1.0
11032     * @category Lang
11033     * @param {*} value The value to clone.
11034     * @returns {*} Returns the cloned value.
11035     * @see _.cloneDeep
11036     * @example
11037     *
11038     * var objects = [{ 'a': 1 }, { 'b': 2 }];
11039     *
11040     * var shallow = _.clone(objects);
11041     * console.log(shallow[0] === objects[0]);
11042     * // => true
11043     */
11044    function clone(value) {
11045      return baseClone(value, CLONE_SYMBOLS_FLAG);
11046    }
11047
11048    /**
11049     * This method is like `_.clone` except that it accepts `customizer` which
11050     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
11051     * cloning is handled by the method instead. The `customizer` is invoked with
11052     * up to four arguments; (value [, index|key, object, stack]).
11053     *
11054     * @static
11055     * @memberOf _
11056     * @since 4.0.0
11057     * @category Lang
11058     * @param {*} value The value to clone.
11059     * @param {Function} [customizer] The function to customize cloning.
11060     * @returns {*} Returns the cloned value.
11061     * @see _.cloneDeepWith
11062     * @example
11063     *
11064     * function customizer(value) {
11065     *   if (_.isElement(value)) {
11066     *     return value.cloneNode(false);
11067     *   }
11068     * }
11069     *
11070     * var el = _.cloneWith(document.body, customizer);
11071     *
11072     * console.log(el === document.body);
11073     * // => false
11074     * console.log(el.nodeName);
11075     * // => 'BODY'
11076     * console.log(el.childNodes.length);
11077     * // => 0
11078     */
11079    function cloneWith(value, customizer) {
11080      customizer = typeof customizer == 'function' ? customizer : undefined;
11081      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
11082    }
11083
11084    /**
11085     * This method is like `_.clone` except that it recursively clones `value`.
11086     *
11087     * @static
11088     * @memberOf _
11089     * @since 1.0.0
11090     * @category Lang
11091     * @param {*} value The value to recursively clone.
11092     * @returns {*} Returns the deep cloned value.
11093     * @see _.clone
11094     * @example
11095     *
11096     * var objects = [{ 'a': 1 }, { 'b': 2 }];
11097     *
11098     * var deep = _.cloneDeep(objects);
11099     * console.log(deep[0] === objects[0]);
11100     * // => false
11101     */
11102    function cloneDeep(value) {
11103      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
11104    }
11105
11106    /**
11107     * This method is like `_.cloneWith` except that it recursively clones `value`.
11108     *
11109     * @static
11110     * @memberOf _
11111     * @since 4.0.0
11112     * @category Lang
11113     * @param {*} value The value to recursively clone.
11114     * @param {Function} [customizer] The function to customize cloning.
11115     * @returns {*} Returns the deep cloned value.
11116     * @see _.cloneWith
11117     * @example
11118     *
11119     * function customizer(value) {
11120     *   if (_.isElement(value)) {
11121     *     return value.cloneNode(true);
11122     *   }
11123     * }
11124     *
11125     * var el = _.cloneDeepWith(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     * // => 20
11133     */
11134    function cloneDeepWith(value, customizer) {
11135      customizer = typeof customizer == 'function' ? customizer : undefined;
11136      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
11137    }
11138
11139    /**
11140     * Checks if `object` conforms to `source` by invoking the predicate
11141     * properties of `source` with the corresponding property values of `object`.
11142     *
11143     * **Note:** This method is equivalent to `_.conforms` when `source` is
11144     * partially applied.
11145     *
11146     * @static
11147     * @memberOf _
11148     * @since 4.14.0
11149     * @category Lang
11150     * @param {Object} object The object to inspect.
11151     * @param {Object} source The object of property predicates to conform to.
11152     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
11153     * @example
11154     *
11155     * var object = { 'a': 1, 'b': 2 };
11156     *
11157     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
11158     * // => true
11159     *
11160     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
11161     * // => false
11162     */
11163    function conformsTo(object, source) {
11164      return source == null || baseConformsTo(object, source, keys(source));
11165    }
11166
11167    /**
11168     * Performs a
11169     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
11170     * comparison between two values to determine if they are equivalent.
11171     *
11172     * @static
11173     * @memberOf _
11174     * @since 4.0.0
11175     * @category Lang
11176     * @param {*} value The value to compare.
11177     * @param {*} other The other value to compare.
11178     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11179     * @example
11180     *
11181     * var object = { 'a': 1 };
11182     * var other = { 'a': 1 };
11183     *
11184     * _.eq(object, object);
11185     * // => true
11186     *
11187     * _.eq(object, other);
11188     * // => false
11189     *
11190     * _.eq('a', 'a');
11191     * // => true
11192     *
11193     * _.eq('a', Object('a'));
11194     * // => false
11195     *
11196     * _.eq(NaN, NaN);
11197     * // => true
11198     */
11199    function eq(value, other) {
11200      return value === other || (value !== value && other !== other);
11201    }
11202
11203    /**
11204     * Checks if `value` is greater than `other`.
11205     *
11206     * @static
11207     * @memberOf _
11208     * @since 3.9.0
11209     * @category Lang
11210     * @param {*} value The value to compare.
11211     * @param {*} other The other value to compare.
11212     * @returns {boolean} Returns `true` if `value` is greater than `other`,
11213     *  else `false`.
11214     * @see _.lt
11215     * @example
11216     *
11217     * _.gt(3, 1);
11218     * // => true
11219     *
11220     * _.gt(3, 3);
11221     * // => false
11222     *
11223     * _.gt(1, 3);
11224     * // => false
11225     */
11226    var gt = createRelationalOperation(baseGt);
11227
11228    /**
11229     * Checks if `value` is greater than or equal to `other`.
11230     *
11231     * @static
11232     * @memberOf _
11233     * @since 3.9.0
11234     * @category Lang
11235     * @param {*} value The value to compare.
11236     * @param {*} other The other value to compare.
11237     * @returns {boolean} Returns `true` if `value` is greater than or equal to
11238     *  `other`, else `false`.
11239     * @see _.lte
11240     * @example
11241     *
11242     * _.gte(3, 1);
11243     * // => true
11244     *
11245     * _.gte(3, 3);
11246     * // => true
11247     *
11248     * _.gte(1, 3);
11249     * // => false
11250     */
11251    var gte = createRelationalOperation(function(value, other) {
11252      return value >= other;
11253    });
11254
11255    /**
11256     * Checks if `value` is likely an `arguments` object.
11257     *
11258     * @static
11259     * @memberOf _
11260     * @since 0.1.0
11261     * @category Lang
11262     * @param {*} value The value to check.
11263     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
11264     *  else `false`.
11265     * @example
11266     *
11267     * _.isArguments(function() { return arguments; }());
11268     * // => true
11269     *
11270     * _.isArguments([1, 2, 3]);
11271     * // => false
11272     */
11273    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
11274      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
11275        !propertyIsEnumerable.call(value, 'callee');
11276    };
11277
11278    /**
11279     * Checks if `value` is classified as an `Array` object.
11280     *
11281     * @static
11282     * @memberOf _
11283     * @since 0.1.0
11284     * @category Lang
11285     * @param {*} value The value to check.
11286     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
11287     * @example
11288     *
11289     * _.isArray([1, 2, 3]);
11290     * // => true
11291     *
11292     * _.isArray(document.body.children);
11293     * // => false
11294     *
11295     * _.isArray('abc');
11296     * // => false
11297     *
11298     * _.isArray(_.noop);
11299     * // => false
11300     */
11301    var isArray = Array.isArray;
11302
11303    /**
11304     * Checks if `value` is classified as an `ArrayBuffer` object.
11305     *
11306     * @static
11307     * @memberOf _
11308     * @since 4.3.0
11309     * @category Lang
11310     * @param {*} value The value to check.
11311     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
11312     * @example
11313     *
11314     * _.isArrayBuffer(new ArrayBuffer(2));
11315     * // => true
11316     *
11317     * _.isArrayBuffer(new Array(2));
11318     * // => false
11319     */
11320    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
11321
11322    /**
11323     * Checks if `value` is array-like. A value is considered array-like if it's
11324     * not a function and has a `value.length` that's an integer greater than or
11325     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
11326     *
11327     * @static
11328     * @memberOf _
11329     * @since 4.0.0
11330     * @category Lang
11331     * @param {*} value The value to check.
11332     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
11333     * @example
11334     *
11335     * _.isArrayLike([1, 2, 3]);
11336     * // => true
11337     *
11338     * _.isArrayLike(document.body.children);
11339     * // => true
11340     *
11341     * _.isArrayLike('abc');
11342     * // => true
11343     *
11344     * _.isArrayLike(_.noop);
11345     * // => false
11346     */
11347    function isArrayLike(value) {
11348      return value != null && isLength(value.length) && !isFunction(value);
11349    }
11350
11351    /**
11352     * This method is like `_.isArrayLike` except that it also checks if `value`
11353     * is an object.
11354     *
11355     * @static
11356     * @memberOf _
11357     * @since 4.0.0
11358     * @category Lang
11359     * @param {*} value The value to check.
11360     * @returns {boolean} Returns `true` if `value` is an array-like object,
11361     *  else `false`.
11362     * @example
11363     *
11364     * _.isArrayLikeObject([1, 2, 3]);
11365     * // => true
11366     *
11367     * _.isArrayLikeObject(document.body.children);
11368     * // => true
11369     *
11370     * _.isArrayLikeObject('abc');
11371     * // => false
11372     *
11373     * _.isArrayLikeObject(_.noop);
11374     * // => false
11375     */
11376    function isArrayLikeObject(value) {
11377      return isObjectLike(value) && isArrayLike(value);
11378    }
11379
11380    /**
11381     * Checks if `value` is classified as a boolean primitive or object.
11382     *
11383     * @static
11384     * @memberOf _
11385     * @since 0.1.0
11386     * @category Lang
11387     * @param {*} value The value to check.
11388     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
11389     * @example
11390     *
11391     * _.isBoolean(false);
11392     * // => true
11393     *
11394     * _.isBoolean(null);
11395     * // => false
11396     */
11397    function isBoolean(value) {
11398      return value === true || value === false ||
11399        (isObjectLike(value) && baseGetTag(value) == boolTag);
11400    }
11401
11402    /**
11403     * Checks if `value` is a buffer.
11404     *
11405     * @static
11406     * @memberOf _
11407     * @since 4.3.0
11408     * @category Lang
11409     * @param {*} value The value to check.
11410     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
11411     * @example
11412     *
11413     * _.isBuffer(new Buffer(2));
11414     * // => true
11415     *
11416     * _.isBuffer(new Uint8Array(2));
11417     * // => false
11418     */
11419    var isBuffer = nativeIsBuffer || stubFalse;
11420
11421    /**
11422     * Checks if `value` is classified as a `Date` object.
11423     *
11424     * @static
11425     * @memberOf _
11426     * @since 0.1.0
11427     * @category Lang
11428     * @param {*} value The value to check.
11429     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
11430     * @example
11431     *
11432     * _.isDate(new Date);
11433     * // => true
11434     *
11435     * _.isDate('Mon April 23 2012');
11436     * // => false
11437     */
11438    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
11439
11440    /**
11441     * Checks if `value` is likely a DOM element.
11442     *
11443     * @static
11444     * @memberOf _
11445     * @since 0.1.0
11446     * @category Lang
11447     * @param {*} value The value to check.
11448     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
11449     * @example
11450     *
11451     * _.isElement(document.body);
11452     * // => true
11453     *
11454     * _.isElement('<body>');
11455     * // => false
11456     */
11457    function isElement(value) {
11458      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
11459    }
11460
11461    /**
11462     * Checks if `value` is an empty object, collection, map, or set.
11463     *
11464     * Objects are considered empty if they have no own enumerable string keyed
11465     * properties.
11466     *
11467     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
11468     * jQuery-like collections are considered empty if they have a `length` of `0`.
11469     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
11470     *
11471     * @static
11472     * @memberOf _
11473     * @since 0.1.0
11474     * @category Lang
11475     * @param {*} value The value to check.
11476     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
11477     * @example
11478     *
11479     * _.isEmpty(null);
11480     * // => true
11481     *
11482     * _.isEmpty(true);
11483     * // => true
11484     *
11485     * _.isEmpty(1);
11486     * // => true
11487     *
11488     * _.isEmpty([1, 2, 3]);
11489     * // => false
11490     *
11491     * _.isEmpty({ 'a': 1 });
11492     * // => false
11493     */
11494    function isEmpty(value) {
11495      if (value == null) {
11496        return true;
11497      }
11498      if (isArrayLike(value) &&
11499          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
11500            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
11501        return !value.length;
11502      }
11503      var tag = getTag(value);
11504      if (tag == mapTag || tag == setTag) {
11505        return !value.size;
11506      }
11507      if (isPrototype(value)) {
11508        return !baseKeys(value).length;
11509      }
11510      for (var key in value) {
11511        if (hasOwnProperty.call(value, key)) {
11512          return false;
11513        }
11514      }
11515      return true;
11516    }
11517
11518    /**
11519     * Performs a deep comparison between two values to determine if they are
11520     * equivalent.
11521     *
11522     * **Note:** This method supports comparing arrays, array buffers, booleans,
11523     * date objects, error objects, maps, numbers, `Object` objects, regexes,
11524     * sets, strings, symbols, and typed arrays. `Object` objects are compared
11525     * by their own, not inherited, enumerable properties. Functions and DOM
11526     * nodes are compared by strict equality, i.e. `===`.
11527     *
11528     * @static
11529     * @memberOf _
11530     * @since 0.1.0
11531     * @category Lang
11532     * @param {*} value The value to compare.
11533     * @param {*} other The other value to compare.
11534     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11535     * @example
11536     *
11537     * var object = { 'a': 1 };
11538     * var other = { 'a': 1 };
11539     *
11540     * _.isEqual(object, other);
11541     * // => true
11542     *
11543     * object === other;
11544     * // => false
11545     */
11546    function isEqual(value, other) {
11547      return baseIsEqual(value, other);
11548    }
11549
11550    /**
11551     * This method is like `_.isEqual` except that it accepts `customizer` which
11552     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11553     * are handled by the method instead. The `customizer` is invoked with up to
11554     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
11555     *
11556     * @static
11557     * @memberOf _
11558     * @since 4.0.0
11559     * @category Lang
11560     * @param {*} value The value to compare.
11561     * @param {*} other The other value to compare.
11562     * @param {Function} [customizer] The function to customize comparisons.
11563     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
11564     * @example
11565     *
11566     * function isGreeting(value) {
11567     *   return /^h(?:i|ello)$/.test(value);
11568     * }
11569     *
11570     * function customizer(objValue, othValue) {
11571     *   if (isGreeting(objValue) && isGreeting(othValue)) {
11572     *     return true;
11573     *   }
11574     * }
11575     *
11576     * var array = ['hello', 'goodbye'];
11577     * var other = ['hi', 'goodbye'];
11578     *
11579     * _.isEqualWith(array, other, customizer);
11580     * // => true
11581     */
11582    function isEqualWith(value, other, customizer) {
11583      customizer = typeof customizer == 'function' ? customizer : undefined;
11584      var result = customizer ? customizer(value, other) : undefined;
11585      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
11586    }
11587
11588    /**
11589     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
11590     * `SyntaxError`, `TypeError`, or `URIError` object.
11591     *
11592     * @static
11593     * @memberOf _
11594     * @since 3.0.0
11595     * @category Lang
11596     * @param {*} value The value to check.
11597     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
11598     * @example
11599     *
11600     * _.isError(new Error);
11601     * // => true
11602     *
11603     * _.isError(Error);
11604     * // => false
11605     */
11606    function isError(value) {
11607      if (!isObjectLike(value)) {
11608        return false;
vendor: 6,607 bytes, lines 11609-11846
11609      }
11610      var tag = baseGetTag(value);
11611      return tag == errorTag || tag == domExcTag ||
11612        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
11613    }
11614
11615    /**
11616     * Checks if `value` is a finite primitive number.
11617     *
11618     * **Note:** This method is based on
11619     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
11620     *
11621     * @static
11622     * @memberOf _
11623     * @since 0.1.0
11624     * @category Lang
11625     * @param {*} value The value to check.
11626     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
11627     * @example
11628     *
11629     * _.isFinite(3);
11630     * // => true
11631     *
11632     * _.isFinite(Number.MIN_VALUE);
11633     * // => true
11634     *
11635     * _.isFinite(Infinity);
11636     * // => false
11637     *
11638     * _.isFinite('3');
11639     * // => false
11640     */
11641    function isFinite(value) {
11642      return typeof value == 'number' && nativeIsFinite(value);
11643    }
11644
11645    /**
11646     * Checks if `value` is classified as a `Function` object.
11647     *
11648     * @static
11649     * @memberOf _
11650     * @since 0.1.0
11651     * @category Lang
11652     * @param {*} value The value to check.
11653     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
11654     * @example
11655     *
11656     * _.isFunction(_);
11657     * // => true
11658     *
11659     * _.isFunction(/abc/);
11660     * // => false
11661     */
11662    function isFunction(value) {
11663      if (!isObject(value)) {
11664        return false;
11665      }
11666      // The use of `Object#toString` avoids issues with the `typeof` operator
11667      // in Safari 9 which returns 'object' for typed arrays and other constructors.
11668      var tag = baseGetTag(value);
11669      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
11670    }
11671
11672    /**
11673     * Checks if `value` is an integer.
11674     *
11675     * **Note:** This method is based on
11676     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
11677     *
11678     * @static
11679     * @memberOf _
11680     * @since 4.0.0
11681     * @category Lang
11682     * @param {*} value The value to check.
11683     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
11684     * @example
11685     *
11686     * _.isInteger(3);
11687     * // => true
11688     *
11689     * _.isInteger(Number.MIN_VALUE);
11690     * // => false
11691     *
11692     * _.isInteger(Infinity);
11693     * // => false
11694     *
11695     * _.isInteger('3');
11696     * // => false
11697     */
11698    function isInteger(value) {
11699      return typeof value == 'number' && value == toInteger(value);
11700    }
11701
11702    /**
11703     * Checks if `value` is a valid array-like length.
11704     *
11705     * **Note:** This method is loosely based on
11706     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
11707     *
11708     * @static
11709     * @memberOf _
11710     * @since 4.0.0
11711     * @category Lang
11712     * @param {*} value The value to check.
11713     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
11714     * @example
11715     *
11716     * _.isLength(3);
11717     * // => true
11718     *
11719     * _.isLength(Number.MIN_VALUE);
11720     * // => false
11721     *
11722     * _.isLength(Infinity);
11723     * // => false
11724     *
11725     * _.isLength('3');
11726     * // => false
11727     */
11728    function isLength(value) {
11729      return typeof value == 'number' &&
11730        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11731    }
11732
11733    /**
11734     * Checks if `value` is the
11735     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
11736     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11737     *
11738     * @static
11739     * @memberOf _
11740     * @since 0.1.0
11741     * @category Lang
11742     * @param {*} value The value to check.
11743     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11744     * @example
11745     *
11746     * _.isObject({});
11747     * // => true
11748     *
11749     * _.isObject([1, 2, 3]);
11750     * // => true
11751     *
11752     * _.isObject(_.noop);
11753     * // => true
11754     *
11755     * _.isObject(null);
11756     * // => false
11757     */
11758    function isObject(value) {
11759      var type = typeof value;
11760      return value != null && (type == 'object' || type == 'function');
11761    }
11762
11763    /**
11764     * Checks if `value` is object-like. A value is object-like if it's not `null`
11765     * and has a `typeof` result of "object".
11766     *
11767     * @static
11768     * @memberOf _
11769     * @since 4.0.0
11770     * @category Lang
11771     * @param {*} value The value to check.
11772     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11773     * @example
11774     *
11775     * _.isObjectLike({});
11776     * // => true
11777     *
11778     * _.isObjectLike([1, 2, 3]);
11779     * // => true
11780     *
11781     * _.isObjectLike(_.noop);
11782     * // => false
11783     *
11784     * _.isObjectLike(null);
11785     * // => false
11786     */
11787    function isObjectLike(value) {
11788      return value != null && typeof value == 'object';
11789    }
11790
11791    /**
11792     * Checks if `value` is classified as a `Map` object.
11793     *
11794     * @static
11795     * @memberOf _
11796     * @since 4.3.0
11797     * @category Lang
11798     * @param {*} value The value to check.
11799     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
11800     * @example
11801     *
11802     * _.isMap(new Map);
11803     * // => true
11804     *
11805     * _.isMap(new WeakMap);
11806     * // => false
11807     */
11808    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
11809
11810    /**
11811     * Performs a partial deep comparison between `object` and `source` to
11812     * determine if `object` contains equivalent property values.
11813     *
11814     * **Note:** This method is equivalent to `_.matches` when `source` is
11815     * partially applied.
11816     *
11817     * Partial comparisons will match empty array and empty object `source`
11818     * values against any array or object value, respectively. See `_.isEqual`
11819     * for a list of supported value comparisons.
11820     *
11821     * @static
11822     * @memberOf _
11823     * @since 3.0.0
11824     * @category Lang
11825     * @param {Object} object The object to inspect.
11826     * @param {Object} source The object of property values to match.
11827     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11828     * @example
11829     *
11830     * var object = { 'a': 1, 'b': 2 };
11831     *
11832     * _.isMatch(object, { 'b': 2 });
11833     * // => true
11834     *
11835     * _.isMatch(object, { 'b': 1 });
11836     * // => false
11837     */
11838    function isMatch(object, source) {
11839      return object === source || baseIsMatch(object, source, getMatchData(source));
11840    }
11841
11842    /**
11843     * This method is like `_.isMatch` except that it accepts `customizer` which
11844     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11845     * are handled by the method instead. The `customizer` is invoked with five
11846     * arguments: (objValue, srcValue, index|key, object, source).
vendor: 12,241 bytes, lines 11847-12312
11847     *
11848     * @static
11849     * @memberOf _
11850     * @since 4.0.0
11851     * @category Lang
11852     * @param {Object} object The object to inspect.
11853     * @param {Object} source The object of property values to match.
11854     * @param {Function} [customizer] The function to customize comparisons.
11855     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11856     * @example
11857     *
11858     * function isGreeting(value) {
11859     *   return /^h(?:i|ello)$/.test(value);
11860     * }
11861     *
11862     * function customizer(objValue, srcValue) {
11863     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
11864     *     return true;
11865     *   }
11866     * }
11867     *
11868     * var object = { 'greeting': 'hello' };
11869     * var source = { 'greeting': 'hi' };
11870     *
11871     * _.isMatchWith(object, source, customizer);
11872     * // => true
11873     */
11874    function isMatchWith(object, source, customizer) {
11875      customizer = typeof customizer == 'function' ? customizer : undefined;
11876      return baseIsMatch(object, source, getMatchData(source), customizer);
11877    }
11878
11879    /**
11880     * Checks if `value` is `NaN`.
11881     *
11882     * **Note:** This method is based on
11883     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11884     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11885     * `undefined` and other non-number values.
11886     *
11887     * @static
11888     * @memberOf _
11889     * @since 0.1.0
11890     * @category Lang
11891     * @param {*} value The value to check.
11892     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11893     * @example
11894     *
11895     * _.isNaN(NaN);
11896     * // => true
11897     *
11898     * _.isNaN(new Number(NaN));
11899     * // => true
11900     *
11901     * isNaN(undefined);
11902     * // => true
11903     *
11904     * _.isNaN(undefined);
11905     * // => false
11906     */
11907    function isNaN(value) {
11908      // An `NaN` primitive is the only value that is not equal to itself.
11909      // Perform the `toStringTag` check first to avoid errors with some
11910      // ActiveX objects in IE.
11911      return isNumber(value) && value != +value;
11912    }
11913
11914    /**
11915     * Checks if `value` is a pristine native function.
11916     *
11917     * **Note:** This method can't reliably detect native functions in the presence
11918     * of the core-js package because core-js circumvents this kind of detection.
11919     * Despite multiple requests, the core-js maintainer has made it clear: any
11920     * attempt to fix the detection will be obstructed. As a result, we're left
11921     * with little choice but to throw an error. Unfortunately, this also affects
11922     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11923     * which rely on core-js.
11924     *
11925     * @static
11926     * @memberOf _
11927     * @since 3.0.0
11928     * @category Lang
11929     * @param {*} value The value to check.
11930     * @returns {boolean} Returns `true` if `value` is a native function,
11931     *  else `false`.
11932     * @example
11933     *
11934     * _.isNative(Array.prototype.push);
11935     * // => true
11936     *
11937     * _.isNative(_);
11938     * // => false
11939     */
11940    function isNative(value) {
11941      if (isMaskable(value)) {
11942        throw new Error(CORE_ERROR_TEXT);
11943      }
11944      return baseIsNative(value);
11945    }
11946
11947    /**
11948     * Checks if `value` is `null`.
11949     *
11950     * @static
11951     * @memberOf _
11952     * @since 0.1.0
11953     * @category Lang
11954     * @param {*} value The value to check.
11955     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11956     * @example
11957     *
11958     * _.isNull(null);
11959     * // => true
11960     *
11961     * _.isNull(void 0);
11962     * // => false
11963     */
11964    function isNull(value) {
11965      return value === null;
11966    }
11967
11968    /**
11969     * Checks if `value` is `null` or `undefined`.
11970     *
11971     * @static
11972     * @memberOf _
11973     * @since 4.0.0
11974     * @category Lang
11975     * @param {*} value The value to check.
11976     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
11977     * @example
11978     *
11979     * _.isNil(null);
11980     * // => true
11981     *
11982     * _.isNil(void 0);
11983     * // => true
11984     *
11985     * _.isNil(NaN);
11986     * // => false
11987     */
11988    function isNil(value) {
11989      return value == null;
11990    }
11991
11992    /**
11993     * Checks if `value` is classified as a `Number` primitive or object.
11994     *
11995     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
11996     * classified as numbers, use the `_.isFinite` method.
11997     *
11998     * @static
11999     * @memberOf _
12000     * @since 0.1.0
12001     * @category Lang
12002     * @param {*} value The value to check.
12003     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
12004     * @example
12005     *
12006     * _.isNumber(3);
12007     * // => true
12008     *
12009     * _.isNumber(Number.MIN_VALUE);
12010     * // => true
12011     *
12012     * _.isNumber(Infinity);
12013     * // => true
12014     *
12015     * _.isNumber('3');
12016     * // => false
12017     */
12018    function isNumber(value) {
12019      return typeof value == 'number' ||
12020        (isObjectLike(value) && baseGetTag(value) == numberTag);
12021    }
12022
12023    /**
12024     * Checks if `value` is a plain object, that is, an object created by the
12025     * `Object` constructor or one with a `[[Prototype]]` of `null`.
12026     *
12027     * @static
12028     * @memberOf _
12029     * @since 0.8.0
12030     * @category Lang
12031     * @param {*} value The value to check.
12032     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
12033     * @example
12034     *
12035     * function Foo() {
12036     *   this.a = 1;
12037     * }
12038     *
12039     * _.isPlainObject(new Foo);
12040     * // => false
12041     *
12042     * _.isPlainObject([1, 2, 3]);
12043     * // => false
12044     *
12045     * _.isPlainObject({ 'x': 0, 'y': 0 });
12046     * // => true
12047     *
12048     * _.isPlainObject(Object.create(null));
12049     * // => true
12050     */
12051    function isPlainObject(value) {
12052      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
12053        return false;
12054      }
12055      var proto = getPrototype(value);
12056      if (proto === null) {
12057        return true;
12058      }
12059      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
12060      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
12061        funcToString.call(Ctor) == objectCtorString;
12062    }
12063
12064    /**
12065     * Checks if `value` is classified as a `RegExp` object.
12066     *
12067     * @static
12068     * @memberOf _
12069     * @since 0.1.0
12070     * @category Lang
12071     * @param {*} value The value to check.
12072     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
12073     * @example
12074     *
12075     * _.isRegExp(/abc/);
12076     * // => true
12077     *
12078     * _.isRegExp('/abc/');
12079     * // => false
12080     */
12081    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
12082
12083    /**
12084     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
12085     * double precision number which isn't the result of a rounded unsafe integer.
12086     *
12087     * **Note:** This method is based on
12088     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
12089     *
12090     * @static
12091     * @memberOf _
12092     * @since 4.0.0
12093     * @category Lang
12094     * @param {*} value The value to check.
12095     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
12096     * @example
12097     *
12098     * _.isSafeInteger(3);
12099     * // => true
12100     *
12101     * _.isSafeInteger(Number.MIN_VALUE);
12102     * // => false
12103     *
12104     * _.isSafeInteger(Infinity);
12105     * // => false
12106     *
12107     * _.isSafeInteger('3');
12108     * // => false
12109     */
12110    function isSafeInteger(value) {
12111      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
12112    }
12113
12114    /**
12115     * Checks if `value` is classified as a `Set` object.
12116     *
12117     * @static
12118     * @memberOf _
12119     * @since 4.3.0
12120     * @category Lang
12121     * @param {*} value The value to check.
12122     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
12123     * @example
12124     *
12125     * _.isSet(new Set);
12126     * // => true
12127     *
12128     * _.isSet(new WeakSet);
12129     * // => false
12130     */
12131    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
12132
12133    /**
12134     * Checks if `value` is classified as a `String` primitive or object.
12135     *
12136     * @static
12137     * @since 0.1.0
12138     * @memberOf _
12139     * @category Lang
12140     * @param {*} value The value to check.
12141     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
12142     * @example
12143     *
12144     * _.isString('abc');
12145     * // => true
12146     *
12147     * _.isString(1);
12148     * // => false
12149     */
12150    function isString(value) {
12151      return typeof value == 'string' ||
12152        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
12153    }
12154
12155    /**
12156     * Checks if `value` is classified as a `Symbol` primitive or object.
12157     *
12158     * @static
12159     * @memberOf _
12160     * @since 4.0.0
12161     * @category Lang
12162     * @param {*} value The value to check.
12163     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
12164     * @example
12165     *
12166     * _.isSymbol(Symbol.iterator);
12167     * // => true
12168     *
12169     * _.isSymbol('abc');
12170     * // => false
12171     */
12172    function isSymbol(value) {
12173      return typeof value == 'symbol' ||
12174        (isObjectLike(value) && baseGetTag(value) == symbolTag);
12175    }
12176
12177    /**
12178     * Checks if `value` is classified as a typed array.
12179     *
12180     * @static
12181     * @memberOf _
12182     * @since 3.0.0
12183     * @category Lang
12184     * @param {*} value The value to check.
12185     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
12186     * @example
12187     *
12188     * _.isTypedArray(new Uint8Array);
12189     * // => true
12190     *
12191     * _.isTypedArray([]);
12192     * // => false
12193     */
12194    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
12195
12196    /**
12197     * Checks if `value` is `undefined`.
12198     *
12199     * @static
12200     * @since 0.1.0
12201     * @memberOf _
12202     * @category Lang
12203     * @param {*} value The value to check.
12204     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
12205     * @example
12206     *
12207     * _.isUndefined(void 0);
12208     * // => true
12209     *
12210     * _.isUndefined(null);
12211     * // => false
12212     */
12213    function isUndefined(value) {
12214      return value === undefined;
12215    }
12216
12217    /**
12218     * Checks if `value` is classified as a `WeakMap` object.
12219     *
12220     * @static
12221     * @memberOf _
12222     * @since 4.3.0
12223     * @category Lang
12224     * @param {*} value The value to check.
12225     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
12226     * @example
12227     *
12228     * _.isWeakMap(new WeakMap);
12229     * // => true
12230     *
12231     * _.isWeakMap(new Map);
12232     * // => false
12233     */
12234    function isWeakMap(value) {
12235      return isObjectLike(value) && getTag(value) == weakMapTag;
12236    }
12237
12238    /**
12239     * Checks if `value` is classified as a `WeakSet` object.
12240     *
12241     * @static
12242     * @memberOf _
12243     * @since 4.3.0
12244     * @category Lang
12245     * @param {*} value The value to check.
12246     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
12247     * @example
12248     *
12249     * _.isWeakSet(new WeakSet);
12250     * // => true
12251     *
12252     * _.isWeakSet(new Set);
12253     * // => false
12254     */
12255    function isWeakSet(value) {
12256      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
12257    }
12258
12259    /**
12260     * Checks if `value` is less than `other`.
12261     *
12262     * @static
12263     * @memberOf _
12264     * @since 3.9.0
12265     * @category Lang
12266     * @param {*} value The value to compare.
12267     * @param {*} other The other value to compare.
12268     * @returns {boolean} Returns `true` if `value` is less than `other`,
12269     *  else `false`.
12270     * @see _.gt
12271     * @example
12272     *
12273     * _.lt(1, 3);
12274     * // => true
12275     *
12276     * _.lt(3, 3);
12277     * // => false
12278     *
12279     * _.lt(3, 1);
12280     * // => false
12281     */
12282    var lt = createRelationalOperation(baseLt);
12283
12284    /**
12285     * Checks if `value` is less than or equal to `other`.
12286     *
12287     * @static
12288     * @memberOf _
12289     * @since 3.9.0
12290     * @category Lang
12291     * @param {*} value The value to compare.
12292     * @param {*} other The other value to compare.
12293     * @returns {boolean} Returns `true` if `value` is less than or equal to
12294     *  `other`, else `false`.
12295     * @see _.gte
12296     * @example
12297     *
12298     * _.lte(1, 3);
12299     * // => true
12300     *
12301     * _.lte(3, 3);
12302     * // => true
12303     *
12304     * _.lte(3, 1);
12305     * // => false
12306     */
12307    var lte = createRelationalOperation(function(value, other) {
12308      return value <= other;
12309    });
12310
12311    /**
12312     * Converts `value` to an array.
vendor: 4,495 bytes, lines 12313-12494
12313     *
12314     * @static
12315     * @since 0.1.0
12316     * @memberOf _
12317     * @category Lang
12318     * @param {*} value The value to convert.
12319     * @returns {Array} Returns the converted array.
12320     * @example
12321     *
12322     * _.toArray({ 'a': 1, 'b': 2 });
12323     * // => [1, 2]
12324     *
12325     * _.toArray('abc');
12326     * // => ['a', 'b', 'c']
12327     *
12328     * _.toArray(1);
12329     * // => []
12330     *
12331     * _.toArray(null);
12332     * // => []
12333     */
12334    function toArray(value) {
12335      if (!value) {
12336        return [];
12337      }
12338      if (isArrayLike(value)) {
12339        return isString(value) ? stringToArray(value) : copyArray(value);
12340      }
12341      if (symIterator && value[symIterator]) {
12342        return iteratorToArray(value[symIterator]());
12343      }
12344      var tag = getTag(value),
12345          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
12346
12347      return func(value);
12348    }
12349
12350    /**
12351     * Converts `value` to a finite number.
12352     *
12353     * @static
12354     * @memberOf _
12355     * @since 4.12.0
12356     * @category Lang
12357     * @param {*} value The value to convert.
12358     * @returns {number} Returns the converted number.
12359     * @example
12360     *
12361     * _.toFinite(3.2);
12362     * // => 3.2
12363     *
12364     * _.toFinite(Number.MIN_VALUE);
12365     * // => 5e-324
12366     *
12367     * _.toFinite(Infinity);
12368     * // => 1.7976931348623157e+308
12369     *
12370     * _.toFinite('3.2');
12371     * // => 3.2
12372     */
12373    function toFinite(value) {
12374      if (!value) {
12375        return value === 0 ? value : 0;
12376      }
12377      value = toNumber(value);
12378      if (value === INFINITY || value === -INFINITY) {
12379        var sign = (value < 0 ? -1 : 1);
12380        return sign * MAX_INTEGER;
12381      }
12382      return value === value ? value : 0;
12383    }
12384
12385    /**
12386     * Converts `value` to an integer.
12387     *
12388     * **Note:** This method is loosely based on
12389     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
12390     *
12391     * @static
12392     * @memberOf _
12393     * @since 4.0.0
12394     * @category Lang
12395     * @param {*} value The value to convert.
12396     * @returns {number} Returns the converted integer.
12397     * @example
12398     *
12399     * _.toInteger(3.2);
12400     * // => 3
12401     *
12402     * _.toInteger(Number.MIN_VALUE);
12403     * // => 0
12404     *
12405     * _.toInteger(Infinity);
12406     * // => 1.7976931348623157e+308
12407     *
12408     * _.toInteger('3.2');
12409     * // => 3
12410     */
12411    function toInteger(value) {
12412      var result = toFinite(value),
12413          remainder = result % 1;
12414
12415      return result === result ? (remainder ? result - remainder : result) : 0;
12416    }
12417
12418    /**
12419     * Converts `value` to an integer suitable for use as the length of an
12420     * array-like object.
12421     *
12422     * **Note:** This method is based on
12423     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12424     *
12425     * @static
12426     * @memberOf _
12427     * @since 4.0.0
12428     * @category Lang
12429     * @param {*} value The value to convert.
12430     * @returns {number} Returns the converted integer.
12431     * @example
12432     *
12433     * _.toLength(3.2);
12434     * // => 3
12435     *
12436     * _.toLength(Number.MIN_VALUE);
12437     * // => 0
12438     *
12439     * _.toLength(Infinity);
12440     * // => 4294967295
12441     *
12442     * _.toLength('3.2');
12443     * // => 3
12444     */
12445    function toLength(value) {
12446      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
12447    }
12448
12449    /**
12450     * Converts `value` to a number.
12451     *
12452     * @static
12453     * @memberOf _
12454     * @since 4.0.0
12455     * @category Lang
12456     * @param {*} value The value to process.
12457     * @returns {number} Returns the number.
12458     * @example
12459     *
12460     * _.toNumber(3.2);
12461     * // => 3.2
12462     *
12463     * _.toNumber(Number.MIN_VALUE);
12464     * // => 5e-324
12465     *
12466     * _.toNumber(Infinity);
12467     * // => Infinity
12468     *
12469     * _.toNumber('3.2');
12470     * // => 3.2
12471     */
12472    function toNumber(value) {
12473      if (typeof value == 'number') {
12474        return value;
12475      }
12476      if (isSymbol(value)) {
12477        return NAN;
12478      }
12479      if (isObject(value)) {
12480        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
12481        value = isObject(other) ? (other + '') : other;
12482      }
12483      if (typeof value != 'string') {
12484        return value === 0 ? value : +value;
12485      }
12486      value = value.replace(reTrim, '');
12487      var isBinary = reIsBinary.test(value);
12488      return (isBinary || reIsOctal.test(value))
12489        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
12490        : (reIsBadHex.test(value) ? NAN : +value);
12491    }
12492
12493    /**
12494     * Converts `value` to a plain object flattening inherited enumerable str
vendor: 9,060 bytes, lines 12494-12801
12494ing
12495     * keyed properties of `value` to own properties of the plain object.
12496     *
12497     * @static
12498     * @memberOf _
12499     * @since 3.0.0
12500     * @category Lang
12501     * @param {*} value The value to convert.
12502     * @returns {Object} Returns the converted plain object.
12503     * @example
12504     *
12505     * function Foo() {
12506     *   this.b = 2;
12507     * }
12508     *
12509     * Foo.prototype.c = 3;
12510     *
12511     * _.assign({ 'a': 1 }, new Foo);
12512     * // => { 'a': 1, 'b': 2 }
12513     *
12514     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
12515     * // => { 'a': 1, 'b': 2, 'c': 3 }
12516     */
12517    function toPlainObject(value) {
12518      return copyObject(value, keysIn(value));
12519    }
12520
12521    /**
12522     * Converts `value` to a safe integer. A safe integer can be compared and
12523     * represented correctly.
12524     *
12525     * @static
12526     * @memberOf _
12527     * @since 4.0.0
12528     * @category Lang
12529     * @param {*} value The value to convert.
12530     * @returns {number} Returns the converted integer.
12531     * @example
12532     *
12533     * _.toSafeInteger(3.2);
12534     * // => 3
12535     *
12536     * _.toSafeInteger(Number.MIN_VALUE);
12537     * // => 0
12538     *
12539     * _.toSafeInteger(Infinity);
12540     * // => 9007199254740991
12541     *
12542     * _.toSafeInteger('3.2');
12543     * // => 3
12544     */
12545    function toSafeInteger(value) {
12546      return value
12547        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
12548        : (value === 0 ? value : 0);
12549    }
12550
12551    /**
12552     * Converts `value` to a string. An empty string is returned for `null`
12553     * and `undefined` values. The sign of `-0` is preserved.
12554     *
12555     * @static
12556     * @memberOf _
12557     * @since 4.0.0
12558     * @category Lang
12559     * @param {*} value The value to convert.
12560     * @returns {string} Returns the converted string.
12561     * @example
12562     *
12563     * _.toString(null);
12564     * // => ''
12565     *
12566     * _.toString(-0);
12567     * // => '-0'
12568     *
12569     * _.toString([1, 2, 3]);
12570     * // => '1,2,3'
12571     */
12572    function toString(value) {
12573      return value == null ? '' : baseToString(value);
12574    }
12575
12576    /*------------------------------------------------------------------------*/
12577
12578    /**
12579     * Assigns own enumerable string keyed properties of source objects to the
12580     * destination object. Source objects are applied from left to right.
12581     * Subsequent sources overwrite property assignments of previous sources.
12582     *
12583     * **Note:** This method mutates `object` and is loosely based on
12584     * [`Object.assign`](https://mdn.io/Object/assign).
12585     *
12586     * @static
12587     * @memberOf _
12588     * @since 0.10.0
12589     * @category Object
12590     * @param {Object} object The destination object.
12591     * @param {...Object} [sources] The source objects.
12592     * @returns {Object} Returns `object`.
12593     * @see _.assignIn
12594     * @example
12595     *
12596     * function Foo() {
12597     *   this.a = 1;
12598     * }
12599     *
12600     * function Bar() {
12601     *   this.c = 3;
12602     * }
12603     *
12604     * Foo.prototype.b = 2;
12605     * Bar.prototype.d = 4;
12606     *
12607     * _.assign({ 'a': 0 }, new Foo, new Bar);
12608     * // => { 'a': 1, 'c': 3 }
12609     */
12610    var assign = createAssigner(function(object, source) {
12611      if (isPrototype(source) || isArrayLike(source)) {
12612        copyObject(source, keys(source), object);
12613        return;
12614      }
12615      for (var key in source) {
12616        if (hasOwnProperty.call(source, key)) {
12617          assignValue(object, key, source[key]);
12618        }
12619      }
12620    });
12621
12622    /**
12623     * This method is like `_.assign` except that it iterates over own and
12624     * inherited source properties.
12625     *
12626     * **Note:** This method mutates `object`.
12627     *
12628     * @static
12629     * @memberOf _
12630     * @since 4.0.0
12631     * @alias extend
12632     * @category Object
12633     * @param {Object} object The destination object.
12634     * @param {...Object} [sources] The source objects.
12635     * @returns {Object} Returns `object`.
12636     * @see _.assign
12637     * @example
12638     *
12639     * function Foo() {
12640     *   this.a = 1;
12641     * }
12642     *
12643     * function Bar() {
12644     *   this.c = 3;
12645     * }
12646     *
12647     * Foo.prototype.b = 2;
12648     * Bar.prototype.d = 4;
12649     *
12650     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
12651     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
12652     */
12653    var assignIn = createAssigner(function(object, source) {
12654      copyObject(source, keysIn(source), object);
12655    });
12656
12657    /**
12658     * This method is like `_.assignIn` except that it accepts `customizer`
12659     * which is invoked to produce the assigned values. If `customizer` returns
12660     * `undefined`, assignment is handled by the method instead. The `customizer`
12661     * is invoked with five arguments: (objValue, srcValue, key, object, source).
12662     *
12663     * **Note:** This method mutates `object`.
12664     *
12665     * @static
12666     * @memberOf _
12667     * @since 4.0.0
12668     * @alias extendWith
12669     * @category Object
12670     * @param {Object} object The destination object.
12671     * @param {...Object} sources The source objects.
12672     * @param {Function} [customizer] The function to customize assigned values.
12673     * @returns {Object} Returns `object`.
12674     * @see _.assignWith
12675     * @example
12676     *
12677     * function customizer(objValue, srcValue) {
12678     *   return _.isUndefined(objValue) ? srcValue : objValue;
12679     * }
12680     *
12681     * var defaults = _.partialRight(_.assignInWith, customizer);
12682     *
12683     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12684     * // => { 'a': 1, 'b': 2 }
12685     */
12686    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12687      copyObject(source, keysIn(source), object, customizer);
12688    });
12689
12690    /**
12691     * This method is like `_.assign` except that it accepts `customizer`
12692     * which is invoked to produce the assigned values. If `customizer` returns
12693     * `undefined`, assignment is handled by the method instead. The `customizer`
12694     * is invoked with five arguments: (objValue, srcValue, key, object, source).
12695     *
12696     * **Note:** This method mutates `object`.
12697     *
12698     * @static
12699     * @memberOf _
12700     * @since 4.0.0
12701     * @category Object
12702     * @param {Object} object The destination object.
12703     * @param {...Object} sources The source objects.
12704     * @param {Function} [customizer] The function to customize assigned values.
12705     * @returns {Object} Returns `object`.
12706     * @see _.assignInWith
12707     * @example
12708     *
12709     * function customizer(objValue, srcValue) {
12710     *   return _.isUndefined(objValue) ? srcValue : objValue;
12711     * }
12712     *
12713     * var defaults = _.partialRight(_.assignWith, customizer);
12714     *
12715     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12716     * // => { 'a': 1, 'b': 2 }
12717     */
12718    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12719      copyObject(source, keys(source), object, customizer);
12720    });
12721
12722    /**
12723     * Creates an array of values corresponding to `paths` of `object`.
12724     *
12725     * @static
12726     * @memberOf _
12727     * @since 1.0.0
12728     * @category Object
12729     * @param {Object} object The object to iterate over.
12730     * @param {...(string|string[])} [paths] The property paths to pick.
12731     * @returns {Array} Returns the picked values.
12732     * @example
12733     *
12734     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12735     *
12736     * _.at(object, ['a[0].b.c', 'a[1]']);
12737     * // => [3, 4]
12738     */
12739    var at = flatRest(baseAt);
12740
12741    /**
12742     * Creates an object that inherits from the `prototype` object. If a
12743     * `properties` object is given, its own enumerable string keyed properties
12744     * are assigned to the created object.
12745     *
12746     * @static
12747     * @memberOf _
12748     * @since 2.3.0
12749     * @category Object
12750     * @param {Object} prototype The object to inherit from.
12751     * @param {Object} [properties] The properties to assign to the object.
12752     * @returns {Object} Returns the new object.
12753     * @example
12754     *
12755     * function Shape() {
12756     *   this.x = 0;
12757     *   this.y = 0;
12758     * }
12759     *
12760     * function Circle() {
12761     *   Shape.call(this);
12762     * }
12763     *
12764     * Circle.prototype = _.create(Shape.prototype, {
12765     *   'constructor': Circle
12766     * });
12767     *
12768     * var circle = new Circle;
12769     * circle instanceof Circle;
12770     * // => true
12771     *
12772     * circle instanceof Shape;
12773     * // => true
12774     */
12775    function create(prototype, properties) {
12776      var result = baseCreate(prototype);
12777      return properties == null ? result : baseAssign(result, properties);
12778    }
12779
12780    /**
12781     * Assigns own and inherited enumerable string keyed properties of source
12782     * objects to the destination object for all destination properties that
12783     * resolve to `undefined`. Source objects are applied from left to right.
12784     * Once a property is set, additional values of the same property are ignored.
12785     *
12786     * **Note:** This method mutates `object`.
12787     *
12788     * @static
12789     * @since 0.1.0
12790     * @memberOf _
12791     * @category Object
12792     * @param {Object} object The destination object.
12793     * @param {...Object} [sources] The source objects.
12794     * @returns {Object} Returns `object`.
12795     * @see _.defaultsDeep
12796     * @example
12797     *
12798     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12799     * // => { 'a': 1, 'b': 2 }
12800     */
12801    var defaults = baseRest(function(
12801args) {
12802      args.push(undefined, customDefaultsAssignIn);
12803      return apply(assignInWith, undefined, args)
vendor: 11,675 bytes, lines 12803-13200
12803;
12804    });
12805
12806    /**
12807     * This method is like `_.defaults` except that it recursively assigns
12808     * default properties.
12809     *
12810     * **Note:** This method mutates `object`.
12811     *
12812     * @static
12813     * @memberOf _
12814     * @since 3.10.0
12815     * @category Object
12816     * @param {Object} object The destination object.
12817     * @param {...Object} [sources] The source objects.
12818     * @returns {Object} Returns `object`.
12819     * @see _.defaults
12820     * @example
12821     *
12822     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
12823     * // => { 'a': { 'b': 2, 'c': 3 } }
12824     */
12825    var defaultsDeep = baseRest(function(args) {
12826      args.push(undefined, customDefaultsMerge);
12827      return apply(mergeWith, undefined, args);
12828    });
12829
12830    /**
12831     * This method is like `_.find` except that it returns the key of the first
12832     * element `predicate` returns truthy for instead of the element itself.
12833     *
12834     * @static
12835     * @memberOf _
12836     * @since 1.1.0
12837     * @category Object
12838     * @param {Object} object The object to inspect.
12839     * @param {Function} [predicate=_.identity] The function invoked per iteration.
12840     * @returns {string|undefined} Returns the key of the matched element,
12841     *  else `undefined`.
12842     * @example
12843     *
12844     * var users = {
12845     *   'barney':  { 'age': 36, 'active': true },
12846     *   'fred':    { 'age': 40, 'active': false },
12847     *   'pebbles': { 'age': 1,  'active': true }
12848     * };
12849     *
12850     * _.findKey(users, function(o) { return o.age < 40; });
12851     * // => 'barney' (iteration order is not guaranteed)
12852     *
12853     * // The `_.matches` iteratee shorthand.
12854     * _.findKey(users, { 'age': 1, 'active': true });
12855     * // => 'pebbles'
12856     *
12857     * // The `_.matchesProperty` iteratee shorthand.
12858     * _.findKey(users, ['active', false]);
12859     * // => 'fred'
12860     *
12861     * // The `_.property` iteratee shorthand.
12862     * _.findKey(users, 'active');
12863     * // => 'barney'
12864     */
12865    function findKey(object, predicate) {
12866      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12867    }
12868
12869    /**
12870     * This method is like `_.findKey` except that it iterates over elements of
12871     * a collection in the opposite order.
12872     *
12873     * @static
12874     * @memberOf _
12875     * @since 2.0.0
12876     * @category Object
12877     * @param {Object} object The object to inspect.
12878     * @param {Function} [predicate=_.identity] The function invoked per iteration.
12879     * @returns {string|undefined} Returns the key of the matched element,
12880     *  else `undefined`.
12881     * @example
12882     *
12883     * var users = {
12884     *   'barney':  { 'age': 36, 'active': true },
12885     *   'fred':    { 'age': 40, 'active': false },
12886     *   'pebbles': { 'age': 1,  'active': true }
12887     * };
12888     *
12889     * _.findLastKey(users, function(o) { return o.age < 40; });
12890     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12891     *
12892     * // The `_.matches` iteratee shorthand.
12893     * _.findLastKey(users, { 'age': 36, 'active': true });
12894     * // => 'barney'
12895     *
12896     * // The `_.matchesProperty` iteratee shorthand.
12897     * _.findLastKey(users, ['active', false]);
12898     * // => 'fred'
12899     *
12900     * // The `_.property` iteratee shorthand.
12901     * _.findLastKey(users, 'active');
12902     * // => 'pebbles'
12903     */
12904    function findLastKey(object, predicate) {
12905      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12906    }
12907
12908    /**
12909     * Iterates over own and inherited enumerable string keyed properties of an
12910     * object and invokes `iteratee` for each property. The iteratee is invoked
12911     * with three arguments: (value, key, object). Iteratee functions may exit
12912     * iteration early by explicitly returning `false`.
12913     *
12914     * @static
12915     * @memberOf _
12916     * @since 0.3.0
12917     * @category Object
12918     * @param {Object} object The object to iterate over.
12919     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12920     * @returns {Object} Returns `object`.
12921     * @see _.forInRight
12922     * @example
12923     *
12924     * function Foo() {
12925     *   this.a = 1;
12926     *   this.b = 2;
12927     * }
12928     *
12929     * Foo.prototype.c = 3;
12930     *
12931     * _.forIn(new Foo, function(value, key) {
12932     *   console.log(key);
12933     * });
12934     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12935     */
12936    function forIn(object, iteratee) {
12937      return object == null
12938        ? object
12939        : baseFor(object, getIteratee(iteratee, 3), keysIn);
12940    }
12941
12942    /**
12943     * This method is like `_.forIn` except that it iterates over properties of
12944     * `object` in the opposite order.
12945     *
12946     * @static
12947     * @memberOf _
12948     * @since 2.0.0
12949     * @category Object
12950     * @param {Object} object The object to iterate over.
12951     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12952     * @returns {Object} Returns `object`.
12953     * @see _.forIn
12954     * @example
12955     *
12956     * function Foo() {
12957     *   this.a = 1;
12958     *   this.b = 2;
12959     * }
12960     *
12961     * Foo.prototype.c = 3;
12962     *
12963     * _.forInRight(new Foo, function(value, key) {
12964     *   console.log(key);
12965     * });
12966     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12967     */
12968    function forInRight(object, iteratee) {
12969      return object == null
12970        ? object
12971        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
12972    }
12973
12974    /**
12975     * Iterates over own enumerable string keyed properties of an object and
12976     * invokes `iteratee` for each property. The iteratee is invoked with three
12977     * arguments: (value, key, object). Iteratee functions may exit iteration
12978     * early by explicitly returning `false`.
12979     *
12980     * @static
12981     * @memberOf _
12982     * @since 0.3.0
12983     * @category Object
12984     * @param {Object} object The object to iterate over.
12985     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12986     * @returns {Object} Returns `object`.
12987     * @see _.forOwnRight
12988     * @example
12989     *
12990     * function Foo() {
12991     *   this.a = 1;
12992     *   this.b = 2;
12993     * }
12994     *
12995     * Foo.prototype.c = 3;
12996     *
12997     * _.forOwn(new Foo, function(value, key) {
12998     *   console.log(key);
12999     * });
13000     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
13001     */
13002    function forOwn(object, iteratee) {
13003      return object && baseForOwn(object, getIteratee(iteratee, 3));
13004    }
13005
13006    /**
13007     * This method is like `_.forOwn` except that it iterates over properties of
13008     * `object` in the opposite order.
13009     *
13010     * @static
13011     * @memberOf _
13012     * @since 2.0.0
13013     * @category Object
13014     * @param {Object} object The object to iterate over.
13015     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13016     * @returns {Object} Returns `object`.
13017     * @see _.forOwn
13018     * @example
13019     *
13020     * function Foo() {
13021     *   this.a = 1;
13022     *   this.b = 2;
13023     * }
13024     *
13025     * Foo.prototype.c = 3;
13026     *
13027     * _.forOwnRight(new Foo, function(value, key) {
13028     *   console.log(key);
13029     * });
13030     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
13031     */
13032    function forOwnRight(object, iteratee) {
13033      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
13034    }
13035
13036    /**
13037     * Creates an array of function property names from own enumerable properties
13038     * of `object`.
13039     *
13040     * @static
13041     * @since 0.1.0
13042     * @memberOf _
13043     * @category Object
13044     * @param {Object} object The object to inspect.
13045     * @returns {Array} Returns the function names.
13046     * @see _.functionsIn
13047     * @example
13048     *
13049     * function Foo() {
13050     *   this.a = _.constant('a');
13051     *   this.b = _.constant('b');
13052     * }
13053     *
13054     * Foo.prototype.c = _.constant('c');
13055     *
13056     * _.functions(new Foo);
13057     * // => ['a', 'b']
13058     */
13059    function functions(object) {
13060      return object == null ? [] : baseFunctions(object, keys(object));
13061    }
13062
13063    /**
13064     * Creates an array of function property names from own and inherited
13065     * enumerable properties of `object`.
13066     *
13067     * @static
13068     * @memberOf _
13069     * @since 4.0.0
13070     * @category Object
13071     * @param {Object} object The object to inspect.
13072     * @returns {Array} Returns the function names.
13073     * @see _.functions
13074     * @example
13075     *
13076     * function Foo() {
13077     *   this.a = _.constant('a');
13078     *   this.b = _.constant('b');
13079     * }
13080     *
13081     * Foo.prototype.c = _.constant('c');
13082     *
13083     * _.functionsIn(new Foo);
13084     * // => ['a', 'b', 'c']
13085     */
13086    function functionsIn(object) {
13087      return object == null ? [] : baseFunctions(object, keysIn(object));
13088    }
13089
13090    /**
13091     * Gets the value at `path` of `object`. If the resolved value is
13092     * `undefined`, the `defaultValue` is returned in its place.
13093     *
13094     * @static
13095     * @memberOf _
13096     * @since 3.7.0
13097     * @category Object
13098     * @param {Object} object The object to query.
13099     * @param {Array|string} path The path of the property to get.
13100     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13101     * @returns {*} Returns the resolved value.
13102     * @example
13103     *
13104     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13105     *
13106     * _.get(object, 'a[0].b.c');
13107     * // => 3
13108     *
13109     * _.get(object, ['a', '0', 'b', 'c']);
13110     * // => 3
13111     *
13112     * _.get(object, 'a.b.c', 'default');
13113     * // => 'default'
13114     */
13115    function get(object, path, defaultValue) {
13116      var result = object == null ? undefined : baseGet(object, path);
13117      return result === undefined ? defaultValue : result;
13118    }
13119
13120    /**
13121     * Checks if `path` is a direct property of `object`.
13122     *
13123     * @static
13124     * @since 0.1.0
13125     * @memberOf _
13126     * @category Object
13127     * @param {Object} object The object to query.
13128     * @param {Array|string} path The path to check.
13129     * @returns {boolean} Returns `true` if `path` exists, else `false`.
13130     * @example
13131     *
13132     * var object = { 'a': { 'b': 2 } };
13133     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
13134     *
13135     * _.has(object, 'a');
13136     * // => true
13137     *
13138     * _.has(object, 'a.b');
13139     * // => true
13140     *
13141     * _.has(object, ['a', 'b']);
13142     * // => true
13143     *
13144     * _.has(other, 'a');
13145     * // => false
13146     */
13147    function has(object, path) {
13148      return object != null && hasPath(object, path, baseHas);
13149    }
13150
13151    /**
13152     * Checks if `path` is a direct or inherited property of `object`.
13153     *
13154     * @static
13155     * @memberOf _
13156     * @since 4.0.0
13157     * @category Object
13158     * @param {Object} object The object to query.
13159     * @param {Array|string} path The path to check.
13160     * @returns {boolean} Returns `true` if `path` exists, else `false`.
13161     * @example
13162     *
13163     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
13164     *
13165     * _.hasIn(object, 'a');
13166     * // => true
13167     *
13168     * _.hasIn(object, 'a.b');
13169     * // => true
13170     *
13171     * _.hasIn(object, ['a', 'b']);
13172     * // => true
13173     *
13174     * _.hasIn(object, 'b');
13175     * // => false
13176     */
13177    function hasIn(object, path) {
13178      return object != null && hasPath(object, path, baseHasIn);
13179    }
13180
13181    /**
13182     * Creates an object composed of the inverted keys and values of `object`.
13183     * If `object` contains duplicate values, subsequent values overwrite
13184     * property assignments of previous values.
13185     *
13186     * @static
13187     * @memberOf _
13188     * @since 0.7.0
13189     * @category Object
13190     * @param {Object} object The object to invert.
13191     * @returns {Object} Returns the new inverted object.
13192     * @example
13193     *
13194     * var object = { 'a': 1, 'b': 2, 'c': 1 };
13195     *
13196     * _.invert(object);
13197     * // => { '1': 'c', '2': 'b' }
13198     */
13199    var invert = createInverter(function(result, value, key) {
13200      
13200result[value] = key;
13201    }, constant(identity));
13202
13203    /**
13204     * This method is like `_.invert` except that the inverted object is generated
13205     * from the results of running each element of `object` thru `iteratee`. The
13206     * corresponding inverted value of each inverted key is an array of keys
13207     * responsible for generating the inverted value. The iteratee is invoked
13208     * with one argument: (value).
13209     *
13210     * @static
13211     * @memberOf _
13212     * @since 4.1.0
13213     * @category Object
13214     * @param {Object} object The object to invert.
13215     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
13216     * @returns {Object} Returns the new inverted object.
13217     * @example
13218     *
13219     * var object = { 'a': 1, 'b': 2, 'c': 1 };
13220     *
13221     * _.invertBy(object);
13222     * // => { '1': ['a', 'c'], '2': ['b'] }
13223     *
13224     * _.invertBy(object, function(value) {
13225     *   return 'group' + value;
13226     * });
13227     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
13228     */
13229    var invertBy = createInverter(function(result, value, key) {
vendor: 9,906 bytes, lines 13229-13542
13229
13230      if (hasOwnProperty.call(result, value)) {
13231        result[value].push(key);
13232      } else {
13233        result[value] = [key];
13234      }
13235    }, getIteratee);
13236
13237    /**
13238     * Invokes the method at `path` of `object`.
13239     *
13240     * @static
13241     * @memberOf _
13242     * @since 4.0.0
13243     * @category Object
13244     * @param {Object} object The object to query.
13245     * @param {Array|string} path The path of the method to invoke.
13246     * @param {...*} [args] The arguments to invoke the method with.
13247     * @returns {*} Returns the result of the invoked method.
13248     * @example
13249     *
13250     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
13251     *
13252     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
13253     * // => [2, 3]
13254     */
13255    var invoke = baseRest(baseInvoke);
13256
13257    /**
13258     * Creates an array of the own enumerable property names of `object`.
13259     *
13260     * **Note:** Non-object values are coerced to objects. See the
13261     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13262     * for more details.
13263     *
13264     * @static
13265     * @since 0.1.0
13266     * @memberOf _
13267     * @category Object
13268     * @param {Object} object The object to query.
13269     * @returns {Array} Returns the array of property names.
13270     * @example
13271     *
13272     * function Foo() {
13273     *   this.a = 1;
13274     *   this.b = 2;
13275     * }
13276     *
13277     * Foo.prototype.c = 3;
13278     *
13279     * _.keys(new Foo);
13280     * // => ['a', 'b'] (iteration order is not guaranteed)
13281     *
13282     * _.keys('hi');
13283     * // => ['0', '1']
13284     */
13285    function keys(object) {
13286      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
13287    }
13288
13289    /**
13290     * Creates an array of the own and inherited enumerable property names of `object`.
13291     *
13292     * **Note:** Non-object values are coerced to objects.
13293     *
13294     * @static
13295     * @memberOf _
13296     * @since 3.0.0
13297     * @category Object
13298     * @param {Object} object The object to query.
13299     * @returns {Array} Returns the array of property names.
13300     * @example
13301     *
13302     * function Foo() {
13303     *   this.a = 1;
13304     *   this.b = 2;
13305     * }
13306     *
13307     * Foo.prototype.c = 3;
13308     *
13309     * _.keysIn(new Foo);
13310     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
13311     */
13312    function keysIn(object) {
13313      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
13314    }
13315
13316    /**
13317     * The opposite of `_.mapValues`; this method creates an object with the
13318     * same values as `object` and keys generated by running each own enumerable
13319     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
13320     * with three arguments: (value, key, object).
13321     *
13322     * @static
13323     * @memberOf _
13324     * @since 3.8.0
13325     * @category Object
13326     * @param {Object} object The object to iterate over.
13327     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13328     * @returns {Object} Returns the new mapped object.
13329     * @see _.mapValues
13330     * @example
13331     *
13332     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
13333     *   return key + value;
13334     * });
13335     * // => { 'a1': 1, 'b2': 2 }
13336     */
13337    function mapKeys(object, iteratee) {
13338      var result = {};
13339      iteratee = getIteratee(iteratee, 3);
13340
13341      baseForOwn(object, function(value, key, object) {
13342        baseAssignValue(result, iteratee(value, key, object), value);
13343      });
13344      return result;
13345    }
13346
13347    /**
13348     * Creates an object with the same keys as `object` and values generated
13349     * by running each own enumerable string keyed property of `object` thru
13350     * `iteratee`. The iteratee is invoked with three arguments:
13351     * (value, key, object).
13352     *
13353     * @static
13354     * @memberOf _
13355     * @since 2.4.0
13356     * @category Object
13357     * @param {Object} object The object to iterate over.
13358     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13359     * @returns {Object} Returns the new mapped object.
13360     * @see _.mapKeys
13361     * @example
13362     *
13363     * var users = {
13364     *   'fred':    { 'user': 'fred',    'age': 40 },
13365     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
13366     * };
13367     *
13368     * _.mapValues(users, function(o) { return o.age; });
13369     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13370     *
13371     * // The `_.property` iteratee shorthand.
13372     * _.mapValues(users, 'age');
13373     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
13374     */
13375    function mapValues(object, iteratee) {
13376      var result = {};
13377      iteratee = getIteratee(iteratee, 3);
13378
13379      baseForOwn(object, function(value, key, object) {
13380        baseAssignValue(result, key, iteratee(value, key, object));
13381      });
13382      return result;
13383    }
13384
13385    /**
13386     * This method is like `_.assign` except that it recursively merges own and
13387     * inherited enumerable string keyed properties of source objects into the
13388     * destination object. Source properties that resolve to `undefined` are
13389     * skipped if a destination value exists. Array and plain object properties
13390     * are merged recursively. Other objects and value types are overridden by
13391     * assignment. Source objects are applied from left to right. Subsequent
13392     * sources overwrite property assignments of previous sources.
13393     *
13394     * **Note:** This method mutates `object`.
13395     *
13396     * @static
13397     * @memberOf _
13398     * @since 0.5.0
13399     * @category Object
13400     * @param {Object} object The destination object.
13401     * @param {...Object} [sources] The source objects.
13402     * @returns {Object} Returns `object`.
13403     * @example
13404     *
13405     * var object = {
13406     *   'a': [{ 'b': 2 }, { 'd': 4 }]
13407     * };
13408     *
13409     * var other = {
13410     *   'a': [{ 'c': 3 }, { 'e': 5 }]
13411     * };
13412     *
13413     * _.merge(object, other);
13414     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
13415     */
13416    var merge = createAssigner(function(object, source, srcIndex) {
13417      baseMerge(object, source, srcIndex);
13418    });
13419
13420    /**
13421     * This method is like `_.merge` except that it accepts `customizer` which
13422     * is invoked to produce the merged values of the destination and source
13423     * properties. If `customizer` returns `undefined`, merging is handled by the
13424     * method instead. The `customizer` is invoked with six arguments:
13425     * (objValue, srcValue, key, object, source, stack).
13426     *
13427     * **Note:** This method mutates `object`.
13428     *
13429     * @static
13430     * @memberOf _
13431     * @since 4.0.0
13432     * @category Object
13433     * @param {Object} object The destination object.
13434     * @param {...Object} sources The source objects.
13435     * @param {Function} customizer The function to customize assigned values.
13436     * @returns {Object} Returns `object`.
13437     * @example
13438     *
13439     * function customizer(objValue, srcValue) {
13440     *   if (_.isArray(objValue)) {
13441     *     return objValue.concat(srcValue);
13442     *   }
13443     * }
13444     *
13445     * var object = { 'a': [1], 'b': [2] };
13446     * var other = { 'a': [3], 'b': [4] };
13447     *
13448     * _.mergeWith(object, other, customizer);
13449     * // => { 'a': [1, 3], 'b': [2, 4] }
13450     */
13451    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
13452      baseMerge(object, source, srcIndex, customizer);
13453    });
13454
13455    /**
13456     * The opposite of `_.pick`; this method creates an object composed of the
13457     * own and inherited enumerable property paths of `object` that are not omitted.
13458     *
13459     * **Note:** This method is considerably slower than `_.pick`.
13460     *
13461     * @static
13462     * @since 0.1.0
13463     * @memberOf _
13464     * @category Object
13465     * @param {Object} object The source object.
13466     * @param {...(string|string[])} [paths] The property paths to omit.
13467     * @returns {Object} Returns the new object.
13468     * @example
13469     *
13470     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13471     *
13472     * _.omit(object, ['a', 'c']);
13473     * // => { 'b': '2' }
13474     */
13475    var omit = flatRest(function(object, paths) {
13476      var result = {};
13477      if (object == null) {
13478        return result;
13479      }
13480      var isDeep = false;
13481      paths = arrayMap(paths, function(path) {
13482        path = castPath(path, object);
13483        isDeep || (isDeep = path.length > 1);
13484        return path;
13485      });
13486      copyObject(object, getAllKeysIn(object), result);
13487      if (isDeep) {
13488        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
13489      }
13490      var length = paths.length;
13491      while (length--) {
13492        baseUnset(result, paths[length]);
13493      }
13494      return result;
13495    });
13496
13497    /**
13498     * The opposite of `_.pickBy`; this method creates an object composed of
13499     * the own and inherited enumerable string keyed properties of `object` that
13500     * `predicate` doesn't return truthy for. The predicate is invoked with two
13501     * arguments: (value, key).
13502     *
13503     * @static
13504     * @memberOf _
13505     * @since 4.0.0
13506     * @category Object
13507     * @param {Object} object The source object.
13508     * @param {Function} [predicate=_.identity] The function invoked per property.
13509     * @returns {Object} Returns the new object.
13510     * @example
13511     *
13512     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13513     *
13514     * _.omitBy(object, _.isNumber);
13515     * // => { 'b': '2' }
13516     */
13517    function omitBy(object, predicate) {
13518      return pickBy(object, negate(getIteratee(predicate)));
13519    }
13520
13521    /**
13522     * Creates an object composed of the picked `object` properties.
13523     *
13524     * @static
13525     * @since 0.1.0
13526     * @memberOf _
13527     * @category Object
13528     * @param {Object} object The source object.
13529     * @param {...(string|string[])} [paths] The property paths to pick.
13530     * @returns {Object} Returns the new object.
13531     * @example
13532     *
13533     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13534     *
13535     * _.pick(object, ['a', 'c']);
13536     * // => { 'a': 1, 'c': 3 }
13537     */
13538    var pick = flatRest(function(object, paths) {
13539      return object == null ? {} : basePick(object, paths);
13540    });
13541
13542    /**
vendor: 11,160 bytes, lines 13543-13881
13543     * Creates an object composed of the `object` properties `predicate` returns
13544     * truthy for. The predicate is invoked with two arguments: (value, key).
13545     *
13546     * @static
13547     * @memberOf _
13548     * @since 4.0.0
13549     * @category Object
13550     * @param {Object} object The source object.
13551     * @param {Function} [predicate=_.identity] The function invoked per property.
13552     * @returns {Object} Returns the new object.
13553     * @example
13554     *
13555     * var object = { 'a': 1, 'b': '2', 'c': 3 };
13556     *
13557     * _.pickBy(object, _.isNumber);
13558     * // => { 'a': 1, 'c': 3 }
13559     */
13560    function pickBy(object, predicate) {
13561      if (object == null) {
13562        return {};
13563      }
13564      var props = arrayMap(getAllKeysIn(object), function(prop) {
13565        return [prop];
13566      });
13567      predicate = getIteratee(predicate);
13568      return basePickBy(object, props, function(value, path) {
13569        return predicate(value, path[0]);
13570      });
13571    }
13572
13573    /**
13574     * This method is like `_.get` except that if the resolved value is a
13575     * function it's invoked with the `this` binding of its parent object and
13576     * its result is returned.
13577     *
13578     * @static
13579     * @since 0.1.0
13580     * @memberOf _
13581     * @category Object
13582     * @param {Object} object The object to query.
13583     * @param {Array|string} path The path of the property to resolve.
13584     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
13585     * @returns {*} Returns the resolved value.
13586     * @example
13587     *
13588     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
13589     *
13590     * _.result(object, 'a[0].b.c1');
13591     * // => 3
13592     *
13593     * _.result(object, 'a[0].b.c2');
13594     * // => 4
13595     *
13596     * _.result(object, 'a[0].b.c3', 'default');
13597     * // => 'default'
13598     *
13599     * _.result(object, 'a[0].b.c3', _.constant('default'));
13600     * // => 'default'
13601     */
13602    function result(object, path, defaultValue) {
13603      path = castPath(path, object);
13604
13605      var index = -1,
13606          length = path.length;
13607
13608      // Ensure the loop is entered when path is empty.
13609      if (!length) {
13610        length = 1;
13611        object = undefined;
13612      }
13613      while (++index < length) {
13614        var value = object == null ? undefined : object[toKey(path[index])];
13615        if (value === undefined) {
13616          index = length;
13617          value = defaultValue;
13618        }
13619        object = isFunction(value) ? value.call(object) : value;
13620      }
13621      return object;
13622    }
13623
13624    /**
13625     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
13626     * it's created. Arrays are created for missing index properties while objects
13627     * are created for all other missing properties. Use `_.setWith` to customize
13628     * `path` creation.
13629     *
13630     * **Note:** This method mutates `object`.
13631     *
13632     * @static
13633     * @memberOf _
13634     * @since 3.7.0
13635     * @category Object
13636     * @param {Object} object The object to modify.
13637     * @param {Array|string} path The path of the property to set.
13638     * @param {*} value The value to set.
13639     * @returns {Object} Returns `object`.
13640     * @example
13641     *
13642     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13643     *
13644     * _.set(object, 'a[0].b.c', 4);
13645     * console.log(object.a[0].b.c);
13646     * // => 4
13647     *
13648     * _.set(object, ['x', '0', 'y', 'z'], 5);
13649     * console.log(object.x[0].y.z);
13650     * // => 5
13651     */
13652    function set(object, path, value) {
13653      return object == null ? object : baseSet(object, path, value);
13654    }
13655
13656    /**
13657     * This method is like `_.set` except that it accepts `customizer` which is
13658     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13659     * path creation is handled by the method instead. The `customizer` is invoked
13660     * with three arguments: (nsValue, key, nsObject).
13661     *
13662     * **Note:** This method mutates `object`.
13663     *
13664     * @static
13665     * @memberOf _
13666     * @since 4.0.0
13667     * @category Object
13668     * @param {Object} object The object to modify.
13669     * @param {Array|string} path The path of the property to set.
13670     * @param {*} value The value to set.
13671     * @param {Function} [customizer] The function to customize assigned values.
13672     * @returns {Object} Returns `object`.
13673     * @example
13674     *
13675     * var object = {};
13676     *
13677     * _.setWith(object, '[0][1]', 'a', Object);
13678     * // => { '0': { '1': 'a' } }
13679     */
13680    function setWith(object, path, value, customizer) {
13681      customizer = typeof customizer == 'function' ? customizer : undefined;
13682      return object == null ? object : baseSet(object, path, value, customizer);
13683    }
13684
13685    /**
13686     * Creates an array of own enumerable string keyed-value pairs for `object`
13687     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13688     * entries are returned.
13689     *
13690     * @static
13691     * @memberOf _
13692     * @since 4.0.0
13693     * @alias entries
13694     * @category Object
13695     * @param {Object} object The object to query.
13696     * @returns {Array} Returns the key-value pairs.
13697     * @example
13698     *
13699     * function Foo() {
13700     *   this.a = 1;
13701     *   this.b = 2;
13702     * }
13703     *
13704     * Foo.prototype.c = 3;
13705     *
13706     * _.toPairs(new Foo);
13707     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13708     */
13709    var toPairs = createToPairs(keys);
13710
13711    /**
13712     * Creates an array of own and inherited enumerable string keyed-value pairs
13713     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13714     * or set, its entries are returned.
13715     *
13716     * @static
13717     * @memberOf _
13718     * @since 4.0.0
13719     * @alias entriesIn
13720     * @category Object
13721     * @param {Object} object The object to query.
13722     * @returns {Array} Returns the key-value pairs.
13723     * @example
13724     *
13725     * function Foo() {
13726     *   this.a = 1;
13727     *   this.b = 2;
13728     * }
13729     *
13730     * Foo.prototype.c = 3;
13731     *
13732     * _.toPairsIn(new Foo);
13733     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13734     */
13735    var toPairsIn = createToPairs(keysIn);
13736
13737    /**
13738     * An alternative to `_.reduce`; this method transforms `object` to a new
13739     * `accumulator` object which is the result of running each of its own
13740     * enumerable string keyed properties thru `iteratee`, with each invocation
13741     * potentially mutating the `accumulator` object. If `accumulator` is not
13742     * provided, a new object with the same `[[Prototype]]` will be used. The
13743     * iteratee is invoked with four arguments: (accumulator, value, key, object).
13744     * Iteratee functions may exit iteration early by explicitly returning `false`.
13745     *
13746     * @static
13747     * @memberOf _
13748     * @since 1.3.0
13749     * @category Object
13750     * @param {Object} object The object to iterate over.
13751     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13752     * @param {*} [accumulator] The custom accumulator value.
13753     * @returns {*} Returns the accumulated value.
13754     * @example
13755     *
13756     * _.transform([2, 3, 4], function(result, n) {
13757     *   result.push(n *= n);
13758     *   return n % 2 == 0;
13759     * }, []);
13760     * // => [4, 9]
13761     *
13762     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13763     *   (result[value] || (result[value] = [])).push(key);
13764     * }, {});
13765     * // => { '1': ['a', 'c'], '2': ['b'] }
13766     */
13767    function transform(object, iteratee, accumulator) {
13768      var isArr = isArray(object),
13769          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
13770
13771      iteratee = getIteratee(iteratee, 4);
13772      if (accumulator == null) {
13773        var Ctor = object && object.constructor;
13774        if (isArrLike) {
13775          accumulator = isArr ? new Ctor : [];
13776        }
13777        else if (isObject(object)) {
13778          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13779        }
13780        else {
13781          accumulator = {};
13782        }
13783      }
13784      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
13785        return iteratee(accumulator, value, index, object);
13786      });
13787      return accumulator;
13788    }
13789
13790    /**
13791     * Removes the property at `path` of `object`.
13792     *
13793     * **Note:** This method mutates `object`.
13794     *
13795     * @static
13796     * @memberOf _
13797     * @since 4.0.0
13798     * @category Object
13799     * @param {Object} object The object to modify.
13800     * @param {Array|string} path The path of the property to unset.
13801     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13802     * @example
13803     *
13804     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13805     * _.unset(object, 'a[0].b.c');
13806     * // => true
13807     *
13808     * console.log(object);
13809     * // => { 'a': [{ 'b': {} }] };
13810     *
13811     * _.unset(object, ['a', '0', 'b', 'c']);
13812     * // => true
13813     *
13814     * console.log(object);
13815     * // => { 'a': [{ 'b': {} }] };
13816     */
13817    function unset(object, path) {
13818      return object == null ? true : baseUnset(object, path);
13819    }
13820
13821    /**
13822     * This method is like `_.set` except that accepts `updater` to produce the
13823     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13824     * is invoked with one argument: (value).
13825     *
13826     * **Note:** This method mutates `object`.
13827     *
13828     * @static
13829     * @memberOf _
13830     * @since 4.6.0
13831     * @category Object
13832     * @param {Object} object The object to modify.
13833     * @param {Array|string} path The path of the property to set.
13834     * @param {Function} updater The function to produce the updated value.
13835     * @returns {Object} Returns `object`.
13836     * @example
13837     *
13838     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13839     *
13840     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13841     * console.log(object.a[0].b.c);
13842     * // => 9
13843     *
13844     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13845     * console.log(object.x[0].y.z);
13846     * // => 0
13847     */
13848    function update(object, path, updater) {
13849      return object == null ? object : baseUpdate(object, path, castFunction(updater));
13850    }
13851
13852    /**
13853     * This method is like `_.update` except that it accepts `customizer` which is
13854     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13855     * path creation is handled by the method instead. The `customizer` is invoked
13856     * with three arguments: (nsValue, key, nsObject).
13857     *
13858     * **Note:** This method mutates `object`.
13859     *
13860     * @static
13861     * @memberOf _
13862     * @since 4.6.0
13863     * @category Object
13864     * @param {Object} object The object to modify.
13865     * @param {Array|string} path The path of the property to set.
13866     * @param {Function} updater The function to produce the updated value.
13867     * @param {Function} [customizer] The function to customize assigned values.
13868     * @returns {Object} Returns `object`.
13869     * @example
13870     *
13871     * var object = {};
13872     *
13873     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13874     * // => { '0': { '1': 'a' } }
13875     */
13876    function updateWith(object, path, updater, customizer) {
13877      customizer = typeof customizer == 'function' ? customizer : undefined;
13878      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13879    }
13880
13881    /**
vendor: 1,263 bytes, lines 13882-13931
13882     * Creates an array of the own enumerable string keyed property values of `object`.
13883     *
13884     * **Note:** Non-object values are coerced to objects.
13885     *
13886     * @static
13887     * @since 0.1.0
13888     * @memberOf _
13889     * @category Object
13890     * @param {Object} object The object to query.
13891     * @returns {Array} Returns the array of property values.
13892     * @example
13893     *
13894     * function Foo() {
13895     *   this.a = 1;
13896     *   this.b = 2;
13897     * }
13898     *
13899     * Foo.prototype.c = 3;
13900     *
13901     * _.values(new Foo);
13902     * // => [1, 2] (iteration order is not guaranteed)
13903     *
13904     * _.values('hi');
13905     * // => ['h', 'i']
13906     */
13907    function values(object) {
13908      return object == null ? [] : baseValues(object, keys(object));
13909    }
13910
13911    /**
13912     * Creates an array of the own and inherited enumerable string keyed property
13913     * values of `object`.
13914     *
13915     * **Note:** Non-object values are coerced to objects.
13916     *
13917     * @static
13918     * @memberOf _
13919     * @since 3.0.0
13920     * @category Object
13921     * @param {Object} object The object to query.
13922     * @returns {Array} Returns the array of property values.
13923     * @example
13924     *
13925     * function Foo() {
13926     *   this.a = 1;
13927     *   this.b = 2;
13928     * }
13929     *
13930     * Foo.prototype.c = 3;
13931     *
vendor: 9,679 bytes, lines 13932-14252
13932     * _.valuesIn(new Foo);
13933     * // => [1, 2, 3] (iteration order is not guaranteed)
13934     */
13935    function valuesIn(object) {
13936      return object == null ? [] : baseValues(object, keysIn(object));
13937    }
13938
13939    /*------------------------------------------------------------------------*/
13940
13941    /**
13942     * Clamps `number` within the inclusive `lower` and `upper` bounds.
13943     *
13944     * @static
13945     * @memberOf _
13946     * @since 4.0.0
13947     * @category Number
13948     * @param {number} number The number to clamp.
13949     * @param {number} [lower] The lower bound.
13950     * @param {number} upper The upper bound.
13951     * @returns {number} Returns the clamped number.
13952     * @example
13953     *
13954     * _.clamp(-10, -5, 5);
13955     * // => -5
13956     *
13957     * _.clamp(10, -5, 5);
13958     * // => 5
13959     */
13960    function clamp(number, lower, upper) {
13961      if (upper === undefined) {
13962        upper = lower;
13963        lower = undefined;
13964      }
13965      if (upper !== undefined) {
13966        upper = toNumber(upper);
13967        upper = upper === upper ? upper : 0;
13968      }
13969      if (lower !== undefined) {
13970        lower = toNumber(lower);
13971        lower = lower === lower ? lower : 0;
13972      }
13973      return baseClamp(toNumber(number), lower, upper);
13974    }
13975
13976    /**
13977     * Checks if `n` is between `start` and up to, but not including, `end`. If
13978     * `end` is not specified, it's set to `start` with `start` then set to `0`.
13979     * If `start` is greater than `end` the params are swapped to support
13980     * negative ranges.
13981     *
13982     * @static
13983     * @memberOf _
13984     * @since 3.3.0
13985     * @category Number
13986     * @param {number} number The number to check.
13987     * @param {number} [start=0] The start of the range.
13988     * @param {number} end The end of the range.
13989     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
13990     * @see _.range, _.rangeRight
13991     * @example
13992     *
13993     * _.inRange(3, 2, 4);
13994     * // => true
13995     *
13996     * _.inRange(4, 8);
13997     * // => true
13998     *
13999     * _.inRange(4, 2);
14000     * // => false
14001     *
14002     * _.inRange(2, 2);
14003     * // => false
14004     *
14005     * _.inRange(1.2, 2);
14006     * // => true
14007     *
14008     * _.inRange(5.2, 4);
14009     * // => false
14010     *
14011     * _.inRange(-3, -2, -6);
14012     * // => true
14013     */
14014    function inRange(number, start, end) {
14015      start = toFinite(start);
14016      if (end === undefined) {
14017        end = start;
14018        start = 0;
14019      } else {
14020        end = toFinite(end);
14021      }
14022      number = toNumber(number);
14023      return baseInRange(number, start, end);
14024    }
14025
14026    /**
14027     * Produces a random number between the inclusive `lower` and `upper` bounds.
14028     * If only one argument is provided a number between `0` and the given number
14029     * is returned. If `floating` is `true`, or either `lower` or `upper` are
14030     * floats, a floating-point number is returned instead of an integer.
14031     *
14032     * **Note:** JavaScript follows the IEEE-754 standard for resolving
14033     * floating-point values which can produce unexpected results.
14034     *
14035     * @static
14036     * @memberOf _
14037     * @since 0.7.0
14038     * @category Number
14039     * @param {number} [lower=0] The lower bound.
14040     * @param {number} [upper=1] The upper bound.
14041     * @param {boolean} [floating] Specify returning a floating-point number.
14042     * @returns {number} Returns the random number.
14043     * @example
14044     *
14045     * _.random(0, 5);
14046     * // => an integer between 0 and 5
14047     *
14048     * _.random(5);
14049     * // => also an integer between 0 and 5
14050     *
14051     * _.random(5, true);
14052     * // => a floating-point number between 0 and 5
14053     *
14054     * _.random(1.2, 5.2);
14055     * // => a floating-point number between 1.2 and 5.2
14056     */
14057    function random(lower, upper, floating) {
14058      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
14059        upper = floating = undefined;
14060      }
14061      if (floating === undefined) {
14062        if (typeof upper == 'boolean') {
14063          floating = upper;
14064          upper = undefined;
14065        }
14066        else if (typeof lower == 'boolean') {
14067          floating = lower;
14068          lower = undefined;
14069        }
14070      }
14071      if (lower === undefined && upper === undefined) {
14072        lower = 0;
14073        upper = 1;
14074      }
14075      else {
14076        lower = toFinite(lower);
14077        if (upper === undefined) {
14078          upper = lower;
14079          lower = 0;
14080        } else {
14081          upper = toFinite(upper);
14082        }
14083      }
14084      if (lower > upper) {
14085        var temp = lower;
14086        lower = upper;
14087        upper = temp;
14088      }
14089      if (floating || lower % 1 || upper % 1) {
14090        var rand = nativeRandom();
14091        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
14092      }
14093      return baseRandom(lower, upper);
14094    }
14095
14096    /*------------------------------------------------------------------------*/
14097
14098    /**
14099     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
14100     *
14101     * @static
14102     * @memberOf _
14103     * @since 3.0.0
14104     * @category String
14105     * @param {string} [string=''] The string to convert.
14106     * @returns {string} Returns the camel cased string.
14107     * @example
14108     *
14109     * _.camelCase('Foo Bar');
14110     * // => 'fooBar'
14111     *
14112     * _.camelCase('--foo-bar--');
14113     * // => 'fooBar'
14114     *
14115     * _.camelCase('__FOO_BAR__');
14116     * // => 'fooBar'
14117     */
14118    var camelCase = createCompounder(function(result, word, index) {
14119      word = word.toLowerCase();
14120      return result + (index ? capitalize(word) : word);
14121    });
14122
14123    /**
14124     * Converts the first character of `string` to upper case and the remaining
14125     * to lower case.
14126     *
14127     * @static
14128     * @memberOf _
14129     * @since 3.0.0
14130     * @category String
14131     * @param {string} [string=''] The string to capitalize.
14132     * @returns {string} Returns the capitalized string.
14133     * @example
14134     *
14135     * _.capitalize('FRED');
14136     * // => 'Fred'
14137     */
14138    function capitalize(string) {
14139      return upperFirst(toString(string).toLowerCase());
14140    }
14141
14142    /**
14143     * Deburrs `string` by converting
14144     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
14145     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
14146     * letters to basic Latin letters and removing
14147     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
14148     *
14149     * @static
14150     * @memberOf _
14151     * @since 3.0.0
14152     * @category String
14153     * @param {string} [string=''] The string to deburr.
14154     * @returns {string} Returns the deburred string.
14155     * @example
14156     *
14157     * _.deburr('déjà vu');
14158     * // => 'deja vu'
14159     */
14160    function deburr(string) {
14161      string = toString(string);
14162      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
14163    }
14164
14165    /**
14166     * Checks if `string` ends with the given target string.
14167     *
14168     * @static
14169     * @memberOf _
14170     * @since 3.0.0
14171     * @category String
14172     * @param {string} [string=''] The string to inspect.
14173     * @param {string} [target] The string to search for.
14174     * @param {number} [position=string.length] The position to search up to.
14175     * @returns {boolean} Returns `true` if `string` ends with `target`,
14176     *  else `false`.
14177     * @example
14178     *
14179     * _.endsWith('abc', 'c');
14180     * // => true
14181     *
14182     * _.endsWith('abc', 'b');
14183     * // => false
14184     *
14185     * _.endsWith('abc', 'b', 2);
14186     * // => true
14187     */
14188    function endsWith(string, target, position) {
14189      string = toString(string);
14190      target = baseToString(target);
14191
14192      var length = string.length;
14193      position = position === undefined
14194        ? length
14195        : baseClamp(toInteger(position), 0, length);
14196
14197      var end = position;
14198      position -= target.length;
14199      return position >= 0 && string.slice(position, end) == target;
14200    }
14201
14202    /**
14203     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
14204     * corresponding HTML entities.
14205     *
14206     * **Note:** No other characters are escaped. To escape additional
14207     * characters use a third-party library like [_he_](https://mths.be/he).
14208     *
14209     * Though the ">" character is escaped for symmetry, characters like
14210     * ">" and "/" don't need escaping in HTML and have no special meaning
14211     * unless they're part of a tag or unquoted attribute value. See
14212     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
14213     * (under "semi-related fun fact") for more details.
14214     *
14215     * When working with HTML you should always
14216     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
14217     * XSS vectors.
14218     *
14219     * @static
14220     * @since 0.1.0
14221     * @memberOf _
14222     * @category String
14223     * @param {string} [string=''] The string to escape.
14224     * @returns {string} Returns the escaped string.
14225     * @example
14226     *
14227     * _.escape('fred, barney, & pebbles');
14228     * // => 'fred, barney, &amp; pebbles'
14229     */
14230    function escape(string) {
14231      string = toString(string);
14232      return (string && reHasUnescapedHtml.test(string))
14233        ? string.replace(reUnescapedHtml, escapeHtmlChar)
14234        : string;
14235    }
14236
14237    /**
14238     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
14239     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
14240     *
14241     * @static
14242     * @memberOf _
14243     * @since 3.0.0
14244     * @category String
14245     * @param {string} [string=''] The string to escape.
14246     * @returns {string} Returns the escaped string.
14247     * @example
14248     *
14249     * _.escapeRegExp('[lodash](https://lodash.com/)');
14250     * // => '\[lodash\]\(https://lodash\.com/\)'
14251     */
14252    function escapeRegExp(string) {
vendor: 4,658 bytes, lines 14253-14422
14253      string = toString(string);
14254      return (string && reHasRegExpChar.test(string))
14255        ? string.replace(reRegExpChar, '\\$&')
14256        : string;
14257    }
14258
14259    /**
14260     * Converts `string` to
14261     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
14262     *
14263     * @static
14264     * @memberOf _
14265     * @since 3.0.0
14266     * @category String
14267     * @param {string} [string=''] The string to convert.
14268     * @returns {string} Returns the kebab cased string.
14269     * @example
14270     *
14271     * _.kebabCase('Foo Bar');
14272     * // => 'foo-bar'
14273     *
14274     * _.kebabCase('fooBar');
14275     * // => 'foo-bar'
14276     *
14277     * _.kebabCase('__FOO_BAR__');
14278     * // => 'foo-bar'
14279     */
14280    var kebabCase = createCompounder(function(result, word, index) {
14281      return result + (index ? '-' : '') + word.toLowerCase();
14282    });
14283
14284    /**
14285     * Converts `string`, as space separated words, to lower case.
14286     *
14287     * @static
14288     * @memberOf _
14289     * @since 4.0.0
14290     * @category String
14291     * @param {string} [string=''] The string to convert.
14292     * @returns {string} Returns the lower cased string.
14293     * @example
14294     *
14295     * _.lowerCase('--Foo-Bar--');
14296     * // => 'foo bar'
14297     *
14298     * _.lowerCase('fooBar');
14299     * // => 'foo bar'
14300     *
14301     * _.lowerCase('__FOO_BAR__');
14302     * // => 'foo bar'
14303     */
14304    var lowerCase = createCompounder(function(result, word, index) {
14305      return result + (index ? ' ' : '') + word.toLowerCase();
14306    });
14307
14308    /**
14309     * Converts the first character of `string` to lower case.
14310     *
14311     * @static
14312     * @memberOf _
14313     * @since 4.0.0
14314     * @category String
14315     * @param {string} [string=''] The string to convert.
14316     * @returns {string} Returns the converted string.
14317     * @example
14318     *
14319     * _.lowerFirst('Fred');
14320     * // => 'fred'
14321     *
14322     * _.lowerFirst('FRED');
14323     * // => 'fRED'
14324     */
14325    var lowerFirst = createCaseFirst('toLowerCase');
14326
14327    /**
14328     * Pads `string` on the left and right sides if it's shorter than `length`.
14329     * Padding characters are truncated if they can't be evenly divided by `length`.
14330     *
14331     * @static
14332     * @memberOf _
14333     * @since 3.0.0
14334     * @category String
14335     * @param {string} [string=''] The string to pad.
14336     * @param {number} [length=0] The padding length.
14337     * @param {string} [chars=' '] The string used as padding.
14338     * @returns {string} Returns the padded string.
14339     * @example
14340     *
14341     * _.pad('abc', 8);
14342     * // => '  abc   '
14343     *
14344     * _.pad('abc', 8, '_-');
14345     * // => '_-abc_-_'
14346     *
14347     * _.pad('abc', 3);
14348     * // => 'abc'
14349     */
14350    function pad(string, length, chars) {
14351      string = toString(string);
14352      length = toInteger(length);
14353
14354      var strLength = length ? stringSize(string) : 0;
14355      if (!length || strLength >= length) {
14356        return string;
14357      }
14358      var mid = (length - strLength) / 2;
14359      return (
14360        createPadding(nativeFloor(mid), chars) +
14361        string +
14362        createPadding(nativeCeil(mid), chars)
14363      );
14364    }
14365
14366    /**
14367     * Pads `string` on the right side if it's shorter than `length`. Padding
14368     * characters are truncated if they exceed `length`.
14369     *
14370     * @static
14371     * @memberOf _
14372     * @since 4.0.0
14373     * @category String
14374     * @param {string} [string=''] The string to pad.
14375     * @param {number} [length=0] The padding length.
14376     * @param {string} [chars=' '] The string used as padding.
14377     * @returns {string} Returns the padded string.
14378     * @example
14379     *
14380     * _.padEnd('abc', 6);
14381     * // => 'abc   '
14382     *
14383     * _.padEnd('abc', 6, '_-');
14384     * // => 'abc_-_'
14385     *
14386     * _.padEnd('abc', 3);
14387     * // => 'abc'
14388     */
14389    function padEnd(string, length, chars) {
14390      string = toString(string);
14391      length = toInteger(length);
14392
14393      var strLength = length ? stringSize(string) : 0;
14394      return (length && strLength < length)
14395        ? (string + createPadding(length - strLength, chars))
14396        : string;
14397    }
14398
14399    /**
14400     * Pads `string` on the left side if it's shorter than `length`. Padding
14401     * characters are truncated if they exceed `length`.
14402     *
14403     * @static
14404     * @memberOf _
14405     * @since 4.0.0
14406     * @category String
14407     * @param {string} [string=''] The string to pad.
14408     * @param {number} [length=0] The padding length.
14409     * @param {string} [chars=' '] The string used as padding.
14410     * @returns {string} Returns the padded string.
14411     * @example
14412     *
14413     * _.padStart('abc', 6);
14414     * // => '   abc'
14415     *
14416     * _.padStart('abc', 6, '_-');
14417     * // => '_-_abc'
14418     *
14419     * _.padStart('abc', 3);
14420     * // => 'abc'
14421     */
14422    function padStart(string, length, chars) {
vendor: 12,646 bytes, lines 14423-14780
14423      string = toString(string);
14424      length = toInteger(length);
14425
14426      var strLength = length ? stringSize(string) : 0;
14427      return (length && strLength < length)
14428        ? (createPadding(length - strLength, chars) + string)
14429        : string;
14430    }
14431
14432    /**
14433     * Converts `string` to an integer of the specified radix. If `radix` is
14434     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
14435     * hexadecimal, in which case a `radix` of `16` is used.
14436     *
14437     * **Note:** This method aligns with the
14438     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
14439     *
14440     * @static
14441     * @memberOf _
14442     * @since 1.1.0
14443     * @category String
14444     * @param {string} string The string to convert.
14445     * @param {number} [radix=10] The radix to interpret `value` by.
14446     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14447     * @returns {number} Returns the converted integer.
14448     * @example
14449     *
14450     * _.parseInt('08');
14451     * // => 8
14452     *
14453     * _.map(['6', '08', '10'], _.parseInt);
14454     * // => [6, 8, 10]
14455     */
14456    function parseInt(string, radix, guard) {
14457      if (guard || radix == null) {
14458        radix = 0;
14459      } else if (radix) {
14460        radix = +radix;
14461      }
14462      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
14463    }
14464
14465    /**
14466     * Repeats the given string `n` times.
14467     *
14468     * @static
14469     * @memberOf _
14470     * @since 3.0.0
14471     * @category String
14472     * @param {string} [string=''] The string to repeat.
14473     * @param {number} [n=1] The number of times to repeat the string.
14474     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14475     * @returns {string} Returns the repeated string.
14476     * @example
14477     *
14478     * _.repeat('*', 3);
14479     * // => '***'
14480     *
14481     * _.repeat('abc', 2);
14482     * // => 'abcabc'
14483     *
14484     * _.repeat('abc', 0);
14485     * // => ''
14486     */
14487    function repeat(string, n, guard) {
14488      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
14489        n = 1;
14490      } else {
14491        n = toInteger(n);
14492      }
14493      return baseRepeat(toString(string), n);
14494    }
14495
14496    /**
14497     * Replaces matches for `pattern` in `string` with `replacement`.
14498     *
14499     * **Note:** This method is based on
14500     * [`String#replace`](https://mdn.io/String/replace).
14501     *
14502     * @static
14503     * @memberOf _
14504     * @since 4.0.0
14505     * @category String
14506     * @param {string} [string=''] The string to modify.
14507     * @param {RegExp|string} pattern The pattern to replace.
14508     * @param {Function|string} replacement The match replacement.
14509     * @returns {string} Returns the modified string.
14510     * @example
14511     *
14512     * _.replace('Hi Fred', 'Fred', 'Barney');
14513     * // => 'Hi Barney'
14514     */
14515    function replace() {
14516      var args = arguments,
14517          string = toString(args[0]);
14518
14519      return args.length < 3 ? string : string.replace(args[1], args[2]);
14520    }
14521
14522    /**
14523     * Converts `string` to
14524     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
14525     *
14526     * @static
14527     * @memberOf _
14528     * @since 3.0.0
14529     * @category String
14530     * @param {string} [string=''] The string to convert.
14531     * @returns {string} Returns the snake cased string.
14532     * @example
14533     *
14534     * _.snakeCase('Foo Bar');
14535     * // => 'foo_bar'
14536     *
14537     * _.snakeCase('fooBar');
14538     * // => 'foo_bar'
14539     *
14540     * _.snakeCase('--FOO-BAR--');
14541     * // => 'foo_bar'
14542     */
14543    var snakeCase = createCompounder(function(result, word, index) {
14544      return result + (index ? '_' : '') + word.toLowerCase();
14545    });
14546
14547    /**
14548     * Splits `string` by `separator`.
14549     *
14550     * **Note:** This method is based on
14551     * [`String#split`](https://mdn.io/String/split).
14552     *
14553     * @static
14554     * @memberOf _
14555     * @since 4.0.0
14556     * @category String
14557     * @param {string} [string=''] The string to split.
14558     * @param {RegExp|string} separator The separator pattern to split by.
14559     * @param {number} [limit] The length to truncate results to.
14560     * @returns {Array} Returns the string segments.
14561     * @example
14562     *
14563     * _.split('a-b-c', '-', 2);
14564     * // => ['a', 'b']
14565     */
14566    function split(string, separator, limit) {
14567      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
14568        separator = limit = undefined;
14569      }
14570      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
14571      if (!limit) {
14572        return [];
14573      }
14574      string = toString(string);
14575      if (string && (
14576            typeof separator == 'string' ||
14577            (separator != null && !isRegExp(separator))
14578          )) {
14579        separator = baseToString(separator);
14580        if (!separator && hasUnicode(string)) {
14581          return castSlice(stringToArray(string), 0, limit);
14582        }
14583      }
14584      return string.split(separator, limit);
14585    }
14586
14587    /**
14588     * Converts `string` to
14589     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
14590     *
14591     * @static
14592     * @memberOf _
14593     * @since 3.1.0
14594     * @category String
14595     * @param {string} [string=''] The string to convert.
14596     * @returns {string} Returns the start cased string.
14597     * @example
14598     *
14599     * _.startCase('--foo-bar--');
14600     * // => 'Foo Bar'
14601     *
14602     * _.startCase('fooBar');
14603     * // => 'Foo Bar'
14604     *
14605     * _.startCase('__FOO_BAR__');
14606     * // => 'FOO BAR'
14607     */
14608    var startCase = createCompounder(function(result, word, index) {
14609      return result + (index ? ' ' : '') + upperFirst(word);
14610    });
14611
14612    /**
14613     * Checks if `string` starts with the given target string.
14614     *
14615     * @static
14616     * @memberOf _
14617     * @since 3.0.0
14618     * @category String
14619     * @param {string} [string=''] The string to inspect.
14620     * @param {string} [target] The string to search for.
14621     * @param {number} [position=0] The position to search from.
14622     * @returns {boolean} Returns `true` if `string` starts with `target`,
14623     *  else `false`.
14624     * @example
14625     *
14626     * _.startsWith('abc', 'a');
14627     * // => true
14628     *
14629     * _.startsWith('abc', 'b');
14630     * // => false
14631     *
14632     * _.startsWith('abc', 'b', 1);
14633     * // => true
14634     */
14635    function startsWith(string, target, position) {
14636      string = toString(string);
14637      position = position == null
14638        ? 0
14639        : baseClamp(toInteger(position), 0, string.length);
14640
14641      target = baseToString(target);
14642      return string.slice(position, position + target.length) == target;
14643    }
14644
14645    /**
14646     * Creates a compiled template function that can interpolate data properties
14647     * in "interpolate" delimiters, HTML-escape interpolated data properties in
14648     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
14649     * properties may be accessed as free variables in the template. If a setting
14650     * object is given, it takes precedence over `_.templateSettings` values.
14651     *
14652     * **Note:** In the development build `_.template` utilizes
14653     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14654     * for easier debugging.
14655     *
14656     * For more information on precompiling templates see
14657     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14658     *
14659     * For more information on Chrome extension sandboxes see
14660     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14661     *
14662     * @static
14663     * @since 0.1.0
14664     * @memberOf _
14665     * @category String
14666     * @param {string} [string=''] The template string.
14667     * @param {Object} [options={}] The options object.
14668     * @param {RegExp} [options.escape=_.templateSettings.escape]
14669     *  The HTML "escape" delimiter.
14670     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14671     *  The "evaluate" delimiter.
14672     * @param {Object} [options.imports=_.templateSettings.imports]
14673     *  An object to import into the template as free variables.
14674     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14675     *  The "interpolate" delimiter.
14676     * @param {string} [options.sourceURL='lodash.templateSources[n]']
14677     *  The sourceURL of the compiled template.
14678     * @param {string} [options.variable='obj']
14679     *  The data object variable name.
14680     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14681     * @returns {Function} Returns the compiled template function.
14682     * @example
14683     *
14684     * // Use the "interpolate" delimiter to create a compiled template.
14685     * var compiled = _.template('hello <%= user %>!');
14686     * compiled({ 'user': 'fred' });
14687     * // => 'hello fred!'
14688     *
14689     * // Use the HTML "escape" delimiter to escape data property values.
14690     * var compiled = _.template('<b><%- value %></b>');
14691     * compiled({ 'value': '<script>' });
14692     * // => '<b>&lt;script&gt;</b>'
14693     *
14694     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14695     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14696     * compiled({ 'users': ['fred', 'barney'] });
14697     * // => '<li>fred</li><li>barney</li>'
14698     *
14699     * // Use the internal `print` function in "evaluate" delimiters.
14700     * var compiled = _.template('<% print("hello " + user); %>!');
14701     * compiled({ 'user': 'barney' });
14702     * // => 'hello barney!'
14703     *
14704     * // Use the ES template literal delimiter as an "interpolate" delimiter.
14705     * // Disable support by replacing the "interpolate" delimiter.
14706     * var compiled = _.template('hello ${ user }!');
14707     * compiled({ 'user': 'pebbles' });
14708     * // => 'hello pebbles!'
14709     *
14710     * // Use backslashes to treat delimiters as plain text.
14711     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14712     * compiled({ 'value': 'ignored' });
14713     * // => '<%- value %>'
14714     *
14715     * // Use the `imports` option to import `jQuery` as `jq`.
14716     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14717     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14718     * compiled({ 'users': ['fred', 'barney'] });
14719     * // => '<li>fred</li><li>barney</li>'
14720     *
14721     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14722     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14723     * compiled(data);
14724     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14725     *
14726     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14727     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14728     * compiled.source;
14729     * // => function(data) {
14730     * //   var __t, __p = '';
14731     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14732     * //   return __p;
14733     * // }
14734     *
14735     * // Use custom template delimiters.
14736     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14737     * var compiled = _.template('hello {{ user }}!');
14738     * compiled({ 'user': 'mustache' });
14739     * // => 'hello mustache!'
14740     *
14741     * // Use the `source` property to inline compiled templates for meaningful
14742     * // line numbers in error messages and stack traces.
14743     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14744     *   var JST = {\
14745     *     "main": ' + _.template(mainText).source + '\
14746     *   };\
14747     * ');
14748     */
14749    function template(string, options, guard) {
14750      // Based on John Resig's `tmpl` implementation
14751      // (http://ejohn.org/blog/javascript-micro-templating/)
14752      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14753      var settings = lodash.templateSettings;
14754
14755      if (guard && isIterateeCall(string, options, guard)) {
14756        options = undefined;
14757      }
14758      string = toString(string);
14759      options = assignInWith({}, options, settings, customDefaultsAssignIn);
14760
14761      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
14762          importsKeys = keys(imports),
14763          importsValues = baseValues(imports, importsKeys);
14764
14765      var isEscaping,
14766          isEvaluating,
14767          index = 0,
14768          interpolate = options.interpolate || reNoMatch,
14769          source = "__p += '";
14770
14771      // Compile the regexp to match each delimiter.
14772      var reDelimiters = RegExp(
14773        (options.escape || reNoMatch).source + '|' +
14774        interpolate.source + '|' +
14775        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14776        (options.evaluate || reNoMatch).source + '|$'
14777      , 'g');
14778
14779      // Use a sourceURL for easier debugging.
14780      
vendor: 1,744 bytes, lines 14780-14824
14780var sourceURL = '//# sourceURL=' +
14781        ('sourceURL' in options
14782          ? options.sourceURL
14783          : ('lodash.templateSources[' + (++templateCounter) + ']')
14784        ) + '\n';
14785
14786      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14787        interpolateValue || (interpolateValue = esTemplateValue);
14788
14789        // Escape characters that can't be included in string literals.
14790        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14791
14792        // Replace delimiters with snippets.
14793        if (escapeValue) {
14794          isEscaping = true;
14795          source += "' +\n__e(" + escapeValue + ") +\n'";
14796        }
14797        if (evaluateValue) {
14798          isEvaluating = true;
14799          source += "';\n" + evaluateValue + ";\n__p += '";
14800        }
14801        if (interpolateValue) {
14802          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14803        }
14804        index = offset + match.length;
14805
14806        // The JS engine embedded in Adobe products needs `match` returned in
14807        // order to produce the correct `offset` value.
14808        return match;
14809      });
14810
14811      source += "';\n";
14812
14813      // If `variable` is not specified wrap a with-statement around the generated
14814      // code to add the data object to the top of the scope chain.
14815      var variable = options.variable;
14816      if (!variable) {
14817        source = 'with (obj) {\n' + source + '\n}\n';
14818      }
14819      // Cleanup code by stripping empty strings.
14820      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14821        .replace(reEmptyStringMiddle, '$1')
14822        .replace(reEmptyStringTrailing, '$1;');
14823
14824      // Frame code as the function body.
vendor: 4,089 bytes, lines 14825-14967
14825      source = 'function(' + (variable || 'obj') + ') {\n' +
14826        (variable
14827          ? ''
14828          : 'obj || (obj = {});\n'
14829        ) +
14830        "var __t, __p = ''" +
14831        (isEscaping
14832           ? ', __e = _.escape'
14833           : ''
14834        ) +
14835        (isEvaluating
14836          ? ', __j = Array.prototype.join;\n' +
14837            "function print() { __p += __j.call(arguments, '') }\n"
14838          : ';\n'
14839        ) +
14840        source +
14841        'return __p\n}';
14842
14843      var result = attempt(function() {
14844        return Function(importsKeys, sourceURL + 'return ' + source)
14845          .apply(undefined, importsValues);
14846      });
14847
14848      // Provide the compiled function's source by its `toString` method or
14849      // the `source` property as a convenience for inlining compiled templates.
14850      result.source = source;
14851      if (isError(result)) {
14852        throw result;
14853      }
14854      return result;
14855    }
14856
14857    /**
14858     * Converts `string`, as a whole, to lower case just like
14859     * [String#toLowerCase](https://mdn.io/toLowerCase).
14860     *
14861     * @static
14862     * @memberOf _
14863     * @since 4.0.0
14864     * @category String
14865     * @param {string} [string=''] The string to convert.
14866     * @returns {string} Returns the lower cased string.
14867     * @example
14868     *
14869     * _.toLower('--Foo-Bar--');
14870     * // => '--foo-bar--'
14871     *
14872     * _.toLower('fooBar');
14873     * // => 'foobar'
14874     *
14875     * _.toLower('__FOO_BAR__');
14876     * // => '__foo_bar__'
14877     */
14878    function toLower(value) {
14879      return toString(value).toLowerCase();
14880    }
14881
14882    /**
14883     * Converts `string`, as a whole, to upper case just like
14884     * [String#toUpperCase](https://mdn.io/toUpperCase).
14885     *
14886     * @static
14887     * @memberOf _
14888     * @since 4.0.0
14889     * @category String
14890     * @param {string} [string=''] The string to convert.
14891     * @returns {string} Returns the upper cased string.
14892     * @example
14893     *
14894     * _.toUpper('--foo-bar--');
14895     * // => '--FOO-BAR--'
14896     *
14897     * _.toUpper('fooBar');
14898     * // => 'FOOBAR'
14899     *
14900     * _.toUpper('__foo_bar__');
14901     * // => '__FOO_BAR__'
14902     */
14903    function toUpper(value) {
14904      return toString(value).toUpperCase();
14905    }
14906
14907    /**
14908     * Removes leading and trailing whitespace or specified characters from `string`.
14909     *
14910     * @static
14911     * @memberOf _
14912     * @since 3.0.0
14913     * @category String
14914     * @param {string} [string=''] The string to trim.
14915     * @param {string} [chars=whitespace] The characters to trim.
14916     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14917     * @returns {string} Returns the trimmed string.
14918     * @example
14919     *
14920     * _.trim('  abc  ');
14921     * // => 'abc'
14922     *
14923     * _.trim('-_-abc-_-', '_-');
14924     * // => 'abc'
14925     *
14926     * _.map(['  foo  ', '  bar  '], _.trim);
14927     * // => ['foo', 'bar']
14928     */
14929    function trim(string, chars, guard) {
14930      string = toString(string);
14931      if (string && (guard || chars === undefined)) {
14932        return string.replace(reTrim, '');
14933      }
14934      if (!string || !(chars = baseToString(chars))) {
14935        return string;
14936      }
14937      var strSymbols = stringToArray(string),
14938          chrSymbols = stringToArray(chars),
14939          start = charsStartIndex(strSymbols, chrSymbols),
14940          end = charsEndIndex(strSymbols, chrSymbols) + 1;
14941
14942      return castSlice(strSymbols, start, end).join('');
14943    }
14944
14945    /**
14946     * Removes trailing whitespace or specified characters from `string`.
14947     *
14948     * @static
14949     * @memberOf _
14950     * @since 4.0.0
14951     * @category String
14952     * @param {string} [string=''] The string to trim.
14953     * @param {string} [chars=whitespace] The characters to trim.
14954     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14955     * @returns {string} Returns the trimmed string.
14956     * @example
14957     *
14958     * _.trimEnd('  abc  ');
14959     * // => '  abc'
14960     *
14961     * _.trimEnd('-_-abc-_-', '_-');
14962     * // => '-_-abc'
14963     */
14964    function trimEnd(string, chars, guard) {
14965      string = toString(string);
14966      if (string && (guard || chars === undefined)) {
14967        return string.replace(reTrimEnd, ''
vendor: 10,736 bytes, lines 14967-15311
14967);
14968      }
14969      if (!string || !(chars = baseToString(chars))) {
14970        return string;
14971      }
14972      var strSymbols = stringToArray(string),
14973          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14974
14975      return castSlice(strSymbols, 0, end).join('');
14976    }
14977
14978    /**
14979     * Removes leading whitespace or specified characters from `string`.
14980     *
14981     * @static
14982     * @memberOf _
14983     * @since 4.0.0
14984     * @category String
14985     * @param {string} [string=''] The string to trim.
14986     * @param {string} [chars=whitespace] The characters to trim.
14987     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14988     * @returns {string} Returns the trimmed string.
14989     * @example
14990     *
14991     * _.trimStart('  abc  ');
14992     * // => 'abc  '
14993     *
14994     * _.trimStart('-_-abc-_-', '_-');
14995     * // => 'abc-_-'
14996     */
14997    function trimStart(string, chars, guard) {
14998      string = toString(string);
14999      if (string && (guard || chars === undefined)) {
15000        return string.replace(reTrimStart, '');
15001      }
15002      if (!string || !(chars = baseToString(chars))) {
15003        return string;
15004      }
15005      var strSymbols = stringToArray(string),
15006          start = charsStartIndex(strSymbols, stringToArray(chars));
15007
15008      return castSlice(strSymbols, start).join('');
15009    }
15010
15011    /**
15012     * Truncates `string` if it's longer than the given maximum string length.
15013     * The last characters of the truncated string are replaced with the omission
15014     * string which defaults to "...".
15015     *
15016     * @static
15017     * @memberOf _
15018     * @since 4.0.0
15019     * @category String
15020     * @param {string} [string=''] The string to truncate.
15021     * @param {Object} [options={}] The options object.
15022     * @param {number} [options.length=30] The maximum string length.
15023     * @param {string} [options.omission='...'] The string to indicate text is omitted.
15024     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
15025     * @returns {string} Returns the truncated string.
15026     * @example
15027     *
15028     * _.truncate('hi-diddly-ho there, neighborino');
15029     * // => 'hi-diddly-ho there, neighbo...'
15030     *
15031     * _.truncate('hi-diddly-ho there, neighborino', {
15032     *   'length': 24,
15033     *   'separator': ' '
15034     * });
15035     * // => 'hi-diddly-ho there,...'
15036     *
15037     * _.truncate('hi-diddly-ho there, neighborino', {
15038     *   'length': 24,
15039     *   'separator': /,? +/
15040     * });
15041     * // => 'hi-diddly-ho there...'
15042     *
15043     * _.truncate('hi-diddly-ho there, neighborino', {
15044     *   'omission': ' [...]'
15045     * });
15046     * // => 'hi-diddly-ho there, neig [...]'
15047     */
15048    function truncate(string, options) {
15049      var length = DEFAULT_TRUNC_LENGTH,
15050          omission = DEFAULT_TRUNC_OMISSION;
15051
15052      if (isObject(options)) {
15053        var separator = 'separator' in options ? options.separator : separator;
15054        length = 'length' in options ? toInteger(options.length) : length;
15055        omission = 'omission' in options ? baseToString(options.omission) : omission;
15056      }
15057      string = toString(string);
15058
15059      var strLength = string.length;
15060      if (hasUnicode(string)) {
15061        var strSymbols = stringToArray(string);
15062        strLength = strSymbols.length;
15063      }
15064      if (length >= strLength) {
15065        return string;
15066      }
15067      var end = length - stringSize(omission);
15068      if (end < 1) {
15069        return omission;
15070      }
15071      var result = strSymbols
15072        ? castSlice(strSymbols, 0, end).join('')
15073        : string.slice(0, end);
15074
15075      if (separator === undefined) {
15076        return result + omission;
15077      }
15078      if (strSymbols) {
15079        end += (result.length - end);
15080      }
15081      if (isRegExp(separator)) {
15082        if (string.slice(end).search(separator)) {
15083          var match,
15084              substring = result;
15085
15086          if (!separator.global) {
15087            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
15088          }
15089          separator.lastIndex = 0;
15090          while ((match = separator.exec(substring))) {
15091            var newEnd = match.index;
15092          }
15093          result = result.slice(0, newEnd === undefined ? end : newEnd);
15094        }
15095      } else if (string.indexOf(baseToString(separator), end) != end) {
15096        var index = result.lastIndexOf(separator);
15097        if (index > -1) {
15098          result = result.slice(0, index);
15099        }
15100      }
15101      return result + omission;
15102    }
15103
15104    /**
15105     * The inverse of `_.escape`; this method converts the HTML entities
15106     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
15107     * their corresponding characters.
15108     *
15109     * **Note:** No other HTML entities are unescaped. To unescape additional
15110     * HTML entities use a third-party library like [_he_](https://mths.be/he).
15111     *
15112     * @static
15113     * @memberOf _
15114     * @since 0.6.0
15115     * @category String
15116     * @param {string} [string=''] The string to unescape.
15117     * @returns {string} Returns the unescaped string.
15118     * @example
15119     *
15120     * _.unescape('fred, barney, &amp; pebbles');
15121     * // => 'fred, barney, & pebbles'
15122     */
15123    function unescape(string) {
15124      string = toString(string);
15125      return (string && reHasEscapedHtml.test(string))
15126        ? string.replace(reEscapedHtml, unescapeHtmlChar)
15127        : string;
15128    }
15129
15130    /**
15131     * Converts `string`, as space separated words, to upper case.
15132     *
15133     * @static
15134     * @memberOf _
15135     * @since 4.0.0
15136     * @category String
15137     * @param {string} [string=''] The string to convert.
15138     * @returns {string} Returns the upper cased string.
15139     * @example
15140     *
15141     * _.upperCase('--foo-bar');
15142     * // => 'FOO BAR'
15143     *
15144     * _.upperCase('fooBar');
15145     * // => 'FOO BAR'
15146     *
15147     * _.upperCase('__foo_bar__');
15148     * // => 'FOO BAR'
15149     */
15150    var upperCase = createCompounder(function(result, word, index) {
15151      return result + (index ? ' ' : '') + word.toUpperCase();
15152    });
15153
15154    /**
15155     * Converts the first character of `string` to upper case.
15156     *
15157     * @static
15158     * @memberOf _
15159     * @since 4.0.0
15160     * @category String
15161     * @param {string} [string=''] The string to convert.
15162     * @returns {string} Returns the converted string.
15163     * @example
15164     *
15165     * _.upperFirst('fred');
15166     * // => 'Fred'
15167     *
15168     * _.upperFirst('FRED');
15169     * // => 'FRED'
15170     */
15171    var upperFirst = createCaseFirst('toUpperCase');
15172
15173    /**
15174     * Splits `string` into an array of its words.
15175     *
15176     * @static
15177     * @memberOf _
15178     * @since 3.0.0
15179     * @category String
15180     * @param {string} [string=''] The string to inspect.
15181     * @param {RegExp|string} [pattern] The pattern to match words.
15182     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15183     * @returns {Array} Returns the words of `string`.
15184     * @example
15185     *
15186     * _.words('fred, barney, & pebbles');
15187     * // => ['fred', 'barney', 'pebbles']
15188     *
15189     * _.words('fred, barney, & pebbles', /[^, ]+/g);
15190     * // => ['fred', 'barney', '&', 'pebbles']
15191     */
15192    function words(string, pattern, guard) {
15193      string = toString(string);
15194      pattern = guard ? undefined : pattern;
15195
15196      if (pattern === undefined) {
15197        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
15198      }
15199      return string.match(pattern) || [];
15200    }
15201
15202    /*------------------------------------------------------------------------*/
15203
15204    /**
15205     * Attempts to invoke `func`, returning either the result or the caught error
15206     * object. Any additional arguments are provided to `func` when it's invoked.
15207     *
15208     * @static
15209     * @memberOf _
15210     * @since 3.0.0
15211     * @category Util
15212     * @param {Function} func The function to attempt.
15213     * @param {...*} [args] The arguments to invoke `func` with.
15214     * @returns {*} Returns the `func` result or error object.
15215     * @example
15216     *
15217     * // Avoid throwing errors for invalid selectors.
15218     * var elements = _.attempt(function(selector) {
15219     *   return document.querySelectorAll(selector);
15220     * }, '>_>');
15221     *
15222     * if (_.isError(elements)) {
15223     *   elements = [];
15224     * }
15225     */
15226    var attempt = baseRest(function(func, args) {
15227      try {
15228        return apply(func, undefined, args);
15229      } catch (e) {
15230        return isError(e) ? e : new Error(e);
15231      }
15232    });
15233
15234    /**
15235     * Binds methods of an object to the object itself, overwriting the existing
15236     * method.
15237     *
15238     * **Note:** This method doesn't set the "length" property of bound functions.
15239     *
15240     * @static
15241     * @since 0.1.0
15242     * @memberOf _
15243     * @category Util
15244     * @param {Object} object The object to bind and assign the bound methods to.
15245     * @param {...(string|string[])} methodNames The object method names to bind.
15246     * @returns {Object} Returns `object`.
15247     * @example
15248     *
15249     * var view = {
15250     *   'label': 'docs',
15251     *   'click': function() {
15252     *     console.log('clicked ' + this.label);
15253     *   }
15254     * };
15255     *
15256     * _.bindAll(view, ['click']);
15257     * jQuery(element).on('click', view.click);
15258     * // => Logs 'clicked docs' when clicked.
15259     */
15260    var bindAll = flatRest(function(object, methodNames) {
15261      arrayEach(methodNames, function(key) {
15262        key = toKey(key);
15263        baseAssignValue(object, key, bind(object[key], object));
15264      });
15265      return object;
15266    });
15267
15268    /**
15269     * Creates a function that iterates over `pairs` and invokes the corresponding
15270     * function of the first predicate to return truthy. The predicate-function
15271     * pairs are invoked with the `this` binding and arguments of the created
15272     * function.
15273     *
15274     * @static
15275     * @memberOf _
15276     * @since 4.0.0
15277     * @category Util
15278     * @param {Array} pairs The predicate-function pairs.
15279     * @returns {Function} Returns the new composite function.
15280     * @example
15281     *
15282     * var func = _.cond([
15283     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
15284     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
15285     *   [_.stubTrue,                      _.constant('no match')]
15286     * ]);
15287     *
15288     * func({ 'a': 1, 'b': 2 });
15289     * // => 'matches A'
15290     *
15291     * func({ 'a': 0, 'b': 1 });
15292     * // => 'matches B'
15293     *
15294     * func({ 'a': '1', 'b': '2' });
15295     * // => 'no match'
15296     */
15297    function cond(pairs) {
15298      var length = pairs == null ? 0 : pairs.length,
15299          toIteratee = getIteratee();
15300
15301      pairs = !length ? [] : arrayMap(pairs, function(pair) {
15302        if (typeof pair[1] != 'function') {
15303          throw new TypeError(FUNC_ERROR_TEXT);
15304        }
15305        return [toIteratee(pair[0]), pair[1]];
15306      });
15307
15308      return baseRest(function(args) {
15309        var index = -1;
15310        while (++index < length) {
15311          var pair = pairs[index];
vendor: 19,681 bytes, lines 15312-16007
15312          if (apply(pair[0], this, args)) {
15313            return apply(pair[1], this, args);
15314          }
15315        }
15316      });
15317    }
15318
15319    /**
15320     * Creates a function that invokes the predicate properties of `source` with
15321     * the corresponding property values of a given object, returning `true` if
15322     * all predicates return truthy, else `false`.
15323     *
15324     * **Note:** The created function is equivalent to `_.conformsTo` with
15325     * `source` partially applied.
15326     *
15327     * @static
15328     * @memberOf _
15329     * @since 4.0.0
15330     * @category Util
15331     * @param {Object} source The object of property predicates to conform to.
15332     * @returns {Function} Returns the new spec function.
15333     * @example
15334     *
15335     * var objects = [
15336     *   { 'a': 2, 'b': 1 },
15337     *   { 'a': 1, 'b': 2 }
15338     * ];
15339     *
15340     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
15341     * // => [{ 'a': 1, 'b': 2 }]
15342     */
15343    function conforms(source) {
15344      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
15345    }
15346
15347    /**
15348     * Creates a function that returns `value`.
15349     *
15350     * @static
15351     * @memberOf _
15352     * @since 2.4.0
15353     * @category Util
15354     * @param {*} value The value to return from the new function.
15355     * @returns {Function} Returns the new constant function.
15356     * @example
15357     *
15358     * var objects = _.times(2, _.constant({ 'a': 1 }));
15359     *
15360     * console.log(objects);
15361     * // => [{ 'a': 1 }, { 'a': 1 }]
15362     *
15363     * console.log(objects[0] === objects[1]);
15364     * // => true
15365     */
15366    function constant(value) {
15367      return function() {
15368        return value;
15369      };
15370    }
15371
15372    /**
15373     * Checks `value` to determine whether a default value should be returned in
15374     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
15375     * or `undefined`.
15376     *
15377     * @static
15378     * @memberOf _
15379     * @since 4.14.0
15380     * @category Util
15381     * @param {*} value The value to check.
15382     * @param {*} defaultValue The default value.
15383     * @returns {*} Returns the resolved value.
15384     * @example
15385     *
15386     * _.defaultTo(1, 10);
15387     * // => 1
15388     *
15389     * _.defaultTo(undefined, 10);
15390     * // => 10
15391     */
15392    function defaultTo(value, defaultValue) {
15393      return (value == null || value !== value) ? defaultValue : value;
15394    }
15395
15396    /**
15397     * Creates a function that returns the result of invoking the given functions
15398     * with the `this` binding of the created function, where each successive
15399     * invocation is supplied the return value of the previous.
15400     *
15401     * @static
15402     * @memberOf _
15403     * @since 3.0.0
15404     * @category Util
15405     * @param {...(Function|Function[])} [funcs] The functions to invoke.
15406     * @returns {Function} Returns the new composite function.
15407     * @see _.flowRight
15408     * @example
15409     *
15410     * function square(n) {
15411     *   return n * n;
15412     * }
15413     *
15414     * var addSquare = _.flow([_.add, square]);
15415     * addSquare(1, 2);
15416     * // => 9
15417     */
15418    var flow = createFlow();
15419
15420    /**
15421     * This method is like `_.flow` except that it creates a function that
15422     * invokes the given functions from right to left.
15423     *
15424     * @static
15425     * @since 3.0.0
15426     * @memberOf _
15427     * @category Util
15428     * @param {...(Function|Function[])} [funcs] The functions to invoke.
15429     * @returns {Function} Returns the new composite function.
15430     * @see _.flow
15431     * @example
15432     *
15433     * function square(n) {
15434     *   return n * n;
15435     * }
15436     *
15437     * var addSquare = _.flowRight([square, _.add]);
15438     * addSquare(1, 2);
15439     * // => 9
15440     */
15441    var flowRight = createFlow(true);
15442
15443    /**
15444     * This method returns the first argument it receives.
15445     *
15446     * @static
15447     * @since 0.1.0
15448     * @memberOf _
15449     * @category Util
15450     * @param {*} value Any value.
15451     * @returns {*} Returns `value`.
15452     * @example
15453     *
15454     * var object = { 'a': 1 };
15455     *
15456     * console.log(_.identity(object) === object);
15457     * // => true
15458     */
15459    function identity(value) {
15460      return value;
15461    }
15462
15463    /**
15464     * Creates a function that invokes `func` with the arguments of the created
15465     * function. If `func` is a property name, the created function returns the
15466     * property value for a given element. If `func` is an array or object, the
15467     * created function returns `true` for elements that contain the equivalent
15468     * source properties, otherwise it returns `false`.
15469     *
15470     * @static
15471     * @since 4.0.0
15472     * @memberOf _
15473     * @category Util
15474     * @param {*} [func=_.identity] The value to convert to a callback.
15475     * @returns {Function} Returns the callback.
15476     * @example
15477     *
15478     * var users = [
15479     *   { 'user': 'barney', 'age': 36, 'active': true },
15480     *   { 'user': 'fred',   'age': 40, 'active': false }
15481     * ];
15482     *
15483     * // The `_.matches` iteratee shorthand.
15484     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
15485     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
15486     *
15487     * // The `_.matchesProperty` iteratee shorthand.
15488     * _.filter(users, _.iteratee(['user', 'fred']));
15489     * // => [{ 'user': 'fred', 'age': 40 }]
15490     *
15491     * // The `_.property` iteratee shorthand.
15492     * _.map(users, _.iteratee('user'));
15493     * // => ['barney', 'fred']
15494     *
15495     * // Create custom iteratee shorthands.
15496     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
15497     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
15498     *     return func.test(string);
15499     *   };
15500     * });
15501     *
15502     * _.filter(['abc', 'def'], /ef/);
15503     * // => ['def']
15504     */
15505    function iteratee(func) {
15506      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
15507    }
15508
15509    /**
15510     * Creates a function that performs a partial deep comparison between a given
15511     * object and `source`, returning `true` if the given object has equivalent
15512     * property values, else `false`.
15513     *
15514     * **Note:** The created function is equivalent to `_.isMatch` with `source`
15515     * partially applied.
15516     *
15517     * Partial comparisons will match empty array and empty object `source`
15518     * values against any array or object value, respectively. See `_.isEqual`
15519     * for a list of supported value comparisons.
15520     *
15521     * @static
15522     * @memberOf _
15523     * @since 3.0.0
15524     * @category Util
15525     * @param {Object} source The object of property values to match.
15526     * @returns {Function} Returns the new spec function.
15527     * @example
15528     *
15529     * var objects = [
15530     *   { 'a': 1, 'b': 2, 'c': 3 },
15531     *   { 'a': 4, 'b': 5, 'c': 6 }
15532     * ];
15533     *
15534     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
15535     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
15536     */
15537    function matches(source) {
15538      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
15539    }
15540
15541    /**
15542     * Creates a function that performs a partial deep comparison between the
15543     * value at `path` of a given object to `srcValue`, returning `true` if the
15544     * object value is equivalent, else `false`.
15545     *
15546     * **Note:** Partial comparisons will match empty array and empty object
15547     * `srcValue` values against any array or object value, respectively. See
15548     * `_.isEqual` for a list of supported value comparisons.
15549     *
15550     * @static
15551     * @memberOf _
15552     * @since 3.2.0
15553     * @category Util
15554     * @param {Array|string} path The path of the property to get.
15555     * @param {*} srcValue The value to match.
15556     * @returns {Function} Returns the new spec function.
15557     * @example
15558     *
15559     * var objects = [
15560     *   { 'a': 1, 'b': 2, 'c': 3 },
15561     *   { 'a': 4, 'b': 5, 'c': 6 }
15562     * ];
15563     *
15564     * _.find(objects, _.matchesProperty('a', 4));
15565     * // => { 'a': 4, 'b': 5, 'c': 6 }
15566     */
15567    function matchesProperty(path, srcValue) {
15568      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
15569    }
15570
15571    /**
15572     * Creates a function that invokes the method at `path` of a given object.
15573     * Any additional arguments are provided to the invoked method.
15574     *
15575     * @static
15576     * @memberOf _
15577     * @since 3.7.0
15578     * @category Util
15579     * @param {Array|string} path The path of the method to invoke.
15580     * @param {...*} [args] The arguments to invoke the method with.
15581     * @returns {Function} Returns the new invoker function.
15582     * @example
15583     *
15584     * var objects = [
15585     *   { 'a': { 'b': _.constant(2) } },
15586     *   { 'a': { 'b': _.constant(1) } }
15587     * ];
15588     *
15589     * _.map(objects, _.method('a.b'));
15590     * // => [2, 1]
15591     *
15592     * _.map(objects, _.method(['a', 'b']));
15593     * // => [2, 1]
15594     */
15595    var method = baseRest(function(path, args) {
15596      return function(object) {
15597        return baseInvoke(object, path, args);
15598      };
15599    });
15600
15601    /**
15602     * The opposite of `_.method`; this method creates a function that invokes
15603     * the method at a given path of `object`. Any additional arguments are
15604     * provided to the invoked method.
15605     *
15606     * @static
15607     * @memberOf _
15608     * @since 3.7.0
15609     * @category Util
15610     * @param {Object} object The object to query.
15611     * @param {...*} [args] The arguments to invoke the method with.
15612     * @returns {Function} Returns the new invoker function.
15613     * @example
15614     *
15615     * var array = _.times(3, _.constant),
15616     *     object = { 'a': array, 'b': array, 'c': array };
15617     *
15618     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
15619     * // => [2, 0]
15620     *
15621     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
15622     * // => [2, 0]
15623     */
15624    var methodOf = baseRest(function(object, args) {
15625      return function(path) {
15626        return baseInvoke(object, path, args);
15627      };
15628    });
15629
15630    /**
15631     * Adds all own enumerable string keyed function properties of a source
15632     * object to the destination object. If `object` is a function, then methods
15633     * are added to its prototype as well.
15634     *
15635     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
15636     * avoid conflicts caused by modifying the original.
15637     *
15638     * @static
15639     * @since 0.1.0
15640     * @memberOf _
15641     * @category Util
15642     * @param {Function|Object} [object=lodash] The destination object.
15643     * @param {Object} source The object of functions to add.
15644     * @param {Object} [options={}] The options object.
15645     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
15646     * @returns {Function|Object} Returns `object`.
15647     * @example
15648     *
15649     * function vowels(string) {
15650     *   return _.filter(string, function(v) {
15651     *     return /[aeiou]/i.test(v);
15652     *   });
15653     * }
15654     *
15655     * _.mixin({ 'vowels': vowels });
15656     * _.vowels('fred');
15657     * // => ['e']
15658     *
15659     * _('fred').vowels().value();
15660     * // => ['e']
15661     *
15662     * _.mixin({ 'vowels': vowels }, { 'chain': false });
15663     * _('fred').vowels();
15664     * // => ['e']
15665     */
15666    function mixin(object, source, options) {
15667      var props = keys(source),
15668          methodNames = baseFunctions(source, props);
15669
15670      if (options == null &&
15671          !(isObject(source) && (methodNames.length || !props.length))) {
15672        options = source;
15673        source = object;
15674        object = this;
15675        methodNames = baseFunctions(source, keys(source));
15676      }
15677      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
15678          isFunc = isFunction(object);
15679
15680      arrayEach(methodNames, function(methodName) {
15681        var func = source[methodName];
15682        object[methodName] = func;
15683        if (isFunc) {
15684          object.prototype[methodName] = function() {
15685            var chainAll = this.__chain__;
15686            if (chain || chainAll) {
15687              var result = object(this.__wrapped__),
15688                  actions = result.__actions__ = copyArray(this.__actions__);
15689
15690              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15691              result.__chain__ = chainAll;
15692              return result;
15693            }
15694            return func.apply(object, arrayPush([this.value()], arguments));
15695          };
15696        }
15697      });
15698
15699      return object;
15700    }
15701
15702    /**
15703     * Reverts the `_` variable to its previous value and returns a reference to
15704     * the `lodash` function.
15705     *
15706     * @static
15707     * @since 0.1.0
15708     * @memberOf _
15709     * @category Util
15710     * @returns {Function} Returns the `lodash` function.
15711     * @example
15712     *
15713     * var lodash = _.noConflict();
15714     */
15715    function noConflict() {
15716      if (root._ === this) {
15717        root._ = oldDash;
15718      }
15719      return this;
15720    }
15721
15722    /**
15723     * This method returns `undefined`.
15724     *
15725     * @static
15726     * @memberOf _
15727     * @since 2.3.0
15728     * @category Util
15729     * @example
15730     *
15731     * _.times(2, _.noop);
15732     * // => [undefined, undefined]
15733     */
15734    function noop() {
15735      // No operation performed.
15736    }
15737
15738    /**
15739     * Creates a function that gets the argument at index `n`. If `n` is negative,
15740     * the nth argument from the end is returned.
15741     *
15742     * @static
15743     * @memberOf _
15744     * @since 4.0.0
15745     * @category Util
15746     * @param {number} [n=0] The index of the argument to return.
15747     * @returns {Function} Returns the new pass-thru function.
15748     * @example
15749     *
15750     * var func = _.nthArg(1);
15751     * func('a', 'b', 'c', 'd');
15752     * // => 'b'
15753     *
15754     * var func = _.nthArg(-2);
15755     * func('a', 'b', 'c', 'd');
15756     * // => 'c'
15757     */
15758    function nthArg(n) {
15759      n = toInteger(n);
15760      return baseRest(function(args) {
15761        return baseNth(args, n);
15762      });
15763    }
15764
15765    /**
15766     * Creates a function that invokes `iteratees` with the arguments it receives
15767     * and returns their results.
15768     *
15769     * @static
15770     * @memberOf _
15771     * @since 4.0.0
15772     * @category Util
15773     * @param {...(Function|Function[])} [iteratees=[_.identity]]
15774     *  The iteratees to invoke.
15775     * @returns {Function} Returns the new function.
15776     * @example
15777     *
15778     * var func = _.over([Math.max, Math.min]);
15779     *
15780     * func(1, 2, 3, 4);
15781     * // => [4, 1]
15782     */
15783    var over = createOver(arrayMap);
15784
15785    /**
15786     * Creates a function that checks if **all** of the `predicates` return
15787     * truthy when invoked with the arguments it receives.
15788     *
15789     * @static
15790     * @memberOf _
15791     * @since 4.0.0
15792     * @category Util
15793     * @param {...(Function|Function[])} [predicates=[_.identity]]
15794     *  The predicates to check.
15795     * @returns {Function} Returns the new function.
15796     * @example
15797     *
15798     * var func = _.overEvery([Boolean, isFinite]);
15799     *
15800     * func('1');
15801     * // => true
15802     *
15803     * func(null);
15804     * // => false
15805     *
15806     * func(NaN);
15807     * // => false
15808     */
15809    var overEvery = createOver(arrayEvery);
15810
15811    /**
15812     * Creates a function that checks if **any** of the `predicates` return
15813     * truthy when invoked with the arguments it receives.
15814     *
15815     * @static
15816     * @memberOf _
15817     * @since 4.0.0
15818     * @category Util
15819     * @param {...(Function|Function[])} [predicates=[_.identity]]
15820     *  The predicates to check.
15821     * @returns {Function} Returns the new function.
15822     * @example
15823     *
15824     * var func = _.overSome([Boolean, isFinite]);
15825     *
15826     * func('1');
15827     * // => true
15828     *
15829     * func(null);
15830     * // => true
15831     *
15832     * func(NaN);
15833     * // => false
15834     */
15835    var overSome = createOver(arraySome);
15836
15837    /**
15838     * Creates a function that returns the value at `path` of a given object.
15839     *
15840     * @static
15841     * @memberOf _
15842     * @since 2.4.0
15843     * @category Util
15844     * @param {Array|string} path The path of the property to get.
15845     * @returns {Function} Returns the new accessor function.
15846     * @example
15847     *
15848     * var objects = [
15849     *   { 'a': { 'b': 2 } },
15850     *   { 'a': { 'b': 1 } }
15851     * ];
15852     *
15853     * _.map(objects, _.property('a.b'));
15854     * // => [2, 1]
15855     *
15856     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15857     * // => [1, 2]
15858     */
15859    function property(path) {
15860      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15861    }
15862
15863    /**
15864     * The opposite of `_.property`; this method creates a function that returns
15865     * the value at a given path of `object`.
15866     *
15867     * @static
15868     * @memberOf _
15869     * @since 3.0.0
15870     * @category Util
15871     * @param {Object} object The object to query.
15872     * @returns {Function} Returns the new accessor function.
15873     * @example
15874     *
15875     * var array = [0, 1, 2],
15876     *     object = { 'a': array, 'b': array, 'c': array };
15877     *
15878     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15879     * // => [2, 0]
15880     *
15881     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15882     * // => [2, 0]
15883     */
15884    function propertyOf(object) {
15885      return function(path) {
15886        return object == null ? undefined : baseGet(object, path);
15887      };
15888    }
15889
15890    /**
15891     * Creates an array of numbers (positive and/or negative) progressing from
15892     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15893     * `start` is specified without an `end` or `step`. If `end` is not specified,
15894     * it's set to `start` with `start` then set to `0`.
15895     *
15896     * **Note:** JavaScript follows the IEEE-754 standard for resolving
15897     * floating-point values which can produce unexpected results.
15898     *
15899     * @static
15900     * @since 0.1.0
15901     * @memberOf _
15902     * @category Util
15903     * @param {number} [start=0] The start of the range.
15904     * @param {number} end The end of the range.
15905     * @param {number} [step=1] The value to increment or decrement by.
15906     * @returns {Array} Returns the range of numbers.
15907     * @see _.inRange, _.rangeRight
15908     * @example
15909     *
15910     * _.range(4);
15911     * // => [0, 1, 2, 3]
15912     *
15913     * _.range(-4);
15914     * // => [0, -1, -2, -3]
15915     *
15916     * _.range(1, 5);
15917     * // => [1, 2, 3, 4]
15918     *
15919     * _.range(0, 20, 5);
15920     * // => [0, 5, 10, 15]
15921     *
15922     * _.range(0, -4, -1);
15923     * // => [0, -1, -2, -3]
15924     *
15925     * _.range(1, 4, 0);
15926     * // => [1, 1, 1]
15927     *
15928     * _.range(0);
15929     * // => []
15930     */
15931    var range = createRange();
15932
15933    /**
15934     * This method is like `_.range` except that it populates values in
15935     * descending order.
15936     *
15937     * @static
15938     * @memberOf _
15939     * @since 4.0.0
15940     * @category Util
15941     * @param {number} [start=0] The start of the range.
15942     * @param {number} end The end of the range.
15943     * @param {number} [step=1] The value to increment or decrement by.
15944     * @returns {Array} Returns the range of numbers.
15945     * @see _.inRange, _.range
15946     * @example
15947     *
15948     * _.rangeRight(4);
15949     * // => [3, 2, 1, 0]
15950     *
15951     * _.rangeRight(-4);
15952     * // => [-3, -2, -1, 0]
15953     *
15954     * _.rangeRight(1, 5);
15955     * // => [4, 3, 2, 1]
15956     *
15957     * _.rangeRight(0, 20, 5);
15958     * // => [15, 10, 5, 0]
15959     *
15960     * _.rangeRight(0, -4, -1);
15961     * // => [-3, -2, -1, 0]
15962     *
15963     * _.rangeRight(1, 4, 0);
15964     * // => [1, 1, 1]
15965     *
15966     * _.rangeRight(0);
15967     * // => []
15968     */
15969    var rangeRight = createRange(true);
15970
15971    /**
15972     * This method returns a new empty array.
15973     *
15974     * @static
15975     * @memberOf _
15976     * @since 4.13.0
15977     * @category Util
15978     * @returns {Array} Returns the new empty array.
15979     * @example
15980     *
15981     * var arrays = _.times(2, _.stubArray);
15982     *
15983     * console.log(arrays);
15984     * // => [[], []]
15985     *
15986     * console.log(arrays[0] === arrays[1]);
15987     * // => false
15988     */
15989    function stubArray() {
15990      return [];
15991    }
15992
15993    /**
15994     * This method returns `false`.
15995     *
15996     * @static
15997     * @memberOf _
15998     * @since 4.13.0
15999     * @category Util
16000     * @returns {boolean} Returns `false`.
16001     * @example
16002     *
16003     * _.times(2, _.stubFalse);
16004     * // => [false, false]
16005     */
16006    function stubFalse() {
16007      return false;
vendor: 1,044 bytes, lines 16008-16061
16008    }
16009
16010    /**
16011     * This method returns a new empty object.
16012     *
16013     * @static
16014     * @memberOf _
16015     * @since 4.13.0
16016     * @category Util
16017     * @returns {Object} Returns the new empty object.
16018     * @example
16019     *
16020     * var objects = _.times(2, _.stubObject);
16021     *
16022     * console.log(objects);
16023     * // => [{}, {}]
16024     *
16025     * console.log(objects[0] === objects[1]);
16026     * // => false
16027     */
16028    function stubObject() {
16029      return {};
16030    }
16031
16032    /**
16033     * This method returns an empty string.
16034     *
16035     * @static
16036     * @memberOf _
16037     * @since 4.13.0
16038     * @category Util
16039     * @returns {string} Returns the empty string.
16040     * @example
16041     *
16042     * _.times(2, _.stubString);
16043     * // => ['', '']
16044     */
16045    function stubString() {
16046      return '';
16047    }
16048
16049    /**
16050     * This method returns `true`.
16051     *
16052     * @static
16053     * @memberOf _
16054     * @since 4.13.0
16055     * @category Util
16056     * @returns {boolean} Returns `true`.
16057     * @example
16058     *
16059     * _.times(2, _.stubTrue);
16060     * // => [true, true]
16061     */
vendor: 9,081 bytes, lines 16062-16405
16062    function stubTrue() {
16063      return true;
16064    }
16065
16066    /**
16067     * Invokes the iteratee `n` times, returning an array of the results of
16068     * each invocation. The iteratee is invoked with one argument; (index).
16069     *
16070     * @static
16071     * @since 0.1.0
16072     * @memberOf _
16073     * @category Util
16074     * @param {number} n The number of times to invoke `iteratee`.
16075     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
16076     * @returns {Array} Returns the array of results.
16077     * @example
16078     *
16079     * _.times(3, String);
16080     * // => ['0', '1', '2']
16081     *
16082     *  _.times(4, _.constant(0));
16083     * // => [0, 0, 0, 0]
16084     */
16085    function times(n, iteratee) {
16086      n = toInteger(n);
16087      if (n < 1 || n > MAX_SAFE_INTEGER) {
16088        return [];
16089      }
16090      var index = MAX_ARRAY_LENGTH,
16091          length = nativeMin(n, MAX_ARRAY_LENGTH);
16092
16093      iteratee = getIteratee(iteratee);
16094      n -= MAX_ARRAY_LENGTH;
16095
16096      var result = baseTimes(length, iteratee);
16097      while (++index < n) {
16098        iteratee(index);
16099      }
16100      return result;
16101    }
16102
16103    /**
16104     * Converts `value` to a property path array.
16105     *
16106     * @static
16107     * @memberOf _
16108     * @since 4.0.0
16109     * @category Util
16110     * @param {*} value The value to convert.
16111     * @returns {Array} Returns the new property path array.
16112     * @example
16113     *
16114     * _.toPath('a.b.c');
16115     * // => ['a', 'b', 'c']
16116     *
16117     * _.toPath('a[0].b.c');
16118     * // => ['a', '0', 'b', 'c']
16119     */
16120    function toPath(value) {
16121      if (isArray(value)) {
16122        return arrayMap(value, toKey);
16123      }
16124      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
16125    }
16126
16127    /**
16128     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
16129     *
16130     * @static
16131     * @since 0.1.0
16132     * @memberOf _
16133     * @category Util
16134     * @param {string} [prefix=''] The value to prefix the ID with.
16135     * @returns {string} Returns the unique ID.
16136     * @example
16137     *
16138     * _.uniqueId('contact_');
16139     * // => 'contact_104'
16140     *
16141     * _.uniqueId();
16142     * // => '105'
16143     */
16144    function uniqueId(prefix) {
16145      var id = ++idCounter;
16146      return toString(prefix) + id;
16147    }
16148
16149    /*------------------------------------------------------------------------*/
16150
16151    /**
16152     * Adds two numbers.
16153     *
16154     * @static
16155     * @memberOf _
16156     * @since 3.4.0
16157     * @category Math
16158     * @param {number} augend The first number in an addition.
16159     * @param {number} addend The second number in an addition.
16160     * @returns {number} Returns the total.
16161     * @example
16162     *
16163     * _.add(6, 4);
16164     * // => 10
16165     */
16166    var add = createMathOperation(function(augend, addend) {
16167      return augend + addend;
16168    }, 0);
16169
16170    /**
16171     * Computes `number` rounded up to `precision`.
16172     *
16173     * @static
16174     * @memberOf _
16175     * @since 3.10.0
16176     * @category Math
16177     * @param {number} number The number to round up.
16178     * @param {number} [precision=0] The precision to round up to.
16179     * @returns {number} Returns the rounded up number.
16180     * @example
16181     *
16182     * _.ceil(4.006);
16183     * // => 5
16184     *
16185     * _.ceil(6.004, 2);
16186     * // => 6.01
16187     *
16188     * _.ceil(6040, -2);
16189     * // => 6100
16190     */
16191    var ceil = createRound('ceil');
16192
16193    /**
16194     * Divide two numbers.
16195     *
16196     * @static
16197     * @memberOf _
16198     * @since 4.7.0
16199     * @category Math
16200     * @param {number} dividend The first number in a division.
16201     * @param {number} divisor The second number in a division.
16202     * @returns {number} Returns the quotient.
16203     * @example
16204     *
16205     * _.divide(6, 4);
16206     * // => 1.5
16207     */
16208    var divide = createMathOperation(function(dividend, divisor) {
16209      return dividend / divisor;
16210    }, 1);
16211
16212    /**
16213     * Computes `number` rounded down to `precision`.
16214     *
16215     * @static
16216     * @memberOf _
16217     * @since 3.10.0
16218     * @category Math
16219     * @param {number} number The number to round down.
16220     * @param {number} [precision=0] The precision to round down to.
16221     * @returns {number} Returns the rounded down number.
16222     * @example
16223     *
16224     * _.floor(4.006);
16225     * // => 4
16226     *
16227     * _.floor(0.046, 2);
16228     * // => 0.04
16229     *
16230     * _.floor(4060, -2);
16231     * // => 4000
16232     */
16233    var floor = createRound('floor');
16234
16235    /**
16236     * Computes the maximum value of `array`. If `array` is empty or falsey,
16237     * `undefined` is returned.
16238     *
16239     * @static
16240     * @since 0.1.0
16241     * @memberOf _
16242     * @category Math
16243     * @param {Array} array The array to iterate over.
16244     * @returns {*} Returns the maximum value.
16245     * @example
16246     *
16247     * _.max([4, 2, 8, 6]);
16248     * // => 8
16249     *
16250     * _.max([]);
16251     * // => undefined
16252     */
16253    function max(array) {
16254      return (array && array.length)
16255        ? baseExtremum(array, identity, baseGt)
16256        : undefined;
16257    }
16258
16259    /**
16260     * This method is like `_.max` except that it accepts `iteratee` which is
16261     * invoked for each element in `array` to generate the criterion by which
16262     * the value is ranked. The iteratee is invoked with one argument: (value).
16263     *
16264     * @static
16265     * @memberOf _
16266     * @since 4.0.0
16267     * @category Math
16268     * @param {Array} array The array to iterate over.
16269     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16270     * @returns {*} Returns the maximum value.
16271     * @example
16272     *
16273     * var objects = [{ 'n': 1 }, { 'n': 2 }];
16274     *
16275     * _.maxBy(objects, function(o) { return o.n; });
16276     * // => { 'n': 2 }
16277     *
16278     * // The `_.property` iteratee shorthand.
16279     * _.maxBy(objects, 'n');
16280     * // => { 'n': 2 }
16281     */
16282    function maxBy(array, iteratee) {
16283      return (array && array.length)
16284        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
16285        : undefined;
16286    }
16287
16288    /**
16289     * Computes the mean of the values in `array`.
16290     *
16291     * @static
16292     * @memberOf _
16293     * @since 4.0.0
16294     * @category Math
16295     * @param {Array} array The array to iterate over.
16296     * @returns {number} Returns the mean.
16297     * @example
16298     *
16299     * _.mean([4, 2, 8, 6]);
16300     * // => 5
16301     */
16302    function mean(array) {
16303      return baseMean(array, identity);
16304    }
16305
16306    /**
16307     * This method is like `_.mean` except that it accepts `iteratee` which is
16308     * invoked for each element in `array` to generate the value to be averaged.
16309     * The iteratee is invoked with one argument: (value).
16310     *
16311     * @static
16312     * @memberOf _
16313     * @since 4.7.0
16314     * @category Math
16315     * @param {Array} array The array to iterate over.
16316     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16317     * @returns {number} Returns the mean.
16318     * @example
16319     *
16320     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16321     *
16322     * _.meanBy(objects, function(o) { return o.n; });
16323     * // => 5
16324     *
16325     * // The `_.property` iteratee shorthand.
16326     * _.meanBy(objects, 'n');
16327     * // => 5
16328     */
16329    function meanBy(array, iteratee) {
16330      return baseMean(array, getIteratee(iteratee, 2));
16331    }
16332
16333    /**
16334     * Computes the minimum value of `array`. If `array` is empty or falsey,
16335     * `undefined` is returned.
16336     *
16337     * @static
16338     * @since 0.1.0
16339     * @memberOf _
16340     * @category Math
16341     * @param {Array} array The array to iterate over.
16342     * @returns {*} Returns the minimum value.
16343     * @example
16344     *
16345     * _.min([4, 2, 8, 6]);
16346     * // => 2
16347     *
16348     * _.min([]);
16349     * // => undefined
16350     */
16351    function min(array) {
16352      return (array && array.length)
16353        ? baseExtremum(array, identity, baseLt)
16354        : undefined;
16355    }
16356
16357    /**
16358     * This method is like `_.min` except that it accepts `iteratee` which is
16359     * invoked for each element in `array` to generate the criterion by which
16360     * the value is ranked. The iteratee is invoked with one argument: (value).
16361     *
16362     * @static
16363     * @memberOf _
16364     * @since 4.0.0
16365     * @category Math
16366     * @param {Array} array The array to iterate over.
16367     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16368     * @returns {*} Returns the minimum value.
16369     * @example
16370     *
16371     * var objects = [{ 'n': 1 }, { 'n': 2 }];
16372     *
16373     * _.minBy(objects, function(o) { return o.n; });
16374     * // => { 'n': 1 }
16375     *
16376     * // The `_.property` iteratee shorthand.
16377     * _.minBy(objects, 'n');
16378     * // => { 'n': 1 }
16379     */
16380    function minBy(array, iteratee) {
16381      return (array && array.length)
16382        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
16383        : undefined;
16384    }
16385
16386    /**
16387     * Multiply two numbers.
16388     *
16389     * @static
16390     * @memberOf _
16391     * @since 4.7.0
16392     * @category Math
16393     * @param {number} multiplier The first number in a multiplication.
16394     * @param {number} multiplicand The second number in a multiplication.
16395     * @returns {number} Returns the product.
16396     * @example
16397     *
16398     * _.multiply(6, 4);
16399     * // => 24
16400     */
16401    var multiply = createMathOperation(function(multiplier, multiplicand) {
16402      return multiplier * multiplicand;
16403    }, 1);
16404
16405    /**
vendor: 13,137 bytes, lines 16406-16844
16406     * Computes `number` rounded to `precision`.
16407     *
16408     * @static
16409     * @memberOf _
16410     * @since 3.10.0
16411     * @category Math
16412     * @param {number} number The number to round.
16413     * @param {number} [precision=0] The precision to round to.
16414     * @returns {number} Returns the rounded number.
16415     * @example
16416     *
16417     * _.round(4.006);
16418     * // => 4
16419     *
16420     * _.round(4.006, 2);
16421     * // => 4.01
16422     *
16423     * _.round(4060, -2);
16424     * // => 4100
16425     */
16426    var round = createRound('round');
16427
16428    /**
16429     * Subtract two numbers.
16430     *
16431     * @static
16432     * @memberOf _
16433     * @since 4.0.0
16434     * @category Math
16435     * @param {number} minuend The first number in a subtraction.
16436     * @param {number} subtrahend The second number in a subtraction.
16437     * @returns {number} Returns the difference.
16438     * @example
16439     *
16440     * _.subtract(6, 4);
16441     * // => 2
16442     */
16443    var subtract = createMathOperation(function(minuend, subtrahend) {
16444      return minuend - subtrahend;
16445    }, 0);
16446
16447    /**
16448     * Computes the sum of the values in `array`.
16449     *
16450     * @static
16451     * @memberOf _
16452     * @since 3.4.0
16453     * @category Math
16454     * @param {Array} array The array to iterate over.
16455     * @returns {number} Returns the sum.
16456     * @example
16457     *
16458     * _.sum([4, 2, 8, 6]);
16459     * // => 20
16460     */
16461    function sum(array) {
16462      return (array && array.length)
16463        ? baseSum(array, identity)
16464        : 0;
16465    }
16466
16467    /**
16468     * This method is like `_.sum` except that it accepts `iteratee` which is
16469     * invoked for each element in `array` to generate the value to be summed.
16470     * The iteratee is invoked with one argument: (value).
16471     *
16472     * @static
16473     * @memberOf _
16474     * @since 4.0.0
16475     * @category Math
16476     * @param {Array} array The array to iterate over.
16477     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
16478     * @returns {number} Returns the sum.
16479     * @example
16480     *
16481     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
16482     *
16483     * _.sumBy(objects, function(o) { return o.n; });
16484     * // => 20
16485     *
16486     * // The `_.property` iteratee shorthand.
16487     * _.sumBy(objects, 'n');
16488     * // => 20
16489     */
16490    function sumBy(array, iteratee) {
16491      return (array && array.length)
16492        ? baseSum(array, getIteratee(iteratee, 2))
16493        : 0;
16494    }
16495
16496    /*------------------------------------------------------------------------*/
16497
16498    // Add methods that return wrapped values in chain sequences.
16499    lodash.after = after;
16500    lodash.ary = ary;
16501    lodash.assign = assign;
16502    lodash.assignIn = assignIn;
16503    lodash.assignInWith = assignInWith;
16504    lodash.assignWith = assignWith;
16505    lodash.at = at;
16506    lodash.before = before;
16507    lodash.bind = bind;
16508    lodash.bindAll = bindAll;
16509    lodash.bindKey = bindKey;
16510    lodash.castArray = castArray;
16511    lodash.chain = chain;
16512    lodash.chunk = chunk;
16513    lodash.compact = compact;
16514    lodash.concat = concat;
16515    lodash.cond = cond;
16516    lodash.conforms = conforms;
16517    lodash.constant = constant;
16518    lodash.countBy = countBy;
16519    lodash.create = create;
16520    lodash.curry = curry;
16521    lodash.curryRight = curryRight;
16522    lodash.debounce = debounce;
16523    lodash.defaults = defaults;
16524    lodash.defaultsDeep = defaultsDeep;
16525    lodash.defer = defer;
16526    lodash.delay = delay;
16527    lodash.difference = difference;
16528    lodash.differenceBy = differenceBy;
16529    lodash.differenceWith = differenceWith;
16530    lodash.drop = drop;
16531    lodash.dropRight = dropRight;
16532    lodash.dropRightWhile = dropRightWhile;
16533    lodash.dropWhile = dropWhile;
16534    lodash.fill = fill;
16535    lodash.filter = filter;
16536    lodash.flatMap = flatMap;
16537    lodash.flatMapDeep = flatMapDeep;
16538    lodash.flatMapDepth = flatMapDepth;
16539    lodash.flatten = flatten;
16540    lodash.flattenDeep = flattenDeep;
16541    lodash.flattenDepth = flattenDepth;
16542    lodash.flip = flip;
16543    lodash.flow = flow;
16544    lodash.flowRight = flowRight;
16545    lodash.fromPairs = fromPairs;
16546    lodash.functions = functions;
16547    lodash.functionsIn = functionsIn;
16548    lodash.groupBy = groupBy;
16549    lodash.initial = initial;
16550    lodash.intersection = intersection;
16551    lodash.intersectionBy = intersectionBy;
16552    lodash.intersectionWith = intersectionWith;
16553    lodash.invert = invert;
16554    lodash.invertBy = invertBy;
16555    lodash.invokeMap = invokeMap;
16556    lodash.iteratee = iteratee;
16557    lodash.keyBy = keyBy;
16558    lodash.keys = keys;
16559    lodash.keysIn = keysIn;
16560    lodash.map = map;
16561    lodash.mapKeys = mapKeys;
16562    lodash.mapValues = mapValues;
16563    lodash.matches = matches;
16564    lodash.matchesProperty = matchesProperty;
16565    lodash.memoize = memoize;
16566    lodash.merge = merge;
16567    lodash.mergeWith = mergeWith;
16568    lodash.method = method;
16569    lodash.methodOf = methodOf;
16570    lodash.mixin = mixin;
16571    lodash.negate = negate;
16572    lodash.nthArg = nthArg;
16573    lodash.omit = omit;
16574    lodash.omitBy = omitBy;
16575    lodash.once = once;
16576    lodash.orderBy = orderBy;
16577    lodash.over = over;
16578    lodash.overArgs = overArgs;
16579    lodash.overEvery = overEvery;
16580    lodash.overSome = overSome;
16581    lodash.partial = partial;
16582    lodash.partialRight = partialRight;
16583    lodash.partition = partition;
16584    lodash.pick = pick;
16585    lodash.pickBy = pickBy;
16586    lodash.property = property;
16587    lodash.propertyOf = propertyOf;
16588    lodash.pull = pull;
16589    lodash.pullAll = pullAll;
16590    lodash.pullAllBy = pullAllBy;
16591    lodash.pullAllWith = pullAllWith;
16592    lodash.pullAt = pullAt;
16593    lodash.range = range;
16594    lodash.rangeRight = rangeRight;
16595    lodash.rearg = rearg;
16596    lodash.reject = reject;
16597    lodash.remove = remove;
16598    lodash.rest = rest;
16599    lodash.reverse = reverse;
16600    lodash.sampleSize = sampleSize;
16601    lodash.set = set;
16602    lodash.setWith = setWith;
16603    lodash.shuffle = shuffle;
16604    lodash.slice = slice;
16605    lodash.sortBy = sortBy;
16606    lodash.sortedUniq = sortedUniq;
16607    lodash.sortedUniqBy = sortedUniqBy;
16608    lodash.split = split;
16609    lodash.spread = spread;
16610    lodash.tail = tail;
16611    lodash.take = take;
16612    lodash.takeRight = takeRight;
16613    lodash.takeRightWhile = takeRightWhile;
16614    lodash.takeWhile = takeWhile;
16615    lodash.tap = tap;
16616    lodash.throttle = throttle;
16617    lodash.thru = thru;
16618    lodash.toArray = toArray;
16619    lodash.toPairs = toPairs;
16620    lodash.toPairsIn = toPairsIn;
16621    lodash.toPath = toPath;
16622    lodash.toPlainObject = toPlainObject;
16623    lodash.transform = transform;
16624    lodash.unary = unary;
16625    lodash.union = union;
16626    lodash.unionBy = unionBy;
16627    lodash.unionWith = unionWith;
16628    lodash.uniq = uniq;
16629    lodash.uniqBy = uniqBy;
16630    lodash.uniqWith = uniqWith;
16631    lodash.unset = unset;
16632    lodash.unzip = unzip;
16633    lodash.unzipWith = unzipWith;
16634    lodash.update = update;
16635    lodash.updateWith = updateWith;
16636    lodash.values = values;
16637    lodash.valuesIn = valuesIn;
16638    lodash.without = without;
16639    lodash.words = words;
16640    lodash.wrap = wrap;
16641    lodash.xor = xor;
16642    lodash.xorBy = xorBy;
16643    lodash.xorWith = xorWith;
16644    lodash.zip = zip;
16645    lodash.zipObject = zipObject;
16646    lodash.zipObjectDeep = zipObjectDeep;
16647    lodash.zipWith = zipWith;
16648
16649    // Add aliases.
16650    lodash.entries = toPairs;
16651    lodash.entriesIn = toPairsIn;
16652    lodash.extend = assignIn;
16653    lodash.extendWith = assignInWith;
16654
16655    // Add methods to `lodash.prototype`.
16656    mixin(lodash, lodash);
16657
16658    /*------------------------------------------------------------------------*/
16659
16660    // Add methods that return unwrapped values in chain sequences.
16661    lodash.add = add;
16662    lodash.attempt = attempt;
16663    lodash.camelCase = camelCase;
16664    lodash.capitalize = capitalize;
16665    lodash.ceil = ceil;
16666    lodash.clamp = clamp;
16667    lodash.clone = clone;
16668    lodash.cloneDeep = cloneDeep;
16669    lodash.cloneDeepWith = cloneDeepWith;
16670    lodash.cloneWith = cloneWith;
16671    lodash.conformsTo = conformsTo;
16672    lodash.deburr = deburr;
16673    lodash.defaultTo = defaultTo;
16674    lodash.divide = divide;
16675    lodash.endsWith = endsWith;
16676    lodash.eq = eq;
16677    lodash.escape = escape;
16678    lodash.escapeRegExp = escapeRegExp;
16679    lodash.every = every;
16680    lodash.find = find;
16681    lodash.findIndex = findIndex;
16682    lodash.findKey = findKey;
16683    lodash.findLast = findLast;
16684    lodash.findLastIndex = findLastIndex;
16685    lodash.findLastKey = findLastKey;
16686    lodash.floor = floor;
16687    lodash.forEach = forEach;
16688    lodash.forEachRight = forEachRight;
16689    lodash.forIn = forIn;
16690    lodash.forInRight = forInRight;
16691    lodash.forOwn = forOwn;
16692    lodash.forOwnRight = forOwnRight;
16693    lodash.get = get;
16694    lodash.gt = gt;
16695    lodash.gte = gte;
16696    lodash.has = has;
16697    lodash.hasIn = hasIn;
16698    lodash.head = head;
16699    lodash.identity = identity;
16700    lodash.includes = includes;
16701    lodash.indexOf = indexOf;
16702    lodash.inRange = inRange;
16703    lodash.invoke = invoke;
16704    lodash.isArguments = isArguments;
16705    lodash.isArray = isArray;
16706    lodash.isArrayBuffer = isArrayBuffer;
16707    lodash.isArrayLike = isArrayLike;
16708    lodash.isArrayLikeObject = isArrayLikeObject;
16709    lodash.isBoolean = isBoolean;
16710    lodash.isBuffer = isBuffer;
16711    lodash.isDate = isDate;
16712    lodash.isElement = isElement;
16713    lodash.isEmpty = isEmpty;
16714    lodash.isEqual = isEqual;
16715    lodash.isEqualWith = isEqualWith;
16716    lodash.isError = isError;
16717    lodash.isFinite = isFinite;
16718    lodash.isFunction = isFunction;
16719    lodash.isInteger = isInteger;
16720    lodash.isLength = isLength;
16721    lodash.isMap = isMap;
16722    lodash.isMatch = isMatch;
16723    lodash.isMatchWith = isMatchWith;
16724    lodash.isNaN = isNaN;
16725    lodash.isNative = isNative;
16726    lodash.isNil = isNil;
16727    lodash.isNull = isNull;
16728    lodash.isNumber = isNumber;
16729    lodash.isObject = isObject;
16730    lodash.isObjectLike = isObjectLike;
16731    lodash.isPlainObject = isPlainObject;
16732    lodash.isRegExp = isRegExp;
16733    lodash.isSafeInteger = isSafeInteger;
16734    lodash.isSet = isSet;
16735    lodash.isString = isString;
16736    lodash.isSymbol = isSymbol;
16737    lodash.isTypedArray = isTypedArray;
16738    lodash.isUndefined = isUndefined;
16739    lodash.isWeakMap = isWeakMap;
16740    lodash.isWeakSet = isWeakSet;
16741    lodash.join = join;
16742    lodash.kebabCase = kebabCase;
16743    lodash.last = last;
16744    lodash.lastIndexOf = lastIndexOf;
16745    lodash.lowerCase = lowerCase;
16746    lodash.lowerFirst = lowerFirst;
16747    lodash.lt = lt;
16748    lodash.lte = lte;
16749    lodash.max = max;
16750    lodash.maxBy = maxBy;
16751    lodash.mean = mean;
16752    lodash.meanBy = meanBy;
16753    lodash.min = min;
16754    lodash.minBy = minBy;
16755    lodash.stubArray = stubArray;
16756    lodash.stubFalse = stubFalse;
16757    lodash.stubObject = stubObject;
16758    lodash.stubString = stubString;
16759    lodash.stubTrue = stubTrue;
16760    lodash.multiply = multiply;
16761    lodash.nth = nth;
16762    lodash.noConflict = noConflict;
16763    lodash.noop = noop;
16764    lodash.now = now;
16765    lodash.pad = pad;
16766    lodash.padEnd = padEnd;
16767    lodash.padStart = padStart;
16768    lodash.parseInt = parseInt;
16769    lodash.random = random;
16770    lodash.reduce = reduce;
16771    lodash.reduceRight = reduceRight;
16772    lodash.repeat = repeat;
16773    lodash.replace = replace;
16774    lodash.result = result;
16775    lodash.round = round;
16776    lodash.runInContext = runInContext;
16777    lodash.sample = sample;
16778    lodash.size = size;
16779    lodash.snakeCase = snakeCase;
16780    lodash.some = some;
16781    lodash.sortedIndex = sortedIndex;
16782    lodash.sortedIndexBy = sortedIndexBy;
16783    lodash.sortedIndexOf = sortedIndexOf;
16784    lodash.sortedLastIndex = sortedLastIndex;
16785    lodash.sortedLastIndexBy = sortedLastIndexBy;
16786    lodash.sortedLastIndexOf = sortedLastIndexOf;
16787    lodash.startCase = startCase;
16788    lodash.startsWith = startsWith;
16789    lodash.subtract = subtract;
16790    lodash.sum = sum;
16791    lodash.sumBy = sumBy;
16792    lodash.template = template;
16793    lodash.times = times;
16794    lodash.toFinite = toFinite;
16795    lodash.toInteger = toInteger;
16796    lodash.toLength = toLength;
16797    lodash.toLower = toLower;
16798    lodash.toNumber = toNumber;
16799    lodash.toSafeInteger = toSafeInteger;
16800    lodash.toString = toString;
16801    lodash.toUpper = toUpper;
16802    lodash.trim = trim;
16803    lodash.trimEnd = trimEnd;
16804    lodash.trimStart = trimStart;
16805    lodash.truncate = truncate;
16806    lodash.unescape = unescape;
16807    lodash.uniqueId = uniqueId;
16808    lodash.upperCase = upperCase;
16809    lodash.upperFirst = upperFirst;
16810
16811    // Add aliases.
16812    lodash.each = forEach;
16813    lodash.eachRight = forEachRight;
16814    lodash.first = head;
16815
16816    mixin(lodash, (function() {
16817      var source = {};
16818      baseForOwn(lodash, function(func, methodName) {
16819        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16820          source[methodName] = func;
16821        }
16822      });
16823      return source;
16824    }()), { 'chain': false });
16825
16826    /*------------------------------------------------------------------------*/
16827
16828    /**
16829     * The semantic version number.
16830     *
16831     * @static
16832     * @memberOf _
16833     * @type {string}
16834     */
16835    lodash.VERSION = VERSION;
16836
16837    // Assign default placeholders.
16838    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16839      lodash[methodName].placeholder = lodash;
16840    });
16841
16842    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16843    arrayEach(['drop', 'take'], function(methodName, index) {
16844      LazyWrapper.prototype[methodName] = function(n) {
vendor: 6,109 bytes, lines 16845-17020
16845        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16846
16847        var result = (this.__filtered__ && !index)
16848          ? new LazyWrapper(this)
16849          : this.clone();
16850
16851        if (result.__filtered__) {
16852          result.__takeCount__ = nativeMin(n, result.__takeCount__);
16853        } else {
16854          result.__views__.push({
16855            'size': nativeMin(n, MAX_ARRAY_LENGTH),
16856            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16857          });
16858        }
16859        return result;
16860      };
16861
16862      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16863        return this.reverse()[methodName](n).reverse();
16864      };
16865    });
16866
16867    // Add `LazyWrapper` methods that accept an `iteratee` value.
16868    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16869      var type = index + 1,
16870          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16871
16872      LazyWrapper.prototype[methodName] = function(iteratee) {
16873        var result = this.clone();
16874        result.__iteratees__.push({
16875          'iteratee': getIteratee(iteratee, 3),
16876          'type': type
16877        });
16878        result.__filtered__ = result.__filtered__ || isFilter;
16879        return result;
16880      };
16881    });
16882
16883    // Add `LazyWrapper` methods for `_.head` and `_.last`.
16884    arrayEach(['head', 'last'], function(methodName, index) {
16885      var takeName = 'take' + (index ? 'Right' : '');
16886
16887      LazyWrapper.prototype[methodName] = function() {
16888        return this[takeName](1).value()[0];
16889      };
16890    });
16891
16892    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
16893    arrayEach(['initial', 'tail'], function(methodName, index) {
16894      var dropName = 'drop' + (index ? '' : 'Right');
16895
16896      LazyWrapper.prototype[methodName] = function() {
16897        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
16898      };
16899    });
16900
16901    LazyWrapper.prototype.compact = function() {
16902      return this.filter(identity);
16903    };
16904
16905    LazyWrapper.prototype.find = function(predicate) {
16906      return this.filter(predicate).head();
16907    };
16908
16909    LazyWrapper.prototype.findLast = function(predicate) {
16910      return this.reverse().find(predicate);
16911    };
16912
16913    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
16914      if (typeof path == 'function') {
16915        return new LazyWrapper(this);
16916      }
16917      return this.map(function(value) {
16918        return baseInvoke(value, path, args);
16919      });
16920    });
16921
16922    LazyWrapper.prototype.reject = function(predicate) {
16923      return this.filter(negate(getIteratee(predicate)));
16924    };
16925
16926    LazyWrapper.prototype.slice = function(start, end) {
16927      start = toInteger(start);
16928
16929      var result = this;
16930      if (result.__filtered__ && (start > 0 || end < 0)) {
16931        return new LazyWrapper(result);
16932      }
16933      if (start < 0) {
16934        result = result.takeRight(-start);
16935      } else if (start) {
16936        result = result.drop(start);
16937      }
16938      if (end !== undefined) {
16939        end = toInteger(end);
16940        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16941      }
16942      return result;
16943    };
16944
16945    LazyWrapper.prototype.takeRightWhile = function(predicate) {
16946      return this.reverse().takeWhile(predicate).reverse();
16947    };
16948
16949    LazyWrapper.prototype.toArray = function() {
16950      return this.take(MAX_ARRAY_LENGTH);
16951    };
16952
16953    // Add `LazyWrapper` methods to `lodash.prototype`.
16954    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16955      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16956          isTaker = /^(?:head|last)$/.test(methodName),
16957          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16958          retUnwrapped = isTaker || /^find/.test(methodName);
16959
16960      if (!lodashFunc) {
16961        return;
16962      }
16963      lodash.prototype[methodName] = function() {
16964        var value = this.__wrapped__,
16965            args = isTaker ? [1] : arguments,
16966            isLazy = value instanceof LazyWrapper,
16967            iteratee = args[0],
16968            useLazy = isLazy || isArray(value);
16969
16970        var interceptor = function(value) {
16971          var result = lodashFunc.apply(lodash, arrayPush([value], args));
16972          return (isTaker && chainAll) ? result[0] : result;
16973        };
16974
16975        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16976          // Avoid lazy use if the iteratee has a "length" value other than `1`.
16977          isLazy = useLazy = false;
16978        }
16979        var chainAll = this.__chain__,
16980            isHybrid = !!this.__actions__.length,
16981            isUnwrapped = retUnwrapped && !chainAll,
16982            onlyLazy = isLazy && !isHybrid;
16983
16984        if (!retUnwrapped && useLazy) {
16985          value = onlyLazy ? value : new LazyWrapper(this);
16986          var result = func.apply(value, args);
16987          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
16988          return new LodashWrapper(result, chainAll);
16989        }
16990        if (isUnwrapped && onlyLazy) {
16991          return func.apply(this, args);
16992        }
16993        result = this.thru(interceptor);
16994        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
16995      };
16996    });
16997
16998    // Add `Array` methods to `lodash.prototype`.
16999    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
17000      var func = arrayProto[methodName],
17001          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
17002          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
17003
17004      lodash.prototype[methodName] = function() {
17005        var args = arguments;
17006        if (retUnwrapped && !this.__chain__) {
17007          var value = this.value();
17008          return func.apply(isArray(value) ? value : [], args);
17009        }
17010        return this[chainName](function(value) {
17011          return func.apply(isArray(value) ? value : [], args);
17012        });
17013      };
17014    });
17015
17016    // Map minified method names to their real names.
17017    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
17018      var lodashFunc = lodash[methodName];
17019      if (lodashFunc) {
17020        var key = 
vendor: 5,398 bytes, lines 17020-17213
17020(lodashFunc.name + ''),
17021            names = realNames[key] || (realNames[key] = []);
17022
17023        names.push({ 'name': methodName, 'func': lodashFunc });
17024      }
17025    });
17026
17027    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
17028      'name': 'wrapper',
17029      'func': undefined
17030    }];
17031
17032    // Add methods to `LazyWrapper`.
17033    LazyWrapper.prototype.clone = lazyClone;
17034    LazyWrapper.prototype.reverse = lazyReverse;
17035    LazyWrapper.prototype.value = lazyValue;
17036
17037    // Add chain sequence methods to the `lodash` wrapper.
17038    lodash.prototype.at = wrapperAt;
17039    lodash.prototype.chain = wrapperChain;
17040    lodash.prototype.commit = wrapperCommit;
17041    lodash.prototype.next = wrapperNext;
17042    lodash.prototype.plant = wrapperPlant;
17043    lodash.prototype.reverse = wrapperReverse;
17044    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
17045
17046    // Add lazy aliases.
17047    lodash.prototype.first = lodash.prototype.head;
17048
17049    if (symIterator) {
17050      lodash.prototype[symIterator] = wrapperToIterator;
17051    }
17052    return lodash;
17053  });
17054
17055  /*--------------------------------------------------------------------------*/
17056
17057  // Export lodash.
17058  var _ = runInContext();
17059
17060  // Some AMD build optimizers, like r.js, check for condition patterns like:
17061  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
17062    // Expose Lodash on the global object to prevent errors when Lodash is
17063    // loaded by a script tag in the presence of an AMD loader.
17064    // See http://requirejs.org/docs/errors.html#mismatch for more details.
17065    // Use `_.noConflict` to remove Lodash from the global object.
17066    root._ = _;
17067
17068    // Define as an anonymous module so, through path mapping, it can be
17069    // referenced as the "underscore" module.
17070    define(function() {
17071      return _;
17072    });
17073  }
17074  // Check for `exports` after `define` in case a build optimizer adds it.
17075  else if (freeModule) {
17076    // Export for Node.js.
17077    (freeModule.exports = _)._ = _;
17078    // Export for CommonJS support.
17079    freeExports._ = _;
17080  }
17081  else {
17082    // Export to the global object.
17083    root._ = _;
17084  }
17085}.call(this));
17086/*!
17087 * jQuery JavaScript Library v1.12.4
17088 * http://jquery.com/
17089 *
17090 * Includes Sizzle.js
17091 * http://sizzlejs.com/
17092 *
17093 * Copyright jQuery Foundation and other contributors
17094 * Released under the MIT license
17095 * http://jquery.org/license
17096 *
17097 * Date: 2016-05-20T17:17Z
17098 */
17099
17100
17101(function( global, factory ) {
17102
17103	if ( typeof module === "object" && typeof module.exports === "object" ) {
17104		// For CommonJS and CommonJS-like environments where a proper `window`
17105		// is present, execute the factory and get jQuery.
17106		// For environments that do not have a `window` with a `document`
17107		// (such as Node.js), expose a factory as module.exports.
17108		// This accentuates the need for the creation of a real `window`.
17109		// e.g. var jQuery = require("jquery")(window);
17110		// See ticket #14549 for more info.
17111		module.exports = global.document ?
17112			factory( global, true ) :
17113			function( w ) {
17114				if ( !w.document ) {
17115					throw new Error( "jQuery requires a window with a document" );
17116				}
17117				return factory( w );
17118			};
17119	} else {
17120		factory( global );
17121	}
17122
17123// Pass this if window is not defined yet
17124}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
17125
17126// Support: Firefox 18+
17127// Can't be in strict mode, several libs including ASP.NET trace
17128// the stack via arguments.caller.callee and Firefox dies if
17129// you try to trace through "use strict" call chains. (#13335)
17130//"use strict";
17131var deletedIds = [];
17132
17133var document = window.document;
17134
17135var slice = deletedIds.slice;
17136
17137var concat = deletedIds.concat;
17138
17139var push = deletedIds.push;
17140
17141var indexOf = deletedIds.indexOf;
17142
17143var class2type = {};
17144
17145var toString = class2type.toString;
17146
17147var hasOwn = class2type.hasOwnProperty;
17148
17149var support = {};
17150
17151
17152
17153var
17154	version = "1.12.4",
17155
17156	// Define a local copy of jQuery
17157	jQuery = function( selector, context ) {
17158
17159		// The jQuery object is actually just the init constructor 'enhanced'
17160		// Need init if jQuery is called (just allow error to be thrown if not included)
17161		return new jQuery.fn.init( selector, context );
17162	},
17163
17164	// Support: Android<4.1, IE<9
17165	// Make sure we trim BOM and NBSP
17166	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
17167
17168	// Matches dashed string for camelizing
17169	rmsPrefix = /^-ms-/,
17170	rdashAlpha = /-([\da-z])/gi,
17171
17172	// Used by jQuery.camelCase as callback to replace()
17173	fcamelCase = function( all, letter ) {
17174		return letter.toUpperCase();
17175	};
17176
17177jQuery.fn = jQuery.prototype = {
17178
17179	// The current version of jQuery being used
17180	jquery: version,
17181
17182	constructor: jQuery,
17183
17184	// Start with an empty selector
17185	selector: "",
17186
17187	// The default length of a jQuery object is 0
17188	length: 0,
17189
17190	toArray: function() {
17191		return slice.call( this );
17192	},
17193
17194	// Get the Nth element in the matched element set OR
17195	// Get the whole matched element set as a clean array
17196	get: function( num ) {
17197		return num != null ?
17198
17199			// Return just the one element from the set
17200			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
17201
17202			// Return all the elements in a clean array
17203			slice.call( this );
17204	},
17205
17206	// Take an array of elements and push it onto the stack
17207	// (returning the new matched element set)
17208	pushStack: function( elems ) {
17209
17210		// Build a new jQuery matched element set
17211		var ret = jQuery.merge( this.constructor(), elems );
17212
17213		// Add the old object onto the stack (as a reference)
vendor: 4,189 bytes, lines 17214-17385
17214		ret.prevObject = this;
17215		ret.context = this.context;
17216
17217		// Return the newly-formed element set
17218		return ret;
17219	},
17220
17221	// Execute a callback for every element in the matched set.
17222	each: function( callback ) {
17223		return jQuery.each( this, callback );
17224	},
17225
17226	map: function( callback ) {
17227		return this.pushStack( jQuery.map( this, function( elem, i ) {
17228			return callback.call( elem, i, elem );
17229		} ) );
17230	},
17231
17232	slice: function() {
17233		return this.pushStack( slice.apply( this, arguments ) );
17234	},
17235
17236	first: function() {
17237		return this.eq( 0 );
17238	},
17239
17240	last: function() {
17241		return this.eq( -1 );
17242	},
17243
17244	eq: function( i ) {
17245		var len = this.length,
17246			j = +i + ( i < 0 ? len : 0 );
17247		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
17248	},
17249
17250	end: function() {
17251		return this.prevObject || this.constructor();
17252	},
17253
17254	// For internal use only.
17255	// Behaves like an Array's method, not like a jQuery method.
17256	push: push,
17257	sort: deletedIds.sort,
17258	splice: deletedIds.splice
17259};
17260
17261jQuery.extend = jQuery.fn.extend = function() {
17262	var src, copyIsArray, copy, name, options, clone,
17263		target = arguments[ 0 ] || {},
17264		i = 1,
17265		length = arguments.length,
17266		deep = false;
17267
17268	// Handle a deep copy situation
17269	if ( typeof target === "boolean" ) {
17270		deep = target;
17271
17272		// skip the boolean and the target
17273		target = arguments[ i ] || {};
17274		i++;
17275	}
17276
17277	// Handle case when target is a string or something (possible in deep copy)
17278	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
17279		target = {};
17280	}
17281
17282	// extend jQuery itself if only one argument is passed
17283	if ( i === length ) {
17284		target = this;
17285		i--;
17286	}
17287
17288	for ( ; i < length; i++ ) {
17289
17290		// Only deal with non-null/undefined values
17291		if ( ( options = arguments[ i ] ) != null ) {
17292
17293			// Extend the base object
17294			for ( name in options ) {
17295				src = target[ name ];
17296				copy = options[ name ];
17297
17298				// Prevent never-ending loop
17299				if ( target === copy ) {
17300					continue;
17301				}
17302
17303				// Recurse if we're merging plain objects or arrays
17304				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
17305					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
17306
17307					if ( copyIsArray ) {
17308						copyIsArray = false;
17309						clone = src && jQuery.isArray( src ) ? src : [];
17310
17311					} else {
17312						clone = src && jQuery.isPlainObject( src ) ? src : {};
17313					}
17314
17315					// Never move original objects, clone them
17316					target[ name ] = jQuery.extend( deep, clone, copy );
17317
17318				// Don't bring in undefined values
17319				} else if ( copy !== undefined ) {
17320					target[ name ] = copy;
17321				}
17322			}
17323		}
17324	}
17325
17326	// Return the modified object
17327	return target;
17328};
17329
17330jQuery.extend( {
17331
17332	// Unique for each copy of jQuery on the page
17333	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
17334
17335	// Assume jQuery is ready without the ready module
17336	isReady: true,
17337
17338	error: function( msg ) {
17339		throw new Error( msg );
17340	},
17341
17342	noop: function() {},
17343
17344	// See test/unit/core.js for details concerning isFunction.
17345	// Since version 1.3, DOM methods and functions like alert
17346	// aren't supported. They return false on IE (#2968).
17347	isFunction: function( obj ) {
17348		return jQuery.type( obj ) === "function";
17349	},
17350
17351	isArray: Array.isArray || function( obj ) {
17352		return jQuery.type( obj ) === "array";
17353	},
17354
17355	isWindow: function( obj ) {
17356		/* jshint eqeqeq: false */
17357		return obj != null && obj == obj.window;
17358	},
17359
17360	isNumeric: function( obj ) {
17361
17362		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
17363		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
17364		// subtraction forces infinities to NaN
17365		// adding 1 corrects loss of precision from parseFloat (#15100)
17366		var realStringObj = obj && obj.toString();
17367		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
17368	},
17369
17370	isEmptyObject: function( obj ) {
17371		var name;
17372		for ( name in obj ) {
17373			return false;
17374		}
17375		return true;
17376	},
17377
17378	isPlainObject: function( obj ) {
17379		var key;
17380
17381		// Must be an Object.
17382		// Because of IE, we also have to check the presence of the constructor property.
17383		// Make sure that DOM nodes and window objects don't pass through, as well
17384		if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
17385			return false;
vendor: 5,825 bytes, lines 17386-17639
17386		}
17387
17388		try {
17389
17390			// Not own constructor property must be Object
17391			if ( obj.constructor &&
17392				!hasOwn.call( obj, "constructor" ) &&
17393				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
17394				return false;
17395			}
17396		} catch ( e ) {
17397
17398			// IE8,9 Will throw exceptions on certain host objects #9897
17399			return false;
17400		}
17401
17402		// Support: IE<9
17403		// Handle iteration over inherited properties before own properties.
17404		if ( !support.ownFirst ) {
17405			for ( key in obj ) {
17406				return hasOwn.call( obj, key );
17407			}
17408		}
17409
17410		// Own properties are enumerated firstly, so to speed up,
17411		// if last one is own, then all properties are own.
17412		for ( key in obj ) {}
17413
17414		return key === undefined || hasOwn.call( obj, key );
17415	},
17416
17417	type: function( obj ) {
17418		if ( obj == null ) {
17419			return obj + "";
17420		}
17421		return typeof obj === "object" || typeof obj === "function" ?
17422			class2type[ toString.call( obj ) ] || "object" :
17423			typeof obj;
17424	},
17425
17426	// Workarounds based on findings by Jim Driscoll
17427	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
17428	globalEval: function( data ) {
17429		if ( data && jQuery.trim( data ) ) {
17430
17431			// We use execScript on Internet Explorer
17432			// We use an anonymous function so that context is window
17433			// rather than jQuery in Firefox
17434			( window.execScript || function( data ) {
17435				window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
17436			} )( data );
17437		}
17438	},
17439
17440	// Convert dashed to camelCase; used by the css and data modules
17441	// Microsoft forgot to hump their vendor prefix (#9572)
17442	camelCase: function( string ) {
17443		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
17444	},
17445
17446	nodeName: function( elem, name ) {
17447		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
17448	},
17449
17450	each: function( obj, callback ) {
17451		var length, i = 0;
17452
17453		if ( isArrayLike( obj ) ) {
17454			length = obj.length;
17455			for ( ; i < length; i++ ) {
17456				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
17457					break;
17458				}
17459			}
17460		} else {
17461			for ( i in obj ) {
17462				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
17463					break;
17464				}
17465			}
17466		}
17467
17468		return obj;
17469	},
17470
17471	// Support: Android<4.1, IE<9
17472	trim: function( text ) {
17473		return text == null ?
17474			"" :
17475			( text + "" ).replace( rtrim, "" );
17476	},
17477
17478	// results is for internal usage only
17479	makeArray: function( arr, results ) {
17480		var ret = results || [];
17481
17482		if ( arr != null ) {
17483			if ( isArrayLike( Object( arr ) ) ) {
17484				jQuery.merge( ret,
17485					typeof arr === "string" ?
17486					[ arr ] : arr
17487				);
17488			} else {
17489				push.call( ret, arr );
17490			}
17491		}
17492
17493		return ret;
17494	},
17495
17496	inArray: function( elem, arr, i ) {
17497		var len;
17498
17499		if ( arr ) {
17500			if ( indexOf ) {
17501				return indexOf.call( arr, elem, i );
17502			}
17503
17504			len = arr.length;
17505			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
17506
17507			for ( ; i < len; i++ ) {
17508
17509				// Skip accessing in sparse arrays
17510				if ( i in arr && arr[ i ] === elem ) {
17511					return i;
17512				}
17513			}
17514		}
17515
17516		return -1;
17517	},
17518
17519	merge: function( first, second ) {
17520		var len = +second.length,
17521			j = 0,
17522			i = first.length;
17523
17524		while ( j < len ) {
17525			first[ i++ ] = second[ j++ ];
17526		}
17527
17528		// Support: IE<9
17529		// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
17530		if ( len !== len ) {
17531			while ( second[ j ] !== undefined ) {
17532				first[ i++ ] = second[ j++ ];
17533			}
17534		}
17535
17536		first.length = i;
17537
17538		return first;
17539	},
17540
17541	grep: function( elems, callback, invert ) {
17542		var callbackInverse,
17543			matches = [],
17544			i = 0,
17545			length = elems.length,
17546			callbackExpect = !invert;
17547
17548		// Go through the array, only saving the items
17549		// that pass the validator function
17550		for ( ; i < length; i++ ) {
17551			callbackInverse = !callback( elems[ i ], i );
17552			if ( callbackInverse !== callbackExpect ) {
17553				matches.push( elems[ i ] );
17554			}
17555		}
17556
17557		return matches;
17558	},
17559
17560	// arg is for internal usage only
17561	map: function( elems, callback, arg ) {
17562		var length, value,
17563			i = 0,
17564			ret = [];
17565
17566		// Go through the array, translating each of the items to their new values
17567		if ( isArrayLike( elems ) ) {
17568			length = elems.length;
17569			for ( ; i < length; i++ ) {
17570				value = callback( elems[ i ], i, arg );
17571
17572				if ( value != null ) {
17573					ret.push( value );
17574				}
17575			}
17576
17577		// Go through every key on the object,
17578		} else {
17579			for ( i in elems ) {
17580				value = callback( elems[ i ], i, arg );
17581
17582				if ( value != null ) {
17583					ret.push( value );
17584				}
17585			}
17586		}
17587
17588		// Flatten any nested arrays
17589		return concat.apply( [], ret );
17590	},
17591
17592	// A global GUID counter for objects
17593	guid: 1,
17594
17595	// Bind a function to a context, optionally partially applying any
17596	// arguments.
17597	proxy: function( fn, context ) {
17598		var args, proxy, tmp;
17599
17600		if ( typeof context === "string" ) {
17601			tmp = fn[ context ];
17602			context = fn;
17603			fn = tmp;
17604		}
17605
17606		// Quick check to determine if target is callable, in the spec
17607		// this throws a TypeError, but we will just return undefined.
17608		if ( !jQuery.isFunction( fn ) ) {
17609			return undefined;
17610		}
17611
17612		// Simulated bind
17613		args = slice.call( arguments, 2 );
17614		proxy = function() {
17615			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
17616		};
17617
17618		// Set the guid of unique handler to the same of original handler, so it can be removed
17619		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
17620
17621		return proxy;
17622	},
17623
17624	now: function() {
17625		return +( new Date() );
17626	},
17627
17628	// jQuery.support is not used in Core but other projects attach their
17629	// properties to it so it needs to exist.
17630	support: support
17631} );
17632
17633// JSHint would error on this code due to the Symbol not being defined in ES5.
17634// Defining this global in .jshintrc would create a danger of using the global
17635// unguarded in another place, it seems safer to just disable JSHint for these
17636// three lines.
17637/* jshint ignore: start */
17638if ( typeof Symbol === "function" ) {
17639	jQuery.fn[ Symbol.iterator ] = deletedIds
vendor: 63,327 bytes, lines 17639-19876
17639[ Symbol.iterator ];
17640}
17641/* jshint ignore: end */
17642
17643// Populate the class2type map
17644jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
17645function( i, name ) {
17646	class2type[ "[object " + name + "]" ] = name.toLowerCase();
17647} );
17648
17649function isArrayLike( obj ) {
17650
17651	// Support: iOS 8.2 (not reproducible in simulator)
17652	// `in` check used to prevent JIT error (gh-2145)
17653	// hasOwn isn't used here due to false negatives
17654	// regarding Nodelist length in IE
17655	var length = !!obj && "length" in obj && obj.length,
17656		type = jQuery.type( obj );
17657
17658	if ( type === "function" || jQuery.isWindow( obj ) ) {
17659		return false;
17660	}
17661
17662	return type === "array" || length === 0 ||
17663		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
17664}
17665var Sizzle =
17666/*!
17667 * Sizzle CSS Selector Engine v2.2.1
17668 * http://sizzlejs.com/
17669 *
17670 * Copyright jQuery Foundation and other contributors
17671 * Released under the MIT license
17672 * http://jquery.org/license
17673 *
17674 * Date: 2015-10-17
17675 */
17676(function( window ) {
17677
17678var i,
17679	support,
17680	Expr,
17681	getText,
17682	isXML,
17683	tokenize,
17684	compile,
17685	select,
17686	outermostContext,
17687	sortInput,
17688	hasDuplicate,
17689
17690	// Local document vars
17691	setDocument,
17692	document,
17693	docElem,
17694	documentIsHTML,
17695	rbuggyQSA,
17696	rbuggyMatches,
17697	matches,
17698	contains,
17699
17700	// Instance-specific data
17701	expando = "sizzle" + 1 * new Date(),
17702	preferredDoc = window.document,
17703	dirruns = 0,
17704	done = 0,
17705	classCache = createCache(),
17706	tokenCache = createCache(),
17707	compilerCache = createCache(),
17708	sortOrder = function( a, b ) {
17709		if ( a === b ) {
17710			hasDuplicate = true;
17711		}
17712		return 0;
17713	},
17714
17715	// General-purpose constants
17716	MAX_NEGATIVE = 1 << 31,
17717
17718	// Instance methods
17719	hasOwn = ({}).hasOwnProperty,
17720	arr = [],
17721	pop = arr.pop,
17722	push_native = arr.push,
17723	push = arr.push,
17724	slice = arr.slice,
17725	// Use a stripped-down indexOf as it's faster than native
17726	// http://jsperf.com/thor-indexof-vs-for/5
17727	indexOf = function( list, elem ) {
17728		var i = 0,
17729			len = list.length;
17730		for ( ; i < len; i++ ) {
17731			if ( list[i] === elem ) {
17732				return i;
17733			}
17734		}
17735		return -1;
17736	},
17737
17738	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
17739
17740	// Regular expressions
17741
17742	// http://www.w3.org/TR/css3-selectors/#whitespace
17743	whitespace = "[\\x20\\t\\r\\n\\f]",
17744
17745	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
17746	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
17747
17748	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
17749	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
17750		// Operator (capture 2)
17751		"*([*^$|!~]?=)" + whitespace +
17752		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
17753		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
17754		"*\\]",
17755
17756	pseudos = ":(" + identifier + ")(?:\\((" +
17757		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
17758		// 1. quoted (capture 3; capture 4 or capture 5)
17759		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
17760		// 2. simple (capture 6)
17761		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
17762		// 3. anything else (capture 2)
17763		".*" +
17764		")\\)|)",
17765
17766	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
17767	rwhitespace = new RegExp( whitespace + "+", "g" ),
17768	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
17769
17770	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
17771	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
17772
17773	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
17774
17775	rpseudo = new RegExp( pseudos ),
17776	ridentifier = new RegExp( "^" + identifier + "$" ),
17777
17778	matchExpr = {
17779		"ID": new RegExp( "^#(" + identifier + ")" ),
17780		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
17781		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
17782		"ATTR": new RegExp( "^" + attributes ),
17783		"PSEUDO": new RegExp( "^" + pseudos ),
17784		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
17785			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
17786			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
17787		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
17788		// For use in libraries implementing .is()
17789		// We use this for POS matching in `select`
17790		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
17791			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
17792	},
17793
17794	rinputs = /^(?:input|select|textarea|button)$/i,
17795	rheader = /^h\d$/i,
17796
17797	rnative = /^[^{]+\{\s*\[native \w/,
17798
17799	// Easily-parseable/retrievable ID or TAG or CLASS selectors
17800	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
17801
17802	rsibling = /[+~]/,
17803	rescape = /'|\\/g,
17804
17805	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
17806	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
17807	funescape = function( _, escaped, escapedWhitespace ) {
17808		var high = "0x" + escaped - 0x10000;
17809		// NaN means non-codepoint
17810		// Support: Firefox<24
17811		// Workaround erroneous numeric interpretation of +"0x"
17812		return high !== high || escapedWhitespace ?
17813			escaped :
17814			high < 0 ?
17815				// BMP codepoint
17816				String.fromCharCode( high + 0x10000 ) :
17817				// Supplemental Plane codepoint (surrogate pair)
17818				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
17819	},
17820
17821	// Used for iframes
17822	// See setDocument()
17823	// Removing the function wrapper causes a "Permission Denied"
17824	// error in IE
17825	unloadHandler = function() {
17826		setDocument();
17827	};
17828
17829// Optimize for push.apply( _, NodeList )
17830try {
17831	push.apply(
17832		(arr = slice.call( preferredDoc.childNodes )),
17833		preferredDoc.childNodes
17834	);
17835	// Support: Android<4.0
17836	// Detect silently failing push.apply
17837	arr[ preferredDoc.childNodes.length ].nodeType;
17838} catch ( e ) {
17839	push = { apply: arr.length ?
17840
17841		// Leverage slice if possible
17842		function( target, els ) {
17843			push_native.apply( target, slice.call(els) );
17844		} :
17845
17846		// Support: IE<9
17847		// Otherwise append directly
17848		function( target, els ) {
17849			var j = target.length,
17850				i = 0;
17851			// Can't trust NodeList.length
17852			while ( (target[j++] = els[i++]) ) {}
17853			target.length = j - 1;
17854		}
17855	};
17856}
17857
17858function Sizzle( selector, context, results, seed ) {
17859	var m, i, elem, nid, nidselect, match, groups, newSelector,
17860		newContext = context && context.ownerDocument,
17861
17862		// nodeType defaults to 9, since context defaults to document
17863		nodeType = context ? context.nodeType : 9;
17864
17865	results = results || [];
17866
17867	// Return early from calls with invalid selector or context
17868	if ( typeof selector !== "string" || !selector ||
17869		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
17870
17871		return results;
17872	}
17873
17874	// Try to shortcut find operations (as opposed to filters) in HTML documents
17875	if ( !seed ) {
17876
17877		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
17878			setDocument( context );
17879		}
17880		context = context || document;
17881
17882		if ( documentIsHTML ) {
17883
17884			// If the selector is sufficiently simple, try using a "get*By*" DOM method
17885			// (excepting DocumentFragment context, where the methods don't exist)
17886			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
17887
17888				// ID selector
17889				if ( (m = match[1]) ) {
17890
17891					// Document context
17892					if ( nodeType === 9 ) {
17893						if ( (elem = context.getElementById( m )) ) {
17894
17895							// Support: IE, Opera, Webkit
17896							// TODO: identify versions
17897							// getElementById can match elements by name instead of ID
17898							if ( elem.id === m ) {
17899								results.push( elem );
17900								return results;
17901							}
17902						} else {
17903							return results;
17904						}
17905
17906					// Element context
17907					} else {
17908
17909						// Support: IE, Opera, Webkit
17910						// TODO: identify versions
17911						// getElementById can match elements by name instead of ID
17912						if ( newContext && (elem = newContext.getElementById( m )) &&
17913							contains( context, elem ) &&
17914							elem.id === m ) {
17915
17916							results.push( elem );
17917							return results;
17918						}
17919					}
17920
17921				// Type selector
17922				} else if ( match[2] ) {
17923					push.apply( results, context.getElementsByTagName( selector ) );
17924					return results;
17925
17926				// Class selector
17927				} else if ( (m = match[3]) && support.getElementsByClassName &&
17928					context.getElementsByClassName ) {
17929
17930					push.apply( results, context.getElementsByClassName( m ) );
17931					return results;
17932				}
17933			}
17934
17935			// Take advantage of querySelectorAll
17936			if ( support.qsa &&
17937				!compilerCache[ selector + " " ] &&
17938				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
17939
17940				if ( nodeType !== 1 ) {
17941					newContext = context;
17942					newSelector = selector;
17943
17944				// qSA looks outside Element context, which is not what we want
17945				// Thanks to Andrew Dupont for this workaround technique
17946				// Support: IE <=8
17947				// Exclude object elements
17948				} else if ( context.nodeName.toLowerCase() !== "object" ) {
17949
17950					// Capture the context ID, setting it first if necessary
17951					if ( (nid = context.getAttribute( "id" )) ) {
17952						nid = nid.replace( rescape, "\\$&" );
17953					} else {
17954						context.setAttribute( "id", (nid = expando) );
17955					}
17956
17957					// Prefix every selector in the list
17958					groups = tokenize( selector );
17959					i = groups.length;
17960					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
17961					while ( i-- ) {
17962						groups[i] = nidselect + " " + toSelector( groups[i] );
17963					}
17964					newSelector = groups.join( "," );
17965
17966					// Expand context for sibling selectors
17967					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
17968						context;
17969				}
17970
17971				if ( newSelector ) {
17972					try {
17973						push.apply( results,
17974							newContext.querySelectorAll( newSelector )
17975						);
17976						return results;
17977					} catch ( qsaError ) {
17978					} finally {
17979						if ( nid === expando ) {
17980							context.removeAttribute( "id" );
17981						}
17982					}
17983				}
17984			}
17985		}
17986	}
17987
17988	// All others
17989	return select( selector.replace( rtrim, "$1" ), context, results, seed );
17990}
17991
17992/**
17993 * Create key-value caches of limited size
17994 * @returns {function(string, object)} Returns the Object data after storing it on itself with
17995 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
17996 *	deleting the oldest entry
17997 */
17998function createCache() {
17999	var keys = [];
18000
18001	function cache( key, value ) {
18002		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
18003		if ( keys.push( key + " " ) > Expr.cacheLength ) {
18004			// Only keep the most recent entries
18005			delete cache[ keys.shift() ];
18006		}
18007		return (cache[ key + " " ] = value);
18008	}
18009	return cache;
18010}
18011
18012/**
18013 * Mark a function for special use by Sizzle
18014 * @param {Function} fn The function to mark
18015 */
18016function markFunction( fn ) {
18017	fn[ expando ] = true;
18018	return fn;
18019}
18020
18021/**
18022 * Support testing using an element
18023 * @param {Function} fn Passed the created div and expects a boolean result
18024 */
18025function assert( fn ) {
18026	var div = document.createElement("div");
18027
18028	try {
18029		return !!fn( div );
18030	} catch (e) {
18031		return false;
18032	} finally {
18033		// Remove from its parent by default
18034		if ( div.parentNode ) {
18035			div.parentNode.removeChild( div );
18036		}
18037		// release memory in IE
18038		div = null;
18039	}
18040}
18041
18042/**
18043 * Adds the same handler for all of the specified attrs
18044 * @param {String} attrs Pipe-separated list of attributes
18045 * @param {Function} handler The method that will be applied
18046 */
18047function addHandle( attrs, handler ) {
18048	var arr = attrs.split("|"),
18049		i = arr.length;
18050
18051	while ( i-- ) {
18052		Expr.attrHandle[ arr[i] ] = handler;
18053	}
18054}
18055
18056/**
18057 * Checks document order of two siblings
18058 * @param {Element} a
18059 * @param {Element} b
18060 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
18061 */
18062function siblingCheck( a, b ) {
18063	var cur = b && a,
18064		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
18065			( ~b.sourceIndex || MAX_NEGATIVE ) -
18066			( ~a.sourceIndex || MAX_NEGATIVE );
18067
18068	// Use IE sourceIndex if available on both nodes
18069	if ( diff ) {
18070		return diff;
18071	}
18072
18073	// Check if b follows a
18074	if ( cur ) {
18075		while ( (cur = cur.nextSibling) ) {
18076			if ( cur === b ) {
18077				return -1;
18078			}
18079		}
18080	}
18081
18082	return a ? 1 : -1;
18083}
18084
18085/**
18086 * Returns a function to use in pseudos for input types
18087 * @param {String} type
18088 */
18089function createInputPseudo( type ) {
18090	return function( elem ) {
18091		var name = elem.nodeName.toLowerCase();
18092		return name === "input" && elem.type === type;
18093	};
18094}
18095
18096/**
18097 * Returns a function to use in pseudos for buttons
18098 * @param {String} type
18099 */
18100function createButtonPseudo( type ) {
18101	return function( elem ) {
18102		var name = elem.nodeName.toLowerCase();
18103		return (name === "input" || name === "button") && elem.type === type;
18104	};
18105}
18106
18107/**
18108 * Returns a function to use in pseudos for positionals
18109 * @param {Function} fn
18110 */
18111function createPositionalPseudo( fn ) {
18112	return markFunction(function( argument ) {
18113		argument = +argument;
18114		return markFunction(function( seed, matches ) {
18115			var j,
18116				matchIndexes = fn( [], seed.length, argument ),
18117				i = matchIndexes.length;
18118
18119			// Match elements found at the specified indexes
18120			while ( i-- ) {
18121				if ( seed[ (j = matchIndexes[i]) ] ) {
18122					seed[j] = !(matches[j] = seed[j]);
18123				}
18124			}
18125		});
18126	});
18127}
18128
18129/**
18130 * Checks a node for validity as a Sizzle context
18131 * @param {Element|Object=} context
18132 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
18133 */
18134function testContext( context ) {
18135	return context && typeof context.getElementsByTagName !== "undefined" && context;
18136}
18137
18138// Expose support vars for convenience
18139support = Sizzle.support = {};
18140
18141/**
18142 * Detects XML nodes
18143 * @param {Element|Object} elem An element or a document
18144 * @returns {Boolean} True iff elem is a non-HTML XML node
18145 */
18146isXML = Sizzle.isXML = function( elem ) {
18147	// documentElement is verified for cases where it doesn't yet exist
18148	// (such as loading iframes in IE - #4833)
18149	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
18150	return documentElement ? documentElement.nodeName !== "HTML" : false;
18151};
18152
18153/**
18154 * Sets document-related variables once based on the current document
18155 * @param {Element|Object} [doc] An element or document object to use to set the document
18156 * @returns {Object} Returns the current document
18157 */
18158setDocument = Sizzle.setDocument = function( node ) {
18159	var hasCompare, parent,
18160		doc = node ? node.ownerDocument || node : preferredDoc;
18161
18162	// Return early if doc is invalid or already selected
18163	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
18164		return document;
18165	}
18166
18167	// Update global variables
18168	document = doc;
18169	docElem = document.documentElement;
18170	documentIsHTML = !isXML( document );
18171
18172	// Support: IE 9-11, Edge
18173	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
18174	if ( (parent = document.defaultView) && parent.top !== parent ) {
18175		// Support: IE 11
18176		if ( parent.addEventListener ) {
18177			parent.addEventListener( "unload", unloadHandler, false );
18178
18179		// Support: IE 9 - 10 only
18180		} else if ( parent.attachEvent ) {
18181			parent.attachEvent( "onunload", unloadHandler );
18182		}
18183	}
18184
18185	/* Attributes
18186	---------------------------------------------------------------------- */
18187
18188	// Support: IE<8
18189	// Verify that getAttribute really returns attributes and not properties
18190	// (excepting IE8 booleans)
18191	support.attributes = assert(function( div ) {
18192		div.className = "i";
18193		return !div.getAttribute("className");
18194	});
18195
18196	/* getElement(s)By*
18197	---------------------------------------------------------------------- */
18198
18199	// Check if getElementsByTagName("*") returns only elements
18200	support.getElementsByTagName = assert(function( div ) {
18201		div.appendChild( document.createComment("") );
18202		return !div.getElementsByTagName("*").length;
18203	});
18204
18205	// Support: IE<9
18206	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
18207
18208	// Support: IE<10
18209	// Check if getElementById returns elements by name
18210	// The broken getElementById methods don't pick up programatically-set names,
18211	// so use a roundabout getElementsByName test
18212	support.getById = assert(function( div ) {
18213		docElem.appendChild( div ).id = expando;
18214		return !document.getElementsByName || !document.getElementsByName( expando ).length;
18215	});
18216
18217	// ID find and filter
18218	if ( support.getById ) {
18219		Expr.find["ID"] = function( id, context ) {
18220			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
18221				var m = context.getElementById( id );
18222				return m ? [ m ] : [];
18223			}
18224		};
18225		Expr.filter["ID"] = function( id ) {
18226			var attrId = id.replace( runescape, funescape );
18227			return function( elem ) {
18228				return elem.getAttribute("id") === attrId;
18229			};
18230		};
18231	} else {
18232		// Support: IE6/7
18233		// getElementById is not reliable as a find shortcut
18234		delete Expr.find["ID"];
18235
18236		Expr.filter["ID"] =  function( id ) {
18237			var attrId = id.replace( runescape, funescape );
18238			return function( elem ) {
18239				var node = typeof elem.getAttributeNode !== "undefined" &&
18240					elem.getAttributeNode("id");
18241				return node && node.value === attrId;
18242			};
18243		};
18244	}
18245
18246	// Tag
18247	Expr.find["TAG"] = support.getElementsByTagName ?
18248		function( tag, context ) {
18249			if ( typeof context.getElementsByTagName !== "undefined" ) {
18250				return context.getElementsByTagName( tag );
18251
18252			// DocumentFragment nodes don't have gEBTN
18253			} else if ( support.qsa ) {
18254				return context.querySelectorAll( tag );
18255			}
18256		} :
18257
18258		function( tag, context ) {
18259			var elem,
18260				tmp = [],
18261				i = 0,
18262				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
18263				results = context.getElementsByTagName( tag );
18264
18265			// Filter out possible comments
18266			if ( tag === "*" ) {
18267				while ( (elem = results[i++]) ) {
18268					if ( elem.nodeType === 1 ) {
18269						tmp.push( elem );
18270					}
18271				}
18272
18273				return tmp;
18274			}
18275			return results;
18276		};
18277
18278	// Class
18279	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
18280		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
18281			return context.getElementsByClassName( className );
18282		}
18283	};
18284
18285	/* QSA/matchesSelector
18286	---------------------------------------------------------------------- */
18287
18288	// QSA and matchesSelector support
18289
18290	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
18291	rbuggyMatches = [];
18292
18293	// qSa(:focus) reports false when true (Chrome 21)
18294	// We allow this because of a bug in IE8/9 that throws an error
18295	// whenever `document.activeElement` is accessed on an iframe
18296	// So, we allow :focus to pass through QSA all the time to avoid the IE error
18297	// See http://bugs.jquery.com/ticket/13378
18298	rbuggyQSA = [];
18299
18300	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
18301		// Build QSA regex
18302		// Regex strategy adopted from Diego Perini
18303		assert(function( div ) {
18304			// Select is set to empty string on purpose
18305			// This is to test IE's treatment of not explicitly
18306			// setting a boolean content attribute,
18307			// since its presence should be enough
18308			// http://bugs.jquery.com/ticket/12359
18309			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
18310				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
18311				"<option selected=''></option></select>";
18312
18313			// Support: IE8, Opera 11-12.16
18314			// Nothing should be selected when empty strings follow ^= or $= or *=
18315			// The test attribute must be unknown in Opera but "safe" for WinRT
18316			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
18317			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
18318				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
18319			}
18320
18321			// Support: IE8
18322			// Boolean attributes and "value" are not treated correctly
18323			if ( !div.querySelectorAll("[selected]").length ) {
18324				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
18325			}
18326
18327			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
18328			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
18329				rbuggyQSA.push("~=");
18330			}
18331
18332			// Webkit/Opera - :checked should return selected option elements
18333			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
18334			// IE8 throws error here and will not see later tests
18335			if ( !div.querySelectorAll(":checked").length ) {
18336				rbuggyQSA.push(":checked");
18337			}
18338
18339			// Support: Safari 8+, iOS 8+
18340			// https://bugs.webkit.org/show_bug.cgi?id=136851
18341			// In-page `selector#id sibing-combinator selector` fails
18342			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
18343				rbuggyQSA.push(".#.+[+~]");
18344			}
18345		});
18346
18347		assert(function( div ) {
18348			// Support: Windows 8 Native Apps
18349			// The type and name attributes are restricted during .innerHTML assignment
18350			var input = document.createElement("input");
18351			input.setAttribute( "type", "hidden" );
18352			div.appendChild( input ).setAttribute( "name", "D" );
18353
18354			// Support: IE8
18355			// Enforce case-sensitivity of name attribute
18356			if ( div.querySelectorAll("[name=d]").length ) {
18357				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
18358			}
18359
18360			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
18361			// IE8 throws error here and will not see later tests
18362			if ( !div.querySelectorAll(":enabled").length ) {
18363				rbuggyQSA.push( ":enabled", ":disabled" );
18364			}
18365
18366			// Opera 10-11 does not throw on post-comma invalid pseudos
18367			div.querySelectorAll("*,:x");
18368			rbuggyQSA.push(",.*:");
18369		});
18370	}
18371
18372	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
18373		docElem.webkitMatchesSelector ||
18374		docElem.mozMatchesSelector ||
18375		docElem.oMatchesSelector ||
18376		docElem.msMatchesSelector) )) ) {
18377
18378		assert(function( div ) {
18379			// Check to see if it's possible to do matchesSelector
18380			// on a disconnected node (IE 9)
18381			support.disconnectedMatch = matches.call( div, "div" );
18382
18383			// This should fail with an exception
18384			// Gecko does not error, returns false instead
18385			matches.call( div, "[s!='']:x" );
18386			rbuggyMatches.push( "!=", pseudos );
18387		});
18388	}
18389
18390	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
18391	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
18392
18393	/* Contains
18394	---------------------------------------------------------------------- */
18395	hasCompare = rnative.test( docElem.compareDocumentPosition );
18396
18397	// Element contains another
18398	// Purposefully self-exclusive
18399	// As in, an element does not contain itself
18400	contains = hasCompare || rnative.test( docElem.contains ) ?
18401		function( a, b ) {
18402			var adown = a.nodeType === 9 ? a.documentElement : a,
18403				bup = b && b.parentNode;
18404			return a === bup || !!( bup && bup.nodeType === 1 && (
18405				adown.contains ?
18406					adown.contains( bup ) :
18407					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
18408			));
18409		} :
18410		function( a, b ) {
18411			if ( b ) {
18412				while ( (b = b.parentNode) ) {
18413					if ( b === a ) {
18414						return true;
18415					}
18416				}
18417			}
18418			return false;
18419		};
18420
18421	/* Sorting
18422	---------------------------------------------------------------------- */
18423
18424	// Document order sorting
18425	sortOrder = hasCompare ?
18426	function( a, b ) {
18427
18428		// Flag for duplicate removal
18429		if ( a === b ) {
18430			hasDuplicate = true;
18431			return 0;
18432		}
18433
18434		// Sort on method existence if only one input has compareDocumentPosition
18435		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
18436		if ( compare ) {
18437			return compare;
18438		}
18439
18440		// Calculate position if both inputs belong to the same document
18441		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
18442			a.compareDocumentPosition( b ) :
18443
18444			// Otherwise we know they are disconnected
18445			1;
18446
18447		// Disconnected nodes
18448		if ( compare & 1 ||
18449			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
18450
18451			// Choose the first element that is related to our preferred document
18452			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
18453				return -1;
18454			}
18455			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
18456				return 1;
18457			}
18458
18459			// Maintain original order
18460			return sortInput ?
18461				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
18462				0;
18463		}
18464
18465		return compare & 4 ? -1 : 1;
18466	} :
18467	function( a, b ) {
18468		// Exit early if the nodes are identical
18469		if ( a === b ) {
18470			hasDuplicate = true;
18471			return 0;
18472		}
18473
18474		var cur,
18475			i = 0,
18476			aup = a.parentNode,
18477			bup = b.parentNode,
18478			ap = [ a ],
18479			bp = [ b ];
18480
18481		// Parentless nodes are either documents or disconnected
18482		if ( !aup || !bup ) {
18483			return a === document ? -1 :
18484				b === document ? 1 :
18485				aup ? -1 :
18486				bup ? 1 :
18487				sortInput ?
18488				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
18489				0;
18490
18491		// If the nodes are siblings, we can do a quick check
18492		} else if ( aup === bup ) {
18493			return siblingCheck( a, b );
18494		}
18495
18496		// Otherwise we need full lists of their ancestors for comparison
18497		cur = a;
18498		while ( (cur = cur.parentNode) ) {
18499			ap.unshift( cur );
18500		}
18501		cur = b;
18502		while ( (cur = cur.parentNode) ) {
18503			bp.unshift( cur );
18504		}
18505
18506		// Walk down the tree looking for a discrepancy
18507		while ( ap[i] === bp[i] ) {
18508			i++;
18509		}
18510
18511		return i ?
18512			// Do a sibling check if the nodes have a common ancestor
18513			siblingCheck( ap[i], bp[i] ) :
18514
18515			// Otherwise nodes in our document sort first
18516			ap[i] === preferredDoc ? -1 :
18517			bp[i] === preferredDoc ? 1 :
18518			0;
18519	};
18520
18521	return document;
18522};
18523
18524Sizzle.matches = function( expr, elements ) {
18525	return Sizzle( expr, null, null, elements );
18526};
18527
18528Sizzle.matchesSelector = function( elem, expr ) {
18529	// Set document vars if needed
18530	if ( ( elem.ownerDocument || elem ) !== document ) {
18531		setDocument( elem );
18532	}
18533
18534	// Make sure that attribute selectors are quoted
18535	expr = expr.replace( rattributeQuotes, "='$1']" );
18536
18537	if ( support.matchesSelector && documentIsHTML &&
18538		!compilerCache[ expr + " " ] &&
18539		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
18540		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
18541
18542		try {
18543			var ret = matches.call( elem, expr );
18544
18545			// IE 9's matchesSelector returns false on disconnected nodes
18546			if ( ret || support.disconnectedMatch ||
18547					// As well, disconnected nodes are said to be in a document
18548					// fragment in IE 9
18549					elem.document && elem.document.nodeType !== 11 ) {
18550				return ret;
18551			}
18552		} catch (e) {}
18553	}
18554
18555	return Sizzle( expr, document, null, [ elem ] ).length > 0;
18556};
18557
18558Sizzle.contains = function( context, elem ) {
18559	// Set document vars if needed
18560	if ( ( context.ownerDocument || context ) !== document ) {
18561		setDocument( context );
18562	}
18563	return contains( context, elem );
18564};
18565
18566Sizzle.attr = function( elem, name ) {
18567	// Set document vars if needed
18568	if ( ( elem.ownerDocument || elem ) !== document ) {
18569		setDocument( elem );
18570	}
18571
18572	var fn = Expr.attrHandle[ name.toLowerCase() ],
18573		// Don't get fooled by Object.prototype properties (jQuery #13807)
18574		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
18575			fn( elem, name, !documentIsHTML ) :
18576			undefined;
18577
18578	return val !== undefined ?
18579		val :
18580		support.attributes || !documentIsHTML ?
18581			elem.getAttribute( name ) :
18582			(val = elem.getAttributeNode(name)) && val.specified ?
18583				val.value :
18584				null;
18585};
18586
18587Sizzle.error = function( msg ) {
18588	throw new Error( "Syntax error, unrecognized expression: " + msg );
18589};
18590
18591/**
18592 * Document sorting and removing duplicates
18593 * @param {ArrayLike} results
18594 */
18595Sizzle.uniqueSort = function( results ) {
18596	var elem,
18597		duplicates = [],
18598		j = 0,
18599		i = 0;
18600
18601	// Unless we *know* we can detect duplicates, assume their presence
18602	hasDuplicate = !support.detectDuplicates;
18603	sortInput = !support.sortStable && results.slice( 0 );
18604	results.sort( sortOrder );
18605
18606	if ( hasDuplicate ) {
18607		while ( (elem = results[i++]) ) {
18608			if ( elem === results[ i ] ) {
18609				j = duplicates.push( i );
18610			}
18611		}
18612		while ( j-- ) {
18613			results.splice( duplicates[ j ], 1 );
18614		}
18615	}
18616
18617	// Clear input after sorting to release objects
18618	// See https://github.com/jquery/sizzle/pull/225
18619	sortInput = null;
18620
18621	return results;
18622};
18623
18624/**
18625 * Utility function for retrieving the text value of an array of DOM nodes
18626 * @param {Array|Element} elem
18627 */
18628getText = Sizzle.getText = function( elem ) {
18629	var node,
18630		ret = "",
18631		i = 0,
18632		nodeType = elem.nodeType;
18633
18634	if ( !nodeType ) {
18635		// If no nodeType, this is expected to be an array
18636		while ( (node = elem[i++]) ) {
18637			// Do not traverse comment nodes
18638			ret += getText( node );
18639		}
18640	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
18641		// Use textContent for elements
18642		// innerText usage removed for consistency of new lines (jQuery #11153)
18643		if ( typeof elem.textContent === "string" ) {
18644			return elem.textContent;
18645		} else {
18646			// Traverse its children
18647			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
18648				ret += getText( elem );
18649			}
18650		}
18651	} else if ( nodeType === 3 || nodeType === 4 ) {
18652		return elem.nodeValue;
18653	}
18654	// Do not include comment or processing instruction nodes
18655
18656	return ret;
18657};
18658
18659Expr = Sizzle.selectors = {
18660
18661	// Can be adjusted by the user
18662	cacheLength: 50,
18663
18664	createPseudo: markFunction,
18665
18666	match: matchExpr,
18667
18668	attrHandle: {},
18669
18670	find: {},
18671
18672	relative: {
18673		">": { dir: "parentNode", first: true },
18674		" ": { dir: "parentNode" },
18675		"+": { dir: "previousSibling", first: true },
18676		"~": { dir: "previousSibling" }
18677	},
18678
18679	preFilter: {
18680		"ATTR": function( match ) {
18681			match[1] = match[1].replace( runescape, funescape );
18682
18683			// Move the given value to match[3] whether quoted or unquoted
18684			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
18685
18686			if ( match[2] === "~=" ) {
18687				match[3] = " " + match[3] + " ";
18688			}
18689
18690			return match.slice( 0, 4 );
18691		},
18692
18693		"CHILD": function( match ) {
18694			/* matches from matchExpr["CHILD"]
18695				1 type (only|nth|...)
18696				2 what (child|of-type)
18697				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
18698				4 xn-component of xn+y argument ([+-]?\d*n|)
18699				5 sign of xn-component
18700				6 x of xn-component
18701				7 sign of y-component
18702				8 y of y-component
18703			*/
18704			match[1] = match[1].toLowerCase();
18705
18706			if ( match[1].slice( 0, 3 ) === "nth" ) {
18707				// nth-* requires argument
18708				if ( !match[3] ) {
18709					Sizzle.error( match[0] );
18710				}
18711
18712				// numeric x and y parameters for Expr.filter.CHILD
18713				// remember that false/true cast respectively to 0/1
18714				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
18715				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
18716
18717			// other types prohibit arguments
18718			} else if ( match[3] ) {
18719				Sizzle.error( match[0] );
18720			}
18721
18722			return match;
18723		},
18724
18725		"PSEUDO": function( match ) {
18726			var excess,
18727				unquoted = !match[6] && match[2];
18728
18729			if ( matchExpr["CHILD"].test( match[0] ) ) {
18730				return null;
18731			}
18732
18733			// Accept quoted arguments as-is
18734			if ( match[3] ) {
18735				match[2] = match[4] || match[5] || "";
18736
18737			// Strip excess characters from unquoted arguments
18738			} else if ( unquoted && rpseudo.test( unquoted ) &&
18739				// Get excess from tokenize (recursively)
18740				(excess = tokenize( unquoted, true )) &&
18741				// advance to the next closing parenthesis
18742				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
18743
18744				// excess is a negative index
18745				match[0] = match[0].slice( 0, excess );
18746				match[2] = unquoted.slice( 0, excess );
18747			}
18748
18749			// Return only captures needed by the pseudo filter method (type and argument)
18750			return match.slice( 0, 3 );
18751		}
18752	},
18753
18754	filter: {
18755
18756		"TAG": function( nodeNameSelector ) {
18757			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
18758			return nodeNameSelector === "*" ?
18759				function() { return true; } :
18760				function( elem ) {
18761					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
18762				};
18763		},
18764
18765		"CLASS": function( className ) {
18766			var pattern = classCache[ className + " " ];
18767
18768			return pattern ||
18769				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
18770				classCache( className, function( elem ) {
18771					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
18772				});
18773		},
18774
18775		"ATTR": function( name, operator, check ) {
18776			return function( elem ) {
18777				var result = Sizzle.attr( elem, name );
18778
18779				if ( result == null ) {
18780					return operator === "!=";
18781				}
18782				if ( !operator ) {
18783					return true;
18784				}
18785
18786				result += "";
18787
18788				return operator === "=" ? result === check :
18789					operator === "!=" ? result !== check :
18790					operator === "^=" ? check && result.indexOf( check ) === 0 :
18791					operator === "*=" ? check && result.indexOf( check ) > -1 :
18792					operator === "$=" ? check && result.slice( -check.length ) === check :
18793					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
18794					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
18795					false;
18796			};
18797		},
18798
18799		"CHILD": function( type, what, argument, first, last ) {
18800			var simple = type.slice( 0, 3 ) !== "nth",
18801				forward = type.slice( -4 ) !== "last",
18802				ofType = what === "of-type";
18803
18804			return first === 1 && last === 0 ?
18805
18806				// Shortcut for :nth-*(n)
18807				function( elem ) {
18808					return !!elem.parentNode;
18809				} :
18810
18811				function( elem, context, xml ) {
18812					var cache, uniqueCache, outerCache, node, nodeIndex, start,
18813						dir = simple !== forward ? "nextSibling" : "previousSibling",
18814						parent = elem.parentNode,
18815						name = ofType && elem.nodeName.toLowerCase(),
18816						useCache = !xml && !ofType,
18817						diff = false;
18818
18819					if ( parent ) {
18820
18821						// :(first|last|only)-(child|of-type)
18822						if ( simple ) {
18823							while ( dir ) {
18824								node = elem;
18825								while ( (node = node[ dir ]) ) {
18826									if ( ofType ?
18827										node.nodeName.toLowerCase() === name :
18828										node.nodeType === 1 ) {
18829
18830										return false;
18831									}
18832								}
18833								// Reverse direction for :only-* (if we haven't yet done so)
18834								start = dir = type === "only" && !start && "nextSibling";
18835							}
18836							return true;
18837						}
18838
18839						start = [ forward ? parent.firstChild : parent.lastChild ];
18840
18841						// non-xml :nth-child(...) stores cache data on `parent`
18842						if ( forward && useCache ) {
18843
18844							// Seek `elem` from a previously-cached index
18845
18846							// ...in a gzip-friendly way
18847							node = parent;
18848							outerCache = node[ expando ] || (node[ expando ] = {});
18849
18850							// Support: IE <9 only
18851							// Defend against cloned attroperties (jQuery gh-1709)
18852							uniqueCache = outerCache[ node.uniqueID ] ||
18853								(outerCache[ node.uniqueID ] = {});
18854
18855							cache = uniqueCache[ type ] || [];
18856							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
18857							diff = nodeIndex && cache[ 2 ];
18858							node = nodeIndex && parent.childNodes[ nodeIndex ];
18859
18860							while ( (node = ++nodeIndex && node && node[ dir ] ||
18861
18862								// Fallback to seeking `elem` from the start
18863								(diff = nodeIndex = 0) || start.pop()) ) {
18864
18865								// When found, cache indexes on `parent` and break
18866								if ( node.nodeType === 1 && ++diff && node === elem ) {
18867									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
18868									break;
18869								}
18870							}
18871
18872						} else {
18873							// Use previously-cached element index if available
18874							if ( useCache ) {
18875								// ...in a gzip-friendly way
18876								node = elem;
18877								outerCache = node[ expando ] || (node[ expando ] = {});
18878
18879								// Support: IE <9 only
18880								// Defend against cloned attroperties (jQuery gh-1709)
18881								uniqueCache = outerCache[ node.uniqueID ] ||
18882									(outerCache[ node.uniqueID ] = {});
18883
18884								cache = uniqueCache[ type ] || [];
18885								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
18886								diff = nodeIndex;
18887							}
18888
18889							// xml :nth-child(...)
18890							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
18891							if ( diff === false ) {
18892								// Use the same loop as above to seek `elem` from the start
18893								while ( (node = ++nodeIndex && node && node[ dir ] ||
18894									(diff = nodeIndex = 0) || start.pop()) ) {
18895
18896									if ( ( ofType ?
18897										node.nodeName.toLowerCase() === name :
18898										node.nodeType === 1 ) &&
18899										++diff ) {
18900
18901										// Cache the index of each encountered element
18902										if ( useCache ) {
18903											outerCache = node[ expando ] || (node[ expando ] = {});
18904
18905											// Support: IE <9 only
18906											// Defend against cloned attroperties (jQuery gh-1709)
18907											uniqueCache = outerCache[ node.uniqueID ] ||
18908												(outerCache[ node.uniqueID ] = {});
18909
18910											uniqueCache[ type ] = [ dirruns, diff ];
18911										}
18912
18913										if ( node === elem ) {
18914											break;
18915										}
18916									}
18917								}
18918							}
18919						}
18920
18921						// Incorporate the offset, then check against cycle size
18922						diff -= last;
18923						return diff === first || ( diff % first === 0 && diff / first >= 0 );
18924					}
18925				};
18926		},
18927
18928		"PSEUDO": function( pseudo, argument ) {
18929			// pseudo-class names are case-insensitive
18930			// http://www.w3.org/TR/selectors/#pseudo-classes
18931			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
18932			// Remember that setFilters inherits from pseudos
18933			var args,
18934				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
18935					Sizzle.error( "unsupported pseudo: " + pseudo );
18936
18937			// The user may use createPseudo to indicate that
18938			// arguments are needed to create the filter function
18939			// just as Sizzle does
18940			if ( fn[ expando ] ) {
18941				return fn( argument );
18942			}
18943
18944			// But maintain support for old signatures
18945			if ( fn.length > 1 ) {
18946				args = [ pseudo, pseudo, "", argument ];
18947				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
18948					markFunction(function( seed, matches ) {
18949						var idx,
18950							matched = fn( seed, argument ),
18951							i = matched.length;
18952						while ( i-- ) {
18953							idx = indexOf( seed, matched[i] );
18954							seed[ idx ] = !( matches[ idx ] = matched[i] );
18955						}
18956					}) :
18957					function( elem ) {
18958						return fn( elem, 0, args );
18959					};
18960			}
18961
18962			return fn;
18963		}
18964	},
18965
18966	pseudos: {
18967		// Potentially complex pseudos
18968		"not": markFunction(function( selector ) {
18969			// Trim the selector passed to compile
18970			// to avoid treating leading and trailing
18971			// spaces as combinators
18972			var input = [],
18973				results = [],
18974				matcher = compile( selector.replace( rtrim, "$1" ) );
18975
18976			return matcher[ expando ] ?
18977				markFunction(function( seed, matches, context, xml ) {
18978					var elem,
18979						unmatched = matcher( seed, null, xml, [] ),
18980						i = seed.length;
18981
18982					// Match elements unmatched by `matcher`
18983					while ( i-- ) {
18984						if ( (elem = unmatched[i]) ) {
18985							seed[i] = !(matches[i] = elem);
18986						}
18987					}
18988				}) :
18989				function( elem, context, xml ) {
18990					input[0] = elem;
18991					matcher( input, null, xml, results );
18992					// Don't keep the element (issue #299)
18993					input[0] = null;
18994					return !results.pop();
18995				};
18996		}),
18997
18998		"has": markFunction(function( selector ) {
18999			return function( elem ) {
19000				return Sizzle( selector, elem ).length > 0;
19001			};
19002		}),
19003
19004		"contains": markFunction(function( text ) {
19005			text = text.replace( runescape, funescape );
19006			return function( elem ) {
19007				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
19008			};
19009		}),
19010
19011		// "Whether an element is represented by a :lang() selector
19012		// is based solely on the element's language value
19013		// being equal to the identifier C,
19014		// or beginning with the identifier C immediately followed by "-".
19015		// The matching of C against the element's language value is performed case-insensitively.
19016		// The identifier C does not have to be a valid language name."
19017		// http://www.w3.org/TR/selectors/#lang-pseudo
19018		"lang": markFunction( function( lang ) {
19019			// lang value must be a valid identifier
19020			if ( !ridentifier.test(lang || "") ) {
19021				Sizzle.error( "unsupported lang: " + lang );
19022			}
19023			lang = lang.replace( runescape, funescape ).toLowerCase();
19024			return function( elem ) {
19025				var elemLang;
19026				do {
19027					if ( (elemLang = documentIsHTML ?
19028						elem.lang :
19029						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
19030
19031						elemLang = elemLang.toLowerCase();
19032						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
19033					}
19034				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
19035				return false;
19036			};
19037		}),
19038
19039		// Miscellaneous
19040		"target": function( elem ) {
19041			var hash = window.location && window.location.hash;
19042			return hash && hash.slice( 1 ) === elem.id;
19043		},
19044
19045		"root": function( elem ) {
19046			return elem === docElem;
19047		},
19048
19049		"focus": function( elem ) {
19050			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
19051		},
19052
19053		// Boolean properties
19054		"enabled": function( elem ) {
19055			return elem.disabled === false;
19056		},
19057
19058		"disabled": function( elem ) {
19059			return elem.disabled === true;
19060		},
19061
19062		"checked": function( elem ) {
19063			// In CSS3, :checked should return both checked and selected elements
19064			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
19065			var nodeName = elem.nodeName.toLowerCase();
19066			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
19067		},
19068
19069		"selected": function( elem ) {
19070			// Accessing this property makes selected-by-default
19071			// options in Safari work properly
19072			if ( elem.parentNode ) {
19073				elem.parentNode.selectedIndex;
19074			}
19075
19076			return elem.selected === true;
19077		},
19078
19079		// Contents
19080		"empty": function( elem ) {
19081			// http://www.w3.org/TR/selectors/#empty-pseudo
19082			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
19083			//   but not by others (comment: 8; processing instruction: 7; etc.)
19084			// nodeType < 6 works because attributes (2) do not appear as children
19085			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
19086				if ( elem.nodeType < 6 ) {
19087					return false;
19088				}
19089			}
19090			return true;
19091		},
19092
19093		"parent": function( elem ) {
19094			return !Expr.pseudos["empty"]( elem );
19095		},
19096
19097		// Element/input types
19098		"header": function( elem ) {
19099			return rheader.test( elem.nodeName );
19100		},
19101
19102		"input": function( elem ) {
19103			return rinputs.test( elem.nodeName );
19104		},
19105
19106		"button": function( elem ) {
19107			var name = elem.nodeName.toLowerCase();
19108			return name === "input" && elem.type === "button" || name === "button";
19109		},
19110
19111		"text": function( elem ) {
19112			var attr;
19113			return elem.nodeName.toLowerCase() === "input" &&
19114				elem.type === "text" &&
19115
19116				// Support: IE<8
19117				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
19118				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
19119		},
19120
19121		// Position-in-collection
19122		"first": createPositionalPseudo(function() {
19123			return [ 0 ];
19124		}),
19125
19126		"last": createPositionalPseudo(function( matchIndexes, length ) {
19127			return [ length - 1 ];
19128		}),
19129
19130		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
19131			return [ argument < 0 ? argument + length : argument ];
19132		}),
19133
19134		"even": createPositionalPseudo(function( matchIndexes, length ) {
19135			var i = 0;
19136			for ( ; i < length; i += 2 ) {
19137				matchIndexes.push( i );
19138			}
19139			return matchIndexes;
19140		}),
19141
19142		"odd": createPositionalPseudo(function( matchIndexes, length ) {
19143			var i = 1;
19144			for ( ; i < length; i += 2 ) {
19145				matchIndexes.push( i );
19146			}
19147			return matchIndexes;
19148		}),
19149
19150		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
19151			var i = argument < 0 ? argument + length : argument;
19152			for ( ; --i >= 0; ) {
19153				matchIndexes.push( i );
19154			}
19155			return matchIndexes;
19156		}),
19157
19158		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
19159			var i = argument < 0 ? argument + length : argument;
19160			for ( ; ++i < length; ) {
19161				matchIndexes.push( i );
19162			}
19163			return matchIndexes;
19164		})
19165	}
19166};
19167
19168Expr.pseudos["nth"] = Expr.pseudos["eq"];
19169
19170// Add button/input type pseudos
19171for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
19172	Expr.pseudos[ i ] = createInputPseudo( i );
19173}
19174for ( i in { submit: true, reset: true } ) {
19175	Expr.pseudos[ i ] = createButtonPseudo( i );
19176}
19177
19178// Easy API for creating new setFilters
19179function setFilters() {}
19180setFilters.prototype = Expr.filters = Expr.pseudos;
19181Expr.setFilters = new setFilters();
19182
19183tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
19184	var matched, match, tokens, type,
19185		soFar, groups, preFilters,
19186		cached = tokenCache[ selector + " " ];
19187
19188	if ( cached ) {
19189		return parseOnly ? 0 : cached.slice( 0 );
19190	}
19191
19192	soFar = selector;
19193	groups = [];
19194	preFilters = Expr.preFilter;
19195
19196	while ( soFar ) {
19197
19198		// Comma and first run
19199		if ( !matched || (match = rcomma.exec( soFar )) ) {
19200			if ( match ) {
19201				// Don't consume trailing commas as valid
19202				soFar = soFar.slice( match[0].length ) || soFar;
19203			}
19204			groups.push( (tokens = []) );
19205		}
19206
19207		matched = false;
19208
19209		// Combinators
19210		if ( (match = rcombinators.exec( soFar )) ) {
19211			matched = match.shift();
19212			tokens.push({
19213				value: matched,
19214				// Cast descendant combinators to space
19215				type: match[0].replace( rtrim, " " )
19216			});
19217			soFar = soFar.slice( matched.length );
19218		}
19219
19220		// Filters
19221		for ( type in Expr.filter ) {
19222			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
19223				(match = preFilters[ type ]( match ))) ) {
19224				matched = match.shift();
19225				tokens.push({
19226					value: matched,
19227					type: type,
19228					matches: match
19229				});
19230				soFar = soFar.slice( matched.length );
19231			}
19232		}
19233
19234		if ( !matched ) {
19235			break;
19236		}
19237	}
19238
19239	// Return the length of the invalid excess
19240	// if we're just parsing
19241	// Otherwise, throw an error or return tokens
19242	return parseOnly ?
19243		soFar.length :
19244		soFar ?
19245			Sizzle.error( selector ) :
19246			// Cache the tokens
19247			tokenCache( selector, groups ).slice( 0 );
19248};
19249
19250function toSelector( tokens ) {
19251	var i = 0,
19252		len = tokens.length,
19253		selector = "";
19254	for ( ; i < len; i++ ) {
19255		selector += tokens[i].value;
19256	}
19257	return selector;
19258}
19259
19260function addCombinator( matcher, combinator, base ) {
19261	var dir = combinator.dir,
19262		checkNonElements = base && dir === "parentNode",
19263		doneName = done++;
19264
19265	return combinator.first ?
19266		// Check against closest ancestor/preceding element
19267		function( elem, context, xml ) {
19268			while ( (elem = elem[ dir ]) ) {
19269				if ( elem.nodeType === 1 || checkNonElements ) {
19270					return matcher( elem, context, xml );
19271				}
19272			}
19273		} :
19274
19275		// Check against all ancestor/preceding elements
19276		function( elem, context, xml ) {
19277			var oldCache, uniqueCache, outerCache,
19278				newCache = [ dirruns, doneName ];
19279
19280			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
19281			if ( xml ) {
19282				while ( (elem = elem[ dir ]) ) {
19283					if ( elem.nodeType === 1 || checkNonElements ) {
19284						if ( matcher( elem, context, xml ) ) {
19285							return true;
19286						}
19287					}
19288				}
19289			} else {
19290				while ( (elem = elem[ dir ]) ) {
19291					if ( elem.nodeType === 1 || checkNonElements ) {
19292						outerCache = elem[ expando ] || (elem[ expando ] = {});
19293
19294						// Support: IE <9 only
19295						// Defend against cloned attroperties (jQuery gh-1709)
19296						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
19297
19298						if ( (oldCache = uniqueCache[ dir ]) &&
19299							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
19300
19301							// Assign to newCache so results back-propagate to previous elements
19302							return (newCache[ 2 ] = oldCache[ 2 ]);
19303						} else {
19304							// Reuse newcache so results back-propagate to previous elements
19305							uniqueCache[ dir ] = newCache;
19306
19307							// A match means we're done; a fail means we have to keep checking
19308							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
19309								return true;
19310							}
19311						}
19312					}
19313				}
19314			}
19315		};
19316}
19317
19318function elementMatcher( matchers ) {
19319	return matchers.length > 1 ?
19320		function( elem, context, xml ) {
19321			var i = matchers.length;
19322			while ( i-- ) {
19323				if ( !matchers[i]( elem, context, xml ) ) {
19324					return false;
19325				}
19326			}
19327			return true;
19328		} :
19329		matchers[0];
19330}
19331
19332function multipleContexts( selector, contexts, results ) {
19333	var i = 0,
19334		len = contexts.length;
19335	for ( ; i < len; i++ ) {
19336		Sizzle( selector, contexts[i], results );
19337	}
19338	return results;
19339}
19340
19341function condense( unmatched, map, filter, context, xml ) {
19342	var elem,
19343		newUnmatched = [],
19344		i = 0,
19345		len = unmatched.length,
19346		mapped = map != null;
19347
19348	for ( ; i < len; i++ ) {
19349		if ( (elem = unmatched[i]) ) {
19350			if ( !filter || filter( elem, context, xml ) ) {
19351				newUnmatched.push( elem );
19352				if ( mapped ) {
19353					map.push( i );
19354				}
19355			}
19356		}
19357	}
19358
19359	return newUnmatched;
19360}
19361
19362function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
19363	if ( postFilter && !postFilter[ expando ] ) {
19364		postFilter = setMatcher( postFilter );
19365	}
19366	if ( postFinder && !postFinder[ expando ] ) {
19367		postFinder = setMatcher( postFinder, postSelector );
19368	}
19369	return markFunction(function( seed, results, context, xml ) {
19370		var temp, i, elem,
19371			preMap = [],
19372			postMap = [],
19373			preexisting = results.length,
19374
19375			// Get initial elements from seed or context
19376			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
19377
19378			// Prefilter to get matcher input, preserving a map for seed-results synchronization
19379			matcherIn = preFilter && ( seed || !selector ) ?
19380				condense( elems, preMap, preFilter, context, xml ) :
19381				elems,
19382
19383			matcherOut = matcher ?
19384				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
19385				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
19386
19387					// ...intermediate processing is necessary
19388					[] :
19389
19390					// ...otherwise use results directly
19391					results :
19392				matcherIn;
19393
19394		// Find primary matches
19395		if ( matcher ) {
19396			matcher( matcherIn, matcherOut, context, xml );
19397		}
19398
19399		// Apply postFilter
19400		if ( postFilter ) {
19401			temp = condense( matcherOut, postMap );
19402			postFilter( temp, [], context, xml );
19403
19404			// Un-match failing elements by moving them back to matcherIn
19405			i = temp.length;
19406			while ( i-- ) {
19407				if ( (elem = temp[i]) ) {
19408					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
19409				}
19410			}
19411		}
19412
19413		if ( seed ) {
19414			if ( postFinder || preFilter ) {
19415				if ( postFinder ) {
19416					// Get the final matcherOut by condensing this intermediate into postFinder contexts
19417					temp = [];
19418					i = matcherOut.length;
19419					while ( i-- ) {
19420						if ( (elem = matcherOut[i]) ) {
19421							// Restore matcherIn since elem is not yet a final match
19422							temp.push( (matcherIn[i] = elem) );
19423						}
19424					}
19425					postFinder( null, (matcherOut = []), temp, xml );
19426				}
19427
19428				// Move matched elements from seed to results to keep them synchronized
19429				i = matcherOut.length;
19430				while ( i-- ) {
19431					if ( (elem = matcherOut[i]) &&
19432						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
19433
19434						seed[temp] = !(results[temp] = elem);
19435					}
19436				}
19437			}
19438
19439		// Add elements to results, through postFinder if defined
19440		} else {
19441			matcherOut = condense(
19442				matcherOut === results ?
19443					matcherOut.splice( preexisting, matcherOut.length ) :
19444					matcherOut
19445			);
19446			if ( postFinder ) {
19447				postFinder( null, results, matcherOut, xml );
19448			} else {
19449				push.apply( results, matcherOut );
19450			}
19451		}
19452	});
19453}
19454
19455function matcherFromTokens( tokens ) {
19456	var checkContext, matcher, j,
19457		len = tokens.length,
19458		leadingRelative = Expr.relative[ tokens[0].type ],
19459		implicitRelative = leadingRelative || Expr.relative[" "],
19460		i = leadingRelative ? 1 : 0,
19461
19462		// The foundational matcher ensures that elements are reachable from top-level context(s)
19463		matchContext = addCombinator( function( elem ) {
19464			return elem === checkContext;
19465		}, implicitRelative, true ),
19466		matchAnyContext = addCombinator( function( elem ) {
19467			return indexOf( checkContext, elem ) > -1;
19468		}, implicitRelative, true ),
19469		matchers = [ function( elem, context, xml ) {
19470			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
19471				(checkContext = context).nodeType ?
19472					matchContext( elem, context, xml ) :
19473					matchAnyContext( elem, context, xml ) );
19474			// Avoid hanging onto element (issue #299)
19475			checkContext = null;
19476			return ret;
19477		} ];
19478
19479	for ( ; i < len; i++ ) {
19480		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
19481			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
19482		} else {
19483			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
19484
19485			// Return special upon seeing a positional matcher
19486			if ( matcher[ expando ] ) {
19487				// Find the next relative operator (if any) for proper handling
19488				j = ++i;
19489				for ( ; j < len; j++ ) {
19490					if ( Expr.relative[ tokens[j].type ] ) {
19491						break;
19492					}
19493				}
19494				return setMatcher(
19495					i > 1 && elementMatcher( matchers ),
19496					i > 1 && toSelector(
19497						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
19498						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
19499					).replace( rtrim, "$1" ),
19500					matcher,
19501					i < j && matcherFromTokens( tokens.slice( i, j ) ),
19502					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
19503					j < len && toSelector( tokens )
19504				);
19505			}
19506			matchers.push( matcher );
19507		}
19508	}
19509
19510	return elementMatcher( matchers );
19511}
19512
19513function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
19514	var bySet = setMatchers.length > 0,
19515		byElement = elementMatchers.length > 0,
19516		superMatcher = function( seed, context, xml, results, outermost ) {
19517			var elem, j, matcher,
19518				matchedCount = 0,
19519				i = "0",
19520				unmatched = seed && [],
19521				setMatched = [],
19522				contextBackup = outermostContext,
19523				// We must always have either seed elements or outermost context
19524				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
19525				// Use integer dirruns iff this is the outermost matcher
19526				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
19527				len = elems.length;
19528
19529			if ( outermost ) {
19530				outermostContext = context === document || context || outermost;
19531			}
19532
19533			// Add elements passing elementMatchers directly to results
19534			// Support: IE<9, Safari
19535			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
19536			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
19537				if ( byElement && elem ) {
19538					j = 0;
19539					if ( !context && elem.ownerDocument !== document ) {
19540						setDocument( elem );
19541						xml = !documentIsHTML;
19542					}
19543					while ( (matcher = elementMatchers[j++]) ) {
19544						if ( matcher( elem, context || document, xml) ) {
19545							results.push( elem );
19546							break;
19547						}
19548					}
19549					if ( outermost ) {
19550						dirruns = dirrunsUnique;
19551					}
19552				}
19553
19554				// Track unmatched elements for set filters
19555				if ( bySet ) {
19556					// They will have gone through all possible matchers
19557					if ( (elem = !matcher && elem) ) {
19558						matchedCount--;
19559					}
19560
19561					// Lengthen the array for every element, matched or not
19562					if ( seed ) {
19563						unmatched.push( elem );
19564					}
19565				}
19566			}
19567
19568			// `i` is now the count of elements visited above, and adding it to `matchedCount`
19569			// makes the latter nonnegative.
19570			matchedCount += i;
19571
19572			// Apply set filters to unmatched elements
19573			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
19574			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
19575			// no element matchers and no seed.
19576			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
19577			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
19578			// numerically zero.
19579			if ( bySet && i !== matchedCount ) {
19580				j = 0;
19581				while ( (matcher = setMatchers[j++]) ) {
19582					matcher( unmatched, setMatched, context, xml );
19583				}
19584
19585				if ( seed ) {
19586					// Reintegrate element matches to eliminate the need for sorting
19587					if ( matchedCount > 0 ) {
19588						while ( i-- ) {
19589							if ( !(unmatched[i] || setMatched[i]) ) {
19590								setMatched[i] = pop.call( results );
19591							}
19592						}
19593					}
19594
19595					// Discard index placeholder values to get only actual matches
19596					setMatched = condense( setMatched );
19597				}
19598
19599				// Add matches to results
19600				push.apply( results, setMatched );
19601
19602				// Seedless set matches succeeding multiple successful matchers stipulate sorting
19603				if ( outermost && !seed && setMatched.length > 0 &&
19604					( matchedCount + setMatchers.length ) > 1 ) {
19605
19606					Sizzle.uniqueSort( results );
19607				}
19608			}
19609
19610			// Override manipulation of globals by nested matchers
19611			if ( outermost ) {
19612				dirruns = dirrunsUnique;
19613				outermostContext = contextBackup;
19614			}
19615
19616			return unmatched;
19617		};
19618
19619	return bySet ?
19620		markFunction( superMatcher ) :
19621		superMatcher;
19622}
19623
19624compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
19625	var i,
19626		setMatchers = [],
19627		elementMatchers = [],
19628		cached = compilerCache[ selector + " " ];
19629
19630	if ( !cached ) {
19631		// Generate a function of recursive functions that can be used to check each element
19632		if ( !match ) {
19633			match = tokenize( selector );
19634		}
19635		i = match.length;
19636		while ( i-- ) {
19637			cached = matcherFromTokens( match[i] );
19638			if ( cached[ expando ] ) {
19639				setMatchers.push( cached );
19640			} else {
19641				elementMatchers.push( cached );
19642			}
19643		}
19644
19645		// Cache the compiled function
19646		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
19647
19648		// Save selector and tokenization
19649		cached.selector = selector;
19650	}
19651	return cached;
19652};
19653
19654/**
19655 * A low-level selection function that works with Sizzle's compiled
19656 *  selector functions
19657 * @param {String|Function} selector A selector or a pre-compiled
19658 *  selector function built with Sizzle.compile
19659 * @param {Element} context
19660 * @param {Array} [results]
19661 * @param {Array} [seed] A set of elements to match against
19662 */
19663select = Sizzle.select = function( selector, context, results, seed ) {
19664	var i, tokens, token, type, find,
19665		compiled = typeof selector === "function" && selector,
19666		match = !seed && tokenize( (selector = compiled.selector || selector) );
19667
19668	results = results || [];
19669
19670	// Try to minimize operations if there is only one selector in the list and no seed
19671	// (the latter of which guarantees us context)
19672	if ( match.length === 1 ) {
19673
19674		// Reduce context if the leading compound selector is an ID
19675		tokens = match[0] = match[0].slice( 0 );
19676		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
19677				support.getById && context.nodeType === 9 && documentIsHTML &&
19678				Expr.relative[ tokens[1].type ] ) {
19679
19680			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
19681			if ( !context ) {
19682				return results;
19683
19684			// Precompiled matchers will still verify ancestry, so step up a level
19685			} else if ( compiled ) {
19686				context = context.parentNode;
19687			}
19688
19689			selector = selector.slice( tokens.shift().value.length );
19690		}
19691
19692		// Fetch a seed set for right-to-left matching
19693		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
19694		while ( i-- ) {
19695			token = tokens[i];
19696
19697			// Abort if we hit a combinator
19698			if ( Expr.relative[ (type = token.type) ] ) {
19699				break;
19700			}
19701			if ( (find = Expr.find[ type ]) ) {
19702				// Search, expanding context for leading sibling combinators
19703				if ( (seed = find(
19704					token.matches[0].replace( runescape, funescape ),
19705					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
19706				)) ) {
19707
19708					// If seed is empty or no tokens remain, we can return early
19709					tokens.splice( i, 1 );
19710					selector = seed.length && toSelector( tokens );
19711					if ( !selector ) {
19712						push.apply( results, seed );
19713						return results;
19714					}
19715
19716					break;
19717				}
19718			}
19719		}
19720	}
19721
19722	// Compile and execute a filtering function if one is not provided
19723	// Provide `match` to avoid retokenization if we modified the selector above
19724	( compiled || compile( selector, match ) )(
19725		seed,
19726		context,
19727		!documentIsHTML,
19728		results,
19729		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
19730	);
19731	return results;
19732};
19733
19734// One-time assignments
19735
19736// Sort stability
19737support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
19738
19739// Support: Chrome 14-35+
19740// Always assume duplicates if they aren't passed to the comparison function
19741support.detectDuplicates = !!hasDuplicate;
19742
19743// Initialize against the default document
19744setDocument();
19745
19746// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
19747// Detached nodes confoundingly follow *each other*
19748support.sortDetached = assert(function( div1 ) {
19749	// Should return 1, but returns 4 (following)
19750	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
19751});
19752
19753// Support: IE<8
19754// Prevent attribute/property "interpolation"
19755// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
19756if ( !assert(function( div ) {
19757	div.innerHTML = "<a href='#'></a>";
19758	return div.firstChild.getAttribute("href") === "#" ;
19759}) ) {
19760	addHandle( "type|href|height|width", function( elem, name, isXML ) {
19761		if ( !isXML ) {
19762			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
19763		}
19764	});
19765}
19766
19767// Support: IE<9
19768// Use defaultValue in place of getAttribute("value")
19769if ( !support.attributes || !assert(function( div ) {
19770	div.innerHTML = "<input/>";
19771	div.firstChild.setAttribute( "value", "" );
19772	return div.firstChild.getAttribute( "value" ) === "";
19773}) ) {
19774	addHandle( "value", function( elem, name, isXML ) {
19775		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
19776			return elem.defaultValue;
19777		}
19778	});
19779}
19780
19781// Support: IE<9
19782// Use getAttributeNode to fetch booleans when getAttribute lies
19783if ( !assert(function( div ) {
19784	return div.getAttribute("disabled") == null;
19785}) ) {
19786	addHandle( booleans, function( elem, name, isXML ) {
19787		var val;
19788		if ( !isXML ) {
19789			return elem[ name ] === true ? name.toLowerCase() :
19790					(val = elem.getAttributeNode( name )) && val.specified ?
19791					val.value :
19792				null;
19793		}
19794	});
19795}
19796
19797return Sizzle;
19798
19799})( window );
19800
19801
19802
19803jQuery.find = Sizzle;
19804jQuery.expr = Sizzle.selectors;
19805jQuery.expr[ ":" ] = jQuery.expr.pseudos;
19806jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
19807jQuery.text = Sizzle.getText;
19808jQuery.isXMLDoc = Sizzle.isXML;
19809jQuery.contains = Sizzle.contains;
19810
19811
19812
19813var dir = function( elem, dir, until ) {
19814	var matched = [],
19815		truncate = until !== undefined;
19816
19817	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
19818		if ( elem.nodeType === 1 ) {
19819			if ( truncate && jQuery( elem ).is( until ) ) {
19820				break;
19821			}
19822			matched.push( elem );
19823		}
19824	}
19825	return matched;
19826};
19827
19828
19829var siblings = function( n, elem ) {
19830	var matched = [];
19831
19832	for ( ; n; n = n.nextSibling ) {
19833		if ( n.nodeType === 1 && n !== elem ) {
19834			matched.push( n );
19835		}
19836	}
19837
19838	return matched;
19839};
19840
19841
19842var rneedsContext = jQuery.expr.match.needsContext;
19843
19844var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
19845
19846
19847
19848var risSimple = /^.[^:#\[\.,]*$/;
19849
19850// Implement the identical functionality for filter and not
19851function winnow( elements, qualifier, not ) {
19852	if ( jQuery.isFunction( qualifier ) ) {
19853		return jQuery.grep( elements, function( elem, i ) {
19854			/* jshint -W018 */
19855			return !!qualifier.call( elem, i, elem ) !== not;
19856		} );
19857
19858	}
19859
19860	if ( qualifier.nodeType ) {
19861		return jQuery.grep( elements, function( elem ) {
19862			return ( elem === qualifier ) !== not;
19863		} );
19864
19865	}
19866
19867	if ( typeof qualifier === "string" ) {
19868		if ( risSimple.test( qualifier ) ) {
19869			return jQuery.filter( qualifier, elements, not );
19870		}
19871
19872		qualifier = jQuery.filter( qualifier, elements );
19873	}
19874
19875	return jQuery.grep( elements, function( elem ) {
19876		return ( 
19876jQuery.inArray( elem, qualifier ) > -1 ) !== not;
19877	} );
19878}
19879
19880jQuery.filter = function( expr, elems, not ) {
19881	var elem = elems[ 0 ];
19882
19883	if ( not ) {
19884		expr = ":not(" + expr + ")";
19885	}
19886
19887	return elems.length === 1 && elem.nodeType === 1 ?
19888		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
19889		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
19890			return elem.nodeType === 1;
19891		} ) );
19892};
19893
19894jQuery.fn.extend( {
19895	find: function( selector ) {
19896		var i,
19897			ret = [],
19898			self = this,
19899			len = self.length;
19900
19901		if ( typeof selector !== "string" ) {
vendor: 5,394 bytes, lines 19902-20104
19902			return this.pushStack( jQuery( selector ).filter( function() {
19903				for ( i = 0; i < len; i++ ) {
19904					if ( jQuery.contains( self[ i ], this ) ) {
19905						return true;
19906					}
19907				}
19908			} ) );
19909		}
19910
19911		for ( i = 0; i < len; i++ ) {
19912			jQuery.find( selector, self[ i ], ret );
19913		}
19914
19915		// Needed because $( selector, context ) becomes $( context ).find( selector )
19916		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
19917		ret.selector = this.selector ? this.selector + " " + selector : selector;
19918		return ret;
19919	},
19920	filter: function( selector ) {
19921		return this.pushStack( winnow( this, selector || [], false ) );
19922	},
19923	not: function( selector ) {
19924		return this.pushStack( winnow( this, selector || [], true ) );
19925	},
19926	is: function( selector ) {
19927		return !!winnow(
19928			this,
19929
19930			// If this is a positional/relative selector, check membership in the returned set
19931			// so $("p:first").is("p:last") won't return true for a doc with two "p".
19932			typeof selector === "string" && rneedsContext.test( selector ) ?
19933				jQuery( selector ) :
19934				selector || [],
19935			false
19936		).length;
19937	}
19938} );
19939
19940
19941// Initialize a jQuery object
19942
19943
19944// A central reference to the root jQuery(document)
19945var rootjQuery,
19946
19947	// A simple way to check for HTML strings
19948	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
19949	// Strict HTML recognition (#11290: must start with <)
19950	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
19951
19952	init = jQuery.fn.init = function( selector, context, root ) {
19953		var match, elem;
19954
19955		// HANDLE: $(""), $(null), $(undefined), $(false)
19956		if ( !selector ) {
19957			return this;
19958		}
19959
19960		// init accepts an alternate rootjQuery
19961		// so migrate can support jQuery.sub (gh-2101)
19962		root = root || rootjQuery;
19963
19964		// Handle HTML strings
19965		if ( typeof selector === "string" ) {
19966			if ( selector.charAt( 0 ) === "<" &&
19967				selector.charAt( selector.length - 1 ) === ">" &&
19968				selector.length >= 3 ) {
19969
19970				// Assume that strings that start and end with <> are HTML and skip the regex check
19971				match = [ null, selector, null ];
19972
19973			} else {
19974				match = rquickExpr.exec( selector );
19975			}
19976
19977			// Match html or make sure no context is specified for #id
19978			if ( match && ( match[ 1 ] || !context ) ) {
19979
19980				// HANDLE: $(html) -> $(array)
19981				if ( match[ 1 ] ) {
19982					context = context instanceof jQuery ? context[ 0 ] : context;
19983
19984					// scripts is true for back-compat
19985					// Intentionally let the error be thrown if parseHTML is not present
19986					jQuery.merge( this, jQuery.parseHTML(
19987						match[ 1 ],
19988						context && context.nodeType ? context.ownerDocument || context : document,
19989						true
19990					) );
19991
19992					// HANDLE: $(html, props)
19993					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
19994						for ( match in context ) {
19995
19996							// Properties of context are called as methods if possible
19997							if ( jQuery.isFunction( this[ match ] ) ) {
19998								this[ match ]( context[ match ] );
19999
20000							// ...and otherwise set as attributes
20001							} else {
20002								this.attr( match, context[ match ] );
20003							}
20004						}
20005					}
20006
20007					return this;
20008
20009				// HANDLE: $(#id)
20010				} else {
20011					elem = document.getElementById( match[ 2 ] );
20012
20013					// Check parentNode to catch when Blackberry 4.6 returns
20014					// nodes that are no longer in the document #6963
20015					if ( elem && elem.parentNode ) {
20016
20017						// Handle the case where IE and Opera return items
20018						// by name instead of ID
20019						if ( elem.id !== match[ 2 ] ) {
20020							return rootjQuery.find( selector );
20021						}
20022
20023						// Otherwise, we inject the element directly into the jQuery object
20024						this.length = 1;
20025						this[ 0 ] = elem;
20026					}
20027
20028					this.context = document;
20029					this.selector = selector;
20030					return this;
20031				}
20032
20033			// HANDLE: $(expr, $(...))
20034			} else if ( !context || context.jquery ) {
20035				return ( context || root ).find( selector );
20036
20037			// HANDLE: $(expr, context)
20038			// (which is just equivalent to: $(context).find(expr)
20039			} else {
20040				return this.constructor( context ).find( selector );
20041			}
20042
20043		// HANDLE: $(DOMElement)
20044		} else if ( selector.nodeType ) {
20045			this.context = this[ 0 ] = selector;
20046			this.length = 1;
20047			return this;
20048
20049		// HANDLE: $(function)
20050		// Shortcut for document ready
20051		} else if ( jQuery.isFunction( selector ) ) {
20052			return typeof root.ready !== "undefined" ?
20053				root.ready( selector ) :
20054
20055				// Execute immediately if ready is not present
20056				selector( jQuery );
20057		}
20058
20059		if ( selector.selector !== undefined ) {
20060			this.selector = selector.selector;
20061			this.context = selector.context;
20062		}
20063
20064		return jQuery.makeArray( selector, this );
20065	};
20066
20067// Give the init function the jQuery prototype for later instantiation
20068init.prototype = jQuery.fn;
20069
20070// Initialize central reference
20071rootjQuery = jQuery( document );
20072
20073
20074var rparentsprev = /^(?:parents|prev(?:Until|All))/,
20075
20076	// methods guaranteed to produce a unique set when starting from a unique set
20077	guaranteedUnique = {
20078		children: true,
20079		contents: true,
20080		next: true,
20081		prev: true
20082	};
20083
20084jQuery.fn.extend( {
20085	has: function( target ) {
20086		var i,
20087			targets = jQuery( target, this ),
20088			len = targets.length;
20089
20090		return this.filter( function() {
20091			for ( i = 0; i < len; i++ ) {
20092				if ( jQuery.contains( this, targets[ i ] ) ) {
20093					return true;
20094				}
20095			}
20096		} );
20097	},
20098
20099	closest: function( selectors, context ) {
20100		var cur,
20101			i = 0,
20102			l = this.length,
20103			matched = [],
20104			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
vendor: 12,881 bytes, lines 20105-20613
20105				jQuery( selectors, context || this.context ) :
20106				0;
20107
20108		for ( ; i < l; i++ ) {
20109			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
20110
20111				// Always skip document fragments
20112				if ( cur.nodeType < 11 && ( pos ?
20113					pos.index( cur ) > -1 :
20114
20115					// Don't pass non-elements to Sizzle
20116					cur.nodeType === 1 &&
20117						jQuery.find.matchesSelector( cur, selectors ) ) ) {
20118
20119					matched.push( cur );
20120					break;
20121				}
20122			}
20123		}
20124
20125		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
20126	},
20127
20128	// Determine the position of an element within
20129	// the matched set of elements
20130	index: function( elem ) {
20131
20132		// No argument, return index in parent
20133		if ( !elem ) {
20134			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
20135		}
20136
20137		// index in selector
20138		if ( typeof elem === "string" ) {
20139			return jQuery.inArray( this[ 0 ], jQuery( elem ) );
20140		}
20141
20142		// Locate the position of the desired element
20143		return jQuery.inArray(
20144
20145			// If it receives a jQuery object, the first element is used
20146			elem.jquery ? elem[ 0 ] : elem, this );
20147	},
20148
20149	add: function( selector, context ) {
20150		return this.pushStack(
20151			jQuery.uniqueSort(
20152				jQuery.merge( this.get(), jQuery( selector, context ) )
20153			)
20154		);
20155	},
20156
20157	addBack: function( selector ) {
20158		return this.add( selector == null ?
20159			this.prevObject : this.prevObject.filter( selector )
20160		);
20161	}
20162} );
20163
20164function sibling( cur, dir ) {
20165	do {
20166		cur = cur[ dir ];
20167	} while ( cur && cur.nodeType !== 1 );
20168
20169	return cur;
20170}
20171
20172jQuery.each( {
20173	parent: function( elem ) {
20174		var parent = elem.parentNode;
20175		return parent && parent.nodeType !== 11 ? parent : null;
20176	},
20177	parents: function( elem ) {
20178		return dir( elem, "parentNode" );
20179	},
20180	parentsUntil: function( elem, i, until ) {
20181		return dir( elem, "parentNode", until );
20182	},
20183	next: function( elem ) {
20184		return sibling( elem, "nextSibling" );
20185	},
20186	prev: function( elem ) {
20187		return sibling( elem, "previousSibling" );
20188	},
20189	nextAll: function( elem ) {
20190		return dir( elem, "nextSibling" );
20191	},
20192	prevAll: function( elem ) {
20193		return dir( elem, "previousSibling" );
20194	},
20195	nextUntil: function( elem, i, until ) {
20196		return dir( elem, "nextSibling", until );
20197	},
20198	prevUntil: function( elem, i, until ) {
20199		return dir( elem, "previousSibling", until );
20200	},
20201	siblings: function( elem ) {
20202		return siblings( ( elem.parentNode || {} ).firstChild, elem );
20203	},
20204	children: function( elem ) {
20205		return siblings( elem.firstChild );
20206	},
20207	contents: function( elem ) {
20208		return jQuery.nodeName( elem, "iframe" ) ?
20209			elem.contentDocument || elem.contentWindow.document :
20210			jQuery.merge( [], elem.childNodes );
20211	}
20212}, function( name, fn ) {
20213	jQuery.fn[ name ] = function( until, selector ) {
20214		var ret = jQuery.map( this, fn, until );
20215
20216		if ( name.slice( -5 ) !== "Until" ) {
20217			selector = until;
20218		}
20219
20220		if ( selector && typeof selector === "string" ) {
20221			ret = jQuery.filter( selector, ret );
20222		}
20223
20224		if ( this.length > 1 ) {
20225
20226			// Remove duplicates
20227			if ( !guaranteedUnique[ name ] ) {
20228				ret = jQuery.uniqueSort( ret );
20229			}
20230
20231			// Reverse order for parents* and prev-derivatives
20232			if ( rparentsprev.test( name ) ) {
20233				ret = ret.reverse();
20234			}
20235		}
20236
20237		return this.pushStack( ret );
20238	};
20239} );
20240var rnotwhite = ( /\S+/g );
20241
20242
20243
20244// Convert String-formatted options into Object-formatted ones
20245function createOptions( options ) {
20246	var object = {};
20247	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
20248		object[ flag ] = true;
20249	} );
20250	return object;
20251}
20252
20253/*
20254 * Create a callback list using the following parameters:
20255 *
20256 *	options: an optional list of space-separated options that will change how
20257 *			the callback list behaves or a more traditional option object
20258 *
20259 * By default a callback list will act like an event callback list and can be
20260 * "fired" multiple times.
20261 *
20262 * Possible options:
20263 *
20264 *	once:			will ensure the callback list can only be fired once (like a Deferred)
20265 *
20266 *	memory:			will keep track of previous values and will call any callback added
20267 *					after the list has been fired right away with the latest "memorized"
20268 *					values (like a Deferred)
20269 *
20270 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
20271 *
20272 *	stopOnFalse:	interrupt callings when a callback returns false
20273 *
20274 */
20275jQuery.Callbacks = function( options ) {
20276
20277	// Convert options from String-formatted to Object-formatted if needed
20278	// (we check in cache first)
20279	options = typeof options === "string" ?
20280		createOptions( options ) :
20281		jQuery.extend( {}, options );
20282
20283	var // Flag to know if list is currently firing
20284		firing,
20285
20286		// Last fire value for non-forgettable lists
20287		memory,
20288
20289		// Flag to know if list was already fired
20290		fired,
20291
20292		// Flag to prevent firing
20293		locked,
20294
20295		// Actual callback list
20296		list = [],
20297
20298		// Queue of execution data for repeatable lists
20299		queue = [],
20300
20301		// Index of currently firing callback (modified by add/remove as needed)
20302		firingIndex = -1,
20303
20304		// Fire callbacks
20305		fire = function() {
20306
20307			// Enforce single-firing
20308			locked = options.once;
20309
20310			// Execute callbacks for all pending executions,
20311			// respecting firingIndex overrides and runtime changes
20312			fired = firing = true;
20313			for ( ; queue.length; firingIndex = -1 ) {
20314				memory = queue.shift();
20315				while ( ++firingIndex < list.length ) {
20316
20317					// Run callback and check for early termination
20318					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
20319						options.stopOnFalse ) {
20320
20321						// Jump to end and forget the data so .add doesn't re-fire
20322						firingIndex = list.length;
20323						memory = false;
20324					}
20325				}
20326			}
20327
20328			// Forget the data if we're done with it
20329			if ( !options.memory ) {
20330				memory = false;
20331			}
20332
20333			firing = false;
20334
20335			// Clean up if we're done firing for good
20336			if ( locked ) {
20337
20338				// Keep an empty list if we have data for future add calls
20339				if ( memory ) {
20340					list = [];
20341
20342				// Otherwise, this object is spent
20343				} else {
20344					list = "";
20345				}
20346			}
20347		},
20348
20349		// Actual Callbacks object
20350		self = {
20351
20352			// Add a callback or a collection of callbacks to the list
20353			add: function() {
20354				if ( list ) {
20355
20356					// If we have memory from a past run, we should fire after adding
20357					if ( memory && !firing ) {
20358						firingIndex = list.length - 1;
20359						queue.push( memory );
20360					}
20361
20362					( function add( args ) {
20363						jQuery.each( args, function( _, arg ) {
20364							if ( jQuery.isFunction( arg ) ) {
20365								if ( !options.unique || !self.has( arg ) ) {
20366									list.push( arg );
20367								}
20368							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
20369
20370								// Inspect recursively
20371								add( arg );
20372							}
20373						} );
20374					} )( arguments );
20375
20376					if ( memory && !firing ) {
20377						fire();
20378					}
20379				}
20380				return this;
20381			},
20382
20383			// Remove a callback from the list
20384			remove: function() {
20385				jQuery.each( arguments, function( _, arg ) {
20386					var index;
20387					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
20388						list.splice( index, 1 );
20389
20390						// Handle firing indexes
20391						if ( index <= firingIndex ) {
20392							firingIndex--;
20393						}
20394					}
20395				} );
20396				return this;
20397			},
20398
20399			// Check if a given callback is in the list.
20400			// If no argument is given, return whether or not list has callbacks attached.
20401			has: function( fn ) {
20402				return fn ?
20403					jQuery.inArray( fn, list ) > -1 :
20404					list.length > 0;
20405			},
20406
20407			// Remove all callbacks from the list
20408			empty: function() {
20409				if ( list ) {
20410					list = [];
20411				}
20412				return this;
20413			},
20414
20415			// Disable .fire and .add
20416			// Abort any current/pending executions
20417			// Clear all callbacks and values
20418			disable: function() {
20419				locked = queue = [];
20420				list = memory = "";
20421				return this;
20422			},
20423			disabled: function() {
20424				return !list;
20425			},
20426
20427			// Disable .fire
20428			// Also disable .add unless we have memory (since it would have no effect)
20429			// Abort any pending executions
20430			lock: function() {
20431				locked = true;
20432				if ( !memory ) {
20433					self.disable();
20434				}
20435				return this;
20436			},
20437			locked: function() {
20438				return !!locked;
20439			},
20440
20441			// Call all callbacks with the given context and arguments
20442			fireWith: function( context, args ) {
20443				if ( !locked ) {
20444					args = args || [];
20445					args = [ context, args.slice ? args.slice() : args ];
20446					queue.push( args );
20447					if ( !firing ) {
20448						fire();
20449					}
20450				}
20451				return this;
20452			},
20453
20454			// Call all the callbacks with the given arguments
20455			fire: function() {
20456				self.fireWith( this, arguments );
20457				return this;
20458			},
20459
20460			// To know if the callbacks have already been called at least once
20461			fired: function() {
20462				return !!fired;
20463			}
20464		};
20465
20466	return self;
20467};
20468
20469
20470jQuery.extend( {
20471
20472	Deferred: function( func ) {
20473		var tuples = [
20474
20475				// action, add listener, listener list, final state
20476				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
20477				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
20478				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
20479			],
20480			state = "pending",
20481			promise = {
20482				state: function() {
20483					return state;
20484				},
20485				always: function() {
20486					deferred.done( arguments ).fail( arguments );
20487					return this;
20488				},
20489				then: function( /* fnDone, fnFail, fnProgress */ ) {
20490					var fns = arguments;
20491					return jQuery.Deferred( function( newDefer ) {
20492						jQuery.each( tuples, function( i, tuple ) {
20493							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
20494
20495							// deferred[ done | fail | progress ] for forwarding actions to newDefer
20496							deferred[ tuple[ 1 ] ]( function() {
20497								var returned = fn && fn.apply( this, arguments );
20498								if ( returned && jQuery.isFunction( returned.promise ) ) {
20499									returned.promise()
20500										.progress( newDefer.notify )
20501										.done( newDefer.resolve )
20502										.fail( newDefer.reject );
20503								} else {
20504									newDefer[ tuple[ 0 ] + "With" ](
20505										this === promise ? newDefer.promise() : this,
20506										fn ? [ returned ] : arguments
20507									);
20508								}
20509							} );
20510						} );
20511						fns = null;
20512					} ).promise();
20513				},
20514
20515				// Get a promise for this deferred
20516				// If obj is provided, the promise aspect is added to the object
20517				promise: function( obj ) {
20518					return obj != null ? jQuery.extend( obj, promise ) : promise;
20519				}
20520			},
20521			deferred = {};
20522
20523		// Keep pipe for back-compat
20524		promise.pipe = promise.then;
20525
20526		// Add list-specific methods
20527		jQuery.each( tuples, function( i, tuple ) {
20528			var list = tuple[ 2 ],
20529				stateString = tuple[ 3 ];
20530
20531			// promise[ done | fail | progress ] = list.add
20532			promise[ tuple[ 1 ] ] = list.add;
20533
20534			// Handle state
20535			if ( stateString ) {
20536				list.add( function() {
20537
20538					// state = [ resolved | rejected ]
20539					state = stateString;
20540
20541				// [ reject_list | resolve_list ].disable; progress_list.lock
20542				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
20543			}
20544
20545			// deferred[ resolve | reject | notify ]
20546			deferred[ tuple[ 0 ] ] = function() {
20547				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
20548				return this;
20549			};
20550			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
20551		} );
20552
20553		// Make the deferred a promise
20554		promise.promise( deferred );
20555
20556		// Call given func if any
20557		if ( func ) {
20558			func.call( deferred, deferred );
20559		}
20560
20561		// All done!
20562		return deferred;
20563	},
20564
20565	// Deferred helper
20566	when: function( subordinate /* , ..., subordinateN */ ) {
20567		var i = 0,
20568			resolveValues = slice.call( arguments ),
20569			length = resolveValues.length,
20570
20571			// the count of uncompleted subordinates
20572			remaining = length !== 1 ||
20573				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
20574
20575			// the master Deferred.
20576			// If resolveValues consist of only a single Deferred, just use that.
20577			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
20578
20579			// Update function for both resolve and progress values
20580			updateFunc = function( i, contexts, values ) {
20581				return function( value ) {
20582					contexts[ i ] = this;
20583					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
20584					if ( values === progressValues ) {
20585						deferred.notifyWith( contexts, values );
20586
20587					} else if ( !( --remaining ) ) {
20588						deferred.resolveWith( contexts, values );
20589					}
20590				};
20591			},
20592
20593			progressValues, progressContexts, resolveContexts;
20594
20595		// add listeners to Deferred subordinates; treat others as resolved
20596		if ( length > 1 ) {
20597			progressValues = new Array( length );
20598			progressContexts = new Array( length );
20599			resolveContexts = new Array( length );
20600			for ( ; i < length; i++ ) {
20601				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
20602					resolveValues[ i ].promise()
20603						.progress( updateFunc( i, progressContexts, progressValues ) )
20604						.done( updateFunc( i, resolveContexts, resolveValues ) )
20605						.fail( deferred.reject );
20606				} else {
20607					--remaining;
20608				}
20609			}
20610		}
20611
20612		// if we're not waiting on anything, resolve the master
20613		if ( !remaining ) {
vendor: 2,149 bytes, lines 20614-20713
20614			deferred.resolveWith( resolveContexts, resolveValues );
20615		}
20616
20617		return deferred.promise();
20618	}
20619} );
20620
20621
20622// The deferred used on DOM ready
20623var readyList;
20624
20625jQuery.fn.ready = function( fn ) {
20626
20627	// Add the callback
20628	jQuery.ready.promise().done( fn );
20629
20630	return this;
20631};
20632
20633jQuery.extend( {
20634
20635	// Is the DOM ready to be used? Set to true once it occurs.
20636	isReady: false,
20637
20638	// A counter to track how many items to wait for before
20639	// the ready event fires. See #6781
20640	readyWait: 1,
20641
20642	// Hold (or release) the ready event
20643	holdReady: function( hold ) {
20644		if ( hold ) {
20645			jQuery.readyWait++;
20646		} else {
20647			jQuery.ready( true );
20648		}
20649	},
20650
20651	// Handle when the DOM is ready
20652	ready: function( wait ) {
20653
20654		// Abort if there are pending holds or we're already ready
20655		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
20656			return;
20657		}
20658
20659		// Remember that the DOM is ready
20660		jQuery.isReady = true;
20661
20662		// If a normal DOM Ready event fired, decrement, and wait if need be
20663		if ( wait !== true && --jQuery.readyWait > 0 ) {
20664			return;
20665		}
20666
20667		// If there are functions bound, to execute
20668		readyList.resolveWith( document, [ jQuery ] );
20669
20670		// Trigger any bound ready events
20671		if ( jQuery.fn.triggerHandler ) {
20672			jQuery( document ).triggerHandler( "ready" );
20673			jQuery( document ).off( "ready" );
20674		}
20675	}
20676} );
20677
20678/**
20679 * Clean-up method for dom ready events
20680 */
20681function detach() {
20682	if ( document.addEventListener ) {
20683		document.removeEventListener( "DOMContentLoaded", completed );
20684		window.removeEventListener( "load", completed );
20685
20686	} else {
20687		document.detachEvent( "onreadystatechange", completed );
20688		window.detachEvent( "onload", completed );
20689	}
20690}
20691
20692/**
20693 * The ready event handler and self cleanup method
20694 */
20695function completed() {
20696
20697	// readyState === "complete" is good enough for us to call the dom ready in oldIE
20698	if ( document.addEventListener ||
20699		window.event.type === "load" ||
20700		document.readyState === "complete" ) {
20701
20702		detach();
20703		jQuery.ready();
20704	}
20705}
20706
20707jQuery.ready.promise = function( obj ) {
20708	if ( !readyList ) {
20709
20710		readyList = jQuery.Deferred();
20711
20712		// Catch cases where $(document).ready() is called
20713		// after the browser event has already occurred.
20714		// Support: IE6-10
20715		// Older IE sometimes signals "interactive" too soon
20716		if ( document.readyState === "complete" ||
20717			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
20718
20719			// Handle it asynchronously to allow scripts the opportunity to delay ready
20720			window.setTimeout( jQuery.ready );
20721
20722		// Standards-based browsers support DOMContentLoaded
20723		} else if ( document.addEventListener ) {
20724
20725			// Use the handy event callback
20726			document.addEventListener( "DOMContentLoaded", completed );
20727
20728			// A fallback to window.onload, that will always work
20729			window.addEventListener( "load", completed );
20730
20731		// If IE event model is used
20732		} else {
20733
20734			// Ensure firing before onload, maybe late but safe also for iframes
20735			document.attachEvent( "onreadystatechange", completed );
20736
20737			// A fallback to window.onload, that will always work
20738			window.attachEvent( "onload", completed );
20739
20740			// If IE and not a frame
20741			// continually check to see if the document is ready
20742			var top = false;
20743
20744			try {
20745				top = window.frameElement == null && document.documentElement;
20746			} catch ( e ) {}
20747
20748			if ( top && top.doScroll ) {
20749				( function doScrollCheck() {
20750					if ( !jQuery.isReady ) {
20751
20752						try {
20753
20754							// Use the trick by Diego Perini
20755							// http://javascript.nwbox.com/IEContentLoaded/
20756							top.doScroll( "left" );
20757						} catch ( e ) {
20758							return window.setTimeout( doScrollCheck, 50 );
20759						}
20760
20761						// detach all dom ready events
20762						detach();
20763
20764						// and execute any waiting functions
20765						jQuery.ready();
20766					}
20767				} )();
20768			}
20769		}
20770	}
20771	return readyList.promise( obj );
20772};
20773
20774// Kick off the DOM ready check even if the user does not
20775jQuery.ready.promise();
20776
20777
20778
20779
20780// Support: IE<9
20781// Iteration over object's inherited properties before its own
20782var i;
20783for ( i in jQuery( support ) ) {
20784	break;
20785}
20786support.ownFirst = i === "0";
20787
20788// Note: most support tests are defined in their respective modules.
20789// false until the test is run
20790support.inlineBlockNeedsLayout = false;
20791
20792// Execute ASAP in case we need to set body.style.zoom
20793jQuery( function() {
20794
20795	// Minified: var a,b,c,d
20796	var val, div, body, container;
20797
20798	body = document.getElementsByTagName( "body" )[ 0 ];
20799	if ( !body || !body.style ) {
20800
20801		// Return for frameset docs that don't have a body
20802		return;
20803	}
20804
20805	// Setup
20806	div = document.createElement( "div" );
20807	container = document.createElement( "div" );
20808	container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
20809	body.appendChild( container ).appendChild( div );
20810
20811	if ( typeof div.style.zoom !== "undefined" ) {
20812
20813		// Support: IE<8
20814		// Check if natively block-level elements act like inline-block
20815		// elements when setting their display to 'inline' and giving
20816		// them layout
20817		div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
20818
20819		support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
20820		if ( val ) {
20821
20822			// Prevent IE 6 from affecting layout for positioned elements #11048
20823			// Prevent IE from shrinking the body in IE 7 mode #12869
20824			// Support: IE<8
20825			body.style.zoom = 1;
20826		}
20827	}
20828
20829	body.removeChild( container );
20830} );
20831
20832
20833( function() {
20834	var div = document.createElement( "div" );
20835
20836	// Support: IE<9
20837	support.deleteExpando = true;
20838	try {
20839		delete div.test;
20840	} catch ( e ) {
20841		support.deleteExpando = false;
20842	}
20843
20844	// Null elements to avoid leaks in IE.
20845	div = null;
20846} )();
20847var acceptData = function( elem ) {
20848	var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
20849		nodeType = +elem.nodeType || 1;
20850
20851	// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
20852	return nodeType !== 1 && nodeType !== 9 ?
20853		false :
20854
20855		// Nodes accept data unless otherwise specified; rejection can be conditional
20856		!noData || noData !== true && elem.getAttribute( "classid" ) === noData;
20857};
20858
20859
20860
20861
20862var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
20863	rmultiDash = /([A-Z])/g;
20864
20865function dataAttr( elem, key, data ) {
20866
20867	// If nothing was found internally, try to fetch any
20868	// data from the HTML5 data-* attribute
20869	if ( data === undefined && elem.nodeType === 1 ) {
20870
20871		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
20872
20873		data = elem.getAttribute( name );
20874
20875		if ( typeof data === "string" ) {
20876			try {
20877				data = data === "true" ? true :
vendor: 11,186 bytes, lines 20878-21342
20878					data === "false" ? false :
20879					data === "null" ? null :
20880
20881					// Only convert to a number if it doesn't change the string
20882					+data + "" === data ? +data :
20883					rbrace.test( data ) ? jQuery.parseJSON( data ) :
20884					data;
20885			} catch ( e ) {}
20886
20887			// Make sure we set the data so it isn't changed later
20888			jQuery.data( elem, key, data );
20889
20890		} else {
20891			data = undefined;
20892		}
20893	}
20894
20895	return data;
20896}
20897
20898// checks a cache object for emptiness
20899function isEmptyDataObject( obj ) {
20900	var name;
20901	for ( name in obj ) {
20902
20903		// if the public data object is empty, the private is still empty
20904		if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
20905			continue;
20906		}
20907		if ( name !== "toJSON" ) {
20908			return false;
20909		}
20910	}
20911
20912	return true;
20913}
20914
20915function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
20916	if ( !acceptData( elem ) ) {
20917		return;
20918	}
20919
20920	var ret, thisCache,
20921		internalKey = jQuery.expando,
20922
20923		// We have to handle DOM nodes and JS objects differently because IE6-7
20924		// can't GC object references properly across the DOM-JS boundary
20925		isNode = elem.nodeType,
20926
20927		// Only DOM nodes need the global jQuery cache; JS object data is
20928		// attached directly to the object so GC can occur automatically
20929		cache = isNode ? jQuery.cache : elem,
20930
20931		// Only defining an ID for JS objects if its cache already exists allows
20932		// the code to shortcut on the same path as a DOM node with no cache
20933		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
20934
20935	// Avoid doing any more work than we need to when trying to get data on an
20936	// object that has no data at all
20937	if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
20938		data === undefined && typeof name === "string" ) {
20939		return;
20940	}
20941
20942	if ( !id ) {
20943
20944		// Only DOM nodes need a new unique ID for each element since their data
20945		// ends up in the global cache
20946		if ( isNode ) {
20947			id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
20948		} else {
20949			id = internalKey;
20950		}
20951	}
20952
20953	if ( !cache[ id ] ) {
20954
20955		// Avoid exposing jQuery metadata on plain JS objects when the object
20956		// is serialized using JSON.stringify
20957		cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
20958	}
20959
20960	// An object can be passed to jQuery.data instead of a key/value pair; this gets
20961	// shallow copied over onto the existing cache
20962	if ( typeof name === "object" || typeof name === "function" ) {
20963		if ( pvt ) {
20964			cache[ id ] = jQuery.extend( cache[ id ], name );
20965		} else {
20966			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
20967		}
20968	}
20969
20970	thisCache = cache[ id ];
20971
20972	// jQuery data() is stored in a separate object inside the object's internal data
20973	// cache in order to avoid key collisions between internal data and user-defined
20974	// data.
20975	if ( !pvt ) {
20976		if ( !thisCache.data ) {
20977			thisCache.data = {};
20978		}
20979
20980		thisCache = thisCache.data;
20981	}
20982
20983	if ( data !== undefined ) {
20984		thisCache[ jQuery.camelCase( name ) ] = data;
20985	}
20986
20987	// Check for both converted-to-camel and non-converted data property names
20988	// If a data property was specified
20989	if ( typeof name === "string" ) {
20990
20991		// First Try to find as-is property data
20992		ret = thisCache[ name ];
20993
20994		// Test for null|undefined property data
20995		if ( ret == null ) {
20996
20997			// Try to find the camelCased property
20998			ret = thisCache[ jQuery.camelCase( name ) ];
20999		}
21000	} else {
21001		ret = thisCache;
21002	}
21003
21004	return ret;
21005}
21006
21007function internalRemoveData( elem, name, pvt ) {
21008	if ( !acceptData( elem ) ) {
21009		return;
21010	}
21011
21012	var thisCache, i,
21013		isNode = elem.nodeType,
21014
21015		// See jQuery.data for more information
21016		cache = isNode ? jQuery.cache : elem,
21017		id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
21018
21019	// If there is already no cache entry for this object, there is no
21020	// purpose in continuing
21021	if ( !cache[ id ] ) {
21022		return;
21023	}
21024
21025	if ( name ) {
21026
21027		thisCache = pvt ? cache[ id ] : cache[ id ].data;
21028
21029		if ( thisCache ) {
21030
21031			// Support array or space separated string names for data keys
21032			if ( !jQuery.isArray( name ) ) {
21033
21034				// try the string as a key before any manipulation
21035				if ( name in thisCache ) {
21036					name = [ name ];
21037				} else {
21038
21039					// split the camel cased version by spaces unless a key with the spaces exists
21040					name = jQuery.camelCase( name );
21041					if ( name in thisCache ) {
21042						name = [ name ];
21043					} else {
21044						name = name.split( " " );
21045					}
21046				}
21047			} else {
21048
21049				// If "name" is an array of keys...
21050				// When data is initially created, via ("key", "val") signature,
21051				// keys will be converted to camelCase.
21052				// Since there is no way to tell _how_ a key was added, remove
21053				// both plain key and camelCase key. #12786
21054				// This will only penalize the array argument path.
21055				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
21056			}
21057
21058			i = name.length;
21059			while ( i-- ) {
21060				delete thisCache[ name[ i ] ];
21061			}
21062
21063			// If there is no data left in the cache, we want to continue
21064			// and let the cache object itself get destroyed
21065			if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
21066				return;
21067			}
21068		}
21069	}
21070
21071	// See jQuery.data for more information
21072	if ( !pvt ) {
21073		delete cache[ id ].data;
21074
21075		// Don't destroy the parent cache unless the internal data object
21076		// had been the only thing left in it
21077		if ( !isEmptyDataObject( cache[ id ] ) ) {
21078			return;
21079		}
21080	}
21081
21082	// Destroy the cache
21083	if ( isNode ) {
21084		jQuery.cleanData( [ elem ], true );
21085
21086	// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
21087	/* jshint eqeqeq: false */
21088	} else if ( support.deleteExpando || cache != cache.window ) {
21089		/* jshint eqeqeq: true */
21090		delete cache[ id ];
21091
21092	// When all else fails, undefined
21093	} else {
21094		cache[ id ] = undefined;
21095	}
21096}
21097
21098jQuery.extend( {
21099	cache: {},
21100
21101	// The following elements (space-suffixed to avoid Object.prototype collisions)
21102	// throw uncatchable exceptions if you attempt to set expando properties
21103	noData: {
21104		"applet ": true,
21105		"embed ": true,
21106
21107		// ...but Flash objects (which have this classid) *can* handle expandos
21108		"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
21109	},
21110
21111	hasData: function( elem ) {
21112		elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
21113		return !!elem && !isEmptyDataObject( elem );
21114	},
21115
21116	data: function( elem, name, data ) {
21117		return internalData( elem, name, data );
21118	},
21119
21120	removeData: function( elem, name ) {
21121		return internalRemoveData( elem, name );
21122	},
21123
21124	// For internal use only.
21125	_data: function( elem, name, data ) {
21126		return internalData( elem, name, data, true );
21127	},
21128
21129	_removeData: function( elem, name ) {
21130		return internalRemoveData( elem, name, true );
21131	}
21132} );
21133
21134jQuery.fn.extend( {
21135	data: function( key, value ) {
21136		var i, name, data,
21137			elem = this[ 0 ],
21138			attrs = elem && elem.attributes;
21139
21140		// Special expections of .data basically thwart jQuery.access,
21141		// so implement the relevant behavior ourselves
21142
21143		// Gets all values
21144		if ( key === undefined ) {
21145			if ( this.length ) {
21146				data = jQuery.data( elem );
21147
21148				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
21149					i = attrs.length;
21150					while ( i-- ) {
21151
21152						// Support: IE11+
21153						// The attrs elements can be null (#14894)
21154						if ( attrs[ i ] ) {
21155							name = attrs[ i ].name;
21156							if ( name.indexOf( "data-" ) === 0 ) {
21157								name = jQuery.camelCase( name.slice( 5 ) );
21158								dataAttr( elem, name, data[ name ] );
21159							}
21160						}
21161					}
21162					jQuery._data( elem, "parsedAttrs", true );
21163				}
21164			}
21165
21166			return data;
21167		}
21168
21169		// Sets multiple values
21170		if ( typeof key === "object" ) {
21171			return this.each( function() {
21172				jQuery.data( this, key );
21173			} );
21174		}
21175
21176		return arguments.length > 1 ?
21177
21178			// Sets one value
21179			this.each( function() {
21180				jQuery.data( this, key, value );
21181			} ) :
21182
21183			// Gets one value
21184			// Try to fetch any internally stored data first
21185			elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
21186	},
21187
21188	removeData: function( key ) {
21189		return this.each( function() {
21190			jQuery.removeData( this, key );
21191		} );
21192	}
21193} );
21194
21195
21196jQuery.extend( {
21197	queue: function( elem, type, data ) {
21198		var queue;
21199
21200		if ( elem ) {
21201			type = ( type || "fx" ) + "queue";
21202			queue = jQuery._data( elem, type );
21203
21204			// Speed up dequeue by getting out quickly if this is just a lookup
21205			if ( data ) {
21206				if ( !queue || jQuery.isArray( data ) ) {
21207					queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
21208				} else {
21209					queue.push( data );
21210				}
21211			}
21212			return queue || [];
21213		}
21214	},
21215
21216	dequeue: function( elem, type ) {
21217		type = type || "fx";
21218
21219		var queue = jQuery.queue( elem, type ),
21220			startLength = queue.length,
21221			fn = queue.shift(),
21222			hooks = jQuery._queueHooks( elem, type ),
21223			next = function() {
21224				jQuery.dequeue( elem, type );
21225			};
21226
21227		// If the fx queue is dequeued, always remove the progress sentinel
21228		if ( fn === "inprogress" ) {
21229			fn = queue.shift();
21230			startLength--;
21231		}
21232
21233		if ( fn ) {
21234
21235			// Add a progress sentinel to prevent the fx queue from being
21236			// automatically dequeued
21237			if ( type === "fx" ) {
21238				queue.unshift( "inprogress" );
21239			}
21240
21241			// clear up the last queue stop function
21242			delete hooks.stop;
21243			fn.call( elem, next, hooks );
21244		}
21245
21246		if ( !startLength && hooks ) {
21247			hooks.empty.fire();
21248		}
21249	},
21250
21251	// not intended for public consumption - generates a queueHooks object,
21252	// or returns the current one
21253	_queueHooks: function( elem, type ) {
21254		var key = type + "queueHooks";
21255		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
21256			empty: jQuery.Callbacks( "once memory" ).add( function() {
21257				jQuery._removeData( elem, type + "queue" );
21258				jQuery._removeData( elem, key );
21259			} )
21260		} );
21261	}
21262} );
21263
21264jQuery.fn.extend( {
21265	queue: function( type, data ) {
21266		var setter = 2;
21267
21268		if ( typeof type !== "string" ) {
21269			data = type;
21270			type = "fx";
21271			setter--;
21272		}
21273
21274		if ( arguments.length < setter ) {
21275			return jQuery.queue( this[ 0 ], type );
21276		}
21277
21278		return data === undefined ?
21279			this :
21280			this.each( function() {
21281				var queue = jQuery.queue( this, type, data );
21282
21283				// ensure a hooks for this queue
21284				jQuery._queueHooks( this, type );
21285
21286				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
21287					jQuery.dequeue( this, type );
21288				}
21289			} );
21290	},
21291	dequeue: function( type ) {
21292		return this.each( function() {
21293			jQuery.dequeue( this, type );
21294		} );
21295	},
21296	clearQueue: function( type ) {
21297		return this.queue( type || "fx", [] );
21298	},
21299
21300	// Get a promise resolved when queues of a certain type
21301	// are emptied (fx is the type by default)
21302	promise: function( type, obj ) {
21303		var tmp,
21304			count = 1,
21305			defer = jQuery.Deferred(),
21306			elements = this,
21307			i = this.length,
21308			resolve = function() {
21309				if ( !( --count ) ) {
21310					defer.resolveWith( elements, [ elements ] );
21311				}
21312			};
21313
21314		if ( typeof type !== "string" ) {
21315			obj = type;
21316			type = undefined;
21317		}
21318		type = type || "fx";
21319
21320		while ( i-- ) {
21321			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
21322			if ( tmp && tmp.empty ) {
21323				count++;
21324				tmp.empty.add( resolve );
21325			}
21326		}
21327		resolve();
21328		return defer.promise( obj );
21329	}
21330} );
21331
21332
21333( function() {
21334	var shrinkWrapBlocksVal;
21335
21336	support.shrinkWrapBlocks = function() {
21337		if ( shrinkWrapBlocksVal != null ) {
21338			return shrinkWrapBlocksVal;
21339		}
21340
21341		// Will be changed later if needed.
21342		shrinkWrapBlocksVal = false;
vendor: 4,171 bytes, lines 21343-21491
21343
21344		// Minified: var b,c,d
21345		var div, body, container;
21346
21347		body = document.getElementsByTagName( "body" )[ 0 ];
21348		if ( !body || !body.style ) {
21349
21350			// Test fired too early or in an unsupported environment, exit.
21351			return;
21352		}
21353
21354		// Setup
21355		div = document.createElement( "div" );
21356		container = document.createElement( "div" );
21357		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
21358		body.appendChild( container ).appendChild( div );
21359
21360		// Support: IE6
21361		// Check if elements with layout shrink-wrap their children
21362		if ( typeof div.style.zoom !== "undefined" ) {
21363
21364			// Reset CSS: box-sizing; display; margin; border
21365			div.style.cssText =
21366
21367				// Support: Firefox<29, Android 2.3
21368				// Vendor-prefix box-sizing
21369				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
21370				"box-sizing:content-box;display:block;margin:0;border:0;" +
21371				"padding:1px;width:1px;zoom:1";
21372			div.appendChild( document.createElement( "div" ) ).style.width = "5px";
21373			shrinkWrapBlocksVal = div.offsetWidth !== 3;
21374		}
21375
21376		body.removeChild( container );
21377
21378		return shrinkWrapBlocksVal;
21379	};
21380
21381} )();
21382var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
21383
21384var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
21385
21386
21387var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
21388
21389var isHidden = function( elem, el ) {
21390
21391		// isHidden might be called from jQuery#filter function;
21392		// in that case, element will be second argument
21393		elem = el || elem;
21394		return jQuery.css( elem, "display" ) === "none" ||
21395			!jQuery.contains( elem.ownerDocument, elem );
21396	};
21397
21398
21399
21400function adjustCSS( elem, prop, valueParts, tween ) {
21401	var adjusted,
21402		scale = 1,
21403		maxIterations = 20,
21404		currentValue = tween ?
21405			function() { return tween.cur(); } :
21406			function() { return jQuery.css( elem, prop, "" ); },
21407		initial = currentValue(),
21408		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
21409
21410		// Starting value computation is required for potential unit mismatches
21411		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
21412			rcssNum.exec( jQuery.css( elem, prop ) );
21413
21414	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
21415
21416		// Trust units reported by jQuery.css
21417		unit = unit || initialInUnit[ 3 ];
21418
21419		// Make sure we update the tween properties later on
21420		valueParts = valueParts || [];
21421
21422		// Iteratively approximate from a nonzero starting point
21423		initialInUnit = +initial || 1;
21424
21425		do {
21426
21427			// If previous iteration zeroed out, double until we get *something*.
21428			// Use string for doubling so we don't accidentally see scale as unchanged below
21429			scale = scale || ".5";
21430
21431			// Adjust and apply
21432			initialInUnit = initialInUnit / scale;
21433			jQuery.style( elem, prop, initialInUnit + unit );
21434
21435		// Update scale, tolerating zero or NaN from tween.cur()
21436		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
21437		} while (
21438			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
21439		);
21440	}
21441
21442	if ( valueParts ) {
21443		initialInUnit = +initialInUnit || +initial || 0;
21444
21445		// Apply relative offset (+=/-=) if specified
21446		adjusted = valueParts[ 1 ] ?
21447			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
21448			+valueParts[ 2 ];
21449		if ( tween ) {
21450			tween.unit = unit;
21451			tween.start = initialInUnit;
21452			tween.end = adjusted;
21453		}
21454	}
21455	return adjusted;
21456}
21457
21458
21459// Multifunctional method to get and set values of a collection
21460// The value/s can optionally be executed if it's a function
21461var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
21462	var i = 0,
21463		length = elems.length,
21464		bulk = key == null;
21465
21466	// Sets many values
21467	if ( jQuery.type( key ) === "object" ) {
21468		chainable = true;
21469		for ( i in key ) {
21470			access( elems, fn, i, key[ i ], true, emptyGet, raw );
21471		}
21472
21473	// Sets one value
21474	} else if ( value !== undefined ) {
21475		chainable = true;
21476
21477		if ( !jQuery.isFunction( value ) ) {
21478			raw = true;
21479		}
21480
21481		if ( bulk ) {
21482
21483			// Bulk operations run against the entire set
21484			if ( raw ) {
21485				fn.call( elems, value );
21486				fn = null;
21487
21488			// ...except when executing function values
21489			} else {
21490				bulk = fn;
21491				fn = function( elem, key, value ) {
21492					return bulk.call( jQuery( elem ), value );
21493				};
21494			}
21495		}
21496
21497		if ( fn ) {
21498			for ( ; i < length; i++ ) {
21499				fn(
21500					elems[ i ],
21501					key,
21502					raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
21503				);
21504			}
21505		}
21506	}
21507
21508	return chainable ?
21509		elems :
21510
21511		// Gets
21512		bulk ?
21513			fn.call( elems ) :
21514			length ? fn( elems[ 0 ], key ) : emptyGet;
21515};
21516var rcheckableType = ( /^(?:checkbox|radio)$/i );
21517
21518var rtagName = ( /<([\w:-]+)/ );
21519
21520var rscriptType = ( /^$|\/(?:java|ecma)script/i );
21521
21522var rleadingWhitespace = ( /^\s+/ );
21523
21524var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
21525		"details|dialog|figcaption|figure|footer|header|hgroup|main|" +
21526		"mark|meter|nav|output|picture|progress|section|summary|template|time|video";
21527
21528
21529
21530function createSafeFragment( document ) {
21531	var list = nodeNames.split( "|" ),
21532		safeFrag = document.createDocumentFragment();
21533
21534	if ( safeFrag.createElement ) {
21535		while ( list.length ) {
21536			safeFrag.createElement(
21537				list.pop()
21538			);
21539		}
21540	}
21541	return safeFrag;
21542}
21543
21544
21545( function() {
21546	var div = document.createElement( "div" ),
21547		fragment = document.createDocumentFragment(),
21548		input = document.createElement( "input" );
21549
21550	// Setup
21551	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
21552
21553	// IE strips leading whitespace when .innerHTML is used
21554	support.leadingWhitespace = div.firstChild.nodeType === 3;
21555
21556	// Make sure that tbody elements aren't automatically inserted
21557	// IE will insert them into empty tables
21558	support.tbody = !div.getElementsByTagName( "tbody" ).length;
21559
21560	// Make sure that link elements get serialized correctly by innerHTML
21561	// This requires a wrapper element in IE
21562	support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
21563
21564	// Makes sure cloning an html5 element does not cause problems
21565	// Where outerHTML is undefined, this still works
21566	support.html5Clone =
21567		document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
21568
21569	// Check if a disconnected checkbox will retain its checked
21570	// value of true after appended to the DOM (IE6/7)
21571	input.type = "checkbox";
21572	input.checked = true;
21573	fragment.appendChild( input );
21574	support.appendChecked = input.checked;
21575
21576	// Make sure textarea (and checkbox) defaultValue is properly cloned
21577	// Support: IE6-IE11+
21578	div.innerHTML = "<textarea>x</textarea>";
21579	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
21580
21581	// #11217 - WebKit loses check when the name is after the checked attribute
21582	fragment.appendChild( div );
21583
21584	// Support: Windows Web Apps (WWA)
21585	// `name` and `type` must use .setAttribute for WWA (#14901)
21586	input = document.createElement( "input" );
21587	input.setAttribute( "type", "radio" );
21588	input.setAttribute( "checked", "checked" );
21589	input.setAttribute( "name", "t" );
21590
21591	div.appendChild( input );
21592
21593	// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
21594	// old WebKit doesn't clone checked state correctly in fragments
21595	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
21596
21597	// Support: IE<9
21598	// Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
21599	support.noCloneEvent = !!div.addEventListener;
21600
21601	// Support: IE<9
21602	// Since attributes and properties are the same in IE,
21603	// cleanData must set properties to undefined rather than use removeAttribute
21604	div[ jQuery.expando ] = 1;
21605	support.attributes = !div.getAttribute( jQuery.expando );
21606} )();
21607
21608
21609// We have to close these tags to support XHTML (#13200)
21610var wrapMap = {
21611	option: [ 1, "<select multiple='multiple'>", "</select>" ],
21612	legend: [ 1, "<fieldset>", "</fieldset>" ],
21613	area: [ 1, "<map>", "</map>" ],
21614
21615	// Support: IE8
21616	param: [ 1, "<object>", "</object>" ],
21617	thead: [ 1, "<table>", "</table>" ],
21618	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
21619	col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
21620	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
21621
21622	// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
21623	// unless wrapped in a div with non-breaking characters in front of it.
21624	_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
21625};
21626
21627// Support: IE8-IE9
21628wrapMap.optgroup = wrapMap.option;
21629
21630wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
21631wrapMap.th = wrapMap.td;
21632
21633
21634function getAll( context, tag ) {
21635	var elems, elem,
21636		i = 0,
21637		found = typeof context.getElementsByTagName !== "undefined" ?
21638			context.getElementsByTagName( tag || "*" ) :
21639			typeof context.querySelectorAll !== "undefined" ?
21640				context.querySelectorAll( tag || "*" ) :
21641				undefined;
21642
21643	if ( !found ) {
21644		for ( found = [], elems = context.childNodes || context;
21645			( elem = elems[ i ] ) != null;
21646			i++
21647		) {
21648			if ( !tag || jQuery.nodeName( elem, tag ) ) {
21649				found.push( elem );
21650			} else {
21651				jQuery.merge( found, getAll( elem, tag ) );
21652			}
21653		}
21654	}
21655
21656	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
21657		jQuery.merge( [ context ], found ) :
21658		found;
21659}
21660
21661
21662// Mark scripts as having already been evaluated
21663function setGlobalEval( elems, refElements ) {
21664	var elem,
21665		i = 0;
21666	for ( ; ( elem = elems[ i ] ) != null; i++ ) {
21667		jQuery._data(
21668			elem,
21669			"globalEval",
21670			!refElements || jQuery._data( refElements[ i ], "globalEval" )
21671		);
21672	}
21673}
21674
21675
vendor: 45,546 bytes, lines 21676-23308
21676var rhtml = /<|&#?\w+;/,
21677	rtbody = /<tbody/i;
21678
21679function fixDefaultChecked( elem ) {
21680	if ( rcheckableType.test( elem.type ) ) {
21681		elem.defaultChecked = elem.checked;
21682	}
21683}
21684
21685function buildFragment( elems, context, scripts, selection, ignored ) {
21686	var j, elem, contains,
21687		tmp, tag, tbody, wrap,
21688		l = elems.length,
21689
21690		// Ensure a safe fragment
21691		safe = createSafeFragment( context ),
21692
21693		nodes = [],
21694		i = 0;
21695
21696	for ( ; i < l; i++ ) {
21697		elem = elems[ i ];
21698
21699		if ( elem || elem === 0 ) {
21700
21701			// Add nodes directly
21702			if ( jQuery.type( elem ) === "object" ) {
21703				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
21704
21705			// Convert non-html into a text node
21706			} else if ( !rhtml.test( elem ) ) {
21707				nodes.push( context.createTextNode( elem ) );
21708
21709			// Convert html into DOM nodes
21710			} else {
21711				tmp = tmp || safe.appendChild( context.createElement( "div" ) );
21712
21713				// Deserialize a standard representation
21714				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
21715				wrap = wrapMap[ tag ] || wrapMap._default;
21716
21717				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
21718
21719				// Descend through wrappers to the right content
21720				j = wrap[ 0 ];
21721				while ( j-- ) {
21722					tmp = tmp.lastChild;
21723				}
21724
21725				// Manually add leading whitespace removed by IE
21726				if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
21727					nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
21728				}
21729
21730				// Remove IE's autoinserted <tbody> from table fragments
21731				if ( !support.tbody ) {
21732
21733					// String was a <table>, *may* have spurious <tbody>
21734					elem = tag === "table" && !rtbody.test( elem ) ?
21735						tmp.firstChild :
21736
21737						// String was a bare <thead> or <tfoot>
21738						wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
21739							tmp :
21740							0;
21741
21742					j = elem && elem.childNodes.length;
21743					while ( j-- ) {
21744						if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
21745							!tbody.childNodes.length ) {
21746
21747							elem.removeChild( tbody );
21748						}
21749					}
21750				}
21751
21752				jQuery.merge( nodes, tmp.childNodes );
21753
21754				// Fix #12392 for WebKit and IE > 9
21755				tmp.textContent = "";
21756
21757				// Fix #12392 for oldIE
21758				while ( tmp.firstChild ) {
21759					tmp.removeChild( tmp.firstChild );
21760				}
21761
21762				// Remember the top-level container for proper cleanup
21763				tmp = safe.lastChild;
21764			}
21765		}
21766	}
21767
21768	// Fix #11356: Clear elements from fragment
21769	if ( tmp ) {
21770		safe.removeChild( tmp );
21771	}
21772
21773	// Reset defaultChecked for any radios and checkboxes
21774	// about to be appended to the DOM in IE 6/7 (#8060)
21775	if ( !support.appendChecked ) {
21776		jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
21777	}
21778
21779	i = 0;
21780	while ( ( elem = nodes[ i++ ] ) ) {
21781
21782		// Skip elements already in the context collection (trac-4087)
21783		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
21784			if ( ignored ) {
21785				ignored.push( elem );
21786			}
21787
21788			continue;
21789		}
21790
21791		contains = jQuery.contains( elem.ownerDocument, elem );
21792
21793		// Append to fragment
21794		tmp = getAll( safe.appendChild( elem ), "script" );
21795
21796		// Preserve script evaluation history
21797		if ( contains ) {
21798			setGlobalEval( tmp );
21799		}
21800
21801		// Capture executables
21802		if ( scripts ) {
21803			j = 0;
21804			while ( ( elem = tmp[ j++ ] ) ) {
21805				if ( rscriptType.test( elem.type || "" ) ) {
21806					scripts.push( elem );
21807				}
21808			}
21809		}
21810	}
21811
21812	tmp = null;
21813
21814	return safe;
21815}
21816
21817
21818( function() {
21819	var i, eventName,
21820		div = document.createElement( "div" );
21821
21822	// Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
21823	for ( i in { submit: true, change: true, focusin: true } ) {
21824		eventName = "on" + i;
21825
21826		if ( !( support[ i ] = eventName in window ) ) {
21827
21828			// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
21829			div.setAttribute( eventName, "t" );
21830			support[ i ] = div.attributes[ eventName ].expando === false;
21831		}
21832	}
21833
21834	// Null elements to avoid leaks in IE.
21835	div = null;
21836} )();
21837
21838
21839var rformElems = /^(?:input|select|textarea)$/i,
21840	rkeyEvent = /^key/,
21841	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
21842	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
21843	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
21844
21845function returnTrue() {
21846	return true;
21847}
21848
21849function returnFalse() {
21850	return false;
21851}
21852
21853// Support: IE9
21854// See #13393 for more info
21855function safeActiveElement() {
21856	try {
21857		return document.activeElement;
21858	} catch ( err ) { }
21859}
21860
21861function on( elem, types, selector, data, fn, one ) {
21862	var origFn, type;
21863
21864	// Types can be a map of types/handlers
21865	if ( typeof types === "object" ) {
21866
21867		// ( types-Object, selector, data )
21868		if ( typeof selector !== "string" ) {
21869
21870			// ( types-Object, data )
21871			data = data || selector;
21872			selector = undefined;
21873		}
21874		for ( type in types ) {
21875			on( elem, type, selector, data, types[ type ], one );
21876		}
21877		return elem;
21878	}
21879
21880	if ( data == null && fn == null ) {
21881
21882		// ( types, fn )
21883		fn = selector;
21884		data = selector = undefined;
21885	} else if ( fn == null ) {
21886		if ( typeof selector === "string" ) {
21887
21888			// ( types, selector, fn )
21889			fn = data;
21890			data = undefined;
21891		} else {
21892
21893			// ( types, data, fn )
21894			fn = data;
21895			data = selector;
21896			selector = undefined;
21897		}
21898	}
21899	if ( fn === false ) {
21900		fn = returnFalse;
21901	} else if ( !fn ) {
21902		return elem;
21903	}
21904
21905	if ( one === 1 ) {
21906		origFn = fn;
21907		fn = function( event ) {
21908
21909			// Can use an empty set, since event contains the info
21910			jQuery().off( event );
21911			return origFn.apply( this, arguments );
21912		};
21913
21914		// Use same guid so caller can remove using origFn
21915		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
21916	}
21917	return elem.each( function() {
21918		jQuery.event.add( this, types, fn, data, selector );
21919	} );
21920}
21921
21922/*
21923 * Helper functions for managing events -- not part of the public interface.
21924 * Props to Dean Edwards' addEvent library for many of the ideas.
21925 */
21926jQuery.event = {
21927
21928	global: {},
21929
21930	add: function( elem, types, handler, data, selector ) {
21931		var tmp, events, t, handleObjIn,
21932			special, eventHandle, handleObj,
21933			handlers, type, namespaces, origType,
21934			elemData = jQuery._data( elem );
21935
21936		// Don't attach events to noData or text/comment nodes (but allow plain objects)
21937		if ( !elemData ) {
21938			return;
21939		}
21940
21941		// Caller can pass in an object of custom data in lieu of the handler
21942		if ( handler.handler ) {
21943			handleObjIn = handler;
21944			handler = handleObjIn.handler;
21945			selector = handleObjIn.selector;
21946		}
21947
21948		// Make sure that the handler has a unique ID, used to find/remove it later
21949		if ( !handler.guid ) {
21950			handler.guid = jQuery.guid++;
21951		}
21952
21953		// Init the element's event structure and main handler, if this is the first
21954		if ( !( events = elemData.events ) ) {
21955			events = elemData.events = {};
21956		}
21957		if ( !( eventHandle = elemData.handle ) ) {
21958			eventHandle = elemData.handle = function( e ) {
21959
21960				// Discard the second event of a jQuery.event.trigger() and
21961				// when an event is called after a page has unloaded
21962				return typeof jQuery !== "undefined" &&
21963					( !e || jQuery.event.triggered !== e.type ) ?
21964					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
21965					undefined;
21966			};
21967
21968			// Add elem as a property of the handle fn to prevent a memory leak
21969			// with IE non-native events
21970			eventHandle.elem = elem;
21971		}
21972
21973		// Handle multiple events separated by a space
21974		types = ( types || "" ).match( rnotwhite ) || [ "" ];
21975		t = types.length;
21976		while ( t-- ) {
21977			tmp = rtypenamespace.exec( types[ t ] ) || [];
21978			type = origType = tmp[ 1 ];
21979			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
21980
21981			// There *must* be a type, no attaching namespace-only handlers
21982			if ( !type ) {
21983				continue;
21984			}
21985
21986			// If event changes its type, use the special event handlers for the changed type
21987			special = jQuery.event.special[ type ] || {};
21988
21989			// If selector defined, determine special event api type, otherwise given type
21990			type = ( selector ? special.delegateType : special.bindType ) || type;
21991
21992			// Update special based on newly reset type
21993			special = jQuery.event.special[ type ] || {};
21994
21995			// handleObj is passed to all event handlers
21996			handleObj = jQuery.extend( {
21997				type: type,
21998				origType: origType,
21999				data: data,
22000				handler: handler,
22001				guid: handler.guid,
22002				selector: selector,
22003				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
22004				namespace: namespaces.join( "." )
22005			}, handleObjIn );
22006
22007			// Init the event handler queue if we're the first
22008			if ( !( handlers = events[ type ] ) ) {
22009				handlers = events[ type ] = [];
22010				handlers.delegateCount = 0;
22011
22012				// Only use addEventListener/attachEvent if the special events handler returns false
22013				if ( !special.setup ||
22014					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
22015
22016					// Bind the global event handler to the element
22017					if ( elem.addEventListener ) {
22018						elem.addEventListener( type, eventHandle, false );
22019
22020					} else if ( elem.attachEvent ) {
22021						elem.attachEvent( "on" + type, eventHandle );
22022					}
22023				}
22024			}
22025
22026			if ( special.add ) {
22027				special.add.call( elem, handleObj );
22028
22029				if ( !handleObj.handler.guid ) {
22030					handleObj.handler.guid = handler.guid;
22031				}
22032			}
22033
22034			// Add to the element's handler list, delegates in front
22035			if ( selector ) {
22036				handlers.splice( handlers.delegateCount++, 0, handleObj );
22037			} else {
22038				handlers.push( handleObj );
22039			}
22040
22041			// Keep track of which events have ever been used, for event optimization
22042			jQuery.event.global[ type ] = true;
22043		}
22044
22045		// Nullify elem to prevent memory leaks in IE
22046		elem = null;
22047	},
22048
22049	// Detach an event or set of events from an element
22050	remove: function( elem, types, handler, selector, mappedTypes ) {
22051		var j, handleObj, tmp,
22052			origCount, t, events,
22053			special, handlers, type,
22054			namespaces, origType,
22055			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
22056
22057		if ( !elemData || !( events = elemData.events ) ) {
22058			return;
22059		}
22060
22061		// Once for each type.namespace in types; type may be omitted
22062		types = ( types || "" ).match( rnotwhite ) || [ "" ];
22063		t = types.length;
22064		while ( t-- ) {
22065			tmp = rtypenamespace.exec( types[ t ] ) || [];
22066			type = origType = tmp[ 1 ];
22067			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
22068
22069			// Unbind all events (on this namespace, if provided) for the element
22070			if ( !type ) {
22071				for ( type in events ) {
22072					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
22073				}
22074				continue;
22075			}
22076
22077			special = jQuery.event.special[ type ] || {};
22078			type = ( selector ? special.delegateType : special.bindType ) || type;
22079			handlers = events[ type ] || [];
22080			tmp = tmp[ 2 ] &&
22081				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
22082
22083			// Remove matching events
22084			origCount = j = handlers.length;
22085			while ( j-- ) {
22086				handleObj = handlers[ j ];
22087
22088				if ( ( mappedTypes || origType === handleObj.origType ) &&
22089					( !handler || handler.guid === handleObj.guid ) &&
22090					( !tmp || tmp.test( handleObj.namespace ) ) &&
22091					( !selector || selector === handleObj.selector ||
22092						selector === "**" && handleObj.selector ) ) {
22093					handlers.splice( j, 1 );
22094
22095					if ( handleObj.selector ) {
22096						handlers.delegateCount--;
22097					}
22098					if ( special.remove ) {
22099						special.remove.call( elem, handleObj );
22100					}
22101				}
22102			}
22103
22104			// Remove generic event handler if we removed something and no more handlers exist
22105			// (avoids potential for endless recursion during removal of special event handlers)
22106			if ( origCount && !handlers.length ) {
22107				if ( !special.teardown ||
22108					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
22109
22110					jQuery.removeEvent( elem, type, elemData.handle );
22111				}
22112
22113				delete events[ type ];
22114			}
22115		}
22116
22117		// Remove the expando if it's no longer used
22118		if ( jQuery.isEmptyObject( events ) ) {
22119			delete elemData.handle;
22120
22121			// removeData also checks for emptiness and clears the expando if empty
22122			// so use it instead of delete
22123			jQuery._removeData( elem, "events" );
22124		}
22125	},
22126
22127	trigger: function( event, data, elem, onlyHandlers ) {
22128		var handle, ontype, cur,
22129			bubbleType, special, tmp, i,
22130			eventPath = [ elem || document ],
22131			type = hasOwn.call( event, "type" ) ? event.type : event,
22132			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
22133
22134		cur = tmp = elem = elem || document;
22135
22136		// Don't do events on text and comment nodes
22137		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
22138			return;
22139		}
22140
22141		// focus/blur morphs to focusin/out; ensure we're not firing them right now
22142		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
22143			return;
22144		}
22145
22146		if ( type.indexOf( "." ) > -1 ) {
22147
22148			// Namespaced trigger; create a regexp to match event type in handle()
22149			namespaces = type.split( "." );
22150			type = namespaces.shift();
22151			namespaces.sort();
22152		}
22153		ontype = type.indexOf( ":" ) < 0 && "on" + type;
22154
22155		// Caller can pass in a jQuery.Event object, Object, or just an event type string
22156		event = event[ jQuery.expando ] ?
22157			event :
22158			new jQuery.Event( type, typeof event === "object" && event );
22159
22160		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
22161		event.isTrigger = onlyHandlers ? 2 : 3;
22162		event.namespace = namespaces.join( "." );
22163		event.rnamespace = event.namespace ?
22164			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
22165			null;
22166
22167		// Clean up the event in case it is being reused
22168		event.result = undefined;
22169		if ( !event.target ) {
22170			event.target = elem;
22171		}
22172
22173		// Clone any incoming data and prepend the event, creating the handler arg list
22174		data = data == null ?
22175			[ event ] :
22176			jQuery.makeArray( data, [ event ] );
22177
22178		// Allow special events to draw outside the lines
22179		special = jQuery.event.special[ type ] || {};
22180		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
22181			return;
22182		}
22183
22184		// Determine event propagation path in advance, per W3C events spec (#9951)
22185		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
22186		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
22187
22188			bubbleType = special.delegateType || type;
22189			if ( !rfocusMorph.test( bubbleType + type ) ) {
22190				cur = cur.parentNode;
22191			}
22192			for ( ; cur; cur = cur.parentNode ) {
22193				eventPath.push( cur );
22194				tmp = cur;
22195			}
22196
22197			// Only add window if we got to document (e.g., not plain obj or detached DOM)
22198			if ( tmp === ( elem.ownerDocument || document ) ) {
22199				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
22200			}
22201		}
22202
22203		// Fire handlers on the event path
22204		i = 0;
22205		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
22206
22207			event.type = i > 1 ?
22208				bubbleType :
22209				special.bindType || type;
22210
22211			// jQuery handler
22212			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
22213				jQuery._data( cur, "handle" );
22214
22215			if ( handle ) {
22216				handle.apply( cur, data );
22217			}
22218
22219			// Native handler
22220			handle = ontype && cur[ ontype ];
22221			if ( handle && handle.apply && acceptData( cur ) ) {
22222				event.result = handle.apply( cur, data );
22223				if ( event.result === false ) {
22224					event.preventDefault();
22225				}
22226			}
22227		}
22228		event.type = type;
22229
22230		// If nobody prevented the default action, do it now
22231		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
22232
22233			if (
22234				( !special._default ||
22235				 special._default.apply( eventPath.pop(), data ) === false
22236				) && acceptData( elem )
22237			) {
22238
22239				// Call a native DOM method on the target with the same name name as the event.
22240				// Can't use an .isFunction() check here because IE6/7 fails that test.
22241				// Don't do default actions on window, that's where global variables be (#6170)
22242				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
22243
22244					// Don't re-trigger an onFOO event when we call its FOO() method
22245					tmp = elem[ ontype ];
22246
22247					if ( tmp ) {
22248						elem[ ontype ] = null;
22249					}
22250
22251					// Prevent re-triggering of the same event, since we already bubbled it above
22252					jQuery.event.triggered = type;
22253					try {
22254						elem[ type ]();
22255					} catch ( e ) {
22256
22257						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
22258						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
22259					}
22260					jQuery.event.triggered = undefined;
22261
22262					if ( tmp ) {
22263						elem[ ontype ] = tmp;
22264					}
22265				}
22266			}
22267		}
22268
22269		return event.result;
22270	},
22271
22272	dispatch: function( event ) {
22273
22274		// Make a writable jQuery.Event from the native event object
22275		event = jQuery.event.fix( event );
22276
22277		var i, j, ret, matched, handleObj,
22278			handlerQueue = [],
22279			args = slice.call( arguments ),
22280			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
22281			special = jQuery.event.special[ event.type ] || {};
22282
22283		// Use the fix-ed jQuery.Event rather than the (read-only) native event
22284		args[ 0 ] = event;
22285		event.delegateTarget = this;
22286
22287		// Call the preDispatch hook for the mapped type, and let it bail if desired
22288		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
22289			return;
22290		}
22291
22292		// Determine handlers
22293		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
22294
22295		// Run delegates first; they may want to stop propagation beneath us
22296		i = 0;
22297		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
22298			event.currentTarget = matched.elem;
22299
22300			j = 0;
22301			while ( ( handleObj = matched.handlers[ j++ ] ) &&
22302				!event.isImmediatePropagationStopped() ) {
22303
22304				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
22305				// a subset or equal to those in the bound event (both can have no namespace).
22306				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
22307
22308					event.handleObj = handleObj;
22309					event.data = handleObj.data;
22310
22311					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
22312						handleObj.handler ).apply( matched.elem, args );
22313
22314					if ( ret !== undefined ) {
22315						if ( ( event.result = ret ) === false ) {
22316							event.preventDefault();
22317							event.stopPropagation();
22318						}
22319					}
22320				}
22321			}
22322		}
22323
22324		// Call the postDispatch hook for the mapped type
22325		if ( special.postDispatch ) {
22326			special.postDispatch.call( this, event );
22327		}
22328
22329		return event.result;
22330	},
22331
22332	handlers: function( event, handlers ) {
22333		var i, matches, sel, handleObj,
22334			handlerQueue = [],
22335			delegateCount = handlers.delegateCount,
22336			cur = event.target;
22337
22338		// Support (at least): Chrome, IE9
22339		// Find delegate handlers
22340		// Black-hole SVG <use> instance trees (#13180)
22341		//
22342		// Support: Firefox<=42+
22343		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
22344		if ( delegateCount && cur.nodeType &&
22345			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
22346
22347			/* jshint eqeqeq: false */
22348			for ( ; cur != this; cur = cur.parentNode || this ) {
22349				/* jshint eqeqeq: true */
22350
22351				// Don't check non-elements (#13208)
22352				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
22353				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
22354					matches = [];
22355					for ( i = 0; i < delegateCount; i++ ) {
22356						handleObj = handlers[ i ];
22357
22358						// Don't conflict with Object.prototype properties (#13203)
22359						sel = handleObj.selector + " ";
22360
22361						if ( matches[ sel ] === undefined ) {
22362							matches[ sel ] = handleObj.needsContext ?
22363								jQuery( sel, this ).index( cur ) > -1 :
22364								jQuery.find( sel, this, null, [ cur ] ).length;
22365						}
22366						if ( matches[ sel ] ) {
22367							matches.push( handleObj );
22368						}
22369					}
22370					if ( matches.length ) {
22371						handlerQueue.push( { elem: cur, handlers: matches } );
22372					}
22373				}
22374			}
22375		}
22376
22377		// Add the remaining (directly-bound) handlers
22378		if ( delegateCount < handlers.length ) {
22379			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
22380		}
22381
22382		return handlerQueue;
22383	},
22384
22385	fix: function( event ) {
22386		if ( event[ jQuery.expando ] ) {
22387			return event;
22388		}
22389
22390		// Create a writable copy of the event object and normalize some properties
22391		var i, prop, copy,
22392			type = event.type,
22393			originalEvent = event,
22394			fixHook = this.fixHooks[ type ];
22395
22396		if ( !fixHook ) {
22397			this.fixHooks[ type ] = fixHook =
22398				rmouseEvent.test( type ) ? this.mouseHooks :
22399				rkeyEvent.test( type ) ? this.keyHooks :
22400				{};
22401		}
22402		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
22403
22404		event = new jQuery.Event( originalEvent );
22405
22406		i = copy.length;
22407		while ( i-- ) {
22408			prop = copy[ i ];
22409			event[ prop ] = originalEvent[ prop ];
22410		}
22411
22412		// Support: IE<9
22413		// Fix target property (#1925)
22414		if ( !event.target ) {
22415			event.target = originalEvent.srcElement || document;
22416		}
22417
22418		// Support: Safari 6-8+
22419		// Target should not be a text node (#504, #13143)
22420		if ( event.target.nodeType === 3 ) {
22421			event.target = event.target.parentNode;
22422		}
22423
22424		// Support: IE<9
22425		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
22426		event.metaKey = !!event.metaKey;
22427
22428		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
22429	},
22430
22431	// Includes some event props shared by KeyEvent and MouseEvent
22432	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
22433		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
22434
22435	fixHooks: {},
22436
22437	keyHooks: {
22438		props: "char charCode key keyCode".split( " " ),
22439		filter: function( event, original ) {
22440
22441			// Add which for key events
22442			if ( event.which == null ) {
22443				event.which = original.charCode != null ? original.charCode : original.keyCode;
22444			}
22445
22446			return event;
22447		}
22448	},
22449
22450	mouseHooks: {
22451		props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
22452			"pageX pageY screenX screenY toElement" ).split( " " ),
22453		filter: function( event, original ) {
22454			var body, eventDoc, doc,
22455				button = original.button,
22456				fromElement = original.fromElement;
22457
22458			// Calculate pageX/Y if missing and clientX/Y available
22459			if ( event.pageX == null && original.clientX != null ) {
22460				eventDoc = event.target.ownerDocument || document;
22461				doc = eventDoc.documentElement;
22462				body = eventDoc.body;
22463
22464				event.pageX = original.clientX +
22465					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
22466					( doc && doc.clientLeft || body && body.clientLeft || 0 );
22467				event.pageY = original.clientY +
22468					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
22469					( doc && doc.clientTop  || body && body.clientTop  || 0 );
22470			}
22471
22472			// Add relatedTarget, if necessary
22473			if ( !event.relatedTarget && fromElement ) {
22474				event.relatedTarget = fromElement === event.target ?
22475					original.toElement :
22476					fromElement;
22477			}
22478
22479			// Add which for click: 1 === left; 2 === middle; 3 === right
22480			// Note: button is not normalized, so don't use it
22481			if ( !event.which && button !== undefined ) {
22482				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
22483			}
22484
22485			return event;
22486		}
22487	},
22488
22489	special: {
22490		load: {
22491
22492			// Prevent triggered image.load events from bubbling to window.load
22493			noBubble: true
22494		},
22495		focus: {
22496
22497			// Fire native event if possible so blur/focus sequence is correct
22498			trigger: function() {
22499				if ( this !== safeActiveElement() && this.focus ) {
22500					try {
22501						this.focus();
22502						return false;
22503					} catch ( e ) {
22504
22505						// Support: IE<9
22506						// If we error on focus to hidden element (#1486, #12518),
22507						// let .trigger() run the handlers
22508					}
22509				}
22510			},
22511			delegateType: "focusin"
22512		},
22513		blur: {
22514			trigger: function() {
22515				if ( this === safeActiveElement() && this.blur ) {
22516					this.blur();
22517					return false;
22518				}
22519			},
22520			delegateType: "focusout"
22521		},
22522		click: {
22523
22524			// For checkbox, fire native event so checked state will be right
22525			trigger: function() {
22526				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
22527					this.click();
22528					return false;
22529				}
22530			},
22531
22532			// For cross-browser consistency, don't fire native .click() on links
22533			_default: function( event ) {
22534				return jQuery.nodeName( event.target, "a" );
22535			}
22536		},
22537
22538		beforeunload: {
22539			postDispatch: function( event ) {
22540
22541				// Support: Firefox 20+
22542				// Firefox doesn't alert if the returnValue field is not set.
22543				if ( event.result !== undefined && event.originalEvent ) {
22544					event.originalEvent.returnValue = event.result;
22545				}
22546			}
22547		}
22548	},
22549
22550	// Piggyback on a donor event to simulate a different one
22551	simulate: function( type, elem, event ) {
22552		var e = jQuery.extend(
22553			new jQuery.Event(),
22554			event,
22555			{
22556				type: type,
22557				isSimulated: true
22558
22559				// Previously, `originalEvent: {}` was set here, so stopPropagation call
22560				// would not be triggered on donor event, since in our own
22561				// jQuery.event.stopPropagation function we had a check for existence of
22562				// originalEvent.stopPropagation method, so, consequently it would be a noop.
22563				//
22564				// Guard for simulated events was moved to jQuery.event.stopPropagation function
22565				// since `originalEvent` should point to the original event for the
22566				// constancy with other events and for more focused logic
22567			}
22568		);
22569
22570		jQuery.event.trigger( e, null, elem );
22571
22572		if ( e.isDefaultPrevented() ) {
22573			event.preventDefault();
22574		}
22575	}
22576};
22577
22578jQuery.removeEvent = document.removeEventListener ?
22579	function( elem, type, handle ) {
22580
22581		// This "if" is needed for plain objects
22582		if ( elem.removeEventListener ) {
22583			elem.removeEventListener( type, handle );
22584		}
22585	} :
22586	function( elem, type, handle ) {
22587		var name = "on" + type;
22588
22589		if ( elem.detachEvent ) {
22590
22591			// #8545, #7054, preventing memory leaks for custom events in IE6-8
22592			// detachEvent needed property on element, by name of that event,
22593			// to properly expose it to GC
22594			if ( typeof elem[ name ] === "undefined" ) {
22595				elem[ name ] = null;
22596			}
22597
22598			elem.detachEvent( name, handle );
22599		}
22600	};
22601
22602jQuery.Event = function( src, props ) {
22603
22604	// Allow instantiation without the 'new' keyword
22605	if ( !( this instanceof jQuery.Event ) ) {
22606		return new jQuery.Event( src, props );
22607	}
22608
22609	// Event object
22610	if ( src && src.type ) {
22611		this.originalEvent = src;
22612		this.type = src.type;
22613
22614		// Events bubbling up the document may have been marked as prevented
22615		// by a handler lower down the tree; reflect the correct value.
22616		this.isDefaultPrevented = src.defaultPrevented ||
22617				src.defaultPrevented === undefined &&
22618
22619				// Support: IE < 9, Android < 4.0
22620				src.returnValue === false ?
22621			returnTrue :
22622			returnFalse;
22623
22624	// Event type
22625	} else {
22626		this.type = src;
22627	}
22628
22629	// Put explicitly provided properties onto the event object
22630	if ( props ) {
22631		jQuery.extend( this, props );
22632	}
22633
22634	// Create a timestamp if incoming event doesn't have one
22635	this.timeStamp = src && src.timeStamp || jQuery.now();
22636
22637	// Mark it as fixed
22638	this[ jQuery.expando ] = true;
22639};
22640
22641// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
22642// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
22643jQuery.Event.prototype = {
22644	constructor: jQuery.Event,
22645	isDefaultPrevented: returnFalse,
22646	isPropagationStopped: returnFalse,
22647	isImmediatePropagationStopped: returnFalse,
22648
22649	preventDefault: function() {
22650		var e = this.originalEvent;
22651
22652		this.isDefaultPrevented = returnTrue;
22653		if ( !e ) {
22654			return;
22655		}
22656
22657		// If preventDefault exists, run it on the original event
22658		if ( e.preventDefault ) {
22659			e.preventDefault();
22660
22661		// Support: IE
22662		// Otherwise set the returnValue property of the original event to false
22663		} else {
22664			e.returnValue = false;
22665		}
22666	},
22667	stopPropagation: function() {
22668		var e = this.originalEvent;
22669
22670		this.isPropagationStopped = returnTrue;
22671
22672		if ( !e || this.isSimulated ) {
22673			return;
22674		}
22675
22676		// If stopPropagation exists, run it on the original event
22677		if ( e.stopPropagation ) {
22678			e.stopPropagation();
22679		}
22680
22681		// Support: IE
22682		// Set the cancelBubble property of the original event to true
22683		e.cancelBubble = true;
22684	},
22685	stopImmediatePropagation: function() {
22686		var e = this.originalEvent;
22687
22688		this.isImmediatePropagationStopped = returnTrue;
22689
22690		if ( e && e.stopImmediatePropagation ) {
22691			e.stopImmediatePropagation();
22692		}
22693
22694		this.stopPropagation();
22695	}
22696};
22697
22698// Create mouseenter/leave events using mouseover/out and event-time checks
22699// so that event delegation works in jQuery.
22700// Do the same for pointerenter/pointerleave and pointerover/pointerout
22701//
22702// Support: Safari 7 only
22703// Safari sends mouseenter too often; see:
22704// https://code.google.com/p/chromium/issues/detail?id=470258
22705// for the description of the bug (it existed in older Chrome versions as well).
22706jQuery.each( {
22707	mouseenter: "mouseover",
22708	mouseleave: "mouseout",
22709	pointerenter: "pointerover",
22710	pointerleave: "pointerout"
22711}, function( orig, fix ) {
22712	jQuery.event.special[ orig ] = {
22713		delegateType: fix,
22714		bindType: fix,
22715
22716		handle: function( event ) {
22717			var ret,
22718				target = this,
22719				related = event.relatedTarget,
22720				handleObj = event.handleObj;
22721
22722			// For mouseenter/leave call the handler if related is outside the target.
22723			// NB: No relatedTarget if the mouse left/entered the browser window
22724			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
22725				event.type = handleObj.origType;
22726				ret = handleObj.handler.apply( this, arguments );
22727				event.type = fix;
22728			}
22729			return ret;
22730		}
22731	};
22732} );
22733
22734// IE submit delegation
22735if ( !support.submit ) {
22736
22737	jQuery.event.special.submit = {
22738		setup: function() {
22739
22740			// Only need this for delegated form submit events
22741			if ( jQuery.nodeName( this, "form" ) ) {
22742				return false;
22743			}
22744
22745			// Lazy-add a submit handler when a descendant form may potentially be submitted
22746			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
22747
22748				// Node name check avoids a VML-related crash in IE (#9807)
22749				var elem = e.target,
22750					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
22751
22752						// Support: IE <=8
22753						// We use jQuery.prop instead of elem.form
22754						// to allow fixing the IE8 delegated submit issue (gh-2332)
22755						// by 3rd party polyfills/workarounds.
22756						jQuery.prop( elem, "form" ) :
22757						undefined;
22758
22759				if ( form && !jQuery._data( form, "submit" ) ) {
22760					jQuery.event.add( form, "submit._submit", function( event ) {
22761						event._submitBubble = true;
22762					} );
22763					jQuery._data( form, "submit", true );
22764				}
22765			} );
22766
22767			// return undefined since we don't need an event listener
22768		},
22769
22770		postDispatch: function( event ) {
22771
22772			// If form was submitted by the user, bubble the event up the tree
22773			if ( event._submitBubble ) {
22774				delete event._submitBubble;
22775				if ( this.parentNode && !event.isTrigger ) {
22776					jQuery.event.simulate( "submit", this.parentNode, event );
22777				}
22778			}
22779		},
22780
22781		teardown: function() {
22782
22783			// Only need this for delegated form submit events
22784			if ( jQuery.nodeName( this, "form" ) ) {
22785				return false;
22786			}
22787
22788			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
22789			jQuery.event.remove( this, "._submit" );
22790		}
22791	};
22792}
22793
22794// IE change delegation and checkbox/radio fix
22795if ( !support.change ) {
22796
22797	jQuery.event.special.change = {
22798
22799		setup: function() {
22800
22801			if ( rformElems.test( this.nodeName ) ) {
22802
22803				// IE doesn't fire change on a check/radio until blur; trigger it on click
22804				// after a propertychange. Eat the blur-change in special.change.handle.
22805				// This still fires onchange a second time for check/radio after blur.
22806				if ( this.type === "checkbox" || this.type === "radio" ) {
22807					jQuery.event.add( this, "propertychange._change", function( event ) {
22808						if ( event.originalEvent.propertyName === "checked" ) {
22809							this._justChanged = true;
22810						}
22811					} );
22812					jQuery.event.add( this, "click._change", function( event ) {
22813						if ( this._justChanged && !event.isTrigger ) {
22814							this._justChanged = false;
22815						}
22816
22817						// Allow triggered, simulated change events (#11500)
22818						jQuery.event.simulate( "change", this, event );
22819					} );
22820				}
22821				return false;
22822			}
22823
22824			// Delegated event; lazy-add a change handler on descendant inputs
22825			jQuery.event.add( this, "beforeactivate._change", function( e ) {
22826				var elem = e.target;
22827
22828				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
22829					jQuery.event.add( elem, "change._change", function( event ) {
22830						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
22831							jQuery.event.simulate( "change", this.parentNode, event );
22832						}
22833					} );
22834					jQuery._data( elem, "change", true );
22835				}
22836			} );
22837		},
22838
22839		handle: function( event ) {
22840			var elem = event.target;
22841
22842			// Swallow native change events from checkbox/radio, we already triggered them above
22843			if ( this !== elem || event.isSimulated || event.isTrigger ||
22844				( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
22845
22846				return event.handleObj.handler.apply( this, arguments );
22847			}
22848		},
22849
22850		teardown: function() {
22851			jQuery.event.remove( this, "._change" );
22852
22853			return !rformElems.test( this.nodeName );
22854		}
22855	};
22856}
22857
22858// Support: Firefox
22859// Firefox doesn't have focus(in | out) events
22860// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
22861//
22862// Support: Chrome, Safari
22863// focus(in | out) events fire after focus & blur events,
22864// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
22865// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
22866if ( !support.focusin ) {
22867	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
22868
22869		// Attach a single capturing handler on the document while someone wants focusin/focusout
22870		var handler = function( event ) {
22871			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
22872		};
22873
22874		jQuery.event.special[ fix ] = {
22875			setup: function() {
22876				var doc = this.ownerDocument || this,
22877					attaches = jQuery._data( doc, fix );
22878
22879				if ( !attaches ) {
22880					doc.addEventListener( orig, handler, true );
22881				}
22882				jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
22883			},
22884			teardown: function() {
22885				var doc = this.ownerDocument || this,
22886					attaches = jQuery._data( doc, fix ) - 1;
22887
22888				if ( !attaches ) {
22889					doc.removeEventListener( orig, handler, true );
22890					jQuery._removeData( doc, fix );
22891				} else {
22892					jQuery._data( doc, fix, attaches );
22893				}
22894			}
22895		};
22896	} );
22897}
22898
22899jQuery.fn.extend( {
22900
22901	on: function( types, selector, data, fn ) {
22902		return on( this, types, selector, data, fn );
22903	},
22904	one: function( types, selector, data, fn ) {
22905		return on( this, types, selector, data, fn, 1 );
22906	},
22907	off: function( types, selector, fn ) {
22908		var handleObj, type;
22909		if ( types && types.preventDefault && types.handleObj ) {
22910
22911			// ( event )  dispatched jQuery.Event
22912			handleObj = types.handleObj;
22913			jQuery( types.delegateTarget ).off(
22914				handleObj.namespace ?
22915					handleObj.origType + "." + handleObj.namespace :
22916					handleObj.origType,
22917				handleObj.selector,
22918				handleObj.handler
22919			);
22920			return this;
22921		}
22922		if ( typeof types === "object" ) {
22923
22924			// ( types-object [, selector] )
22925			for ( type in types ) {
22926				this.off( type, selector, types[ type ] );
22927			}
22928			return this;
22929		}
22930		if ( selector === false || typeof selector === "function" ) {
22931
22932			// ( types [, fn] )
22933			fn = selector;
22934			selector = undefined;
22935		}
22936		if ( fn === false ) {
22937			fn = returnFalse;
22938		}
22939		return this.each( function() {
22940			jQuery.event.remove( this, types, fn, selector );
22941		} );
22942	},
22943
22944	trigger: function( type, data ) {
22945		return this.each( function() {
22946			jQuery.event.trigger( type, data, this );
22947		} );
22948	},
22949	triggerHandler: function( type, data ) {
22950		var elem = this[ 0 ];
22951		if ( elem ) {
22952			return jQuery.event.trigger( type, data, elem, true );
22953		}
22954	}
22955} );
22956
22957
22958var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
22959	rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
22960	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
22961
22962	// Support: IE 10-11, Edge 10240+
22963	// In IE/Edge using regex groups here causes severe slowdowns.
22964	// See https://connect.microsoft.com/IE/feedback/details/1736512/
22965	rnoInnerhtml = /<script|<style|<link/i,
22966
22967	// checked="checked" or checked
22968	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
22969	rscriptTypeMasked = /^true\/(.*)/,
22970	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
22971	safeFragment = createSafeFragment( document ),
22972	fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
22973
22974// Support: IE<8
22975// Manipulating tables requires a tbody
22976function manipulationTarget( elem, content ) {
22977	return jQuery.nodeName( elem, "table" ) &&
22978		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
22979
22980		elem.getElementsByTagName( "tbody" )[ 0 ] ||
22981			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
22982		elem;
22983}
22984
22985// Replace/restore the type attribute of script elements for safe DOM manipulation
22986function disableScript( elem ) {
22987	elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
22988	return elem;
22989}
22990function restoreScript( elem ) {
22991	var match = rscriptTypeMasked.exec( elem.type );
22992	if ( match ) {
22993		elem.type = match[ 1 ];
22994	} else {
22995		elem.removeAttribute( "type" );
22996	}
22997	return elem;
22998}
22999
23000function cloneCopyEvent( src, dest ) {
23001	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
23002		return;
23003	}
23004
23005	var type, i, l,
23006		oldData = jQuery._data( src ),
23007		curData = jQuery._data( dest, oldData ),
23008		events = oldData.events;
23009
23010	if ( events ) {
23011		delete curData.handle;
23012		curData.events = {};
23013
23014		for ( type in events ) {
23015			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
23016				jQuery.event.add( dest, type, events[ type ][ i ] );
23017			}
23018		}
23019	}
23020
23021	// make the cloned public data object a copy from the original
23022	if ( curData.data ) {
23023		curData.data = jQuery.extend( {}, curData.data );
23024	}
23025}
23026
23027function fixCloneNodeIssues( src, dest ) {
23028	var nodeName, e, data;
23029
23030	// We do not need to do anything for non-Elements
23031	if ( dest.nodeType !== 1 ) {
23032		return;
23033	}
23034
23035	nodeName = dest.nodeName.toLowerCase();
23036
23037	// IE6-8 copies events bound via attachEvent when using cloneNode.
23038	if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
23039		data = jQuery._data( dest );
23040
23041		for ( e in data.events ) {
23042			jQuery.removeEvent( dest, e, data.handle );
23043		}
23044
23045		// Event data gets referenced instead of copied if the expando gets copied too
23046		dest.removeAttribute( jQuery.expando );
23047	}
23048
23049	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
23050	if ( nodeName === "script" && dest.text !== src.text ) {
23051		disableScript( dest ).text = src.text;
23052		restoreScript( dest );
23053
23054	// IE6-10 improperly clones children of object elements using classid.
23055	// IE10 throws NoModificationAllowedError if parent is null, #12132.
23056	} else if ( nodeName === "object" ) {
23057		if ( dest.parentNode ) {
23058			dest.outerHTML = src.outerHTML;
23059		}
23060
23061		// This path appears unavoidable for IE9. When cloning an object
23062		// element in IE9, the outerHTML strategy above is not sufficient.
23063		// If the src has innerHTML and the destination does not,
23064		// copy the src.innerHTML into the dest.innerHTML. #10324
23065		if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
23066			dest.innerHTML = src.innerHTML;
23067		}
23068
23069	} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
23070
23071		// IE6-8 fails to persist the checked state of a cloned checkbox
23072		// or radio button. Worse, IE6-7 fail to give the cloned element
23073		// a checked appearance if the defaultChecked value isn't also set
23074
23075		dest.defaultChecked = dest.checked = src.checked;
23076
23077		// IE6-7 get confused and end up setting the value of a cloned
23078		// checkbox/radio button to an empty string instead of "on"
23079		if ( dest.value !== src.value ) {
23080			dest.value = src.value;
23081		}
23082
23083	// IE6-8 fails to return the selected option to the default selected
23084	// state when cloning options
23085	} else if ( nodeName === "option" ) {
23086		dest.defaultSelected = dest.selected = src.defaultSelected;
23087
23088	// IE6-8 fails to set the defaultValue to the correct value when
23089	// cloning other types of input fields
23090	} else if ( nodeName === "input" || nodeName === "textarea" ) {
23091		dest.defaultValue = src.defaultValue;
23092	}
23093}
23094
23095function domManip( collection, args, callback, ignored ) {
23096
23097	// Flatten any nested arrays
23098	args = concat.apply( [], args );
23099
23100	var first, node, hasScripts,
23101		scripts, doc, fragment,
23102		i = 0,
23103		l = collection.length,
23104		iNoClone = l - 1,
23105		value = args[ 0 ],
23106		isFunction = jQuery.isFunction( value );
23107
23108	// We can't cloneNode fragments that contain checked, in WebKit
23109	if ( isFunction ||
23110			( l > 1 && typeof value === "string" &&
23111				!support.checkClone && rchecked.test( value ) ) ) {
23112		return collection.each( function( index ) {
23113			var self = collection.eq( index );
23114			if ( isFunction ) {
23115				args[ 0 ] = value.call( this, index, self.html() );
23116			}
23117			domManip( self, args, callback, ignored );
23118		} );
23119	}
23120
23121	if ( l ) {
23122		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
23123		first = fragment.firstChild;
23124
23125		if ( fragment.childNodes.length === 1 ) {
23126			fragment = first;
23127		}
23128
23129		// Require either new content or an interest in ignored elements to invoke the callback
23130		if ( first || ignored ) {
23131			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
23132			hasScripts = scripts.length;
23133
23134			// Use the original fragment for the last item
23135			// instead of the first because it can end up
23136			// being emptied incorrectly in certain situations (#8070).
23137			for ( ; i < l; i++ ) {
23138				node = fragment;
23139
23140				if ( i !== iNoClone ) {
23141					node = jQuery.clone( node, true, true );
23142
23143					// Keep references to cloned scripts for later restoration
23144					if ( hasScripts ) {
23145
23146						// Support: Android<4.1, PhantomJS<2
23147						// push.apply(_, arraylike) throws on ancient WebKit
23148						jQuery.merge( scripts, getAll( node, "script" ) );
23149					}
23150				}
23151
23152				callback.call( collection[ i ], node, i );
23153			}
23154
23155			if ( hasScripts ) {
23156				doc = scripts[ scripts.length - 1 ].ownerDocument;
23157
23158				// Reenable scripts
23159				jQuery.map( scripts, restoreScript );
23160
23161				// Evaluate executable scripts on first document insertion
23162				for ( i = 0; i < hasScripts; i++ ) {
23163					node = scripts[ i ];
23164					if ( rscriptType.test( node.type || "" ) &&
23165						!jQuery._data( node, "globalEval" ) &&
23166						jQuery.contains( doc, node ) ) {
23167
23168						if ( node.src ) {
23169
23170							// Optional AJAX dependency, but won't run scripts if not present
23171							if ( jQuery._evalUrl ) {
23172								jQuery._evalUrl( node.src );
23173							}
23174						} else {
23175							jQuery.globalEval(
23176								( node.text || node.textContent || node.innerHTML || "" )
23177									.replace( rcleanScript, "" )
23178							);
23179						}
23180					}
23181				}
23182			}
23183
23184			// Fix #11809: Avoid leaking memory
23185			fragment = first = null;
23186		}
23187	}
23188
23189	return collection;
23190}
23191
23192function remove( elem, selector, keepData ) {
23193	var node,
23194		elems = selector ? jQuery.filter( selector, elem ) : elem,
23195		i = 0;
23196
23197	for ( ; ( node = elems[ i ] ) != null; i++ ) {
23198
23199		if ( !keepData && node.nodeType === 1 ) {
23200			jQuery.cleanData( getAll( node ) );
23201		}
23202
23203		if ( node.parentNode ) {
23204			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
23205				setGlobalEval( getAll( node, "script" ) );
23206			}
23207			node.parentNode.removeChild( node );
23208		}
23209	}
23210
23211	return elem;
23212}
23213
23214jQuery.extend( {
23215	htmlPrefilter: function( html ) {
23216		return html.replace( rxhtmlTag, "<$1></$2>" );
23217	},
23218
23219	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
23220		var destElements, node, clone, i, srcElements,
23221			inPage = jQuery.contains( elem.ownerDocument, elem );
23222
23223		if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
23224			!rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
23225
23226			clone = elem.cloneNode( true );
23227
23228		// IE<=8 does not properly clone detached, unknown element nodes
23229		} else {
23230			fragmentDiv.innerHTML = elem.outerHTML;
23231			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
23232		}
23233
23234		if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
23235				( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
23236
23237			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
23238			destElements = getAll( clone );
23239			srcElements = getAll( elem );
23240
23241			// Fix all IE cloning issues
23242			for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
23243
23244				// Ensure that the destination node is not null; Fixes #9587
23245				if ( destElements[ i ] ) {
23246					fixCloneNodeIssues( node, destElements[ i ] );
23247				}
23248			}
23249		}
23250
23251		// Copy the events from the original to the clone
23252		if ( dataAndEvents ) {
23253			if ( deepDataAndEvents ) {
23254				srcElements = srcElements || getAll( elem );
23255				destElements = destElements || getAll( clone );
23256
23257				for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
23258					cloneCopyEvent( node, destElements[ i ] );
23259				}
23260			} else {
23261				cloneCopyEvent( elem, clone );
23262			}
23263		}
23264
23265		// Preserve script evaluation history
23266		destElements = getAll( clone, "script" );
23267		if ( destElements.length > 0 ) {
23268			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
23269		}
23270
23271		destElements = srcElements = node = null;
23272
23273		// Return the cloned set
23274		return clone;
23275	},
23276
23277	cleanData: function( elems, /* internal */ forceAcceptData ) {
23278		var elem, type, id, data,
23279			i = 0,
23280			internalKey = jQuery.expando,
23281			cache = jQuery.cache,
23282			attributes = support.attributes,
23283			special = jQuery.event.special;
23284
23285		for ( ; ( elem = elems[ i ] ) != null; i++ ) {
23286			if ( forceAcceptData || acceptData( elem ) ) {
23287
23288				id = elem[ internalKey ];
23289				data = id && cache[ id ];
23290
23291				if ( data ) {
23292					if ( data.events ) {
23293						for ( type in data.events ) {
23294							if ( special[ type ] ) {
23295								jQuery.event.remove( elem, type );
23296
23297							// This is a shortcut to avoid jQuery.event.remove's overhead
23298							} else {
23299								jQuery.removeEvent( elem, type, data.handle );
23300							}
23301						}
23302					}
23303
23304					// Remove cache only if it was not already removed by jQuery.event.remove
23305					if ( cache[ id ] ) {
23306
23307						delete cache[ id ];
23308
23309						// Support: IE<9
23310						// IE does not allow us to delete expando properties from nodes
23311						// IE creates expando attributes along with the property
23312						// IE does not have a removeAttribute function on Document nodes
23313						if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
23314							elem.removeAttribute( internalKey );
23315
23316						// Webkit & Blink performance suffers when deleting properties
23317						// from DOM nodes, so set to undefined instead
23318						// https://code.google.com/p/chromium/issues/detail?id=378607
23319						} else {
23320							elem[ internalKey ] = undefined;
23321						}
23322
23323						deletedIds.push( id );
23324					}
23325				}
23326			}
23327		}
23328	}
23329} );
23330
23331jQuery.fn.extend( {
23332
23333	// Keep domManip exposed until 3.0 (gh-2225)
23334	domManip: domManip,
23335
23336	detach: function( selector ) {
23337		return remove( this, selector, true );
23338	},
23339
23340	remove: function( selector ) {
23341		return remove( this, selector );
23342	},
23343
23344	text: function( value ) {
23345		return access( this, function( value ) {
23346			return value === undefined ?
23347				jQuery.text( this ) :
23348				this.empty().append(
23349					( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
23350				);
23351		}, null, value, arguments.length );
23352	},
23353
23354	append: function() {
23355		return domManip( this, arguments, function( elem ) {
23356			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
23357				var target = manipulationTarget( this, elem );
23358				target.appendChild( elem );
23359			}
23360		} );
23361	},
23362
vendor: 4,288 bytes, lines 23363-23536
23363	prepend: function() {
23364		return domManip( this, arguments, function( elem ) {
23365			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
23366				var target = manipulationTarget( this, elem );
23367				target.insertBefore( elem, target.firstChild );
23368			}
23369		} );
23370	},
23371
23372	before: function() {
23373		return domManip( this, arguments, function( elem ) {
23374			if ( this.parentNode ) {
23375				this.parentNode.insertBefore( elem, this );
23376			}
23377		} );
23378	},
23379
23380	after: function() {
23381		return domManip( this, arguments, function( elem ) {
23382			if ( this.parentNode ) {
23383				this.parentNode.insertBefore( elem, this.nextSibling );
23384			}
23385		} );
23386	},
23387
23388	empty: function() {
23389		var elem,
23390			i = 0;
23391
23392		for ( ; ( elem = this[ i ] ) != null; i++ ) {
23393
23394			// Remove element nodes and prevent memory leaks
23395			if ( elem.nodeType === 1 ) {
23396				jQuery.cleanData( getAll( elem, false ) );
23397			}
23398
23399			// Remove any remaining nodes
23400			while ( elem.firstChild ) {
23401				elem.removeChild( elem.firstChild );
23402			}
23403
23404			// If this is a select, ensure that it displays empty (#12336)
23405			// Support: IE<9
23406			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
23407				elem.options.length = 0;
23408			}
23409		}
23410
23411		return this;
23412	},
23413
23414	clone: function( dataAndEvents, deepDataAndEvents ) {
23415		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
23416		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
23417
23418		return this.map( function() {
23419			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
23420		} );
23421	},
23422
23423	html: function( value ) {
23424		return access( this, function( value ) {
23425			var elem = this[ 0 ] || {},
23426				i = 0,
23427				l = this.length;
23428
23429			if ( value === undefined ) {
23430				return elem.nodeType === 1 ?
23431					elem.innerHTML.replace( rinlinejQuery, "" ) :
23432					undefined;
23433			}
23434
23435			// See if we can take a shortcut and just use innerHTML
23436			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
23437				( support.htmlSerialize || !rnoshimcache.test( value )  ) &&
23438				( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
23439				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
23440
23441				value = jQuery.htmlPrefilter( value );
23442
23443				try {
23444					for ( ; i < l; i++ ) {
23445
23446						// Remove element nodes and prevent memory leaks
23447						elem = this[ i ] || {};
23448						if ( elem.nodeType === 1 ) {
23449							jQuery.cleanData( getAll( elem, false ) );
23450							elem.innerHTML = value;
23451						}
23452					}
23453
23454					elem = 0;
23455
23456				// If using innerHTML throws an exception, use the fallback method
23457				} catch ( e ) {}
23458			}
23459
23460			if ( elem ) {
23461				this.empty().append( value );
23462			}
23463		}, null, value, arguments.length );
23464	},
23465
23466	replaceWith: function() {
23467		var ignored = [];
23468
23469		// Make the changes, replacing each non-ignored context element with the new content
23470		return domManip( this, arguments, function( elem ) {
23471			var parent = this.parentNode;
23472
23473			if ( jQuery.inArray( this, ignored ) < 0 ) {
23474				jQuery.cleanData( getAll( this ) );
23475				if ( parent ) {
23476					parent.replaceChild( elem, this );
23477				}
23478			}
23479
23480		// Force callback invocation
23481		}, ignored );
23482	}
23483} );
23484
23485jQuery.each( {
23486	appendTo: "append",
23487	prependTo: "prepend",
23488	insertBefore: "before",
23489	insertAfter: "after",
23490	replaceAll: "replaceWith"
23491}, function( name, original ) {
23492	jQuery.fn[ name ] = function( selector ) {
23493		var elems,
23494			i = 0,
23495			ret = [],
23496			insert = jQuery( selector ),
23497			last = insert.length - 1;
23498
23499		for ( ; i <= last; i++ ) {
23500			elems = i === last ? this : this.clone( true );
23501			jQuery( insert[ i ] )[ original ]( elems );
23502
23503			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
23504			push.apply( ret, elems.get() );
23505		}
23506
23507		return this.pushStack( ret );
23508	};
23509} );
23510
23511
23512var iframe,
23513	elemdisplay = {
23514
23515		// Support: Firefox
23516		// We have to pre-define these values for FF (#10227)
23517		HTML: "block",
23518		BODY: "block"
23519	};
23520
23521/**
23522 * Retrieve the actual display of a element
23523 * @param {String} name nodeName of the element
23524 * @param {Object} doc Document object
23525 */
23526
23527// Called only from within defaultDisplay
23528function actualDisplay( name, doc ) {
23529	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
23530
23531		display = jQuery.css( elem[ 0 ], "display" );
23532
23533	// We don't have any data stored on the element,
23534	// so use "detach" method as fast way to get rid of the element
23535	elem.detach();
23536
23537	return display;
23538}
23539
23540/**
23541 * Try to determine the default display value of an element
23542 * @param {String} nodeName
23543 */
23544function defaultDisplay( nodeName ) {
23545	var doc = document,
23546		display = elemdisplay[ nodeName ];
23547
23548	if ( !display ) {
23549		display = actualDisplay( nodeName, doc );
23550
23551		// If the simple way fails, read from inside an iframe
23552		if ( display === "none" || !display ) {
23553
23554			// Use the already-created iframe if possible
23555			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
23556				.appendTo( doc.documentElement );
23557
23558			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
23559			doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
23560
23561			// Support: IE
23562			doc.write();
23563			doc.close();
23564
23565			display = actualDisplay( nodeName, doc );
23566			iframe.detach();
23567		}
23568
23569		// Store the correct default display
23570		elemdisplay[ nodeName ] = display;
23571	}
23572
23573	return display;
23574}
23575var rmargin = ( /^margin/ );
23576
23577var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
23578
23579var swap = function( elem, options, callback, args ) {
23580	var ret, name,
23581		old = {};
23582
23583	// Remember the old values, and insert the new ones
23584	for ( name in options ) {
23585		old[ name ] = elem.style[ name ];
23586		elem.style[ name ] = options[ name ];
23587	}
23588
23589	ret = callback.apply( elem, args || [] );
23590
23591	// Revert the old values
23592	for ( name in options ) {
23593		elem.style[ name ] = old[ name ];
23594	}
23595
23596	return ret;
23597};
23598
23599
23600var documentElement = document.documentElement;
23601
23602
23603
23604( function() {
23605	var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
23606		reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
23607		container = document.createElement( "div" ),
23608		div = document.createElement( "div" );
23609
23610	// Finish early in limited (non-browser) environments
23611	if ( !div.style ) {
23612		return;
23613	}
23614
23615	div.style.cssText = "float:left;opacity:.5";
23616
23617	// Support: IE<9
23618	// Make sure that element opacity exists (as opposed to filter)
23619	support.opacity = div.style.opacity === "0.5";
23620
23621	// Verify style float existence
23622	// (IE uses styleFloat instead of cssFloat)
23623	support.cssFloat = !!div.style.cssFloat;
23624
23625	div.style.backgroundClip = "content-box";
23626	div.cloneNode( true ).style.backgroundClip = "";
23627	support.clearCloneStyle = div.style.backgroundClip === "content-box";
23628
23629	container = document.createElement( "div" );
23630	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
23631		"padding:0;margin-top:1px;position:absolute";
23632	div.innerHTML = "";
23633	container.appendChild( div );
23634
23635	// Support: Firefox<29, Android 2.3
23636	// Vendor-prefix box-sizing
23637	support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
23638		div.style.WebkitBoxSizing === "";
23639
23640	jQuery.extend( support, {
23641		reliableHiddenOffsets: function() {
23642			if ( pixelPositionVal == null ) {
23643				computeStyleTests();
23644			}
23645			return reliableHiddenOffsetsVal;
23646		},
23647
23648		boxSizingReliable: function() {
23649
23650			// We're checking for pixelPositionVal here instead of boxSizingReliableVal
23651			// since that compresses better and they're computed together anyway.
23652			if ( pixelPositionVal == null ) {
23653				computeStyleTests();
23654			}
23655			return boxSizingReliableVal;
23656		},
23657
23658		pixelMarginRight: function() {
23659
23660			// Support: Android 4.0-4.3
23661			if ( pixelPositionVal == null ) {
23662				computeStyleTests();
23663			}
23664			return pixelMarginRightVal;
23665		},
23666
23667		pixelPosition: function() {
23668			if ( pixelPositionVal == null ) {
23669				computeStyleTests();
23670			}
23671			return pixelPositionVal;
23672		},
23673
23674		reliableMarginRight: function() {
23675
23676			// Support: Android 2.3
23677			if ( pixelPositionVal == null ) {
23678				computeStyleTests();
23679			}
23680			return reliableMarginRightVal;
23681		},
23682
23683		reliableMarginLeft: function() {
23684
23685			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
23686			if ( pixelPositionVal == null ) {
23687				computeStyleTests();
23688			}
23689			return reliableMarginLeftVal;
23690		}
23691	} );
23692
23693	function computeStyleTests() {
23694		var contents, divStyle,
23695			documentElement = document.documentElement;
23696
23697		// Setup
23698		documentElement.appendChild( container );
23699
23700		div.style.cssText =
23701
23702			// Support: Android 2.3
23703			// Vendor-prefix box-sizing
23704			"-webkit-box-sizing:border-box;box-sizing:border-box;" +
23705			"position:relative;display:block;" +
23706			"margin:auto;border:1px;padding:1px;" +
23707			"top:1%;width:50%";
23708
23709		// Support: IE<9
23710		// Assume reasonable values in the absence of getComputedStyle
23711		pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
23712		pixelMarginRightVal = reliableMarginRightVal = true;
23713
23714		// Check for getComputedStyle so that this code is not run in IE<9.
23715		if ( window.getComputedStyle ) {
23716			divStyle = window.getComputedStyle( div );
23717			pixelPositionVal = ( divStyle || {} ).top !== "1%";
23718			reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
23719			boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
23720
23721			// Support: Android 4.0 - 4.3 only
23722			// Some styles come back with percentage values, even though they shouldn't
23723			div.style.marginRight = "50%";
23724			pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
23725
23726			// Support: Android 2.3 only
23727			// Div with explicit width and no margin-right incorrectly
23728			// gets computed margin-right based on width of container (#3333)
23729			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
23730			contents = div.appendChild( document.createElement( "div" ) );
23731
23732			// Reset CSS: box-sizing; display; margin; border; padding
23733			contents.style.cssText = div.style.cssText =
23734
23735				// Support: Android 2.3
23736				// Vendor-prefix box-sizing
23737				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
23738				"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
23739			contents.style.marginRight = contents.style.width = "0";
23740			div.style.width = "1px";
23741
23742			reliableMarginRightVal =
23743				!parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
23744
23745			div.removeChild( contents );
23746		}
23747
23748		// Support: IE6-8
23749		// First check that getClientRects works as expected
23750		// Check if table cells still have offsetWidth/Height when they are set
23751		// to display:none and there are still other visible table cells in a
23752		// table row; if so, offsetWidth/Height are not reliable for use when
23753		// determining if an element has been hidden directly using
23754		// display:none (it is still safe to use offsets if a parent element is
23755		// hidden; don safety goggles and see bug #4512 for more information).
23756		div.style.display = "none";
23757		reliableHiddenOffsetsVal = div.getClientRects().length === 0;
23758		if ( reliableHiddenOffsetsVal ) {
23759			div.style.display = "";
23760			div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
23761			div.childNodes[ 0 ].style.borderCollapse = "separate";
23762			contents = div.getElementsByTagName( "td" );
23763			contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
23764			reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
23765			if ( reliableHiddenOffsetsVal ) {
23766				contents[ 0 ].style.display = "";
23767				contents[ 1 ].style.display = "none";
23768				reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
23769			}
23770		}
23771
23772		// Teardown
23773		documentElement.removeChild( container );
23774	}
23775
23776} )();
23777
23778
23779var getStyles, curCSS,
23780	rposition = /^(top|right|bottom|left)$/;
23781
23782if ( window.getComputedStyle ) {
23783	getStyles = function( elem ) {
23784
23785		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
23786		// IE throws on elements created in popups
23787		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
23788		var view = elem.ownerDocument.defaultView;
23789
23790		if ( !view || !view.opener ) {
23791			view = window;
23792		}
23793
23794		return view.getComputedStyle( elem );
23795	};
23796
23797	curCSS = function( elem, name, computed ) {
23798		var width, minWidth, maxWidth, ret,
23799			style = elem.style;
23800
23801		computed = computed || getStyles( elem );
23802
23803		// getPropertyValue is only needed for .css('filter') in IE9, see #12537
23804		ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
23805
23806		// Support: Opera 12.1x only
23807		// Fall back to style even without computed
23808		// computed is undefined for elems on document fragments
23809		if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
23810			ret = jQuery.style( elem, name );
23811		}
23812
23813		if ( computed ) {
23814
23815			// A tribute to the "awesome hack by Dean Edwards"
23816			// Chrome < 17 and Safari 5.0 uses "computed value"
23817			// instead of "used value" for margin-right
23818			// Safari 5.1.7 (at least) returns percentage for a larger set of values,
23819			// but width seems to be reliably pixels
23820			// this is against the CSSOM draft spec:
23821			// http://dev.w3.org/csswg/cssom/#resolved-values
23822			if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
23823
23824				// Remember the original values
23825				width = style.width;
23826				minWidth = style.minWidth;
23827				maxWidth = style.maxWidth;
23828
23829				// Put in the new values to get a computed value out
23830				style.minWidth = style.maxWidth = style.width = ret;
23831				ret = computed.width;
23832
23833				// Revert the changed values
23834				style.width = width;
23835				style.minWidth = minWidth;
23836				style.maxWidth = maxWidth;
23837			}
23838		}
23839
vendor: 4,152 bytes, lines 23840-24002
23840		// Support: IE
23841		// IE returns zIndex value as an integer.
23842		return ret === undefined ?
23843			ret :
23844			ret + "";
23845	};
23846} else if ( documentElement.currentStyle ) {
23847	getStyles = function( elem ) {
23848		return elem.currentStyle;
23849	};
23850
23851	curCSS = function( elem, name, computed ) {
23852		var left, rs, rsLeft, ret,
23853			style = elem.style;
23854
23855		computed = computed || getStyles( elem );
23856		ret = computed ? computed[ name ] : undefined;
23857
23858		// Avoid setting ret to empty string here
23859		// so we don't default to auto
23860		if ( ret == null && style && style[ name ] ) {
23861			ret = style[ name ];
23862		}
23863
23864		// From the awesome hack by Dean Edwards
23865		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
23866
23867		// If we're not dealing with a regular pixel number
23868		// but a number that has a weird ending, we need to convert it to pixels
23869		// but not position css attributes, as those are
23870		// proportional to the parent element instead
23871		// and we can't measure the parent instead because it
23872		// might trigger a "stacking dolls" problem
23873		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
23874
23875			// Remember the original values
23876			left = style.left;
23877			rs = elem.runtimeStyle;
23878			rsLeft = rs && rs.left;
23879
23880			// Put in the new values to get a computed value out
23881			if ( rsLeft ) {
23882				rs.left = elem.currentStyle.left;
23883			}
23884			style.left = name === "fontSize" ? "1em" : ret;
23885			ret = style.pixelLeft + "px";
23886
23887			// Revert the changed values
23888			style.left = left;
23889			if ( rsLeft ) {
23890				rs.left = rsLeft;
23891			}
23892		}
23893
23894		// Support: IE
23895		// IE returns zIndex value as an integer.
23896		return ret === undefined ?
23897			ret :
23898			ret + "" || "auto";
23899	};
23900}
23901
23902
23903
23904
23905function addGetHookIf( conditionFn, hookFn ) {
23906
23907	// Define the hook, we'll check on the first run if it's really needed.
23908	return {
23909		get: function() {
23910			if ( conditionFn() ) {
23911
23912				// Hook not needed (or it's not possible to use it due
23913				// to missing dependency), remove it.
23914				delete this.get;
23915				return;
23916			}
23917
23918			// Hook needed; redefine it so that the support test is not executed again.
23919			return ( this.get = hookFn ).apply( this, arguments );
23920		}
23921	};
23922}
23923
23924
23925var
23926
23927		ralpha = /alpha\([^)]*\)/i,
23928	ropacity = /opacity\s*=\s*([^)]*)/i,
23929
23930	// swappable if display is none or starts with table except
23931	// "table", "table-cell", or "table-caption"
23932	// see here for display values:
23933	// https://developer.mozilla.org/en-US/docs/CSS/display
23934	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
23935	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
23936
23937	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
23938	cssNormalTransform = {
23939		letterSpacing: "0",
23940		fontWeight: "400"
23941	},
23942
23943	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
23944	emptyStyle = document.createElement( "div" ).style;
23945
23946
23947// return a css property mapped to a potentially vendor prefixed property
23948function vendorPropName( name ) {
23949
23950	// shortcut for names that are not vendor prefixed
23951	if ( name in emptyStyle ) {
23952		return name;
23953	}
23954
23955	// check for vendor prefixed names
23956	var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
23957		i = cssPrefixes.length;
23958
23959	while ( i-- ) {
23960		name = cssPrefixes[ i ] + capName;
23961		if ( name in emptyStyle ) {
23962			return name;
23963		}
23964	}
23965}
23966
23967function showHide( elements, show ) {
23968	var display, elem, hidden,
23969		values = [],
23970		index = 0,
23971		length = elements.length;
23972
23973	for ( ; index < length; index++ ) {
23974		elem = elements[ index ];
23975		if ( !elem.style ) {
23976			continue;
23977		}
23978
23979		values[ index ] = jQuery._data( elem, "olddisplay" );
23980		display = elem.style.display;
23981		if ( show ) {
23982
23983			// Reset the inline display of this element to learn if it is
23984			// being hidden by cascaded rules or not
23985			if ( !values[ index ] && display === "none" ) {
23986				elem.style.display = "";
23987			}
23988
23989			// Set elements which have been overridden with display: none
23990			// in a stylesheet to whatever the default browser style is
23991			// for such an element
23992			if ( elem.style.display === "" && isHidden( elem ) ) {
23993				values[ index ] =
23994					jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
23995			}
23996		} else {
23997			hidden = isHidden( elem );
23998
23999			if ( display && display !== "none" || !hidden ) {
24000				jQuery._data(
24001					elem,
24002					"olddisplay",
vendor: 6,043 bytes, lines 24003-24214
24003					hidden ? display : jQuery.css( elem, "display" )
24004				);
24005			}
24006		}
24007	}
24008
24009	// Set the display of most of the elements in a second loop
24010	// to avoid the constant reflow
24011	for ( index = 0; index < length; index++ ) {
24012		elem = elements[ index ];
24013		if ( !elem.style ) {
24014			continue;
24015		}
24016		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
24017			elem.style.display = show ? values[ index ] || "" : "none";
24018		}
24019	}
24020
24021	return elements;
24022}
24023
24024function setPositiveNumber( elem, value, subtract ) {
24025	var matches = rnumsplit.exec( value );
24026	return matches ?
24027
24028		// Guard against undefined "subtract", e.g., when used as in cssHooks
24029		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
24030		value;
24031}
24032
24033function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
24034	var i = extra === ( isBorderBox ? "border" : "content" ) ?
24035
24036		// If we already have the right measurement, avoid augmentation
24037		4 :
24038
24039		// Otherwise initialize for horizontal or vertical properties
24040		name === "width" ? 1 : 0,
24041
24042		val = 0;
24043
24044	for ( ; i < 4; i += 2 ) {
24045
24046		// both box models exclude margin, so add it if we want it
24047		if ( extra === "margin" ) {
24048			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
24049		}
24050
24051		if ( isBorderBox ) {
24052
24053			// border-box includes padding, so remove it if we want content
24054			if ( extra === "content" ) {
24055				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
24056			}
24057
24058			// at this point, extra isn't border nor margin, so remove border
24059			if ( extra !== "margin" ) {
24060				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
24061			}
24062		} else {
24063
24064			// at this point, extra isn't content, so add padding
24065			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
24066
24067			// at this point, extra isn't content nor padding, so add border
24068			if ( extra !== "padding" ) {
24069				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
24070			}
24071		}
24072	}
24073
24074	return val;
24075}
24076
24077function getWidthOrHeight( elem, name, extra ) {
24078
24079	// Start with offset property, which is equivalent to the border-box value
24080	var valueIsBorderBox = true,
24081		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
24082		styles = getStyles( elem ),
24083		isBorderBox = support.boxSizing &&
24084			jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
24085
24086	// some non-html elements return undefined for offsetWidth, so check for null/undefined
24087	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
24088	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
24089	if ( val <= 0 || val == null ) {
24090
24091		// Fall back to computed then uncomputed css if necessary
24092		val = curCSS( elem, name, styles );
24093		if ( val < 0 || val == null ) {
24094			val = elem.style[ name ];
24095		}
24096
24097		// Computed unit is not pixels. Stop here and return.
24098		if ( rnumnonpx.test( val ) ) {
24099			return val;
24100		}
24101
24102		// we need the check for style in case a browser which returns unreliable values
24103		// for getComputedStyle silently falls back to the reliable elem.style
24104		valueIsBorderBox = isBorderBox &&
24105			( support.boxSizingReliable() || val === elem.style[ name ] );
24106
24107		// Normalize "", auto, and prepare for extra
24108		val = parseFloat( val ) || 0;
24109	}
24110
24111	// use the active box-sizing model to add/subtract irrelevant styles
24112	return ( val +
24113		augmentWidthOrHeight(
24114			elem,
24115			name,
24116			extra || ( isBorderBox ? "border" : "content" ),
24117			valueIsBorderBox,
24118			styles
24119		)
24120	) + "px";
24121}
24122
24123jQuery.extend( {
24124
24125	// Add in style property hooks for overriding the default
24126	// behavior of getting and setting a style property
24127	cssHooks: {
24128		opacity: {
24129			get: function( elem, computed ) {
24130				if ( computed ) {
24131
24132					// We should always get a number back from opacity
24133					var ret = curCSS( elem, "opacity" );
24134					return ret === "" ? "1" : ret;
24135				}
24136			}
24137		}
24138	},
24139
24140	// Don't automatically add "px" to these possibly-unitless properties
24141	cssNumber: {
24142		"animationIterationCount": true,
24143		"columnCount": true,
24144		"fillOpacity": true,
24145		"flexGrow": true,
24146		"flexShrink": true,
24147		"fontWeight": true,
24148		"lineHeight": true,
24149		"opacity": true,
24150		"order": true,
24151		"orphans": true,
24152		"widows": true,
24153		"zIndex": true,
24154		"zoom": true
24155	},
24156
24157	// Add in properties whose names you wish to fix before
24158	// setting or getting the value
24159	cssProps: {
24160
24161		// normalize float css property
24162		"float": support.cssFloat ? "cssFloat" : "styleFloat"
24163	},
24164
24165	// Get and set the style property on a DOM Node
24166	style: function( elem, name, value, extra ) {
24167
24168		// Don't set styles on text and comment nodes
24169		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
24170			return;
24171		}
24172
24173		// Make sure that we're working with the right name
24174		var ret, type, hooks,
24175			origName = jQuery.camelCase( name ),
24176			style = elem.style;
24177
24178		name = jQuery.cssProps[ origName ] ||
24179			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
24180
24181		// gets hook for the prefixed version
24182		// followed by the unprefixed version
24183		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
24184
24185		// Check if we're setting a value
24186		if ( value !== undefined ) {
24187			type = typeof value;
24188
24189			// Convert "+=" or "-=" to relative numbers (#7345)
24190			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
24191				value = adjustCSS( elem, name, ret );
24192
24193				// Fixes bug #9237
24194				type = "number";
24195			}
24196
24197			// Make sure that null and NaN values aren't set. See: #7116
24198			if ( value == null || value !== value ) {
24199				return;
24200			}
24201
24202			// If a number was passed in, add the unit (except for certain CSS properties)
24203			if ( type === "number" ) {
24204				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
24205			}
24206
24207			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
24208			// but it would mean to define eight
24209			// (for every problematic property) identical functions
24210			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
24211				style[ name ] = "inherit";
24212			}
24213
24214			// If a hook was provided, use that value, otherwise just set the specified value
vendor: 4,586 bytes, lines 24215-24370
24215			if ( !hooks || !( "set" in hooks ) ||
24216				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
24217
24218				// Support: IE
24219				// Swallow errors from 'invalid' CSS values (#5509)
24220				try {
24221					style[ name ] = value;
24222				} catch ( e ) {}
24223			}
24224
24225		} else {
24226
24227			// If a hook was provided get the non-computed value from there
24228			if ( hooks && "get" in hooks &&
24229				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
24230
24231				return ret;
24232			}
24233
24234			// Otherwise just get the value from the style object
24235			return style[ name ];
24236		}
24237	},
24238
24239	css: function( elem, name, extra, styles ) {
24240		var num, val, hooks,
24241			origName = jQuery.camelCase( name );
24242
24243		// Make sure that we're working with the right name
24244		name = jQuery.cssProps[ origName ] ||
24245			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
24246
24247		// gets hook for the prefixed version
24248		// followed by the unprefixed version
24249		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
24250
24251		// If a hook was provided get the computed value from there
24252		if ( hooks && "get" in hooks ) {
24253			val = hooks.get( elem, true, extra );
24254		}
24255
24256		// Otherwise, if a way to get the computed value exists, use that
24257		if ( val === undefined ) {
24258			val = curCSS( elem, name, styles );
24259		}
24260
24261		//convert "normal" to computed value
24262		if ( val === "normal" && name in cssNormalTransform ) {
24263			val = cssNormalTransform[ name ];
24264		}
24265
24266		// Return, converting to number if forced or a qualifier was provided and val looks numeric
24267		if ( extra === "" || extra ) {
24268			num = parseFloat( val );
24269			return extra === true || isFinite( num ) ? num || 0 : val;
24270		}
24271		return val;
24272	}
24273} );
24274
24275jQuery.each( [ "height", "width" ], function( i, name ) {
24276	jQuery.cssHooks[ name ] = {
24277		get: function( elem, computed, extra ) {
24278			if ( computed ) {
24279
24280				// certain elements can have dimension info if we invisibly show them
24281				// however, it must have a current display style that would benefit from this
24282				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
24283					elem.offsetWidth === 0 ?
24284						swap( elem, cssShow, function() {
24285							return getWidthOrHeight( elem, name, extra );
24286						} ) :
24287						getWidthOrHeight( elem, name, extra );
24288			}
24289		},
24290
24291		set: function( elem, value, extra ) {
24292			var styles = extra && getStyles( elem );
24293			return setPositiveNumber( elem, value, extra ?
24294				augmentWidthOrHeight(
24295					elem,
24296					name,
24297					extra,
24298					support.boxSizing &&
24299						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
24300					styles
24301				) : 0
24302			);
24303		}
24304	};
24305} );
24306
24307if ( !support.opacity ) {
24308	jQuery.cssHooks.opacity = {
24309		get: function( elem, computed ) {
24310
24311			// IE uses filters for opacity
24312			return ropacity.test( ( computed && elem.currentStyle ?
24313				elem.currentStyle.filter :
24314				elem.style.filter ) || "" ) ?
24315					( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
24316					computed ? "1" : "";
24317		},
24318
24319		set: function( elem, value ) {
24320			var style = elem.style,
24321				currentStyle = elem.currentStyle,
24322				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
24323				filter = currentStyle && currentStyle.filter || style.filter || "";
24324
24325			// IE has trouble with opacity if it does not have layout
24326			// Force it by setting the zoom level
24327			style.zoom = 1;
24328
24329			// if setting opacity to 1, and no other filters exist -
24330			// attempt to remove filter attribute #6652
24331			// if value === "", then remove inline opacity #12685
24332			if ( ( value >= 1 || value === "" ) &&
24333					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
24334					style.removeAttribute ) {
24335
24336				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
24337				// if "filter:" is present at all, clearType is disabled, we want to avoid this
24338				// style.removeAttribute is IE Only, but so apparently is this code path...
24339				style.removeAttribute( "filter" );
24340
24341				// if there is no filter style applied in a css rule
24342				// or unset inline opacity, we are done
24343				if ( value === "" || currentStyle && !currentStyle.filter ) {
24344					return;
24345				}
24346			}
24347
24348			// otherwise, set new filter values
24349			style.filter = ralpha.test( filter ) ?
24350				filter.replace( ralpha, opacity ) :
24351				filter + " " + opacity;
24352		}
24353	};
24354}
24355
24356jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
24357	function( elem, computed ) {
24358		if ( computed ) {
24359			return swap( elem, { "display": "inline-block" },
24360				curCSS, [ elem, "marginRight" ] );
24361		}
24362	}
24363);
24364
24365jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
24366	function( elem, computed ) {
24367		if ( computed ) {
24368			return (
24369				parseFloat( curCSS( elem, "marginLeft" ) ) ||
24370
vendor: 4,625 bytes, lines 24371-24549
24371				// Support: IE<=11+
24372				// Running getBoundingClientRect on a disconnected node in IE throws an error
24373				// Support: IE8 only
24374				// getClientRects() errors on disconnected elems
24375				( jQuery.contains( elem.ownerDocument, elem ) ?
24376					elem.getBoundingClientRect().left -
24377						swap( elem, { marginLeft: 0 }, function() {
24378							return elem.getBoundingClientRect().left;
24379						} ) :
24380					0
24381				)
24382			) + "px";
24383		}
24384	}
24385);
24386
24387// These hooks are used by animate to expand properties
24388jQuery.each( {
24389	margin: "",
24390	padding: "",
24391	border: "Width"
24392}, function( prefix, suffix ) {
24393	jQuery.cssHooks[ prefix + suffix ] = {
24394		expand: function( value ) {
24395			var i = 0,
24396				expanded = {},
24397
24398				// assumes a single number if not a string
24399				parts = typeof value === "string" ? value.split( " " ) : [ value ];
24400
24401			for ( ; i < 4; i++ ) {
24402				expanded[ prefix + cssExpand[ i ] + suffix ] =
24403					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
24404			}
24405
24406			return expanded;
24407		}
24408	};
24409
24410	if ( !rmargin.test( prefix ) ) {
24411		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
24412	}
24413} );
24414
24415jQuery.fn.extend( {
24416	css: function( name, value ) {
24417		return access( this, function( elem, name, value ) {
24418			var styles, len,
24419				map = {},
24420				i = 0;
24421
24422			if ( jQuery.isArray( name ) ) {
24423				styles = getStyles( elem );
24424				len = name.length;
24425
24426				for ( ; i < len; i++ ) {
24427					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
24428				}
24429
24430				return map;
24431			}
24432
24433			return value !== undefined ?
24434				jQuery.style( elem, name, value ) :
24435				jQuery.css( elem, name );
24436		}, name, value, arguments.length > 1 );
24437	},
24438	show: function() {
24439		return showHide( this, true );
24440	},
24441	hide: function() {
24442		return showHide( this );
24443	},
24444	toggle: function( state ) {
24445		if ( typeof state === "boolean" ) {
24446			return state ? this.show() : this.hide();
24447		}
24448
24449		return this.each( function() {
24450			if ( isHidden( this ) ) {
24451				jQuery( this ).show();
24452			} else {
24453				jQuery( this ).hide();
24454			}
24455		} );
24456	}
24457} );
24458
24459
24460function Tween( elem, options, prop, end, easing ) {
24461	return new Tween.prototype.init( elem, options, prop, end, easing );
24462}
24463jQuery.Tween = Tween;
24464
24465Tween.prototype = {
24466	constructor: Tween,
24467	init: function( elem, options, prop, end, easing, unit ) {
24468		this.elem = elem;
24469		this.prop = prop;
24470		this.easing = easing || jQuery.easing._default;
24471		this.options = options;
24472		this.start = this.now = this.cur();
24473		this.end = end;
24474		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
24475	},
24476	cur: function() {
24477		var hooks = Tween.propHooks[ this.prop ];
24478
24479		return hooks && hooks.get ?
24480			hooks.get( this ) :
24481			Tween.propHooks._default.get( this );
24482	},
24483	run: function( percent ) {
24484		var eased,
24485			hooks = Tween.propHooks[ this.prop ];
24486
24487		if ( this.options.duration ) {
24488			this.pos = eased = jQuery.easing[ this.easing ](
24489				percent, this.options.duration * percent, 0, 1, this.options.duration
24490			);
24491		} else {
24492			this.pos = eased = percent;
24493		}
24494		this.now = ( this.end - this.start ) * eased + this.start;
24495
24496		if ( this.options.step ) {
24497			this.options.step.call( this.elem, this.now, this );
24498		}
24499
24500		if ( hooks && hooks.set ) {
24501			hooks.set( this );
24502		} else {
24503			Tween.propHooks._default.set( this );
24504		}
24505		return this;
24506	}
24507};
24508
24509Tween.prototype.init.prototype = Tween.prototype;
24510
24511Tween.propHooks = {
24512	_default: {
24513		get: function( tween ) {
24514			var result;
24515
24516			// Use a property on the element directly when it is not a DOM element,
24517			// or when there is no matching style property that exists.
24518			if ( tween.elem.nodeType !== 1 ||
24519				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
24520				return tween.elem[ tween.prop ];
24521			}
24522
24523			// passing an empty string as a 3rd parameter to .css will automatically
24524			// attempt a parseFloat and fallback to a string if the parse fails
24525			// so, simple values such as "10px" are parsed to Float.
24526			// complex values such as "rotate(1rad)" are returned as is.
24527			result = jQuery.css( tween.elem, tween.prop, "" );
24528
24529			// Empty strings, null, undefined and "auto" are converted to 0.
24530			return !result || result === "auto" ? 0 : result;
24531		},
24532		set: function( tween ) {
24533
24534			// use step hook for back compat - use cssHook if its there - use .style if its
24535			// available and use plain properties where available
24536			if ( jQuery.fx.step[ tween.prop ] ) {
24537				jQuery.fx.step[ tween.prop ]( tween );
24538			} else if ( tween.elem.nodeType === 1 &&
24539				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
24540					jQuery.cssHooks[ tween.prop ] ) ) {
24541				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
24542			} else {
24543				tween.elem[ tween.prop ] = tween.now;
24544			}
24545		}
24546	}
24547};
24548
24549// Support: IE <=9
vendor: 5,654 bytes, lines 24550-24766
24550// Panic based approach to setting things on disconnected nodes
24551
24552Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
24553	set: function( tween ) {
24554		if ( tween.elem.nodeType && tween.elem.parentNode ) {
24555			tween.elem[ tween.prop ] = tween.now;
24556		}
24557	}
24558};
24559
24560jQuery.easing = {
24561	linear: function( p ) {
24562		return p;
24563	},
24564	swing: function( p ) {
24565		return 0.5 - Math.cos( p * Math.PI ) / 2;
24566	},
24567	_default: "swing"
24568};
24569
24570jQuery.fx = Tween.prototype.init;
24571
24572// Back Compat <1.8 extension point
24573jQuery.fx.step = {};
24574
24575
24576
24577
24578var
24579	fxNow, timerId,
24580	rfxtypes = /^(?:toggle|show|hide)$/,
24581	rrun = /queueHooks$/;
24582
24583// Animations created synchronously will run synchronously
24584function createFxNow() {
24585	window.setTimeout( function() {
24586		fxNow = undefined;
24587	} );
24588	return ( fxNow = jQuery.now() );
24589}
24590
24591// Generate parameters to create a standard animation
24592function genFx( type, includeWidth ) {
24593	var which,
24594		attrs = { height: type },
24595		i = 0;
24596
24597	// if we include width, step value is 1 to do all cssExpand values,
24598	// if we don't include width, step value is 2 to skip over Left and Right
24599	includeWidth = includeWidth ? 1 : 0;
24600	for ( ; i < 4 ; i += 2 - includeWidth ) {
24601		which = cssExpand[ i ];
24602		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
24603	}
24604
24605	if ( includeWidth ) {
24606		attrs.opacity = attrs.width = type;
24607	}
24608
24609	return attrs;
24610}
24611
24612function createTween( value, prop, animation ) {
24613	var tween,
24614		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
24615		index = 0,
24616		length = collection.length;
24617	for ( ; index < length; index++ ) {
24618		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
24619
24620			// we're done with this property
24621			return tween;
24622		}
24623	}
24624}
24625
24626function defaultPrefilter( elem, props, opts ) {
24627	/* jshint validthis: true */
24628	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
24629		anim = this,
24630		orig = {},
24631		style = elem.style,
24632		hidden = elem.nodeType && isHidden( elem ),
24633		dataShow = jQuery._data( elem, "fxshow" );
24634
24635	// handle queue: false promises
24636	if ( !opts.queue ) {
24637		hooks = jQuery._queueHooks( elem, "fx" );
24638		if ( hooks.unqueued == null ) {
24639			hooks.unqueued = 0;
24640			oldfire = hooks.empty.fire;
24641			hooks.empty.fire = function() {
24642				if ( !hooks.unqueued ) {
24643					oldfire();
24644				}
24645			};
24646		}
24647		hooks.unqueued++;
24648
24649		anim.always( function() {
24650
24651			// doing this makes sure that the complete handler will be called
24652			// before this completes
24653			anim.always( function() {
24654				hooks.unqueued--;
24655				if ( !jQuery.queue( elem, "fx" ).length ) {
24656					hooks.empty.fire();
24657				}
24658			} );
24659		} );
24660	}
24661
24662	// height/width overflow pass
24663	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
24664
24665		// Make sure that nothing sneaks out
24666		// Record all 3 overflow attributes because IE does not
24667		// change the overflow attribute when overflowX and
24668		// overflowY are set to the same value
24669		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
24670
24671		// Set display property to inline-block for height/width
24672		// animations on inline elements that are having width/height animated
24673		display = jQuery.css( elem, "display" );
24674
24675		// Test default display if display is currently "none"
24676		checkDisplay = display === "none" ?
24677			jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
24678
24679		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
24680
24681			// inline-level elements accept inline-block;
24682			// block-level elements need to be inline with layout
24683			if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
24684				style.display = "inline-block";
24685			} else {
24686				style.zoom = 1;
24687			}
24688		}
24689	}
24690
24691	if ( opts.overflow ) {
24692		style.overflow = "hidden";
24693		if ( !support.shrinkWrapBlocks() ) {
24694			anim.always( function() {
24695				style.overflow = opts.overflow[ 0 ];
24696				style.overflowX = opts.overflow[ 1 ];
24697				style.overflowY = opts.overflow[ 2 ];
24698			} );
24699		}
24700	}
24701
24702	// show/hide pass
24703	for ( prop in props ) {
24704		value = props[ prop ];
24705		if ( rfxtypes.exec( value ) ) {
24706			delete props[ prop ];
24707			toggle = toggle || value === "toggle";
24708			if ( value === ( hidden ? "hide" : "show" ) ) {
24709
24710				// If there is dataShow left over from a stopped hide or show
24711				// and we are going to proceed with show, we should pretend to be hidden
24712				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
24713					hidden = true;
24714				} else {
24715					continue;
24716				}
24717			}
24718			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
24719
24720		// Any non-fx value stops us from restoring the original display value
24721		} else {
24722			display = undefined;
24723		}
24724	}
24725
24726	if ( !jQuery.isEmptyObject( orig ) ) {
24727		if ( dataShow ) {
24728			if ( "hidden" in dataShow ) {
24729				hidden = dataShow.hidden;
24730			}
24731		} else {
24732			dataShow = jQuery._data( elem, "fxshow", {} );
24733		}
24734
24735		// store state if its toggle - enables .stop().toggle() to "reverse"
24736		if ( toggle ) {
24737			dataShow.hidden = !hidden;
24738		}
24739		if ( hidden ) {
24740			jQuery( elem ).show();
24741		} else {
24742			anim.done( function() {
24743				jQuery( elem ).hide();
24744			} );
24745		}
24746		anim.done( function() {
24747			var prop;
24748			jQuery._removeData( elem, "fxshow" );
24749			for ( prop in orig ) {
24750				jQuery.style( elem, prop, orig[ prop ] );
24751			}
24752		} );
24753		for ( prop in orig ) {
24754			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
24755
24756			if ( !( prop in dataShow ) ) {
24757				dataShow[ prop ] = tween.start;
24758				if ( hidden ) {
24759					tween.end = tween.start;
24760					tween.start = prop === "width" || prop === "height" ? 1 : 0;
24761				}
24762			}
24763		}
24764
24765	// If this is a noop like .hide().hide(), restore an overwritten display value
24766	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : dis
vendor: 10,851 bytes, lines 24766-25198
24766play ) === "inline" ) {
24767		style.display = display;
24768	}
24769}
24770
24771function propFilter( props, specialEasing ) {
24772	var index, name, easing, value, hooks;
24773
24774	// camelCase, specialEasing and expand cssHook pass
24775	for ( index in props ) {
24776		name = jQuery.camelCase( index );
24777		easing = specialEasing[ name ];
24778		value = props[ index ];
24779		if ( jQuery.isArray( value ) ) {
24780			easing = value[ 1 ];
24781			value = props[ index ] = value[ 0 ];
24782		}
24783
24784		if ( index !== name ) {
24785			props[ name ] = value;
24786			delete props[ index ];
24787		}
24788
24789		hooks = jQuery.cssHooks[ name ];
24790		if ( hooks && "expand" in hooks ) {
24791			value = hooks.expand( value );
24792			delete props[ name ];
24793
24794			// not quite $.extend, this wont overwrite keys already present.
24795			// also - reusing 'index' from above because we have the correct "name"
24796			for ( index in value ) {
24797				if ( !( index in props ) ) {
24798					props[ index ] = value[ index ];
24799					specialEasing[ index ] = easing;
24800				}
24801			}
24802		} else {
24803			specialEasing[ name ] = easing;
24804		}
24805	}
24806}
24807
24808function Animation( elem, properties, options ) {
24809	var result,
24810		stopped,
24811		index = 0,
24812		length = Animation.prefilters.length,
24813		deferred = jQuery.Deferred().always( function() {
24814
24815			// don't match elem in the :animated selector
24816			delete tick.elem;
24817		} ),
24818		tick = function() {
24819			if ( stopped ) {
24820				return false;
24821			}
24822			var currentTime = fxNow || createFxNow(),
24823				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
24824
24825				// Support: Android 2.3
24826				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
24827				temp = remaining / animation.duration || 0,
24828				percent = 1 - temp,
24829				index = 0,
24830				length = animation.tweens.length;
24831
24832			for ( ; index < length ; index++ ) {
24833				animation.tweens[ index ].run( percent );
24834			}
24835
24836			deferred.notifyWith( elem, [ animation, percent, remaining ] );
24837
24838			if ( percent < 1 && length ) {
24839				return remaining;
24840			} else {
24841				deferred.resolveWith( elem, [ animation ] );
24842				return false;
24843			}
24844		},
24845		animation = deferred.promise( {
24846			elem: elem,
24847			props: jQuery.extend( {}, properties ),
24848			opts: jQuery.extend( true, {
24849				specialEasing: {},
24850				easing: jQuery.easing._default
24851			}, options ),
24852			originalProperties: properties,
24853			originalOptions: options,
24854			startTime: fxNow || createFxNow(),
24855			duration: options.duration,
24856			tweens: [],
24857			createTween: function( prop, end ) {
24858				var tween = jQuery.Tween( elem, animation.opts, prop, end,
24859						animation.opts.specialEasing[ prop ] || animation.opts.easing );
24860				animation.tweens.push( tween );
24861				return tween;
24862			},
24863			stop: function( gotoEnd ) {
24864				var index = 0,
24865
24866					// if we are going to the end, we want to run all the tweens
24867					// otherwise we skip this part
24868					length = gotoEnd ? animation.tweens.length : 0;
24869				if ( stopped ) {
24870					return this;
24871				}
24872				stopped = true;
24873				for ( ; index < length ; index++ ) {
24874					animation.tweens[ index ].run( 1 );
24875				}
24876
24877				// resolve when we played the last frame
24878				// otherwise, reject
24879				if ( gotoEnd ) {
24880					deferred.notifyWith( elem, [ animation, 1, 0 ] );
24881					deferred.resolveWith( elem, [ animation, gotoEnd ] );
24882				} else {
24883					deferred.rejectWith( elem, [ animation, gotoEnd ] );
24884				}
24885				return this;
24886			}
24887		} ),
24888		props = animation.props;
24889
24890	propFilter( props, animation.opts.specialEasing );
24891
24892	for ( ; index < length ; index++ ) {
24893		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
24894		if ( result ) {
24895			if ( jQuery.isFunction( result.stop ) ) {
24896				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
24897					jQuery.proxy( result.stop, result );
24898			}
24899			return result;
24900		}
24901	}
24902
24903	jQuery.map( props, createTween, animation );
24904
24905	if ( jQuery.isFunction( animation.opts.start ) ) {
24906		animation.opts.start.call( elem, animation );
24907	}
24908
24909	jQuery.fx.timer(
24910		jQuery.extend( tick, {
24911			elem: elem,
24912			anim: animation,
24913			queue: animation.opts.queue
24914		} )
24915	);
24916
24917	// attach callbacks from options
24918	return animation.progress( animation.opts.progress )
24919		.done( animation.opts.done, animation.opts.complete )
24920		.fail( animation.opts.fail )
24921		.always( animation.opts.always );
24922}
24923
24924jQuery.Animation = jQuery.extend( Animation, {
24925
24926	tweeners: {
24927		"*": [ function( prop, value ) {
24928			var tween = this.createTween( prop, value );
24929			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
24930			return tween;
24931		} ]
24932	},
24933
24934	tweener: function( props, callback ) {
24935		if ( jQuery.isFunction( props ) ) {
24936			callback = props;
24937			props = [ "*" ];
24938		} else {
24939			props = props.match( rnotwhite );
24940		}
24941
24942		var prop,
24943			index = 0,
24944			length = props.length;
24945
24946		for ( ; index < length ; index++ ) {
24947			prop = props[ index ];
24948			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
24949			Animation.tweeners[ prop ].unshift( callback );
24950		}
24951	},
24952
24953	prefilters: [ defaultPrefilter ],
24954
24955	prefilter: function( callback, prepend ) {
24956		if ( prepend ) {
24957			Animation.prefilters.unshift( callback );
24958		} else {
24959			Animation.prefilters.push( callback );
24960		}
24961	}
24962} );
24963
24964jQuery.speed = function( speed, easing, fn ) {
24965	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
24966		complete: fn || !fn && easing ||
24967			jQuery.isFunction( speed ) && speed,
24968		duration: speed,
24969		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
24970	};
24971
24972	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
24973		opt.duration in jQuery.fx.speeds ?
24974			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
24975
24976	// normalize opt.queue - true/undefined/null -> "fx"
24977	if ( opt.queue == null || opt.queue === true ) {
24978		opt.queue = "fx";
24979	}
24980
24981	// Queueing
24982	opt.old = opt.complete;
24983
24984	opt.complete = function() {
24985		if ( jQuery.isFunction( opt.old ) ) {
24986			opt.old.call( this );
24987		}
24988
24989		if ( opt.queue ) {
24990			jQuery.dequeue( this, opt.queue );
24991		}
24992	};
24993
24994	return opt;
24995};
24996
24997jQuery.fn.extend( {
24998	fadeTo: function( speed, to, easing, callback ) {
24999
25000		// show any hidden elements after setting opacity to 0
25001		return this.filter( isHidden ).css( "opacity", 0 ).show()
25002
25003			// animate to the value specified
25004			.end().animate( { opacity: to }, speed, easing, callback );
25005	},
25006	animate: function( prop, speed, easing, callback ) {
25007		var empty = jQuery.isEmptyObject( prop ),
25008			optall = jQuery.speed( speed, easing, callback ),
25009			doAnimation = function() {
25010
25011				// Operate on a copy of prop so per-property easing won't be lost
25012				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
25013
25014				// Empty animations, or finishing resolves immediately
25015				if ( empty || jQuery._data( this, "finish" ) ) {
25016					anim.stop( true );
25017				}
25018			};
25019			doAnimation.finish = doAnimation;
25020
25021		return empty || optall.queue === false ?
25022			this.each( doAnimation ) :
25023			this.queue( optall.queue, doAnimation );
25024	},
25025	stop: function( type, clearQueue, gotoEnd ) {
25026		var stopQueue = function( hooks ) {
25027			var stop = hooks.stop;
25028			delete hooks.stop;
25029			stop( gotoEnd );
25030		};
25031
25032		if ( typeof type !== "string" ) {
25033			gotoEnd = clearQueue;
25034			clearQueue = type;
25035			type = undefined;
25036		}
25037		if ( clearQueue && type !== false ) {
25038			this.queue( type || "fx", [] );
25039		}
25040
25041		return this.each( function() {
25042			var dequeue = true,
25043				index = type != null && type + "queueHooks",
25044				timers = jQuery.timers,
25045				data = jQuery._data( this );
25046
25047			if ( index ) {
25048				if ( data[ index ] && data[ index ].stop ) {
25049					stopQueue( data[ index ] );
25050				}
25051			} else {
25052				for ( index in data ) {
25053					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
25054						stopQueue( data[ index ] );
25055					}
25056				}
25057			}
25058
25059			for ( index = timers.length; index--; ) {
25060				if ( timers[ index ].elem === this &&
25061					( type == null || timers[ index ].queue === type ) ) {
25062
25063					timers[ index ].anim.stop( gotoEnd );
25064					dequeue = false;
25065					timers.splice( index, 1 );
25066				}
25067			}
25068
25069			// start the next in the queue if the last step wasn't forced
25070			// timers currently will call their complete callbacks, which will dequeue
25071			// but only if they were gotoEnd
25072			if ( dequeue || !gotoEnd ) {
25073				jQuery.dequeue( this, type );
25074			}
25075		} );
25076	},
25077	finish: function( type ) {
25078		if ( type !== false ) {
25079			type = type || "fx";
25080		}
25081		return this.each( function() {
25082			var index,
25083				data = jQuery._data( this ),
25084				queue = data[ type + "queue" ],
25085				hooks = data[ type + "queueHooks" ],
25086				timers = jQuery.timers,
25087				length = queue ? queue.length : 0;
25088
25089			// enable finishing flag on private data
25090			data.finish = true;
25091
25092			// empty the queue first
25093			jQuery.queue( this, type, [] );
25094
25095			if ( hooks && hooks.stop ) {
25096				hooks.stop.call( this, true );
25097			}
25098
25099			// look for any active animations, and finish them
25100			for ( index = timers.length; index--; ) {
25101				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
25102					timers[ index ].anim.stop( true );
25103					timers.splice( index, 1 );
25104				}
25105			}
25106
25107			// look for any animations in the old queue and finish them
25108			for ( index = 0; index < length; index++ ) {
25109				if ( queue[ index ] && queue[ index ].finish ) {
25110					queue[ index ].finish.call( this );
25111				}
25112			}
25113
25114			// turn off finishing flag
25115			delete data.finish;
25116		} );
25117	}
25118} );
25119
25120jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
25121	var cssFn = jQuery.fn[ name ];
25122	jQuery.fn[ name ] = function( speed, easing, callback ) {
25123		return speed == null || typeof speed === "boolean" ?
25124			cssFn.apply( this, arguments ) :
25125			this.animate( genFx( name, true ), speed, easing, callback );
25126	};
25127} );
25128
25129// Generate shortcuts for custom animations
25130jQuery.each( {
25131	slideDown: genFx( "show" ),
25132	slideUp: genFx( "hide" ),
25133	slideToggle: genFx( "toggle" ),
25134	fadeIn: { opacity: "show" },
25135	fadeOut: { opacity: "hide" },
25136	fadeToggle: { opacity: "toggle" }
25137}, function( name, props ) {
25138	jQuery.fn[ name ] = function( speed, easing, callback ) {
25139		return this.animate( props, speed, easing, callback );
25140	};
25141} );
25142
25143jQuery.timers = [];
25144jQuery.fx.tick = function() {
25145	var timer,
25146		timers = jQuery.timers,
25147		i = 0;
25148
25149	fxNow = jQuery.now();
25150
25151	for ( ; i < timers.length; i++ ) {
25152		timer = timers[ i ];
25153
25154		// Checks the timer has not already been removed
25155		if ( !timer() && timers[ i ] === timer ) {
25156			timers.splice( i--, 1 );
25157		}
25158	}
25159
25160	if ( !timers.length ) {
25161		jQuery.fx.stop();
25162	}
25163	fxNow = undefined;
25164};
25165
25166jQuery.fx.timer = function( timer ) {
25167	jQuery.timers.push( timer );
25168	if ( timer() ) {
25169		jQuery.fx.start();
25170	} else {
25171		jQuery.timers.pop();
25172	}
25173};
25174
25175jQuery.fx.interval = 13;
25176
25177jQuery.fx.start = function() {
25178	if ( !timerId ) {
25179		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
25180	}
25181};
25182
25183jQuery.fx.stop = function() {
25184	window.clearInterval( timerId );
25185	timerId = null;
25186};
25187
25188jQuery.fx.speeds = {
25189	slow: 600,
25190	fast: 200,
25191
25192	// Default speed
25193	_default: 400
25194};
25195
25196
25197// Based off of the plugin by Clint Helfers, with permission.
25198// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
25199jQuery.fn.delay = function( time, type ) {
25200	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
25201	type = type || "fx";
25202
25203	return this.queue( type, function( next, hooks ) {
25204		var timeout = window.setTimeout( next, time );
25205		hooks.stop = function() {
25206			window.clearTimeout( timeout );
25207		};
25208	} );
25209};
25210
25211
25212( function() {
25213	var a,
25214		input = document.createElement( "input" ),
25215		div = document.createElement( "div" ),
25216		select = document.createElement( "select" ),
25217		opt = select.appendChild( document.createElement( "option" ) );
25218
25219	// Setup
25220	div = document.createElement( "div" );
25221	div.setAttribute( "className", "t" );
25222	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
25223	a = div.getElementsByTagName( "a" )[ 0 ];
25224
25225	// Support: Windows Web Apps (WWA)
25226	// `type` must use .setAttribute for WWA (#14901)
25227	input.setAttribute( "type", "checkbox" );
25228	div.appendChild( input );
25229
25230	a = div.getElementsByTagName( "a" )[ 0 ];
25231
25232	// First batch of tests.
25233	a.style.cssText = "top:1px";
25234
25235	// Test setAttribute on camelCase class.
25236	// If it works, we need attrFixes when doing get/setAttribute (ie6/7)
vendor: 2,696 bytes, lines 25237-25338
25237	support.getSetAttribute = div.className !== "t";
25238
25239	// Get the style information from getAttribute
25240	// (IE uses .cssText instead)
25241	support.style = /top/.test( a.getAttribute( "style" ) );
25242
25243	// Make sure that URLs aren't manipulated
25244	// (IE normalizes it by default)
25245	support.hrefNormalized = a.getAttribute( "href" ) === "/a";
25246
25247	// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
25248	support.checkOn = !!input.value;
25249
25250	// Make sure that a selected-by-default option has a working selected property.
25251	// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
25252	support.optSelected = opt.selected;
25253
25254	// Tests for enctype support on a form (#6743)
25255	support.enctype = !!document.createElement( "form" ).enctype;
25256
25257	// Make sure that the options inside disabled selects aren't marked as disabled
25258	// (WebKit marks them as disabled)
25259	select.disabled = true;
25260	support.optDisabled = !opt.disabled;
25261
25262	// Support: IE8 only
25263	// Check if we can trust getAttribute("value")
25264	input = document.createElement( "input" );
25265	input.setAttribute( "value", "" );
25266	support.input = input.getAttribute( "value" ) === "";
25267
25268	// Check if an input maintains its value after becoming a radio
25269	input.value = "t";
25270	input.setAttribute( "type", "radio" );
25271	support.radioValue = input.value === "t";
25272} )();
25273
25274
25275var rreturn = /\r/g,
25276	rspaces = /[\x20\t\r\n\f]+/g;
25277
25278jQuery.fn.extend( {
25279	val: function( value ) {
25280		var hooks, ret, isFunction,
25281			elem = this[ 0 ];
25282
25283		if ( !arguments.length ) {
25284			if ( elem ) {
25285				hooks = jQuery.valHooks[ elem.type ] ||
25286					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
25287
25288				if (
25289					hooks &&
25290					"get" in hooks &&
25291					( ret = hooks.get( elem, "value" ) ) !== undefined
25292				) {
25293					return ret;
25294				}
25295
25296				ret = elem.value;
25297
25298				return typeof ret === "string" ?
25299
25300					// handle most common string cases
25301					ret.replace( rreturn, "" ) :
25302
25303					// handle cases where value is null/undef or number
25304					ret == null ? "" : ret;
25305			}
25306
25307			return;
25308		}
25309
25310		isFunction = jQuery.isFunction( value );
25311
25312		return this.each( function( i ) {
25313			var val;
25314
25315			if ( this.nodeType !== 1 ) {
25316				return;
25317			}
25318
25319			if ( isFunction ) {
25320				val = value.call( this, i, jQuery( this ).val() );
25321			} else {
25322				val = value;
25323			}
25324
25325			// Treat null/undefined as ""; convert numbers to string
25326			if ( val == null ) {
25327				val = "";
25328			} else if ( typeof val === "number" ) {
25329				val += "";
25330			} else if ( jQuery.isArray( val ) ) {
25331				val = jQuery.map( val, function( value ) {
25332					return value == null ? "" : value + "";
25333				} );
25334			}
25335
25336			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
25337
25338			// If set returns undefined, fall back to normal setting
vendor: 4,648 bytes, lines 25339-25529
25339			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
25340				this.value = val;
25341			}
25342		} );
25343	}
25344} );
25345
25346jQuery.extend( {
25347	valHooks: {
25348		option: {
25349			get: function( elem ) {
25350				var val = jQuery.find.attr( elem, "value" );
25351				return val != null ?
25352					val :
25353
25354					// Support: IE10-11+
25355					// option.text throws exceptions (#14686, #14858)
25356					// Strip and collapse whitespace
25357					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
25358					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
25359			}
25360		},
25361		select: {
25362			get: function( elem ) {
25363				var value, option,
25364					options = elem.options,
25365					index = elem.selectedIndex,
25366					one = elem.type === "select-one" || index < 0,
25367					values = one ? null : [],
25368					max = one ? index + 1 : options.length,
25369					i = index < 0 ?
25370						max :
25371						one ? index : 0;
25372
25373				// Loop through all the selected options
25374				for ( ; i < max; i++ ) {
25375					option = options[ i ];
25376
25377					// oldIE doesn't update selected after form reset (#2551)
25378					if ( ( option.selected || i === index ) &&
25379
25380							// Don't return options that are disabled or in a disabled optgroup
25381							( support.optDisabled ?
25382								!option.disabled :
25383								option.getAttribute( "disabled" ) === null ) &&
25384							( !option.parentNode.disabled ||
25385								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
25386
25387						// Get the specific value for the option
25388						value = jQuery( option ).val();
25389
25390						// We don't need an array for one selects
25391						if ( one ) {
25392							return value;
25393						}
25394
25395						// Multi-Selects return an array
25396						values.push( value );
25397					}
25398				}
25399
25400				return values;
25401			},
25402
25403			set: function( elem, value ) {
25404				var optionSet, option,
25405					options = elem.options,
25406					values = jQuery.makeArray( value ),
25407					i = options.length;
25408
25409				while ( i-- ) {
25410					option = options[ i ];
25411
25412					if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
25413
25414						// Support: IE6
25415						// When new option element is added to select box we need to
25416						// force reflow of newly added node in order to workaround delay
25417						// of initialization properties
25418						try {
25419							option.selected = optionSet = true;
25420
25421						} catch ( _ ) {
25422
25423							// Will be executed only in IE6
25424							option.scrollHeight;
25425						}
25426
25427					} else {
25428						option.selected = false;
25429					}
25430				}
25431
25432				// Force browsers to behave consistently when non-matching value is set
25433				if ( !optionSet ) {
25434					elem.selectedIndex = -1;
25435				}
25436
25437				return options;
25438			}
25439		}
25440	}
25441} );
25442
25443// Radios and checkboxes getter/setter
25444jQuery.each( [ "radio", "checkbox" ], function() {
25445	jQuery.valHooks[ this ] = {
25446		set: function( elem, value ) {
25447			if ( jQuery.isArray( value ) ) {
25448				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
25449			}
25450		}
25451	};
25452	if ( !support.checkOn ) {
25453		jQuery.valHooks[ this ].get = function( elem ) {
25454			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
25455		};
25456	}
25457} );
25458
25459
25460
25461
25462var nodeHook, boolHook,
25463	attrHandle = jQuery.expr.attrHandle,
25464	ruseDefault = /^(?:checked|selected)$/i,
25465	getSetAttribute = support.getSetAttribute,
25466	getSetInput = support.input;
25467
25468jQuery.fn.extend( {
25469	attr: function( name, value ) {
25470		return access( this, jQuery.attr, name, value, arguments.length > 1 );
25471	},
25472
25473	removeAttr: function( name ) {
25474		return this.each( function() {
25475			jQuery.removeAttr( this, name );
25476		} );
25477	}
25478} );
25479
25480jQuery.extend( {
25481	attr: function( elem, name, value ) {
25482		var ret, hooks,
25483			nType = elem.nodeType;
25484
25485		// Don't get/set attributes on text, comment and attribute nodes
25486		if ( nType === 3 || nType === 8 || nType === 2 ) {
25487			return;
25488		}
25489
25490		// Fallback to prop when attributes are not supported
25491		if ( typeof elem.getAttribute === "undefined" ) {
25492			return jQuery.prop( elem, name, value );
25493		}
25494
25495		// All attributes are lowercase
25496		// Grab necessary hook if one is defined
25497		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
25498			name = name.toLowerCase();
25499			hooks = jQuery.attrHooks[ name ] ||
25500				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
25501		}
25502
25503		if ( value !== undefined ) {
25504			if ( value === null ) {
25505				jQuery.removeAttr( elem, name );
25506				return;
25507			}
25508
25509			if ( hooks && "set" in hooks &&
25510				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
25511				return ret;
25512			}
25513
25514			elem.setAttribute( name, value + "" );
25515			return value;
25516		}
25517
25518		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
25519			return ret;
25520		}
25521
25522		ret = jQuery.find.attr( elem, name );
25523
25524		// Non-existent attributes return null, we normalize to undefined
25525		return ret == null ? undefined : ret;
25526	},
25527
25528	attrHooks: {
25529		type: {
vendor: 4,457 bytes, lines 25530-25696
25530			set: function( elem, value ) {
25531				if ( !support.radioValue && value === "radio" &&
25532					jQuery.nodeName( elem, "input" ) ) {
25533
25534					// Setting the type on a radio button after the value resets the value in IE8-9
25535					// Reset value to default in case type is set after value during creation
25536					var val = elem.value;
25537					elem.setAttribute( "type", value );
25538					if ( val ) {
25539						elem.value = val;
25540					}
25541					return value;
25542				}
25543			}
25544		}
25545	},
25546
25547	removeAttr: function( elem, value ) {
25548		var name, propName,
25549			i = 0,
25550			attrNames = value && value.match( rnotwhite );
25551
25552		if ( attrNames && elem.nodeType === 1 ) {
25553			while ( ( name = attrNames[ i++ ] ) ) {
25554				propName = jQuery.propFix[ name ] || name;
25555
25556				// Boolean attributes get special treatment (#10870)
25557				if ( jQuery.expr.match.bool.test( name ) ) {
25558
25559					// Set corresponding property to false
25560					if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
25561						elem[ propName ] = false;
25562
25563					// Support: IE<9
25564					// Also clear defaultChecked/defaultSelected (if appropriate)
25565					} else {
25566						elem[ jQuery.camelCase( "default-" + name ) ] =
25567							elem[ propName ] = false;
25568					}
25569
25570				// See #9699 for explanation of this approach (setting first, then removal)
25571				} else {
25572					jQuery.attr( elem, name, "" );
25573				}
25574
25575				elem.removeAttribute( getSetAttribute ? name : propName );
25576			}
25577		}
25578	}
25579} );
25580
25581// Hooks for boolean attributes
25582boolHook = {
25583	set: function( elem, value, name ) {
25584		if ( value === false ) {
25585
25586			// Remove boolean attributes when set to false
25587			jQuery.removeAttr( elem, name );
25588		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
25589
25590			// IE<8 needs the *property* name
25591			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
25592
25593		} else {
25594
25595			// Support: IE<9
25596			// Use defaultChecked and defaultSelected for oldIE
25597			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
25598		}
25599		return name;
25600	}
25601};
25602
25603jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
25604	var getter = attrHandle[ name ] || jQuery.find.attr;
25605
25606	if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
25607		attrHandle[ name ] = function( elem, name, isXML ) {
25608			var ret, handle;
25609			if ( !isXML ) {
25610
25611				// Avoid an infinite loop by temporarily removing this function from the getter
25612				handle = attrHandle[ name ];
25613				attrHandle[ name ] = ret;
25614				ret = getter( elem, name, isXML ) != null ?
25615					name.toLowerCase() :
25616					null;
25617				attrHandle[ name ] = handle;
25618			}
25619			return ret;
25620		};
25621	} else {
25622		attrHandle[ name ] = function( elem, name, isXML ) {
25623			if ( !isXML ) {
25624				return elem[ jQuery.camelCase( "default-" + name ) ] ?
25625					name.toLowerCase() :
25626					null;
25627			}
25628		};
25629	}
25630} );
25631
25632// fix oldIE attroperties
25633if ( !getSetInput || !getSetAttribute ) {
25634	jQuery.attrHooks.value = {
25635		set: function( elem, value, name ) {
25636			if ( jQuery.nodeName( elem, "input" ) ) {
25637
25638				// Does not return so that setAttribute is also used
25639				elem.defaultValue = value;
25640			} else {
25641
25642				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
25643				return nodeHook && nodeHook.set( elem, value, name );
25644			}
25645		}
25646	};
25647}
25648
25649// IE6/7 do not support getting/setting some attributes with get/setAttribute
25650if ( !getSetAttribute ) {
25651
25652	// Use this for any attribute in IE6/7
25653	// This fixes almost every IE6/7 issue
25654	nodeHook = {
25655		set: function( elem, value, name ) {
25656
25657			// Set the existing or create a new attribute node
25658			var ret = elem.getAttributeNode( name );
25659			if ( !ret ) {
25660				elem.setAttributeNode(
25661					( ret = elem.ownerDocument.createAttribute( name ) )
25662				);
25663			}
25664
25665			ret.value = value += "";
25666
25667			// Break association with cloned elements by also using setAttribute (#9646)
25668			if ( name === "value" || value === elem.getAttribute( name ) ) {
25669				return value;
25670			}
25671		}
25672	};
25673
25674	// Some attributes are constructed with empty-string values when not defined
25675	attrHandle.id = attrHandle.name = attrHandle.coords =
25676		function( elem, name, isXML ) {
25677			var ret;
25678			if ( !isXML ) {
25679				return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
25680					ret.value :
25681					null;
25682			}
25683		};
25684
25685	// Fixing value retrieval on a button requires this module
25686	jQuery.valHooks.button = {
25687		get: function( elem, name ) {
25688			var ret = elem.getAttributeNode( name );
25689			if ( ret && ret.specified ) {
25690				return ret.value;
25691			}
25692		},
25693		set: nodeHook.set
25694	};
25695
25696	// Set contenteditable to false on removals(#10429)
25697	// Setting to empty string throws an error as an invalid value
25698	jQuery.attrHooks.contenteditable = {
25699		set: function( elem, value, name ) {
25700			nodeHook.set( elem, value === "" ? false : value, name );
25701		}
25702	};
25703
25704	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
25705	// This is for removals
25706	jQuery.each( [ "width", "height" ], function( i, name ) {
25707		jQuery.attrHooks[ name ] = {
25708			set: function( elem, value ) {
25709				if ( value === "" ) {
25710					elem.setAttribute( name, "auto" );
25711					return value;
25712				}
25713			}
25714		};
25715	} );
25716}
25717
25718if ( !support.style ) {
25719	jQuery.attrHooks.style = {
25720		get: function( elem ) {
25721
25722			// Return undefined in the case of empty string
25723			// Note: IE uppercases css property names, but if we were to .toLowerCase()
25724			// .cssText, that would destroy case sensitivity in URL's, like in "background"
25725			return elem.style.cssText || undefined;
25726		},
25727		set: function( elem, value ) {
25728			return ( elem.style.cssText = value + "" );
25729		}
25730	};
25731}
25732
25733
25734
25735
25736var rfocusable = /^(?:input|select|textarea|button|object)$/i,
25737	rclickable = /^(?:a|area)$/i;
25738
25739jQuery.fn.extend( {
25740	prop: function( name, value ) {
25741		return access( this, jQuery.prop, name, value, arguments.length > 1 );
25742	},
25743
25744	removeProp: function( name ) {
25745		name = jQuery.propFix[ name ] || name;
25746		return this.each( function() {
25747
25748			// try/catch handles cases where IE balks (such as removing a property on window)
25749			try {
25750				this[ name ] = undefined;
25751				delete this[ name ];
25752			} catch ( e ) {}
25753		} );
25754	}
25755} );
25756
25757jQuery.extend( {
25758	prop: function( elem, name, value ) {
25759		var ret, hooks,
25760			nType = elem.nodeType;
25761
25762		// Don't get/set properties on text, comment and attribute nodes
25763		if ( nType === 3 || nType === 8 || nType === 2 ) {
25764			return;
25765		}
25766
25767		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
25768
25769			// Fix name and attach hooks
25770			name = jQuery.propFix[ name ] || name;
25771			hooks = jQuery.propHooks[ name ];
25772		}
25773
25774		if ( value !== undefined ) {
25775			if ( hooks && "set" in hooks &&
25776				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
25777				return ret;
25778			}
25779
25780			return ( elem[ name ] = value );
25781		}
25782
25783		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
25784			return ret;
25785		}
25786
25787		return elem[ name ];
25788	},
25789
25790	propHooks: {
25791		tabIndex: {
25792			get: function( elem ) {
25793
25794				// elem.tabIndex doesn't always return the
25795				// correct value when it hasn't been explicitly set
25796				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
25797				// Use proper attribute retrieval(#12072)
25798				var tabindex = jQuery.find.attr( elem, "tabindex" );
25799
25800				return tabindex ?
25801					parseInt( tabindex, 10 ) :
25802					rfocusable.test( elem.nodeName ) ||
25803						rclickable.test( elem.nodeName ) && elem.href ?
25804							0 :
25805							-1;
25806			}
25807		}
25808	},
25809
25810	propFix: {
25811		"for": "htmlFor",
25812		"class": "className"
25813	}
25814} );
25815
25816// Some attributes require a special call on IE
25817// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
25818if ( !support.hrefNormalized ) {
25819
25820	// href/src property should get the full normalized URL (#10299/#12915)
25821	jQuery.each( [ "href", "src" ], function( i, name ) {
25822		jQuery.propHooks[ name ] = {
25823			get: function( elem ) {
25824				return elem.getAttribute( name, 4 );
25825			}
25826		};
25827	} );
25828}
25829
25830// Support: Safari, IE9+
25831// Accessing the selectedIndex property
25832// forces the browser to respect setting selected
25833// on the option
25834// The getter ensures a default option is selected
25835// when in an optgroup
25836if ( !support.optSelected ) {
25837	jQuery.propHooks.selected = {
25838		get: function( elem ) {
25839			var parent = elem.parentNode;
25840
25841			if ( parent ) {
25842				parent.selectedIndex;
25843
25844				// Make sure that it also works with optgroups, see #5701
25845				if ( parent.parentNode ) {
25846					parent.parentNode.selectedIndex;
25847				}
25848			}
25849			return null;
25850		},
25851		set: function( elem ) {
25852			var parent = elem.parentNode;
25853			if ( parent ) {
25854				parent.selectedIndex;
25855
25856				if ( parent.parentNode ) {
25857					parent.parentNode.selectedIndex;
25858				}
25859			}
25860		}
25861	};
25862}
25863
25864jQuery.each( [
25865	"tabIndex",
25866	"readOnly",
25867	"maxLength",
25868	"cellSpacing",
25869	"cellPadding",
25870	"rowSpan",
25871	"colSpan",
25872	"useMap",
25873	"frameBorder",
25874	"contentEditable"
25875], function() {
25876	jQuery.propFix[ this.toLowerCase() ] = this;
25877} );
25878
25879// IE6/7 call enctype encoding
25880if ( !support.enctype ) {
25881	jQuery.propFix.enctype = "encoding";
25882}
25883
25884
25885
25886
25887var rclass = /[\t\r\n\f]/g;
25888
25889function getClass( elem ) {
25890	return jQuery.attr( elem, "class" ) || "";
25891}
25892
25893jQuery.fn.extend( {
25894	addClass: function( value ) {
25895		var classes, elem, cur, curValue, clazz, j, finalValue,
25896			i = 0;
25897
25898		if ( jQuery.isFunction( value ) ) {
25899			return this.each( function( j ) {
25900				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
25901			} );
25902		}
25903
25904		if ( typeof value === "string" && value ) {
25905			classes = value.match( rnotwhite ) || [];
25906
25907			while ( ( elem = this[ i++ ] ) ) {
25908				curValue = getClass( elem );
25909				cur = elem.nodeType === 1 &&
25910					( " " + curValue + " " ).replace( rclass, " " );
25911
25912				if ( cur ) {
25913					j = 0;
25914					while ( ( clazz = classes[ j++ ] ) ) {
25915						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
25916							cur += clazz + " ";
25917						}
25918					}
25919
25920					// only assign if different to avoid unneeded rendering.
25921					finalValue = jQuery.trim( cur );
25922					if ( curValue !== finalValue ) {
25923						jQuery.attr( elem, "class", finalValue );
25924					}
25925				}
25926			}
25927		}
25928
25929		return this;
25930	},
25931
25932	removeClass: function( value ) {
25933		var classes, elem, cur, curValue, clazz, j, finalValue,
25934			i = 0;
25935
25936		if ( jQuery.isFunction( value ) ) {
25937			return this.each( function( j ) {
25938				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
25939			} );
25940		}
25941
25942		if ( !arguments.length ) {
25943			return this.attr( "class", "" );
25944		}
25945
25946		if ( typeof value === "string" && value ) {
25947			classes = value.match( rnotwhite ) || [];
25948
25949			while ( ( elem = this[ i++ ] ) ) {
25950				curValue = getClass( elem );
25951
25952				// This expression is here for better compressibility (see addClass)
25953				cur = elem.nodeType === 1 &&
25954					( " " + curValue + " " ).replace( rclass, " " );
25955
25956				if ( cur ) {
25957					j = 0;
25958					while ( ( clazz = classes[ j++ ] ) ) {
25959
25960						// Remove *all* instances
25961						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
25962							cur = cur.replace( " " + clazz + " ", " " );
25963						}
25964					}
25965
25966					// Only assign if different to avoid unneeded rendering.
25967					finalValue = jQuery.trim( cur );
25968					if ( curValue !== finalValue ) {
25969						jQuery.attr( elem, "class", finalValue );
25970					}
25971				}
25972			}
25973		}
25974
25975		return this;
25976	},
25977
25978	toggleClass: function( value, stateVal ) {
25979		var type = typeof value;
25980
25981		if ( typeof stateVal === "boolean" && type === "string" ) {
25982			return stateVal ? this.addClass( value ) : this.removeClass( value );
25983		}
25984
25985		if ( jQuery.isFunction( value ) ) {
25986			return this.each( function( i ) {
25987				jQuery( this ).toggleClass(
25988					value.call( this, i, getClass( this ), stateVal ),
25989					stateVal
25990				);
25991			} );
25992		}
25993
25994		return this.each( function() {
25995			var className, i, self, classNames;
25996
25997			if ( type === "string" ) {
25998
25999				// Toggle individual class names
26000				i = 0;
26001				self = jQuery( this );
26002				classNames = value.match( rnotwhite ) || [];
26003
26004				while ( ( className = classNames[ i++ ] ) ) {
26005
26006					// Check each className given, space separated list
26007					if ( self.hasClass( className ) ) {
26008						self.removeClass( className );
26009					} else {
26010						self.addClass( className );
26011					}
26012				}
26013
26014			// Toggle whole class name
26015			} else if ( value === undefined || type === "boolean" ) {
26016				className = getClass( this );
26017				if ( className ) {
26018
26019					// store className if set
26020					jQuery._data( this, "__className__", className );
26021				}
26022
26023				// If the element has a class name or if we're passed "false",
26024				// then remove the whole classname (if there was one, the above saved it).
26025				// Otherwise bring back whatever was previously saved (if anything),
26026				// falling back to the empty string if nothing was stored.
26027				jQuery.attr( this, "class",
26028					className || value === false ?
26029					"" :
26030					jQuery._data( this, "__className__" ) || ""
26031				);
26032			}
26033		} );
26034	},
26035
26036	hasClass: function( selector ) {
26037		var className, elem,
26038			i = 0;
26039
26040		className = " " + selector + " ";
26041		while ( ( elem = this[ i++ ] ) ) {
26042			if ( elem.nodeType === 1 &&
26043				( " " + getClass( elem ) + " " ).replace( rclass, " " )
26044					.indexOf( className ) > -1
26045			) {
26046				return true;
26047			}
26048		}
26049
26050		return false;
26051	}
26052} );
26053
26054
26055
26056
26057// Return jQuery for attributes-only inclusion
26058
26059
26060jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
26061	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
26062	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
26063	function( i, name ) {
26064
26065	// Handle event binding
26066	jQuery.fn[ name ] = function( data, fn ) {
26067		return arguments.length > 0 ?
26068			this.on( name, null, data, fn ) :
26069			this.trigger( name );
26070	};
26071} );
26072
26073jQuery.fn.extend( {
26074	hover: function( fnOver, fnOut ) {
26075		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
26076	}
26077} );
26078
26079
26080var location = window.location;
26081
26082var nonce = jQuery.now();
26083
26084var rquery = ( /\?/ );
26085
26086
26087
26088var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
26089
26090jQuery.parseJSON = function( data ) {
26091
26092	// Attempt to parse using the native JSON parser first
26093	if ( window.JSON && window.JSON.parse ) {
26094
26095		// Support: Android 2.3
26096		// Workaround failure to string-cast null input
26097		return window.JSON.parse( data + "" );
26098	}
26099
26100	var requireNonComma,
26101		depth = null,
26102		str = jQuery.trim( data + "" );
26103
26104	// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
26105	// after removing valid tokens
26106	return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
26107
26108		// Force termination if we see a misplaced comma
26109		if ( requireNonComma && comma ) {
26110			depth = 0;
26111		}
26112
26113		// Perform no more replacements after returning to outermost depth
26114		if ( depth === 0 ) {
26115			return token;
26116		}
26117
26118		// Commas must not follow "[", "{", or ","
26119		requireNonComma = open || comma;
26120
26121		// Determine new depth
26122		// array/object open ("[" or "{"): depth += true - false (increment)
26123		// array/object close ("]" or "}"): depth += false - true (decrement)
26124		// other cases ("," or primitive): depth += true - true (numeric cast)
26125		depth += !close - !open;
26126
26127		// Remove this token
26128		return "";
26129	} ) ) ?
26130		( Function( "return " + str ) )() :
26131		jQuery.error( "Invalid JSON: " + data );
26132};
26133
26134
26135// Cross-browser xml parsing
vendor: 10,393 bytes, lines 26136-26541
26136jQuery.parseXML = function( data ) {
26137	var xml, tmp;
26138	if ( !data || typeof data !== "string" ) {
26139		return null;
26140	}
26141	try {
26142		if ( window.DOMParser ) { // Standard
26143			tmp = new window.DOMParser();
26144			xml = tmp.parseFromString( data, "text/xml" );
26145		} else { // IE
26146			xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
26147			xml.async = "false";
26148			xml.loadXML( data );
26149		}
26150	} catch ( e ) {
26151		xml = undefined;
26152	}
26153	if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
26154		jQuery.error( "Invalid XML: " + data );
26155	}
26156	return xml;
26157};
26158
26159
26160var
26161	rhash = /#.*$/,
26162	rts = /([?&])_=[^&]*/,
26163
26164	// IE leaves an \r character at EOL
26165	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
26166
26167	// #7653, #8125, #8152: local protocol detection
26168	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
26169	rnoContent = /^(?:GET|HEAD)$/,
26170	rprotocol = /^\/\//,
26171	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
26172
26173	/* Prefilters
26174	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
26175	 * 2) These are called:
26176	 *    - BEFORE asking for a transport
26177	 *    - AFTER param serialization (s.data is a string if s.processData is true)
26178	 * 3) key is the dataType
26179	 * 4) the catchall symbol "*" can be used
26180	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
26181	 */
26182	prefilters = {},
26183
26184	/* Transports bindings
26185	 * 1) key is the dataType
26186	 * 2) the catchall symbol "*" can be used
26187	 * 3) selection will start with transport dataType and THEN go to "*" if needed
26188	 */
26189	transports = {},
26190
26191	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
26192	allTypes = "*/".concat( "*" ),
26193
26194	// Document location
26195	ajaxLocation = location.href,
26196
26197	// Segment location into parts
26198	ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
26199
26200// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
26201function addToPrefiltersOrTransports( structure ) {
26202
26203	// dataTypeExpression is optional and defaults to "*"
26204	return function( dataTypeExpression, func ) {
26205
26206		if ( typeof dataTypeExpression !== "string" ) {
26207			func = dataTypeExpression;
26208			dataTypeExpression = "*";
26209		}
26210
26211		var dataType,
26212			i = 0,
26213			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
26214
26215		if ( jQuery.isFunction( func ) ) {
26216
26217			// For each dataType in the dataTypeExpression
26218			while ( ( dataType = dataTypes[ i++ ] ) ) {
26219
26220				// Prepend if requested
26221				if ( dataType.charAt( 0 ) === "+" ) {
26222					dataType = dataType.slice( 1 ) || "*";
26223					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
26224
26225				// Otherwise append
26226				} else {
26227					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
26228				}
26229			}
26230		}
26231	};
26232}
26233
26234// Base inspection function for prefilters and transports
26235function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
26236
26237	var inspected = {},
26238		seekingTransport = ( structure === transports );
26239
26240	function inspect( dataType ) {
26241		var selected;
26242		inspected[ dataType ] = true;
26243		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
26244			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
26245			if ( typeof dataTypeOrTransport === "string" &&
26246				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
26247
26248				options.dataTypes.unshift( dataTypeOrTransport );
26249				inspect( dataTypeOrTransport );
26250				return false;
26251			} else if ( seekingTransport ) {
26252				return !( selected = dataTypeOrTransport );
26253			}
26254		} );
26255		return selected;
26256	}
26257
26258	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
26259}
26260
26261// A special extend for ajax options
26262// that takes "flat" options (not to be deep extended)
26263// Fixes #9887
26264function ajaxExtend( target, src ) {
26265	var deep, key,
26266		flatOptions = jQuery.ajaxSettings.flatOptions || {};
26267
26268	for ( key in src ) {
26269		if ( src[ key ] !== undefined ) {
26270			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
26271		}
26272	}
26273	if ( deep ) {
26274		jQuery.extend( true, target, deep );
26275	}
26276
26277	return target;
26278}
26279
26280/* Handles responses to an ajax request:
26281 * - finds the right dataType (mediates between content-type and expected dataType)
26282 * - returns the corresponding response
26283 */
26284function ajaxHandleResponses( s, jqXHR, responses ) {
26285	var firstDataType, ct, finalDataType, type,
26286		contents = s.contents,
26287		dataTypes = s.dataTypes;
26288
26289	// Remove auto dataType and get content-type in the process
26290	while ( dataTypes[ 0 ] === "*" ) {
26291		dataTypes.shift();
26292		if ( ct === undefined ) {
26293			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
26294		}
26295	}
26296
26297	// Check if we're dealing with a known content-type
26298	if ( ct ) {
26299		for ( type in contents ) {
26300			if ( contents[ type ] && contents[ type ].test( ct ) ) {
26301				dataTypes.unshift( type );
26302				break;
26303			}
26304		}
26305	}
26306
26307	// Check to see if we have a response for the expected dataType
26308	if ( dataTypes[ 0 ] in responses ) {
26309		finalDataType = dataTypes[ 0 ];
26310	} else {
26311
26312		// Try convertible dataTypes
26313		for ( type in responses ) {
26314			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
26315				finalDataType = type;
26316				break;
26317			}
26318			if ( !firstDataType ) {
26319				firstDataType = type;
26320			}
26321		}
26322
26323		// Or just use first one
26324		finalDataType = finalDataType || firstDataType;
26325	}
26326
26327	// If we found a dataType
26328	// We add the dataType to the list if needed
26329	// and return the corresponding response
26330	if ( finalDataType ) {
26331		if ( finalDataType !== dataTypes[ 0 ] ) {
26332			dataTypes.unshift( finalDataType );
26333		}
26334		return responses[ finalDataType ];
26335	}
26336}
26337
26338/* Chain conversions given the request and the original response
26339 * Also sets the responseXXX fields on the jqXHR instance
26340 */
26341function ajaxConvert( s, response, jqXHR, isSuccess ) {
26342	var conv2, current, conv, tmp, prev,
26343		converters = {},
26344
26345		// Work with a copy of dataTypes in case we need to modify it for conversion
26346		dataTypes = s.dataTypes.slice();
26347
26348	// Create converters map with lowercased keys
26349	if ( dataTypes[ 1 ] ) {
26350		for ( conv in s.converters ) {
26351			converters[ conv.toLowerCase() ] = s.converters[ conv ];
26352		}
26353	}
26354
26355	current = dataTypes.shift();
26356
26357	// Convert to each sequential dataType
26358	while ( current ) {
26359
26360		if ( s.responseFields[ current ] ) {
26361			jqXHR[ s.responseFields[ current ] ] = response;
26362		}
26363
26364		// Apply the dataFilter if provided
26365		if ( !prev && isSuccess && s.dataFilter ) {
26366			response = s.dataFilter( response, s.dataType );
26367		}
26368
26369		prev = current;
26370		current = dataTypes.shift();
26371
26372		if ( current ) {
26373
26374			// There's only work to do if current dataType is non-auto
26375			if ( current === "*" ) {
26376
26377				current = prev;
26378
26379			// Convert response if prev dataType is non-auto and differs from current
26380			} else if ( prev !== "*" && prev !== current ) {
26381
26382				// Seek a direct converter
26383				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
26384
26385				// If none found, seek a pair
26386				if ( !conv ) {
26387					for ( conv2 in converters ) {
26388
26389						// If conv2 outputs current
26390						tmp = conv2.split( " " );
26391						if ( tmp[ 1 ] === current ) {
26392
26393							// If prev can be converted to accepted input
26394							conv = converters[ prev + " " + tmp[ 0 ] ] ||
26395								converters[ "* " + tmp[ 0 ] ];
26396							if ( conv ) {
26397
26398								// Condense equivalence converters
26399								if ( conv === true ) {
26400									conv = converters[ conv2 ];
26401
26402								// Otherwise, insert the intermediate dataType
26403								} else if ( converters[ conv2 ] !== true ) {
26404									current = tmp[ 0 ];
26405									dataTypes.unshift( tmp[ 1 ] );
26406								}
26407								break;
26408							}
26409						}
26410					}
26411				}
26412
26413				// Apply converter (if not an equivalence)
26414				if ( conv !== true ) {
26415
26416					// Unless errors are allowed to bubble, catch and return them
26417					if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
26418						response = conv( response );
26419					} else {
26420						try {
26421							response = conv( response );
26422						} catch ( e ) {
26423							return {
26424								state: "parsererror",
26425								error: conv ? e : "No conversion from " + prev + " to " + current
26426							};
26427						}
26428					}
26429				}
26430			}
26431		}
26432	}
26433
26434	return { state: "success", data: response };
26435}
26436
26437jQuery.extend( {
26438
26439	// Counter for holding the number of active queries
26440	active: 0,
26441
26442	// Last-Modified header cache for next request
26443	lastModified: {},
26444	etag: {},
26445
26446	ajaxSettings: {
26447		url: ajaxLocation,
26448		type: "GET",
26449		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
26450		global: true,
26451		processData: true,
26452		async: true,
26453		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
26454		/*
26455		timeout: 0,
26456		data: null,
26457		dataType: null,
26458		username: null,
26459		password: null,
26460		cache: null,
26461		throws: false,
26462		traditional: false,
26463		headers: {},
26464		*/
26465
26466		accepts: {
26467			"*": allTypes,
26468			text: "text/plain",
26469			html: "text/html",
26470			xml: "application/xml, text/xml",
26471			json: "application/json, text/javascript"
26472		},
26473
26474		contents: {
26475			xml: /\bxml\b/,
26476			html: /\bhtml/,
26477			json: /\bjson\b/
26478		},
26479
26480		responseFields: {
26481			xml: "responseXML",
26482			text: "responseText",
26483			json: "responseJSON"
26484		},
26485
26486		// Data converters
26487		// Keys separate source (or catchall "*") and destination types with a single space
26488		converters: {
26489
26490			// Convert anything to text
26491			"* text": String,
26492
26493			// Text to html (true = no transformation)
26494			"text html": true,
26495
26496			// Evaluate text as a json expression
26497			"text json": jQuery.parseJSON,
26498
26499			// Parse text as xml
26500			"text xml": jQuery.parseXML
26501		},
26502
26503		// For options that shouldn't be deep extended:
26504		// you can add your own custom options here if
26505		// and when you create one that shouldn't be
26506		// deep extended (see ajaxExtend)
26507		flatOptions: {
26508			url: true,
26509			context: true
26510		}
26511	},
26512
26513	// Creates a full fledged settings object into target
26514	// with both ajaxSettings and settings fields.
26515	// If target is omitted, writes into ajaxSettings.
26516	ajaxSetup: function( target, settings ) {
26517		return settings ?
26518
26519			// Building a settings object
26520			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
26521
26522			// Extending ajaxSettings
26523			ajaxExtend( jQuery.ajaxSettings, target );
26524	},
26525
26526	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
26527	ajaxTransport: addToPrefiltersOrTransports( transports ),
26528
26529	// Main method
26530	ajax: function( url, options ) {
26531
26532		// If url is an object, simulate pre-1.5 signature
26533		if ( typeof url === "object" ) {
26534			options = url;
26535			url = undefined;
26536		}
26537
26538		// Force options to be an object
26539		options = options || {};
26540
26541		var
vendor: 5,146 bytes, lines 26542-26732
26542
26543			// Cross-domain detection vars
26544			parts,
26545
26546			// Loop variable
26547			i,
26548
26549			// URL without anti-cache param
26550			cacheURL,
26551
26552			// Response headers as string
26553			responseHeadersString,
26554
26555			// timeout handle
26556			timeoutTimer,
26557
26558			// To know if global events are to be dispatched
26559			fireGlobals,
26560
26561			transport,
26562
26563			// Response headers
26564			responseHeaders,
26565
26566			// Create the final options object
26567			s = jQuery.ajaxSetup( {}, options ),
26568
26569			// Callbacks context
26570			callbackContext = s.context || s,
26571
26572			// Context for global events is callbackContext if it is a DOM node or jQuery collection
26573			globalEventContext = s.context &&
26574				( callbackContext.nodeType || callbackContext.jquery ) ?
26575					jQuery( callbackContext ) :
26576					jQuery.event,
26577
26578			// Deferreds
26579			deferred = jQuery.Deferred(),
26580			completeDeferred = jQuery.Callbacks( "once memory" ),
26581
26582			// Status-dependent callbacks
26583			statusCode = s.statusCode || {},
26584
26585			// Headers (they are sent all at once)
26586			requestHeaders = {},
26587			requestHeadersNames = {},
26588
26589			// The jqXHR state
26590			state = 0,
26591
26592			// Default abort message
26593			strAbort = "canceled",
26594
26595			// Fake xhr
26596			jqXHR = {
26597				readyState: 0,
26598
26599				// Builds headers hashtable if needed
26600				getResponseHeader: function( key ) {
26601					var match;
26602					if ( state === 2 ) {
26603						if ( !responseHeaders ) {
26604							responseHeaders = {};
26605							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
26606								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
26607							}
26608						}
26609						match = responseHeaders[ key.toLowerCase() ];
26610					}
26611					return match == null ? null : match;
26612				},
26613
26614				// Raw string
26615				getAllResponseHeaders: function() {
26616					return state === 2 ? responseHeadersString : null;
26617				},
26618
26619				// Caches the header
26620				setRequestHeader: function( name, value ) {
26621					var lname = name.toLowerCase();
26622					if ( !state ) {
26623						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
26624						requestHeaders[ name ] = value;
26625					}
26626					return this;
26627				},
26628
26629				// Overrides response content-type header
26630				overrideMimeType: function( type ) {
26631					if ( !state ) {
26632						s.mimeType = type;
26633					}
26634					return this;
26635				},
26636
26637				// Status-dependent callbacks
26638				statusCode: function( map ) {
26639					var code;
26640					if ( map ) {
26641						if ( state < 2 ) {
26642							for ( code in map ) {
26643
26644								// Lazy-add the new callback in a way that preserves old ones
26645								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
26646							}
26647						} else {
26648
26649							// Execute the appropriate callbacks
26650							jqXHR.always( map[ jqXHR.status ] );
26651						}
26652					}
26653					return this;
26654				},
26655
26656				// Cancel the request
26657				abort: function( statusText ) {
26658					var finalText = statusText || strAbort;
26659					if ( transport ) {
26660						transport.abort( finalText );
26661					}
26662					done( 0, finalText );
26663					return this;
26664				}
26665			};
26666
26667		// Attach deferreds
26668		deferred.promise( jqXHR ).complete = completeDeferred.add;
26669		jqXHR.success = jqXHR.done;
26670		jqXHR.error = jqXHR.fail;
26671
26672		// Remove hash character (#7531: and string promotion)
26673		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
26674		// Handle falsy url in the settings object (#10093: consistency with old signature)
26675		// We also use the url parameter if available
26676		s.url = ( ( url || s.url || ajaxLocation ) + "" )
26677			.replace( rhash, "" )
26678			.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
26679
26680		// Alias method option to type as per ticket #12004
26681		s.type = options.method || options.type || s.method || s.type;
26682
26683		// Extract dataTypes list
26684		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
26685
26686		// A cross-domain request is in order when we have a protocol:host:port mismatch
26687		if ( s.crossDomain == null ) {
26688			parts = rurl.exec( s.url.toLowerCase() );
26689			s.crossDomain = !!( parts &&
26690				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
26691					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
26692						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
26693			);
26694		}
26695
26696		// Convert data if not already a string
26697		if ( s.data && s.processData && typeof s.data !== "string" ) {
26698			s.data = jQuery.param( s.data, s.traditional );
26699		}
26700
26701		// Apply prefilters
26702		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
26703
26704		// If request was aborted inside a prefilter, stop there
26705		if ( state === 2 ) {
26706			return jqXHR;
26707		}
26708
26709		// We can fire global events as of now if asked to
26710		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
26711		fireGlobals = jQuery.event && s.global;
26712
26713		// Watch for a new set of requests
26714		if ( fireGlobals && jQuery.active++ === 0 ) {
26715			jQuery.event.trigger( "ajaxStart" );
26716		}
26717
26718		// Uppercase the type
26719		s.type = s.type.toUpperCase();
26720
26721		// Determine if request has content
26722		s.hasContent = !rnoContent.test( s.type );
26723
26724		// Save the URL in case we're toying with the If-Modified-Since
26725		// and/or If-None-Match header later on
26726		cacheURL = s.url;
26727
26728		// More options handling for requests with no content
26729		if ( !s.hasContent ) {
26730
26731			// If data is available, append data to url
26732			if ( s.data ) {
vendor: 8,244 bytes, lines 26733-27072
26733				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
26734
26735				// #9682: remove data so that it's not used in an eventual retry
26736				delete s.data;
26737			}
26738
26739			// Add anti-cache in url if needed
26740			if ( s.cache === false ) {
26741				s.url = rts.test( cacheURL ) ?
26742
26743					// If there is already a '_' parameter, set its value
26744					cacheURL.replace( rts, "$1_=" + nonce++ ) :
26745
26746					// Otherwise add one to the end
26747					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
26748			}
26749		}
26750
26751		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
26752		if ( s.ifModified ) {
26753			if ( jQuery.lastModified[ cacheURL ] ) {
26754				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
26755			}
26756			if ( jQuery.etag[ cacheURL ] ) {
26757				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
26758			}
26759		}
26760
26761		// Set the correct header, if data is being sent
26762		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
26763			jqXHR.setRequestHeader( "Content-Type", s.contentType );
26764		}
26765
26766		// Set the Accepts header for the server, depending on the dataType
26767		jqXHR.setRequestHeader(
26768			"Accept",
26769			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
26770				s.accepts[ s.dataTypes[ 0 ] ] +
26771					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
26772				s.accepts[ "*" ]
26773		);
26774
26775		// Check for headers option
26776		for ( i in s.headers ) {
26777			jqXHR.setRequestHeader( i, s.headers[ i ] );
26778		}
26779
26780		// Allow custom headers/mimetypes and early abort
26781		if ( s.beforeSend &&
26782			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
26783
26784			// Abort if not done already and return
26785			return jqXHR.abort();
26786		}
26787
26788		// aborting is no longer a cancellation
26789		strAbort = "abort";
26790
26791		// Install callbacks on deferreds
26792		for ( i in { success: 1, error: 1, complete: 1 } ) {
26793			jqXHR[ i ]( s[ i ] );
26794		}
26795
26796		// Get transport
26797		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
26798
26799		// If no transport, we auto-abort
26800		if ( !transport ) {
26801			done( -1, "No Transport" );
26802		} else {
26803			jqXHR.readyState = 1;
26804
26805			// Send global event
26806			if ( fireGlobals ) {
26807				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
26808			}
26809
26810			// If request was aborted inside ajaxSend, stop there
26811			if ( state === 2 ) {
26812				return jqXHR;
26813			}
26814
26815			// Timeout
26816			if ( s.async && s.timeout > 0 ) {
26817				timeoutTimer = window.setTimeout( function() {
26818					jqXHR.abort( "timeout" );
26819				}, s.timeout );
26820			}
26821
26822			try {
26823				state = 1;
26824				transport.send( requestHeaders, done );
26825			} catch ( e ) {
26826
26827				// Propagate exception as error if not done
26828				if ( state < 2 ) {
26829					done( -1, e );
26830
26831				// Simply rethrow otherwise
26832				} else {
26833					throw e;
26834				}
26835			}
26836		}
26837
26838		// Callback for when everything is done
26839		function done( status, nativeStatusText, responses, headers ) {
26840			var isSuccess, success, error, response, modified,
26841				statusText = nativeStatusText;
26842
26843			// Called once
26844			if ( state === 2 ) {
26845				return;
26846			}
26847
26848			// State is "done" now
26849			state = 2;
26850
26851			// Clear timeout if it exists
26852			if ( timeoutTimer ) {
26853				window.clearTimeout( timeoutTimer );
26854			}
26855
26856			// Dereference transport for early garbage collection
26857			// (no matter how long the jqXHR object will be used)
26858			transport = undefined;
26859
26860			// Cache response headers
26861			responseHeadersString = headers || "";
26862
26863			// Set readyState
26864			jqXHR.readyState = status > 0 ? 4 : 0;
26865
26866			// Determine if successful
26867			isSuccess = status >= 200 && status < 300 || status === 304;
26868
26869			// Get response data
26870			if ( responses ) {
26871				response = ajaxHandleResponses( s, jqXHR, responses );
26872			}
26873
26874			// Convert no matter what (that way responseXXX fields are always set)
26875			response = ajaxConvert( s, response, jqXHR, isSuccess );
26876
26877			// If successful, handle type chaining
26878			if ( isSuccess ) {
26879
26880				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
26881				if ( s.ifModified ) {
26882					modified = jqXHR.getResponseHeader( "Last-Modified" );
26883					if ( modified ) {
26884						jQuery.lastModified[ cacheURL ] = modified;
26885					}
26886					modified = jqXHR.getResponseHeader( "etag" );
26887					if ( modified ) {
26888						jQuery.etag[ cacheURL ] = modified;
26889					}
26890				}
26891
26892				// if no content
26893				if ( status === 204 || s.type === "HEAD" ) {
26894					statusText = "nocontent";
26895
26896				// if not modified
26897				} else if ( status === 304 ) {
26898					statusText = "notmodified";
26899
26900				// If we have data, let's convert it
26901				} else {
26902					statusText = response.state;
26903					success = response.data;
26904					error = response.error;
26905					isSuccess = !error;
26906				}
26907			} else {
26908
26909				// We extract error from statusText
26910				// then normalize statusText and status for non-aborts
26911				error = statusText;
26912				if ( status || !statusText ) {
26913					statusText = "error";
26914					if ( status < 0 ) {
26915						status = 0;
26916					}
26917				}
26918			}
26919
26920			// Set data for the fake xhr object
26921			jqXHR.status = status;
26922			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
26923
26924			// Success/Error
26925			if ( isSuccess ) {
26926				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
26927			} else {
26928				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
26929			}
26930
26931			// Status-dependent callbacks
26932			jqXHR.statusCode( statusCode );
26933			statusCode = undefined;
26934
26935			if ( fireGlobals ) {
26936				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
26937					[ jqXHR, s, isSuccess ? success : error ] );
26938			}
26939
26940			// Complete
26941			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
26942
26943			if ( fireGlobals ) {
26944				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
26945
26946				// Handle the global AJAX counter
26947				if ( !( --jQuery.active ) ) {
26948					jQuery.event.trigger( "ajaxStop" );
26949				}
26950			}
26951		}
26952
26953		return jqXHR;
26954	},
26955
26956	getJSON: function( url, data, callback ) {
26957		return jQuery.get( url, data, callback, "json" );
26958	},
26959
26960	getScript: function( url, callback ) {
26961		return jQuery.get( url, undefined, callback, "script" );
26962	}
26963} );
26964
26965jQuery.each( [ "get", "post" ], function( i, method ) {
26966	jQuery[ method ] = function( url, data, callback, type ) {
26967
26968		// shift arguments if data argument was omitted
26969		if ( jQuery.isFunction( data ) ) {
26970			type = type || callback;
26971			callback = data;
26972			data = undefined;
26973		}
26974
26975		// The url can be an options object (which then must have .url)
26976		return jQuery.ajax( jQuery.extend( {
26977			url: url,
26978			type: method,
26979			dataType: type,
26980			data: data,
26981			success: callback
26982		}, jQuery.isPlainObject( url ) && url ) );
26983	};
26984} );
26985
26986
26987jQuery._evalUrl = function( url ) {
26988	return jQuery.ajax( {
26989		url: url,
26990
26991		// Make this explicit, since user can override this through ajaxSetup (#11264)
26992		type: "GET",
26993		dataType: "script",
26994		cache: true,
26995		async: false,
26996		global: false,
26997		"throws": true
26998	} );
26999};
27000
27001
27002jQuery.fn.extend( {
27003	wrapAll: function( html ) {
27004		if ( jQuery.isFunction( html ) ) {
27005			return this.each( function( i ) {
27006				jQuery( this ).wrapAll( html.call( this, i ) );
27007			} );
27008		}
27009
27010		if ( this[ 0 ] ) {
27011
27012			// The elements to wrap the target around
27013			var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
27014
27015			if ( this[ 0 ].parentNode ) {
27016				wrap.insertBefore( this[ 0 ] );
27017			}
27018
27019			wrap.map( function() {
27020				var elem = this;
27021
27022				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
27023					elem = elem.firstChild;
27024				}
27025
27026				return elem;
27027			} ).append( this );
27028		}
27029
27030		return this;
27031	},
27032
27033	wrapInner: function( html ) {
27034		if ( jQuery.isFunction( html ) ) {
27035			return this.each( function( i ) {
27036				jQuery( this ).wrapInner( html.call( this, i ) );
27037			} );
27038		}
27039
27040		return this.each( function() {
27041			var self = jQuery( this ),
27042				contents = self.contents();
27043
27044			if ( contents.length ) {
27045				contents.wrapAll( html );
27046
27047			} else {
27048				self.append( html );
27049			}
27050		} );
27051	},
27052
27053	wrap: function( html ) {
27054		var isFunction = jQuery.isFunction( html );
27055
27056		return this.each( function( i ) {
27057			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
27058		} );
27059	},
27060
27061	unwrap: function() {
27062		return this.parent().each( function() {
27063			if ( !jQuery.nodeName( this, "body" ) ) {
27064				jQuery( this ).replaceWith( this.childNodes );
27065			}
27066		} ).end();
27067	}
27068} );
27069
27070
27071function getDisplay( elem ) {
27072	return elem.style && elem.style.display || jQuery.css( elem, "dis
27072play" );
27073}
27074
27075function filterHidden( elem ) {
27076
27077	// Disconnected elements are considered hidden
27078	if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
27079		return true;
27080	}
27081	while ( elem && elem.nodeType === 1 ) {
27082		if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
27083			return true;
27084		}
27085		elem = elem.parentNode;
27086	}
27087	return false;
27088}
27089
27090jQuery.expr.filters.hidden = function( elem ) {
27091
27092	// Support: Opera <= 12.12
27093	// Opera reports offsetWidths and offsetHeights less than zero on some elements
27094	return support.reliableHiddenOffsets() ?
27095		( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
27096			!elem.getClientRects().length ) :
27097			filterHidden( elem );
27098};
27099
27100jQuery.expr.filters.visible = function( elem ) {
27101	return !jQuery.expr.filters.hidden( elem );
27102};
27103
27104
27105
27106
27107var r20 = /%20/g,
27108	rbracket = /\[\]$/,
27109	rCRLF = /\r?\n/g,
27110	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
27111	rsubmittable = /^(?:input|select|textarea|keygen)/i;
27112
27113function buildParams( prefix, obj, traditional, add ) {
27114	var name;
27115
27116	if ( jQuery.isArray( obj ) ) {
27117
27118		// Serialize array item.
27119		jQuery.each( obj, function( i, v ) {
27120			if ( traditional || rbracket.test( prefix ) ) {
27121
27122				// Treat each array item as a scalar.
27123				add( prefix, v );
27124
27125			} else {
27126
27127				// Item is non-scalar (array or object), encode its numeric index.
27128				buildParams(
27129					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
27130					v,
27131					traditional,
27132					add
27133				);
27134			}
27135		} );
27136
27137	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
27138
27139		// Serialize object item.
27140		for ( name in obj ) {
27141			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
27142		}
27143
27144	} else {
27145
27146		// Serialize scalar item.
27147		add( prefix, obj );
27148	}
27149}
27150
27151// Serialize an array of form elements or a set of
27152// key/values into a query string
27153jQuery.param = function( a, traditional ) {
27154	var prefix,
27155		s = [],
27156		add = function( key, value ) {
27157
27158			// If value is a function, invoke it and return its value
27159			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
27160			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
27161		};
27162
27163	// Set traditional to true for jQuery <= 1.3.2 behavior.
27164	if ( traditional === undefined ) {
27165		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
27166	}
27167
27168	// If an array was passed in, assume that it is an array of form elements.
27169	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
27170
27171		// Serialize the form elements
27172		jQuery.each( a, function() {
27173			add( this.name, this.value );
27174		} );
27175
27176	} else {
27177
27178		// If traditional, encode the "old" way (the way 1.3.2 or older
27179		// did it), otherwise encode params recursively.
27180		for ( prefix in a ) {
27181			buildParams( prefix, a[ prefix ], traditional, add );
27182		}
27183	}
27184
27185	// Return the resulting serialization
27186	return s.join( "&" ).replace( r20, "+" );
27187};
27188
27189jQuery.fn.extend( {
27190	serialize: function() {
27191		return jQuery.param( this.serializeArray() );
27192	},
27193	serializeArray: function() {
27194		return this.map( function() {
27195
27196			// Can add propHook for "elements" to filter or add form elements
27197			var elements = jQuery.prop( this, "elements" );
27198			return elements ? jQuery.makeArray( elements ) : this;
27199		} )
27200		.filter( function() {
27201			var type = this.type;
27202
27203			// Use .is(":disabled") so that fieldset[disabled] works
27204			return this.name && !jQuery( this ).is( ":disabled" ) &&
27205				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
27206				( this.checked || !rcheckableType.test( type ) );
27207		} )
27208		.map( function( i, elem ) {
27209			var val = jQuery( this ).val();
27210
27211			return val == null ?
27212				null :
27213				jQuery.isArray( val ) ?
27214					jQuery.map( val, function( val ) {
27215						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
27216					} ) :
27217					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
27218		} ).get();
27219	}
27220} );
27221
27222
27223// Create the request object
27224// (This is still attached to ajaxSettings for backward compatibility)
27225jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
27226
27227	// Support: IE6-IE8
27228	function() {
27229
27230		// XHR cannot access local files, always use ActiveX for that case
27231		if ( this.isLocal ) {
27232			return createActiveXHR();
27233		}
27234
vendor: 22,565 bytes, lines 27235-28055
27235		// Support: IE 9-11
27236		// IE seems to error on cross-domain PATCH requests when ActiveX XHR
27237		// is used. In IE 9+ always use the native XHR.
27238		// Note: this condition won't catch Edge as it doesn't define
27239		// document.documentMode but it also doesn't support ActiveX so it won't
27240		// reach this code.
27241		if ( document.documentMode > 8 ) {
27242			return createStandardXHR();
27243		}
27244
27245		// Support: IE<9
27246		// oldIE XHR does not support non-RFC2616 methods (#13240)
27247		// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
27248		// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
27249		// Although this check for six methods instead of eight
27250		// since IE also does not support "trace" and "connect"
27251		return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
27252			createStandardXHR() || createActiveXHR();
27253	} :
27254
27255	// For all other browsers, use the standard XMLHttpRequest object
27256	createStandardXHR;
27257
27258var xhrId = 0,
27259	xhrCallbacks = {},
27260	xhrSupported = jQuery.ajaxSettings.xhr();
27261
27262// Support: IE<10
27263// Open requests must be manually aborted on unload (#5280)
27264// See https://support.microsoft.com/kb/2856746 for more info
27265if ( window.attachEvent ) {
27266	window.attachEvent( "onunload", function() {
27267		for ( var key in xhrCallbacks ) {
27268			xhrCallbacks[ key ]( undefined, true );
27269		}
27270	} );
27271}
27272
27273// Determine support properties
27274support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
27275xhrSupported = support.ajax = !!xhrSupported;
27276
27277// Create transport if the browser can provide an xhr
27278if ( xhrSupported ) {
27279
27280	jQuery.ajaxTransport( function( options ) {
27281
27282		// Cross domain only allowed if supported through XMLHttpRequest
27283		if ( !options.crossDomain || support.cors ) {
27284
27285			var callback;
27286
27287			return {
27288				send: function( headers, complete ) {
27289					var i,
27290						xhr = options.xhr(),
27291						id = ++xhrId;
27292
27293					// Open the socket
27294					xhr.open(
27295						options.type,
27296						options.url,
27297						options.async,
27298						options.username,
27299						options.password
27300					);
27301
27302					// Apply custom fields if provided
27303					if ( options.xhrFields ) {
27304						for ( i in options.xhrFields ) {
27305							xhr[ i ] = options.xhrFields[ i ];
27306						}
27307					}
27308
27309					// Override mime type if needed
27310					if ( options.mimeType && xhr.overrideMimeType ) {
27311						xhr.overrideMimeType( options.mimeType );
27312					}
27313
27314					// X-Requested-With header
27315					// For cross-domain requests, seeing as conditions for a preflight are
27316					// akin to a jigsaw puzzle, we simply never set it to be sure.
27317					// (it can always be set on a per-request basis or even using ajaxSetup)
27318					// For same-domain requests, won't change header if already provided.
27319					if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
27320						headers[ "X-Requested-With" ] = "XMLHttpRequest";
27321					}
27322
27323					// Set headers
27324					for ( i in headers ) {
27325
27326						// Support: IE<9
27327						// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
27328						// request header to a null-value.
27329						//
27330						// To keep consistent with other XHR implementations, cast the value
27331						// to string and ignore `undefined`.
27332						if ( headers[ i ] !== undefined ) {
27333							xhr.setRequestHeader( i, headers[ i ] + "" );
27334						}
27335					}
27336
27337					// Do send the request
27338					// This may raise an exception which is actually
27339					// handled in jQuery.ajax (so no try/catch here)
27340					xhr.send( ( options.hasContent && options.data ) || null );
27341
27342					// Listener
27343					callback = function( _, isAbort ) {
27344						var status, statusText, responses;
27345
27346						// Was never called and is aborted or complete
27347						if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
27348
27349							// Clean up
27350							delete xhrCallbacks[ id ];
27351							callback = undefined;
27352							xhr.onreadystatechange = jQuery.noop;
27353
27354							// Abort manually if needed
27355							if ( isAbort ) {
27356								if ( xhr.readyState !== 4 ) {
27357									xhr.abort();
27358								}
27359							} else {
27360								responses = {};
27361								status = xhr.status;
27362
27363								// Support: IE<10
27364								// Accessing binary-data responseText throws an exception
27365								// (#11426)
27366								if ( typeof xhr.responseText === "string" ) {
27367									responses.text = xhr.responseText;
27368								}
27369
27370								// Firefox throws an exception when accessing
27371								// statusText for faulty cross-domain requests
27372								try {
27373									statusText = xhr.statusText;
27374								} catch ( e ) {
27375
27376									// We normalize with Webkit giving an empty statusText
27377									statusText = "";
27378								}
27379
27380								// Filter status for non standard behaviors
27381
27382								// If the request is local and we have data: assume a success
27383								// (success with no data won't get notified, that's the best we
27384								// can do given current implementations)
27385								if ( !status && options.isLocal && !options.crossDomain ) {
27386									status = responses.text ? 200 : 404;
27387
27388								// IE - #1450: sometimes returns 1223 when it should be 204
27389								} else if ( status === 1223 ) {
27390									status = 204;
27391								}
27392							}
27393						}
27394
27395						// Call complete if needed
27396						if ( responses ) {
27397							complete( status, statusText, responses, xhr.getAllResponseHeaders() );
27398						}
27399					};
27400
27401					// Do send the request
27402					// `xhr.send` may raise an exception, but it will be
27403					// handled in jQuery.ajax (so no try/catch here)
27404					if ( !options.async ) {
27405
27406						// If we're in sync mode we fire the callback
27407						callback();
27408					} else if ( xhr.readyState === 4 ) {
27409
27410						// (IE6 & IE7) if it's in cache and has been
27411						// retrieved directly we need to fire the callback
27412						window.setTimeout( callback );
27413					} else {
27414
27415						// Register the callback, but delay it in case `xhr.send` throws
27416						// Add to the list of active xhr callbacks
27417						xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
27418					}
27419				},
27420
27421				abort: function() {
27422					if ( callback ) {
27423						callback( undefined, true );
27424					}
27425				}
27426			};
27427		}
27428	} );
27429}
27430
27431// Functions to create xhrs
27432function createStandardXHR() {
27433	try {
27434		return new window.XMLHttpRequest();
27435	} catch ( e ) {}
27436}
27437
27438function createActiveXHR() {
27439	try {
27440		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
27441	} catch ( e ) {}
27442}
27443
27444
27445
27446
27447// Install script dataType
27448jQuery.ajaxSetup( {
27449	accepts: {
27450		script: "text/javascript, application/javascript, " +
27451			"application/ecmascript, application/x-ecmascript"
27452	},
27453	contents: {
27454		script: /\b(?:java|ecma)script\b/
27455	},
27456	converters: {
27457		"text script": function( text ) {
27458			jQuery.globalEval( text );
27459			return text;
27460		}
27461	}
27462} );
27463
27464// Handle cache's special case and global
27465jQuery.ajaxPrefilter( "script", function( s ) {
27466	if ( s.cache === undefined ) {
27467		s.cache = false;
27468	}
27469	if ( s.crossDomain ) {
27470		s.type = "GET";
27471		s.global = false;
27472	}
27473} );
27474
27475// Bind script tag hack transport
27476jQuery.ajaxTransport( "script", function( s ) {
27477
27478	// This transport only deals with cross domain requests
27479	if ( s.crossDomain ) {
27480
27481		var script,
27482			head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
27483
27484		return {
27485
27486			send: function( _, callback ) {
27487
27488				script = document.createElement( "script" );
27489
27490				script.async = true;
27491
27492				if ( s.scriptCharset ) {
27493					script.charset = s.scriptCharset;
27494				}
27495
27496				script.src = s.url;
27497
27498				// Attach handlers for all browsers
27499				script.onload = script.onreadystatechange = function( _, isAbort ) {
27500
27501					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
27502
27503						// Handle memory leak in IE
27504						script.onload = script.onreadystatechange = null;
27505
27506						// Remove the script
27507						if ( script.parentNode ) {
27508							script.parentNode.removeChild( script );
27509						}
27510
27511						// Dereference the script
27512						script = null;
27513
27514						// Callback if not abort
27515						if ( !isAbort ) {
27516							callback( 200, "success" );
27517						}
27518					}
27519				};
27520
27521				// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
27522				// Use native DOM manipulation to avoid our domManip AJAX trickery
27523				head.insertBefore( script, head.firstChild );
27524			},
27525
27526			abort: function() {
27527				if ( script ) {
27528					script.onload( undefined, true );
27529				}
27530			}
27531		};
27532	}
27533} );
27534
27535
27536
27537
27538var oldCallbacks = [],
27539	rjsonp = /(=)\?(?=&|$)|\?\?/;
27540
27541// Default jsonp settings
27542jQuery.ajaxSetup( {
27543	jsonp: "callback",
27544	jsonpCallback: function() {
27545		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
27546		this[ callback ] = true;
27547		return callback;
27548	}
27549} );
27550
27551// Detect, normalize options and install callbacks for jsonp requests
27552jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
27553
27554	var callbackName, overwritten, responseContainer,
27555		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
27556			"url" :
27557			typeof s.data === "string" &&
27558				( s.contentType || "" )
27559					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
27560				rjsonp.test( s.data ) && "data"
27561		);
27562
27563	// Handle iff the expected data type is "jsonp" or we have a parameter to set
27564	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
27565
27566		// Get callback name, remembering preexisting value associated with it
27567		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
27568			s.jsonpCallback() :
27569			s.jsonpCallback;
27570
27571		// Insert callback into url or form data
27572		if ( jsonProp ) {
27573			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
27574		} else if ( s.jsonp !== false ) {
27575			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
27576		}
27577
27578		// Use data converter to retrieve json after script execution
27579		s.converters[ "script json" ] = function() {
27580			if ( !responseContainer ) {
27581				jQuery.error( callbackName + " was not called" );
27582			}
27583			return responseContainer[ 0 ];
27584		};
27585
27586		// force json dataType
27587		s.dataTypes[ 0 ] = "json";
27588
27589		// Install callback
27590		overwritten = window[ callbackName ];
27591		window[ callbackName ] = function() {
27592			responseContainer = arguments;
27593		};
27594
27595		// Clean-up function (fires after converters)
27596		jqXHR.always( function() {
27597
27598			// If previous value didn't exist - remove it
27599			if ( overwritten === undefined ) {
27600				jQuery( window ).removeProp( callbackName );
27601
27602			// Otherwise restore preexisting value
27603			} else {
27604				window[ callbackName ] = overwritten;
27605			}
27606
27607			// Save back as free
27608			if ( s[ callbackName ] ) {
27609
27610				// make sure that re-using the options doesn't screw things around
27611				s.jsonpCallback = originalSettings.jsonpCallback;
27612
27613				// save the callback name for future use
27614				oldCallbacks.push( callbackName );
27615			}
27616
27617			// Call if it was a function and we have a response
27618			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
27619				overwritten( responseContainer[ 0 ] );
27620			}
27621
27622			responseContainer = overwritten = undefined;
27623		} );
27624
27625		// Delegate to script
27626		return "script";
27627	}
27628} );
27629
27630
27631
27632
27633// data: string of html
27634// context (optional): If specified, the fragment will be created in this context,
27635// defaults to document
27636// keepScripts (optional): If true, will include scripts passed in the html string
27637jQuery.parseHTML = function( data, context, keepScripts ) {
27638	if ( !data || typeof data !== "string" ) {
27639		return null;
27640	}
27641	if ( typeof context === "boolean" ) {
27642		keepScripts = context;
27643		context = false;
27644	}
27645	context = context || document;
27646
27647	var parsed = rsingleTag.exec( data ),
27648		scripts = !keepScripts && [];
27649
27650	// Single tag
27651	if ( parsed ) {
27652		return [ context.createElement( parsed[ 1 ] ) ];
27653	}
27654
27655	parsed = buildFragment( [ data ], context, scripts );
27656
27657	if ( scripts && scripts.length ) {
27658		jQuery( scripts ).remove();
27659	}
27660
27661	return jQuery.merge( [], parsed.childNodes );
27662};
27663
27664
27665// Keep a copy of the old load method
27666var _load = jQuery.fn.load;
27667
27668/**
27669 * Load a url into a page
27670 */
27671jQuery.fn.load = function( url, params, callback ) {
27672	if ( typeof url !== "string" && _load ) {
27673		return _load.apply( this, arguments );
27674	}
27675
27676	var selector, type, response,
27677		self = this,
27678		off = url.indexOf( " " );
27679
27680	if ( off > -1 ) {
27681		selector = jQuery.trim( url.slice( off, url.length ) );
27682		url = url.slice( 0, off );
27683	}
27684
27685	// If it's a function
27686	if ( jQuery.isFunction( params ) ) {
27687
27688		// We assume that it's the callback
27689		callback = params;
27690		params = undefined;
27691
27692	// Otherwise, build a param string
27693	} else if ( params && typeof params === "object" ) {
27694		type = "POST";
27695	}
27696
27697	// If we have elements to modify, make the request
27698	if ( self.length > 0 ) {
27699		jQuery.ajax( {
27700			url: url,
27701
27702			// If "type" variable is undefined, then "GET" method will be used.
27703			// Make value of this field explicit since
27704			// user can override it through ajaxSetup method
27705			type: type || "GET",
27706			dataType: "html",
27707			data: params
27708		} ).done( function( responseText ) {
27709
27710			// Save response for use in complete callback
27711			response = arguments;
27712
27713			self.html( selector ?
27714
27715				// If a selector was specified, locate the right elements in a dummy div
27716				// Exclude scripts to avoid IE 'Permission Denied' errors
27717				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
27718
27719				// Otherwise use the full result
27720				responseText );
27721
27722		// If the request succeeds, this function gets "data", "status", "jqXHR"
27723		// but they are ignored because response was set above.
27724		// If it fails, this function gets "jqXHR", "status", "error"
27725		} ).always( callback && function( jqXHR, status ) {
27726			self.each( function() {
27727				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
27728			} );
27729		} );
27730	}
27731
27732	return this;
27733};
27734
27735
27736
27737
27738// Attach a bunch of functions for handling common AJAX events
27739jQuery.each( [
27740	"ajaxStart",
27741	"ajaxStop",
27742	"ajaxComplete",
27743	"ajaxError",
27744	"ajaxSuccess",
27745	"ajaxSend"
27746], function( i, type ) {
27747	jQuery.fn[ type ] = function( fn ) {
27748		return this.on( type, fn );
27749	};
27750} );
27751
27752
27753
27754
27755jQuery.expr.filters.animated = function( elem ) {
27756	return jQuery.grep( jQuery.timers, function( fn ) {
27757		return elem === fn.elem;
27758	} ).length;
27759};
27760
27761
27762
27763
27764
27765/**
27766 * Gets a window from an element
27767 */
27768function getWindow( elem ) {
27769	return jQuery.isWindow( elem ) ?
27770		elem :
27771		elem.nodeType === 9 ?
27772			elem.defaultView || elem.parentWindow :
27773			false;
27774}
27775
27776jQuery.offset = {
27777	setOffset: function( elem, options, i ) {
27778		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
27779			position = jQuery.css( elem, "position" ),
27780			curElem = jQuery( elem ),
27781			props = {};
27782
27783		// set position first, in-case top/left are set even on static elem
27784		if ( position === "static" ) {
27785			elem.style.position = "relative";
27786		}
27787
27788		curOffset = curElem.offset();
27789		curCSSTop = jQuery.css( elem, "top" );
27790		curCSSLeft = jQuery.css( elem, "left" );
27791		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
27792			jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
27793
27794		// need to be able to calculate position if either top or left
27795		// is auto and position is either absolute or fixed
27796		if ( calculatePosition ) {
27797			curPosition = curElem.position();
27798			curTop = curPosition.top;
27799			curLeft = curPosition.left;
27800		} else {
27801			curTop = parseFloat( curCSSTop ) || 0;
27802			curLeft = parseFloat( curCSSLeft ) || 0;
27803		}
27804
27805		if ( jQuery.isFunction( options ) ) {
27806
27807			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
27808			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
27809		}
27810
27811		if ( options.top != null ) {
27812			props.top = ( options.top - curOffset.top ) + curTop;
27813		}
27814		if ( options.left != null ) {
27815			props.left = ( options.left - curOffset.left ) + curLeft;
27816		}
27817
27818		if ( "using" in options ) {
27819			options.using.call( elem, props );
27820		} else {
27821			curElem.css( props );
27822		}
27823	}
27824};
27825
27826jQuery.fn.extend( {
27827	offset: function( options ) {
27828		if ( arguments.length ) {
27829			return options === undefined ?
27830				this :
27831				this.each( function( i ) {
27832					jQuery.offset.setOffset( this, options, i );
27833				} );
27834		}
27835
27836		var docElem, win,
27837			box = { top: 0, left: 0 },
27838			elem = this[ 0 ],
27839			doc = elem && elem.ownerDocument;
27840
27841		if ( !doc ) {
27842			return;
27843		}
27844
27845		docElem = doc.documentElement;
27846
27847		// Make sure it's not a disconnected DOM node
27848		if ( !jQuery.contains( docElem, elem ) ) {
27849			return box;
27850		}
27851
27852		// If we don't have gBCR, just use 0,0 rather than error
27853		// BlackBerry 5, iOS 3 (original iPhone)
27854		if ( typeof elem.getBoundingClientRect !== "undefined" ) {
27855			box = elem.getBoundingClientRect();
27856		}
27857		win = getWindow( doc );
27858		return {
27859			top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
27860			left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
27861		};
27862	},
27863
27864	position: function() {
27865		if ( !this[ 0 ] ) {
27866			return;
27867		}
27868
27869		var offsetParent, offset,
27870			parentOffset = { top: 0, left: 0 },
27871			elem = this[ 0 ];
27872
27873		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
27874		// because it is its only offset parent
27875		if ( jQuery.css( elem, "position" ) === "fixed" ) {
27876
27877			// we assume that getBoundingClientRect is available when computed position is fixed
27878			offset = elem.getBoundingClientRect();
27879		} else {
27880
27881			// Get *real* offsetParent
27882			offsetParent = this.offsetParent();
27883
27884			// Get correct offsets
27885			offset = this.offset();
27886			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
27887				parentOffset = offsetParent.offset();
27888			}
27889
27890			// Add offsetParent borders
27891			parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
27892			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
27893		}
27894
27895		// Subtract parent offsets and element margins
27896		// note: when an element has margin: auto the offsetLeft and marginLeft
27897		// are the same in Safari causing offset.left to incorrectly be 0
27898		return {
27899			top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
27900			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
27901		};
27902	},
27903
27904	offsetParent: function() {
27905		return this.map( function() {
27906			var offsetParent = this.offsetParent;
27907
27908			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
27909				jQuery.css( offsetParent, "position" ) === "static" ) ) {
27910				offsetParent = offsetParent.offsetParent;
27911			}
27912			return offsetParent || documentElement;
27913		} );
27914	}
27915} );
27916
27917// Create scrollLeft and scrollTop methods
27918jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
27919	var top = /Y/.test( prop );
27920
27921	jQuery.fn[ method ] = function( val ) {
27922		return access( this, function( elem, method, val ) {
27923			var win = getWindow( elem );
27924
27925			if ( val === undefined ) {
27926				return win ? ( prop in win ) ? win[ prop ] :
27927					win.document.documentElement[ method ] :
27928					elem[ method ];
27929			}
27930
27931			if ( win ) {
27932				win.scrollTo(
27933					!top ? val : jQuery( win ).scrollLeft(),
27934					top ? val : jQuery( win ).scrollTop()
27935				);
27936
27937			} else {
27938				elem[ method ] = val;
27939			}
27940		}, method, val, arguments.length, null );
27941	};
27942} );
27943
27944// Support: Safari<7-8+, Chrome<37-44+
27945// Add the top/left cssHooks using jQuery.fn.position
27946// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
27947// getComputedStyle returns percent when specified for top/left/bottom/right
27948// rather than make the css module depend on the offset module, we just check for it here
27949jQuery.each( [ "top", "left" ], function( i, prop ) {
27950	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
27951		function( elem, computed ) {
27952			if ( computed ) {
27953				computed = curCSS( elem, prop );
27954
27955				// if curCSS returns percentage, fallback to offset
27956				return rnumnonpx.test( computed ) ?
27957					jQuery( elem ).position()[ prop ] + "px" :
27958					computed;
27959			}
27960		}
27961	);
27962} );
27963
27964
27965// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
27966jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
27967	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
27968	function( defaultExtra, funcName ) {
27969
27970		// margin is only for outerHeight, outerWidth
27971		jQuery.fn[ funcName ] = function( margin, value ) {
27972			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
27973				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
27974
27975			return access( this, function( elem, type, value ) {
27976				var doc;
27977
27978				if ( jQuery.isWindow( elem ) ) {
27979
27980					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
27981					// isn't a whole lot we can do. See pull request at this URL for discussion:
27982					// https://github.com/jquery/jquery/pull/764
27983					return elem.document.documentElement[ "client" + name ];
27984				}
27985
27986				// Get document width or height
27987				if ( elem.nodeType === 9 ) {
27988					doc = elem.documentElement;
27989
27990					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
27991					// whichever is greatest
27992					// unfortunately, this causes bug #3838 in IE6/8 only,
27993					// but there is currently no good, small way to fix it.
27994					return Math.max(
27995						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
27996						elem.body[ "offset" + name ], doc[ "offset" + name ],
27997						doc[ "client" + name ]
27998					);
27999				}
28000
28001				return value === undefined ?
28002
28003					// Get width or height on the element, requesting but not forcing parseFloat
28004					jQuery.css( elem, type, extra ) :
28005
28006					// Set width or height on the element
28007					jQuery.style( elem, type, value, extra );
28008			}, type, chainable ? margin : undefined, chainable, null );
28009		};
28010	} );
28011} );
28012
28013
28014jQuery.fn.extend( {
28015
28016	bind: function( types, data, fn ) {
28017		return this.on( types, null, data, fn );
28018	},
28019	unbind: function( types, fn ) {
28020		return this.off( types, null, fn );
28021	},
28022
28023	delegate: function( selector, types, data, fn ) {
28024		return this.on( types, selector, data, fn );
28025	},
28026	undelegate: function( selector, types, fn ) {
28027
28028		// ( namespace ) or ( selector, types [, fn] )
28029		return arguments.length === 1 ?
28030			this.off( selector, "**" ) :
28031			this.off( types, selector || "**", fn );
28032	}
28033} );
28034
28035// The number of elements contained in the matched element set
28036jQuery.fn.size = function() {
28037	return this.length;
28038};
28039
28040jQuery.fn.andSelf = jQuery.fn.addBack;
28041
28042
28043
28044
28045// Register as a named AMD module, since jQuery can be concatenated with other
28046// files that may use define, but not via a proper concatenation script that
28047// understands anonymous AMD modules. A named AMD is safest and most robust
28048// way to register. Lowercase jquery is used because AMD module names are
28049// derived from file names, and jQuery is normally delivered in a lowercase
28050// file name. Do this after creating the global so that if an AMD module wants
28051// to call noConflict to hide this version of jQuery, it will work.
28052
28053// Note that for maximum portability, libraries that are not jQuery should
28054// declare themselves as anonymous modules, and avoid setting a global if an
28055// AMD loader is present. jQuery is a special case. For more information, see
28056// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
28057
28058if ( typeof define === "function" && define.amd ) {
28059	define( "jquery", [], function() {
28060		return jQuery;
28061	} );
28062}
28063
28064
28065
28066var
28067
28068	// Map over jQuery in case of overwrite
28069	_jQuery = window.jQuery,
28070
28071	// Map over the $ in case of overwrite
28072	_$ = window.$;
28073
28074jQuery.noConflict = function( deep ) {
28075	if ( window.$ === jQuery ) {
28076		window.$ = _$;
28077	}
28078
28079	if ( deep && window.jQuery === jQuery ) {
28080		window.jQuery = _jQuery;
28081	}
28082
28083	return jQuery;
28084};
28085
28086// Expose jQuery and $ identifiers, even in
28087// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
28088// and CommonJS for browser emulators (#13566)
28089if ( !noGlobal ) {
28090	window.jQuery = window.$ = jQuery;
28091}
28092
28093return jQuery;
28094}));
28095(function($, undefined) {
28096
28097/**
28098 * Unobtrusive scripting adapter for jQuery
28099 * https://github.com/rails/jquery-ujs
28100 *
28101 * Requires jQuery 1.8.0 or later.
28102 *
28103 * Released under the MIT license
28104 *
28105 */
28106
28107  // Cut down on the number of issues from people inadvertently including jquery_ujs twice
28108  // by detecting and raising an error when it happens.
28109  'use strict';
28110
28111  if ( $.rails !== undefined ) {
28112    $.error('jquery-ujs has already been loaded!');
28113  }
28114
28115  // Shorthand to make it a little easier to call public rails functions from within rails.js
28116  var rails;
28117  var $document = $(document);
28118
28119  $.rails = rails = {
28120    // Link elements bound by jquery-ujs
28121    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
28122
28123    // Button elements bound by jquery-ujs
28124    buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)',
28125
28126    // Select elements bound by jquery-ujs
28127    inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
28128
28129    // Form elements bound by jquery-ujs
28130    formSubmitSelector: 'form',
28131
28132    // Form input elements bound by jquery-ujs
28133    formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
28134
28135    // Form input elements disabled during form submission
28136    disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
28137
28138    // Form input elements re-enabled after form submission
28139    enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
28140
28141    // Form required input elements
28142    requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])',
28143
28144    // Form file input elements
28145    fileInputSelector: 'input[name][type=file]:not([disabled])',
28146
28147    // Link onClick disable selector with possible reenable after remote submission
28148    linkDisableSelector: 'a[data-disable-with], a[data-disable]',
28149
28150    // Button onClick disable selector with possible reenable after remote submission
28151    buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',
28152
28153    // Up-to-date Cross-Site Request Forgery token
28154    csrfToken: function() {
28155     return $('meta[name=csrf-token]').attr('content');
28156    },
28157
28158    // URL param that must contain the CSRF token
28159    csrfParam: function() {
28160     return $('meta[name=csrf-param]').attr('content');
28161    },
28162
28163    // Make sure that every Ajax request sends the CSRF token
28164    CSRFProtection: function(xhr) {
28165      var token = rails.csrfToken();
28166      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
28167    },
28168
28169    // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones)
28170    refreshCSRFTokens: function(){
28171      $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken());
28172    },
28173
28174    // Triggers an event on an element and returns false if the event result is false
28175    fire: function(obj, name, data) {
28176      var event = $.Event(name);
28177      obj.trigger(event, data);
28178      return event.result !== false;
28179    },
28180
28181    // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
28182    confirm: function(message) {
28183      return confirm(message);
28184    },
28185
28186    // Default ajax function, may be overridden with custom function in $.rails.ajax
28187    ajax: function(options) {
28188      return $.ajax(options);
28189    },
28190
28191    // Default way to get an element's href. May be overridden at $.rails.href.
28192    href: function(element) {
28193      return element[0].href;
28194    },
28195
28196    // Checks "data-remote" if true to handle the request through a XHR request.
28197    isRemote: function(element) {
28198      return element.data('remote') !== undefined && element.data('remote') !== false;
28199    },
28200
28201    // Submits "remote" forms and links with ajax
28202    handleRemote: function(element) {
28203      var method, url, data, withCredentials, dataType, options;
28204
28205      if (rails.fire(element, 'ajax:before')) {
28206        withCredentials = element.data('with-credentials') || null;
28207        dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
28208
28209        if (element.is('form')) {
28210          method = element.data('ujs:submit-button-formmethod') || element.attr('method');
28211          url = element.data('ujs:submit-button-formaction') || element.attr('action');
28212          data = $(element[0]).serializeArray();
28213          // memoized value from clicked submit button
28214          var button = element.data('ujs:submit-button');
28215          if (button) {
28216            data.push(button);
28217            element.data('ujs:submit-button', null);
28218          }
28219          element.data('ujs:submit-button-formmethod', null);
28220          element.data('ujs:submit-button-formaction', null);
28221        } else if (element.is(rails.inputChangeSelector)) {
28222          method = element.data('method');
28223          url = element.data('url');
28224          data = element.serialize();
28225          if (element.data('params')) data = data + '&' + element.data('params');
28226        } else if (element.is(rails.buttonClickSelector)) {
28227          method = element.data('method') || 'get';
28228          url = element.data('url');
28229          data = element.serialize();
28230          if (element.data('params')) data = data + '&' + element.data('params');
28231        } else {
28232          method = element.data('method');
28233          url = rails.href(element);
28234          data = element.data('params') || null;
28235        }
28236
28237        options = {
28238          type: method || 'GET', data: data, dataType: dataType,
28239          // stopping the "ajax:beforeSend" event will cancel the ajax request
28240          beforeSend: function(xhr, settings) {
28241            if (settings.dataType === undefined) {
28242              xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
28243            }
28244            if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
28245              element.trigger('ajax:send', xhr);
28246            } else {
28247              return false;
28248            }
28249          },
28250          success: function(data, status, xhr) {
28251            element.trigger('ajax:success', [data, status, xhr]);
28252          },
28253          complete: function(xhr, status) {
28254            element.trigger('ajax:complete', [xhr, status]);
28255          },
28256          error: function(xhr, status, error) {
28257            element.trigger('ajax:error', [xhr, status, error]);
28258          },
28259          crossDomain: rails.isCrossDomain(url)
28260        };
28261
28262        // There is no withCredentials for IE6-8 when
28263        // "Enable native XMLHTTP support" is disabled
28264        if (withCredentials) {
28265          options.xhrFields = {
28266            withCredentials: withCredentials
28267          };
28268        }
28269
28270        // Only pass url to `ajax` options if not blank
28271        if (url) { options.url = url; }
28272
28273        return rails.ajax(options);
28274      } else {
28275        return false;
28276      }
28277    },
28278
28279    // Determines if the request is a cross domain request.
28280    isCrossDomain: function(url) {
28281      var originAnchor = document.createElement('a');
28282      originAnchor.href = location.href;
28283      var urlAnchor = document.createElement('a');
28284
28285      try {
28286        urlAnchor.href = url;
28287        // This is a workaround to a IE bug.
28288        urlAnchor.href = urlAnchor.href;
28289
28290        // If URL protocol is false or is a string containing a single colon
28291        // *and* host are false, assume it is not a cross-domain request
28292        // (should only be the case for IE7 and IE compatibility mode).
28293        // Otherwise, evaluate protocol and host of the URL against the origin
28294        // protocol and host.
28295        return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) ||
28296          (originAnchor.protocol + '//' + originAnchor.host ===
28297            urlAnchor.protocol + '//' + urlAnchor.host));
28298      } catch (e) {
28299        // If there is an error parsing the URL, assume it is crossDomain.
28300        return true;
28301      }
28302    },
28303
28304    // Handles "data-method" on links such as:
28305    // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
28306    handleMethod: function(link) {
28307      var href = rails.href(link),
28308        method = link.data('method'),
28309        target = link.attr('target'),
28310        csrfToken = rails.csrfToken(),
28311        csrfParam = rails.csrfParam(),
28312        form = $('<form method="post" action="' + href + '"></form>'),
28313        metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
28314
28315      if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {
28316        metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
28317      }
28318
28319      if (target) { form.attr('target', target); }
28320
28321      form.hide().append(metadataInput).appendTo('body');
28322      form.submit();
28323    },
28324
28325    // Helper function that returns form elements that match the specified CSS selector
28326    // If form is actually a "form" element this will return associated elements outside the from that have
28327    // the html form attribute set
28328    formElements: function(form, selector) {
28329      return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector);
28330    },
28331
28332    /* Disables form elements:
28333      - Caches element value in 'ujs:enable-with' data store
28334      - Replaces element text with value of 'data-disable-with' attribute
28335      - Sets disabled property to true
28336    */
28337    disableFormElements: function(form) {
28338      rails.formElements(form, rails.disableSelector).each(function() {
28339        rails.disableFormElement($(this));
28340      });
28341    },
28342
28343    disableFormElement: function(element) {
28344      var method, replacement;
28345
28346      method = element.is('button') ? 'html' : 'val';
28347      replacement = element.data('disable-with');
28348
28349      if (replacement !== undefined) {
28350        element.data('ujs:enable-with', element[method]());
28351        element[method](replacement);
28352      }
28353
28354      element.prop('disabled', true);
28355      element.data('ujs:disabled', true);
28356    },
28357
28358    /* Re-enables disabled form elements:
28359      - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
28360      - Sets disabled property to false
28361    */
28362    enableFormElements: function(form) {
28363      rails.formElements(form, rails.enableSelector).each(function() {
28364        rails.enableFormElement($(this));
28365      });
28366    },
28367
28368    enableFormElement: function(element) {
28369      var method = element.is('button') ? 'html' : 'val';
28370      if (element.data('ujs:enable-with') !== undefined) {
28371        element[method](element.data('ujs:enable-with'));
28372        element.removeData('ujs:enable-with'); // clean up cache
28373      }
28374      element.prop('disabled', false);
28375      element.removeData('ujs:disabled');
28376    },
28377
28378   /* For 'data-confirm' attribute:
28379      - Fires `confirm` event
28380      - Shows the confirmation dialog
28381      - Fires the `confirm:complete` event
28382
28383      Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
28384      Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
28385      Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
28386      return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
28387   */
28388    allowAction: function(element) {
28389      var message = element.data('confirm'),
28390          answer = false, callback;
28391      if (!message) { return true; }
28392
28393      if (rails.fire(element, 'confirm')) {
28394        try {
28395          answer = rails.confirm(message);
28396        } catch (e) {
28397          (console.error || console.log).call(console, e.stack || e);
28398        }
28399        callback = rails.fire(element, 'confirm:complete', [answer]);
28400      }
28401      return answer && callback;
28402    },
28403
28404    // Helper function which checks for blank inputs in a form that match the specified CSS selector
28405    blankInputs: function(form, specifiedSelector, nonBlank) {
28406      var foundInputs = $(),
28407        input,
28408        valueToCheck,
28409        radiosForNameWithNoneSelected,
28410        radioName,
28411        selector = specifiedSelector || 'input,textarea',
28412        requiredInputs = form.find(selector),
28413        checkedRadioButtonNames = {};
28414
28415      requiredInputs.each(function() {
28416        input = $(this);
28417        if (input.is('input[type=radio]')) {
28418
28419          // Don't count unchecked required radio as blank if other radio with same name is checked,
28420          // regardless of whether same-name radio input has required attribute or not. The spec
28421          // states https://www.w3.org/TR/html5/forms.html#the-required-attribute
28422          radioName = input.attr('name');
28423
28424          // Skip if we've already seen the radio with this name.
28425          if (!checkedRadioButtonNames[radioName]) {
28426
28427            // If none checked
28428            if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) {
28429              radiosForNameWithNoneSelected = form.find(
28430                'input[type=radio][name="' + radioName + '"]');
28431              foundInputs = foundInputs.add(radiosForNameWithNoneSelected);
28432            }
28433
28434            // We only need to check each name once.
28435            checkedRadioButtonNames[radioName] = radioName;
28436          }
28437        } else {
28438          valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val();
28439          if (valueToCheck === nonBlank) {
28440            foundInputs = foundInputs.add(input);
28441          }
28442        }
28443      });
28444      return foundInputs.length ? foundInputs : false;
28445    },
28446
28447    // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
28448    nonBlankInputs: function(form, specifiedSelector) {
28449      return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
28450    },
28451
28452    // Helper function, needed to provide consistent behavior in IE
28453    stopEverything: function(e) {
28454      $(e.target).trigger('ujs:everythingStopped');
28455      e.stopImmediatePropagation();
28456      return false;
28457    },
28458
28459    //  Replace element's html with the 'data-disable-with' after storing original html
28460    //  and prevent clicking on it
28461    disableElement: function(element) {
28462      var replacement = element.data('disable-with');
28463
28464      if (replacement !== undefined) {
28465        element.data('ujs:enable-with', element.html()); // store enabled state
28466        element.html(replacement);
28467      }
28468
28469      element.bind('click.railsDisable', function(e) { // prevent further clicking
28470        return rails.stopEverything(e);
28471      });
28472      element.data('ujs:disabled', true);
28473    },
28474
28475    // Restore element to its original state which was disabled by 'disableElement' above
28476    enableElement: function(element) {
28477      if (element.data('ujs:enable-with') !== undefined) {
28478        element.html(element.data('ujs:enable-with')); // set to old enabled state
28479        element.removeData('ujs:enable-with'); // clean up cache
28480      }
28481      element.unbind('click.railsDisable'); // enable element
28482      element.removeData('ujs:disabled');
28483    }
28484  };
28485
28486  if (rails.fire($document, 'rails:attachBindings')) {
28487
28488    $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
28489
28490    // This event works the same as the load event, except that it fires every
28491    // time the page is loaded.
28492    //
28493    // See https://github.com/rails/jquery-ujs/issues/357
28494    // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
28495    $(window).on('pageshow.rails', function () {
28496      $($.rails.enableSelector).each(function () {
28497        var element = $(this);
28498
28499        if (element.data('ujs:disabled')) {
28500          $.rails.enableFormElement(element);
28501        }
28502      });
28503
28504      $($.rails.linkDisableSelector).each(function () {
28505        var element = $(this);
28506
28507        if (element.data('ujs:disabled')) {
28508          $.rails.enableElement(element);
28509        }
28510      });
28511    });
28512
28513    $document.on('ajax:complete', rails.linkDisableSelector, function() {
28514        rails.enableElement($(this));
28515    });
28516
28517    $document.on('ajax:complete', rails.buttonDisableSelector, function() {
28518        rails.enableFormElement($(this));
28519    });
28520
28521    $document.on('click.rails', rails.linkClickSelector, function(e) {
28522      var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
28523      if (!rails.allowAction(link)) return rails.stopEverything(e);
28524
28525      if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);
28526
28527      if (rails.isRemote(link)) {
28528        if (metaClick && (!method || method === 'GET') && !data) { return true; }
28529
28530        var handleRemote = rails.handleRemote(link);
28531        // Response from rails.handleRemote() will either be false or a deferred object promise.
28532        if (handleRemote === false) {
28533          rails.enableElement(link);
28534        } else {
28535          handleRemote.fail( function() { rails.enableElement(link); } );
28536        }
28537        return false;
28538
28539      } else if (method) {
28540        rails.handleMethod(link);
28541        return false;
28542      }
28543    });
28544
28545    $document.on('click.rails', rails.buttonClickSelector, function(e) {
28546      var button = $(this);
28547
28548      if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e);
28549
28550      if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button);
28551
28552      var handleRemote = rails.handleRemote(button);
28553      // Response from rails.handleRemote() will either be false or a deferred object promise.
28554      if (handleRemote === false) {
28555        rails.enableFormElement(button);
28556      } else {
28557        handleRemote.fail( function() { rails.enableFormElement(button); } );
28558      }
28559      return false;
28560    });
28561
28562    $document.on('change.rails', rails.inputChangeSelector, function(e) {
28563      var link = $(this);
28564      if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e);
28565
28566      rails.handleRemote(link);
28567      return false;
28568    });
28569
28570    $document.on('submit.rails', rails.formSubmitSelector, function(e) {
28571      var form = $(this),
28572        remote = rails.isRemote(form),
28573        blankRequiredInputs,
28574        nonBlankFileInputs;
28575
28576      if (!rails.allowAction(form)) return rails.stopEverything(e);
28577
28578      // Skip other logic when required values are missing or file upload is present
28579      if (form.attr('novalidate') === undefined) {
28580        if (form.data('ujs:formnovalidate-button') === undefined) {
28581          blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false);
28582          if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
28583            return rails.stopEverything(e);
28584          }
28585        } else {
28586          // Clear the formnovalidate in case the next button click is not on a formnovalidate button
28587          // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain
28588          form.data('ujs:formnovalidate-button', undefined);
28589        }
28590      }
28591
28592      if (remote) {
28593        nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
28594        if (nonBlankFileInputs) {
28595          // Slight timeout so that the submit button gets properly serialized
28596          // (make it easy for event handler to serialize form without disabled values)
28597          setTimeout(function(){ rails.disableFormElements(form); }, 13);
28598          var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
28599
28600          // Re-enable form elements if event bindings return false (canceling normal form submission)
28601          if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
28602
28603          return aborted;
28604        }
28605
28606        rails.handleRemote(form);
28607        return false;
28608
28609      } else {
28610        // Slight timeout so that the submit button gets properly serialized
28611        setTimeout(function(){ rails.disableFormElements(form); }, 13);
28612      }
28613    });
28614
28615    $document.on('click.rails', rails.formInputClickSelector, function(event) {
28616      var button = $(this);
28617
28618      if (!rails.allowAction(button)) return rails.stopEverything(event);
28619
28620      // Register the pressed submit button
28621      var name = button.attr('name'),
28622        data = name ? {name:name, value:button.val()} : null;
28623
28624      var form = button.closest('form');
28625      if (form.length === 0) {
28626        form = $('#' + button.attr('form'));
28627      }
28628      form.data('ujs:submit-button', data);
28629
28630      // Save attributes from button
28631      form.data('ujs:formnovalidate-button', button.attr('formnovalidate'));
28632      form.data('ujs:submit-button-formaction', button.attr('formaction'));
28633      form.data('ujs:submit-button-formmethod', button.attr('formmethod'));
28634    });
28635
28636    $document.on('ajax:send.rails', rails.formSubmitSelector, function(event) {
28637      if (this === event.target) rails.disableFormElements($(this));
28638    });
28639
28640    $document.on('ajax:complete.rails', rails.formSubmitSelector, function(event) {
28641      if (this === event.target) rails.enableFormElements($(this));
28642    });
28643
28644    $(function(){
28645      rails.refreshCSRFTokens();
28646    });
28647  }
28648
28649})( jQuery );
28650/*
28651 * jQuery mmenu v5.4.0
28652 * @requires jQuery 1.7.0 or later
28653 *
28654 * mmenu.frebsite.nl
28655 *	
28656 * Copyright (c) Fred Heusschen
28657 * www.frebsite.nl
28658 *
28659 * Licensed under the MIT license:
28660 * http://en.wikipedia.org/wiki/MIT_License
28661 */
28662
28663!function(e){function t(){e[n].glbl||(l={$wndw:e(window),$html:e("html"),$body:e("body")},a={},i={},r={},e.each([a,i,r],function(e,t){t.add=function(e){e=e.split(" ");for(var n=0,s=e.length;s>n;n++)t[e[n]]=t.mm(e[n])}}),a.mm=function(e){return"mm-"+e},a.add("wrapper menu panel nopanel current highest opened subopened navbar hasnavbar title btn prev next listview nolistview inset vertical selected divider spacer hidden fullsubopen"),a.umm=function(e){return"mm-"==e.slice(0,3)&&(e=e.slice(3)),e},i.mm=function(e){return"mm-"+e},i.add("parent sub"),r.mm=function(e){return e+".mm"},r.add("transitionend webkitTransitionEnd mousedown mouseup touchstart touchmove touchend click keydown"),e[n]._c=a,e[n]._d=i,e[n]._e=r,e[n].glbl=l)}var n="mmenu",s="5.4.0";if(!e[n]){e[n]=function(e,t,n){this.$menu=e,this._api=["bind","init","update","setSelected","getInstance","openPanel","closePanel","closeAllPanels"],this.opts=t,this.conf=n,this.vars={},this.cbck={},"function"==typeof this.___deprecated&&this.___deprecated(),this._initMenu(),this._initAnchors();var s=this.$menu.children(this.conf.panelNodetype);return this._initAddons(),this.init(s),"function"==typeof this.___debug&&this.___debug(),this},e[n].version=s,e[n].addons={},e[n].uniqueId=0,e[n].defaults={extensions:[],navbar:{add:!0,title:"Menu",titleLink:"panel"},onClick:{setSelected:!0},slidingSubmenus:!0},e[n].configuration={classNames:{divider:"Divider",inset:"Inset",panel:"Panel",selected:"Selected",spacer:"Spacer",vertical:"Vertical"},clone:!1,openingInterval:25,panelNodetype:"ul, ol, div",transitionDuration:400},e[n].prototype={init:function(e){e=e.not("."+a.nopanel),e=this._initPanels(e),this.trigger("init",e),this.trigger("update")},update:function(){this.trigger("update")},setSelected:function(e){this.$menu.find("."+a.listview).children().removeClass(a.selected),e.addClass(a.selected),this.trigger("setSelected",e)},openPanel:function(t){var s=t.parent();if(s.hasClass(a.vertical)){var i=s.parents("."+a.subopened);
28663if(i.length)return this.openPanel(i.first());s.addClass(a.opened)}else{if(t.hasClass(a.current))return;var r=this.$menu.children("."+a.panel),l=r.filter("."+a.current);r.removeClass(a.highest).removeClass(a.current).not(t).not(l).not("."+a.vertical).addClass(a.hidden),e[n].support.csstransitions||l.addClass(a.hidden),t.hasClass(a.opened)?t.nextAll("."+a.opened).addClass(a.highest).removeClass(a.opened).removeClass(a.subopened):(t.addClass(a.highest),l.addClass(a.subopened)),t.removeClass(a.hidden).addClass(a.current),setTimeout(function(){t.removeClass(a.subopened).addClass(a.opened)},this.conf.openingInterval)}this.trigger("openPanel",t)},closePanel:function(e){var t=e.parent();t.hasClass(a.vertical)&&(t.removeClass(a.opened),this.trigger("closePanel",e))},closeAllPanels:function(){this.$menu.find("."+a.listview).children().removeClass(a.selected).filter("."+a.vertical).removeClass(a.opened);var e=this.$menu.children("."+a.panel),t=e.first();this.$menu.children("."+a.panel).not(t).removeClass(a.subopened).removeClass(a.opened).removeClass(a.current).removeClass(a.highest).addClass(a.hidden),this.openPanel(t)},togglePanel:function(e){var t=e.parent();t.hasClass(a.vertical)&&this[t.hasClass(a.opened)?"closePanel":"openPanel"](e)},getInstance:function(){return this},bind:function(e,t){this.cbck[e]=this.cbck[e]||[],this.cbck[e].push(t)},trigger:function(){var e=this,t=Array.prototype.slice.call(arguments),n=t.shift();if(this.cbck[n])for(var s=0,a=this.cbck[n].length;a>s;s++)this.cbck[n][s].apply(e,t)},_initMenu:function(){this.opts.offCanvas&&this.conf.clone&&(this.$menu=this.$menu.clone(!0),this.$menu.add(this.$menu.find("[id]")).filter("[id]").each(function(){e(this).attr("id",a.mm(e(this).attr("id")))})),this.$menu.contents().each(function(){3==e(this)[0].nodeType&&e(this).remove()}),this.$menu.parent().addClass(a.wrapper);var t=[a.menu];this.opts.slidingSubmenus||t.push(a.vertical),this.opts.extensions=this.opts.extensions.length?"mm-"+this.opts.extensions.join(" mm-"):"",this.opts.extensions&&t.push(this.opts.extensions),this.$menu.addClass(t.join(" "))},_initPanels:function(t){var n=this,s=this.__findAddBack(t,"ul, ol");this.__refactorClass(s,this.conf.classNames.inset,"inset").addClass(a.nolistview+" "+a.nopanel),s.not("."+a.nolistview).addClass(a.listview);var r=this.__findAddBack(t,"."+a.listview).children();this.__refactorClass(r,this.conf.classNames.selected,"selected"),this.__refactorClass(r,this.conf.classNames.divider,"divider"),this.__refactorClass(r,this.conf.classNames.spacer,"spacer"),this.__refactorClass(this.__findAddBack(t,"."+this.conf.classNames.panel),this.conf.classNames.panel,"panel");var l=e(),d=t.add(t.find("."+a.panel)).add(this.__findAddBack(t,"."+a.listview).children().children(this.conf.panelNodetype)).not("."+a.nopanel);this.__refactorClass(d,this.conf.classNames.vertical,"vertical"),this.opts.slidingSubmenus||d.addClass(a.vertical),d.each(function(){var t=e(this),s=t;t.is("ul, ol")?(t.wrap('<div class="'+a.panel+'" />'),s=t.parent()):s.addClass(a.panel);var i=t.attr("id");t.removeAttr("id"),s.attr("id",i||n.__getUniqueId()),t.hasClass(a.vertical)&&(t.removeClass(n.conf.classNames.vertical),s.add(s.parent()).addClass(a.vertical)),l=l.add(s)});var o=e("."+a.panel,this.$menu);l.each(function(){var t=e(this),s=t.parent(),r=s.children("a, span").first();if(s.is("."+a.menu)||(s.data(i.sub,t),t.data(i.parent,s)),!s.children("."+a.next).length&&s.parent().is("."+a.listview)){var l=t.attr("id"),d=e('<a class="'+a.next+'" href="#'+l+'" data-target="#'+l+'" />').insertBefore(r);r.is("span")&&d.addClass(a.fullsubopen)}if(!t.children("."+a.navbar).length&&!s.hasClass(a.vertical)){if(s.parent().is("."+a.listview))var s=s.closest("."+a.panel);else var r=s.closest("."+a.panel).find('a[href="#'+t.attr("id")+'"]').first(),s=r.closest("."+a.panel);var o=e('<div class="'+a.navbar+'" />');if(s.length){var l=s.attr("id");switch(n.opts.navbar.titleLink){case"anchor":_url=r.attr("href");break;case"panel":case"parent":_url="#"+l;break;case"none":default:_url=!1}o.append('<a class="'+a.btn+" "+a.prev+'" href="#'+l+'" data-target="#'+l+'" />').append(e('<a class="'+a.title+'"'+(_url?' href="'+_url+'"':"")+" />").text(r.text())).prependTo(t),n.opts.navbar.add&&t.addClass(a.hasnavbar)}else n.opts.navbar.title&&(o.append('<a class="'+a.title+'">'+n.opts.navbar.title+"</a>").prependTo(t),n.opts.navbar.add&&t.addClass(a.hasnavbar))}});var c=this.__findAddBack(t,"."+a.listview).children("."+a.selected).removeClass(a.selected).last(
28663).addClass(a.selected);c.add(c.parentsUntil("."+a.menu,"li")).filter("."+a.vertical).addClass(a.opened).end().not("."+a.vertical).each(function(){e(this).parentsUntil("."+a.menu,"."+a.panel).not("."+a.vertical).first().addClass(a.opened).parentsUntil("."+a.menu,"."+a.panel).not("."+a.vertical).first().addClass(a.opened).addClass(a.subopened)}),c.children("."+a.panel).not("."+a.vertical).addClass(a.opened).parentsUntil("."+a.menu,"."+a.panel).not("."+a.vertical).first().addClass(a.opened).addClass(a.subopened);var u=o.filter("."+a.opened);return u.length||(u=l.first()),u.addClass(a.opened).last().addClass(a.current),l.not("."+a.vertical).not(u.last()).addClass(a.hidden).end().appendTo(this.$menu),l},_initAnchors:function(){var t=this;l.$body.on(r.click+"-oncanvas","a[href]",function(s){var i=e(this),r=!1,d=t.$menu.find(i).length;for(var o in e[n].addons)if(r=e[n].addons[o].clickAnchor.call(t,i,d))break;if(!r&&d){var c=i.attr("href");if(c.length>1&&"#"==c.slice(0,1))try{var u=e(c,t.$menu);u.is("."+a.panel)&&(r=!0,t[i.parent().hasClass(a.vertical)?"togglePanel":"openPanel"](u))}catch(h){}}if(r&&s.preventDefault(),!r&&d&&i.is("."+a.listview+" > li > a")&&!i.is('[rel="external"]')&&!i.is('[target="_blank"]')){t.__valueOrFn(t.opts.onClick.setSelected,i)&&t.setSelected(e(s.target).parent());var p=t.__valueOrFn(t.opts.onClick.preventDefault,i,"#"==c.slice(0,1));p&&s.preventDefault(),t.__valueOrFn(t.opts.onClick.blockUI,i,!p)&&l.$html.addClass(a.blocking),t.__valueOrFn(t.opts.onClick.close,i,p)&&t.close()}})},_initAddons:function(){for(var t in e[n].addons)e[n].addons[t].add.call(this),e[n].addons[t].add=function(){};for(var t in e[n].addons)e[n].addons[t].setup.call(this)},__api:function(){var t=this,n={};return e.each(this._api,function(){var e=this;n[e]=function(){var s=t[e].apply(t,arguments);return"undefined"==typeof s?n:s}}),n},__valueOrFn:function(e,t,n){return"function"==typeof e?e.call(t[0]):"undefined"==typeof e&&"undefined"!=typeof n?n:e},__refactorClass:function(e,t,n){return e.filter("."+t).removeClass(t).addClass(a[n])},__findAddBack:function(e,t){return e.find(t).add(e.filter(t))},__filterListItems:function(e){return e.not("."+a.divider).not("."+a.hidden)},__transitionend:function(e,t,n){var s=!1,a=function(){s||t.call(e[0]),s=!0};e.one(r.transitionend,a),e.one(r.webkitTransitionEnd,a),setTimeout(a,1.1*n)},__getUniqueId:function(){return a.mm(e[n].uniqueId++)}},e.fn[n]=function(s,a){return t(),s=e.extend(!0,{},e[n].defaults,s),a=e.extend(!0,{},e[n].configuration,a),this.each(function(){var t=e(this);if(!t.data(n)){var i=new e[n](t,s,a);t.data(n,i.__api())}})},e[n].support={touch:"ontouchstart"in window||navigator.msMaxTouchPoints,csstransitions:function(){if("undefined"!=typeof Modernizr)return Modernizr.csstransitions;var e=document.body||document.documentElement,t=e.style,n="transition";if("string"==typeof t[n])return!0;var s=["Moz","webkit","Webkit","Khtml","O","ms"];n=n.charAt(0).toUpperCase()+n.substr(1);for(var a=0;a<s.length;a++)if("string"==typeof t[s[a]+n])return!0;return!1}()};var a,i,r,l}}(jQuery);
28664/*	
28665 * jQuery mmenu offCanvas addon
28666 * mmenu.frebsite.nl
28667 *
28668 * Copyright (c) Fred Heusschen
28669 */
28670!function(t){var e="mmenu",o="offCanvas";t[e].addons[o]={setup:function(){if(this.opts[o]){var n=this.opts[o],i=this.conf[o];a=t[e].glbl,this._api=t.merge(this._api,["open","close","setPage"]),("top"==n.position||"bottom"==n.position)&&(n.zposition="front"),"string"!=typeof i.pageSelector&&(i.pageSelector="> "+i.pageNodetype),a.$allMenus=(a.$allMenus||t()).add(this.$menu),this.vars.opened=!1;var r=[s.offcanvas];"left"!=n.position&&r.push(s.mm(n.position)),"back"!=n.zposition&&r.push(s.mm(n.zposition)),this.$menu.addClass(r.join(" ")).parent().removeClass(s.wrapper),this.setPage(a.$page),this._initBlocker(),this["_initWindow_"+o](),this.$menu[i.menuInjectMethod+"To"](i.menuWrapperSelector)}},add:function(){s=t[e]._c,n=t[e]._d,i=t[e]._e,s.add("offcanvas slideout modal background opening blocker page"),n.add("style"),i.add("resize")},clickAnchor:function(t){if(!this.opts[o])return!1;var e=this.$menu.attr("id");if(e&&e.length&&(this.conf.clone&&(e=s.umm(e)),t.is('[href="#'+e+'"]')))return this.open(),!0;if(a.$page){var e=a.$page.first().attr("id");return e&&e.length&&t.is('[href="#'+e+'"]')?(this.close(),!0):!1}}},t[e].defaults[o]={position:"left",zposition:"back",modal:!1,moveBackgroun
28670d:!0},t[e].configuration[o]={pageNodetype:"div",pageSelector:null,wrapPageIfNeeded:!0,menuWrapperSelector:"body",menuInjectMethod:"prepend"},t[e].prototype.open=function(){if(!this.vars.opened){var t=this;this._openSetup(),setTimeout(function(){t._openFinish()},this.conf.openingInterval),this.trigger("open")}},t[e].prototype._openSetup=function(){var e=this;this.closeAllOthers(),a.$page.each(function(){t(this).data(n.style,t(this).attr("style")||"")}),a.$wndw.trigger(i.resize+"-offcanvas",[!0]);var r=[s.opened];this.opts[o].modal&&r.push(s.modal),this.opts[o].moveBackground&&r.push(s.background),"left"!=this.opts[o].position&&r.push(s.mm(this.opts[o].position)),"back"!=this.opts[o].zposition&&r.push(s.mm(this.opts[o].zposition)),this.opts.extensions&&r.push(this.opts.extensions),a.$html.addClass(r.join(" ")),setTimeout(function(){e.vars.opened=!0},this.conf.openingInterval),this.$menu.addClass(s.current+" "+s.opened)},t[e].prototype._openFinish=function(){var t=this;this.__transitionend(a.$page.first(),function(){t.trigger("opened")},this.conf.transitionDuration),a.$html.addClass(s.opening),this.trigger("opening")},t[e].prototype.close=function(){if(this.vars.opened){var e=this;this.__transitionend(a.$page.first(),function(){e.$menu.removeClass(s.current).removeClass(s.opened),a.$html.removeClass(s.opened).removeClass(s.modal).removeClass(s.background).removeClass(s.mm(e.opts[o].position)).removeClass(s.mm(e.opts[o].zposition)),e.opts.extensions&&a.$html.removeClass(e.opts.extensions),a.$page.each(function(){t(this).attr("style",t(this).data(n.style))}),e.vars.opened=!1,e.trigger("closed")},this.conf.transitionDuration),a.$html.removeClass(s.opening),this.trigger("close"),this.trigger("closing")}},t[e].prototype.closeAllOthers=function(){a.$allMenus.not(this.$menu).each(function(){var o=t(this).data(e);o&&o.close&&o.close()})},t[e].prototype.setPage=function(e){var n=this,i=this.conf[o];e&&e.length||(e=a.$body.find(i.pageSelector),e.length>1&&i.wrapPageIfNeeded&&(e=e.wrapAll("<"+this.conf[o].pageNodetype+" />").parent())),e.each(function(){t(this).attr("id",t(this).attr("id")||n.__getUniqueId())}),e.addClass(s.page+" "+s.slideout),a.$page=e,this.trigger("setPage",e)},t[e].prototype["_initWindow_"+o]=function(){a.$wndw.off(i.keydown+"-offcanvas").on(i.keydown+"-offcanvas",function(t){return a.$html.hasClass(s.opened)&&9==t.keyCode?(t.preventDefault(),!1):void 0});var t=0;a.$wndw.off(i.resize+"-offcanvas").on(i.resize+"-offcanvas",function(e,o){if(1==a.$page.length&&(o||a.$html.hasClass(s.opened))){var n=a.$wndw.height();(o||n!=t)&&(t=n,a.$page.css("minHeight",n))}})},t[e].prototype._initBlocker=function(){var e=this;a.$blck||(a.$blck=t('<div id="'+s.blocker+'" class="'+s.slideout+'" />')),a.$blck.appendTo(a.$body).off(i.touchstart+"-offcanvas "+i.touchmove+"-offcanvas").on(i.touchstart+"-offcanvas "+i.touchmove+"-offcanvas",function(t){t.preventDefault(),t.stopPropagation(),a.$blck.trigger(i.mousedown+"-offcanvas")}).off(i.mousedown+"-offcanvas").on(i.mousedown+"-offcanvas",function(t){t.preventDefault(),a.$html.hasClass(s.modal)||(e.closeAllOthers(),e.close())})};var s,n,i,a}(jQuery);
28671/*	
28672 * jQuery mmenu autoHeight addon
28673 * mmenu.frebsite.nl
28674 *
28675 * Copyright (c) Fred Heusschen
28676 */
28677!function(t){var e="mmenu",i="autoHeight";t[e].addons[i]={setup:function(){if(this.opts.offCanvas){switch(this.opts.offCanvas.position){case"left":case"right":return}var n=this,o=this.opts[i];if(this.conf[i],h=t[e].glbl,"boolean"==typeof o&&o&&(o={height:"auto"}),"object"!=typeof o&&(o={}),o=this.opts[i]=t.extend(!0,{},t[e].defaults[i],o),"auto"==o.height){this.$menu.addClass(s.autoheight);var u=function(t){var e=this.$menu.children("."+s.current);_top=parseInt(e.css("top"),10)||0,_bot=parseInt(e.css("bottom"),10)||0,this.$menu.addClass(s.measureheight),t=t||this.$menu.children("."+s.current),t.is("."+s.vertical)&&(t=t.parents("."+s.panel).not("."+s.vertical).first()),this.$menu.height(t.outerHeight()+_top+_bot).removeClass(s.measureheight)};this.bind("update",u),this.bind("openPanel",u),this.bind("closePanel",u),this.bind("open",u),h.$wndw.off(a.resize+"-autoheight").on(a.resize+"-autoheight",function(){u.call(n)})}}},add:function(){s=t[e]._c,n=t[e]._d,a=t[e]._e,s.add("autoheight measureheight"),a.add("resize")},clickAnchor:function(){}},t[e].defaults[i]={height:"default"};var s,n,a,h}(jQuery);
28678/*	
28679 * jQuery mmenu backButton addon
28680 * mmenu.frebsite.nl
28681 *
28682 * Copyright (c) Fred Heusschen
28683 */
28684!function(o){var t="mmenu",n="backButton";o[t].addons[n]={setup:function(){if(this.opts.offCanvas){var i=this,e=this.opts[n];if(this.conf[n],a=o[t].glbl,"boolean"==typeof e&&(e={close:e}),"object"!=typeof e&&(e={}),e=o.extend(!0,{},o[t].defaults[n],e),e.close){var c="#"+i.$menu.attr("id");this.bind("opened",function(){location.hash!=c&&history.pushState(null,document.title,c)}),o(window).on("popstate",function(o){a.$html.hasClass(s.opened)?(o.stopPropagation(),i.close()):location.hash==c&&(o.stopPropagation(),i.open())})}}},add:function(){return window.history&&window.history.pushState?(s=o[t]._c,i=o[t]._d,e=o[t]._e,void 0):(o[t].addons[n].setup=function(){},void 0)},clickAnchor:function(){}},o[t].defaults[n]={close:!1};var s,i,e,a}(jQuery);
28685/*	
28686 * jQuery mmenu counters addon
28687 * mmenu.frebsite.nl
28688 *
28689 * Copyright (c) Fred Heusschen
28690 */
28691!function(t){var n="mmenu",e="counters";t[n].addons[e]={setup:function(){var c=this,o=this.opts[e];this.conf[e],s=t[n].glbl,"boolean"==typeof o&&(o={add:o,update:o}),"object"!=typeof o&&(o={}),o=this.opts[e]=t.extend(!0,{},t[n].defaults[e],o),this.bind("init",function(n){this.__refactorClass(t("em",n),this.conf.classNames[e].counter,"counter")}),o.add&&this.bind("init",function(n){n.each(function(){var n=t(this).data(a.parent);
28691n&&(n.children("em."+i.counter).length||n.prepend(t('<em class="'+i.counter+'" />')))})}),o.update&&this.bind("update",function(){this.$menu.find("."+i.panel).each(function(){var n=t(this),e=n.data(a.parent);if(e){var s=e.children("em."+i.counter);s.length&&(n=n.children("."+i.listview),n.length&&s.html(c.__filterListItems(n.children()).length))}})})},add:function(){i=t[n]._c,a=t[n]._d,c=t[n]._e,i.add("counter search noresultsmsg")},clickAnchor:function(){}},t[n].defaults[e]={add:!1,update:!1},t[n].configuration.classNames[e]={counter:"Counter"};var i,a,c,s}(jQuery);
28692/*	
28693 * jQuery mmenu dividers addon
28694 * mmenu.frebsite.nl
28695 *
28696 * Copyright (c) Fred Heusschen
28697 */
28698!function(i){var e="mmenu",s="dividers";i[e].addons[s]={setup:function(){var n=this,a=this.opts[s];if(this.conf[s],l=i[e].glbl,"boolean"==typeof a&&(a={add:a,fixed:a}),"object"!=typeof a&&(a={}),a=this.opts[s]=i.extend(!0,{},i[e].defaults[s],a),this.bind("init",function(){this.__refactorClass(i("li",this.$menu),this.conf.classNames[s].collapsed,"collapsed")}),a.add&&this.bind("init",function(e){switch(a.addTo){case"panels":var s=e;break;default:var s=i(a.addTo,this.$menu).filter("."+d.panel)}i("."+d.divider,s).remove(),s.find("."+d.listview).not("."+d.vertical).each(function(){var e="";n.__filterListItems(i(this).children()).each(function(){var s=i.trim(i(this).children("a, span").text()).slice(0,1).toLowerCase();s!=e&&s.length&&(e=s,i('<li class="'+d.divider+'">'+s+"</li>").insertBefore(this))})})}),a.collapse&&this.bind("init",function(e){i("."+d.divider,e).each(function(){var e=i(this),s=e.nextUntil("."+d.divider,"."+d.collapsed);s.length&&(e.children("."+d.subopen).length||(e.wrapInner("<span />"),e.prepend('<a href="#" class="'+d.subopen+" "+d.fullsubopen+'" />')))})}),a.fixed){var o=function(e){e=e||this.$menu.children("."+d.current);var s=e.find("."+d.divider).not("."+d.hidden);if(s.length){this.$menu.addClass(d.hasdividers);var n=e.scrollTop()||0,t="";e.is(":visible")&&e.find("."+d.divider).not("."+d.hidden).each(function(){i(this).position().top+n<n+1&&(t=i(this).text())}),this.$fixeddivider.text(t)}else this.$menu.removeClass(d.hasdividers)};this.$fixeddivider=i('<ul class="'+d.listview+" "+d.fixeddivider+'"><li class="'+d.divider+'"></li></ul>').prependTo(this.$menu).children(),this.bind("openPanel",o),this.bind("init",function(e){e.off(t.scroll+"-dividers "+t.touchmove+"-dividers").on(t.scroll+"-dividers "+t.touchmove+"-dividers",function(){o.call(n,i(this))})})}},add:function(){d=i[e]._c,n=i[e]._d,t=i[e]._e,d.add("collapsed uncollapsed fixeddivider hasdividers"),t.add("scroll")},clickAnchor:function(i,e){if(this.opts[s].collapse&&e){var n=i.parent();if(n.is("."+d.divider)){var t=n.nextUntil("."+d.divider,"."+d.collapsed);return n.toggleClass(d.opened),t[n.hasClass(d.opened)?"addClass":"removeClass"](d.uncollapsed),!0}}return!1}},i[e].defaults[s]={add:!1,addTo:"panels",fixed:!1,collapse:!1},i[e].configuration.classNames[s]={collapsed:"Collapsed"};var d,n,t,l}(jQuery);
28699/*	
28700 * jQuery mmenu dragOpen addon
28701 * mmenu.frebsite.nl
28702 *
28703 * Copyright (c) Fred Heusschen
28704 */
28705!function(e){function t(e,t,n){return t>e&&(e=t),e>n&&(e=n),e}var n="mmenu",o="dragOpen";e[n].addons[o]={setup:function(){if(this.opts.offCanvas){var i=this,a=this.opts[o],p=this.conf[o];if(r=e[n].glbl,"boolean"==typeof a&&(a={open:a}),"object"!=typeof a&&(a={}),a=this.opts[o]=e.extend(!0,{},e[n].defaults[o],a),a.open){var d,f,c,u,h,l={},m=0,g=!1,v=!1,w=0,_=0;switch(this.opts.offCanvas.position){case"left":case"right":l.events="panleft panright",l.typeLower="x",l.typeUpper="X",v="width";break;case"top":case"bottom":l.events="panup pandown",l.typeLower="y",l.typeUpper="Y",v="height"}switch(this.opts.offCanvas.position){case"right":case"bottom":l.negative=!0,u=function(e){e>=r.$wndw[v]()-a.maxStartPos&&(m=1)};break;default:l.negative=!1,u=function(e){e<=a.maxStartPos&&(m=1)}}switch(this.opts.offCanvas.position){case"left":l.open_dir="right",l.close_dir="left";break;case"right":l.open_dir="left",l.close_dir="right";break;case"top":l.open_dir="down",l.close_dir="up";break;case"bottom":l.open_dir="up",l.close_dir="down"}switch(this.opts.offCanvas.zposition){case"front":h=function(){return this.$menu};break;default:h=function(){return e("."+s.slideout)}}var b=this.__valueOrFn(a.pageNode,this.$menu,r.$page);"string"==typeof b&&(b=e(b));var y=new Hammer(b[0],a.vendors.hammer);y.on("panstart",function(e){u(e.center[l.typeLower]),r.$slideOutNodes=h(),g=l.open_dir}).on(l.events+" panend",function(e){m>0&&e.preventDefault()}).on(l.events,function(e){if(d=e["delta"+l.typeUpper],l.negative&&(d=-d),d!=w&&(g=d>=w?l.open_dir:l.close_dir),w=d,w>a.threshold&&1==m){if(r.$html.hasClass(s.opened))return;m=2,i._openSetup(),i.trigger("opening"),r.$html.addClass(s.dragging),_=t(r.$wndw[v]()*p[v].perc,p[v].min,p[v].max)}2==m&&(f=t(w,10,_)-("front"==i.opts.offCanvas.zposition?_:0),l.negative&&(f=-f),c="translate"+l.typeUpper+"("+f+"px )",r.$slideOutNodes.css({"-webkit-transform":"-webkit-"+c,transform:c}))}).on("panend",function(){2==m&&(r.$html.removeClass(s.dragging),r.$slideOutNodes.css("transform",""),i[g==l.open_dir?"_openFinish":"close"]()),m=0})}}},add:function(){return"function"!=typeof Hammer||Hammer.VERSION<2?(e[n].addons[o].setup=function(){},void 0):(s=e[n]._c,i=e[n]._d,a=e[n]._e,s.add("dragging"),void 0)},clickAnchor:function(){}},e[n].defaults[o]={open:!1,maxStartPos:100,threshold:50,vendors:{hammer
28705:{}}},e[n].configuration[o]={width:{perc:.8,min:140,max:440},height:{perc:.8,min:140,max:880}};var s,i,a,r}(jQuery);
28706/*	
28707 * jQuery mmenu fixedElements addon
28708 * mmenu.frebsite.nl
28709 *
28710 * Copyright (c) Fred Heusschen
28711 */
28712!function(i){var s="mmenu",n="fixedElements";i[s].addons[n]={setup:function(){if(this.opts.offCanvas){this.opts[n],this.conf[n],o=i[s].glbl;var a=function(i){var s=this.conf.classNames[n].fixed;this.__refactorClass(i.find("."+s),s,"slideout").appendTo(o.$body)};a.call(this,o.$page),this.bind("setPage",a)}},add:function(){a=i[s]._c,t=i[s]._d,e=i[s]._e,a.add("fixed")},clickAnchor:function(){}},i[s].configuration.classNames[n]={fixed:"Fixed"};var a,t,e,o}(jQuery);
28713/*	
28714 * jQuery mmenu iconPanels addon
28715 * mmenu.frebsite.nl
28716 *
28717 * Copyright (c) Fred Heusschen
28718 */
28719!function(e){var n="mmenu",i="iconPanels";e[n].addons[i]={setup:function(){var a=this,l=this.opts[i];if(this.conf[i],d=e[n].glbl,"boolean"==typeof l&&(l={add:l}),"number"==typeof l&&(l={add:!0,visible:l}),"object"!=typeof l&&(l={}),l=this.opts[i]=e.extend(!0,{},e[n].defaults[i],l),l.visible++,l.add){this.$menu.addClass(s.iconpanel);for(var t=[],o=0;o<=l.visible;o++)t.push(s.iconpanel+"-"+o);t=t.join(" ");var c=function(n){var i=a.$menu.children("."+s.panel).removeClass(t),d=i.filter("."+s.subopened);d.removeClass(s.hidden).add(n).slice(-l.visible).each(function(n){e(this).addClass(s.iconpanel+"-"+n)})};this.bind("openPanel",c),this.bind("init",function(n){c.call(a,a.$menu.children("."+s.current)),l.hideNavbars&&n.removeClass(s.hasnavbar),n.each(function(){e(this).children("."+s.subblocker).length||e(this).prepend('<a href="#'+e(this).closest("."+s.panel).attr("id")+'" class="'+s.subblocker+'" />')})})}},add:function(){s=e[n]._c,a=e[n]._d,l=e[n]._e,s.add("iconpanel subblocker")},clickAnchor:function(){}},e[n].defaults[i]={add:!1,visible:3,hideNavbars:!1};var s,a,l,d}(jQuery);
28720/*	
28721 * jQuery mmenu navbar addon
28722 * mmenu.frebsite.nl
28723 *
28724 * Copyright (c) Fred Heusschen
28725 */
28726!function(n){var a="mmenu",e="navbars";n[a].addons[e]={setup:function(){var r=this,i=this.opts[e],c=this.conf[e];if(s=n[a].glbl,"undefined"!=typeof i){i instanceof Array||(i=[i]);var d={};n.each(i,function(s){var o=i[s];"boolean"==typeof o&&o&&(o={}),"object"!=typeof o&&(o={}),"undefined"==typeof o.content&&(o.content=["prev","title"]),o.content instanceof Array||(o.content=[o.content]),o=n.extend(!0,{},r.opts.navbar,o);var l=o.position,h=o.height;"number"!=typeof h&&(h=1),h=Math.min(4,Math.max(1,h)),"bottom"!=l&&(l="top"),d[l]||(d[l]=0),d[l]++;var f=n("<div />").addClass(t.navbar+" "+t.navbar+"-"+l+" "+t.navbar+"-"+l+"-"+d[l]+" "+t.navbar+"-size-"+h);d[l]+=h-1;for(var v=0,u=o.content.length;u>v;v++){var p=n[a].addons[e][o.content[v]]||!1;p?p.call(r,f,o,c):(p=o.content[v],p instanceof n||(p=n(o.content[v])),p.each(function(){f.append(n(this))}))}var b=Math.ceil(f.children().not("."+t.btn).length/h);b>1&&f.addClass(t.navbar+"-content-"+b),f.children("."+t.btn).length&&f.addClass(t.hasbtns),f.prependTo(r.$menu)});for(var o in d)r.$menu.addClass(t.hasnavbar+"-"+o+"-"+d[o])}},add:function(){t=n[a]._c,r=n[a]._d,i=n[a]._e,t.add("close hasbtns")},clickAnchor:function(){}},n[a].configuration[e]={breadcrumbSeparator:"/"},n[a].configuration.classNames[e]={panelTitle:"Title",panelNext:"Next",panelPrev:"Prev"};var t,r,i,s}(jQuery),/*	
28727 * jQuery mmenu navbar addon breadcrumbs content
28728 * mmenu.frebsite.nl
28729 *
28730 * Copyright (c) Fred Heusschen
28731 */
28732function(n){var a="mmenu",e="navbars",t="breadcrumbs";n[a].addons[e][t]=function(e,t,r){var i=n[a]._c,s=n[a]._d;i.add("breadcrumbs separator"),e.append('<span class="'+i.breadcrumbs+'"></span>'),this.bind("init",function(a){a.removeClass(i.hasnavbar).each(function(){for(var a=[],e=n(this),t=n('<span class="'+i.breadcrumbs+'"></span>'),c=n(this).children().first(),d=!0;c&&c.length;){c.is("."+i.panel)||(c=c.closest("."+i.panel));var o=c.children("."+i.navbar).children("."+i.title).text();a.unshift(d?"<span>"+o+"</span>":'<a href="#'+c.attr("id")+'">'+o+"</a>"),d=!1,c=c.data(s.parent)}t.append(a.join('<span class="'+i.separator+'">'+r.breadcrumbSeparator+"</span>")).appendTo(e.children("."+i.navbar))})});var c=function(){var n=this.$menu.children("."+i.current),a=e.find("."+i.breadcrumbs),t=n.children("."+i.navbar).children("."+i.breadcrumbs);a.html(t.html())};this.bind("openPanel",c),this.bind("init",c)}}(jQuery),/*	
28733 * jQuery mmenu navbar addon close content
28734 * mmenu.frebsite.nl
28735 *
28736 * Copyright (c) Fred Heusschen
28737 */
28738function(n){var a="mmenu",e="navbars",t="close";n[a].addons[e][t]=function(e){var t=n[a]._c,r=n[a].glbl;e.append('<a class="'+t.close+" "+t.btn+'" href="#"></a>');var i=function(n){e.find("."+t.close).attr("href","#"+n.attr("id"))};i.call(this,r.$page),this.bind("setPage",i)}}(jQuery),/*	
28739 * jQuery mmenu navbar addon next content
28740 * mmenu.frebsite.nl
28741 *
28742 * Copyright (c) Fred Heusschen
28743 */
28744function(n){var a="mmenu",e="navbars",t="next";n[a].addons[e][t]=function(t){var r=n[a]._c;t.append('<a class="'+r.next+" "+r.btn+'" href="#"></a>');var i=function(n){n=n||this.$menu.children("."+r.current);var a=t.find("."+r.next),i=n.find("."+this.conf.classNames[e].panelNext),s=i.attr("href"),c=i.html();a[s?"attr":"removeAttr"]("href",s),a[s||c?"removeClass":"addClass"](r.hidden),a.html(c)};this.bind("openPanel",i),this.bind("init",function(){i.call(this)})}}(jQuery),/*	
28745 * jQuery mmenu navbar addon prev content
28746 * mmenu.frebsite.nl
28747 *
28748 * Copyright (c) Fred Heusschen
28749 */
28750function(n){var a="mmenu",e="navbars",t="prev";n[a].addons[e][t]=function(t){var r=n[a]._c;t.append('<a class="'+r.prev+" "+r.btn+'" href="#"></a>'),this.bind("init",function(n){n.removeClass(r.hasnavbar)});var i=function(){var n=this.$menu.children("."+r.current),a=t.find("."+r.prev),i=n.find("."+this.conf.classNames[e].panelPrev);i.length||(i=n.children("."+r.navbar).children("."+r.prev));var s=i.attr("href"),c=i.html();a[s?"attr":"removeAttr"]("href",s),a[s||c?"removeClass":"addClass"](r.hidden),a.html(c)};this.bind("openPanel",i),this.bind("init",i)}}(jQuery),/*	
28751 * jQuery mmenu navbar addon searchfield content
28752 * mmenu.frebsite.nl
28753 *
28754 * Copyright (c) Fred Heusschen
28755 */
28756function(n){var a="mmenu",e="navbars",t="searchfield";n[a].addons[e][t]=function(e){var t=n[a]._c,r=n('<div class="'+t.search+'" />').appendTo(e);"object"!=typeof this.opts.searchfield&&(this.opts.searchfield={}),this.opts.searchfield.add=!0,this.opts.searchfield.addTo=r}}(jQuery),/*	
28757 * jQuery mmenu navbar addon title content
28758 * mmenu.frebsite.nl
28759 *
28760 * Copyright (c) Fred Heusschen
28761 */
28762function(n){var a="mmenu",e="navbars",t="title";n[a].addons[e][t]=function(t,r){var i=n[a]._c;t.append('<a class="'+i.title+'"></a>');var s=function(n){n=n||this.$menu.children("."+i.current);var a=t.find("."+i.title),s=n.find("."+this.conf.classNames[e].panelTitle);s.length||(s=n.children("."+i.navbar).children("."+i.title));var c=s.attr("href"),d=s.html()||r.title;a[c?"attr":"removeAttr"]("href",c),a[c||d?"removeClass":"addClass"](i.hidden),a.html(d)};
28762this.bind("openPanel",s),this.bind("init",function(){s.call(this)})}}(jQuery);
28763/*	
28764 * jQuery mmenu searchfield addon
28765 * mmenu.frebsite.nl
28766 *
28767 * Copyright (c) Fred Heusschen
28768 */
28769!function(e){function s(e){switch(e){case 9:case 16:case 17:case 18:case 37:case 38:case 39:case 40:return!0}return!1}var n="mmenu",a="searchfield";e[n].addons[a]={setup:function(){var o=this,d=this.opts[a],c=this.conf[a];r=e[n].glbl,"boolean"==typeof d&&(d={add:d}),"object"!=typeof d&&(d={}),d=this.opts[a]=e.extend(!0,{},e[n].defaults[a],d),this.bind("close",function(){this.$menu.find("."+t.search).find("input").blur()}),this.bind("init",function(n){if(d.add){switch(d.addTo){case"panels":var a=n;break;default:var a=e(d.addTo,this.$menu)}a.each(function(){var s=e(this);if(!s.is("."+t.panel)||!s.is("."+t.vertical)){if(!s.children("."+t.search).length){var n=c.form?"form":"div",a=e("<"+n+' class="'+t.search+'" />');if(c.form&&"object"==typeof c.form)for(var l in c.form)a.attr(l,c.form[l]);a.append('<input placeholder="'+d.placeholder+'" type="text" autocomplete="off" />'),s.hasClass(t.search)?s.replaceWith(a):s.prepend(a).addClass(t.hassearch)}if(d.noResults){var i=s.closest("."+t.panel).length;if(i||(s=o.$menu.children("."+t.panel).first()),!s.children("."+t.noresultsmsg).length){var r=s.children("."+t.listview).first();e('<div class="'+t.noresultsmsg+'" />').append(d.noResults)[r.length?"insertAfter":"prependTo"](r.length?r:s)}}}}),d.search&&e("."+t.search,this.$menu).each(function(){var n=e(this),a=n.closest("."+t.panel).length;if(a)var r=n.closest("."+t.panel),c=r;else var r=e("."+t.panel,o.$menu),c=o.$menu;var h=n.children("input"),u=o.__findAddBack(r,"."+t.listview).children("li"),f=u.filter("."+t.divider),p=o.__filterListItems(u),v="> a",m=v+", > span",b=function(){var s=h.val().toLowerCase();r.scrollTop(0),p.add(f).addClass(t.hidden).find("."+t.fullsubopensearch).removeClass(t.fullsubopen).removeClass(t.fullsubopensearch),p.each(function(){var n=e(this),a=v;(d.showTextItems||d.showSubPanels&&n.find("."+t.next))&&(a=m),e(a,n).text().toLowerCase().indexOf(s)>-1&&n.add(n.prevAll("."+t.divider).first()).removeClass(t.hidden)}),d.showSubPanels&&r.each(function(){var s=e(this);o.__filterListItems(s.find("."+t.listview).children()).each(function(){var s=e(this),n=s.data(l.sub);s.removeClass(t.nosubresults),n&&n.find("."+t.listview).children().removeClass(t.hidden)})}),e(r.get().reverse()).each(function(s){var n=e(this),i=n.data(l.parent);i&&(o.__filterListItems(n.find("."+t.listview).children()).length?(i.hasClass(t.hidden)&&i.children("."+t.next).not("."+t.fullsubopen).addClass(t.fullsubopen).addClass(t.fullsubopensearch),i.removeClass(t.hidden).removeClass(t.nosubresults).prevAll("."+t.divider).first().removeClass(t.hidden)):a||(n.hasClass(t.opened)&&setTimeout(function(){o.openPanel(i.closest("."+t.panel))},1.5*(s+1)*o.conf.openingInterval),i.addClass(t.nosubresults)))}),c[p.not("."+t.hidden).length?"removeClass":"addClass"](t.noresults),this.update()};h.off(i.keyup+"-searchfield "+i.change+"-searchfield").on(i.keyup+"-searchfield",function(e){s(e.keyCode)||b.call(o)}).on(i.change+"-searchfield",function(){b.call(o)})})}})},add:function(){t=e[n]._c,l=e[n]._d,i=e[n]._e,t.add("search hassearch noresultsmsg noresults nosubresults fullsubopensearch"),i.add("change keyup")},clickAnchor:function(){}},e[n].defaults[a]={add:!1,addTo:"panels",search:!0,placeholder:"Search",noResults:"No results found.",showTextItems:!1,showSubPanels:!0},e[n].configuration[a]={form:!1};var t,l,i,r}(jQuery);
28770/*	
28771 * jQuery mmenu sectionIndexer addon
28772 * mmenu.frebsite.nl
28773 *
28774 * Copyright (c) Fred Heusschen
28775 */
28776!function(e){var a="mmenu",r="sectionIndexer";e[a].addons[r]={setup:function(){var i=this,d=this.opts[r];this.conf[r],s=e[a].glbl,"boolean"==typeof d&&(d={add:d}),"object"!=typeof d&&(d={}),d=this.opts[r]=e.extend(!0,{},e[a].defaults[r],d),this.bind("init",function(a){if(d.add){switch(d.addTo){case"panels":var r=a;break;default:var r=e(d.addTo,this.$menu).filter("."+n.panel)}r.find("."+n.divider).closest("."+n.panel).addClass(n.hasindexer)}if(!this.$indexer&&this.$menu.children("."+n.hasindexer).length){this.$indexer=e('<div class="'+n.indexer+'" />').prependTo(this.$menu).append('<a href="#a">a</a><a href="#b">b</a><a href="#c">c</a><a href="#d">d</a><a href="#e">e</a><a href="#f">f</a><a href="#g">g</a><a href="#h">h</a><a href="#i">i</a><a href="#j">j</a><a href="#k">k</a><a href="#l">l</a><a href="#m">m</a><a href="#n">n</a><a href="#o">o</a><a href="#p">p</a><a href="#q">q</a><a href="#r">r</a><a href="#s">s</a><a href="#t">t</a><a href="#u">u</a><a href="#v">v</a><a href="#w">w</a><a href="#x">x</a><a href="#y">y</a><a href="#z">z</a>'),this.$indexer.children().on(t.mouseover+"-sectionindexer "+n.touchstart+"-sectionindexer",function(){var a=e(this).attr("href").slice(1),r=i.$menu.children("."+n.current),t=r.find("."+n.listview),s=!1,d=r.scrollTop(),h=t.position().top+parseInt(t.css("margin-top"),10)+parseInt(t.css("padding-top"),10)+d;r.scrollTop(0),t.children("."+n.divider).not("."+n.hidden).each(function(){s===!1&&a==e(this).text().slice(0,1).toLowerCase()&&(s=e(this).position().top+h)}),r.scrollTop(s!==!1?s:d)});var s=function(e){i.$menu[(e.hasClass(n.hasindexer)?"add":"remove")+"Class"](n.hasindexer)};this.bind("openPanel",s),s.call(this,this.$menu.children("."+n.current))}})},add:function(){n=e[a]._c,i=e[a]._d,t=e[a]._e,n.add("indexer hasindexer"),t.add("mouseover touchstart")},clickAnchor:function(e){return e.parent().is("."+n.indexer)?!0:void 0}},e[a].defaults[r]={add:!1,addTo:"panels"};var n,i,t,s}(jQuery);
28777/*	
28778 * jQuery mmenu toggles addon
28779 * mmenu.frebsite.nl
28780 *
28781 * Copyright (c) Fred Heusschen
28782 */
28783!function(t){var e="mmenu",c="toggles";t[e].addons[c]={setup:function(){var n=this;this.opts[c],this.conf[c],l=t[e].glbl,this.bind("init",function(e){this.__refactorClass(t("input",e),this.conf.classNames[c].toggle,"toggle"),this.__refactorClass(t("input",e),this.conf.classNames[c].check,"check"),t("input."+s.toggle+", input."+s.check,e).each(function(){var e=t(this),c=e.closest("li"),i=e.hasClass(s.toggle)?"toggle":"check",l=e.attr("id")||n.__getUniqueId();c.children('label[for="'+l+'"]').length||(e.attr("id",l),c.prepend(e),t('<label for="'+l+'" class="'+s[i]+'"></label>').insertBefore(c.children("a, span").last()))})})},add:function(){s=t[e]._c,n=t[e]._d,i=t[e]._e,s.add("toggle check")},clickAnchor:function(){}},t[e].configuration.classNames[c]={toggle:"Toggle",check:"Check"};var s,n,i,l}(jQuery);
28784/*jshint eqnull:true */
28785/*!
28786 * jQuery Cookie Plugin v1.2
28787 * https://github.com/carhartl/jquery-cookie
28788 *
28789 * Copyright 2011, Klaus Hartl
28790 * Dual licensed under the MIT or GPL Version 2 licenses.
28791 * http://www.opensource.org/licenses/mit-license.php
28792 * http://www.opensource.org/licenses/GPL-2.0
28793 */
28794
28795(function ($, document, undefined) {
28796
28797	var pluses = /\+/g;
28798
28799	function raw(s) {
28800		return s;
28801	}
28802
28803	function decoded(s) {
28804		return decodeURIComponent(s.replace(pluses, ' '));
28805	}
28806
28807	var config = $.cookie = function (key, value, options) {
28808
28809		// write
28810		if (value !== undefined) {
28811			options = $.extend({}, config.defaults, options);
28812
28813			if (value === null) {
28814				options.expires = -1;
28815			}
28816
28817			if (typeof options.expires === 'number') {
28818				var days = options.expires, t = options.expires = new Date();
28819				t.setDate(t.getDate() + days);
28820			}
28821
28822			value = config.json ? JSON.stringify(value) : String(value);
28823
28824			return (document.cookie = [
28825				encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
28826				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
28827				options.path    ? '; path=' + options.path : '',
28828				options.domain  ? '; domain=' + options.domain : '',
28829				options.secure  ? '; secure' : ''
28830			].join(''));
28831		}
28832
28833		// read
28834		var decode = config.raw ? raw : decoded;
28835		var cookies = document.cookie.split('; ');
28836		for (var i = 0, parts; (parts = cookies[i] && cookies[i].split('=')); i++) {
28837			if (decode(parts.shift()) === key) {
28838				var cookie = decode(parts.join('='));
28839				return config.json ? JSON.parse(cookie) : cookie;
28840			}
28841		}
28842
28843		return null;
28844	};
28845
28846	config.defaults = {};
28847
28848	$.removeCookie = function (key, options) {
28849		if ($.cookie(key, options) !== null) {
28850			$.cookie(key, null, options);
28851			return true;
28852		}
28853		return false;
28854	};
28855
28856})(jQuery, document);
28857/*! modernizr 3.3.1 (Custom Build) | MIT *
28858 * https://modernizr.com/download/?-cookies-flexbox-flexboxlegacy-flexboxtweener-flexwrap-localstorage-setclasses-shiv !*/
28859
28860!function(e,t,n){function r(e,t){return typeof e===t}function o(){var e,t,n,o,a,i,s;for(var l in x)if(x.hasOwnProperty(l)){if(e=[],t=x[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(o=r(t.fn,"function")?t.fn():t.fn,a=0;a<e.length;a++)i=e[a],s=i.split("."),1===s.length?Modernizr[s[0]]=o:(!Modernizr[s[0]]||Modernizr[s[0]]instanceof Boolean||(Modernizr[s[0]]=new Boolean(Modernizr[s[0]])),Modernizr[s[0]][s[1]]=o),y.push((o?"":"no-")+s.join("-"))}}function a(e){var t=E.className,n=Modernizr._config.classPrefix||"";if(b&&(t=t.baseVal),Modernizr._config.enableJSClass){var r=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(r,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(t+=" "+n+e.join(" "+n),b?E.className.baseVal=t:E.className=t)}function i(e,t){return!!~(""+e).indexOf(t)}function s(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):b?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function l(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function c(e,t){return function(){return e.apply(t,arguments)}}function u(e,t,n){var o;for(var a in e)if(e[a]in t)return n===!1?e[a]:(o=t[e[a]],r(o,"function")?c(o,n||t):o);return!1}function f(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function d(){var e=t.body;return e||(e=s(b?"svg":"body"),e.fake=!0),e}function p(e,n,r,o){var a,i,l,c,u="modernizr",f=s("div"),p=d();if(parseInt(r,10))for(;r--;)l=s("div"),l.id=o?o[r]:u+(r+1),f.appendChild(l);return a=s("style"),a.type="text/css",a.id="s"+u,(p.fake?p:f).appendChild(a),p.appendChild(f),a.styleSheet?a.styleSheet.cssText=e:a.appendChild(t.createTextNode(e)),f.id=u,p.fake&&(p.style.background="",p.style.overflow="hidden",c=E.style.overflow,E.style.overflow="hidden",E.appendChild(p)),i=n(f,e),p.fake?(p.parentNode.removeChild(p),E.style.overflow=c,E.offsetHeight):f.parentNode.removeChild(f),!!i}function m(t,r){var o=t.length;if("CSS"in e&&"supports"in e.CSS){for(;o--;)if(e.CSS.supports(f(t[o]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var a=[];o--;)a.push("("+f(t[o])+":"+r+")");return a=a.join(" or "),p("@supports ("+a+") { #modernizr { position: absolute; } }",function(e){return"absolute"==getComputedStyle(e,null).position})}return n}function h(e,t,o,a){function c(){f&&(delete T.style,delete T.modElem)}if(a=r(a,"undefined")?!1:a,!r(o,"undefined")){var u=m(e,o);if(!r(u,"undefined"))return u}for(var f,d,p,h,g,v=["modernizr","tspan","samp"];!T.style&&v.length;)f=!0,T.modElem=s(v.shift()),T.style=T.modElem.style;for(p=e.length,d=0;p>d;d++)if(h=e[d],g=T.style[h],i(h,"-")&&(h=l(h)),T.style[h]!==n){if(a||r(o,"undefined"))return c(),"pfx"==t?h:!0;try{T.style[h]=o}catch(y){}if(T.style[h]!=g)return c(),"pfx"==t?h:!0}return c(),!1}function g(e,t,n,o,a){var i=e.charAt(0).toUpperCase()+e.slice(1),s=(e+" "+w.join(i+" ")+i).split(" ");return r(t,"string")||r(t,"undefined")?h(s,t,o,a):(s=(e+" "+_.join(i+" ")+i).split(" "),u(s,t,n))}function v(e,t,r){return g(e,n,n,t,r)}var y=[],x=[],C={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){x.push({name:e,fn:t,options:n})},addAsyncTest:function(e){x.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=C,Modernizr=new Modernizr,Modernizr.addTest("cookies",function(){try{t.cookie="cookietest=1";var e=-1!=t.cookie.indexOf("cookietest=");return t.cookie="cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT",e}catch(n){return!1}}),Modernizr.addTest("localstorage",function(){var e="modernizr";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(t){return!1}});var E=t.documentElement,b="svg"===E.nodeName.toLowerCase();b||!function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=x.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=x.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),x.elements=n+" "+e,c(t)}function a(e){var t=y[e[g]];return t||(t={},v++,e[g]=v,y[v]=t),t}function i(e,n,r){if(n||(n=t),f)return n.createElement(e);r||(r=a(n));var o;return o=r.cache[e]?r.cache[e].cloneNode():h.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!o.canHaveChildren||m.test(e)||o.tagUrn?o:r.frag.appendChild(o)}function s(e,n){if(e||(e=t),f)return e.createDocumentFragment();n=n||a(e);for(var o=n.frag.cloneNode(),i=0,s=r(),l=s.length;l>i;i++)o.createElement(s[i]);return o}function l(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return x.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(x,t.frag)}function c(e){e||(e=t);var r=a(e);return!x.shivCSS||u||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
28860play:block}mark{background:#FF0;color:#000}template{display:none}")),f||l(e,r),e}var u,f,d="3.7.3",p=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,h=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",v=0,y={};!function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",u="hidden"in e,f=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){u=!0,f=!0}}();var x={elements:p.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:d,shivCSS:p.shivCSS!==!1,supportsUnknownElements:f,shivMethods:p.shivMethods!==!1,type:"default",shivDocument:c,createElement:i,createDocumentFragment:s,addElements:o};e.html5=x,c(t),"object"==typeof module&&module.exports&&(module.exports=x)}("undefined"!=typeof e?e:this,t);var S="Moz O ms Webkit",w=C._config.usePrefixes?S.split(" "):[];C._cssomPrefixes=w;var _=C._config.usePrefixes?S.toLowerCase().split(" "):[];C._domPrefixes=_;var k={elem:s("modernizr")};Modernizr._q.push(function(){delete k.elem});var T={style:k.elem.style};Modernizr._q.unshift(function(){delete T.style}),C.testAllProps=g,C.testAllProps=v,Modernizr.addTest("flexbox",v("flexBasis","1px",!0)),Modernizr.addTest("flexboxlegacy",v("boxDirection","reverse",!0)),Modernizr.addTest("flexboxtweener",v("flexAlign","end",!0)),Modernizr.addTest("flexwrap",v("flexWrap","wrap",!0)),o(),a(y),delete C.addTest,delete C.addAsyncTest;for(var N=0;N<Modernizr._q.length;N++)Modernizr._q[N]();e.Modernizr=Modernizr}(window,document);
28861/*
28862  Modified by Robert Gerald Porter, for Weever Apps Inc.
28863
28864  Version:  1.1.4
28865  Release:  January 29, 2014
28866
28867  Based upon Mobile Bookmark Bubble by Google Inc., original copyrights and license below.
28868
28869  Changelog:
28870
28871  1.0.1  :  - First public release of fork.
28872          - Added support for Android phones, Blackberry Touch Smartphones (OS6+), BlackBerry PlayBook.
28873          - Modified colour and layout.
28874          - Added WebkitBackgroundSize = "contain" to handle high-resolution icons
28875          - Added base64-encoded images for iOS Safari "forward" button, PlayBook "save bookmark" icon, BlackBerry button icon.
28876          - Fixed layout issue with close button.
28877          - Moved location of bubble on PlayBook to match location of the "save bookmark" UI.
28878  1.1.0 : - Fork by okamototk
28879          - Support jQuery Mobile.
28880          - Internationalization and Japanese translation.
28881          - Optimize bubble icon size.
28882  1.1.1 : - Android 4.0 support.
28883  1.1.2 : - Android 4.0 Tablet / Mobile both support.
28884  1.1.3 : - Fork by wiifm
28885          - iOS7 support.
28886  1.1.4 : - Fork by triq6
28887          - Chrome for Android 32+ support
28888
28889  ##########################
28890
28891  Copyright 2010 Google Inc.
28892
28893  Licensed under the Apache License, Version 2.0 (the "License");
28894  you may not use this file except in compliance with the License.
28895  You may obtain a copy of the License at
28896
28897       http://www.apache.org/licenses/LICENSE-2.0
28898
28899  Unless required by applicable law or agreed to in writing, software
28900  distributed under the License is distributed on an "AS IS" BASIS,
28901  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28902  See the License for the specific language governing permissions and
28903  limitations under the License.
28904*/
28905
28906/**
28907 * @fileoverview Bookmark bubble library. This is meant to be included in the
28908 * main JavaScript binary of a mobile web application.
28909 *
28910 * Supported browsers: iPhone / iPod / iPad Safari 3.0+
28911 */
28912
28913
28914var google = google || {};
28915google.bookmarkbubble = google.bookmarkbubble || {};
28916
28917
28918/**
28919 * Binds a context object to the function.
28920 * @param {Function} fn The function to bind to.
28921 * @param {Object} context The "this" object to use when the function is run.
28922 * @return {Function} A partially-applied form of fn.
28923 */
28924google.bind = function(fn, context) {
28925  return function() {
28926    return fn.apply(context, arguments);
28927  };
28928};
28929
28930
28931/**
28932 * Function used to define an abstract method in a base class. If a subclass
28933 * fails to override the abstract method, then an error will be thrown whenever
28934 * that method is invoked.
28935 */
28936google.abstractMethod = function() {
28937  throw Error('Unimplemented abstract method.');
28938};
28939
28940
28941
28942/**
28943 * The bubble constructor. Instantiating an object does not cause anything to
28944 * be rendered yet, so if necessary you can set instance properties before
28945 * showing the bubble.
28946 * @constructor
28947 */
28948google.bookmarkbubble.Bubble = function() {
28949  /**
28950   * Handler for the scroll event. Keep a reference to it here, so it can be
28951   * unregistered when the bubble is destroyed.
28952   * @type {function()}
28953   * @private
28954   */
28955  this.boundScrollHandler_ = google.bind(this.setPosition, this);
28956
28957  /**
28958   * The bubble element.
28959   * @type {Element}
28960   * @private
28961   */
28962  this.element_ = null;
28963
28964  /**
28965   * Whether the bubble has been destroyed.
28966   * @type {boolean}
28967   * @private
28968   */
28969  this.hasBeenDestroyed_ = false;
28970};
28971
28972
28973/**
28974 * Shows the bubble if allowed. It is not allowed if:
28975 * - The browser is not Mobile Safari, or
28976 * - The user has dismissed it too often already, or
28977 * - The hash parameter is present in the location hash, or
28978 * - The application is in fullscreen mode, which means it was already loaded
28979 *   from a homescreen bookmark.
28980 * @return {boolean} True if the bubble is being shown, false if it is not
28981 *     allowed to show for one of the aforementioned reasons.
28982 */
28983google.bookmarkbubble.Bubble.prototype.showIfAllowed = function() {
28984  if (!this.isAllowedToShow_()) {
28985    return false;
28986  }
28987
28988  this.show_();
28989  return true;
28990};
28991
28992
28993/**
28994 * Shows the bubble if allowed after loading the icon image. This method creates
28995 * an image element to load the image into the browser's cache before showing
28996 * the bubble to ensure that the image isn't blank. Use this instead of
28997 * showIfAllowed if the image url is http and cacheable.
28998 * This hack is necessary because Mobile Safari does not properly render
28999 * image elements with border-radius CSS.
29000 * @param {function()} opt_callback Closure to be called if and when the bubble
29001 *        actually shows.
29002 * @return {boolean} True if the bubble is allowed to show.
29003 */
29004google.bookmarkbubble.Bubble.prototype.showIfAllowedWhenLoaded =
29005    function(opt_callback) {
29006  if (!this.isAllowedToShow_()) {
29007    return false;
29008  }
29009
29010  var self = this;
29011  // Attach to self to avoid garbage collection.
29012  var img = self.loadImg_ = document.createElement('img');
29013  img.src = self.getIconUrl_();
29014  img.onload = function() {
29015    if (img.complete) {
29016      delete self.loadImg_;
29017      img.onload = null;  // Break the circular reference.
29018
29019      self.show_();
29020      opt_callback && opt_callback();
29021    }
29022  };
29023  img.onload();
29024
29025  return true;
29026};
29027
29028
29029/**
29030 * Sets the parameter in the location hash. As it is
29031 * unpredictable what hash scheme is to be used, this method must be
29032 * implemented by the host application.
29033 *
29034 * This gets called automatically when the bubble is shown. The idea is that if
29035 * the user then creates a bookmark, we can later recognize on application
29036 * startup whether it was from a bookmark suggested with this bubble.
29037 *
29038 * NOTE: Using a hash parameter to track whether the bubble has been shown
29039 * conflicts with the navigation system in jQuery Mobile. If you are using that
29040 * library, you should implement this function to track the bubble's status in
29041 * a different way, e.g. using window.localStorage in HTML5.
29042 */
29043google.bookmarkbubble.Bubble.prototype.setHashParameter = google.abstractMethod;
29044
29045
29046/**
29047 * Whether the parameter is present in the location hash. As it is
29048 * unpredictable what hash scheme is to be used, this method must be
29049 * implemented by the host application.
29050 *
29051 * Call this method during application startup if you want to log whether the
29052 * application was loaded from a bookmark with the bookmark bubble promotion
29053 * parameter in it.
29054 *
29055 * @return {boolean} Whether the bookmark bubble parameter is present in the
29056 *     location hash.
29057 */
29058google.bookmarkbubble.Bubble.prototype.hasHashParameter = google.abstractMethod;
29059
29060/**
29061 * The number of times the user must dismiss the bubble before we stop showing
29062 * it. This is a public property and can be changed by the host application if
29063 * necessary.
29064 * @type {number}
29065 */
29066google.bookmarkbubble.Bubble.prototype.NUMBER_OF_TIMES_TO_DISMISS = 2;
29067
29068
29069/**
29070 * Time in milliseconds. If the user does not dismiss the bubble, it will auto
29071 * destruct after this amount of time.
29072 * @type {number}
29073 */
29074google.bookmarkbubble.Bubble.prototype.TIME_UNTIL_AUTO_DESTRUCT = 15000;
29075
29076
29077/**
29078 * The prefix for keys in local storage. This is a public property and can be
29079 * changed by the host application if necessary.
29080 * @type {string}
29081 */
29082google.bookmarkbubble.Bubble.prototype.LOCAL_STORAGE_PREFIX = 'BOOKMARK_';
29083
29084
29085/**
29086 * The key name for the dismissed state.
29087 * @type {string}
29088 * @private
29089 */
29090google.bookmarkbubble.Bubble.prototype.DISMISSED_ = 'DISMISSED_COUNT';
29091
29092
29093/**
29094 * The arrow image in base64 data url format.
29095 * @type {string}
29096 * @private
29097 */
29098google.bookmarkbubble.Bubble.prototype.IMAGE_ARROW_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAZCAMAAAAYAM5SAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzJFNTUzOTVGM0Q5MTFFMDk1OUZGOTUxMzQxOTZBOTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzJFNTUzOTZGM0Q5MTFFMDk1OUZGOTUxMzQxOTZBOTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3MkU1NTM5M0YzRDkxMUUwOTU5RkY5NTEzNDE5NkE5NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3MkU1NTM5NEYzRDkxMUUwOTU5RkY5NTEzNDE5NkE5NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmaTRQ0AAAAMUExURe7u7v////X19f///0GahZ4AAAAEdFJOU////wBAKqn0AAAAR0lEQVR42tzJyQEAIAgDMND9d/ZGWmEB843UTYsArWJF54rPFx0UHhYclT8ud0/de8suqHNR7QtrXVzzkhqXVb+0hl+rCTAAtw4F95zesBUAAAAASUVORK5CYII=';
29099
29100
29101/**
29102 * The close image in base64 data url format.
29103 * @type {string}
29104 * @private
29105 */
29106google.bookmarkbubble.Bubble.prototype.IMAGE_CLOSE_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i
2910677u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjhEMjhFOTJGMzI4MTFFMDk1OUZGOTUxMzQxOTZBOTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjhEMjhFOTNGMzI4MTFFMDk1OUZGOTUxMzQxOTZBOTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpERDM2MDFBNUYyMjkxMUUwOTU5RkY5NTEzNDE5NkE5NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpERDM2MDFBNkYyMjkxMUUwOTU5RkY5NTEzNDE5NkE5NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjMAla0AAAAwUExURTMzM6ioqEpKSs3NzTo6OmpqakNDQ+Li4ioqKlpaWnZ2doeHh5qamlZWVlFRUeTk5IUDvwkAAAIJSURBVHja3JbZsoMgDIZZg6DA+7/tScIWtTOltyfYqQQ//oRN1fGjKaV+JRyoBW+ZM7khbtfARK+aGJg9K9GfmAwSeL9n0aeLwnNQSt6yiCKaUgIoWBGW19+9IcY0EJPjh/J2TYQCi5uREXKwyq+5OEKirdPseMTW0F3BL5WBZM8t7XfmTLpX96AldmSpUnK5WitTkRx+alQdM3kKI0dH0HSPoYZwUd2GwDWMNLaZzE/Et3T4QXzmGiKh+jX7PTDHC8bkxL0iE4IufkZVz7lg8lQhGaKu0S2OkKUAOTHbWulqyEGLDGW42DlqoStyImaUPAPrCK7t8LbUmhZydKTvh/MJVF3kfvGJEeXEDtP1jthiXkjPfzrtHfGPXUm5PBBz3mT0YyNLlVHiTQUXlwFRzECIYTMAbTpELrE1GG4tkdPniRn2GDFakSDM0HFxU4EP81JPibBKT6aZnb2LlOJCMLCrI51Zo2XzYqx7qKil4lc0SVTCKZGpwgfu6liDc1qENs7kgRyMgLvEKsFqESMN4LjAVMHInBORJKAuxIBf4+SfKiQjFpfuUYhR8x3JEtFz2i30PpNc0HeEkkmvHtGs2DZv5KO9/FAmopzidrUuJUHV3S77O/K9SBX2PB6Qt+OuLJX2hv7+Dpcqm6/9qXL8I0Rtf8Nk/rqQZ/I36yc/fSj4TcMXsv4TYADp7j2MNhJKiAAAAABJRU5ErkJggg==';
29107
29108
29109google.bookmarkbubble.Bubble.prototype.IMAGE_BLACKBERRY_ICON_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA7BpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wUmlnaHRzPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvcmlnaHRzLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcFJpZ2h0czpNYXJrZWQ9IkZhbHNlIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6Rjc3RjExNzQwNzIwNjgxMThGNjJERkQwMEY0QTI1MDUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjBCMkE0OTU4QkMwMTFFMEE4MDNEMUFBM0ZDREM1QjgiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjBCMkE0OTQ4QkMwMTFFMEE4MDNEMUFBM0ZDREM1QjgiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MzJGOTcxODNCRDhCRTAxMUEwRTNGNjkyNUFDRkE2MTkiIHN0UmVmOmRvY3VtZW50SUQ9InV1aWQ6MTBCREIxMUNGRjVBRTAxMUJDRDJBNzcxMjgxOTJDMzgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz55WxUmAAAB70lEQVR42sRTTaupURhdL07yUeSrzGTga2hgRilGkpmpCUoZGTP3A85A/oGZgYGBOkchUUpkIFK+opOI1EnYx7PvvW/OrTs6g/vU8+79rr33s9dae2+BMYafhAQ/DNlkMqGW1Wo1SCQSWK1WaLVaweFwsFKphMvlApPJhEAgQPOE8/kMYq1Wq/H+/g7kcjlK0iFmt9tlnU7nG5bNZtn1esVqtcJyucThcEC5XIas1Wp9o6TX66HT6VCpVERMKpXCYrHgd7HnEITtdov1es2Ox6Mo4fPzU3j02Xw+57OMRiMeGwkajYYlk0mOqVQqvL6+QkZV2+02brcb5HI5nE4nDAYDp/fx8cF393q9aDQafOF+vxfbxWIBGZmXSqVETqPRCPl8niUSCRArCiqaTqd5nzahdLvdiEajkPV6vYcQgdMn/cFgEOPxGOQ2YUqlEuFwmONms5ljxKpQKAj8HpAmMpJkDAYDbgwZ1u/3MRwOMZvNOEZSCacilPRfLBa5B8Kzrff7HfV6Hc1mk1P1eDzIZDKoVqvY7XbivOl0+usiPS9WKBTw+XyIRCJ4e3sT8c1mw0heLBbDy8sLbDYb4vH49wJ2u/1Pl5EHFKTf7/fzI/ubqXiV6eNyufD8qMjd0+nEzz8UCv1zMR/476/xS4ABAJ70zF1PPvhAAAAAAElFTkSuQmCC';
29110
29111
29112google.bookmarkbubble.Bubble.prototype.IMAGE_SAFARI_FORWARD_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAkCAYAAAD2IghRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAgZJREFUeNrsl99HQ2EYx8/WRImyP2BELFGWJWIXxW4SdVOKSJFSiixdJyK66WKJXaQUkbopdR/RbpqNSCNKRCQ2IrpZ35fncGRnO++Pnc7JvnwutvOec74e3+d5z+uJRqOazfoAE+BS5iFezX75wQXYBLVuMq5rBVyBZrcZZ+oBaTDoNuNMjeAMxHmi4wTjuhbADWhxm3GmMEVn2G3GmRrACUiAOrNFPlAQePgzxzRg6yJkKMTxjhlq3hGQLWacVxnQV2ZNkDLLpkVAovrt4BbMg0OZqOTIdM7keoQmxAMZDyiKzgHYM0aH1/iaiWm9MtciM9miJqlx28yi4hHYAddltm8OBalAiz6Jh9SAHWoiO8Xe65cxHv8D0y9gDCRF53gMzNls+hx0MNOiGxCbxRsC97FZnBK47xssgSGQl5njiTKNmKKqJMnsPfgyXOfZ8J5oA0rJbkCjoLvI/3dgnzaJd0XROAXTxirLGI/9+s2OX6uCESgVjWWwXWoRj/GwodpvlLtjxQ34SNHIqPw61D81WRxaK2CaRaPTimle4wNgl07oeYWGWePOUqU/rd5kNSrs4+aVmkWlsrShZHhv9HJUpV+x6SPQZWK6yYknIFaEKTBuEo1emt+aqqmiSvUlrm3RtNKcaNxMaZ6jnZMOy6FKNKfjVDVut4o1Z6Fa8arxf2T8R4ABAMxNWkZtHiMqAAAAAElFTkSuQmCC';
29113
29114
29115google.bookmarkbubble.Bubble.prototype.IMAGE_IOS7_FORWARD_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAtCAMAAADm86mrAAABMlBMVEUAAAACbP/k8v4AWf+qzf1hpf0HdP8Cbv+21v0fhf2v0P282P0xkv200/1CnP0AbP8Ab/8Ae/+22P0Bd/8Aav8ReP58sv4OeP8BdP8HeP/u9v4Gb/8Abv/Y6/7R5v3V6v2hzf1apf1Gmv1Pov5Vof0Sef5Wo/2v1P0efv5Zpf2Ow/2y0/252P0Aaf+82/30+f71+f4EcP+52f2Dtv4Yfv8ef/76/P4AU/+szf2sz/2v0/35/P4JaP+/2v34+/6q0f1Wof0AXf+myv6t0P0AXP/k8f7y+P4vkP73+v7+//8Abf8AYf8AZv8AZf8AaP8KdP/////8/f+01P0Oef/z+f7T5/37/f/e7v71+v4AY/+y1P32+/6v0f34/P4BbP/9/v8AZ//3+/601f11rv0Ldf8AZP81S/JRAAAAAXRSTlMAQObYZgAAAP5JREFUeNrt0NlOwkAUgOEDAgIqKqs7Ki6AyuIGLmyuFFpAgdpapFO07/8KNCk0mQba4coL+l+ci5MvJ5OBye0dfgB5u5uNGLn+2lhbRwctQh3d8SwHfKtHhLe3Q+xSkPUzJ0S6drwFK7QI+/WEue5m4xKAFynjFJVN/+e93VFmD/0os9TomvFOFTQOr0CSxuF/+C0njOIeNK7thIyOX9OyGlN5HPNUbrTjL/hPnLdvLr/Vngtjns7fq6vzJH+G8+aV0dtFWXf979eIS/LA4nPH7/jiLPzpRZiFt97AjONZ3OJ4gp43w0ac1fOIkxKnRtmRG+eu+mJ/arbagkNlQ2Wzhs4sFDqpAAAAAElFTkSuQmCC';
29116
29117
29118google.bookmarkbubble.Bubble.prototype.IMAGE_PLAYBOOK_BOOKMARK_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAA0CAMAAADypuvZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i
2911877u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjhEMjhFOTZGMzI4MTFFMDk1OUZGOTUxMzQxOTZBOTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjhEMjhFOTdGMzI4MTFFMDk1OUZGOTUxMzQxOTZBOTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2OEQyOEU5NEYzMjgxMUUwOTU5RkY5NTEzNDE5NkE5NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2OEQyOEU5NUYzMjgxMUUwOTU5RkY5NTEzNDE5NkE5NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pmi5WPMAAAAwUExURb29vdPT08fHx5aWluTk5GlpaXx8fOzs7KysrPX19VZWVoiIiP39/WFhYaKiov///2c8oVAAAAAQdFJOU////////////////////wDgI10ZAAABEElEQVR42uzW0ZKDIAwF0CCRACH0//92rdVaBYHs085seSQeB66QER6/GPBF/wsFCOVkjLGJaCY9ggh6xJHVCCUKahEsdVCixEudkw6RLHWhz6fPo4ZgrYAO8VphFUJZK0V+zT3B9j7QIN4Qd9CU/XvY99LtMZmnEiHH9mCsLC/5pvGpvqdpviViboNAd2McNm5usFVjQ/O6VzfmU69HFBubp4HGgmc141A3OqfhhloYyTlsGkFw2RMMoHRN3aY+oiI96iOzB+D3QEwfbV/X0oO2hfo+Wt8vrxmQRuhw6Q5uX5FxtU5RoGfg+TifId+G/jFrr2dtOYu2g0iKq4OuHvqBTC6vTsjm+x/xJ9CPAAMAEPqQqkGB5zYAAAAASUVORK5CYII=';
29119
29120
29121google.bookmarkbubble.Bubble.prototype.IMAGE_ANDROID3_BOOKMARK_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAACMUlEQVRYR+2WzcdqURTGIxGJSEQiEpGIlGgUKY0SiWiURmnyJiLRIJESKY0S6R9d129TqnPq7HN6r1zuQxzb2ms961kfO5d8Ga4vx5d/m0C/3xd+n+AjBeLxuMRisU/iOy/BYrEQCCSTSZnP545JOFagUCjIcDiUwWAgfDuFIwLH4/FB+mg0Kpw5gSMCjUZDqtXqLV6tVpN6ve4kvrMeIOP9fn8LuNvtHDejbQUYu2w2a8g2k8mofrALUwJkN5vN5OfnR3q9niB5qVRSzeb3+2U6nRriMAk+n0/ZYMudbrerGhV7fK5WK8O9BwJk4HK5BInz+bzKtFwuS6vVUkRGo5Gs1+uXSW42GxXwSpq7KAOpSCSifD8vLoMCGAQCgYca25X12X673UooFDLdmqYlQDKv1yvj8fjT2Eo1fE0mE1NfL5uQmlFv5HQKegA1Kc0rvJ2Cy+Ui4XBYmHO7YE9w93Q6vb2qNYbsezpbF8ViUdLptJa5FgGUCAaDWg6xpeGsMr860yJAUzJOukilUtovpBaBdrttqw/omWazqcVXiwALiXF6Bmdm48V5Lpf7PQL86zkcDjeH1JeScM6P7/vnmG+2qQ4sFWCL8c/nCsrBbHc6HcPZvexMzrv5125CFlGlUpHlcqnmmnKcz2dDcqjCzmdaeC94B3SWmKUCNJTb7ZZEImH6Cj4z4VVEMY/Ho4hbwZIAI4XsdsEdnWVkScBu4Ht7s/f/2d9fJaBD/j+BryvwBySPr9aPfFVqAAAAAElFTkSuQmCC';
29122
29123
29124google.bookmarkbubble.Bubble.prototype.IMAGE_ANDROID4_MOBILE_BOOKMARK_DATA_URL_ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABYSURBVFhH7ZRBCgAgDMOs//+zimdPpVCQ7AMrWTOtM6M4s7j7riYABORYIOnZXUcoTgCBOgHLguT7tgKgYfIE9RISwLIg2QErABomT4AFdQKWBXQAAl8R2B3oJR7LKvEUAAAAAElFTkSuQmCC';
29125
29126/**
29127 * Popup message to create shortcut to Home.
29128 */
29129google.bookmarkbubble.Bubble.prototype.msg = {
29130  android:
29131    '<b>Install this app:</b><br /> 1) Add to Bookmarks,<br /> 2) Tap and Hold the bookmark,<br /> 3) Select "<b>Add Shortcut to Home</b>"',
29132  android3:
29133    '<b>Install this app:</b><br /> Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_ANDROID3_BOOKMARK_DATA_URL_ +'" style="height: 1.5em;display: inline-block;padding:0;margin:0;" />,<br /> select "<b>Add to</b>" and then "<b>Home screen</b>"',
29134  android4:
29135    '<b>Install this app:</b><br /> 1) Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_ANDROID4_MOBILE_BOOKMARK_DATA_URL_ +'" style="height: 1.5em;display: inline-block;padding:0;margin:0;" />,<br /> 2) Select "<b>Save to bookmarks</b>",<br /> 3) Select "<b>Add to</b>" and then "<b>Home</b>"',
29136  android41:
29137    '<b>Install this app:</b><br /> 1) Add to Bookmarks,<br /> 2) Tap and Hold the bookmark,<br /> 3) Select "<b>Add Shortcut</b>"',
29138  chrome32:
29139    '<b>Install this app:</b><br /> 1) Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_ANDROID4_MOBILE_BOOKMARK_DATA_URL_ +'" style="height: 1.5em;display: inline-block;padding:0;margin:0;" />,<br /> 2) Select "<b>Add to homescreen</b>"',
29140  blackberry:
29141    '<b>Install this app:</b><br /> Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_BLACKBERRY_ICON_DATA_URL_ +'" style="height: 1em;display: inline-block;padding:0;margin:0" />, select "<b>Add to Home Screen</b>"',
29142  playbook:
29143     '<b>Install this app:</b><br /> Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_PLAYBOOK_BOOKMARK_DATA_URL_ +'" style="height: 1.5em;display: inline-block;padding:0;margin:0;" />, select  <br />"<b>Add to Home Screen</b>"',
29144  ios42orlater :
29145     '<b>Install this app</b>:<br /> Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_SAFARI_FORWARD_DATA_URL_ +'" style="height: 1em;display: inline-block;padding: 0;margin: 0" /> and then <b>"Add to Home Screen"</b>',
29146  ios7orlater :
29147     '<b>Install this app</b>:<br /> Tap <img src="'+ google.bookmarkbubble.Bubble.prototype.IMAGE_IOS7_FORWARD_DATA_URL_ +'" style="height: 2em;display: inline-block;padding: 0;margin: 0" /> and then <b>"Add to Home Screen"</b>',
29148  ioslegacy: '<b>Install this app</b>:<br /> Tap <b style="font-size:15px">+</b> and then <b>"Add to Home Screen"</b>'
29149};
29150
29151
29152/**
29153 * The link used to locate the application's home screen icon to display inside
29154 * the bubble. The default link used here is for an iPhone home screen icon
29155 * without gloss. If your application uses a glossy icon, change this to
29156 * 'apple-touch-icon'.
29157 * @type {string}
29158 * @private
29159 */
29160google.bookmarkbubble.Bubble.prototype.REL_ICON_ =
29161    'apple-touch-icon-precomposed';
29162
29163
29164/**
29165 * Regular expression for detecting an iPhone or iPod or iPad.
29166 * @type {!RegExp}
29167 * @private
29168 */
29169google.bookmarkbubble.Bubble.prototype.MOBILE_SAFARI_USERAGENT_REGEX_ =
29170    /iPhone|iPod|iPad|Android|BlackBerry|PlayBook/;
29171
29172
29173/**
29174 * Regular expression for detecting an iPad.
29175 * @type {!RegExp}
29176 * @private
29177 */
29178google.bookmarkbubble.Bubble.prototype.IPAD_USERAGENT_REGEX_ = /iPad/;
29179
29180/**
29181* additional stuffs for Android, BlackBerry
29182*/
29183google.bookmarkbubble.Bubble.prototype.ANDROID_USERAGENT_REGEX_ = /Android/;
29184google.bookmarkbubble.Bubble.prototype.CHROME_USERAGENT_REGEX_ = /Chrome/;
29185google.bookmarkbubble.Bubble.prototype.BLACKBERRY_USERAGENT_REGEX_ = /BlackBerry/;
29186google.bookmarkbubble.Bubble.prototype.PLAYBOOK_USERAGENT_REGEX_ = /PlayBook/;
29187
29188/**
29189 * Regular expression for extracting the iOS version. Only matches 2.0 and up.
29190 * @type {!RegExp}
29191 * @private
29192 */
29193google.bookmarkbubble.Bubble.prototype.IOS_VERSION_USERAGENT_REGEX_ =
29194    /OS (\d)_(\d)(?:_(\d))?/;
29195
29196/**
29197 * Regular expression for extracting the Android version.
29198 * @type {!RegExp}
29199 * @private
29200 */
29201google.bookmarkbubble.Bubble.prototype.ANDROID_VERSION_USERAGENT_REGEX_ =
29202    /Android (\d)\.(\d)(?:\.(\d))?/;
29203
29204/**
29205 * Regular expression for extracting the Chrome version.
29206 * @type {!RegExp}
29207 * @private
29208 */
29209google.bookmarkbubble.Bubble.prototype.CHROME_VERSION_USERAGENT_REGEX_ =
29210    /CHROME\/(\d)\.(\d)(?:\.(\d))?/;
29211
29212
29213/**
29214 * Determines whether the bubble should be shown or not.
29215 * @return {boolean} Whether the bubble should be shown or not.
29216 * @private
29217 */
29218google.bookmarkbubble.Bubble.prototype.isAllowedToShow_ = function() {
29219  return this.isMobileSafari_() &&
29220      !this.hasBeenDismissedTooManyTimes_() &&
29221      !this.isFullscreen_() &&
29222      !this.hasHashParameter();
29223};
29224
29225
29226/**
29227 * Builds and shows the bubble.
29228 * @private
29229 */
29230google.bookmarkbubble.Bubble.prototype.show_ = function() {
29231  this.element_ = this.build_();
29232
29233  document.body.appendChild(this.element_);
29234  this.element_.style.WebkitTransform =
29235      'translate3d(0,' + this.getHiddenYPosition_() + 'px,0)';
29236
29237  this.setHashParameter();
29238
29239  window.setTimeout(this.boundScrollHandler_, 1);
29240  window.addEventListener('scroll', this.boundScrollHandler_, false);
29241
29242  // If the user does not dismiss the bubble, slide out and destroy it after
29243  // some time.
29244  window.setTimeout(google.bind(this.autoDestruct_, this),
29245      this.TIME_UNTIL_AUTO_DESTRUCT);
29246};
29247
29248
29249/**
29250 * Destroys the bubble by removing its DOM nodes from the document.
29251 */
29252google.bookmarkbubble.Bubble.prototype.destroy = function() {
29253  if (this.hasBeenDestroyed_) {
29254    return;
29255  }
29256  window.removeEventListener('scroll', this.boundScrollHandler_, false);
29257  if (this.element_ && this.element_.parentNode == document.body) {
29258    document.body.removeChild(this.element_);
29259    this.element_ = null;
29260  }
29261  this.hasBeenDestroyed_ = true;
29262};
29263
29264
29265/**
29266 * Remember that the user has dismissed the bubble once more.
29267 * @private
29268 */
29269google.bookmarkbubble.Bubble.prototype.rememberDismissal_ = function() {
29270  if (window.localStorage) {
29271    try {
29272      var key = this.LOCAL_STORAGE_PREFIX + this.DISMISSED_;
29273      var value = Number(window.localStorage[key]) || 0;
29274      window.localStorage[key] = String(value + 1);
29275    } catch (ex) {
29276      // Looks like we've hit the storage size limit. Currently we have no
29277      // fallback for this scenario, but we could use cookie storage instead.
29278      // This would increase the code bloat though.
29279    }
29280  }
29281};
29282
29283
29284/**
29285 * Whether the user has dismissed the bubble often enough that we will not
29286 * show it again.
29287 * @return {boolean} Whether the user has dismissed the bubble often enough
29288 *     that we will not show it again.
29289 * @private
29290 */
29291google.bookmarkbubble.Bubble.prototype.hasBeenDismissedTooManyTimes_ =
29292    function() {
29293  if (!window.localStorage) {
29294    // If we can not use localStorage to remember how many times the user has
29295    // dismissed the bubble, assume he has dismissed it. Otherwise we might end
29296    // up showing it every time the host application loads, into eternity.
29297    return false;
29298  }
29299  try {
29300    var key = this.LOCAL_STORAGE_PREFIX + this.DISMISSED_;
29301
29302    // If the key has never been set, localStorage yields undefined, which
29303    // Number() turns into NaN. In that case we'll fall back to zero for
29304    // clarity's sake.
29305    var value = Number(window.localStorage[key]) || 0;
29306
29307    return value >= this.NUMBER_OF_TIMES_TO_DISMISS;
29308  } catch (ex) {
29309    // If we got here, something is wrong with the localStorage. Make the same
29310    // assumption as when it does not exist at all. Exceptions should only
29311    // occur when setting a value (due to storage limitations) but let's be
29312    // extra careful.
29313    return true;
29314  }
29315};
29316
29317
29318/**
29319 * Whether the application is running in fullscreen mode.
29320 * @return {boolean} Whether the application is running in fullscreen mode.
29321 * @private
29322 */
29323google.bookmarkbubble.Bubble.prototype.isFullscreen_ = function() {
29324  return !!window.navigator.standalone;
29325};
29326
29327
29328/**
29329 * Whether the application is running inside Mobile Safari.
29330 * @return {boolean} True if the current user agent looks like Mobile Safari.
29331 * @private
29332 */
29333google.bookmarkbubble.Bubble.prototype.isMobileSafari_ = function() {
29334  return this.MOBILE_SAFARI_USERAGENT_REGEX_.test(window.navigator.userAgent);
29335};
29336
29337
29338/**
29339 * Whether the application is running on an iPad.
29340 * @return {boolean} True if the current user agent looks like an iPad.
29341 * @private
29342 */
29343google.bookmarkbubble.Bubble.prototype.isIpad_ = function() {
29344  return this.IPAD_USERAGENT_REGEX_.test(window.navigator.userAgent);
29345};
29346
29347google.bookmarkbubble.Bubble.prototype.isAndroid_ = function() {
29348  return this.ANDROID_USERAGENT_REGEX_.test(window.navigator.userAgent);
29349};
29350
29351google.bookmarkbubble.Bubble.prototype.isChrome_ = function() {
29352  return this.CHROME_USERAGENT_REGEX_.test(window.navigator.userAgent);
29353};
29354
29355google.bookmarkbubble.Bubble.prototype.isBlackBerry_ = function() {
29356  return this.BLACKBERRY_USERAGENT_REGEX_.test(window.navigator.userAgent);
29357};
29358
29359google.bookmarkbubble.Bubble.prototype.isPlayBook_ = function() {
29360  return this.PLAYBOOK_USERAGENT_REGEX_.test(window.navigator.userAgent);
29361};
29362
29363
29364/**
29365 * Creates a version number from 4 integer pieces between 0 and 127 (inclusive).
29366 * @param {*=} opt_a The major version.
29367 * @param {*=} opt_b The minor version.
29368 * @param {*=} opt_c The revision number.
29369 * @param {*=} opt_d The build number.
29370 * @return {number} A representation of the version.
29371 * @private
29372 */
29373google.bookmarkbubble.Bubble.prototype.getVersion_ = function(opt_a, opt_b,
29374    opt_c, opt_d) {
29375  // We want to allow implicit conversion of any type to number while avoiding
29376  // compiler warnings about the type.
29377  return /** @type {number} */ (opt_a) << 21 |
29378      /** @type {number} */ (opt_b) << 14 |
29379      /** @type {number} */ (opt_c) << 7 |
29380      /** @type {number} */ (opt_d);
29381};
29382
29383
29384/**
29385 * Gets the iOS version of the device. Only works for 2.0+.
29386 * @return {number} The iOS version.
29387 * @private
29388 */
29389google.bookmarkbubble.Bubble.prototype.getIosVersion_ = function() {
29390  var groups = this.IOS_VERSION_USERAGENT_REGEX_.exec(
29391      window.navigator.userAgent) || [];
29392  groups.shift();
29393  return this.getVersion_.apply(this, groups);
29394};
29395
29396/**
29397 * Gets the Android version of the device.
29398 * @return {number} The Android version.
29399 * @private
29400 */
29401google.bookmarkbubble.Bubble.prototype.getAndroidVersion_ = function() {
29402  var groups = this.ANDROID_VERSION_USERAGENT_REGEX_.exec(
29403      window.navigator.userAgent) || [];
29404  groups.shift();
29405  return this.getVersion_.apply(this, groups);
29406};
29407
29408/**
29409 * Gets the Chrome version of the device.
29410 * @return {number} The Chrome version.
29411 * @private
29412 */
29413google.bookmarkbubble.Bubble.prototype.getChromeVersion_ = function() {
29414  var groups = this.CHROME_VERSION_USERAGENT_REGEX_.exec(
29415      window.navigator.userAgent) || [];
29416  groups.shift();
29417  return this.getVersion_.apply(this, groups);
29418};
29419
29420google.bookmarkbubble.Bubble.prototype.isMobile_ = function() {
29421  return window.navigator.userAgent.indexOf("Mobile Safari") >= 0;
29422};
29423
29424/**
29425 * Positions the bubble at the bottom of the viewport using an animated
29426 * transition.
29427 */
29428google.bookmarkbubble.Bubble.prototype.setPosition = function() {
29429  this.element_.style.WebkitTransition = '-webkit-transform 0.7s ease-out';
29430  this.element_.style.WebkitTransform =
29431      'translate3d(0,' + this.getVisibleYPosition_() + 'px,0)';
29432};
29433
29434
29435/**
29436 * Destroys the bubble by removing its DOM nodes from the document, and
29437 * remembers that it was dismissed.
29438 * @private
29439 */
29440google.bookmarkbubble.Bubble.prototype.closeClickHandler_ = function() {
29441  this.destroy();
29442  this.rememberDismissal_();
29443};
29444
29445
29446/**
29447 * Gets called after a while if the user ignores the bubble.
29448 * @private
29449 */
29450google.bookmarkbubble.Bubble.prototype.autoDestruct_ = function() {
29451  if (this.hasBeenDestroyed_) {
29452    return;
29453  }
29454  this.element_.style.WebkitTransition = '-webkit-transform 0.7s ease-in';
29455  this.element_.style.WebkitTransform =
29456      'translate3d(0,' + this.getHiddenYPosition_() + 'px,0)';
29457  window.setTimeout(google.bind(this.destroy, this), 700);
29458};
29459
29460
29461/**
29462 * Gets the y offset used to show the bubble (i.e., position it on-screen).
29463 * @return {number} The y offset.
29464 * @private
29465 */
29466google.bookmarkbubble.Bubble.prototype.getVisibleYPosition_ = function() {
29467  return this.isIpad_() || this.isPlayBook_() || this.getAndroidVersion_() >= this.getVersion_(3, 0) ?
29468      window.pageYOffset + 17 :
29469      window.pageYOffset - this.element_.offsetHeight + window.innerHeight - 17;
29470};
29471
29472
29473/**
29474 * Gets the y offset used to hide the bubble (i.e., position it off-screen).
29475 * @return {number} The y offset.
29476 * @private
29477 */
29478google.bookmarkbubble.Bubble.prototype.getHiddenYPosition_ = function() {
29479  return this.isIpad_() || this.isPlayBook_() || this.getAndroidVersion_() >= this.getVersion_(3, 0) ?
29480      window.pageYOffset - this.element_.offsetHeight :
29481      window.pageYOffset + window.innerHeight;
29482};
29483
29484
29485/**
29486 * The url of the app's bookmark icon.
29487 * @type {string|undefined}
29488 * @private
29489 */
29490google.bookmarkbubble.Bubble.prototype.iconUrl_;
29491
29492
29493/**
29494 * Scrapes the document for a link element that specifies an Apple favicon and
29495 * returns the icon url. Returns an empty data url if nothing can be found.
29496 * @return {string} A url string.
29497 * @private
29498 */
29499google.bookmarkbubble.Bubble.prototype.getIconUrl_ = function() {
29500  if (!this.iconUrl_) {
29501    var link = this.getLink(this.REL_ICON_);
29502    if (!link || !(this.iconUrl_ = link.href)) {
29503      this.iconUrl_ = 'data:image/png;base64,';
29504    }
29505  }
29506  return this.iconUrl_;
29507};
29508
29509
29510/**
29511 * Gets the requested link tag if it exists.
29512 * @param {string} rel The rel attribute of the link tag to get.
29513 * @return {Element} The requested link tag or null.
29514 */
29515google.bookmarkbubble.Bubble.prototype.getLink = function(rel) {
29516  rel = rel.toLowerCase();
29517  var links = document.getElementsByTagName('link');
29518  for (var i = 0; i < links.length; ++i) {
29519    var currLink = /** @type {Element} */ (links[i]);
29520    if (currLink.getAttribute('rel').toLowerCase() == rel) {
29521      return currLink;
29522    }
29523  }
29524  return null;
29525};
29526
29527
29528/**
29529 * Creates the bubble and appends it to the document.
29530 * @return {Element} The bubble element.
29531 * @private
29532 */
29533google.bookmarkbubble.Bubble.prototype.build_ = function() {
29534  var bubble = document.createElement('div'),
29535      isIpad = this.isIpad_(),
29536      isAndroid = this.isAndroid_(),
29537      isPlayBook = this.isPlayBook_(),
29538      isBlackBerry = this.isBlackBerry_();
29539
29540
29541  bubble.style.position = 'absolute';
29542  bubble.style.zIndex = 100000;
29543  bubble.style.width = '100%';
29544  bubble.style.left = '0';
29545  bubble.style.top = '0';
29546
29547  var bubbleInner = document.createElement('div');
29548  bubbleInner.style.position = 'relative';
29549  bubbleInner.style.width = '214px';
29550  if (this.getAndroidVersion_() >= this.getVersion_(3, 0)) {
29551    bubbleInner.style.margin = '0 0 0 ' +(window.innerWidth - 240) + 'px';
29552  } else {
29553    bubbleInner.style.margin = isIpad ? '0 0 0 82px' : '0 auto';
29554  }
29555  bubbleInner.style.border = '2px solid #fff';
29556  bubbleInner.style.padding = '1em 1.5em 1em 0.5em';
29557  bubbleInner.style.WebkitBorderRadius = '8px';
29558  bubbleInner.style.WebkitBoxShadow = '0 0 8px rgba(0, 0, 0, 0.7)';
29559  bubbleInner.style.WebkitBackgroundSize = '100% 8px';
29560  bubbleInner.style.backgroundColor = '#eee';
29561  bubbleInner.style.background = '#cddcf3 -webkit-gradient(linear, ' +
29562      'left bottom, left top, ' + isIpad || isPlayBook || this.getAndroidVersion_() >= this.getVersion_(3, 0) ?
29563          'from(#cddcf3), to(#b3caed)) no-repeat top' :
29564          'from(#b3caed), to(#cddcf3)) no-repeat bottom';
29565  bubbleInner.style.font = '0.75em sans-serif';
29566  bubble.appendChild(bubbleInner);
29567
29568  // The "Add to Home Screen" text is intended to be the exact same text
29569  // that is displayed in the menu of Android / Mobile Safari.
29570  if (isAndroid) {
29571    console.log('we got android!');
29572    bubbleInner.style.font = '0.625em sans-serif';
29573    if (this.getChromeVersion_() < this.getVersion_(32, 0)) {
29574      console.log('we got chrome!');
29575      bubbleInner.innerHTML = this.msg.chrome32;
29576    } else if (this.getAndroidVersion_() < this.getVersion_(3, 0)) {
29577      bubbleInner.innerHTML = this.msg.android;
29578    } else {
29579      if ((this.getAndroidVersion_() < this.getVersion_(4, 0)) && this.isMobile_()) {
29580        bubbleInner.innerHTML = this.msg.android3;
29581      }
29582      else {
29583        if ((this.getAndroidVersion_() < this.getVersion_(4, 1)) && this.isMobile_()) {
29584          bubbleInner.innerHTML = this.msg.android4;
29585        }
29586        else {
29587          bubbleInner.innerHTML = this.msg.android41;
29588        }
29589      }
29590    }
29591  }
29592  else if (isBlackBerry) {
29593    bubbleInner.innerHTML = this.msg.blackberry;
29594  }
29595  else if(isPlayBook) {
29596    bubbleInner.innerHTML = this.msg.playbook;
29597    bubbleInner.style.position = 'absolute';
29598    bubbleInner.style.right = '0px';
29599  }
29600  else {
29601    if (this.getIosVersion_() >= this.getVersion_(7, 0)) {
29602      bubbleInner.innerHTML = this.msg.ios7orlater;
29603    }
29604    else if (this.getIosVersion_() >= this.getVersion_(4, 2)) {
29605      bubbleInner.innerHTML = this.msg.ios42orlater;
29606    }
29607    else {
29608      bubbleInner.innerHTML = this.msg.ioslegacy;
29609    }
29610  }
29611
29612  var icon = document.createElement('div');
29613  icon.style['float'] = 'left';
29614  icon.style.width = '55px';
29615  icon.style.height = '55px';
29616  icon.style.margin = '-2px 7px 3px 5px';
29617  icon.style.background =
29618      '#fff url(' + this.getIconUrl_() + ') no-repeat 0 0';
29619  icon.style.WebkitBackgroundSize = 'contain';
29620  icon.style.WebkitBorderRadius = '10px';
29621  icon.style.WebkitBoxShadow = '0 2px 5px rgba(0, 0, 0, 0.4)';
29622  bubbleInner.insertBefore(icon, bubbleInner.firstChild);
29623
29624  // var arrow = document.createElement('div');
29625  // arrow.style.backgroundImage = 'url(' + this.IMAGE_ARROW_DATA_URL_ + ')';
29626  // arrow.style.width = '25px';
29627  // arrow.style.height = '19px';
29628  // arrow.style.position = 'absolute';
29629  // arrow.style.left = '111px';
29630  // if (isIpad || isPlayBook) {
29631  //   arrow.style.WebkitTransform = 'rotate(180deg)';
29632  //   arrow.style.top = '-19px';
29633  //   arrow.style.left = '111px';
29634  // } else if ((this.getAndroidVersion_() >= this.getVersion_(3, 0)) || (this.getChromeVersion_() >= this.getVersion_(32, 0))) {
29635  //   arrow.style.WebkitTransform = 'scale(1, -1)';
29636  //   arrow.style.top = '-19px';
29637  //   arrow.style.left = '180px';
29638  // } else {
29639  //   arrow.style.bottom = '-19px';
29640  //   arrow.style.left = '111px';
29641  // }
29642  // bubbleInner.appendChild(arrow);
29643
29644  var close = document.createElement('a');
29645  close.onclick = google.bind(this.closeClickHandler_, this);
29646  close.style.position = 'absolute';
29647  close.style.display = 'block';
29648  close.style.top = '5px';
29649  close.style.right = '5px';
29650  close.style.width = '16px';
29651  close.style.height = '16px';
29652  // close.style.border = '10px solid transparent';
29653  close.style.background =
29654      'url(' + this.IMAGE_CLOSE_DATA_URL_ + ') no-repeat';
29655  close.style.WebkitBackgroundSize = "contain";
29656  bubbleInner.appendChild(close);
29657
29658  return bubble;
29659};
29660!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.svg4everybody=b()}):"object"==typeof module&&module.exports?module.exports=b():a.svg4everybody=b()}(this,function(){function a(a,b,c){if(c){var d=document.createDocumentFragment(),e=!b.hasAttribute("viewBox")&&c.getAttribute("viewBox");e&&b.setAttribute("viewBox",e);for(var f=c.cloneNode(!0);f.childNodes.length;)d.appendChild(f.firstChild);a.appendChild(d)}}function b(b){b.onreadystatechange=function(){if(4===b.readyState){var c=b._cachedDocument;c||(c=b._cachedDocument=document.implementation.createHTMLDocument(""),c.body.innerHTML=b.responseText,b._cachedTarget={}),b._embeds.splice(0).map(function(d){var e=b._cachedTarget[d.id];e||(e=b._cachedTarget[d.id]=c.getElementById(d.id)),a(d.parent,d.svg,e)})}},b.onreadystatechange()}function c(c){function e(){for(var c=0;c<o.length;){var h=o[c],i=h.parentNode,j=d(i);if(j){var k=h.getAttribute("xlink:href")||h.getAttribute("href");!k&&g.attributeName&&(k=h.getAttribute(g.attributeName));if(f)if(!g.validate||g.validate(k,j,h)){i.removeChild(h);var l=k.split("#"),q=l.shift(),r=l.join("#");if(q.length){var s=m[q];
29660s||(s=m[q]=new XMLHttpRequest,s.open("GET",q),s.send(),s._embeds=[]),s._embeds.push({parent:i,svg:j,id:r}),b(s)}else a(i,j,document.getElementById(r))}else++c,++p}else++c}(!o.length||o.length-p>0)&&n(e,67)}var f,g=Object(c),h=/\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/,i=/\bAppleWebKit\/(\d+)\b/,j=/\bEdge\/12\.(\d+)\b/,k=/\bEdge\/.(\d+)\b/,l=window.top!==window.self;f="polyfill"in g?g.polyfill:h.test(navigator.userAgent)||(navigator.userAgent.match(j)||[])[1]<10547||(navigator.userAgent.match(i)||[])[1]<537||k.test(navigator.userAgent)&&l;var m={},n=window.requestAnimationFrame||setTimeout,o=document.getElementsByTagName("use"),p=0;f&&e()}function d(a){for(var b=a;"svg"!==b.nodeName.toLowerCase()&&(b=b.parentNode););return b}return c});
29661/*
29662 Copyright (C) Federico Zivolo 2019
29663 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
29664 */
29665(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}
vendor: 3,236 bytes, line 29665
29665function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10
vendor: 13,566 bytes, line 29665
29665);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f]
vendor: 2,544 bytes, line 29665
29665,10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;
29665void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
29666
29667var tippy=function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;function e(){return(e=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t}).apply(this,arguments)}var n={passive:!0},r="tippy-iOS",i="tippy-popper",o="tippy-tooltip",a="tippy-content",p="tippy-backdrop",u="tippy-arrow",s="tippy-svg-arrow",c="."+i,l="."+o,f="."+a,d="."+u,v="."+s;function m(t,e){t.innerHTML=e}function h(t){return!(!t||!t._tippy||t._tippy.reference!==t)}function g(t,e){return{}.hasOwnProperty.call(t,e)}function b(t){return A(t)?[t]:function(t){return E(t,"NodeList")}(t)?k(t):Array.isArray(t)?t:k(document.querySelectorAll(t))}function y(t,e,n){if(Array.isArray(t)){var r=t[e];return null==r?Array.isArray(n)?n[e]:n:r}return t}function w(t,e){return t&&t.modifiers&&t.modifiers[e]}function E(t,e){var n={}.toString.call(t);return 0===n.indexOf("[object")&&n.indexOf(e+"]")>-1}function A(t){return E(t,"Element")}function T(t){return E(t,"MouseEvent")}function C(t,e){return"function"==typeof t?t.apply(void 0,e):t}function x(t,e,n,r){t.filter(function(t){return t.name===e})[0][n]=r}function I(){return document.createElement("div")}function O(t,e){t.forEach(function(t){t&&(t.style.transitionDuration=e+"ms")})}function D(t,e){t.forEach(function(t){t&&t.setAttribute("data-state",e)})}function L(t,e){return 0===e?t:function(r){clearTimeout(n),n=setTimeout(function(){t(r)},e)};var n}function M(t,e,n){t&&t!==e&&t.apply(void 0,n)}function k(t){return[].slice.call(t)}function S(t,e){for(;t;){if(e(t))return t;t=t.parentElement}return null}function P(t,e){return t.indexOf(e)>-1}function V(t){return t.split(/\s+/).filter(Boolean)}function B(t,e){return void 0!==t?t:e}function H(t){return[].concat(t)}function U(t){var e=H(t)[0];return e&&e.ownerDocument||document}function N(t,e){-1===t.indexOf(e)&&t.push(e)}function R(t){return"number"==typeof t?t:parseFloat(t)}function z(t,e,n){void 0===e&&(e=5);var r={top:0,right:0,bottom:0,left:0};return Object.keys(r).reduce(function(r,i){return r[i]="number"==typeof e?e:e[i],t===i&&(r[i]="number"==typeof e?e+n:e[t]+n),r},r)}var q={isTouch:!1},F=0;function j(){q.isTouch||(q.isTouch=!0,window.performance&&document.addEventListener("mousemove",_))}function _(){var t=performance.now();t-F<20&&(q.isTouch=!1,document.removeEventListener("mousemove",_)),F=t}function W(){var t=document.activeElement;if(h(t)){var e=t._tippy;t.blur&&!e.state.isVisible&&t.blur()}}var X="undefined"!=typeof window&&"undefined"!=typeof document,Y=X?navigator.userAgent:"",J=/MSIE |Trident\//.test(Y),G=/UCBrowser\//.test(Y),K=X&&/iPhone|iPad|iPod/.test(navigator.platform);function Q(t){var e=t&&K&&q.isTouch;document.body.classList[e?"add":"remove"](r)}var Z={allowHTML:!0,animateFill:!1,animation:"fade",appendTo:function(){return document.body},aria:"describedby",arrow:!0,boundary:"scrollParent",content:"",delay:0,distance:10,duration:[300,250],flip:!0,flipBehavior:"flip",flipOnUpdate:!1,followCursor:!1,hideOnClick:!0,ignoreAttributes:!1,inl
29667inePositioning:!1,inertia:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,lazy:!0,maxWidth:350,multiple:!1,offset:0,onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},placement:"top",plugins:[],popperOptions:{},role:"tooltip",showOnCreate:!1,sticky:!1,theme:"",touch:!0,trigger:"mouseenter focus",triggerTarget:null,updateDuration:0,zIndex:9999},$=Object.keys(Z),tt=["arrow","boundary","distance","flip","flipBehavior","flipOnUpdate","offset","placement","popperOptions"];function et(t){return e({},t,{},t.plugins.reduce(function(e,n){var r=n.name,i=n.defaultValue;return r&&(e[r]=void 0!==t[r]?t[r]:i),e},{}))}function nt(t,n){var r=e({},n,{content:C(n.content,[t])},n.ignoreAttributes?{}:function(t,n){return(n?Object.keys(et(e({},Z,{plugins:n}))):$).reduce(function(e,n){var r=(t.getAttribute("data-tippy-"+n)||"").trim();if(!r)return e;if("content"===n)e[n]=r;else try{e[n]=JSON.parse(r)}catch(t){e[n]=r}return e},{})}(t,n.plugins));return r.interactive&&(r.aria=null),r}function rt(t){return t.split("-")[0]}function it(t){t.setAttribute("data-inertia","")}function ot(t){t.setAttribute("data-interactive","")}function at(t,e){if(A(e.content))m(t,""),t.appendChild(e.content);else if("function"!=typeof e.content){t[e.allowHTML?"innerHTML":"textContent"]=e.content}}function pt(t){return{tooltip:t.querySelector(l),content:t.querySelector(f),arrow:t.querySelector(d)||t.querySelector(v)}}function ut(t){var e=I();return!0===t?e.className=u:(e.className=s,A(t)?e.appendChild(t):m(e,t)),e}function st(t,e){var n=I();n.className=i,n.style.position="absolute",n.style.top="0",n.style.left="0";var r=I();r.className=o,r.id="tippy-"+t,r.setAttribute("data-state","hidden"),r.setAttribute("tabindex","-1"),ft(r,"add",e.theme);var p=I();return p.className=a,p.setAttribute("data-state","hidden"),e.interactive&&ot(r),e.arrow&&(r.setAttribute("data-arrow",""),r.appendChild(ut(e.arrow))),e.inertia&&it(r),at(p,e),r.appendChild(p),n.appendChild(r),ct(n,e,e),n}function ct(t,e,n){var r,i=pt(t),o=i.tooltip,a=i.content,p=i.arrow;t.style.zIndex=""+n.zIndex,o.setAttribute("data-animation",n.animation),o.style.maxWidth="number"==typeof(r=n.maxWidth)?r+"px":r,n.role?o.setAttribute("role",n.role):o.removeAttribute("role"),e.content!==n.content&&at(a,n),!e.arrow&&n.arrow?(o.appendChild(ut(n.arrow)),o.setAttribute("data-arrow","")):e.arrow&&!n.arrow?(o.removeChild(p),o.removeAttribute("data-arrow")):e.arrow!==n.arrow&&(o.removeChild(p),o.appendChild(ut(n.arrow))),!e.interactive&&n.interactive?ot(o):e.interactive&&!n.interactive&&function(t){t.removeAttribute("data-interactive")}(o),!e.inertia&&n.inertia?it(o):e.inertia&&!n.inertia&&function(t){t.removeAttribute("data-inertia")}(o),e.theme!==n.theme&&(ft(o,"remove",e.theme),ft(o,"add",n.theme))}function lt(t,e,n){var r=G&&void 0!==document.body.style.webkitTransition?"webkitTransitionEnd":"transitionend";t[e+"EventListener"](r,n)}function ft(t,e,n){V(n).forEach(function(n){t.classList[e](n+"-theme")})}var dt=1,vt=[],mt=[];function ht(r,i){var o,a,p,u=et(nt(r,i));if(!u.multiple&&r._tippy)return null;var s,l,f,d,v,m=!1,h=!1,b=0,E=[],A=L(Ot,u.interactiveDebounce),I=U(u.triggerTarget||r),F=dt++,j=st(F,u),_=pt(j),W=(v=u.plugins).filter(function(t,e){return v.indexOf(t)===e}),X=_.tooltip,Y=_.content,G=[X,Y],K={id:F,reference:r,popper:j,popperChildren:_,popperInstance:null,props:u,state:{currentPlacement:null,isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:W,clearDelayTimeouts:function(){clearTimeout(o),clearTimeout(a),cancelAnimationFrame(p)},setProps:function(t){if(K.state.isDestroyed)return;ft("onBeforeUpdate",[K,t]),xt();var n=K.props,i=nt(r,e({},K.props,{},t,{ignoreAttributes:!0}));i.ignoreAttributes=B(t.ignoreAttributes,n.ignoreAttributes),K.props=i,Ct(),n.interactiveDebounce!==i.interactiveDebounce&&(bt(),A=L(Ot,i.interactiveDebounce));ct(j,n,i),K.popperChildren=pt(j),n.triggerTarget&&!i.triggerTarget?H(n.triggerTarget).forEach(function(t){t.removeAttribute("aria-expanded")}):i.triggerTarget&&r.removeAttribute("aria-expanded");gt(),K.popperInstance&&(tt.some(function(e){return g(t,e)&&t[e]!==n[e]})?(K.popperInstance.destroy(),kt(),K.state.isVisible&&K.popperInstance.enableEventListeners()):K.popperInstance.update(
29667));ft("onAfterUpdate",[K,t])},setContent:function(t){K.setProps({content:t})},show:function(t){void 0===t&&(t=y(K.props.duration,0,Z.duration));var e=K.state.isVisible,n=K.state.isDestroyed,r=!K.state.isEnabled,i=q.isTouch&&!K.props.touch;if(e||n||r||i)return;if(at().hasAttribute("disabled"))return;K.popperInstance||kt();if(ft("onShow",[K],!1),!1===K.props.onShow(K))return;wt(),j.style.visibility="visible",K.state.isVisible=!0,K.state.isMounted||O(G.concat(j),0);l=function(){K.state.isVisible&&(O([j],K.props.updateDuration),O(G,t),D(G,"visible"),ht(),gt(),N(mt,K),Q(!0),K.state.isMounted=!0,ft("onMount",[K]),function(t,e){At(t,e)}(t,function(){K.state.isShown=!0,ft("onShown",[K])}))},function(){b=0;var t,e=K.props.appendTo,n=at();t=K.props.interactive&&e===Z.appendTo||"parent"===e?n.parentNode:C(e,[n]);t.contains(j)||t.appendChild(j);x(K.popperInstance.modifiers,"flip","enabled",K.props.flip),K.popperInstance.enableEventListeners(),K.popperInstance.update()}()},hide:function(t){void 0===t&&(t=y(K.props.duration,1,Z.duration));var e=!K.state.isVisible&&!m,n=K.state.isDestroyed,r=!K.state.isEnabled&&!m;if(e||n||r)return;if(ft("onHide",[K],!1),!1===K.props.onHide(K)&&!m)return;Et(),j.style.visibility="hidden",K.state.isVisible=!1,K.state.isShown=!1,O(G,t),D(G,"hidden"),ht(),gt(),function(t,e){At(t,function(){!K.state.isVisible&&j.parentNode&&j.parentNode.contains(j)&&e()})}(t,function(){K.popperInstance.disableEventListeners(),K.popperInstance.options.placement=K.props.placement,j.parentNode.removeChild(j),0===(mt=mt.filter(function(t){return t!==K})).length&&Q(!1),K.state.isMounted=!1,ft("onHidden",[K])})},enable:function(){K.state.isEnabled=!0},disable:function(){K.hide(),K.state.isEnabled=!1},destroy:function(){if(K.state.isDestroyed)return;m=!0,K.clearDelayTimeouts(),K.hide(0),xt(),delete r._tippy,K.popperInstance&&K.popperInstance.destroy();m=!1,K.state.isDestroyed=!0,ft("onDestroy",[K])}};r._tippy=K,j._tippy=K;var $=W.map(function(t){return t.fn(K)});return Ct(),gt(),u.lazy||kt(),ft("onCreate",[K]),u.showOnCreate&&Pt(),j.addEventListener("mouseenter",function(){K.props.interactive&&K.state.isVisible&&K.clearDelayTimeouts()}),j.addEventListener("mouseleave",function(){K.props.interactive&&P(K.props.trigger,"mouseenter")&&I.addEventListener("mousemove",A)}),K;function it(){var t=K.props.touch;return Array.isArray(t)?t:[t,0]}function ot(){return"hold"===it()[0]}function at(){return d||r}function ut(t){return K.state.isMounted&&!K.state.isVisible||q.isTouch||!s||"focus"===s.type?0:y(K.props.delay,t?0:1,Z.delay)}function ft(t,e,n){var r;(void 0===n&&(n=!0),$.forEach(function(n){g(n,t)&&n[t].apply(n,e)}),n)&&(r=K.props)[t].apply(r,e)}function ht(){var t=K.props.aria;if(t){var e="aria-"+t,n=X.id;H(K.props.triggerTarget||r).forEach(function(t){var r=t.getAttribute(e);if(K.state.isVisible)t.setAttribute(e,r?r+" "+n:n);else{var i=r&&r.replace(n,"").trim();i?t.setAttribute(e,i):t.removeAttribute(e)}})}}function gt(){H(K.props.triggerTarget||r).forEach(function(t){K.props.interactive?t.setAttribute("aria-expanded",K.state.isVisible&&t===at()?"true":"false"):t.removeAttribute("aria-expanded")})}function bt(){I.body.removeEventListener("mouseleave",Vt),I.removeEventListener("mousemove",A),vt=vt.filter(function(t){return t!==A})}function yt(t){if(!K.props.interactive||!j.contains(t.target)){if(at().contains(t.target)){if(q.isTouch)return;if(K.state.isVisible&&P(K.props.trigger,"click"))return}!0===K.props.hideOnClick&&(K.clearDelayTimeouts(),K.hide(),h=!0,setTimeout(function(){h=!1}),K.state.isMounted||Et())}}function wt(){I.addEventListener("mousedown",yt,!0)}function Et(){I.removeEventListener("mousedown",yt,!0)}function At(t,e){function n(t){t.target===X&&(lt(X,"remove",n),e())}if(0===t)return e();lt(X,"remove",f),lt(X,"add",n),f=n}function Tt(t,e,n){void 0===n&&(n=!1),H(K.props.triggerTarget||r).forEach(function(r){r.addEventListener(t,e,n),E.push({node:r,eventType:t,handler:e,options:n})})}function Ct(){ot()&&(Tt("touchstart",It,n),Tt("touchend",Dt,n)),V(K.props.trigger).forEach(function(t){if("manual"!==t)switch(Tt(t,It),t){case"mouseenter":Tt("mouseleave",Dt);break;
29667case"focus":Tt(J?"focusout":"blur",Lt)}})}function xt(){E.forEach(function(t){var e=t.node,n=t.eventType,r=t.handler,i=t.options;e.removeEventListener(n,r,i)}),E=[]}function It(t){if(K.state.isEnabled&&!Mt(t)&&!h)if(s=t,d=t.currentTarget,gt(),!K.state.isVisible&&T(t)&&vt.forEach(function(e){return e(t)}),"click"===t.type&&!1!==K.props.hideOnClick&&K.state.isVisible)Vt(t);else{var e=it(),n=e[0],r=e[1];q.isTouch&&"hold"===n&&r?o=setTimeout(function(){Pt(t)},r):Pt(t)}}function Ot(t){S(t.target,function(t){return t===r||t===j})||function(t,e){var n=e.clientX,r=e.clientY;return t.every(function(t){var e=t.popperRect,i=t.tooltipRect,o=t.interactiveBorder,a=Math.min(e.top,i.top),p=Math.max(e.right,i.right),u=Math.max(e.bottom,i.bottom),s=Math.min(e.left,i.left);return a-r>o||r-u>o||s-n>o||n-p>o})}(k(j.querySelectorAll(c)).concat(j).map(function(t){var e=t._tippy,n=e.popperChildren.tooltip,r=e.props.interactiveBorder;return{popperRect:t.getBoundingClientRect(),tooltipRect:n.getBoundingClientRect(),interactiveBorder:r}}),t)&&(bt(),Vt(t))}function Dt(t){if(!Mt(t))return K.props.interactive?(I.body.addEventListener("mouseleave",Vt),I.addEventListener("mousemove",A),void N(vt,A)):void Vt(t)}function Lt(t){t.target===at()&&(K.props.interactive&&t.relatedTarget&&j.contains(t.relatedTarget)||Vt(t))}function Mt(t){var e="ontouchstart"in window,n=P(t.type,"touch"),r=ot();return e&&q.isTouch&&r&&!n||q.isTouch&&!r&&n}function kt(){var n,i=K.props.popperOptions,o=K.popperChildren.arrow,a=w(i,"flip"),p=w(i,"preventOverflow");function u(t){var e=K.state.currentPlacement;K.state.currentPlacement=t.placement,K.props.flip&&!K.props.flipOnUpdate&&(t.flipped&&(K.popperInstance.options.placement=t.placement),x(K.popperInstance.modifiers,"flip","enabled",!1)),X.setAttribute("data-placement",t.placement),!1!==t.attributes["x-out-of-boundaries"]?X.setAttribute("data-out-of-boundaries",""):X.removeAttribute("data-out-of-boundaries");var r=rt(t.placement),i=P(["top","bottom"],r),o=P(["bottom","right"],r);X.style.top="0",X.style.left="0",X.style[i?"top":"left"]=(o?1:-1)*n+"px",e&&e!==t.placement&&K.popperInstance.update()}var s=e({eventsEnabled:!1,placement:K.props.placement},i,{modifiers:e({},i&&i.modifiers,{tippyDistance:{enabled:!0,order:0,fn:function(t){n=function(t,e){var n="string"==typeof e&&P(e,"rem"),r=t.documentElement;return r&&n?parseFloat(getComputedStyle(r).fontSize||String(16))*R(e):R(e)}(I,K.props.distance);var e=rt(t.placement),r=z(e,p&&p.padding,n),i=z(e,a&&a.padding,n),o=K.popperInstance.modifiers;return x(o,"preventOverflow","padding",r),x(o,"flip","padding",i),t}},preventOverflow:e({boundariesElement:K.props.boundary},p),flip:e({enabled:K.props.flip,behavior:K.props.flipBehavior},a),arrow:e({element:o,enabled:!!o},w(i,"arrow")),offset:e({offset:K.props.offset},w(i,"offset"))}),onCreate:function(t){u(t),M(i&&i.onCreate,s.onCreate,[t]),St()},onUpdate:function(t){u(t),M(i&&i.onUpdate,s.onUpdate,[t]),St()}});K.popperInstance=new t(r,j,s)}function St(){0===b?(b++,K.popperInstance.update()):l&&1===b&&(b++,j.offsetHeight,l())}function Pt(t){K.clearDelayTimeouts(),K.popperInstance||kt(),t&&ft("onTrigger",[K,t]),wt();var e=ut(!0);e?o=setTimeout(function(){K.show()},e):K.show()}function Vt(t){if(K.clearDelayTimeouts(),ft("onUntrigger",[K,t]),K.state.isVisible){var e=ut(!1);e?a=setTimeout(function(){K.state.isVisible&&K.hide()},e):p=requestAnimationFrame(function(){K.hide()})}else Et()}}function gt(t,r,i){void 0===r&&(r={}),void 0===i&&(i=[]),i=Z.plugins.concat(r.plugins||i),document.addEventListener("touchstart",j,e({},n,{capture:!0})),window.addEventListener("blur",W);var o=e({},Z,{},r,{plugins:i}),a=b(t).reduce(function(t,e){var n=e&&ht(e,o);return n&&t.push(n),t},[]);return A(t)?a[0]:a}gt.version="5.1.1",gt.defaultProps=Z,gt.setDefaultProps=function(t){Object.keys(t).forEach(function(e){Z[e]=t[e]})},gt.currentInput=q;var bt={mouseover:"mouseenter",focusin:"focus",click:"click"};var yt={name:"animateFill",defaultValue:!1,fn:function(t){var e=t.popperChildren,n=e.tooltip,r=e.content,i=t.props.animateFill&&!G?function(){var t=I();return t.className=p,D([t],"hidden"),t}():null;function o(){t.popperChildren.backdrop=i}return{onCreate:function(){i&&(o(),n.insertBefore(i,n.firstElementChild),n.setAttribute("data-animatefill",""),n.style.overflow="hidden",t.setProps({animation:"shift-away",arrow:!1}))},onMount:function(){if(i){var t=n.style.transitionDuration,e=Number(t.replace("ms",""));r.style.transitionDelay=Math.round(e/10)+"ms",i.style.transitionDuration=t,D([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&D([i],"hidden")},onAfterUpdate:function(){o()}}}};var wt={name:"followCursor",defaultValue:!1,fn:function(t){var e,n=t.reference,r=t.popper,i=U(t.props.triggerTarget||n),o=null,a=!1,p=t.props;function u(){return"manual"===t.props.trigger.trim()}function s(){var e=!!u()||null!==o&&!(0===o.clientX&&0===o.clientY);return t.props.followCursor&&e}function c(){return q.isTouch||"initial"===t.props.followCursor&&t.state.isVisible}function l(){t.popperInstance&&(t.popperInstance.reference=n)}function f(){if(s()||t.props.placement!==p.placement){var e=p.placement,n=e.split("-")[1];a=!0,t.setProps({placement:s()&&n?e.replace(n,"start"===n?"end":"start"):e}),a=!1}}function d(){t.popperInstance&&s()&&(c()||!0!==t.props.followCursor)&&t.popperInstance.disableEventListeners()}function v(){s()?i.addEventListener("mousemove",g):l()}function m(){s()&&g(e)}function h(){i.removeEventListener("mousemove",g)}function g(i){var o=e=i,a=o.clientX,p=o.clientY;if(t.popperInstance&&t.state.currentPlacement){var u=S(i.target,function(t){return t===n}),s=n.getBoundingClientRect(),l=t.props.followCursor,f="horizontal"===l,d="vertical"===l,v=P
29667(["top","bottom"],rt(t.state.currentPlacement)),m=function(t,e){var n=e?t.offsetWidth:t.offsetHeight;return{size:n,x:e?n:0,y:e?0:n}}(r,v),g=m.size,b=m.x,y=m.y;!u&&t.props.interactive||(t.popperInstance.reference={referenceNode:n,clientWidth:0,clientHeight:0,getBoundingClientRect:function(){return{width:v?g:0,height:v?0:g,top:(f?s.top:p)-y,bottom:(f?s.bottom:p)+y,left:(d?s.left:a)-b,right:(d?s.right:a)+b}}},t.popperInstance.update()),c()&&h()}}return{onAfterUpdate:function(t,e){var n;a||(n=e,Object.keys(n).forEach(function(t){p[t]=B(n[t],p[t])}),e.placement&&f()),e.placement&&d(),requestAnimationFrame(m)},onMount:function(){m(),d()},onShow:function(){u()&&(e=o={clientX:0,clientY:0},f(),v())},onTrigger:function(t,n){o||(T(n)&&(o={clientX:n.clientX,clientY:n.clientY},e=n),f(),v())},onUntrigger:function(){t.state.isVisible||(h(),o=null)},onHidden:function(){h(),l(),o=null}}}};var Et={name:"inlinePositioning",defaultValue:!1,fn:function(t){var e=t.reference;function n(){return t.props.inlinePositioning}return{onHidden:function(){n()&&(t.popperInstance.reference=e)},onShow:function(){n()&&(t.popperInstance.reference={referenceNode:e,clientWidth:0,clientHeight:0,getBoundingClientRect:function(){return function(t,e,n){if(n.length<2||null===t)return e;var r;switch(t){case"top":case"bottom":var i=n[0],o=n[n.length-1],a="top"===t,p=i.top,u=o.bottom,s=a?i.left:o.left,c=a?i.right:o.right;r={top:p,bottom:u,left:s,right:c,width:c-s,height:u-p};break;case"left":case"right":var l=Math.min.apply(Math,n.map(function(t){return t.left})),f=Math.max.apply(Math,n.map(function(t){return t.right})),d=n.filter(function(e){return"left"===t?e.left===l:e.right===f}),v=d[0].top,m=d[d.length-1].bottom;r={top:v,bottom:m,left:l,right:f,width:f-l,height:m-v};break;default:r=e}return r}(t.state.currentPlacement&&rt(t.state.currentPlacement),e.getBoundingClientRect(),k(e.getClientRects()))}})}}}};var At={name:"sticky",defaultValue:!1,fn:function(t){var e=t.reference,n=t.popper;function r(e){return!0===t.props.sticky||t.props.sticky===e}var i=null,o=null;function a(){var p=r("reference")?e.getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(p&&Tt(i,p)||u&&Tt(o,u))&&t.popperInstance.update(),i=p,o=u,t.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){t.props.sticky&&a()}}}};function Tt(t,e){return!t||!e||(t.top!==e.top||t.right!==e.right||t.bottom!==e.bottom||t.left!==e.left)}return X&&function(t){var e=document.createElement("style");e.textContent=t,e.setAttribute("data-tippy-stylesheet","");var n=document.head,r=document.querySelector("head>style,head>link");r?n.insertBefore(e,r):n.appendChild(e)}(".tippy-tooltip[data-animation=fade][data-state=hidden]{opacity:0}.tippy-iOS{cursor:pointer!important;-webkit-tap-highlight-color:transparent}.tippy-popper{pointer-events:none;max-width:calc(100vw - 10px);transition-timing-function:cubic-bezier(.165,.84,.44,1);transition-property:transform}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;background-color:#333;transition-property:visibility,opacity,transform;outline:0}.tippy-tooltip[data-placement^=top]>.tippy-arrow{border-width:8px 8px 0;border-top-color:#333;margin:0 3px;transform-origin:50% 0;bottom:-7px}.tippy-tooltip[data-placement^=bottom]>.tippy-arrow{border-width:0 8px 8px;border-bottom-color:#333;margin:0 3px;transform-origin:50% 7px;top:-7px}.tippy-tooltip[data-placement^=left]>.tippy-arrow{border-width:8px 0 8px 8px;border-left-color:#333;margin:3px 0;transform-origin:0 50%;right:-7px}.tippy-tooltip[data-placement^=right]>.tippy-arrow{border-width:8px 8px 8px 0;border-right-color:#333;margin:3px 0;transform-origin:7px 50%;left:-7px}.tippy-tooltip[data-interactive][data-state=visible]{pointer-events:auto}.tippy-tooltip[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{position:absolute;border-color:transparent;border-style:solid}.tippy-content{padding:5px 9px}"),gt.setDefaultProps({plugins:[yt,wt,Et,At]}),gt.createSingleton=function(t,n,r){void 0===n&&(n={}),void 0===r&&(r=[]),r=n.plugins||r,t.forEach(function(t){t.disable()});var i,o,a=e({},Z,{},n).aria,p=!1,u=t.map(function(t){return t.reference}),s={fn:function(e){function n(t){if(i){var n="aria-"+i;t&&!e.props.interactive?o.setAttribute(n,e.popperChildren.tooltip.id):o.removeAttribute(n)}}return{onAfterUpdate:function(t,n){var r=n.aria;void 0!==r&&r!==a&&(p?(p=!0,e.setProps({aria:null}),p=!1):a=r)},onDestroy:function(){t.forEach(function(t){t.enable()})},onMount:function(){n(!0)},onUntrigger:function(){n(!1)},onTrigger:function(r,p){var s=p.currentTarget,c=u.indexOf(s);o=s,i=a,e.state.isVisible&&n(!0),e.popperInstance.reference={referenceNode:s,clientHeight:0,clientWidth:0,getBoundingClientRect:function(){return s.getBoundingClientRect()}},e.setContent(t[c].props.content)}}}};return gt(I(),e({},n,{plugins:[s].concat(r),aria:null,triggerTarget:u}))},gt.delegate=function(t,n,r){void 0===r&&(r=[]),r=n.plugins||r;var i,o,a=[],p=[],u=n.target,s=(i=["target"],o=e({}
29667,n),i.forEach(function(t){delete o[t]}),o),c=e({},s,{plugins:r,trigger:"manual"}),l=e({},s,{plugins:r,showOnCreate:!0}),f=gt(t,c);function d(t){if(t.target){var e=t.target.closest(u);if(e)if(P(e.getAttribute("data-tippy-trigger")||n.trigger||Z.trigger,bt[t.type])){var r=gt(e,l);r&&(p=p.concat(r))}}}function v(t,e,n,r){void 0===r&&(r=!1),t.addEventListener(e,n,r),a.push({node:t,eventType:e,handler:n,options:r})}return H(f).forEach(function(t){var e=t.destroy;t.destroy=function(t){void 0===t&&(t=!0),t&&p.forEach(function(t){t.destroy()}),p=[],a.forEach(function(t){var e=t.node,n=t.eventType,r=t.handler,i=t.options;e.removeEventListener(n,r,i)}),a=[],e()},function(t){var e=t.reference;v(e,"mouseover",d),v(e,"focusin",d),v(e,"click",d)}(t)}),f},gt.hideAll=function(t){var e=void 0===t?{}:t,n=e.exclude,r=e.duration;mt.forEach(function(t){var e=!1;n&&(e=h(n)?t.reference===n:t.popper===n.popper),e||t.hide(r)})},gt.roundArrow='<svg viewBox="0 0 18 7" xmlns="http://www.w3.org/2000/svg"><path d="M0 7s2.021-.015 5.253-4.218C6.584 1.051 7.797.007 9 0c1.203-.007 2.416 1.035 3.761 2.782C16.012 7.005 18 7 18 7H0z"/></svg>',gt}(Popper);
29668
29669SUPERCAT = {
29670
29671  common : {
29672    init : function() {
29673      SUPERCAT.ecat.svg_fallback();
29674
29675      if (Modernizr.localstorage) {
29676        SUPERCAT.favorites.init();
29677      } else {
29678        SUPERCAT.no_favorites.init();
29679      }
29680
29681      SUPERCAT.currentModal = '';
29682      this.initModals();
29683      this.initDropdowns();
29684      this.initPanelDropdownTabs();
29685      this.initWidgetDropdownTabs();
29686      this.initListGridToggle();
29687      this.initToggleElements();
29688      this.initTooltips();
29689
29690      this.bookmarkBubble();
29691
29692      // Init any date range filters
29693      if($('.date-range-custom').length && $('.date-range-select').length) SUPERCAT.dateRange.initDateRangeSelect();
29694
29695      // Initialize any interactive filters
29696      SUPERCAT.filters.init();
29697
29698      SUPERCAT.popups.init();
29699
29700      // Initialize the datepicker
29701      document.addEventListener('turbo:load', () => SUPERCAT.common.initDatePicker());
29702      document.addEventListener('turbo:frame-load', () => SUPERCAT.common.initDatePicker());
29703
29704      // Re-init tooltips after Turbo navigations/frame loads so help bubbles on
29705      // freshly rendered content (e.g. Rep Total) are bound.
29706      document.addEventListener('turbo:load', () => SUPERCAT.common.initTooltips());
29707      document.addEventListener('turbo:frame-load', () => SUPERCAT.common.initTooltips());
29708
29709      $(document).on('click', 'tfoot .show-more', function(e) {
29710        e.preventDefault();
29711        $(this).parents('table').find('.is-hidden').removeClass('is-hidden');
29712        $(this).hide();
29713        $(this).parents('table').find('.hideable .show-less').show();
29714      });
29715
29716      $(document).on('click', '.show-less', function(e) {
29717        e.preventDefault();
29718        $(this).parents('table').find('.hideable').addClass('is-hidden');
29719        $(this).hide();
29720        $(this).parents('table').find('.show-more').show();
29721      });
29722
29723      // run polyfill for SVG in IE
29724      svg4everybody();
29725
29726      this.bookmarkBubble();
29727    },
29728
29729    triggerShowModal : function(e) {
29730      e.stopPropagation();
29731      SUPERCAT.modals.openModal($(this).data('modal'), this);
29732      return false;
29733    },
29734
29735    triggerCloseModal : function(e) {
29736      e.stopPropagation();
29737      SUPERCAT.modals.closeModal();
29738      return false;
29739    },
29740
29741    initModals : function() {
29742      SUPERCAT.modals.init();
29743
29744      //first remove the event handlers to prevent multiple firings
29745      $(document).off('click', '.modal-trigger', this.triggerShowModal);
29746      $(document).off('click', '.modal-close', this.triggerCloseModal);
29747
29748      $(document).on('click', '.modal-trigger', this.triggerShowModal);
29749      $(document).on('click', '.modal-close', this.triggerCloseModal);
29750    },
29751
29752    initPrintModalLinks : function(parentClass) {
29753      if (typeof(parentClass) == 'undefined') {
29754        parentClass = '.modal';
29755      }
29756      $(document).on('click', '.print-modal', function(e) {
29757        e.preventDefault();
29758        $(this).parents(parentClass).find('.panel').printThis({
29759          printDelay: 500
29760        });
29761        return false;
29762      });
29763    },
29764
29765    initDropdowns : function() {
29766      var $dd = $('.dropdown-wrapper');
29767      if($dd.length == 0) return;
29768
29769      $dd.each(function() {
29770        var dd = new DropDown($(this));
29771      });
29772    },
29773
29774    initPanelDropdownTabs : function() {
29775
29776      // Setup date-range show/hide listener
29777      $('.panel').on('panelTab.change', function(e) {
29778        $dateRangeForm = $(this).find('.panel-header .date-range-form');
29779        if($(e.target).data('input') == 'date-range') {
29780          $dateRangeForm.removeClass('is-hidden');
29781        } else {
29782          $dateRangeForm.addClass('is-hidden');
29783        }
29784      });
29785
29786      var $dd = $('.panel-dropdown-wrapper');
29787      if($dd.length == 0) return;
29788
29789      $dd.each(function() {
29790        var $link =  $(this).find('.dropdown li > a');
29791        $link.click(function(e) {
29792          $(this).tab('show');
29793          $(this).trigger('panelTab.change');
29794          e.preventDefault();
29795        });
29796        $link.each(function() {
29797          if($(this).data('active')) {
29798            $link.click();
29799            $(this).trigger('panelTab.change');
29800          }
29801        });
29802      });
29803
29804      $('.widget').on('change.widgetTab', function(e) {
29805        $dateRangeForm = $(this).find('.widget-header .date-range-form');
29806        if($(e.target).data('input') == 'date-range') {
29807          $dateRangeForm.removeClass('is-hidden');
29808        } else {
29809          $dateRangeForm.addClass('is-hidden');
29810        }
29811      });
29812
29813    },
29814
29815    initWidgetDropdownTabs : function() {
29816      var $dd = $('.widget-dropdown-wrapper');
29817      if($dd.length == 0) return;
29818
29819      $dd.each(function() {
29820        var $link =  $(this).find('.dropdown li a');
29821        $link.click(function(e) {
29822          $(this).tab('show');
29823          e.preventDefault();
29824        });
29825      });
29826
29827    },
29828
29829    initDatePicker : function() {
29830        // See https://github.com/flatpickr/flatpickr/issues/1992#issuecomment-578970962
29831        function iPadMobileFix() {
29832          return function(instance) {
29833            return {
29834              onParseConfig: function() {
29835                if (instance.isMobile) {
29836                  return;
29837                }
29838                if (
29839                  window.navigator.userAgent.match(/iPad/i) ||
29840                  window.navigator.userAgent.match(/iPhone/i) ||
29841                  /iPad|iPhone|iPod/.test(window.navigator.platform) ||
29842                  (window.navigator.platform === 'MacIntel' && window.navigator.maxTouchPoints > 1)
29843                ) {
29844                  instance.isMobile = true;
29845                }
29846              }
29847            };
29848          };
29849      };
29850
29851      defaultOptions = {
29852        dateFormat: 'Y-m-d',
29853        maxDate: 'today',
29854        onOpen: function(selectedDates, dateStr, instance) {
29855          // Ensure the datepicker is added to the body, not to a child node which would give it an incorrect offset
29856          $(instance.calendarContainer).appendTo('body');
29857        },
29858        plugins: [iPadMobileFix()]
29859      };
29860
29861      $('input[type=date]').flatpickr(defaultOptions);
29862
29863      withoutMaxDate = { ...defaultOptions, ...{ maxDate: undefined } };
29864
29865      $('.future-dates-allowed').flatpickr(withoutMaxDate);
29866
29867      // Set the minimum and maximum date for each matching
29868      // element from its data attributes. Each is optional.
29869      $('.min-max-dates-enforced').each(function() {
29870        const minDate = $(this).data().minDate;
29871        const maxDate = $(this).data().maxDate;
29872
29873        const withMinMaxDates =
29874          { ...defaultOptions, ...{ minDate: minDate, maxDate: maxDate }};
29875
29876        $(this).flatpickr(withMinMaxDates);
29877      });
29878    },
29879
29880    searchAction : function(target, searchTerm) {
29881      var $this = target,
29882          $list = $($this.data('list')),
29883          selected_option = $list.find('input:checked').val()
29884
29885      $this.addClass('loading');
29886      $.get($this.data('source'), {query: searchTerm, selected_option: selected_option})
29887        .done(function(data) {
29888          $list.html(data);
29889        })
29890        .fail(function(data) {
29891          $list.html('<li>There was an error returning your search results.</li>')
29892        })
29893        .always(function() {
29894          $this.removeClass('loading');
29895        });
29896    },
29897
29898    initListGridToggle : function() {
29899      var timeout = 1000,
29900          clocker;
29901
29902      // Handle ajax search
29903      $(document).on('keyup', 'input[data-toggle="ajaxSearch"]', function() {
29904        var $this = $(this),
29905            searchTerm = $this.val()
29906
29907        clearTimeout(clocker);
29908
29909        if (searchTerm.length > 2 || searchTerm.length === 0) {
29910          clocker = setTimeout(function() { SUPERCAT.common.searchAction($this, searchTerm); }, timeout);
29911        }
29912      });
29913
29914      // toggle between list and grid view classes
29915      $(document).on('click', '[data-toggle="list-grid"]', function(e) {
29916        e.preventDefault();
29917        var $this = $(this),
29918            $tgt = $($this.attr('href'));
29919
29920        $tgt.toggleClass('is-grid is-list');
29921        var txt = ($this.text() == 'Show Grid') ? 'Show List' : 'Show Grid';
29922        $this.text(txt);
29923
29924        // if an item is selected, ensure it's scrolled into view when switching to grid or list
29925        if ($tgt.find('input:checked').length > 0) {
29926          var pos = $tgt.find('input:checked').parents('li').position(),
29927              off = $tgt.find('input:checked').parents('li').offset(),
29928              pOff = $tgt.parents('.panel').offset();
29929
29930          if ($tgt.hasClass('is-list')) {
29931            $tgt.scrollLeft(pos.left);
29932          } else {
29933            $tgt.parents('.panel').scrollTop(off.top - pOff.top);
29934          }
29935        }
29936      });
29937    },
29938
29939    bookmarkBubble : function() {
29940      var org = SUPERCAT.ecat.get_org();
29941      var hideBubble = localStorage.getItem(org + "_hide_bubble");
29942
29943      if (!hideBubble && !IS_ECAT_REQUEST) {
29944        if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
29945          SUPERCAT.modals.openModal('bookmark-bubble-modal',this);
29946        }
29947      }
29948
29949      $('#hide-bubble').click(function() {
29950        SUPERCAT.modals.closeModal();
29951        localStorage.setItem(org + "_hide_bubble", true);
29952      })
29953    },
29954
29955    // Allow links to toggle elements visibility
29956    initToggleElements : function() {
29957      $(document).on('click change', '[data-toggle="elements"]', function(e) {
29958        var $this = $(this),
29959            tagName = $this.prop('tagName').toLowerCase();
29960
29961        if(tagName == 'a') e.preventDefault();
29962
29963        // If the elements to toggle are set in the tag (link) then create an array of them
29964        if($this.data('toggle-elements')) {
29965          var toggle_array = $this.data('toggle-elements').split(',');
29966        }
29967        if($this.data('toggle-elements-show')) {
29968          var show_array = $this.data('toggle-elements-show').split(',');
29969        }
29970        if($this.data('toggle-elements-hide')) {
29971          var hide_array = $this.data('toggle-elements-hide').split(',');
29972        }
29973
29974        // If a select tag, each option may toggle different elements
29975        if(tagName == 'select') {
29976          if ($this.find(':selected').data('toggle-elements-show')) {
29977            var show_array = $this.find(':selected').data('toggle-elements-show').split(',');
29978          }
29979          if ($this.find(':selected').data('toggle-elements-hide')) {
29980            var hide_array = $this.find(':selected').data('toggle-elements-hide').split(',');
29981          }
29982        }
29983
29984        if(toggle_array) {
29985          for (var i = 0; i < toggle_array.length; i++) {
29986            var $el = $(toggle_array[i]);
29987            $el.toggle();
29988          }
29989        }
29990
29991        if(show_array) {
29992          for (var i = 0; i < show_array.length; i++) {
29993            var $el = $(show_array[i]);
29994            $el.show();
29995          }
29996        }
29997
29998        if(hide_array) {
29999          for (var i = 0; i < hide_array.length; i++) {
30000            var $el = $(hide_array[i]);
30001            $el.hide();
30002          }
30003        }
30004
30005      });
30006    },
30007
30008    initTooltips: function() {
30009      // Bind only elements that don't already have an instance so this is safe
30010      // to re-run after Turbo swaps in new content (e.g. the Rep Total help
30011      // bubble, which only appears once a territory filter is applied).
30012      document.querySelectorAll('.has-tooltip').forEach(function(el) {
30013        if (!el._tippy) tippy(el);
30014      });
30015    },
30016
30017    // Returns an object with keys/values matching url parameter keys/values
30018    getParams : function() {
30019      return _.chain(location.href)
30020              .replace(/^.+\?/, '')
30021              .split('&')
30022              .map(_.partial(_.split, _, '=', 2))
30023              .fromPairs()
30024              .value()
30025    }
30026  },
30027
30028
30029  ecat : {
30030
30031    get_org : function() {
30032      var url = window.location.href;
30033      var segments = url.split('/');
30034      return segments[3];
30035    },
30036
30037    email_product_message : function(product_data) {
30038      msg = "Product: " + product_data.long_desc + "\n";
30039      msg += "Product ID: " + product_data.num + "\n";
30040      msg += "Tear sheet: http://supercat.supercatsolutions.com/" + product_data.org + "/public/tear_sheet/" + product_data.num + "\n";
30041      return msg;
30042    },
30043
30044    email_product : function(product_data) {
30045      var msg = "For more information on this product, please click on the link below to view a printable tear sheet for the item.\n\n";
30046      msg += SUPERCAT.ecat.email_product_message(product_data);
30047      str = "mailto:?subject=" + product_data.desc + "&body=" + encodeURIComponent(msg);
30048      document.location.href = str;
30049    },
30050
30051    email_product_list : function() {
30052      var favs = SUPERCAT.favorites.get_favorites();
30053      var msg = "For more information on these products, please click on the links below to view a printable tear sheet for each item.\n\n";
30054      $.each(favs, function() {
30055        var product_data = this;
30056        msg += SUPERCAT.ecat.email_product_message(product_data);
30057        msg += "\n--------------------\n\n";
30058      });
30059      str = "mailto:?subject=Favorite%20Products&body=" + encodeURIComponent(msg);
30060      document.location.href = str;
30061    },
30062
30063    supports_svg : function() {
30064      return !! document.createElementNS && !! document.createElementNS('http://www.w3.org/2000/svg','svg').createSVGRect;
30065    },
30066
30067    svg_fallback : function() {
30068      // Src: http://toddmotto.com/mastering-svg-use-for-a-retina-web-fallbacks-with-png-script/
30069      if (this.supports_svg()) {
30070        $(document).addClass('svg');
30071      } else {
30072        $(document).addClass('no-svg');
30073        $('img[src*="svg"]').attr('src', function() {
30074          return $(this).attr('src').replace('.svg', '.png');
30075        });
30076      }
30077    },
30078
30079  },
30080
30081
30082  login : {
30083    init : function() {
30084      $('form input')
30085        .bind('input propertychange', function() {
30086          $(this).addClass('is-not-empty');
30087        })
30088        .each(function(i, field) {
30089          var $field = $(field);
30090          if ($field.val() && _.trim($field.val()) != "") {
30091            $field.addClass('is-not-empty');
30092          }
30093        });
30094
30095      $('i[class^="icon-"]').click(function() {
30096        $(this).siblings('input').focus();
30097      });
30098
30099      $('.old-toggle-forgot-link').click(function() {
30100        $(this).parents('form').addClass('is-hidden')
30101                               .siblings('form').removeClass('is-hidden');
30102      });
30103      $('.toggle-login-form').click(function(e) {
30104        e.preventDefault();
30105        var tgt = $('.' + $(this).data('target'));
30106        $(this).parents('form').addClass('is-hidden');
30107        $(tgt).removeClass('is-hidden');
30108      });
30109
30110      // Check for hash in URL
30111      if (window.location.hash) {
30112        $('[data-target="' + window.location.hash.substring(1) + '"]').click();
30113      }
30114    }
30115  },
30116
30117
30118  catalog : {
30119    state : 'unstarted',
30120    started : function (){
30121      return this.state == 'started';
30122    },
30123    init : function() {
30124      if(SUPERCAT.catalog.started()){
30125        SUPERCAT.filters.unbindFiltersLink();
30126      } else {
30127        this.state = 'started';
30128      };
30129
30130      SUPERCAT.filters.initFiltersLink();
30131      $('.favorites-button').each(function() {
30132        SUPERCAT.favorites.update_favorites_star($(this));
30133      });
30134    }
30135  },
30136
30137
30138  product_detail : {
30139    init : function() {
30140      $('.item-actions .favorites-button').each(function() {
30141        $this = $(this);
30142        SUPERCAT.favorites.update_favorites_button($this); // initialize the button
30143        $this.click(function() {
30144          SUPERCAT.favorites.update_favorites_button($this); // update this button
30145
30146          // TODO: just update the catalog item for this product
30147          // currently, update ALL catalog stars to ensure they're correct
30148          $('.catalog-item-action-button.favorites-button').each(function() {
30149            SUPERCAT.favorites.update_favorites_star($(this));
30150          });
30151        });
30152      });
30153    }
30154  },
30155
30156
30157  product_favorites : {
30158    init : function() {
30159      if (Modernizr.localstorage) {
30160        SUPERCAT.favorites.display_favorites();
30161
30162        // Init clear favs button
30163        $('#clear-favorites').click(function() {
30164          SUPERCAT.favorites.clear_favorites();
30165          $('#favorites-items').html(SUPERCAT.favorites.no_favorites_msg());
30166        });
30167
30168        // Init show/hide email form link
30169        $('.email-favorites-link').click(function() {
30170          var $email_panel = $('.email-panel');
30171          if($email_panel.hasClass('is-hidden')) {
30172            $email_panel.removeClass('is-hidden');
30173          } else {
30174            $email_panel.addClass('is-hidden');
30175          }
30176        });
30177
30178        // Prefill the hidden variable in the emailer form with a list of product IDs to send
30179        var favorites_records = SUPERCAT.favorites.get_favorites();
30180        if (!favorites_records) {
30181          favorites_records = [];
30182        }
30183        var favs = $.map(favorites_records, function (val, i) { return val['id']; });
30184        $('#product_ids').attr('value', JSON.stringify(favs));
30185      }
30186      else {
30187        SUPERCAT.no_favorites.display_no_favorites();
30188      }
30189    }
30190  },
30191
30192
30193  favorites : {
30194
30195    init : function() {
30196      if(!this.initialized) {
30197        this.initialized = true;
30198        this.favorites = this.get_favorites();
30199        this.org = SUPERCAT.ecat.get_org();
30200      }
30201    },
30202
30203    no_favorites_msg : function() {
30204      return 'No results found.';
30205    },
30206
30207    get_raw_favorites : function() {
30208      var org = this.org;
30209      return localStorage.getItem(org + "_ecat_product_favorites");
30210    },
30211
30212    get_favorites : function() {
30213      var product_favorites = JSON.parse(SUPERCAT.favorites.get_raw_favorites());
30214      return product_favorites;
30215    },
30216
30217    set_favorites : function(favs) {
30218      var org = this.org;
30219      localStorage.setItem(org + "_ecat_product_favorites", JSON.stringify(favs));
30220    },
30221
30222    clear_favorites : function() {
30223      var org = this.org;
30224      localStorage.removeItem(org + "_ecat_product_favorites");
30225    },
30226
30227    add_to_favorites : function(product_data, callback) {
30228      var favs = SUPERCAT.favorites.get_favorites();
30229      if(favs) {
30230        favs.push(product_data);
30231      } else {
30232        favs = [product_data];
30233      }
30234      SUPERCAT.favorites.set_favorites(favs);
30235      if(callback) { callback(); }
30236    },
30237
30238    remove_from_favorites : function(product_data, callback) {
30239      var favs = SUPERCAT.favorites.get_favorites();
30240      var product_id = product_data.id;
30241      favs = _.reject(favs, function(favObj) {
30242        return favObj.id == product_id;
30243      });
30244      SUPERCAT.favorites.set_favorites(favs);
30245      if(callback) { callback(); }
30246    },
30247
30248    is_favorite : function(product_data) {
30249      var favs = SUPERCAT.favorites.get_favorites();
30250      return (_.find(favs, {id: product_data.id})) ? true : false;
30251    },
30252
30253    update_favorites_star : function($fav_star) {
30254      var product_data = $fav_star.data('product'),
30255          $icon = $fav_star.find('svg>use');
30256
30257        if(SUPERCAT.favorites.is_favorite(product_data)) {
30258          $icon.attr('xlink:href', '/assets/ecat/sprite-f735286eb66d77a8d5b4bb12cc0f7d9ba6d598816ffbd8de99e56ae067520e2b.svg#icon-star-full');
30259          $fav_star.unbind('click')
30260                        .bind('click', function(e) {
30261                          SUPERCAT.favorites.remove_from_favorites(product_data, function() {
30262                            SUPERCAT.favorites.update_favorites_star($fav_star);
30263                          });
30264                          e.preventDefault();
30265                        });
30266        } else {
30267          $icon.attr('xlink:href', '/assets/ecat/sprite-f735286eb66d77a8d5b4bb12cc0f7d9ba6d598816ffbd8de99e56ae067520e2b.svg#icon-star');
30268          $fav_star.unbind('click')
30269                        .bind('click', function(e) {
30270                          SUPERCAT.favorites.add_to_favorites(product_data, function() {
30271                            SUPERCAT.favorites.update_favorites_star($fav_star);
30272                          });
30273                          e.preventDefault();
30274                        });
30275      }
30276    },
30277
30278    update_favorites_button : function($btn) {
30279      var product_data = $btn.data('product');
30280
30281      if(SUPERCAT.favorites.is_favorite(product_data)) {
30282        $btn.addClass('is-favorite')
30283            .html('<svg class="icon"><use xlink:href="/assets/ecat/sprite-f735286eb66d77a8d5b4bb12cc0f7d9ba6d598816ffbd8de99e56ae067520e2b.svg#icon-star-full" /></svg> Remove from Favorites')
30284            .unbind('click')
30285            .bind('click', function(e) {
30286              SUPERCAT.favorites.remove_from_favorites(product_data, function() {
30287                SUPERCAT.favorites.update_favorites_button($btn);
30288              });
30289              e.preventDefault();
30290            });
30291      } else {
30292        $btn.removeClass('is-favorite')
30293            .html('<svg class="icon"><use xlink:href="/assets/ecat/sprite-f735286eb66d77a8d5b4bb12cc0f7d9ba6d598816ffbd8de99e56ae067520e2b.svg#icon-star" /></svg> Add to Favorites')
30294            .unbind('click')
30295            .bind('click', function(e) {
30296              SUPERCAT.favorites.add_to_favorites(product_data, function() {
30297                SUPERCAT.favorites.update_favorites_button($btn);
30298              });
30299              e.preventDefault();
30300            });
30301      }
30302    },
30303
30304    display_favorites : function() {
30305      var favs = SUPERCAT.favorites.get_favorites();
30306      if (favs) {
30307        var item_numbers = _.map(favs, function(fav) {
30308          return fav.num;
30309        });
30310        var item_numbers_json = JSON.stringify(item_numbers);
30311        jQuery.get(SUPERCAT.line_fetch_url + "?item_numbers=" + encodeURIComponent(item_numbers_json)).
30312          success(function(data) {
30313            var grid_str = '';
30314            _.each(data, function(product) {
30315              grid_str += SUPERCAT.line_template({product: product});
30316            });
30317            $('#favorites-items').html(grid_str);
30318          });
30319      } else {
30320        $('#favorites-items').html(SUPERCAT.favorites.no_favorites_msg());
30321      }
30322      SUPERCAT.favorites.update_empty_message();
30323    },
30324
30325    update_empty_message : function() {
30326      var favs = SUPERCAT.favorites.get_favorites();
30327      var message = '<h3 class="favorites-empty-message page-message">Your favorites list is currently empty.</h3>'
30328    }
30329
30330  },
30331
30332  no_favorites : {
30333    init : function() {
30334      $('.favorites-button').each(function() {
30335        $this = $(this);
30336        $this.click(function() {
30337          alert("Please enable cookies or local storage in order to enable favorites");
30338        });
30339      });
30340    },
30341
30342    display_no_favorites : function() {
30343      $('.content').text("Please enable cookies or local storage in order to enable favorites");
30344    }
30345  },
30346
30347  customers : {
30348    init : function() {
30349      SUPERCAT.filters.initFiltersLink();
30350    }
30351  },
30352
30353  invoices : {
30354    init : function() {
30355      SUPERCAT.filters.initFiltersLink();
30356      SUPERCAT.common.initPrintModalLinks();
30357    },
30358
30359    // printDiv : function(id) {
30360    //   var $printMe = $('#' + id);
30361    //   var printDoc = window.frames['print-frame'].document;
30362
30363    //   printDoc.write("<html><body></body></html>");
30364    //   printDoc.body.innerHTML = $printMe.html();
30365
30366    //   // Need window.print *first* for Firefox:
30367    //   if (navigator.userAgent.toLowerCase().indexOf("firefox")!=-1){
30368    //     window.print();
30369    //   } else {
30370
30371    //     // If not Firefox, try the execCommand for IE, or fallback (again) to window.print
30372    //     try {
30373    //       printDoc.execCommand('print', false, null);
30374    //     } catch(e) {
30375    //       window.print();
30376    //     }
30377    //   }
30378
30379    // }
30380  },
30381
30382  orders : {
30383    init : function() {
30384      SUPERCAT.filters.initFiltersLink();
30385      SUPERCAT.common.initPrintModalLinks();
30386    }
30387  },
30388
30389  reporting : {
30390    init : function() {
30391      SUPERCAT.filters.initFiltersLink();
30392    }
30393  },
30394
30395  modals : {
30396    init : function() {
30397      this.currentModalURL = '';
30398      this.currentScroll = '0';
30399      this.currentBrowserURL = window.location.href;
30400
30401      // Add the master modal container
30402      $('.modal-overlay').before('<div class="modal" id="master-modal"></div>');
30403      this.masterModal = $('#master-modal');
30404
30405      // Detect when back button is triggered
30406      $(window).on('popstate', function(e) {
30407
30408        // If returning to a URL that is the same as the original browser URL, close the modal
30409        // Else if an existing modal, trigger a reload modal event
30410        if(window.location == SUPERCAT.modals.currentBrowserURL) {
30411          SUPERCAT.modals.closeModal();
30412        } else if (SUPERCAT.currentModal != '') {
30413          SUPERCAT.currentModal.trigger($.Event('reload.bs.modal', {
30414            url: window.location
30415          }));
30416        } else {
30417          // console.log("no modal");
30418        }
30419      });
30420
30421      // Close modals when ESC key is pressed
30422      $(document).keyup(function(e) {
30423        if(e.keyCode === 27 && SUPERCAT.currentModal != '') SUPERCAT.modals.closeModal();
30424      });
30425    },
30426
30427    openModal : function(id, target, url) {
30428      var $modal = $('#' + id),
30429          url = (typeof url !== 'undefined') ?  url : '';
30430
30431      // Move targeted modal into master-modal
30432      var $sourceModal = $modal.detach().removeClass('modal');
30433      if(SUPERCAT.modals.masterModal.html() != '') {
30434        SUPERCAT.modals.returnContent(SUPERCAT.modals.masterModal.html());
30435      }
30436      SUPERCAT.modals.masterModal.append($sourceModal);
30437
30438      $modal.trigger($.Event('show.bs.modal', {
30439        relatedTarget: target,
30440        url: url
30441      }));
30442
30443      // If we've scrolled down, store the new scroll
30444      // scroll-loading of new products messes with the scroll values, so pick the greater of the window's scroll
30445      // or the body's CSS top offset
30446      var cssTop = Math.abs(parseInt($('body').css('top'), 10));
30447      if (isNaN(cssTop)) { cssTop = 0; }
30448      SUPERCAT.modals.currentScroll = Math.max($(window).scrollTop(), cssTop);
30449
30450
30451      SUPERCAT.modals.masterModal.addClass('modal-show');
30452      $('body').addClass('modal-is-visible').css('top', -1 * SUPERCAT.modals.currentScroll);
30453      SUPERCAT.currentModal = $modal;
30454
30455      if($modal.hasClass('modal-setperspective')) {
30456        setTimeout(function() {
30457          $('html').addClass('modal-perspective');
30458        }, 25);
30459      }
30460    },
30461
30462    closeModal : function() {
30463      SUPERCAT.modals.masterModal.removeClass('modal-show');
30464      SUPERCAT.currentModal = '';
30465      SUPERCAT.modals.currentModalURL = '';
30466      $('html').removeClass('modal-perspective');
30467      $('body').removeClass('modal-is-visible').css('top', '');
30468      SUPERCAT.modals.returnContent(SUPERCAT.modals.masterModal.html());
30469
30470      // reset scroll position
30471      $(window).scrollTop(SUPERCAT.modals.currentScroll);
30472
30473      // reset browser URL
30474      if (window.location.href != SUPERCAT.modals.currentBrowserURL) {
30475        history.replaceState(null, null, SUPERCAT.modals.currentBrowserURL);
30476      }
30477    },
30478
30479    returnContent : function(content) {
30480      // Return content from the modal back to the DOM, hidden
30481      var returnedContent = $(content).insertBefore('.modal-overlay');
30482      returnedContent.addClass('modal');
30483      SUPERCAT.modals.masterModal.empty();
30484    }
30485  },
30486
30487
30488  validation : {
30489    validateOptions : function($form) {
30490      var $btn = $form.find('.submit-button'),
30491          valid = true;
30492
30493      $('.option-thumbs.required').each(function() {
30494        valid = valid && ($('.option-selection:checked', this).length > 0);
30495      });
30496
30497      if(!valid) {
30498        this.showError($btn, 'Please select the required options above.');
30499      }
30500
30501      return valid && this.validateOptionForms($form);
30502    },
30503
30504    validateOptionForms : function($form) {
30505      var $btn = $form.find('.submit-button'),
30506          valid = true;
30507
30508      $('.option-form-fields input[type=text].required:enabled').each(function() {
30509        valid = valid && ($(this).val() != '');
30510      });
30511
30512      $('.option-form-field-selection.required:visible').each(function() {
30513        valid = valid && ($(this).find('input[type=radio]:enabled:checked').length > 0);
30514      });
30515
30516      if(!valid) {
30517        this.showError($btn, 'Please supply the required option configuration above.');
30518      }
30519
30520      return valid;
30521    },
30522
30523    showError : function($btn, message, ms) {
30524      if($btn.parents('form').find('.errors').length == 0) {
30525        $btn.before('<div class="errors alert-error"></div>');
30526      }
30527      var $errors = $btn.prev('.errors');
30528      $errors.html(message);
30529
30530      if(ms != undefined) {
30531        setTimeout(function() {
30532          $errors.remove()
30533        }, ms)
30534      }
30535    }
30536  },
30537
30538  popups : {
30539    init : function() {
30540      tippy('.popup-trigger', {
30541        placement: 'bottom',
30542        animation: 'shift-away',
30543        trigger: 'click',
30544        content: function(el) { return el.querySelector('.popup') },
30545        interactive: true,
30546        popperOptions: {
30547          positionFixed: true,
30548        },
30549        arrow: true,
30550        theme: 'light'
30551      });
30552    }
30553  },
30554
30555  dateRange : {
30556    initDateRangeSelect : function() {
30557      var select = $('.date-range-select');
30558      select.change(function() {
30559        SUPERCAT.dateRange.updateDateRangeVisibility(this);
30560      });
30561      SUPERCAT.dateRange.updateDateRangeVisibility(select);
30562    },
30563
30564    updateDateRangeVisibility : function(el) {
30565      var $element = $(el),
30566          $params = SUPERCAT.common.getParams(),
30567          $custom = $element.parents('form').find('.date-range-custom'),
30568          $from_date = $custom.find('#from_date');
30569          $to_date = $custom.find('#to_date');
30570      if ($element.val() == 'custom') {
30571        $custom.removeClass('is-hidden');
30572      } else {
30573        $custom.addClass('is-hidden');
30574      }
30575    }
30576  },
30577
30578  dateRangeAlert : {
30579    init : function() {
30580      $(document).on('click', '#filters-alert-close', function() {
30581        SUPERCAT.dateRangeAlert.setCookie();
30582      });
30583    },
30584
30585    setCookie: function() {
30586      var today = new Date();
30587      var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
30588      var duration = lastDayOfMonth.getDate() - today.getDate();
30589
30590      $.cookie('hide_date_range_alert', 'true', { expires: duration });
30591    }
30592  },
30593
30594  filters : {
30595    init : function() {
30596      tippy('.catalog-filters-label.editable', {
30597        placement: 'bottom',
30598        animation: 'shift-away',
30599        trigger: 'click',
30600        content: function(el) { return el.querySelector('.popup') },
30601        interactive: true,
30602        popperOptions: {
30603          positionFixed: true,
30604        },
30605        arrow: true,
30606        theme: 'light',
30607        onShown: function(el) {
30608          SUPERCAT.dateRange.initDateRangeSelect();
30609        }
30610      });
30611
30612      $(document).on('change', '.date-range-select', function() {
30613        SUPERCAT.dateRange.updateDateRangeVisibility(this);
30614      });
30615    },
30616
30617    unbindFiltersLink : function() {
30618      var $fl = $('.catalog-filters-link');
30619      if($fl.length == 0) return;
30620
30621      $fl.unbind('click');
30622    },
30623
30624    initFiltersLink : function() {
30625      var $fl = $('.catalog-filters-link');
30626      if($fl.length == 0) return;
30627
30628      $fl.click(function() {
30629        var $customizeOptions = $('.catalog-filters-customize'),
30630            $currentFilters = $('.catalog-filters');
30631
30632          if($customizeOptions.hasClass('is-hidden')) {
30633            $customizeOptions.removeClass('is-hidden').addClass('is-showing');
30634            $currentFilters.addClass('is-hiding');
30635            setTimeout(function() {
30636              $customizeOptions.removeClass('is-showing');
30637              $currentFilters.addClass('is-hidden').removeClass('is-hiding');
30638            }, 350);
30639          } else {
30640            $currentFilters.removeClass('is-hidden').addClass('is-showing');
30641            $customizeOptions.addClass('is-hiding');
30642            setTimeout(function() {
30643              $currentFilters.removeClass('is-showing');
30644              $customizeOptions.addClass('is-hidden').removeClass('is-hiding');
30645            }, 350);
30646          }
30647      });
30648
30649      // Init any date range filters
30650      if($('.date-range-custom').length && $('.date-range-select').length) {
30651        SUPERCAT.dateRange.initDateRangeSelect();
30652        SUPERCAT.dateRangeAlert.init();
30653      }
30654    }
30655  }
30656
30657}
30658
30659
30660// Email Favorites
30661// ----------------------------------------------------------------
30662$(document).delegate('.email-favorites', 'pageinit', function(event) {
30663  var favs = $.map(SUPERCAT.favorites.get_favorites(), function (val, i) { return val['id']; });
30664  $('#product_ids').attr('value', JSON.stringify(favs));
30665});
30666
30667
30668
30669/* via http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/ */
30670UTIL = {
30671
30672  fire : function(func,funcname, args){
30673    var namespace = SUPERCAT;  // indicate your obj literal namespace here
30674    funcname = (funcname === undefined) ? 'init' : funcname;
30675    if (func !== '' && namespace[func] && typeof namespace[func][funcname] == 'function'){
30676      namespace[func][funcname](args);
30677    }
30678  },
30679
30680  loadEvents : function(){
30681    var bodyId = document.body.id;
30682
30683    // hit up common first.
30684    UTIL.fire('common');
30685
30686    // do all the classes too.
30687    $.each(document.body.className.split(/\s+/),function(i,classnm){
30688      UTIL.fire(classnm);
30689      UTIL.fire(classnm,bodyId);
30690    });
30691    UTIL.fire('common','finalize');
30692  }
30693
30694};
30695
30696// kick it all off here
30697$(document).ready(UTIL.loadEvents);
30698EcatKitModel = function() {
30699  var kitModel = {};
30700
30701  function set_selected_option_data(data) {
30702    kitModel.selected_option_data = data;
30703  }
30704
30705  // kit_items: full information for each *possible* kit item
30706  // configuration: minimal information for each *selected* kit item
30707  //      [{ item_number: String, item_group_code: String, selected_option_data: [[info]]}]
30708  function initialize(kit_items, configuration) {
30709    // KitItem
30710    this.parent_kit_item = kit_items[0];
30711
30712    // [KitItem]
30713    this.selected_kit_items = [];
30714
30715    // [[KitItem]]
30716    const kit_items_grouped_by_item_group_code =
30717      Object.groupBy(kit_items.slice(1), ({ item_group_code }) => item_group_code);
30718    this.item_groups = Object.values(kit_items_grouped_by_item_group_code);
30719
30720    // {item_number: [OptionData]}
30721    this.selected_option_data = {};
30722
30723    this.option_searches = {};
30724
30725    this.selected_quantity = 1;
30726
30727    var that = this;
30728    if (configuration) {
30729      // quantity
30730      var parent_kit_item_configuration = configuration.find(item => {
30731        return item.item_number === that.parent_kit_item.item_number
30732      })
30733      if (parent_kit_item_configuration && parent_kit_item_configuration.quantity) {
30734        that.selected_quantity = parent_kit_item_configuration.quantity
30735      }
30736
30737      // selected items
30738      _.each(configuration, function(item) {
30739        var full_item = _.find(_.flatten(that.item_groups), function(kit_item) {
30740          return kit_item.item_group_code === item.item_group_code &&
30741                kit_item.item_number === item.item_number;
30742        });
30743
30744        if (full_item) {
30745          add_to_selected(full_item);
30746        }
30747      });
30748
30749      // option data
30750      var new_option_data = _.reduce(configuration, function(result, item) {
30751        result[item.item_number] = item.selected_option_data;
30752        return result;
30753      }, {});
30754      set_selected_option_data(new_option_data);
30755
30756      // option search input values
30757      this.option_searches = _.reduce(configuration, function(result, item) {
30758        result[item.item_number] = item.option_searches;
30759        return result;
30760      }, {});
30761
30762    }
30763
30764    function select_item_if_not_selected(item) {
30765      var foundKitItem = _.find(kitModel.selected_kit_items, function(kit_item) {
30766        return kit_item.item_number === item.item_number;
30767      });
30768      if (!foundKitItem) {
30769        add_to_selected(item)
30770      }
30771    }
30772
30773    // item preselection
30774    if (configuration.length === 0) {
30775      _.each(this.item_groups, function (kit_items) {
30776        if (kit_items.length == 1) { // singleton item group -> preselect
30777          select_item_if_not_selected(kit_items[0]);
30778        } else {
30779          _.each(kit_items, function (kit_item) {
30780            if (kit_item.preselected) {
30781              select_item_if_not_selected(kit_item);
30782            }
30783          });
30784        }
30785      });
30786    }
30787
30788    function add_to_selected(kit_item) {
30789      // This uuid is used when deleting kit items. Objects with identical
30790      // item number can be added to the kit view multiple times, the
30791      // uuid ensures that there is something different about each one.
30792      // Thus if one of them is deleted, we do not delete kit items with
30793      // the same item number.
30794      add_uuid(kit_item);
30795      kitModel.selected_kit_items.push(kit_item)
30796    }
30797  }
30798
30799  function unselected_kit_item_groups() {
30800    var that = kitModel;
30801    return _.filter(that.item_groups, function(item_group) {
30802      return item_group[0].repeatable == true ||
30803        !_.find(that.selected_kit_items, function(kit_item) {
30804          return item_group[0].item_group_code == kit_item.item_group_code;
30805      });
30806    });
30807  }
30808
30809  function build_base_option_link_url(kit_item) {
30810    return kitModel.option_popup_url_template({id: kit_item.product.id});
30811  }
30812
30813  /**
30814   * Build the link that takes the user from the option configuration back
30815   * to the kit configurator. This sends item number and option
30816   * configuration to ecat_order_process#add_kit_to_order
30817   */
30818  function build_option_link_return_url(kit_item) {
30819    var that = kitModel;
30820    var current_state = _.map(that.selected_kit_items, function(selected_kit_item) {
30821      return {
30822        item_number: selected_kit_item.item_number,
30823        item_group_code: selected_kit_item.item_group_code,
30824        selected_options: that.selected_option_data[selected_kit_item.item_number]
30825      };
30826    });
30827    // [{item_number: '123',
30828    //   item_group_code: 'Cushions',
30829    //   selected_options: [[...]]}]
30830
30831    // add parent item
30832    current_state.push({
30833        item_number: that.parent_kit_item.item_number,
30834        item_group_code: that.parent_kit_item.item_group_code,
30835        quantity: that.selected_quantity,
30836        selected_options: that.selected_option_data[that.parent_kit_item.item_number]
30837    })
30838    return kitModel.kit_configurator_url_template({id: kit_item.parent_id, configuration: escape(JSON.stringify(current_state))});
30839  }
30840
30841  //KitItem -> String
30842  function build_option_form_parameters(kit_item) {
30843    var selected_options = kitModel.selected_option_data[kit_item.item_number];
30844    var forms =
30845      _.chain(selected_options)
30846          .map(function(option_data) {
30847            if (data=option_data[3]) {
30848              data = data[0];
30849              var type_code   = option_data[0];
30850              var option_code = option_data[1];
30851              var group_code  = option_data[2]
30852              return Object.keys(data).map(function(formKey){
30853                var fields =
30854                  Object.keys(data[formKey]).map(function(fieldKey){
30855                    return `forms-${type_code}-${option_code}-${group_code}[${formKey}][${fieldKey}]=${data[formKey][fieldKey]}`;
30856                  });
30857                return _.join(fields, "&");
30858              });
30859            }
30860      }).value();
30861
30862    //E.G. "forms-OptionSet1-S_22-S_FAB[COM][mill]=qualin&forms-OptionSet1[COM][text2]=lime&forms-OptionSet2-S_31-S_B[LAM][lamtext1]=crane"
30863    return _.join(_.flatten(forms), "&");
30864  }
30865
30866  // KitItem -> [String]
30867  function build_option_configuration(kit_item) {
30868    var selected_options = kitModel.selected_option_data[kit_item.item_number];
30869    var result =
30870      _.chain(selected_options)
30871          .map(function(option_data) {
30872            return _.slice(option_data, 0, 2);
30873          })
30874          .value();
30875    return result;
30876  }
30877
30878  /**
30879   * Build a link to take a user from the kit configurator to the option
30880   * configurator for a given item. If the item is already configured, this
30881   * includes option configuration already on the item.
30882   */
30883  function build_options_link_url(kit_item) {
30884    var option_url = build_base_option_link_url(kit_item);
30885    var parameters = [
30886      "suppress_notes=true",
30887      "suppress_quantity=true",
30888      "return_url=" + escape(build_option_link_return_url(kit_item)),
30889    ];
30890    var option_configuration = build_option_configuration(kit_item);
30891    _.each(option_configuration, function(pair) {
30892      var string = _.chain(pair)
30893          .map(escape)
30894          .join("=");
30895      parameters.push(string);
30896    });
30897
30898    var option_searches = kitModel.option_searches[kit_item.item_number]
30899    _.each(option_searches, function(pair) {
30900      var string = _.chain(pair)
30901        .map(escape)
30902        .join("=");
30903      parameters.push(string);
30904    });
30905
30906    var option_forms = build_option_form_parameters(kit_item);
30907    parameters.push(option_forms);
30908
30909    return option_url + "?" + _.join(parameters, "&");
30910  }
30911
30912  function update_ui() {
30913    var that = this;
30914    const parent_kit_item = this.parent_kit_item;
30915    // Even though parent kit items cannot be deleted, a UUID is
30916    // added to the parent for consistency with other kit items on the page,
30917    add_uuid(parent_kit_item)
30918    const parent_option_url = build_options_link_url(parent_kit_item);
30919    $('table.kit-items-table thead').html(
30920      this.selected_kit_item_template({
30921        product: parent_kit_item.product,
30922        removable: false,
30923        quantity_changeable: true,
30924        is_parent: true,
30925        option_url: parent_option_url,
30926        selected_options: that.selected_option_data[parent_kit_item.item_number],
30927        uuid: parent_kit_item.uuid
30928      })
30929    )
30930    $('#unselected-kit-item-area').html(this.unselected_kit_item_group_template({item_groups: unselected_kit_item_groups()}));
30931    $('table.kit-items-table tbody').html(_.reduce(this.selected_kit_items, function(string, kit_item) {
30932      var option_url = build_options_link_url(kit_item);
30933      return string + that.selected_kit_item_template({product: kit_item.product, removable: true, quantity_changeable: false, option_url: option_url, selected_options: that.
30933selected_option_data[kit_item.item_number], uuid: kit_item.uuid});
30934    }, ""));
30935    $('table.kit-items-table')
30936      .find(".ajax-loading")
30937      .each(function() {
30938        var li = $(this);
30939        li.load(li.data('href'));
30940      });
30941    $('table.kit-items-table thead input').val(this.selected_quantity);
30942    this.update_quantities(this.selected_quantity);
30943    this.update_prices();
30944  }
30945
30946  /**
30947   * Is the given kit item incomplete? I.e. are there any required option
30948   * sets that are missing an option selection?
30949   */
30950  function kit_item_is_incomplete(kit_item) {
30951    var selected_options = kitModel.selected_option_data[kit_item.item_number];
30952    var unselected_required_option_sets =
30953      _.filter(kit_item.product.option_sets, function(option_set) {
30954        var pertinent_option = _.find(selected_options, function(option_data) {
30955          return option_set.option_type_code == option_data[0];
30956        });
30957        return !pertinent_option && option_set.required;
30958      });
30959    return unselected_required_option_sets.length > 0;
30960  }
30961
30962  /**
30963   * Add the given kit item to the kit. If there are any options to
30964   * configure go ahead and take the user to the option configurator for this
30965   * kit item.
30966   */
30967  function select_kit_item(kit_item) {
30968    add_uuid(kit_item)
30969
30970    this.selected_kit_items.push(kit_item);
30971    if (kit_item_is_incomplete(kit_item)) {
30972      var url = build_options_link_url(kit_item);
30973      var link = $('<a data-modal="addtoorder" href="' + url + '" data-submit-action="EcatKitModel.submit_kit_item">not visible</a>')
30974        .appendTo('#unselected-kit-item-area')
30975        .addClass("modal-trigger");
30976      link.click();
30977    } else {
30978      this.update_ui();
30979    }
30980  }
30981
30982  /**
30983   * Remove kit items corresponding to the given item number from the kit.
30984   * This is how we remove stuff from the kit.
30985   */
30986  function deselect_kit_item(item_number, uuid) {
30987    this.selected_kit_items =
30988      this.selected_kit_items.filter((kit_item) => kit_item.uuid !== uuid);
30989
30990    const existing_kit_item =
30991      this.selected_kit_items.find((kit_item) => kit_item.item_number === item_number)
30992
30993    // If there are no other kit items with this item number, delete the selected
30994    // options. Thus when a new kit item with the same item number is added it must
30995    // be reconfigured. If there are other kit items with this item number, we want
30996    // to leave the option selection in place so they are automatically applied when
30997    // a kit item with the same item_number is added.
30998    if (!existing_kit_item) {
30999      delete kitModel.selected_option_data[item_number]
31000    }
31001
31002    this.update_ui();
31003  }
31004
31005  function all_kit_items() {
31006    var kit_items = kitModel.selected_kit_items.slice(0);
31007    kit_items.unshift(kitModel.parent_kit_item);
31008    return kit_items;
31009  }
31010
31011  function selected_quantity_for_item_number(item_number) {
31012    var quantity_string = $('.kit-items-table tr[data-item-number="' + item_number + '"] input').val();
31013    return parseInt(quantity_string);
31014  }
31015
31016  /**
31017   * Build the final add-to-order form data for the given kit item.
31018   */
31019  function build_form_data_for_kit_item(kit_item) {
31020    // # params is like {option_type_code => JSON.generate([option_type_code, option_code, group_code])}
31021    var option_datas = kitModel.selected_option_data[kit_item.item_number];
31022    var form_data = {
31023      item_number: kit_item.item_number,
31024      quantity: selected_quantity_for_item_number(kit_item.item_number),
31025      discount_amount: kit_item.discount_amount,
31026      discount_percent: kit_item.discount_percent
31027    };
31028    return _.reduce(option_datas, function(result, option_data) {
31029      result[option_data[0]] = JSON.stringify(option_data);
31030      return result;
31031    }, form_data);
31032  }
31033
31034  /**
31035   * Build the final add-to-order form POST data for this kit.
31036   */
31037  function build_form_data() {
31038    return _.map(all_kit_items(), build_form_data_for_kit_item);
31039  }
31040
31041  function update_quantities(quantity) {
31042    _.each(this.selected_kit_items, function(kit_item) {
31043      var item_number = kit_item.item_number;
31044      var quantity_field = $('tr[data-item-number="' + item_number + '"] .addtoorder-qty-field input').each(function() {
31045        var multiplier = kit_item.quantity || 1;
31046        $(this).val('' + multiplier * quantity);
31047      });
31048    });
31049  }
31050
31051  function update_price_for_row(tr) {
31052    tr.find('.catalog-item-price').text("Calculating...");
31053
31054    var item_number = tr.data('item-number');
31055    var base_url = kitModel.item_price_url_template({item_number: item_number});
31056    $.ajax({
31057      url: base_url,
31058      data: build_get_price_data(item_number),
31059      headers: kitModel.csrf_token_header()
31060    }).done(function(data) {
31061      tr.find('.catalog-item-price').text(data.price_string);
31062    }).error(function() {
31063      tr.find('.catalog-item-price').text("");
31064    });
31065  }
31066
31067  function update_total_price(tr) {
31068    tr.find('.catalog-item-price').text("Calculating...");
31069
31070    const unconfigured_kit_items = EcatKitModel.incomplete_kit_items_and_groups();
31071    if (unconfigured_kit_items.complete) {
31072      const url = document.querySelector('#kit-modal').dataset.kitTotalPriceUrl;
31073      const form_data = EcatKitModel.build_form_data();
31074      const submission_data = {
31075        products: form_data
31076      };
31077      $.ajax(url, {
31078        data: submission_data,
31079        method: 'GET',
31080        headers: EcatKitModel.csrf_token_header()
31081      }).done(function (data) {
31082        tr.find('.catalog-item-price').text(data.price_string);
31083      }).error(function() {
31084        tr.find('.catalog-item-price').text("");
31085      });
31086    } else {
31087      tr.find('.catalog-item-price').text("Select options on all items for price");
31088    }
31089  }
31090  
31091  function update_item_number_for_row(tr) {
31092    var item_number = tr.data('item-number');
31093    var base_url = kitModel.item_number_url_template({item_number: item_number});
31094    $.ajax({
31095      url: base_url,
31096      data: build_get_price_data(item_number),
31097      headers: kitModel.csrf_token_header()
31098    }).done(function(data) {
31099      tr.find('.catalog-item-number').text(data.item_number_string);
31100    }).error(function() {
31101      tr.find('.catalog-item-number').text(item_number);
31102    });
31103  }
31104
31105  function update_prices() {
31106    // Update the total kit price
31107    const kit_parent_tr = $('.kit-items-table thead tr')
31108    update_total_price(kit_parent_tr);
31109    update_item_number_for_row(kit_parent_tr);
31110    // Update the prices for all the selected kit items
31111    $('.kit-items-table tbody tr').each(function() {
31112      var tr = $(this);
31113      update_price_for_row(tr);
31114      update_item_number_for_row(tr);
31115    });
31116  }
31117
31118  function update_urls() {
31119    _.each(this.selected_kit_items, function (kit_item) {
31120      $('tr[data-item-number="' + kit_item.item_number + '"] td.kit-items-table-actions div.catalog-item-options a').prop('href', build_options_link_url(kit_item))
31121    })
31122  }
31123
31124  function kit_item_for_item_number(item_number) {
31125    return _.find(all_kit_items(), function(kit_item) {
31126      return kit_item.item_number == item_number;
31127    });
31128  }
31129  function build_get_price_data(item_number) {
31130    return build_form_data_for_kit_item(kit_item_for_item_number(item_number));
31131  }
31132  function csrf_token_header() {
31133    return {
31134             "X-CSRF-Token": $("meta[name='csrf-token']").attr("content")
31135           }
31136  }
31137
31138  /**
31139   * Return an object describing incomplete kit items, or an object that
31140   * responds to object.complete with true if it's complete. This is used to
31141   * validate and prevent adding the kit to order if there are still options to
31142   * select.
31143   */
31144  function incomplete_kit_items_and_groups() {
31145    var that = this;
31146
31147    var required_unselected_item_groups =
31148      _.filter(unselected_kit_item_groups(), function(item_group) {
31149        return item_group[0].required;
31150      });
31151
31152    var kit_items = this.selected_kit_items.concat(this.parent_kit_item);
31153    var incomplete_kit_items =
31154      _.filter(kit_items, kit_item_is_incomplete);
31155
31156    var complete = required_unselected_item_groups.length === 0 &&
31157                      incomplete_kit_items.length === 0;
31158
31159    return {
31160      required_unselected_item_groups: required_unselected_item_groups,
31161      incomplete_kit_items:            incomplete_kit_items,
31162      complete:                        complete
31163    };
31164  }
31165  function option_form_changed() { }
31166
31167  /**
31168   * Used to add a configured kit item to the order. I.e.
31169   * - user views kit
31170   * - adds item to kit
31171   * - UI takes user to option configuration
31172   * - user configures options
31173   * - user clicks Add to Kit (or whatever) -> this method
31174   */
31175  function submit_kit_item(event) {
31176    event.preventDefault();
31177    var $form = $(this).parents('form'),
31178        $button = $(".qty-notes-submit", $form),
31179        kitURLString = $form.data("return-url"),
31180        kitURLPath = kitURLString.split('?')[0],
31181        kitURLSearch = kitURLString.split('?')[1],
31182        applyOptionsToAll = this.dataset['applyOptionsToAll'] === 'true';
31183
31184    if (kitURLSearch === "") {
31185      kitSubmitURL = kitURLPath + "?option_submission=" + escape($form.serialize());
31186    } else {
31187      kitSubmitURL = kitURLPath + "?" + kitURLSearch + "&option_submission=" + escape($form.serialize());
31188    }
31189
31190    if (applyOptionsToAll) {
31191      kitSubmitURL += "&apply_options_to_all=true";
31192    }
31193
31194    if (SUPERCAT.validation.validateOptions($form)) {
31195      var link = $('<a data-modal="kit-modal" href="' + kitSubmitURL + '">not visible</a>').appendTo($button.parent());
31196      SUPERCAT.modals.openModal('kit-modal', link);
31197    }
31198  }
31199
31200  function render_selected_options(product, selected_options) {
31201    var that = kitModel;
31202    var result = [];
31203
31204    _.each(product.option_sets, function(option_set) {
31205      _.each(selected_options, function(selected_option) {
31206        if (selected_option[0] == option_set.option_type_code) {
31207          var selected_forms = selected_option[3] ? selected_option[3][0] : {}
31208
31209          var url = that.rendered_option_url_template({ product_id: product.id,
31210                                                        option_type_code: selected_option[0],
31211                                                        option_code: selected_option[1],
31212                                                        option_forms: escape(JSON.stringify(selected_forms)) });
31213
31214          result.push({
31215            rendered_option_url: url,
31216          });
31217        }
31218      });
31219    });
31220    return result;
31221  }
31222
31223  function handle_ajax_fail(jqXHR) {
31224    var msg = '';
31225    if (jqXHR.status === 0) {
31226      msg = 'Cannot connect to the SuperCat server.\n Please verify your connection to the Internet and try again.';
31227      SUPERCAT.validation.showError($('#add-kit-to-order-button'), msg, 10000);
31228    } else {
31229      SUPERCAT.modals.openModal('server-error', this);
31230    }
31231  }
31232
31233  // Add a uuid property to the kit_item object so we can
31234  // uniquely identify kit items in the client side JS code.
31235  function add_uuid(kit_item) {
31236    kit_item.uuid = crypto.randomUUID();
31237  }
31238
31239  kitModel.initialize                         = initialize;
31240  kitModel.update_ui                          = update_ui;
31241  kitModel.select_kit_item                    = select_kit_item;
31242  kitModel.deselect_kit_item                  = deselect_kit_item;
31243  kitModel.build_form_data                    = build_form_data;
31244  kitModel.update_quantities                  = update_quantities;
31245  kitModel.update_prices                      = update_prices;
31246  kitModel.update_urls                        = update_urls;
31247  kitModel.csrf_token_header                  = csrf_token_header;
31248  kitModel.incomplete_kit_items_and_groups    = incomplete_kit_items_and_groups;
31249  kitModel.submit_kit_item                    = submit_kit_item;
31250  kitModel.render_selected_options            = render_selected_options;
31251  kitModel.handle_ajax_fail                   = handle_ajax_fail;
31252
31253  return kitModel;
31254}();
31255
31256EcatKitView = function() {
31257  return {
31258    init: function(options) {
31259      if (!_.some(options.kit_items))
31260        return;
31261
31262      EcatKitModel.initialize(options.kit_items, options.configuration);
31263      EcatKitModel.selected_kit_item_template         = _.template($('#selected-kit-item').text());
31264      EcatKitModel.unselected_kit_item_group_template = _.template($('#unselected-kit-item-group').text());
31265      EcatKitModel.item_price_url_template            = _.template(_.trim($('#item-price-url').text()).replace("ITEMNUMBER", "<%= item_number %>"));
31266      EcatKitModel.item_number_url_template           = _.template(_.trim($('#item-number-url').text()).replace("ITEMNUMBER", "<%= item_number %>"));
31267      EcatKitModel.option_popup_url_template          = _.template(_.trim($('#option-popup-url').text()).replace("PRODUCTID", "<%= id %>"));
31268      EcatKitModel.option_image_url_template          = _.template(_.trim($('#option-image-url').text()).replace("FILENAME", "<%= filename %>"));
31269      EcatKitModel.rendered_option_url_template       = _.template(_.trim($('#rendered-option-url').text()).replace("PRODUCT_ID", "<%= product_id %>")
31270                                                                              .replace("OPTION_TYPE_CODE", "<%= option_type_code %>")
31271                                                                              .replace("OPTION_CODE", "<%= option_code %>")
31272                                                                              .replace("OPTION_FORMS", "<%= option_forms %>"));
31273      EcatKitModel.kit_configurator_url_template      = _.template(_.trim($('#kit-configurator-url').text()).replace("PRODUCTID", "<%= id %>").replace("CONFIGURATION", "<%= configuration %>"));
31274      EcatKitModel.update_ui();
31275
31276      $('#unselected-kit-item-area').on('click', '.add-to-kit-button', function() {
31277        var kit_item = $(this).data('kit-item');
31278        EcatKitModel.select_kit_item(kit_item);
31279      });
31280
31281      $('table.kit-items-table').on('click', '.remove-selected-kit-item', function() {
31282        const item_number = $(this).parent().parent().data('item-number');
31283        const uuid = $(this).parent().parent().data('uuid');
31284        EcatKitModel.deselect_kit_item(item_number, uuid);
31285        return false;
31286      });
31287
31288      $('table.kit-items-table').on('change', '.addtoorder-qty-field input', function() {
31289        var parent_quantity = parseInt($(this).val());
31290        EcatKitModel.selected_quantity = parent_quantity;
31291        EcatKitModel.update_quantities(parent_quantity);
31292        EcatKitModel.update_prices();
31293        EcatKitModel.update_urls();
31294      });
31295
31296      $('#add-kit-to-order-button').click(function(event) {
31297        event.preventDefault();
31298        var unconfigured_kit_items = EcatKitModel.incomplete_kit_items_and_groups();
31299        if (unconfigured_kit_items.complete) {
31300          var path = options.add_multiple_path;
31301          var form_data = EcatKitModel.build_form_data();
31302          var submission_data = {
31303            products: form_data
31304          };
31305          $.ajax(path, {
31306            data: submission_data,
31307            method: 'POST',
31308            headers: EcatKitModel.csrf_token_header()
31309          }).done(function() {
31310            $('#kit-confirmation').show().delay(500).fadeOut();
31311            SUPERCAT.modals.closeModal();
31312            $('#order-preview-menu-item').show();
31313          }).fail(function(jqXHR, exception) {
31314            EcatKitModel.handle_ajax_fail(jqXHR);
31315          });
31316        }
31317        else {
31318          _.each(unconfigured_kit_items.required_unselected_item_groups,
31319                  function(item_group) {
31320                    $('.kit-items-add[data-item-group-code="' + item_group[0].item_group_code + '"]').
31321                      addClass('error-highlight');
31322                  });
31323
31324          _.each(unconfigured_kit_items.incomplete_kit_items,
31325                  function(kit_item) {
31326                    $('table.kit-items-table tr[data-item-number="' + kit_item.item_number + '"]').
31327                      addClass('error-highlight');
31328                  });
31329
31330          SUPERCAT.validation.showError($('#add-kit-to-order-button'), 'Please finish configuring the items', 1000);
31331        }
31332      });
31333    }
31334  }
31335}();
31336EcatPortal = function() {
31337  function loadDataForTab(tab) {
31338    var content_href = $(tab).data('content-href');
31339    if (content_href) {
31340      return $.ajax({
31341        url: content_href,
31342        headers: {
31343           "X-CSRF-Token": $("meta[name='csrf-token']").attr("content")
31344          }
31345      });
31346    }
31347    else {
31348      // maybe this will work. goal is composability
31349      var result = $.Deferred();
31350      result.reject();
31351      return result;
31352    }
31353  }
31354
31355
31356  function init() {
31357    loadGraph();
31358  }
31359  
31360  function commaDelimitNumericQuantity(quantity) {
31361    return quantity.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
31362  }
31363
31364  function loadGraph() {
31365    loadDataForTab('#graph')
31366      .done(function(data) {
31367        $('#graph').html(data);
31368      });
31369  }
31370
31371  return {
31372    init: init,
31373    commaDelimitNumericQuantity: commaDelimitNumericQuantity,
31374    loadDataForTab: loadDataForTab
31375  };
31376}();
31377var EcatLiveModalLoad = function() {
31378  function loadDataFromUrl(url) {
31379    return $.ajax({
31380      url: url,
31381      headers: {
31382         "X-CSRF-Token": $("meta[name='csrf-token']").attr("content")
31383        }
31384    });
31385  }
31386
31387  function loadingHTML() {
31388    return "<div class=\"top-nav\">" +
31389            "</div>" +
31390            "<div class=\"panel\">" +
31391            "  Loading&hellip;" +
31392            "</div>";
31393  }
31394
31395  function errorHTML(errorText) {
31396    return "<div class=\"top-nav\">" +
31397            "</div>" +
31398            "<div class=\"panel\">" +
31399            "  " + errorText +
31400            "</div>";
31401  }
31402
31403  function showModal(e, url) {
31404    var button = $(e.relatedTarget),
31405        modal = $(e.target);
31406        url = (typeof url !== 'undefined') ? url : button.attr('href');
31407
31408    $(modal.find(".modal-content")).html(loadingHTML());
31409    loadDataFromUrl(url).done(function(data) {
31410        modal.find(".modal-content").html(data);
31411        history.pushState(data, null, url);
31412        SUPERCAT.modals.currentModalURL = url;
31413      }).error(function(response) {
31414        var errorText = response.responseJSON['message'] || 'Something went wrong, please try again.';
31415        $(modal.find(".modal-content")).html(errorHTML(errorText));
31416      });
31417  }
31418
31419  function reloadModal(e) {
31420    loadDataFromUrl(e.url)
31421      .done(function(data) {
31422        SUPERCAT.currentModal.find(".modal-content").html(data);
31423        SUPERCAT.modals.currentModalURL = e.url;
31424      })
31425      .error(function() {
31426        console.log('error');
31427      });
31428  }
31429
31430  function init(modalSelector) {
31431    // First, remove any previous modal events to prevent multiple triggers
31432    $(document).off('show.bs.modal', modalSelector, showModal);
31433    $(document).off('reload.bs.modal', modalSelector, reloadModal);
31434
31435    // Reinitialize
31436    $(document).on('show.bs.modal', modalSelector, showModal);
31437    $(document).on('reload.bs.modal', modalSelector, reloadModal);
31438  }
31439
31440  return {
31441    init: init
31442  };
31443}();
31444var SuperCat = SuperCat || {};
31445SuperCat.EcatQtyNotes = SuperCat.EcatQtyNotes || {};
31446
31447_.assign(SuperCat.EcatQtyNotes, (function () {
31448  var submitQtyNotesForm = function (evt, successFunc) {
31449    var form = $('#modal-qty-notes-dialog');
31450    var path = form.attr('action');
31451    var form_data = form.serialize();
31452    var obj_id = form.data('obj-id');
31453
31454    if(SUPERCAT.validation.validateOptions(form)) {
31455      jQuery.post(path,
31456                  form_data,
31457                  function (data, textStatus, jqXHR) {
31458                    $('#qty-notes-confirmation').show().delay(500).fadeOut();
31459                    successFunc({ 'obj_id'     : obj_id,
31460                                  'qty'        : $('#quantity').val(),
31461                                  'line_notes' : $('#line_notes').val(),
31462                                  'messages'   : data.join('. ') });
31463                  },
31464                  "json").fail(function (data, textStatus, jqXHR) {
31465                    alert('Failed: ' + data.responseJSON.join('. '));
31466                  });
31467
31468      SUPERCAT.modals.closeModal();
31469    }
31470  };
31471  
31472  var setUpFormBehavior = function() {
31473    $(document).on('show.bs.modal', "#addtoorder", function(e) {
31474      var button = $(e.relatedTarget);
31475      var submitFunctionName = button.data('submit-action');
31476      if (submitFunctionName) {
31477        var submitFunction = eval(submitFunctionName); // better way??
31478        // first remove event handlers that were attached in other pages that load
31479        // this script to ensure the event handler is only registered once
31480        $(e.target).off('click', '.qty-notes-submit', submitFunction);
31481        $(e.target).on('click', '.qty-notes-submit', submitFunction);
31482      }
31483
31484      // the change-action is not currently implemented in the app
31485      var changeFunctionName = button.data('change-action');
31486      if (changeFunctionName) {
31487        var changeFunction = eval(changeFunctionName);
31488        $(e.target).on('change', 'input', changeFunction);
31489        $(e.target).on('change', 'textarea', changeFunction);
31490      }
31491    });
31492  };
31493
31494  return {
31495    submitQtyNotesForm : submitQtyNotesForm,
31496    setUpFormBehavior : setUpFormBehavior,
31497  };
31498}()));
31499var SuperCat = SuperCat || {};
31500SuperCat.EcatProjects = SuperCat.EcatProjects || {};
31501
31502_.assign(SuperCat.EcatProjects, (function () {
31503
31504  var addProjectAjaxComplete = function(evt, data, sts, xhr) {
31505    if (sts == 'success') {
31506      SUPERCAT.modals.closeModal();
31507      $('#project-create-success-flash').show().delay(2000).fadeOut();
31508    } else {
31509      $('#project-create-error-details').empty();
31510      _(data.responseJSON).forEach(function(m){
31511        $('#project-create-error-details').append(m);
31512        $('#project-create-error-details').append("<br/>");
31513      });
31514      $('#project-create-error-flash').show().delay(4000).fadeOut();
31515    }
31516  };
31517
31518  var undoProductRemovalAjaxComplete = function(e, data, sts) {
31519    if (sts == 'success') {
31520      location.reload(true);
31521    } else {
31522      $('#project-create-error-details').empty();
31523      _(data.responseJSON).forEach(function(m){
31524        $('#project-create-error-details').append(m);
31525        $('#project-create-error-details').append("<br/>");
31526      });
31527      $('#project-create-error-flash').show().delay(4000).fadeOut();
31528    }
31529  }
31530
31531  var loadNames = function(e) {
31532    var path=$("#nav-project").data('url');
31533    $.get(path,
31534      function (data) {
31535        // Remove all existing projects, except the first child as this contains the company logo
31536        $(".project-names li:not(:first-child)").remove();
31537        _(data).forEach(function(payload){
31538          $(".project-names").append("<li data-selection-id=project-"+payload[2]+"><a href="+payload[1]+">"+payload[0]+"</a></li>");
31539        });
31540        $(".project-names").append("<li data-selection-id=project-selection-fallback class='hidden'></li>");
31541      }
31542    );
31543  };
31544
31545  var rememberEmailFields = function () {
31546    var get_org = function() {
31547     var url = window.location.href;
31548     var segments = url.split('/');
31549     return segments[3] + "_project";
31550    };
31551
31552    var org = get_org();
31553
31554    var retrieveEmailValues = function () {
31555     var from_name = localStorage.getItem(org + "_from_name");
31556     var from_email = localStorage.getItem(org + "_from_email");
31557
31558     if(from_email) {
31559       $('#email-project-panel input#from_name').val(from_name);
31560       $('#email-project-panel input#from').val(from_email);
31561     }
31562    };
31563
31564    var setEmailValues = function () {
31565     var from_name = $('#email-project-panel input[name="from_name"]').val();
31566     var from_email = $('#email-project-panel input[name="from"]').val();
31567     localStorage.setItem(org + "_from_name", from_name);
31568     localStorage.setItem(org + "_from_email", from_email);
31569    }
31570
31571    $('#email-project-panel form').on('submit', setEmailValues);
31572    retrieveEmailValues();
31573  };
31574
31575  var emailPanelShowHide = function(e) {
31576    //show/hide email form link
31577    var $email_panel = $('#email-project-panel');
31578    if($email_panel.hasClass('is-hidden')) {
31579      $email_panel.removeClass('is-hidden');
31580    } else {
31581      $email_panel.addClass('is-hidden');
31582    }
31583  };
31584
31585
31586  var migrateFavoritesToProjects = function(e) {
31587    favs = SUPERCAT.favorites.get_favorites();
31588    if (favs !== null && favs.length > 0) {
31589      item_numbers = favs.map(function(f) {
31590        return f.num;
31591      });
31592
31593      base = window.location.origin;
31594      parts = window.location.pathname.split('/');
31595      url = base +'/'+ parts[1] +'/'+ parts[2] +'/' + parts[3] + '/projects/migrate'
31596      $.post( url,
31597        {'item_numbers[]': item_numbers},
31598        function(response, sts) {
31599          if( sts == "success") {
31600            SUPERCAT.favorites.clear_favorites();
31601          }
31602      });
31603    }
31604  }
31605
31606  //Main entry point
31607  var setUp = function() {
31608    $(document).on('show.bs.modal', "#projects-modal", function(e) {
31609      var elem = $(e.relatedTarget);
31610      var ajaxCompleteActionName = elem.data('ajax-complete-action');
31611      if (ajaxCompleteActionName) {
31612        var ajaxCompleteAction = eval(ajaxCompleteActionName);
31613        $(e.target).on('ajax:complete', ajaxCompleteAction);
31614      }
31615    });
31616
31617    //ajax for projects navigation
31618    $(document).on('click', "#nav-project", loadNames);
31619
31620    // auto focus on input when creating new project
31621    $(document).on('click', '#create-new-project', function(){
31622      $('#projects-modal-add #project_name').focus();
31623    });
31624  };
31625
31626  //Entry point for show pages
31627  var setUpShow = function() {
31628    $(document).on('click', ".email-project-link", emailPanelShowHide);
31629    $(rememberEmailFields);
31630
31631   //product deletion undo
31632    $('#undo-project-remove-product').on('ajax:complete', undoProductRemovalAjaxComplete);
31633  }
31634
31635  return {
31636    setUp: setUp,
31637    setUpShow: setUpShow,
31638    addProjectAjaxComplete: addProjectAjaxComplete,
31639    migrate: migrateFavoritesToProjects
31640  };
31641}()));
31642
31643EcatFormHelper = function() {
31644  // This is an additional form validation safety net that kicks in after built in browser validation for:
31645  // 1. browsers that do not have built in form validation (e.g. safari mobile)
31646  // 2. Cases where the browser validation fails (e.g. blah@blah is permitted by Firefox & Chrome)
31647  //
31648  // It prevents form submission and sets a red background color for the element if there is a validation error.
31649  // This function supports multiple forms on the page, only the form that was submitted will be affected.
31650  function _validateFields(e, options) {
31651    var requiredFields = $(options.requiredSelector, e.target);
31652    var emailFields    = $(options.emailSelector, e.target);
31653    var error = false;
31654    var color = 'rgb(255,155,155)'
31655    // This is a modified RFC 2822 implementation: simplified AND
31656    // modified to prevent single character domain extensions by removing ? at the end
31657    var regex = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])/;
31658
31659    _.forEach(requiredFields, function(field) {
31660     if(field.value == '') {
31661       field.style.backgroundColor = color;
31662       error = true;
31663     } else {
31664       field.style.backgroundColor = 'initial'
31665     }
31666    });
31667
31668    _.forEach(emailFields, function(field) {
31669      if (false === regex.test(String(field.value).toLowerCase())) {
31670         field.style.backgroundColor = color;
31671         error = true;
31672      } else {
31673         field.style.backgroundColor = 'initial'
31674      }
31675    });
31676
31677    if(error) {
31678      e.preventDefault();
31679      return false
31680    }
31681  }
31682
31683  // Entry point for a generic form validator.
31684  // options.parentSelector: The event listener will be attached to this node. Optional. Default '#email-form'
31685  // options.requiredSelector: Selector for all required elements in the form. Optional. Default '[required]'
31686  // options.emailSelector: Selector for email fields in the form. Optional. Default '[type=email]'
31687  function validateFields(options) {
31688    options = options || {}
31689    options.parentSelector = (options.parentSelector === undefined) ? '#email-form' : options.parentSelector;
31690    options.requiredSelector =  (options.requiredSelector === undefined) ? '[required]' : options.requiredSelector;
31691    options.emailSelector = (options.emailSelector === undefined) ? '[type=email]' : options.emailSelector;
31692
31693    $(options.parentSelector + ' form').on('submit', function(e) {
31694      _validateFields(e, options);
31695    });
31696  }
31697
31698  return {
31699    validateFields: validateFields,
31700  };
31701}();
31702var SuperCat = SuperCat || {};
31703SuperCat.PricingLevels = SuperCat.PricingLevels || {};
31704
31705_.assign(SuperCat.PricingLevels, (function () {
31706  
31707  function initialize(options){
31708    wrapper = options.wrapper;
31709
31710    var secondaryInputWrapper = wrapper.getElementsByClassName('secondary-input-wrapper')[0];
31711    var secondaryInputTrigger = wrapper.getElementsByClassName('secondary-input-trigger')[0];
31712    var secondaryInputField = secondaryInputWrapper.getElementsByClassName('secondary-input-field')[0];
31713    
31714    // on catalog radio click
31715    secondaryInputTrigger.addEventListener('change', function() {
31716      secondaryInputWrapper.style.display='inline-block';
31717      secondaryInputField.focus();
31718    });
31719
31720    // On page load if catalog was already selected
31721    if (secondaryInputTrigger.checked) {
31722      secondaryInputField.required = true;
31723      secondaryInputWrapper.style.display='inline-block';
31724    }
31725
31726    //When catalog is chosen then other choice is made
31727    var others = document.querySelectorAll('.checkboxes input:not(.secondary-input-trigger)[type=radio]')
31728
31729    others.forEach(function(button) {
31730      button.addEventListener('click', function() {
31731        secondaryInputField.required = false;
31732        secondaryInputWrapper.style.display='none';
31733      });
31734    });
31735  };
31736
31737  return {
31738    initialize: initialize,
31739  };
31740}()));
31741var SuperCat = SuperCat || {};
31742SuperCat.EcatReports = SuperCat.EcatReports || {};
31743
31744_.assign(SuperCat.EcatReports, (function () {
31745  var aweb_key = null;
31746  var mobile   = null;
31747  var org      = null;
31748
31749  var displayFlashMessage = function(){
31750    var flash_id = '#wait-flash-message'
31751    var slideUpFlashMessage = function(){
31752      $(flash_id).slideUp(1000);
31753    };
31754
31755    $(flash_id).slideDown(1000,function(){
31756      setTimeout(slideUpFlashMessage, 5000);
31757    });
31758  };
31759
31760  var downloadXlsxReport = function(controller, action, org_shortname, mobile_sitename){
31761    org       = org_shortname;
31762    mobile    = mobile_sitename;
31763    var url   = '/' + org + '/e/' + mobile + '/reports/ecat_export_csv.json';
31764    var query = null;
31765
31766    if(!window.location.search){
31767      query = '?source=' + controller + '&type=' + action;
31768    } else {
31769      query = window.location.search + '&source=' + controller + '&type=' + action;
31770    }
31771
31772    jQuery.get( url + query, function(response){ displayFlashMessage(); }).
31773      fail(function(){ console.log(response)}); // we are already emailing user if report failed; leaving this here for debugging purposes
31774  };
31775
31776  return {
31777    downloadXlsxReport: downloadXlsxReport,
31778    displayFlashMessage: displayFlashMessage
31779  };
31780}()));
31781var SuperCat = SuperCat || {};
31782SuperCat.RmaRequests = SuperCat.RmaRequests || {};
31783
31784_.assign(SuperCat.RmaRequests, (function () {
31785  var photosProgress;
31786  var codeName;
31787  var errorsPresent;
31788  var ineligibilityReason;
31789
31790  function resetShipToFields() {
31791    $(".shipping-address-fields input").each(function(i, element) {
31792      element.value = element.defaultValue;
31793    });
31794  };
31795
31796  //--------------------------//
31797  //     < UI Validations >   //
31798  //--------------------------//
31799  function validatePhotoRequired(selectedOption, callbacks){
31800    if($(selectedOption).data('photo-required') && !anyAttachedPhoto()){
31801      errorsPresent.push(displayPhotoRequiredError);
31802      errorsPresent.push(enableDropzone);
31803    };
31804  };
31805
31806  function validateIneligibleCode(selectedOption){
31807    if(!$(selectedOption).data('elegible')){
31808
31809      ineligibilityReason = $(selectedOption).data('inelegibility-reason');
31810
31811      errorsPresent.push(displayIneligibilityError);
31812    };
31813  };
31814
31815  function validateExpiredCode(selectedOption){
31816    if($(selectedOption).data('is-expired')){
31817      const expirationTime = selectedOption.data('expiration-time');
31818      const expirationMessage = `Selected return code is only valid for ${expirationTime} days from the Invoice Date. Please contact Customer Service for assistance`
31819      errorsPresent.push(() => { displayCodeExpiredError(expirationMessage) });
31820    };
31821  };
31822
31823  function displayMaxPhotosError(){
31824    freezeDropzone();
31825
31826    $('.photo-list').css('cursor', 'default');
31827    $('.max-photos-error').show().delay(3000).fadeOut();
31828  };
31829
31830  function displayFileTypeError(){
31831    $('.type-files-error').show().delay(3000).fadeOut();
31832  };
31833
31834  function displayPhotoRequiredError(){
31835    $('.upload-photo-required').show();
31836  };
31837
31838  function hidePhotoRequiredError(){
31839    $('.upload-photo-required').hide();
31840  };
31841
31842  function displayIneligibilityError(){
31843    $('.ineligible-return-code div').append('* This code is not elegible for returns. ' + ineligibilityReason);
31844    $('.ineligible-return-code').show();
31845  };
31846
31847  function hideInelegibilityError(){
31848    $('.ineligible-return-code div').html('');
31849    $('.ineligible-return-code').hide();
31850  };
31851
31852  function displayCodeExpiredError(msg){
31853    $('.expired-return-code').html(msg);
31854    $('.expired-return-code').show();
31855  };
31856
31857  function hideCodeExpiredError(){
31858    $('.expired-return-code').hide();
31859  };
31860
31861  function toggleInformativeMessages(){
31862    $('.drop-text').toggle();
31863    $('.drop-loading').toggle();
31864    $('.photo-list').toggle();
31865  };
31866
31867  function displayInvalidQuantityError(){
31868    $('.invalid-quantity').show();
31869  };
31870
31871  function hideInvalidQuantityError(){
31872    $('.invalid-quantity').hide();
31873  };
31874
31875  function disableSubmitButton(){
31876    var $submitButton = $('#submit-rma-request');
31877
31878    $submitButton.attr('disabled', 'disabled');
31879    $submitButton.css('cursor', 'default');
31880    $submitButton.css('background-color', 'gray');
31881  };
31882
31883  function enableSubmitButton(){
31884    var $submitButton = $('#submit-rma-request');
31885
31886    $submitButton.removeAttr('disabled');
31887    $submitButton.css('cursor', 'pointer');
31888    $submitButton.css('background-color', '#3870a0');
31889  };
31890
31891  function freezeDropzone(){
31892    $('.dropzone').data('enabled', false);
31893    $('.dropzone').unbind();
31894    $('.attach-photos').unbind();
31895
31896    $('.dropzone').css('cursor', 'default');
31897    $('.dropzone').on('dragover', onDragOverDragEnter);
31898    $('.dropzone').on('dragenter', onDragOverDragEnter);
31899    $('.dropzone').on('dragleave', onDragLeave);
31900  };
31901
31902  function enableDropzone(){
31903    if($(".dropzone").data('enabled')) { return };
31904
31905    $('.dropzone').data('enabled', true);
31906    $('.dropzone').css('cursor', 'pointer');
31907
31908    $('.dropzone').on('dragover', onDragOverDragEnter);
31909    $('.dropzone').on('dragenter', onDragOverDragEnter);
31910    $('.dropzone').on('dragleave', onDragLeave);
31911    $('.dropzone').on('drop', onDrop);
31912    $('.dropzone').on('click', onDropzoneClick);
31913    $('.attach-photos').on('change', onChange);
31914  };
31915  //---------------------------//
31916  //     </ UI Validations >   //
31917  //---------------------------//
31918
31919
31920  //----------------------------//
31921  //     < Internal Process >   //
31922  //----------------------------//
31923  function incrementAttachedPhotosAmount(){
31924    var currentAttachedPhotos = $('.photo-list').data('attached-photos');
31925    $('.photo-list').data('attached-photos', 1 + currentAttachedPhotos);
31926  };
31927
31928  function maxAmountOfPhotos(){
31929    return $('.photo-list').data('attached-photos') + 1 >= 6;
31930  };
31931
31932  function amountOfAttachedPhotos(){
31933    return $('ul.photo-list li').length;
31934  };
31935
31936  function anyAttachedPhoto(){
31937    return amountOfAttachedPhotos() > 0;
31938  };
31939
31940  function missingPhotos(){
31941    return $('#rma_request_code option:selected').data('photo-required') &&
31942      amountOfAttachedPhotos() == 0;
31943  };
31944
31945  function invalidQuantity(){
31946    var enteredQuantity  = $('#rma_request_quantity').val();
31947    var invoicedQuantity = $('#rma_request_quantity').data('quantity-invoiced');
31948
31949    if(enteredQuantity === '' || enteredQuantity <= 0){
31950      return true;
31951    } else {
31952      return (parseInt(enteredQuantity) > invoicedQuantity);
31953    }
31954  };
31955
31956  function photosUploadProgress(photoName, e){
31957    if (e.lengthComputable) {
31958
31959      var progress = (e.loaded / e.total) * 100 ;
31960
31961      photosProgress[photoName] = progress;
31962
31963      $('.upload-progress').css('width', calculateGlobalUploadProgress() + '%');
31964    }
31965  };
31966
31967  function calculateGlobalUploadProgress(){
31968    var imagesProgress = Object.values(photosProgress);
31969    var globalProgress = imagesProgress.reduce(function(total, progress){
31970      return total + progress;
31971    });
31972
31973    return (globalProgress / imagesProgress.length);
31974  };
31975
31976  function photoUploadCompleted(photoName, e){
31977    attachPhotoToRmaForm(photoName, function(){
31978      if(calculateGlobalUploadProgress() == 100){
31979        // For safety give it a 2 sec period of grace to complete
31980        // last image upload
31981        setTimeout(function(){
31982          $('form#create-rma-request').submit();
31983        }, 2000);
31984      }
31985    });
31986  };
31987
31988  function attachPhotoToRmaForm(photoName, callback){
31989    var newPhotoInput = '<input class="new-photo" type=hidden name=rma_request[photos][] value="' + photoName + '">';
31990
31991    $('form#create-rma-request').append(newPhotoInput);
31992
31993    callback();
31994  };
31995
31996  function photoNameInS3(imageElement){
31997    return codeName + '-' + $(imageElement).data('name');
31998  };
31999
32000  // Convert resized 64-based photo to Blob
32001  function b64toBlob(b64Data, contentType, sliceSize) {
32002    var contentType    = contentType || '';
32003    var sliceSize      = sliceSize || 512;
32004    var byteCharacters = atob(b64Data);
32005    var byteArrays     = [];
32006
32007    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
32008      var slice       = byteCharacters.slice(offset, offset + sliceSize);
32009      var byteNumbers = new Array(slice.length);
32010
32011      for (var i = 0; i < slice.length; i++) {
32012        byteNumbers[i] = slice.charCodeAt(i);
32013      }
32014
32015      var byteArray = new Uint8Array(byteNumbers);
32016
32017      byteArrays.push(byteArray);
32018    }
32019
32020    var blob = new Blob(byteArrays, {type: contentType});
32021
32022    return blob;
32023  };
32024
32025  function conditionallyEnableSubmitButton() {
32026    var otherErrors = errorsPresent.filter(function(value) {
32027      return value != displayPhotoRequiredError && value != enableDropzone;
32028    });
32029
32030    if (otherErrors.length == 0) {
32031      enableSubmitButton();
32032    }
32033  }
32034
32035  // Attach photos
32036  function proccessPhotos(files){
32037    var errors = [];
32038
32039    conditionallyEnableSubmitButton();
32040
32041    $.each(files, function(i, file) {
32042      var reader = new FileReader();
32043
32044      // Validates user can't attach more than
32045      // 5 files at the same time
32046      if(i >= 5){ errors.push(displayMaxPhotosError) };
32047
32048      if(!file.type.match('image.*')) {
32049        if(!anyAttachedPhoto()){ toggleInformativeMessages(); };
32050
32051        errors.push(displayFileTypeError);
32052      };
32053
32054      if(errors.length > 0){
32055        $.each( errors, function(i, error){ error(); });
32056      };
32057
32058      reader.onload = $.proxy(function(file, $photoList, event) {
32059        // Validates user can't attach more than N + 1 files
32060        // at different times
32061        if( maxAmountOfPhotos() ){ return displayMaxPhotosError(); }
32062
32063        if(!file.type.match('image.*')){
32064          if(!anyAttachedPhoto()){ toggleInformativeMessages(); };
32065
32066          return displayFileTypeError();
32067        }
32068
32069        incrementAttachedPhotosAmount();
32070
32071        var photo = new Image();
32072
32073        photo.onload = function(){
32074          var canvas    = document.createElement("canvas");
32075          var context   = canvas.getContext("2d");
32076          var newSizes  = photoResizedDimentions(photo.width, photo.height);
32077          canvas.width  = newSizes.width;
32078          canvas.height = newSizes.height;
32079
32080          context.drawImage(
32081            photo,
32082            0,
32083            0,
32084            photo.width,
32085            photo.height,
32086            0,
32087            0,
32088            canvas.width,
32089            canvas.height
32090          );
32091
32092          var img = file.type.match('image.*') ? "<img class='upload-to-s3' style='max-width: 120px; max-height: 80px;' data-name='" + file.name + "' src='" + canvas.toDataURL() + "' /> " : "";
32093          $photoList.append( $("<li style='display: inline; margin-right: 15px;'>").append( img ) );
32094
32095          $('.drop-loading').hide();
32096        };
32097
32098        photo.src = event.target.result;
32099      }, this, file, $(".photo-list"));
32100
32101      reader.readAsDataURL(file);
32102    });
32103  };
32104
32105  // Resize photo if exceeds 2048x1536 pixels
32106  function photoResizedDimentions(width, height){
32107    if(width <= 2048 && height <= 1536){
32108      return {width: width, height: height};
32109    };
32110
32111    var newWidth  = width;
32112    var newHeight = height;
32113    var maxWidth  = 2048;
32114    var maxHeight = 1536;
32115    var ratio     = 0;
32116
32117    if(width > maxWidth){
32118      ratio     = maxWidth / width;
32119      newHeight = height * ratio;
32120      newWidth  = width * ratio;
32121    }
32122
32123    if(newHeight > maxHeight){
32124      ratio     = maxHeight / newHeight;
32125      newWidth  = newWidth * ratio;
32126      newHeight = newHeight * ratio;
32127    }
32128
32129    return {width: newWidth, height: newHeight};
32130  };
32131
32132  function resetAllErrorMessages(){
32133    errorsPresent = [];
32134    hidePhotoRequiredError();
32135    hideInelegibilityError();
32136    hideCodeExpiredError();
32137  };
32138  //-----------------------------//
32139  //     </ Internal Process >   //
32140  //-----------------------------//
32141
32142
32143  //------------------//
32144  //     < Events >   //
32145  //------------------//
32146  function onSubmitRMAButtonClick(e){
32147    // If form is invalid due to HTML5 validations then return immediately
32148    // Form will not submit anyway and we want a valid form before proceeding
32149    // This fixes issues with custom field validations interfering with the following functionality
32150    if (this.form.checkValidity() === false) {
32151      return
32152    }
32153
32154    e.preventDefault();
32155
32156    if(invalidQuantity()){
32157      return displayInvalidQuantityError();
32158    };
32159
32160    if(missingPhotos()){
32161      // display 'At least 1 photo is required'
32162      return displayPhotoRequiredError();
32163    } else if(!anyAttachedPhoto()) {
32164
32165      if(noReplacementChekced()){
32166        if(confirmContinueWithoutReplacement() == false){ return };
32167      };
32168
32169      // submit form if no photos are attached
32170      // and no photos are required
32171      $(this).unbind('click').click();
32172    } else {
32173      if(noReplacementChekced()){
32174        if(confirmContinueWithoutReplacement() == false){ return };
32175      };
32176    };
32177
32178    disableSubmitButton();
32179    freezeDropzone();
32180
32181    var photosToUpload = $('img.upload-to-s3');
32182    var form           = document.getElementById('s3-uploader');
32183    var formFields     = { };
32184    var uploadBarWidth = 0;
32185
32186    // Serialize form fields
32187    $.each($(form).serializeArray(), function() {
32188      formFields[this.name] = this.value;
32189    });
32190
32191    if(anyAttachedPhoto()){ $('.upload-progress').show(); };
32192
32193    // Individual uploads; AWS S3 supports one
32194    // object per HTTP request:
32195    // "POST requires exactly one file upload per request."
32196    $.each(photosToUpload, function(i, img) {
32197      var photoURL    = $(img).attr('src');
32198      var photoName   = photoNameInS3(img);
32199      var block       = photoURL.split(";");
32200      var contentType = block[0].split(":")[1];
32201      var realData    = block[1].split(",")[1];
32202      var blob        = b64toBlob(realData, contentType);
32203      var formData    = new FormData(); // Create formData object to append data to be sent
32204      var request     = new XMLHttpRequest(); // Create request object to perform ajax call
32205
32206      // Append form fields to 'formData'
32207      $.each(formFields, function(key, val) {
32208        formData.append(key, val);
32209      });
32210
32211      photosProgress[photoName] = 0;
32212      formData.append('file', blob, photoName); // Append photo file to 'formData'
32213      request.upload.addEventListener('progress', photosUploadProgress.bind(null, photoName)); // Attach progress listener to request
32214      request.upload.addEventListener('load', photoUploadCompleted.bind(null, photoName)); // Attach progress listener to request
32215      request.open('POST', form.action); // Prepare request
32216      request.send(formData); // Submit request
32217    });
32218  };
32219
32220  function onDragOverDragEnter(e) {
32221    e.preventDefault();
32222    e.stopPropagation();
32223
32224    //In case we want to add any styling
32225    $(this).addClass('dragover');
32226  };
32227
32228  function onDragLeave(e) {
32229    e.preventDefault();
32230    e.stopPropagation();
32231
32232    //In case we want to add any styling
32233    $(this).removeClass('dragover');
32234  };
32235
32236  function onDropzoneClick(e){
32237    $('input.attach-photos').click();
32238  };
32239
32240  function onChange(e){
32241    hidePhotoRequiredError();
32242
32243    proccessPhotos(this.files);
32244
32245    if(!anyAttachedPhoto()){ toggleInformativeMessages(); };
32246  };
32247
32248  function onDrop(e) {
32249    $(this).removeClass('dragover');
32250
32251    hidePhotoRequiredError();
32252
32253    if(!anyAttachedPhoto()){ toggleInformativeMessages(); };
32254
32255    var dataTransfer = e.originalEvent.dataTransfer;
32256
32257    if( dataTransfer && dataTransfer.files.length) {
32258      e.preventDefault();
32259      e.stopPropagation();
32260      proccessPhotos(dataTransfer.files);
32261    }
32262  };
32263  //-------------------//
32264  //     </ Events >   //
32265  //-------------------//
32266
32267
32268  //----------------------------//
32269  //     < Public Interface >   //
32270  //----------------------------//
32271  function initialize() {
32272    photosProgress = {};
32273
32274    $("#different_address_no").click(resetShipToFields);
32275    $("#submit-rma-request").click(onSubmitRMAButtonClick);
32276
32277    enableDropzone();
32278    disableSubmitButton();
32279  };
32280
32281  // All code-dependent validations
32282  function validateSelectedCode(selectedOption){
32283    resetAllErrorMessages();
32284
32285    $('option.default').removeAttr('selected');
32286
32287    codeName = $(selectedOption).data('code-name');
32288
32289    var handlePhotoRequiredValidation = new Promise(function(resolve, reject){
32290      validatePhotoRequired(selectedOption);
32291
32292      if(errorsPresent.length > 0){
32293        reject(errorsPresent);
32294      } else {resolve()}
32295    });
32296    var handleIneligibleCodeValidation = new Promise(function(resolve, reject){
32297      validateIneligibleCode(selectedOption);
32298
32299      if(errorsPresent.length > 0){
32300        reject(errorsPresent);
32301      } else {resolve()}
32302    });
32303    var handleExpiredCodeValidation = new Promise(function(resolve, reject){
32304      validateExpiredCode(selectedOption);
32305
32306      if(errorsPresent.length > 0){
32307        reject(errorsPresent);
32308      } else {resolve()}
32309    });
32310
32311    Promise.all([handlePhotoRequiredValidation, handleIneligibleCodeValidation, handleExpiredCodeValidation])
32312    .then(function(){
32313      enableDropzone();
32314      enableSubmitButton();
32315    }).catch(function(failingValidationsCallbacks){
32316      freezeDropzone();
32317      disableSubmitButton();
32318      $.each(failingValidationsCallbacks, function(i, error){ error(); });
32319    });
32320  };
32321
32322  function allowOnlyNumbers(){
32323    var event = window.event;
32324
32325    // Handle paste
32326    if (event.type === 'paste') {
32327      key = event.clipboardData.getData('text/plain');
32328    } else {
32329      // Handle key press
32330      var key = event.keyCode || event.which;
32331      key = String.fromCharCode(key);
32332    }
32333    var regex = /[0-9]/;
32334    if( !regex.test(key) ) {
32335      event.returnValue = false;
32336      if(event.preventDefault) event.preventDefault();
32337    }
32338  };
32339
32340  function validateQuantity(){
32341    if(invalidQuantity()){
32342      displayInvalidQuantityError();
32343    } else {
32344      hideInvalidQuantityError();
32345    };
32346  };
32347
32348  function noReplacementChekced(){
32349    return $('#replacement_no').is(':checked');
32350  };
32351
32352  function confirmContinueWithoutReplacement(){
32353    return confirm('Are you sure you want to proceed without a replacement?');
32354  }
32355
32356  //-----------------------------//
32357  //     </ Public Interface >   //
32358  //-----------------------------//
32359
32360
32361  return {
32362    initialize: initialize,
32363    validateSelectedCode: validateSelectedCode,
32364    allowOnlyNumbers: allowOnlyNumbers,
32365    validateQuantity: validateQuantity
32366  };
32367}()));
32368var SuperCat = SuperCat || {};
32369SuperCat.EcatCustomers = SuperCat.EcatCustomers || {};
32370
32371_.assign(SuperCat.EcatCustomers, (function () {
32372
32373  var doExportPurchases = function () {
32374    url = $(this).data('url');
32375    $.get(url,
32376    function(response, sts) {
32377      if(sts == "success") {
32378        SuperCat.EcatReports.displayFlashMessage();
32379      }
32380    });
32381  };
32382
32383  var doExportCustomers = function () {
32384    url = $(this).data('url');
32385    $.get(url,
32386    function(response, sts) {
32387      if(sts == "success") {
32388        SuperCat.EcatReports.displayFlashMessage();
32389      }
32390    });
32391  };
32392
32393  var purchasesDateChange = function () {
32394    this.form.submit();
32395  };
32396
32397  // Entry point for exporting products purchased
32398  var setUpShow = function () {
32399    $(document).on('click', '.export-products-purchased', doExportPurchases);
32400    $(document).on('change', '.customer-purchase-date-range select', purchasesDateChange);
32401  };
32402
32403  // Entry point for exporting customers on index page
32404  var setUpIndex = function () {
32405    $(document).on('click', '.export-customers', doExportCustomers);
32406  };
32407
32408  return {
32409    setUpShow:  setUpShow,
32410    setUpIndex: setUpIndex
32411  };
32412
32413}()));
32414var SuperCat = SuperCat || {};
32415SuperCat.AsyncWeb = SuperCat.AsyncWeb || {};
32416
32417_.assign(SuperCat.AsyncWeb, (function () {
32418  var refresh_seconds = null;
32419  var setTimeoutTrack = null;
32420
32421  var CheckProgress = new Object(
32422    {
32423      start: function(aweb_id, callback, asyncWebEndpoint) {
32424        var baseUrl          = window.location.origin;
32425        if (!asyncWebEndpoint) {
vendor: 7,436 bytes, lines 32426-32664
32426          asyncWebEndpoint = '/supercat/async_web/check_progress/';
32427        }
32428        var url              = baseUrl + asyncWebEndpoint + aweb_id + '/';
32429
32430        jQuery.
32431          get(url).
32432          done(function (data) {
32433          obj = jQuery.parseJSON(data);
32434
32435          if (obj.percent_complete > 99) {
32436            if( typeof(callback)==='function' ) {
32437              callback();
32438              clearTimeout(setTimeoutTrack);
32439            }
32440            else { location.reload(); }
32441          }
32442        });
32443
32444        setTimeoutTrack = setTimeout(function() { CheckProgress.start(aweb_id, callback, asyncWebEndpoint) }, refresh_seconds * 1000);
32445      }
32446    }
32447  );
32448
32449  // Public: Start AJAX calls to backend to check for status of
32450  //         AsyncWeb job associated to given awebid.
32451  //
32452  // awebid:              async_web.id
32453  // refresh_secs:        Amount of seconds between each 'async web status' call to backend.
32454  // [optional] callback: If given, it will execute given function as a final step once async
32455  //                      web job is finished. It replaces `window.location`.
32456  // [optional] asyncWebEndpoint: if given, it will perform 'async web status' call against
32457  //                              given endpoint instead of default one (ie /async_web/check_progress/')
32458  var init = function (awebid, refresh_secs, callback, asyncWebEndpoint) {
32459    refresh_seconds = refresh_secs;
32460
32461    CheckProgress.start(awebid, callback, asyncWebEndpoint);
32462  };
32463
32464  return {
32465    init : init
32466  };
32467}()));
32468+function ($) {
32469  'use strict';
32470
32471  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
32472  // ============================================================
32473
32474  function transitionEnd() {
32475    var el = document.createElement('bootstrap')
32476
32477    var transEndEventNames = {
32478      WebkitTransition : 'webkitTransitionEnd',
32479      MozTransition    : 'transitionend',
32480      OTransition      : 'oTransitionEnd otransitionend',
32481      transition       : 'transitionend'
32482    }
32483
32484    for (var name in transEndEventNames) {
32485      if (el.style[name] !== undefined) {
32486        return { end: transEndEventNames[name] }
32487      }
32488    }
32489
32490    return false // explicit for ie8 (  ._.)
32491  }
32492
32493  // http://blog.alexmaccaw.com/css-transitions
32494  $.fn.emulateTransitionEnd = function (duration) {
32495    var called = false
32496    var $el = this
32497    $(this).one('bsTransitionEnd', function () { called = true })
32498    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
32499    setTimeout(callback, duration)
32500    return this
32501  }
32502
32503  $(function () {
32504    $.support.transition = transitionEnd()
32505
32506    if (!$.support.transition) return
32507
32508    $.event.special.bsTransitionEnd = {
32509      bindType: $.support.transition.end,
32510      delegateType: $.support.transition.end,
32511      handle: function (e) {
32512        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
32513      }
32514    }
32515  })
32516
32517}(jQuery);
32518
32519
32520
32521/* ========================================================================
32522 * Bootstrap: carousel.js v3.3.5
32523 * http://getbootstrap.com/javascript/#carousel
32524 * ========================================================================
32525 * Copyright 2011-2015 Twitter, Inc.
32526 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
32527 * ======================================================================== */
32528
32529
32530+function ($) {
32531  'use strict';
32532
32533  // CAROUSEL CLASS DEFINITION
32534  // =========================
32535
32536  var Carousel = function (element, options) {
32537    this.$element    = $(element)
32538    this.$indicators = this.$element.find('.carousel-indicators')
32539    this.options     = options
32540    this.paused      = null
32541    this.sliding     = null
32542    this.interval    = null
32543    this.$active     = null
32544    this.$items      = null
32545
32546    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
32547
32548    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
32549      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
32550      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
32551  }
32552
32553  Carousel.VERSION  = '3.3.5'
32554
32555  Carousel.TRANSITION_DURATION = 600
32556
32557  Carousel.DEFAULTS = {
32558    interval: 5000,
32559    pause: 'hover',
32560    wrap: true,
32561    keyboard: true
32562  }
32563
32564  Carousel.prototype.keydown = function (e) {
32565    if (/input|textarea/i.test(e.target.tagName)) return
32566    switch (e.which) {
32567      case 37: this.prev(); break
32568      case 39: this.next(); break
32569      default: return
32570    }
32571
32572    e.preventDefault()
32573  }
32574
32575  Carousel.prototype.cycle = function (e) {
32576    e || (this.paused = false)
32577
32578    this.interval && clearInterval(this.interval)
32579
32580    this.options.interval
32581      && !this.paused
32582      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
32583
32584    return this
32585  }
32586
32587  Carousel.prototype.getItemIndex = function (item) {
32588    this.$items = item.parent().children('.item')
32589    return this.$items.index(item || this.$active)
32590  }
32591
32592  Carousel.prototype.getItemForDirection = function (direction, active) {
32593    var activeIndex = this.getItemIndex(active)
32594    var willWrap = (direction == 'prev' && activeIndex === 0)
32595                || (direction == 'next' && activeIndex == (this.$items.length - 1))
32596    if (willWrap && !this.options.wrap) return active
32597    var delta = direction == 'prev' ? -1 : 1
32598    var itemIndex = (activeIndex + delta) % this.$items.length
32599    return this.$items.eq(itemIndex)
32600  }
32601
32602  Carousel.prototype.to = function (pos) {
32603    var that        = this
32604    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
32605
32606    if (pos > (this.$items.length - 1) || pos < 0) return
32607
32608    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
32609    if (activeIndex == pos) return this.pause().cycle()
32610
32611    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
32612  }
32613
32614  Carousel.prototype.pause = function (e) {
32615    e || (this.paused = true)
32616
32617    if (this.$element.find('.next, .prev').length && $.support.transition) {
32618      this.$element.trigger($.support.transition.end)
32619      this.cycle(true)
32620    }
32621
32622    this.interval = clearInterval(this.interval)
32623
32624    return this
32625  }
32626
32627  Carousel.prototype.next = function () {
32628    if (this.sliding) return
32629    return this.slide('next')
32630  }
32631
32632  Carousel.prototype.prev = function () {
32633    if (this.sliding) return
32634    return this.slide('prev')
32635  }
32636
32637  Carousel.prototype.slide = function (type, next) {
32638    var $active   = this.$element.find('.item.active')
32639    var $next     = next || this.getItemForDirection(type, $active)
32640    var isCycling = this.interval
32641    var direction = type == 'next' ? 'left' : 'right'
32642    var that      = this
32643
32644    if ($next.hasClass('active')) return (this.sliding = false)
32645
32646    var relatedTarget = $next[0]
32647    var slideEvent = $.Event('slide.bs.carousel', {
32648      relatedTarget: relatedTarget,
32649      direction: direction
32650    })
32651    this.$element.trigger(slideEvent)
32652    if (slideEvent.isDefaultPrevented()) return
32653
32654    this.sliding = true
32655
32656    isCycling && this.pause()
32657
32658    if (this.$indicators.length) {
32659      this.$indicators.find('.active').removeClass('active')
32660      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
32661      $nextIndicator && $nextIndicator.addClass('active')
32662    }
32663
32664    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
vendor: 7,646 bytes, lines 32665-32927
32665    if ($.support.transition && this.$element.hasClass('slide')) {
32666      $next.addClass(type)
32667      $next[0].offsetWidth // force reflow
32668      $active.addClass(direction)
32669      $next.addClass(direction)
32670      $active
32671        .one('bsTransitionEnd', function () {
32672          $next.removeClass([type, direction].join(' ')).addClass('active')
32673          $active.removeClass(['active', direction].join(' '))
32674          that.sliding = false
32675          setTimeout(function () {
32676            that.$element.trigger(slidEvent)
32677          }, 0)
32678        })
32679        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
32680    } else {
32681      $active.removeClass('active')
32682      $next.addClass('active')
32683      this.sliding = false
32684      this.$element.trigger(slidEvent)
32685    }
32686
32687    isCycling && this.cycle()
32688
32689    return this
32690  }
32691
32692
32693  // CAROUSEL PLUGIN DEFINITION
32694  // ==========================
32695
32696  function Plugin(option) {
32697    return this.each(function () {
32698      var $this   = $(this)
32699      var data    = $this.data('bs.carousel')
32700      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
32701      var action  = typeof option == 'string' ? option : options.slide
32702
32703      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
32704      if (typeof option == 'number') data.to(option)
32705      else if (action) data[action]()
32706      else if (options.interval) data.pause().cycle()
32707    })
32708  }
32709
32710  var old = $.fn.carousel
32711
32712  $.fn.carousel             = Plugin
32713  $.fn.carousel.Constructor = Carousel
32714
32715
32716  // CAROUSEL NO CONFLICT
32717  // ====================
32718
32719  $.fn.carousel.noConflict = function () {
32720    $.fn.carousel = old
32721    return this
32722  }
32723
32724
32725  // CAROUSEL DATA-API
32726  // =================
32727
32728  var clickHandler = function (e) {
32729    var href
32730    var $this   = $(this)
32731    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
32732    if (!$target.hasClass('carousel')) return
32733    var options = $.extend({}, $target.data(), $this.data())
32734    var slideIndex = $this.attr('data-slide-to')
32735    if (slideIndex) options.interval = false
32736
32737    Plugin.call($target, options)
32738
32739    if (slideIndex) {
32740      $target.data('bs.carousel').to(slideIndex)
32741    }
32742
32743    e.preventDefault()
32744  }
32745
32746  $(document)
32747    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
32748    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
32749
32750  $(window).on('load', function () {
32751    $('[data-ride="carousel"]').each(function () {
32752      var $carousel = $(this)
32753      Plugin.call($carousel, $carousel.data())
32754    })
32755  })
32756
32757}(jQuery);
32758/* ========================================================================
32759 * Bootstrap: tab.js v3.3.5
32760 * http://getbootstrap.com/javascript/#tabs
32761 * ========================================================================
32762 * Copyright 2011-2015 Twitter, Inc.
32763 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
32764 * ======================================================================== */
32765
32766
32767
32768+function ($) {
32769  'use strict';
32770
32771  // TAB CLASS DEFINITION
32772  // ====================
32773
32774  var Tab = function (element) {
32775    // jscs:disable requireDollarBeforejQueryAssignment
32776    this.element = $(element)
32777    // jscs:enable requireDollarBeforejQueryAssignment
32778  }
32779
32780  Tab.VERSION = '3.3.5'
32781
32782  Tab.TRANSITION_DURATION = 150
32783
32784  Tab.prototype.show = function () {
32785    var $this    = this.element
32786    var $ul      = $this.closest('ul:not(.dropdown-menu)')
32787    var selector = $this.data('target')
32788
32789    if (!selector) {
32790      selector = $this.attr('href')
32791      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
32792    }
32793
32794    if ($this.parent('li').hasClass('active')) return
32795
32796    var $previous = $ul.find('.active:last a')
32797    var hideEvent = $.Event('hide.bs.tab', {
32798      relatedTarget: $this[0]
32799    })
32800    var showEvent = $.Event('show.bs.tab', {
32801      relatedTarget: $previous[0]
32802    })
32803
32804    $previous.trigger(hideEvent)
32805    $this.trigger(showEvent)
32806
32807    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
32808
32809    var $target = $(selector)
32810
32811    this.activate($this.closest('li'), $ul)
32812    this.activate($target, $target.parent(), function () {
32813      $previous.trigger({
32814        type: 'hidden.bs.tab',
32815        relatedTarget: $this[0]
32816      })
32817      $this.trigger({
32818        type: 'shown.bs.tab',
32819        relatedTarget: $previous[0]
32820      })
32821    })
32822  }
32823
32824  Tab.prototype.activate = function (element, container, callback) {
32825    var $active    = container.find('> .active')
32826    var transition = callback
32827      && $.support.transition
32828      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
32829
32830    function next() {
32831      $active
32832        .removeClass('active')
32833        .find('> .dropdown-menu > .active')
32834          .removeClass('active')
32835        .end()
32836        .find('[data-toggle="tab"]')
32837          .attr('aria-expanded', false)
32838
32839      element
32840        .addClass('active')
32841        .find('[data-toggle="tab"]')
32842          .attr('aria-expanded', true)
32843
32844      if (transition) {
32845        element[0].offsetWidth // reflow for transition
32846        element.addClass('in')
32847      } else {
32848        element.removeClass('fade')
32849      }
32850
32851      if (element.parent('.dropdown-menu').length) {
32852        element
32853          .closest('li.dropdown')
32854            .addClass('active')
32855          .end()
32856          .find('[data-toggle="tab"]')
32857            .attr('aria-expanded', true)
32858      }
32859
32860      callback && callback()
32861    }
32862
32863    $active.length && transition ?
32864      $active
32865        .one('bsTransitionEnd', next)
32866        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
32867      next()
32868
32869    $active.removeClass('in')
32870  }
32871
32872
32873  // TAB PLUGIN DEFINITION
32874  // =====================
32875
32876  function Plugin(option) {
32877    return this.each(function () {
32878      var $this = $(this)
32879      var data  = $this.data('bs.tab')
32880
32881      if (!data) $this.data('bs.tab', (data = new Tab(this)))
32882      if (typeof option == 'string') data[option]()
32883    })
32884  }
32885
32886  var old = $.fn.tab
32887
32888  $.fn.tab             = Plugin
32889  $.fn.tab.Constructor = Tab
32890
32891
32892  // TAB NO CONFLICT
32893  // ===============
32894
32895  $.fn.tab.noConflict = function () {
32896    $.fn.tab = old
32897    return this
32898  }
32899
32900
32901  // TAB DATA-API
32902  // ============
32903
32904  var clickHandler = function (e) {
32905    e.preventDefault()
32906    Plugin.call($(this), 'show')
32907  }
32908
32909  $(document)
32910    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
32911    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
32912
32913}(jQuery);
32914/*!
32915 * Chart.js
32916 * http://chartjs.org/
32917 * Version: 2.7.2
32918 *
32919 * Copyright 2018 Chart.js Contributors
32920 * Released under the MIT license
32921 * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
32922 */
32923
32924(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Chart = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
32925
32926},{}],2:[function(require,module,exports){
32927/* MIT license */
vendor: 17,840 bytes, lines 32928-33675
32928var colorNames = require(6);
32929
32930module.exports = {
32931   getRgba: getRgba,
32932   getHsla: getHsla,
32933   getRgb: getRgb,
32934   getHsl: getHsl,
32935   getHwb: getHwb,
32936   getAlpha: getAlpha,
32937
32938   hexString: hexString,
32939   rgbString: rgbString,
32940   rgbaString: rgbaString,
32941   percentString: percentString,
32942   percentaString: percentaString,
32943   hslString: hslString,
32944   hslaString: hslaString,
32945   hwbString: hwbString,
32946   keyword: keyword
32947}
32948
32949function getRgba(string) {
32950   if (!string) {
32951      return;
32952   }
32953   var abbr =  /^#([a-fA-F0-9]{3})$/i,
32954       hex =  /^#([a-fA-F0-9]{6})$/i,
32955       rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
32956       per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i,
32957       keyword = /(\w+)/;
32958
32959   var rgb = [0, 0, 0],
32960       a = 1,
32961       match = string.match(abbr);
32962   if (match) {
32963      match = match[1];
32964      for (var i = 0; i < rgb.length; i++) {
32965         rgb[i] = parseInt(match[i] + match[i], 16);
32966      }
32967   }
32968   else if (match = string.match(hex)) {
32969      match = match[1];
32970      for (var i = 0; i < rgb.length; i++) {
32971         rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);
32972      }
32973   }
32974   else if (match = string.match(rgba)) {
32975      for (var i = 0; i < rgb.length; i++) {
32976         rgb[i] = parseInt(match[i + 1]);
32977      }
32978      a = parseFloat(match[4]);
32979   }
32980   else if (match = string.match(per)) {
32981      for (var i = 0; i < rgb.length; i++) {
32982         rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);
32983      }
32984      a = parseFloat(match[4]);
32985   }
32986   else if (match = string.match(keyword)) {
32987      if (match[1] == "transparent") {
32988         return [0, 0, 0, 0];
32989      }
32990      rgb = colorNames[match[1]];
32991      if (!rgb) {
32992         return;
32993      }
32994   }
32995
32996   for (var i = 0; i < rgb.length; i++) {
32997      rgb[i] = scale(rgb[i], 0, 255);
32998   }
32999   if (!a && a != 0) {
33000      a = 1;
33001   }
33002   else {
33003      a = scale(a, 0, 1);
33004   }
33005   rgb[3] = a;
33006   return rgb;
33007}
33008
33009function getHsla(string) {
33010   if (!string) {
33011      return;
33012   }
33013   var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
33014   var match = string.match(hsl);
33015   if (match) {
33016      var alpha = parseFloat(match[4]);
33017      var h = scale(parseInt(match[1]), 0, 360),
33018          s = scale(parseFloat(match[2]), 0, 100),
33019          l = scale(parseFloat(match[3]), 0, 100),
33020          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
33021      return [h, s, l, a];
33022   }
33023}
33024
33025function getHwb(string) {
33026   if (!string) {
33027      return;
33028   }
33029   var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/;
33030   var match = string.match(hwb);
33031   if (match) {
33032    var alpha = parseFloat(match[4]);
33033      var h = scale(parseInt(match[1]), 0, 360),
33034          w = scale(parseFloat(match[2]), 0, 100),
33035          b = scale(parseFloat(match[3]), 0, 100),
33036          a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);
33037      return [h, w, b, a];
33038   }
33039}
33040
33041function getRgb(string) {
33042   var rgba = getRgba(string);
33043   return rgba && rgba.slice(0, 3);
33044}
33045
33046function getHsl(string) {
33047  var hsla = getHsla(string);
33048  return hsla && hsla.slice(0, 3);
33049}
33050
33051function getAlpha(string) {
33052   var vals = getRgba(string);
33053   if (vals) {
33054      return vals[3];
33055   }
33056   else if (vals = getHsla(string)) {
33057      return vals[3];
33058   }
33059   else if (vals = getHwb(string)) {
33060      return vals[3];
33061   }
33062}
33063
33064// generators
33065function hexString(rgb) {
33066   return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1])
33067              + hexDouble(rgb[2]);
33068}
33069
33070function rgbString(rgba, alpha) {
33071   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
33072      return rgbaString(rgba, alpha);
33073   }
33074   return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")";
33075}
33076
33077function rgbaString(rgba, alpha) {
33078   if (alpha === undefined) {
33079      alpha = (rgba[3] !== undefined ? rgba[3] : 1);
33080   }
33081   return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2]
33082           + ", " + alpha + ")";
33083}
33084
33085function percentString(rgba, alpha) {
33086   if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {
33087      return percentaString(rgba, alpha);
33088   }
33089   var r = Math.round(rgba[0]/255 * 100),
33090       g = Math.round(rgba[1]/255 * 100),
33091       b = Math.round(rgba[2]/255 * 100);
33092
33093   return "rgb(" + r + "%, " + g + "%, " + b + "%)";
33094}
33095
33096function percentaString(rgba, alpha) {
33097   var r = Math.round(rgba[0]/255 * 100),
33098       g = Math.round(rgba[1]/255 * 100),
33099       b = Math.round(rgba[2]/255 * 100);
33100   return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")";
33101}
33102
33103function hslString(hsla, alpha) {
33104   if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {
33105      return hslaString(hsla, alpha);
33106   }
33107   return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)";
33108}
33109
33110function hslaString(hsla, alpha) {
33111   if (alpha === undefined) {
33112      alpha = (hsla[3] !== undefined ? hsla[3] : 1);
33113   }
33114   return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, "
33115           + alpha + ")";
33116}
33117
33118// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax
33119// (hwb have alpha optional & 1 is default value)
33120function hwbString(hwb, alpha) {
33121   if (alpha === undefined) {
33122      alpha = (hwb[3] !== undefined ? hwb[3] : 1);
33123   }
33124   return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%"
33125           + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")";
33126}
33127
33128function keyword(rgb) {
33129  return reverseNames[rgb.slice(0, 3)];
33130}
33131
33132// helpers
33133function scale(num, min, max) {
33134   return Math.min(Math.max(min, num), max);
33135}
33136
33137function hexDouble(num) {
33138  var str = num.toString(16).toUpperCase();
33139  return (str.length < 2) ? "0" + str : str;
33140}
33141
33142
33143//create a list of reverse color names
33144var reverseNames = {};
33145for (var name in colorNames) {
33146   reverseNames[colorNames[name]] = name;
33147}
33148
33149},{"6":6}],3:[function(require,module,exports){
33150/* MIT license */
33151var convert = require(5);
33152var string = require(2);
33153
33154var Color = function (obj) {
33155	if (obj instanceof Color) {
33156		return obj;
33157	}
33158	if (!(this instanceof Color)) {
33159		return new Color(obj);
33160	}
33161
33162	this.valid = false;
33163	this.values = {
33164		rgb: [0, 0, 0],
33165		hsl: [0, 0, 0],
33166		hsv: [0, 0, 0],
33167		hwb: [0, 0, 0],
33168		cmyk: [0, 0, 0, 0],
33169		alpha: 1
33170	};
33171
33172	// parse Color() argument
33173	var vals;
33174	if (typeof obj === 'string') {
33175		vals = string.getRgba(obj);
33176		if (vals) {
33177			this.setValues('rgb', vals);
33178		} else if (vals = string.getHsla(obj)) {
33179			this.setValues('hsl', vals);
33180		} else if (vals = string.getHwb(obj)) {
33181			this.setValues('hwb', vals);
33182		}
33183	} else if (typeof obj === 'object') {
33184		vals = obj;
33185		if (vals.r !== undefined || vals.red !== undefined) {
33186			this.setValues('rgb', vals);
33187		} else if (vals.l !== undefined || vals.lightness !== undefined) {
33188			this.setValues('hsl', vals);
33189		} else if (vals.v !== undefined || vals.value !== undefined) {
33190			this.setValues('hsv', vals);
33191		} else if (vals.w !== undefined || vals.whiteness !== undefined) {
33192			this.setValues('hwb', vals);
33193		} else if (vals.c !== undefined || vals.cyan !== undefined) {
33194			this.setValues('cmyk', vals);
33195		}
33196	}
33197};
33198
33199Color.prototype = {
33200	isValid: function () {
33201		return this.valid;
33202	},
33203	rgb: function () {
33204		return this.setSpace('rgb', arguments);
33205	},
33206	hsl: function () {
33207		return this.setSpace('hsl', arguments);
33208	},
33209	hsv: function () {
33210		return this.setSpace('hsv', arguments);
33211	},
33212	hwb: function () {
33213		return this.setSpace('hwb', arguments);
33214	},
33215	cmyk: function () {
33216		return this.setSpace('cmyk', arguments);
33217	},
33218
33219	rgbArray: function () {
33220		return this.values.rgb;
33221	},
33222	hslArray: function () {
33223		return this.values.hsl;
33224	},
33225	hsvArray: function () {
33226		return this.values.hsv;
33227	},
33228	hwbArray: function () {
33229		var values = this.values;
33230		if (values.alpha !== 1) {
33231			return values.hwb.concat([values.alpha]);
33232		}
33233		return values.hwb;
33234	},
33235	cmykArray: function () {
33236		return this.values.cmyk;
33237	},
33238	rgbaArray: function () {
33239		var values = this.values;
33240		return values.rgb.concat([values.alpha]);
33241	},
33242	hslaArray: function () {
33243		var values = this.values;
33244		return values.hsl.concat([values.alpha]);
33245	},
33246	alpha: function (val) {
33247		if (val === undefined) {
33248			return this.values.alpha;
33249		}
33250		this.setValues('alpha', val);
33251		return this;
33252	},
33253
33254	red: function (val) {
33255		return this.setChannel('rgb', 0, val);
33256	},
33257	green: function (val) {
33258		return this.setChannel('rgb', 1, val);
33259	},
33260	blue: function (val) {
33261		return this.setChannel('rgb', 2, val);
33262	},
33263	hue: function (val) {
33264		if (val) {
33265			val %= 360;
33266			val = val < 0 ? 360 + val : val;
33267		}
33268		return this.setChannel('hsl', 0, val);
33269	},
33270	saturation: function (val) {
33271		return this.setChannel('hsl', 1, val);
33272	},
33273	lightness: function (val) {
33274		return this.setChannel('hsl', 2, val);
33275	},
33276	saturationv: function (val) {
33277		return this.setChannel('hsv', 1, val);
33278	},
33279	whiteness: function (val) {
33280		return this.setChannel('hwb', 1, val);
33281	},
33282	blackness: function (val) {
33283		return this.setChannel('hwb', 2, val);
33284	},
33285	value: function (val) {
33286		return this.setChannel('hsv', 2, val);
33287	},
33288	cyan: function (val) {
33289		return this.setChannel('cmyk', 0, val);
33290	},
33291	magenta: function (val) {
33292		return this.setChannel('cmyk', 1, val);
33293	},
33294	yellow: function (val) {
33295		return this.setChannel('cmyk', 2, val);
33296	},
33297	black: function (val) {
33298		return this.setChannel('cmyk', 3, val);
33299	},
33300
33301	hexString: function () {
33302		return string.hexString(this.values.rgb);
33303	},
33304	rgbString: function () {
33305		return string.rgbString(this.values.rgb, this.values.alpha);
33306	},
33307	rgbaString: function () {
33308		return string.rgbaString(this.values.rgb, this.values.alpha);
33309	},
33310	percentString: function () {
33311		return string.percentString(this.values.rgb, this.values.alpha);
33312	},
33313	hslString: function () {
33314		return string.hslString(this.values.hsl, this.values.alpha);
33315	},
33316	hslaString: function () {
33317		return string.hslaString(this.values.hsl, this.values.alpha);
33318	},
33319	hwbString: function () {
33320		return string.hwbString(this.values.hwb, this.values.alpha);
33321	},
33322	keyword: function () {
33323		return string.keyword(this.values.rgb, this.values.alpha);
33324	},
33325
33326	rgbNumber: function () {
33327		var rgb = this.values.rgb;
33328		return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];
33329	},
33330
33331	luminosity: function () {
33332		// http://www.w3.org/TR/WCAG20/#relativeluminancedef
33333		var rgb = this.values.rgb;
33334		var lum = [];
33335		for (var i = 0; i < rgb.length; i++) {
33336			var chan = rgb[i] / 255;
33337			lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);
33338		}
33339		return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];
33340	},
33341
33342	contrast: function (color2) {
33343		// http://www.w3.org/TR/WCAG20/#contrast-ratiodef
33344		var lum1 = this.luminosity();
33345		var lum2 = color2.luminosity();
33346		if (lum1 > lum2) {
33347			return (lum1 + 0.05) / (lum2 + 0.05);
33348		}
33349		return (lum2 + 0.05) / (lum1 + 0.05);
33350	},
33351
33352	level: function (color2) {
33353		var contrastRatio = this.contrast(color2);
33354		if (contrastRatio >= 7.1) {
33355			return 'AAA';
33356		}
33357
33358		return (contrastRatio >= 4.5) ? 'AA' : '';
33359	},
33360
33361	dark: function () {
33362		// YIQ equation from http://24ways.org/2010/calculating-color-contrast
33363		var rgb = this.values.rgb;
33364		var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;
33365		return yiq < 128;
33366	},
33367
33368	light: function () {
33369		return !this.dark();
33370	},
33371
33372	negate: function () {
33373		var rgb = [];
33374		for (var i = 0; i < 3; i++) {
33375			rgb[i] = 255 - this.values.rgb[i];
33376		}
33377		this.setValues('rgb', rgb);
33378		return this;
33379	},
33380
33381	lighten: function (ratio) {
33382		var hsl = this.values.hsl;
33383		hsl[2] += hsl[2] * ratio;
33384		this.setValues('hsl', hsl);
33385		return this;
33386	},
33387
33388	darken: function (ratio) {
33389		var hsl = this.values.hsl;
33390		hsl[2] -= hsl[2] * ratio;
33391		this.setValues('hsl', hsl);
33392		return this;
33393	},
33394
33395	saturate: function (ratio) {
33396		var hsl = this.values.hsl;
33397		hsl[1] += hsl[1] * ratio;
33398		this.setValues('hsl', hsl);
33399		return this;
33400	},
33401
33402	desaturate: function (ratio) {
33403		var hsl = this.values.hsl;
33404		hsl[1] -= hsl[1] * ratio;
33405		this.setValues('hsl', hsl);
33406		return this;
33407	},
33408
33409	whiten: function (ratio) {
33410		var hwb = this.values.hwb;
33411		hwb[1] += hwb[1] * ratio;
33412		this.setValues('hwb', hwb);
33413		return this;
33414	},
33415
33416	blacken: function (ratio) {
33417		var hwb = this.values.hwb;
33418		hwb[2] += hwb[2] * ratio;
33419		this.setValues('hwb', hwb);
33420		return this;
33421	},
33422
33423	greyscale: function () {
33424		var rgb = this.values.rgb;
33425		// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
33426		var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;
33427		this.setValues('rgb', [val, val, val]);
33428		return this;
33429	},
33430
33431	clearer: function (ratio) {
33432		var alpha = this.values.alpha;
33433		this.setValues('alpha', alpha - (alpha * ratio));
33434		return this;
33435	},
33436
33437	opaquer: function (ratio) {
33438		var alpha = this.values.alpha;
33439		this.setValues('alpha', alpha + (alpha * ratio));
33440		return this;
33441	},
33442
33443	rotate: function (degrees) {
33444		var hsl = this.values.hsl;
33445		var hue = (hsl[0] + degrees) % 360;
33446		hsl[0] = hue < 0 ? 360 + hue : hue;
33447		this.setValues('hsl', hsl);
33448		return this;
33449	},
33450
33451	/**
33452	 * Ported from sass implementation in C
33453	 * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209
33454	 */
33455	mix: function (mixinColor, weight) {
33456		var color1 = this;
33457		var color2 = mixinColor;
33458		var p = weight === undefined ? 0.5 : weight;
33459
33460		var w = 2 * p - 1;
33461		var a = color1.alpha() - color2.alpha();
33462
33463		var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
33464		var w2 = 1 - w1;
33465
33466		return this
33467			.rgb(
33468				w1 * color1.red() + w2 * color2.red(),
33469				w1 * color1.green() + w2 * color2.green(),
33470				w1 * color1.blue() + w2 * color2.blue()
33471			)
33472			.alpha(color1.alpha() * p + color2.alpha() * (1 - p));
33473	},
33474
33475	toJSON: function () {
33476		return this.rgb();
33477	},
33478
33479	clone: function () {
33480		// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,
33481		// making the final build way to big to embed in Chart.js. So let's do it manually,
33482		// assuming that values to clone are 1 dimension arrays containing only numbers,
33483		// except 'alpha' which is a number.
33484		var result = new Color();
33485		var source = this.values;
33486		var target = result.values;
33487		var value, type;
33488
33489		for (var prop in source) {
33490			if (source.hasOwnProperty(prop)) {
33491				value = source[prop];
33492				type = ({}).toString.call(value);
33493				if (type === '[object Array]') {
33494					target[prop] = value.slice(0);
33495				} else if (type === '[object Number]') {
33496					target[prop] = value;
33497				} else {
33498					console.error('unexpected color value:', value);
33499				}
33500			}
33501		}
33502
33503		return result;
33504	}
33505};
33506
33507Color.prototype.spaces = {
33508	rgb: ['red', 'green', 'blue'],
33509	hsl: ['hue', 'saturation', 'lightness'],
33510	hsv: ['hue', 'saturation', 'value'],
33511	hwb: ['hue', 'whiteness', 'blackness'],
33512	cmyk: ['cyan', 'magenta', 'yellow', 'black']
33513};
33514
33515Color.prototype.maxes = {
33516	rgb: [255, 255, 255],
33517	hsl: [360, 100, 100],
33518	hsv: [360, 100, 100],
33519	hwb: [360, 100, 100],
33520	cmyk: [100, 100, 100, 100]
33521};
33522
33523Color.prototype.getValues = function (space) {
33524	var values = this.values;
33525	var vals = {};
33526
33527	for (var i = 0; i < space.length; i++) {
33528		vals[space.charAt(i)] = values[space][i];
33529	}
33530
33531	if (values.alpha !== 1) {
33532		vals.a = values.alpha;
33533	}
33534
33535	// {r: 255, g: 255, b: 255, a: 0.4}
33536	return vals;
33537};
33538
33539Color.prototype.setValues = function (space, vals) {
33540	var values = this.values;
33541	var spaces = this.spaces;
33542	var maxes = this.maxes;
33543	var alpha = 1;
33544	var i;
33545
33546	this.valid = true;
33547
33548	if (space === 'alpha') {
33549		alpha = vals;
33550	} else if (vals.length) {
33551		// [10, 10, 10]
33552		values[space] = vals.slice(0, space.length);
33553		alpha = vals[space.length];
33554	} else if (vals[space.charAt(0)] !== undefined) {
33555		// {r: 10, g: 10, b: 10}
33556		for (i = 0; i < space.length; i++) {
33557			values[space][i] = vals[space.charAt(i)];
33558		}
33559
33560		alpha = vals.a;
33561	} else if (vals[spaces[space][0]] !== undefined) {
33562		// {red: 10, green: 10, blue: 10}
33563		var chans = spaces[space];
33564
33565		for (i = 0; i < space.length; i++) {
33566			values[space][i] = vals[chans[i]];
33567		}
33568
33569		alpha = vals.alpha;
33570	}
33571
33572	values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));
33573
33574	if (space === 'alpha') {
33575		return false;
33576	}
33577
33578	var capped;
33579
33580	// cap values of the space prior converting all values
33581	for (i = 0; i < space.length; i++) {
33582		capped = Math.max(0, Math.min(maxes[space][i], values[space][i]));
33583		values[space][i] = Math.round(capped);
33584	}
33585
33586	// convert to all the other color spaces
33587	for (var sname in spaces) {
33588		if (sname !== space) {
33589			values[sname] = convert[space][sname](values[space]);
33590		}
33591	}
33592
33593	return true;
33594};
33595
33596Color.prototype.setSpace = function (space, args) {
33597	var vals = args[0];
33598
33599	if (vals === undefined) {
33600		// color.rgb()
33601		return this.getValues(space);
33602	}
33603
33604	// color.rgb(10, 10, 10)
33605	if (typeof vals === 'number') {
33606		vals = Array.prototype.slice.call(args);
33607	}
33608
33609	this.setValues(space, vals);
33610	return this;
33611};
33612
33613Color.prototype.setChannel = function (space, index, val) {
33614	var svalues = this.values[space];
33615	if (val === undefined) {
33616		// color.red()
33617		return svalues[index];
33618	} else if (val === svalues[index]) {
33619		// color.red(color.red())
33620		return this;
33621	}
33622
33623	// color.red(100)
33624	svalues[index] = val;
33625	this.setValues(space, svalues);
33626
33627	return this;
33628};
33629
33630if (typeof window !== 'undefined') {
33631	window.Color = Color;
33632}
33633
33634module.exports = Color;
33635
33636},{"2":2,"5":5}],4:[function(require,module,exports){
33637/* MIT license */
33638
33639module.exports = {
33640  rgb2hsl: rgb2hsl,
33641  rgb2hsv: rgb2hsv,
33642  rgb2hwb: rgb2hwb,
33643  rgb2cmyk: rgb2cmyk,
33644  rgb2keyword: rgb2keyword,
33645  rgb2xyz: rgb2xyz,
33646  rgb2lab: rgb2lab,
33647  rgb2lch: rgb2lch,
33648
33649  hsl2rgb: hsl2rgb,
33650  hsl2hsv: hsl2hsv,
33651  hsl2hwb: hsl2hwb,
33652  hsl2cmyk: hsl2cmyk,
33653  hsl2keyword: hsl2keyword,
33654
33655  hsv2rgb: hsv2rgb,
33656  hsv2hsl: hsv2hsl,
33657  hsv2hwb: hsv2hwb,
33658  hsv2cmyk: hsv2cmyk,
33659  hsv2keyword: hsv2keyword,
33660
33661  hwb2rgb: hwb2rgb,
33662  hwb2hsl: hwb2hsl,
33663  hwb2hsv: hwb2hsv,
33664  hwb2cmyk: hwb2cmyk,
33665  hwb2keyword: hwb2keyword,
33666
33667  cmyk2rgb: cmyk2rgb,
33668  cmyk2hsl: cmyk2hsl,
33669  cmyk2hsv: cmyk2hsv,
33670  cmyk2hwb: cmyk2hwb,
33671  cmyk2keyword: cmyk2keyword,
33672
33673  keyword2rgb: keyword2rgb,
33674  keyword2hsl: keyword2hsl,
33675  keyword2hsv: keyword2hsv,
33676  keyword2hwb: keyword2hwb,
33677  keyword2cmyk: keyword2cmyk,
33678  keyword2lab: keyword2lab,
33679  keyword2xyz: keyword2xyz,
33680
33681  xyz2rgb: xyz2rgb,
33682  xyz2lab: xyz2lab,
33683  xyz2lch: xyz2lch,
33684
33685  lab2xyz: lab2xyz,
33686  lab2rgb: lab2rgb,
33687  lab2lch: lab2lch,
33688
33689  lch2lab: lch2lab,
33690  lch2xyz: lch2xyz,
33691  lch2rgb: lch2rgb
33692}
33693
33694
33695function rgb2hsl(rgb) {
33696  var r = rgb[0]/255,
33697      g = rgb[1]/255,
33698      b = rgb[2]/255,
33699      min = Math.min(r, g, b),
33700      max = Math.max(r, g, b),
33701      delta = max - min,
33702      h, s, l;
33703
33704  if (max == min)
33705    h = 0;
33706  else if (r == max)
33707    h = (g - b) / delta;
33708  else if (g == max)
33709    h = 2 + (b - r) / delta;
33710  else if (b == max)
33711    h = 4 + (r - g)/ delta;
33712
33713  h = Math.min(h * 60, 360);
33714
33715  if (h < 0)
33716    h += 360;
33717
33718  l = (min + max) / 2;
33719
33720  if (max == min)
33721    s = 0;
33722  else if (l <= 0.5)
33723    s = delta / (max + min);
33724  else
33725    s = delta / (2 - max - min);
33726
33727  return [h, s * 100, l * 100];
33728}
33729
33730function rgb2hsv(rgb) {
33731  var r = rgb[0],
33732      g = rgb[1],
33733      b = rgb[2],
33734      min = Math.min(r, g, b),
33735      max = Math.max(r, g, b),
33736      delta = max - min,
33737      h, s, v;
33738
33739  if (max == 0)
33740    s = 0;
33741  else
33742    s = (delta/max * 1000)/10;
33743
33744  if (max == min)
33745    h = 0;
33746  else if (r == max)
33747    h = (g - b) / delta;
33748  else if (g == max)
33749    h = 2 + (b - r) / delta;
33750  else if (b == max)
33751    h = 4 + (r - g) / delta;
33752
33753  h = Math.min(h * 60, 360);
33754
33755  if (h < 0)
33756    h += 360;
33757
33758  v = ((max / 255) * 1000) / 10;
33759
33760  return [h, s, v];
33761}
33762
33763function rgb2hwb(rgb) {
33764  var r = rgb[0],
33765      g = rgb[1],
33766      b = rgb[2],
33767      h = rgb2hsl(rgb)[0],
33768      w = 1/255 * Math.min(r, Math.min(g, b)),
33769      b = 1 - 1/255 * Math.max(r, Math.max(g, b));
33770
33771  return [h, w * 100, b * 100];
33772}
33773
33774function rgb2cmyk(rgb) {
33775  var r = rgb[0] / 255,
33776      g = rgb[1] / 255,
33777      b = rgb[2] / 255,
33778      c, m, y, k;
33779
33780  k = Math.min(1 - r, 1 - g, 1 - b);
33781  c = (1 - r - k) / (1 - k) || 0;
33782  m = (1 - g - k) / (1 - k) || 0;
33783  y = (1 - b - k) / (1 - k) || 0;
33784  return [c * 100, m * 100, y * 100, k * 100];
33785}
33786
33787function rgb2keyword(rgb) {
33788  return reverseKeywords[JSON.stringify(rgb)];
33789}
33790
33791function rgb2xyz(rgb) {
33792  var r = rgb[0] / 255,
33793      g = rgb[1] / 255,
33794      b = rgb[2] / 255;
33795
33796  // assume sRGB
33797  r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
33798  g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
33799  b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
33800
33801  var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
33802  var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
33803  var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
33804
33805  return [x * 100, y *100, z * 100];
33806}
33807
33808function rgb2lab(rgb) {
33809  var xyz = rgb2xyz(rgb),
33810        x = xyz[0],
33811        y = xyz[1],
33812        z = xyz[2],
33813        l, a, b;
33814
33815  x /= 95.047;
33816  y /= 100;
33817  z /= 108.883;
33818
33819  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
33820  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
33821  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
33822
33823  l = (116 * y) - 16;
33824  a = 500 * (x - y);
33825  b = 200 * (y - z);
33826
33827  return [l, a, b];
33828}
33829
33830function rgb2lch(args) {
33831  return lab2lch(rgb2lab(args));
33832}
33833
33834function hsl2rgb(hsl) {
33835  var h = hsl[0] / 360,
33836      s = hsl[1] / 100,
33837      l = hsl[2] / 100,
33838      t1, t2, t3, rgb, val;
33839
33840  if (s == 0) {
33841    val = l * 255;
33842    return [val, val, val];
33843  }
33844
33845  if (l < 0.5)
33846    t2 = l * (1 + s);
33847  else
33848    t2 = l + s - l * s;
33849  t1 = 2 * l - t2;
33850
33851  rgb = [0, 0, 0];
33852  for (var i = 0; i < 3; i++) {
33853    t3 = h + 1 / 3 * - (i - 1);
33854    t3 < 0 && t3++;
33855    t3 > 1 && t3--;
33856
33857    if (6 * t3 < 1)
33858      val = t1 + (t2 - t1) * 6 * t3;
33859    else if (2 * t3 < 1)
33860      val = t2;
33861    else if (3 * t3 < 2)
33862      val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
33863    else
33864      val = t1;
33865
33866    rgb[i] = val * 255;
33867  }
33868
33869  return rgb;
33870}
33871
33872function hsl2hsv(hsl) {
33873  var h = hsl[0],
33874      s = hsl[1] / 100,
33875      l = hsl[2] / 100,
33876      sv, v;
33877
33878  if(l === 0) {
33879      // no need to do calc on black
33880      // also avoids divide by 0 error
33881      return [0, 0, 0];
33882  }
33883
33884  l *= 2;
33885  s *= (l <= 1) ? l : 2 - l;
33886  v = (l + s) / 2;
33887  sv = (2 * s) / (l + s);
33888  return [h, sv * 100, v * 100];
33889}
33890
33891function hsl2hwb(args) {
33892  return rgb2hwb(hsl2rgb(args));
33893}
33894
33895function hsl2cmyk(args) {
33896  return rgb2cmyk(hsl2rgb(args));
33897}
33898
33899function hsl2keyword(args) {
33900  return rgb2keyword(hsl2rgb(args));
33901}
33902
33903
33904function hsv2rgb(hsv) {
33905  var h = hsv[0] / 60,
33906      s = hsv[1] / 100,
33907      v = hsv[2] / 100,
33908      hi = Math.floor(h) % 6;
33909
33910  var f = h - Math.floor(h),
33911      p = 255 * v * (1 - s),
33912      q = 255 * v * (1 - (s * f)),
33913      t = 255 * v * (1 - (s * (1 - f))),
33914      v = 255 * v;
33915
33916  switch(hi) {
33917    case 0:
33918      return [v, t, p];
33919    case 1:
33920      return [q, v, p];
33921    case 2:
33922      return [p, v, t];
33923    case 3:
33924      return [p, q, v];
33925    case 4:
33926      return [t, p, v];
33927    case 5:
33928      return [v, p, q];
33929  }
33930}
33931
33932function hsv2hsl(hsv) {
33933  var h = hsv[0],
33934      s = hsv[1] / 100,
33935      v = hsv[2] / 100,
33936      sl, l;
33937
33938  l = (2 - s) * v;
33939  sl = s * v;
33940  sl /= (l <= 1) ? l : 2 - l;
33941  sl = sl || 0;
33942  l /= 2;
33943  return [h, sl * 100, l * 100];
33944}
33945
33946function hsv2hwb(args) {
33947  return rgb2hwb(hsv2rgb(args))
33948}
33949
33950function hsv2cmyk(args) {
33951  return rgb2cmyk(hsv2rgb(args));
33952}
33953
33954function hsv2keyword(args) {
33955  return rgb2keyword(hsv2rgb(args));
33956}
33957
33958// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
33959function hwb2rgb(hwb) {
33960  var h = hwb[0] / 360,
33961      wh = hwb[1] / 100,
33962      bl = hwb[2] / 100,
33963      ratio = wh + bl,
33964      i, v, f, n;
33965
33966  // wh + bl cant be > 1
33967  if (ratio > 1) {
33968    wh /= ratio;
33969    bl /= ratio;
33970  }
33971
33972  i = Math.floor(6 * h);
33973  v = 1 - bl;
33974  f = 6 * h - i;
33975  if ((i & 0x01) != 0) {
33976    f = 1 - f;
33977  }
33978  n = wh + f * (v - wh);  // linear interpolation
33979
33980  switch (i) {
33981    default:
33982    case 6:
33983    case 0: r = v; g = n; b = wh; break;
33984    case 1: r = n; g = v; b = wh; break;
33985    case 2: r = wh; g = v; b = n; break;
33986    case 3: r = wh; g = n; b = v; break;
33987    case 4: r = n; g = wh; b = v; break;
33988    case 5: r = v; g = wh; b = n; break;
33989  }
33990
33991  return [r * 255, g * 255, b * 255];
33992}
33993
33994function hwb2hsl(args) {
33995  return rgb2hsl(hwb2rgb(args));
33996}
33997
33998function hwb2hsv(args) {
33999  return rgb2hsv(hwb2rgb(args));
34000}
34001
34002function hwb2cmyk(args) {
34003  return rgb2cmyk(hwb2rgb(args));
34004}
34005
34006function hwb2keyword(args) {
34007  return rgb2keyword(hwb2rgb(args));
34008}
34009
34010function cmyk2rgb(cmyk) {
34011  var c = cmyk[0] / 100,
34012      m = cmyk[1] / 100,
34013      y = cmyk[2] / 100,
34014      k = cmyk[3] / 100,
34015      r, g, b;
34016
34017  r = 1 - Math.min(1, c * (1 - k) + k);
34018  g = 1 - Math.min(1, m * (1 - k) + k);
34019  b = 1 - Math.min(1, y * (1 - k) + k);
34020  return [r * 255, g * 255, b * 255];
34021}
34022
34023function cmyk2hsl(args) {
34024  return rgb2hsl(cmyk2rgb(args));
34025}
34026
34027function cmyk2hsv(args) {
34028  return rgb2hsv(cmyk2rgb(args));
34029}
34030
34031function cmyk2hwb(args) {
34032  return rgb2hwb(cmyk2rgb(args));
34033}
34034
34035function cmyk2keyword(args) {
34036  return rgb2keyword(cmyk2rgb(args));
34037}
34038
34039
34040function xyz2rgb(xyz) {
34041  var x = xyz[0] / 100,
34042      y = xyz[1] / 100,
34043      z = xyz[2] / 100,
34044      r, g, b;
34045
34046  r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
34047  g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
34048  b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
34049
34050  // assume sRGB
34051  r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
34052    : r = (r * 12.92);
34053
34054  g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
34055    : g = (g * 12.92);
34056
34057  b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
34058    : b = (b * 12.92);
34059
34060  r = Math.min(Math.max(0, r), 1);
34061  g = Math.min(Math.max(0, g), 1);
34062  b = Math.min(Math.max(0, b), 1);
34063
34064  return [r * 255, g * 255, b * 255];
34065}
34066
34067function xyz2lab(xyz) {
34068  var x = xyz[0],
34069      y = xyz[1],
34070      z = xyz[2],
34071      l, a, b;
34072
34073  x /= 95.047;
34074  y /= 100;
34075  z /= 108.883;
34076
34077  x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116);
34078  y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116);
34079  z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116);
34080
34081  l = (116 * y) - 16;
34082  a = 500 * (x - y);
34083  b = 200 * (y - z);
34084
34085  return [l, a, b];
34086}
34087
34088function xyz2lch(args) {
34089  return lab2lch(xyz2lab(args));
34090}
34091
34092function lab2xyz(lab) {
34093  var l = lab[0],
34094      a = lab[1],
34095      b = lab[2],
34096      x, y, z, y2;
34097
34098  if (l <= 8) {
34099    y = (l * 100) / 903.3;
34100    y2 = (7.787 * (y / 100)) + (16 / 116);
34101  } else {
34102    y = 100 * Math.pow((l + 16) / 116, 3);
34103    y2 = Math.pow(y / 100, 1/3);
34104  }
34105
34106  x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
34107
34108  z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
34109
34110  return [x, y, z];
34111}
34112
34113function lab2lch(lab) {
34114  var l = lab[0],
34115      a = lab[1],
34116      b = lab[2],
34117      hr, h, c;
34118
34119  hr = Math.atan2(b, a);
34120  h = hr * 360 / 2 / Math.PI;
34121  if (h < 0) {
34122    h += 360;
34123  }
34124  c = Math.sqrt(a * a + b * b);
34125  return [l, c, h];
34126}
34127
34128function lab2rgb(args) {
34129  return xyz2rgb(lab2xyz(args));
34130}
34131
34132function lch2lab(lch) {
34133  var l = lch[0],
34134      c = lch[1],
34135      h = lch[2],
34136      a, b, hr;
34137
34138  hr = h / 360 * 2 * Math.PI;
34139  a = c * Math.cos(hr);
34140  b = c * Math.sin(hr);
34141  return [l, a, b];
34142}
34143
34144function lch2xyz(args) {
34145  return lab2xyz(lch2lab(args));
34146}
34147
34148function lch2rgb(args) {
34149  return lab2rgb(lch2lab(args));
34150}
34151
34152function keyword2rgb(keyword) {
34153  return cssKeywords[keyword];
34154}
34155
34156function keyword2hsl(args) {
34157  return rgb2hsl(keyword2rgb(args));
34158}
34159
34160function keyword2hsv(args) {
34161  return rgb2hsv(keyword2rgb(args));
34162}
34163
34164function keyword2hwb(args) {
34165  return rgb2hwb(keyword2rgb(args));
34166}
34167
34168function keyword2cmyk(args) {
34169  return rgb2cmyk(keyword2rgb(args));
34170}
34171
34172function keyword2lab(args) {
34173  return rgb2lab(keyword2rgb(args));
34174}
34175
34176function keyword2xyz(args) {
34177  return rgb2xyz(keyword2rgb(args));
34178}
34179
34180var cssKeywords = {
34181  aliceblue:  [240,248,255],
34182  antiquewhite: [250,235,215],
34183  aqua: [0,255,255],
34184  aquamarine: [127,255,212],
34185  azure:  [240,255,255],
34186  beige:  [245,245,220],
34187  bisque: [255,228,196],
34188  black:  [0,0,0],
34189  blanchedalmond: [255,235,205],
34190  blue: [0,0,255],
34191  blueviolet: [138,43,226],
34192  brown:  [165,42,42],
34193  burlywood:  [222,184,135],
34194  cadetblue:  [95,158,160],
34195  chartreuse: [127,255,0],
34196  chocolate:  [210,105,30],
34197  coral:  [255,127,80],
34198  cornflowerblue: [100,149,237],
34199  cornsilk: [255,248,220],
34200  crimson:  [220,20,60],
34201  cyan: [0,255,255],
34202  darkblue: [0,0,139],
34203  darkcyan: [0,139,139],
34204  darkgoldenrod:  [184,134,11],
34205  darkgray: [169,169,169],
34206  darkgreen:  [0,100,0],
34207  darkgrey: [169,169,169],
34208  darkkhaki:  [189,183,107],
34209  darkmagenta:  [139,0,139],
34210  darkolivegreen: [85,107,47],
34211  darkorange: [255,140,0],
34212  darkorchid: [153,50,204],
34213  darkred:  [139,0,0],
34214  darksalmon: [233,150,122],
34215  darkseagreen: [143,188,143],
34216  darkslateblue:  [72,61,139],
34217  darkslategray:  [47,79,79],
34218  darkslategrey:  [47,79,79],
34219  darkturquoise:  [0,206,209],
34220  darkviolet: [148,0,211],
34221  deeppink: [255,20,147],
34222  deepskyblue:  [0,191,255],
34223  dimgray:  [105,105,105],
34224  dimgrey:  [105,105,105],
34225  dodgerblue: [30,144,255],
34226  firebrick:  [178,34,34],
34227  floralwhite:  [255,250,240],
34228  forestgreen:  [34,139,34],
34229  fuchsia:  [255,0,255],
34230  gainsboro:  [220,220,220],
34231  ghostwhite: [248,248,255],
34232  gold: [255,215,0],
34233  goldenrod:  [218,165,32],
34234  gray: [128,128,128],
34235  green:  [0,128,0],
34236  greenyellow:  [173,255,47],
34237  grey: [128,128,128],
34238  honeydew: [240,255,240],
34239  hotpink:  [255,105,180],
34240  indianred:  [205,92,92],
34241  indigo: [75,0,130],
34242  ivory:  [255,255,240],
34243  khaki:  [240,230,140],
34244  lavender: [230,230,250],
34245  lavenderblush:  [255,240,245],
34246  lawngreen:  [124,252,0],
34247  lemonchiffon: [255,250,205],
34248  lightblue:  [173,216,230],
34249  lightcoral: [240,128,128],
34250  lightcyan:  [224,255,255],
34251  lightgoldenrodyellow: [250,250,210],
34252  lightgray:  [211,211,211],
34253  lightgreen: [144,238,144],
34254  lightgrey:  [211,211,211],
34255  lightpink:  [255,182,193],
34256  lightsalmon:  [255,160,122],
34257  lightseagreen:  [32,178,170],
34258  lightskyblue: [135,206,250],
34259  lightslategray: [119,136,153],
34260  lightslategrey: [119,136,153],
34261  lightsteelblue: [176,196,222],
34262  lightyellow:  [255,255,224],
34263  lime: [0,255,0],
34264  limegreen:  [50,205,50],
34265  linen:  [250,240,230],
34266  magenta:  [255,0,255],
34267  maroon: [128,0,0],
34268  mediumaquamarine: [102,205,170],
34269  mediumblue: [0,0,205],
34270  mediumorchid: [186,85,211],
34271  mediumpurple: [147,112,219],
34272  mediumseagreen: [60,179,113],
34273  mediumslateblue:  [123,104,238],
34274  mediumspringgreen:  [0,250,154],
34275  mediumturquoise:  [72,209,204],
34276  mediumvioletred:  [199,21,133],
34277  midnightblue: [25,25,112],
34278  mintcream:  [245,255,250],
34279  mistyrose:  [255,228,225],
34280  moccasin: [255,228,181],
34281  navajowhite:  [255,222,173],
34282  navy: [0,0,128],
34283  oldlace:  [253,245,230],
34284  olive:  [128,128,0],
34285  olivedrab:  [107,142,35],
34286  orange: [255,165,0],
34287  orangered:  [255,69,0],
34288  orchid: [218,112,214],
34289  palegoldenrod:  [238,232,170],
34290  palegreen:  [152,251,152],
34291  paleturquoise:  [175,238,238],
34292  palevioletred:  [219,112,147],
34293  papayawhip: [255,239,213],
34294  peachpuff:  [255,218,185],
34295  peru: [205,133,63],
34296  pink: [255,192,203],
34297  plum: [221,160,221],
34298  powderblue: [176,224,230],
34299  purple: [128,0,128],
34300  rebeccapurple: [102, 51, 153],
34301  red:  [255,0,0],
34302  rosybrown:  [188,143,143],
34303  royalblue:  [65,105,225],
34304  saddlebrown:  [139,69,19],
34305  salmon: [250,128,114],
34306  sandybrown: [244,164,96],
34307  seagreen: [46,139,87],
34308  seashell: [255,245,238],
34309  sienna: [160,82,45],
34310  silver: [192,192,192],
34311  skyblue:  [135,206,235],
34312  slateblue:  [106,90,205],
34313  slategray:  [112,128,144],
34314  slategrey:  [112,128,144],
34315  snow: [255,250,250],
34316  springgreen:  [0,255,127],
34317  steelblue:  [70,130,180],
34318  tan:  [210,180,140],
34319  teal: [0,128,128],
34320  thistle:  [216,191,216],
34321  tomato: [255,99,71],
34322  turquoise:  [64,224,208],
34323  violet: [238,130,238],
34324  wheat:  [245,222,179],
34325  white:  [255,255,255],
34326  whitesmoke: [245,245,245],
34327  yellow: [255,255,0],
34328  yellowgreen:  [154,205,50]
34329};
34330
34331var reverseKeywords = {};
34332for (var key in cssKeywords) {
34333  reverseKeywords[JSON.stringify(cssKeywords[key])] = key;
34334}
34335
34336},{}],5:[function(require,module,exports){
34337var conversions = require(4);
34338
34339var convert = function() {
34340   return new Converter();
34341}
34342
34343for (var func in conversions) {
34344  // export Raw versions
34345  convert[func + "Raw"] =  (function(func) {
34346    // accept array or plain args
34347    return function(arg) {
34348      if (typeof arg == "number")
34349        arg = Array.prototype.slice.call(arguments);
34350      return conversions[func](arg);
34351    }
34352  })(func);
34353
34354  var pair = /(\w+)2(\w+)/.exec(func),
34355      from = pair[1],
34356      to = pair[2];
34357
34358  // export rgb2hsl and ["rgb"]["hsl"]
34359  convert[from] = convert[from] || {};
34360
34361  convert[from][to] = convert[func] = (function(func) { 
34362    return function(arg) {
34363      if (typeof arg == "number")
34364        arg = Array.prototype.slice.call(arguments);
34365      
34366      var val = conversions[func](arg);
34367      if (typeof val == "string" || val === undefined)
34368        return val; // keyword
34369
34370      for (var i = 0; i < val.length; i++)
34371        val[i] = Math.round(val[i]);
34372      return val;
34373    }
34374  })(func);
34375}
34376
34377
34378/* Converter does lazy conversion and caching */
34379var Converter = function() {
34380   this.convs = {};
34381};
34382
34383/* Either get the values for a space or
34384  set the values for a space, depending on args */
34385Converter.prototype.routeSpace = function(space, args) {
34386   var values = args[0];
34387   if (values === undefined) {
34388      // color.rgb()
34389      return this.getValues(space);
34390   }
34391   // color.rgb(10, 10, 10)
34392   if (typeof values == "number") {
34393      values = Array.prototype.slice.call(args);        
34394   }
34395
34396   return this.setValues(space, values);
34397};
34398  
34399/* Set the values for a space, invalidating cache */
34400Converter.prototype.setValues = function(space, values) {
34401   this.space = space;
34402   this.convs = {};
34403   this.convs[space] = values;
34404   return this;
34405};
34406
34407/* Get the values for a space. If there's already
34408  a conversion for the space, fetch it, otherwise
34409  compute it */
34410Converter.prototype.getValues = function(space) {
34411   var vals = this.convs[space];
34412   if (!vals) {
34413      var fspace = this.space,
34414          from = this.convs[fspace];
34415      vals = convert[fspace][space](from);
34416
34417      this.convs[space] = vals;
34418   }
34419  return vals;
34420};
34421
34422["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) {
34423   Converter.prototype[space] = function(vals) {
34424      return this.routeSpace(space, arguments);
34425   }
34426});
34427
34428module.exports = convert;
34429},{"4":4}],6:[function(require,module,exports){
34430'use strict'
34431
34432module.exports = {
34433	"aliceblue": [240, 248, 255],
34434	"antiquewhite": [250, 235, 215],
34435	"aqua": [0, 255, 255],
34436	"aquamarine": [127, 255, 212],
34437	"azure": [240, 255, 255],
34438	"beige": [245, 245, 220],
34439	"bisque": [255, 228, 196],
34440	"black": [0, 0, 0],
34441	"blanchedalmond": [255, 235, 205],
34442	"blue": [0, 0, 255],
34443	"blueviolet": [138, 43, 226],
34444	"brown": [165, 42, 42],
34445	"burlywood": [222, 184, 135],
34446	"cadetblue": [95, 158, 160],
34447	"chartreuse": [127, 255, 0],
34448	"chocolate": [210, 105, 30],
34449	"coral": [255, 127, 80],
34450	"cornflowerblue": [100, 149, 237],
34451	"cornsilk": [255, 248, 220],
34452	"crimson": [220, 20, 60],
34453	"cyan": [0, 255, 255],
34454	"darkblue": [0, 0, 139],
34455	"darkcyan": [0, 139, 139],
34456	"darkgoldenrod": [184, 134, 11],
34457	"darkgray": [169, 169, 169],
34458	"darkgreen": [0, 100, 0],
34459	"darkgrey": [169, 169, 169],
34460	"darkkhaki": [189, 183, 107],
34461	"darkmagenta": [139, 0, 139],
34462	"darkolivegreen": [85, 107, 47],
34463	"darkorange": [255, 140, 0],
34464	"darkorchid": [153, 50, 204],
34465	"darkred": [139, 0, 0],
34466	"darksalmon": [233, 150, 122],
34467	"darkseagreen": [143, 188, 143],
34468	"darkslateblue": [72, 61, 139],
34469	"darkslategray": [47, 79, 79],
34470	"darkslategrey": [47, 79, 79],
34471	"darkturquoise": [0, 206, 209],
34472	"darkviolet": [148, 0, 211],
34473	"deeppink": [255, 20, 147],
34474	"deepskyblue": [0, 191, 255],
34475	"dimgray": [105, 105, 105],
34476	"dimgrey": [105, 105, 105],
34477	"dodgerblue": [30, 144, 255],
34478	"firebrick": [178, 34, 34],
34479	"floralwhite": [255, 250, 240],
34480	"forestgreen": [34, 139, 34],
34481	"fuchsia": [255, 0, 255],
34482	"gainsboro": [220, 220, 220],
34483	"ghostwhite": [248, 248, 255],
34484	"gold": [255, 215, 0],
34485	"goldenrod": [218, 165, 32],
34486	"gray": [128, 128, 128],
34487	"green": [0, 128, 0],
34488	"greenyellow": [173, 255, 47],
34489	"grey": [128, 128, 128],
34490	"honeydew": [240, 255, 240],
34491	"hotpink": [255, 105, 180],
34492	"indianred": [205, 92, 92],
34493	"indigo": [75, 0, 130],
34494	"ivory": [255, 255, 240],
34495	"khaki": [240, 230, 140],
34496	"lavender": [230, 230, 250],
34497	"lavenderblush": [255, 240, 245],
34498	"lawngreen": [124, 252, 0],
34499	"lemonchiffon": [255, 250, 205],
34500	"lightblue": [173, 216, 230],
34501	"lightcoral": [240, 128, 128],
34502	"lightcyan": [224, 255, 255],
34503	"lightgoldenrodyellow": [250, 250, 210],
34504	"lightgray": [211, 211, 211],
34505	"lightgreen": [144, 238, 144],
34506	"lightgrey": [211, 211, 211],
34507	"lightpink": [255, 182, 193],
34508	"lightsalmon": [255, 160, 122],
34509	"lightseagreen": [32, 178, 170],
34510	"lightskyblue": [135, 206, 250],
34511	"lightslategray": [119, 136, 153],
34512	"lightslategrey": [119, 136, 153],
34513	"lightsteelblue": [176, 196, 222],
34514	"lightyellow": [255, 255, 224],
34515	"lime": [0, 255, 0],
34516	"limegreen": [50, 205, 50],
34517	"linen": [250, 240, 230],
34518	"magenta": [255, 0, 255],
34519	"maroon": [128, 0, 0],
34520	"mediumaquamarine": [102, 205, 170],
34521	"mediumblue": [0, 0, 205],
34522	"mediumorchid": [186, 85, 211],
34523	"mediumpurple": [147, 112, 219],
34524	"mediumseagreen": [60, 179, 113],
34525	"mediumslateblue": [123, 104, 238],
34526	"mediumspringgreen": [0, 250, 154],
34527	"mediumturquoise": [72, 209, 204],
34528	"mediumvioletred": [199, 21, 133],
34529	"midnightblue": [25, 25, 112],
34530	"mintcream": [245, 255, 250],
34531	"mistyrose": [255, 228, 225],
34532	"moccasin": [255, 228, 181],
34533	"navajowhite": [255, 222, 173],
34534	"navy": [0, 0, 128],
34535	"oldlace": [253, 245, 230],
34536	"olive": [128, 128, 0],
34537	"olivedrab": [107, 142, 35],
34538	"orange": [255, 165, 0],
34539	"orangered": [255, 69, 0],
34540	"orchid": [218, 112, 214],
34541	"palegoldenrod": [238, 232, 170],
34542	"palegreen": [152, 251, 152],
34543	"paleturquoise": [175, 238, 238],
34544	"palevioletred": [219, 112, 147],
34545	"papayawhip": [255, 239, 213],
34546	"peachpuff": [255, 218, 185],
34547	"peru": [205, 133, 63],
34548	"pink": [255, 192, 203],
34549	"plum": [221, 160, 221],
34550	"powderblue": [176, 224, 230],
34551	"purple": [128, 0, 128],
34552	"rebeccapurple": [102, 51, 153],
34553	"red": [255, 0, 0],
34554	"rosybrown": [188, 143, 143],
34555	"royalblue": [65, 105, 225],
34556	"saddlebrown": [139, 69, 19],
34557	"salmon": [250, 128, 114],
34558	"sandybrown": [244, 164, 96],
34559	"seagreen": [46, 139, 87],
34560	"seashell": [255, 245, 238],
34561	"sienna": [160, 82, 45],
34562	"silver": [192, 192, 192],
34563	"skyblue": [135, 206, 235],
34564	"slateblue": [106, 90, 205],
34565	"slategray": [112, 128, 144],
34566	"slategrey": [112, 128, 144],
34567	"snow": [255, 250, 250],
34568	"springgreen": [0, 255, 127],
34569	"steelblue": [70, 130, 180],
34570	"tan": [210, 180, 140],
34571	"teal": [0, 128, 128],
34572	"thistle": [216, 191, 216],
34573	"tomato": [255, 99, 71],
34574	"turquoise": [64, 224, 208],
34575	"violet": [238, 130, 238],
34576	"wheat": [245, 222, 179],
34577	"white": [255, 255, 255],
34578	"whitesmoke": [245, 245, 245],
34579	"yellow": [255, 255, 0],
34580	"yellowgreen": [154, 205, 50]
34581};
34582
34583},{}],7:[function(require,module,exports){
34584/**
34585 * @namespace Chart
34586 */
34587var Chart = require(29)();
34588
34589Chart.helpers = require(45);
34590
34591// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!
34592require(27)(Chart);
34593
34594Chart.defaults = require(25);
34595Chart.Element = require(26);
34596Chart.elements = require(40);
34597Chart.Interaction = require(28);
34598Chart.layouts = require(30);
34599Chart.platform = require(48);
34600Chart.plugins = require(31);
34601Chart.Ticks = require(34);
34602
34603require(22)(Chart);
34604require(23)(Chart);
34605require(24)(Chart);
34606require(33)(Chart);
34607require(32)(Chart);
34608require(35)(Chart);
34609
34610require(55)(Chart);
34611require(53)(Chart);
34612require(54)(Chart);
34613require(56)(Chart);
34614require(57)(Chart);
34615require(58)(Chart);
34616
34617// Controllers must be loaded after elements
34618// See Chart.core.datasetController.dataElementType
34619require(15)(Chart);
34620require(16)(Chart);
34621require(17)(Chart);
34622require(18)(Chart);
34623require(19)(Chart);
34624require(20)(Chart);
34625require(21)(Chart);
34626
34627require(8)(Chart);
34628require(9)(Chart);
34629require(10)(Chart);
34630require(11)(Chart);
34631require(12)(Chart);
34632require(13)(Chart);
34633require(14)(Chart);
34634
34635// Loading built-it plugins
34636var plugins = require(49);
34637for (var k in plugins) {
34638	if (plugins.hasOwnProperty(k)) {
34639		Chart.plugins.register(plugins[k]);
34640	}
34641}
34642
34643Chart.platform.initialize();
34644
34645module.exports = Chart;
34646if (typeof window !== 'undefined') {
34647	window.Chart = Chart;
34648}
34649
34650// DEPRECATIONS
34651
34652/**
34653 * Provided for backward compatibility, not available anymore
34654 * @namespace Chart.Legend
34655 * @deprecated since version 2.1.5
34656 * @todo remove at version 3
34657 * @private
34658 */
34659Chart.Legend = plugins.legend._element;
34660
34661/**
34662 * Provided for backward compatibility, not available anymore
34663 * @namespace Chart.Title
34664 * @deprecated since version 2.1.5
34665 * @todo remove at version 3
34666 * @private
34667 */
34668Chart.Title = plugins.title._element;
34669
34670/**
34671 * Provided for backward compatibility, use Chart.plugins instead
34672 * @namespace Chart.pluginService
34673 * @deprecated since version 2.1.5
34674 * @todo remove at version 3
34675 * @private
34676 */
34677Chart.pluginService = Chart.plugins;
34678
34679/**
34680 * Provided for backward compatibility, inheriting from Chart.PlugingBase has no
34681 * effect, instead simply create/register plugins via plain JavaScript objects.
34682 * @interface Chart.PluginBase
34683 * @deprecated since version 2.5.0
34684 * @todo remove at version 3
34685 * @private
34686 */
34687Chart.PluginBase = Chart.Element.extend({});
34688
34689/**
34690 * Provided for backward compatibility, use Chart.helpers.canvas instead.
34691 * @namespace Chart.canvasHelpers
34692 * @deprecated since version 2.6.0
34693 * @todo remove at version 3
34694 * @private
34695 */
34696Chart.canvasHelpers = Chart.helpers.canvas;
34697
34698/**
34699 * Provided for backward compatibility, use Chart.layouts instead.
34700 * @namespace Chart.layoutService
34701 * @deprecated since version 2.8.0
34702 * @todo remove at version 3
34703 * @private
34704 */
34705Chart.layoutService = Chart.layouts;
34706
34707},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"40":40,"45":45,"48":48,"49":49,"53":53,"54":54,"55":55,"56":56,"57":57,"58":58,"8":8,"9":9}],8:[function(require,module,exports){
34708'use strict';
34709
34710module.exports = function(Chart) {
34711
34712	Chart.Bar = function(context, config) {
34713		config.type = 'bar';
34714
34715		return new Chart(context, config);
34716	};
34717
34718};
34719
34720},{}],9:[function(require,module,exports){
34721'use strict';
34722
34723module.exports = function(Chart) {
34724
34725	Chart.Bubble = function(context, config) {
34726		config.type = 'bubble';
34727		return new Chart(context, config);
34728	};
34729
34730};
34731
34732},{}],10:[function(require,module,exports){
34733'use strict';
34734
34735module.exports = function(Chart) {
34736
34737	Chart.Doughnut = function(context, config) {
34738		config.type = 'doughnut';
34739
34740		return new Chart(context, config);
34741	};
34742
34743};
34744
34745},{}],11:[function(require,module,exports){
34746'use strict';
34747
34748module.exports = function(Chart) {
34749
34750	Chart.Line = function(context, config) {
34751		config.type = 'line';
34752
34753		return new Chart(context, config);
34754	};
34755
34756};
34757
34758},{}],12:[function(require,module,exports){
34759'use strict';
34760
34761module.exports = function(Chart) {
34762
34763	Chart.PolarArea = function(context, config) {
34764		config.type = 'polarArea';
34765
34766		return new Chart(context, config);
34767	};
34768
34769};
34770
34771},{}],13:[function(require,module,exports){
34772'use strict';
34773
34774module.exports = function(Chart) {
34775
34776	Chart.Radar = function(context, config) {
34777		config.type = 'radar';
34778
34779		return new Chart(context, config);
34780	};
34781
34782};
34783
34784},{}],14:[function(require,module,exports){
34785'use strict';
34786
34787module.exports = function(Chart) {
34788	Chart.Scatter = function(context, config) {
34789		config.type = 'scatter';
34790		return new Chart(context, config);
34791	};
34792};
34793
34794},{}],15:[function(require,module,exports){
34795'use strict';
34796
34797var defaults = require(25);
34798var elements = require(40);
34799var helpers = require(45);
34800
34801defaults._set('bar', {
34802	hover: {
34803		mode: 'label'
34804	},
34805
34806	scales: {
34807		xAxes: [{
34808			type: 'category',
34809
34810			// Specific to Bar Controller
34811			categoryPercentage: 0.8,
34812			barPercentage: 0.9,
34813
34814			// offset settings
34815			offset: true,
34816
34817			// grid line settings
34818			gridLines: {
34819				offsetGridLines: true
34820			}
34821		}],
34822
34823		yAxes: [{
34824			type: 'linear'
34825		}]
34826	}
34827});
34828
34829defaults._set('horizontalBar', {
34830	hover: {
34831		mode: 'index',
34832		axis: 'y'
34833	},
34834
34835	scales: {
34836		xAxes: [{
34837			type: 'linear',
34838			position: 'bottom'
34839		}],
34840
34841		yAxes: [{
34842			position: 'left',
34843			type: 'category',
34844
34845			// Specific to Horizontal Bar Controller
34846			categoryPercentage: 0.8,
34847			barPercentage: 0.9,
34848
34849			// offset settings
34850			offset: true,
34851
34852			// grid line settings
34853			gridLines: {
34854				offsetGridLines: true
34855			}
34856		}]
34857	},
34858
34859	elements: {
34860		rectangle: {
34861			borderSkipped: 'left'
34862		}
34863	},
34864
34865	tooltips: {
34866		callbacks: {
34867			title: function(item, data) {
34868				// Pick first xLabel for now
34869				var title = '';
34870
34871				if (item.length > 0) {
34872					if (item[0].yLabel) {
34873						title = item[0].yLabel;
34874					} else if (data.labels.length > 0 && item[0].index < data.labels.length) {
34875						title = data.labels[item[0].index];
34876					}
34877				}
34878
34879				return title;
34880			},
34881
34882			label: function(item, data) {
34883				var datasetLabel = data.datasets[item.datasetIndex].label || '';
34884				return datasetLabel + ': ' + item.xLabel;
34885			}
34886		},
34887		mode: 'index',
34888		axis: 'y'
34889	}
34890});
34891
34892/**
34893 * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap.
34894 * @private
34895 */
34896function computeMinSampleSize(scale, pixels) {
34897	var min = scale.isHorizontal() ? scale.width : scale.height;
34898	var ticks = scale.getTicks();
34899	var prev, curr, i, ilen;
34900
34901	for (i = 1, ilen = pixels.length; i < ilen; ++i) {
34902		min = Math.min(min, pixels[i] - pixels[i - 1]);
34903	}
34904
34905	for (i = 0, ilen = ticks.length; i < ilen; ++i) {
34906		curr = scale.getPixelForTick(i);
34907		min = i > 0 ? Math.min(min, curr - prev) : min;
34908		prev = curr;
34909	}
34910
34911	return min;
34912}
34913
34914/**
34915 * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null,
34916 * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This
34917 * mode currently always generates bars equally sized (until we introduce scriptable options?).
34918 * @private
34919 */
34920function computeFitCategoryTraits(index, ruler, options) {
34921	var thickness = options.barThickness;
34922	var count = ruler.stackCount;
34923	var curr = ruler.pixels[index];
34924	var size, ratio;
34925
34926	if (helpers.isNullOrUndef(thickness)) {
34927		size = ruler.min * options.categoryPercentage;
34928		ratio = options.barPercentage;
34929	} else {
34930		// When bar thickness is enforced, category and bar percentages are ignored.
34931		// Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')
34932		// and deprecate barPercentage since this value is ignored when thickness is absolute.
34933		size = thickness * count;
34934		ratio = 1;
34935	}
34936
34937	return {
34938		chunk: size / count,
34939		ratio: ratio,
34940		start: curr - (size / 2)
34941	};
34942}
34943
34944/**
34945 * Computes an "optimal" category that globally arranges bars side by side (no gap when
34946 * percentage options are 1), based on the previous and following categories. This mode
34947 * generates bars with different widths when data are not evenly spaced.
34948 * @private
34949 */
34950function computeFlexCategoryTraits(index, ruler, options) {
34951	var pixels = ruler.pixels;
34952	var curr = pixels[index];
34953	var prev = index > 0 ? pixels[index - 1] : null;
34954	var next = index < pixels.length - 1 ? pixels[index + 1] : null;
34955	var percent = options.categoryPercentage;
34956	var start, size;
34957
34958	if (prev === null) {
34959		// first data: its size is double based on the next point or,
34960		// if it's also the last data, we use the scale end extremity.
34961		prev = curr - (next === null ? ruler.end - curr : next - curr);
34962	}
34963
34964	if (next === null) {
34965		// last data: its size is also double based on the previous point.
34966		next = curr + curr - prev;
34967	}
34968
34969	start = curr - ((curr - prev) / 2) * percent;
34970	size = ((next - prev) / 2) * percent;
34971
34972	return {
34973		chunk: size / ruler.stackCount,
34974		ratio: options.barPercentage,
34975		start: start
34976	};
34977}
34978
34979module.exports = function(Chart) {
34980
34981	Chart.controllers.bar = Chart.DatasetController.extend({
34982
34983		dataElementType: elements.Rectangle,
34984
34985		initialize: function() {
34986			var me = this;
34987			var meta;
34988
34989			Chart.DatasetController.prototype.initialize.apply(me, arguments);
34990
34991			meta = me.getMeta();
34992			meta.stack = me.getDataset().stack;
34993			meta.bar = true;
34994		},
34995
34996		update: function(reset) {
34997			var me = this;
34998			var rects = me.getMeta().data;
34999			var i, ilen;
35000
35001			me._ruler = me.getRuler();
35002
35003			for (i = 0, ilen = rects.length; i < ilen; ++i) {
35004				me.updateElement(rects[i], i, reset);
35005			}
35006		},
35007
35008		updateElement: function(rectangle, index, reset) {
35009			var me = this;
35010			var chart = me.chart;
35011			var meta = me.getMeta();
35012			var dataset = me.getDataset();
35013			var custom = rectangle.custom || {};
35014			var rectangleOptions = chart.options.elements.rectangle;
35015
35016			rectangle._xScale = me.getScaleForId(meta.xAxisID);
35017			rectangle._yScale = me.getScaleForId(meta.yAxisID);
35018			rectangle._datasetIndex = me.index;
35019			rectangle._index = index;
35020
35021			rectangle._model = {
35022				datasetLabel: dataset.label,
35023				label: chart.data.labels[index],
35024				borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped,
35025				backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor),
35026				borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor),
35027				borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth)
35028			};
35029
35030			me.updateElementGeometry(rectangle, index, reset);
35031
35032			rectangle.pivot();
35033		},
35034
35035		/**
35036		 * @private
35037		 */
35038		updateElementGeometry: function(rectangle, index, reset) {
35039			var me = this;
35040			var model = rectangle._model;
35041			var vscale = me.getValueScale();
35042			var base = vscale.getBasePixel();
35043			var horizontal = vscale.isHorizontal();
35044			var ruler = me._ruler || me.getRuler();
35045			var vpixels = me.calculateBarValuePixels(me.index, index);
35046			var ipixels = me.calculateBarIndexPixels(me.index, index, ruler);
35047
35048			model.horizontal = horizontal;
35049			model.base = reset ? base : vpixels.base;
35050			model.x = horizontal ? reset ? base : vpixels.head : ipixels.center;
35051			model.y = horizontal ? ipixels.center : reset ? base : vpixels.head;
35052			model.height = horizontal ? ipixels.size : undefined;
35053			model.width = horizontal ? undefined : ipixels.size;
35054		},
35055
35056		/**
35057		 * @private
35058		 */
35059		getValueScaleId: function() {
35060			return this.getMeta().yAxisID;
35061		},
35062
35063		/**
35064		 * @private
35065		 */
35066		getIndexScaleId: function() {
35067			return this.getMeta().xAxisID;
35068		},
35069
35070		/**
35071		 * @private
35072		 */
35073		getValueScale: function() {
35074			return this.getScaleForId(this.getValueScaleId());
35075		},
35076
35077		/**
35078		 * @private
35079		 */
35080		getIndexScale: function() {
35081			return this.getScaleForId(this.getIndexScaleId());
35082		},
35083
35084		/**
35085		 * Returns the stacks based on groups and bar visibility.
35086		 * @param {Number} [last] - The dataset index
35087		 * @returns {Array} The stack list
35088		 * @private
35089		 */
35090		_getStacks: function(last) {
35091			var me = this;
35092			var chart = me.chart;
35093			var scale = me.getIndexScale();
35094			var stacked = scale.options.stacked;
35095			var ilen = last === undefined ? chart.data.datasets.length : last + 1;
35096			var stacks = [];
35097			var i, meta;
35098
35099			for (i = 0; i < ilen; ++i) {
35100				meta = chart.getDatasetMeta(i);
35101				if (meta.bar && chart.isDatasetVisible(i) &&
35102					(stacked === false ||
35103					(stacked === true && stacks.indexOf(meta.stack) === -1) ||
35104					(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
35105					stacks.push(meta.stack);
35106				}
35107			}
35108
35109			return stacks;
35110		},
35111
35112		/**
35113		 * Returns the effective number of stacks based on groups and bar visibility.
35114		 * @private
35115		 */
35116		getStackCount: function() {
35117			return this._getStacks().length;
35118		},
35119
35120		/**
35121		 * Returns the stack index for the given dataset based on groups and bar visibility.
35122		 * @param {Number} [datasetIndex] - The dataset index
35123		 * @param {String} [name] - The stack name to find
35124		 * @returns {Number} The stack index
35125		 * @private
35126		 */
35127		getStackIndex: function(datasetIndex, name) {
35128			var stacks = this._getStacks(datasetIndex);
35129			var index = (name !== undefined)
35130				? stacks.indexOf(name)
35131				: -1; // indexOf returns -1 if element is not present
35132
35133			return (index === -1)
35134				? stacks.length - 1
35135				: index;
35136		},
35137
35138		/**
35139		 * @private
35140		 */
35141		getRuler: function() {
35142			var me = this;
35143			var scale = me.getIndexScale();
35144			var stackCount = me.getStackCount();
35145			var datasetIndex = me.index;
35146			var isHorizontal = scale.isHorizontal();
35147			var start = isHorizontal ? scale.left : scale.top;
35148			var end = start + (isHorizontal ? scale.width : scale.height);
35149			var pixels = [];
35150			var i, ilen, min;
35151
35152			for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {
35153				pixels.push(scale.getPixelForValue(null, i, datasetIndex));
35154			}
35155
35156			min = helpers.isNullOrUndef(scale.options.barThickness)
35157				? computeMinSampleSize(scale, pixels)
35158				: -1;
35159
35160			return {
35161				min: min,
35162				pixels: pixels,
35163				start: start,
35164				end: end,
35165				stackCount: stackCount,
35166				scale: scale
35167			};
35168		},
35169
35170		/**
35171		 * Note: pixel values are not clamped to the scale area.
35172		 * @private
35173		 */
35174		calculateBarValuePixels: function(datasetIndex, index) {
35175			var me = this;
35176			var chart = me.chart;
35177			var meta = me.getMeta();
35178			var scale = me.getValueScale();
35179			var datasets = chart.data.datasets;
35180			var value = scale.getRightValue(datasets[datasetIndex].data[index]);
35181			var stacked = scale.options.stacked;
35182			var stack = meta.stack;
35183			var start = 0;
35184			var i, imeta, ivalue, base, head, size;
35185
35186			if (stacked || (stacked === undefined && stack !== undefined)) {
35187				for (i = 0; i < datasetIndex; ++i) {
35188					imeta = chart.getDatasetMeta(i);
35189
35190					if (imeta.bar &&
35191						imeta.stack === stack &&
35192						imeta.controller.getValueScaleId() === scale.id &&
35193						chart.isDatasetVisible(i)) {
35194
35195						ivalue = scale.getRightValue(datasets[i].data[index]);
35196						if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) {
35197							start += ivalue;
35198						}
35199					}
35200				}
35201			}
35202
35203			base = scale.getPixelForValue(start);
35204			head = scale.getPixelForValue(start + value);
35205			size = (head - base) / 2;
35206
35207			return {
35208				size: size,
35209				base: base,
35210				head: head,
35211				center: head + size / 2
35212			};
35213		},
35214
35215		/**
35216		 * @private
35217		 */
35218		calculateBarIndexPixels: function(datasetIndex, index, ruler) {
35219			var me = this;
35220			var options = ruler.scale.options;
35221			var range = options.barThickness === 'flex'
35222				? computeFlexCategoryTraits(index, ruler, options)
35223				: computeFitCategoryTraits(index, ruler, options);
35224
35225			var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);
35226			var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
35227			var size = Math.min(
35228				helpers.valueOrDefault(options.maxBarThickness, Infinity),
35229				range.chunk * range.ratio);
35230
35231			return {
35232				base: center - size / 2,
35233				head: center + size / 2,
35234				center: center,
35235				size: size
35236			};
35237		},
35238
35239		draw: function() {
35240			var me = this;
35241			var chart = me.chart;
35242			var scale = me.getValueScale();
35243			var rects = me.getMeta().data;
35244			var dataset = me.getDataset();
35245			var ilen = rects.length;
35246			var i = 0;
35247
35248			helpers.canvas.clipArea(chart.ctx, chart.chartArea);
35249
35250			for (; i < ilen; ++i) {
35251				if (!isNaN(scale.getRightValue(dataset.data[i]))) {
35252					rects[i].draw();
35253				}
35254			}
35255
35256			helpers.canvas.unclipArea(chart.ctx);
35257		},
35258
35259		setHoverStyle: function(rectangle) {
35260			var dataset = this.chart.data.datasets[rectangle._datasetIndex];
35261			var index = rectangle._index;
35262			var custom = rectangle.custom || {};
35263			var model = rectangle._model;
35264
35265			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
35266			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor));
35267			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
35268		},
35269
35270		removeHoverStyle: function(rectangle) {
35271			var dataset = this.chart.data.datasets[rectangle._datasetIndex];
35272			var index = rectangle._index;
35273			var custom = rectangle.custom || {};
35274			var model = rectangle._model;
35275			var rectangleElementOptions = this.chart.options.elements.rectangle;
35276
35277			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor);
35278			model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor);
35279			model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth);
35280		}
35281	});
35282
35283	Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
35284		/**
35285		 * @private
35286		 */
35287		getValueScaleId: function() {
35288			return this.getMeta().xAxisID;
35289		},
35290
35291		/**
35292		 * @private
35293		 */
35294		getIndexScaleId: function() {
35295			return this.getMeta().yAxisID;
35296		}
35297	});
35298};
35299
35300},{"25":25,"40":40,"45":45}],16:[function(require,module,exports){
35301'use strict';
35302
35303var defaults = require(25);
35304var elements = require(40);
35305var helpers = require(45);
35306
35307defaults._set('bubble', {
35308	hover: {
35309		mode: 'single'
35310	},
35311
35312	scales: {
35313		xAxes: [{
35314			type: 'linear', // bubble should probably use a linear scale by default
35315			position: 'bottom',
35316			id: 'x-axis-0' // need an ID so datasets can reference the scale
35317		}],
35318		yAxes: [{
35319			type: 'linear',
35320			position: 'left',
35321			id: 'y-axis-0'
35322		}]
35323	},
35324
35325	tooltips: {
35326		callbacks: {
35327			title: function() {
35328				// Title doesn't make sense for scatter since we format the data as a point
35329				return '';
35330			},
35331			label: function(item, data) {
35332				var datasetLabel = data.datasets[item.datasetIndex].label || '';
35333				var dataPoint = data.datasets[item.datasetIndex].data[item.index];
35334				return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';
35335			}
35336		}
35337	}
35338});
35339
35340
35341module.exports = function(Chart) {
35342
35343	Chart.controllers.bubble = Chart.DatasetController.extend({
35344		/**
35345		 * @protected
35346		 */
35347		dataElementType: elements.Point,
35348
35349		/**
35350		 * @protected
35351		 */
35352		update: function(reset) {
35353			var me = this;
35354			var meta = me.getMeta();
35355			var points = meta.data;
35356
35357			// Update Points
35358			helpers.each(points, function(point, index) {
35359				me.updateElement(point, index, reset);
35360			});
35361		},
35362
35363		/**
35364		 * @protected
35365		 */
35366		updateElement: function(point, index, reset) {
35367			var me = this;
35368			var meta = me.getMeta();
35369			var custom = point.custom || {};
35370			var xScale = me.getScaleForId(meta.xAxisID);
35371			var yScale = me.getScaleForId(meta.yAxisID);
35372			var options = me._resolveElementOptions(point, index);
35373			var data = me.getDataset().data[index];
35374			var dsIndex = me.index;
35375
35376			var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);
35377			var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);
35378
35379			point._xScale = xScale;
35380			point._yScale = yScale;
35381			point._options = options;
35382			point._datasetIndex = dsIndex;
35383			point._index = index;
35384			point._model = {
35385				backgroundColor: options.backgroundColor,
35386				borderColor: options.borderColor,
35387				borderWidth: options.borderWidth,
35388				hitRadius: options.hitRadius,
35389				pointStyle: options.pointStyle,
35390				radius: reset ? 0 : options.radius,
35391				skip: custom.skip || isNaN(x) || isNaN(y),
35392				x: x,
35393				y: y,
35394			};
35395
35396			point.pivot();
35397		},
35398
35399		/**
35400		 * @protected
35401		 */
35402		setHoverStyle: function(point) {
35403			var model = point._model;
35404			var options = point._options;
35405
35406			model.backgroundColor = helpers.valueOrDefault(options.hoverBackgroun
35406dColor, helpers.getHoverColor(options.backgroundColor));
35407			model.borderColor = helpers.valueOrDefault(options.hoverBorderColor, helpers.getHoverColor(options.borderColor));
35408			model.borderWidth = helpers.valueOrDefault(options.hoverBorderWidth, options.borderWidth);
35409			model.radius = options.radius + options.hoverRadius;
35410		},
35411
35412		/**
35413		 * @protected
35414		 */
35415		removeHoverStyle: function(point) {
35416			var model = point._model;
35417			var options = point._options;
35418
35419			model.backgroundColor = options.backgroundColor;
35420			model.borderColor = options.borderColor;
35421			model.borderWidth = options.borderWidth;
35422			model.radius = options.radius;
35423		},
35424
35425		/**
35426		 * @private
35427		 */
35428		_resolveElementOptions: function(point, index) {
35429			var me = this;
35430			var chart = me.chart;
35431			var datasets = chart.data.datasets;
35432			var dataset = datasets[me.index];
35433			var custom = point.custom || {};
35434			var options = chart.options.elements.point;
35435			var resolve = helpers.options.resolve;
35436			var data = dataset.data[index];
35437			var values = {};
35438			var i, ilen, key;
35439
35440			// Scriptable options
35441			var context = {
35442				chart: chart,
35443				dataIndex: index,
35444				dataset: dataset,
35445				datasetIndex: me.index
35446			};
35447
35448			var keys = [
35449				'backgroundColor',
35450				'borderColor',
35451				'borderWidth',
35452				'hoverBackgroundColor',
35453				'hoverBorderColor',
35454				'hoverBorderWidth',
35455				'hoverRadius',
35456				'hitRadius',
35457				'pointStyle'
35458			];
35459
35460			for (i = 0, ilen = keys.length; i < ilen; ++i) {
35461				key = keys[i];
35462				values[key] = resolve([
35463					custom[key],
35464					dataset[key],
35465					options[key]
35466				], context, index);
35467			}
35468
35469			// Custom radius resolution
35470			values.radius = resolve([
35471				custom.radius,
35472				data ? data.r : undefined,
35473				dataset.radius,
35474				options.radius
35475			], context, index);
35476
35477			return values;
35478		}
35479	});
35480};
35481
35482},{"25":25,"40":40,"45":45}],17:[function(require,module,exports){
35483'use strict';
35484
35485var defaults = require(25);
35486var elements = require(40);
35487var helpers = require(45);
35488
35489defaults._set('doughnut', {
35490	animation: {
35491		// Boolean - Whether we animate the rotation of the Doughnut
35492		animateRotate: true,
35493		// Boolean - Whether we animate scaling the Doughnut from the centre
35494		animateScale: false
35495	},
35496	hover: {
35497		mode: 'single'
35498	},
35499	legendCallback: function(chart) {
35500		var text = [];
35501		text.push('<ul class="' + chart.id + '-legend">');
35502
35503		var data = chart.data;
35504		var datasets = data.datasets;
35505		var labels = data.labels;
35506
35507		if (datasets.length) {
35508			for (var i = 0; i < datasets[0].data.length; ++i) {
35509				text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
35510				if (labels[i]) {
35511					text.push(labels[i]);
35512				}
35513				text.push('</li>');
35514			}
35515		}
35516
35517		text.push('</ul>');
35518		return text.join('');
35519	},
35520	legend: {
35521		labels: {
35522			generateLabels: function(chart) {
35523				var data = chart.data;
35524				if (data.labels.length && data.datasets.length) {
35525					return data.labels.map(function(label, i) {
35526						var meta = chart.getDatasetMeta(0);
35527						var ds = data.datasets[0];
35528						var arc = meta.data[i];
35529						var custom = arc && arc.custom || {};
35530						var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
35531						var arcOpts = chart.options.elements.arc;
35532						var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
35533						var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
35534						var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
35535
35536						return {
35537							text: label,
35538							fillStyle: fill,
35539							strokeStyle: stroke,
35540							lineWidth: bw,
35541							hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
35542
35543							// Extra data used for toggling the correct item
35544							index: i
35545						};
35546					});
35547				}
35548				return [];
35549			}
35550		},
35551
35552		onClick: function(e, legendItem) {
35553			var index = legendItem.index;
35554			var chart = this.chart;
35555			var i, ilen, meta;
35556
35557			for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
35558				meta = chart.getDatasetMeta(i);
35559				// toggle visibility of index if exists
35560				if (meta.data[index]) {
35561					meta.data[index].hidden = !meta.data[index].hidden;
35562				}
35563			}
35564
35565			chart.update();
35566		}
35567	},
35568
35569	// The percentage of the chart that we cut out of the middle.
35570	cutoutPercentage: 50,
35571
35572	// The rotation of the chart, where the first data arc begins.
35573	rotation: Math.PI * -0.5,
35574
35575	// The total circumference of the chart.
35576	circumference: Math.PI * 2.0,
35577
35578	// Need to override these to give a nice default
35579	tooltips: {
35580		callbacks: {
35581			title: function() {
35582				return '';
35583			},
35584			label: function(tooltipItem, data) {
35585				var dataLabel = data.labels[tooltipItem.index];
35586				var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
35587
35588				if (helpers.isArray(dataLabel)) {
35589					// show value on first line of multiline label
35590					// need to clone because we are changing the value
35591					dataLabel = dataLabel.slice();
35592					dataLabel[0] += value;
35593				} else {
35594					dataLabel += value;
35595				}
35596
35597				return dataLabel;
35598			}
35599		}
35600	}
35601});
35602
35603defaults._set('pie', helpers.clone(defaults.doughnut));
35604defaults._set('pie', {
35605	cutoutPercentage: 0
35606});
35607
35608module.exports = function(Chart) {
35609
35610	Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
35611
35612		dataElementType: elements.Arc,
35613
35614		linkScales: helpers.noop,
35615
35616		// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
35617		getRingIndex: function(datasetIndex) {
35618			var ringIndex = 0;
35619
35620			for (var j = 0; j < datasetIndex; ++j) {
35621				if (this.chart.isDatasetVisible(j)) {
35622					++ringIndex;
35623				}
35624			}
35625
35626			return ringIndex;
35627		},
35628
35629		update: function(reset) {
35630			var me = this;
35631			var chart = me.chart;
35632			var chartArea = chart.chartArea;
35633			var opts = chart.options;
35634			var arcOpts = opts.elements.arc;
35635			var availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth;
35636			var availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth;
35637			var minSize = Math.min(availableWidth, availableHeight);
35638			var offset = {x: 0, y: 0};
35639			var meta = me.getMeta();
35640			var cutoutPercentage = opts.cutoutPercentage;
35641			var circumference = opts.circumference;
35642
35643			// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
35644			if (circumference < Math.PI * 2.0) {
35645				var startAngle = opts.rotation % (Math.PI * 2.0);
35646				startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
35647				var endAngle = startAngle + circumference;
35648				var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)};
35649				var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)};
35650				var contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle);
35651				var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle);
35652				var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle);
35653				var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle);
35654				var cutout = cutoutPercentage / 100.0;
35655				var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))};
35656				var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))};
35657				var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5};
35658				minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
35659				offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
35660			}
35661
35662			chart.borderWidth = me.getMaxBorderWidth(meta.data);
35663			chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
35664			chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
35665			chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
35666			chart.offsetX = offset.x * chart.outerRadius;
35667			chart.offsetY = offset.y * chart.outerRadius;
35668
35669			meta.total = me.calculateTotal();
35670
35671			me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
35672			me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
35673
35674			helpers.each(meta.data, function(arc, index) {
35675				me.updateElement(arc, index, reset);
35676			});
35677		},
35678
35679		updateElement: function(arc, index, reset) {
35680			var me = this;
35681			var chart = me.chart;
35682			var chartArea = chart.chartArea;
35683			var opts = chart.options;
35684			var animationOpts = opts.animation;
35685			var centerX = (chartArea.left + chartArea.right) / 2;
35686			var centerY = (chartArea.top + chartArea.bottom) / 2;
35687			var startAngle = opts.rotation; // non reset case handled later
35688			var endAngle = opts.rotation; // non reset case handled later
35689			var dataset = me.getDataset();
35690			var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI));
35691			var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
35692			var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
35693			var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
35694
35695			helpers.extend(arc, {
35696				// Utility
35697				_datasetIndex: me.index,
35698				_index: index,
35699
35700				// Desired view properties
35701				_model: {
35702					x: centerX + chart.offsetX,
35703					y: centerY + chart.offsetY,
35704					startAngle: startAngle,
35705					endAngle: endAngle,
35706					circumference: circumference,
35707					outerRadius: outerRadius,
35708					innerRadius: innerRadius,
35709					label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
35710				}
35711			});
35712
35713			var model = arc._model;
35714			// Resets the visual styles
35715			this.removeHoverStyle(arc);
35716
35717			// Set correct angles if not resetting
35718			if (!reset || !animationOpts.animateRotate) {
35719				if (index === 0) {
35720					model.startAngle = opts.rotation;
35721				} else {
35722					model.startAngle = me.getMeta().data[index - 1]._model.endAngle;
35723				}
35724
35725				model.endAngle = model.startAngle + model.circumference;
35726			}
35727
35728			arc.pivot();
35729		},
35730
35731		removeHoverStyle: function(arc) {
35732			Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
35733		},
35734
35735		calculateTotal: function() {
35736			var dataset = this.getDataset();
35737			var meta = this.getMeta();
35738			var total = 0;
35739			var value;
35740
35741			helpers.each(meta.data, function(element, index) {
35742				value = dataset.data[index];
35743				if (!isNaN(value) && !element.hidden) {
35744					total += Math.abs(value);
35745				}
35746			});
35747
35748			/* if (total === 0) {
35749				total = NaN;
35750			}*/
35751
35752			return total;
35753		},
35754
35755		calculateCircumference: function(value) {
35756			var total = this.getMeta().total;
35757			if (total > 0 && !isNaN(value)) {
35758				return (Math.PI * 2.0) * (Math.abs(value) / total);
35759			}
35760			return 0;
35761		},
35762
35763		// gets the max border or hover width to properly scale pie charts
35764		getMaxBorderWidth: function(arcs) {
35765			var max = 0;
35766			var index = this.index;
35767			var length = arcs.length;
35768			var borderWidth;
35769			var hoverWidth;
35770
35771			for (var i = 0; i < length; i++) {
35772				borderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0;
35773				hoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
35774
35775				max = borderWidth > max ? borderWidth : max;
35776				max = hoverWidth > max ? hoverWidth : max;
35777			}
35778			return max;
35779		}
35780	});
35781};
35782
35783},{"25":25,"40":40,"45":45}],18:[function(require,module,exports){
35784'use strict';
35785
35786var defaults = require(25);
35787var elements = require(40);
35788var helpers = require(45);
35789
35790defaults._set('line', {
35791	showLines: true,
35792	spanGaps: false,
35793
35794	hover: {
35795		mode: 'label'
35796	},
35797
35798	scales: {
35799		xAxes: [{
35800			type: 'category',
35801			id: 'x-axis-0'
35802		}],
35803		yAxes: [{
35804			type: 'linear',
35805			id: 'y-axis-0'
35806		}]
35807	}
35808});
35809
35810module.exports = function(Chart) {
35811
35812	function lineEnabled(dataset, options) {
35813		return helpers.valueOrDefault(dataset.showLine, options.showLines);
35814	}
35815
35816	Chart.controllers.line = Chart.DatasetController.extend({
35817
35818		datasetElementType: elements.Line,
35819
35820		dataElementType: elements.Point,
35821
35822		update: function(reset) {
35823			var me = this;
35824			var meta = me.getMeta();
35825			var line = meta.dataset;
35826			var points = meta.data || [];
35827			var options = me.chart.options;
35828			var lineElementOptions = options.elements.line;
35829			var scale = me.getScaleForId(meta.yAxisID);
35830			var i, ilen, custom;
35831			var dataset = me.getDataset();
35832			var showLine = lineEnabled(dataset, options);
35833
35834			// Update Line
35835			if (showLine) {
35836				custom = line.custom || {};
35837
35838				// Compatibility: If the properties are defined with only the old name, use those values
35839				if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
35840					dataset.lineTension = dataset.tension;
35841				}
35842
35843				// Utility
35844				line._scale = scale;
35845				line._datasetIndex = me.index;
35846				// Data
35847				line._children = points;
35848				// Model
35849				line._model = {
35850					// Appearance
35851					// The default behavior of lines is to break at null values, according
35852					// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
35853					// This option gives lines the ability to span gaps
35854					spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
35855					tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),
35856					backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
35857					borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
35858					borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
35859					borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
35860					borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
35861					borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
35862					borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
35863					fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
35864					steppedLine: custom.steppedLine ? custom.steppedLine : helpers.valueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
35865					cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.valueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode),
35866				};
35867
35868				line.pivot();
35869			}
35870
35871			// Update Points
35872			for (i = 0, ilen = points.length; i < ilen; ++i) {
35873				me.updateElement(points[i], i, reset);
35874			}
35875
35876			if (showLine && line._model.tension !== 0) {
35877				me.updateBezierControlPoints();
35878			}
35879
35880			// Now pivot the point for animation
35881			for (i = 0, ilen = points.length; i < ilen; ++i) {
35882				points[i].pivot();
35883			}
35884		},
35885
35886		getPointBackgroundColor: function(point, index) {
35887			var backgroundColor = this.chart.options.elements.point.backgroundColor;
35888			var dataset = this.getDataset();
35889			var custom = point.custom || {};
35890
35891			if (custom.backgroundColor) {
35892				backgroundColor = custom.backgroundColor;
35893			}
35893 else if (dataset.pointBackgroundColor) {
35894				backgroundColor = helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
35895			} else if (dataset.backgroundColor) {
35896				backgroundColor = dataset.backgroundColor;
35897			}
35898
35899			return backgroundColor;
35900		},
35901
35902		getPointBorderColor: function(point, index) {
35903			var borderColor = this.chart.options.elements.point.borderColor;
35904			var dataset = this.getDataset();
35905			var custom = point.custom || {};
35906
35907			if (custom.borderColor) {
35908				borderColor = custom.borderColor;
35909			} else if (dataset.pointBorderColor) {
35910				borderColor = helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor);
35911			} else if (dataset.borderColor) {
35912				borderColor = dataset.borderColor;
35913			}
35914
35915			return borderColor;
35916		},
35917
35918		getPointBorderWidth: function(point, index) {
35919			var borderWidth = this.chart.options.elements.point.borderWidth;
35920			var dataset = this.getDataset();
35921			var custom = point.custom || {};
35922
35923			if (!isNaN(custom.borderWidth)) {
35924				borderWidth = custom.borderWidth;
35925			} else if (!isNaN(dataset.pointBorderWidth) || helpers.isArray(dataset.pointBorderWidth)) {
35926				borderWidth = helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
35927			} else if (!isNaN(dataset.borderWidth)) {
35928				borderWidth = dataset.borderWidth;
35929			}
35930
35931			return borderWidth;
35932		},
35933
35934		updateElement: function(point, index, reset) {
35935			var me = this;
35936			var meta = me.getMeta();
35937			var custom = point.custom || {};
35938			var dataset = me.getDataset();
35939			var datasetIndex = me.index;
35940			var value = dataset.data[index];
35941			var yScale = me.getScaleForId(meta.yAxisID);
35942			var xScale = me.getScaleForId(meta.xAxisID);
35943			var pointOptions = me.chart.options.elements.point;
35944			var x, y;
35945
35946			// Compatibility: If the properties are defined with only the old name, use those values
35947			if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
35948				dataset.pointRadius = dataset.radius;
35949			}
35950			if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
35951				dataset.pointHitRadius = dataset.hitRadius;
35952			}
35953
35954			x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);
35955			y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
35956
35957			// Utility
35958			point._xScale = xScale;
35959			point._yScale = yScale;
35960			point._datasetIndex = datasetIndex;
35961			point._index = index;
35962
35963			// Desired view properties
35964			point._model = {
35965				x: x,
35966				y: y,
35967				skip: custom.skip || isNaN(x) || isNaN(y),
35968				// Appearance
35969				radius: custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius),
35970				pointStyle: custom.pointStyle || helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle),
35971				backgroundColor: me.getPointBackgroundColor(point, index),
35972				borderColor: me.getPointBorderColor(point, index),
35973				borderWidth: me.getPointBorderWidth(point, index),
35974				tension: meta.dataset._model ? meta.dataset._model.tension : 0,
35975				steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
35976				// Tooltip
35977				hitRadius: custom.hitRadius || helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
35978			};
35979		},
35980
35981		calculatePointY: function(value, index, datasetIndex) {
35982			var me = this;
35983			var chart = me.chart;
35984			var meta = me.getMeta();
35985			var yScale = me.getScaleForId(meta.yAxisID);
35986			var sumPos = 0;
35987			var sumNeg = 0;
35988			var i, ds, dsMeta;
35989
35990			if (yScale.options.stacked) {
35991				for (i = 0; i < datasetIndex; i++) {
35992					ds = chart.data.datasets[i];
35993					dsMeta = chart.getDatasetMeta(i);
35994					if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
35995						var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
35996						if (stackedRightValue < 0) {
35997							sumNeg += stackedRightValue || 0;
35998						} else {
35999							sumPos += stackedRightValue || 0;
36000						}
36001					}
36002				}
36003
36004				var rightValue = Number(yScale.getRightValue(value));
36005				if (rightValue < 0) {
36006					return yScale.getPixelForValue(sumNeg + rightValue);
36007				}
36008				return yScale.getPixelForValue(sumPos + rightValue);
36009			}
36010
36011			return yScale.getPixelForValue(value);
36012		},
36013
36014		updateBezierControlPoints: function() {
36015			var me = this;
36016			var meta = me.getMeta();
36017			var area = me.chart.chartArea;
36018			var points = (meta.data || []);
36019			var i, ilen, point, model, controlPoints;
36020
36021			// Only consider points that are drawn in case the spanGaps option is used
36022			if (meta.dataset._model.spanGaps) {
36023				points = points.filter(function(pt) {
36024					return !pt._model.skip;
36025				});
36026			}
36027
36028			function capControlPoint(pt, min, max) {
36029				return Math.max(Math.min(pt, max), min);
36030			}
36031
36032			if (meta.dataset._model.cubicInterpolationMode === 'monotone') {
36033				helpers.splineCurveMonotone(points);
36034			} else {
36035				for (i = 0, ilen = points.length; i < ilen; ++i) {
36036					point = points[i];
36037					model = point._model;
36038					controlPoints = helpers.splineCurve(
36039						helpers.previousItem(points, i)._model,
36040						model,
36041						helpers.nextItem(points, i)._model,
36042						meta.dataset._model.tension
36043					);
36044					model.controlPointPreviousX = controlPoints.previous.x;
36045					model.controlPointPreviousY = controlPoints.previous.y;
36046					model.controlPointNextX = controlPoints.next.x;
36047					model.controlPointNextY = controlPoints.next.y;
36048				}
36049			}
36050
36051			if (me.chart.options.elements.line.capBezierPoints) {
36052				for (i = 0, ilen = points.length; i < ilen; ++i) {
36053					model = points[i]._model;
36054					model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);
36055					model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);
36056					model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);
36057					model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);
36058				}
36059			}
36060		},
36061
36062		draw: function() {
36063			var me = this;
36064			var chart = me.chart;
36065			var meta = me.getMeta();
36066			var points = meta.data || [];
36067			var area = chart.chartArea;
36068			var ilen = points.length;
36069			var i = 0;
36070
36071			helpers.canvas.clipArea(chart.ctx, area);
36072
36073			if (lineEnabled(me.getDataset(), chart.options)) {
36074				meta.dataset.draw();
36075			}
36076
36077			helpers.canvas.unclipArea(chart.ctx);
36078
36079			// Draw the points
36080			for (; i < ilen; ++i) {
36081				points[i].draw(area);
36082			}
36083		},
36084
36085		setHoverStyle: function(point) {
36086			// Point
36087			var dataset = this.chart.data.datasets[point._datasetIndex];
36088			var index = point._index;
36089			var custom = point.custom || {};
36090			var model = point._model;
36091
36092			model.radius = custom.hoverRadius || helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
36093			model.backgroundColor = custom.hoverBackgroundColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
36094			model.borderColor = custom.hoverBorderColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
36095			model.borderWidth = custom.hoverBorderWidth || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
36096		},
36097
36098		removeHoverStyle: function(point) {
36099			var me = this;
36100			var dataset = me.chart.data.datasets[point._datasetIndex];
36101			var index = point._index;
36102			var custom = point.custom || {};
36103			var model = point._model;
36104
36105			// Compatibility: If the properties are defined with only the old name, use those values
36106			if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
36107				dataset.pointRadius = dataset.radius;
36108			}
36109
36110			model.radius = custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, me.chart.options.elements.point.radius);
36111			model.backgroundColor = me.getPointBackgroundColor(point, index);
36112			model.borderColor = me.getPointBorderColor(point, index);
36113			model.borderWidth = me.getPointBorderWidth(point, index);
36114		}
36115	});
36116};
36117
36118},{"25":25,"40":40,"45":45}],19:[function(require,module,exports){
36119'use strict';
36120
36121var defaults = require(25);
36122var elements = require(40);
36123var helpers = require(45);
36124
36125defaults._set('polarArea', {
36126	scale: {
36127		type: 'radialLinear',
36128		angleLines: {
36129			display: false
36130		},
36131		gridLines: {
36132			circular: true
36133		},
36134		pointLabels: {
36135			display: false
36136		},
36137		ticks: {
36138			beginAtZero: true
36139		}
36140	},
36141
36142	// Boolean - Whether to animate the rotation of the chart
36143	animation: {
36144		animateRotate: true,
36145		animateScale: true
36146	},
36147
36148	startAngle: -0.5 * Math.PI,
36149	legendCallback: function(chart) {
36150		var text = [];
36151		text.push('<ul class="' + chart.id + '-legend">');
36152
36153		var data = chart.data;
36154		var datasets = data.datasets;
36155		var labels = data.labels;
36156
36157		if (datasets.length) {
36158			for (var i = 0; i < datasets[0].data.length; ++i) {
36159				text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
36160				if (labels[i]) {
36161					text.push(labels[i]);
36162				}
36163				text.push('</li>');
36164			}
36165		}
36166
36167		text.push('</ul>');
36168		return text.join('');
36169	},
36170	legend: {
36171		labels: {
36172			generateLabels: function(chart) {
36173				var data = chart.data;
36174				if (data.labels.length && data.datasets.length) {
36175					return data.labels.map(function(label, i) {
36176						var meta = chart.getDatasetMeta(0);
36177						var ds = data.datasets[0];
36178						var arc = meta.data[i];
36179						var custom = arc.custom || {};
36180						var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
36181						var arcOpts = chart.options.elements.arc;
36182						var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
36183						var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
36184						var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
36185
36186						return {
36187							text: label,
36188							fillStyle: fill,
36189							strokeStyle: stroke,
36190							lineWidth: bw,
36191							hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
36192
36193							// Extra data used for toggling the correct item
36194							index: i
36195						};
36196					});
36197				}
36198				return [];
36199			}
36200		},
36201
36202		onClick: function(e, legendItem) {
36203			var index = legendItem.index;
36204			var chart = this.chart;
36205			var i, ilen, meta;
36206
36207			for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
36208				meta = chart.getDatasetMeta(i);
36209				meta.data[index].hidden = !meta.data[index].hidden;
36210			}
36211
36212			chart.update();
36213		}
36214	},
36215
36216	// Need to override these to give a nice default
36217	tooltips: {
36218		callbacks: {
36219			title: function() {
36220				return '';
36221			},
36222			label: function(item, data) {
36223				return data.labels[item.index] + ': ' + item.yLabel;
36224			}
36225		}
36226	}
36227});
36228
36229module.exports = function(Chart) {
36230
36231	Chart.controllers.polarArea = Chart.DatasetController.extend({
36232
36233		dataElementType: elements.Arc,
36234
36235		linkScales: helpers.noop,
36236
36237		update: function(reset) {
36238			var me = this;
36239			var chart = me.chart;
36240			var chartArea = chart.chartArea;
36241			var meta = me.getMeta();
36242			var opts = chart.options;
36243			var arcOpts = opts.elements.arc;
36244			var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
36245			chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
36246			chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
36247			chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
36248
36249			me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);
36250			me.innerRadius = me.outerRadius - chart.radiusLength;
36251
36252			meta.count = me.countVisibleElements();
36253
36254			helpers.each(meta.data, function(arc, index) {
36255				me.updateElement(arc, index, reset);
36256			});
36257		},
36258
36259		updateElement: function(arc, index, reset) {
36260			var me = this;
36261			var chart = me.chart;
36262			var dataset = me.getDataset();
36263			var opts = chart.options;
36264			var animationOpts = opts.animation;
36265			var scale = chart.scale;
36266			var labels = chart.data.labels;
36267
36268			var circumference = me.calculateCircumference(dataset.data[index]);
36269			var centerX = scale.xCenter;
36270			var centerY = scale.yCenter;
36271
36272			// If there is NaN data before us, we need to calculate the starting angle correctly.
36273			// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
36274			var visibleCount = 0;
36275			var meta = me.getMeta();
36276			for (var i = 0; i < index; ++i) {
36277				if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) {
36278					++visibleCount;
36279				}
36280			}
36281
36282			// var negHalfPI = -0.5 * Math.PI;
36283			var datasetStartAngle = opts.startAngle;
36284			var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
36285			var startAngle = datasetStartAngle + (circumference * visibleCount);
36286			var endAngle = startAngle + (arc.hidden ? 0 : circumference);
36287
36288			var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
36289
36290			helpers.extend(arc, {
36291				// Utility
36292				_datasetIndex: me.index,
36293				_index: index,
36294				_scale: scale,
36295
36296				// Desired view properties
36297				_model: {
36298					x: centerX,
36299					y: centerY,
36300					innerRadius: 0,
36301					outerRadius: reset ? resetRadius : distance,
36302					startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
36303					endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
36304					label: helpers.valueAtIndexOrDefault(labels, index, labels[index])
36305				}
36306			});
36307
36308			// Apply border and fill style
36309			me.removeHoverStyle(arc);
36310
36311			arc.pivot();
36312		},
36313
36314		removeHoverStyle: function(arc) {
36315			Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc);
36316		},
36317
36318		countVisibleElements: function() {
36319			var dataset = this.getDataset();
36320			var meta = this.getMeta();
36321			var count = 0;
36322
36323			helpers.each(meta.data, function(element, index) {
36324				if (!isNaN(dataset.data[index]) && !element.hidden) {
36325					count++;
36326				}
36327			});
36328
36329			return count;
36330		},
36331
36332		calculateCircumference: function(value) {
36333			var count = this.getMeta().count;
36334			if (count > 0 && !isNaN(value)) {
36335				return (2 * Math.PI) / count;
36336			}
36337			return 0;
36338		}
36339	});
36340};
36341
36342},{"25":25,"40":40,"45":45}],20:[function(require,module,exports){
36343'use strict';
36344
36345var defaults = require(25);
36346var elements = require(40);
36347var helpers = require(45);
36348
36349defaults._set('radar', {
36350	scale: {
36351		type: 'radialLinear'
36352	},
36353	elements: {
36354		line: {
36355			tension: 0 // no bezier in radar
36356		}
36357	}
36358});
36359
36360module.exports = function(Chart) {
36361
36362	Chart.controllers.radar = Chart.DatasetController.extend({
36363
36364		datasetElementType: elements.Line,
36365
36366		dataElementType: elements.Point,
36367
36368		linkScales: helpers.noop,
36369
36370		update: function(reset) {
36371			var me = this;
36372			var meta = me.getMeta();
36373			var line = meta.dataset;
36374			var points = meta.data;
36375			var custom = line.custom || {};
36376			var dataset = me.getDataset();
36377			var lineElementOptions = me.chart.options.elements.line;
36378			var scale = me.chart.scale;
36379
36380			// Compatibility: If the properties are defined with only the old name, use those values
36381			if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) {
36382				dataset.lineTension = dataset.tension;
36383			}
36384
36385			helpers.extend(meta.dataset, {
36386				// Utility
36387				_datasetIndex: me.index,
36388				_scale: scale,
36389				// Data
36390				_children: points,
36391				_loop: true,
36392				// Model
36393				_model: {
36394					// Appearance
36395					tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension),
36396					backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
36397					borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
36398					borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor),
36399					fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
36400					borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle),
36401					borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash),
36402					borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
36403					borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
36404				}
36405			});
36406
36407			meta.dataset.pivot();
36408
36409			// Update Points
36410			helpers.each(points, function(point, index) {
36411				me.updateElement(point, index, reset);
36412			}, me);
36413
36414			// Update bezier control points
36415			me.updateBezierControlPoints();
36416		},
36417		updateElement: function(point, index, reset) {
36418			var me = this;
36419			var custom = point.custom || {};
36420			var dataset = me.getDataset();
36421			var scale = me.chart.scale;
36422			var pointElementOptions = me.chart.options.elements.point;
36423			var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);
36424
36425			// Compatibility: If the properties are defined with only the old name, use those values
36426			if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) {
36427				dataset.pointRadius = dataset.radius;
36428			}
36429			if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) {
36430				dataset.pointHitRadius = dataset.hitRadius;
36431			}
36432
36433			helpers.extend(point, {
36434				// Utility
36435				_datasetIndex: me.index,
36436				_index: index,
36437				_scale: scale,
36438
36439				// Desired view properties
36440				_model: {
36441					x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
36442					y: reset ? scale.yCenter : pointPosition.y,
36443
36444					// Appearance
36445					tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension),
36446					radius: custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius),
36447					backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroun
36447dColor, index, pointElementOptions.backgroundColor),
36448					borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor),
36449					borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth),
36450					pointStyle: custom.pointStyle ? custom.pointStyle : helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle),
36451
36452					// Tooltip
36453					hitRadius: custom.hitRadius ? custom.hitRadius : helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius)
36454				}
36455			});
36456
36457			point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
36458		},
36459		updateBezierControlPoints: function() {
36460			var chartArea = this.chart.chartArea;
36461			var meta = this.getMeta();
36462
36463			helpers.each(meta.data, function(point, index) {
36464				var model = point._model;
36465				var controlPoints = helpers.splineCurve(
36466					helpers.previousItem(meta.data, index, true)._model,
36467					model,
36468					helpers.nextItem(meta.data, index, true)._model,
36469					model.tension
36470				);
36471
36472				// Prevent the bezier going outside of the bounds of the graph
36473				model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left);
36474				model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top);
36475
36476				model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left);
36477				model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top);
36478
36479				// Now pivot the point for animation
36480				point.pivot();
36481			});
36482		},
36483
36484		setHoverStyle: function(point) {
36485			// Point
36486			var dataset = this.chart.data.datasets[point._datasetIndex];
36487			var custom = point.custom || {};
36488			var index = point._index;
36489			var model = point._model;
36490
36491			model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
36492			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor));
36493			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor));
36494			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth);
36495		},
36496
36497		removeHoverStyle: function(point) {
36498			var dataset = this.chart.data.datasets[point._datasetIndex];
36499			var custom = point.custom || {};
36500			var index = point._index;
36501			var model = point._model;
36502			var pointElementOptions = this.chart.options.elements.point;
36503
36504			model.radius = custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius);
36505			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroun
36505dColor, index, pointElementOptions.backgroundColor);
36506			model.borderColor = custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor);
36507			model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth);
36508		}
36509	});
36510};
36511
36512},{"25":25,"40":40,"45":45}],21:[function(require,module,exports){
36513'use strict';
36514
36515var defaults = require(25);
36516
36517defaults._set('scatter', {
36518	hover: {
36519		mode: 'single'
36520	},
36521
36522	scales: {
36523		xAxes: [{
36524			id: 'x-axis-1',    // need an ID so datasets can reference the scale
36525			type: 'linear',    // scatter should not use a category axis
36526			position: 'bottom'
36527		}],
36528		yAxes: [{
36529			id: 'y-axis-1',
36530			type: 'linear',
36531			position: 'left'
36532		}]
36533	},
36534
36535	showLines: false,
36536
36537	tooltips: {
36538		callbacks: {
36539			title: function() {
36540				return '';     // doesn't make sense for scatter since data are formatted as a point
36541			},
36542			label: function(item) {
36543				return '(' + item.xLabel + ', ' + item.yLabel + ')';
36544			}
36545		}
36546	}
36547});
36548
36549module.exports = function(Chart) {
36550
36551	// Scatter charts use line controllers
36552	Chart.controllers.scatter = Chart.controllers.line;
36553
36554};
36555
36556},{"25":25}],22:[function(require,module,exports){
36557/* global window: false */
36558'use strict';
36559
36560var defaults = require(25);
36561var Element = require(26);
36562var helpers = require(45);
36563
36564defaults._set('global', {
36565	animation: {
36566		duration: 1000,
36567		easing: 'easeOutQuart',
36568		onProgress: helpers.noop,
36569		onComplete: helpers.noop
36570	}
36571});
36572
36573module.exports = function(Chart) {
36574
36575	Chart.Animation = Element.extend({
36576		chart: null, // the animation associated chart instance
36577		currentStep: 0, // the current animation step
36578		numSteps: 60, // default number of steps
36579		easing: '', // the easing to use for this animation
36580		render: null, // render function used by the animation service
36581
36582		onAnimationProgress: null, // user specified callback to fire on each step of the animation
36583		onAnimationComplete: null, // user specified callback to fire when the animation finishes
36584	});
36585
36586	Chart.animationService = {
36587		frameDuration: 17,
36588		animations: [],
36589		dropFrames: 0,
36590		request: null,
36591
36592		/**
36593		 * @param {Chart} chart - The chart to animate.
36594		 * @param {Chart.Animation} animation - The animation that we will animate.
36595		 * @param {Number} duration - The animation duration in ms.
36596		 * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions
36597		 */
36598		addAnimation: function(chart, animation, duration, lazy) {
36599			var animations = this.animations;
36600			var i, ilen;
36601
36602			animation.chart = chart;
36603
36604			if (!lazy) {
36605				chart.animating = true;
36606			}
36607
36608			for (i = 0, ilen = animations.length; i < ilen; ++i) {
36609				if (animations[i].chart === chart) {
36610					animations[i] = animation;
36611					return;
36612				}
36613			}
36614
36615			animations.push(animation);
36616
36617			// If there are no animations queued, manually kickstart a digest, for lack of a better word
36618			if (animations.length === 1) {
36619				this.requestAnimationFrame();
36620			}
36621		},
36622
36623		cancelAnimation: function(chart) {
36624			var index = helpers.findIndex(this.animations, function(animation) {
36625				return animation.chart === chart;
36626			});
36627
36628			if (index !== -1) {
36629				this.animations.splice(index, 1);
36630				chart.animating = false;
36631			}
36632		},
36633
36634		requestAnimationFrame: function() {
36635			var me = this;
36636			if (me.request === null) {
36637				// Skip animation frame requests until the active one is executed.
36638				// This can happen when processing mouse events, e.g. 'mousemove'
36639				// and 'mouseout' events will trigger multiple renders.
36640				me.request = helpers.requestAnimFrame.call(window, function() {
36641					me.request = null;
36642					me.startDigest();
36643				});
36644			}
36645		},
36646
36647		/**
36648		 * @private
36649		 */
36650		startDigest: function() {
36651			var me = this;
36652			var startTime = Date.now();
36653			var framesToDrop = 0;
36654
36655			if (me.dropFrames > 1) {
36656				framesToDrop = Math.floor(me.dropFrames);
36657				me.dropFrames = me.dropFrames % 1;
36658			}
36659
36660			me.advance(1 + framesToDrop);
36661
36662			var endTime = Date.now();
36663
36664			me.dropFrames += (endTime - startTime) / me.frameDuration;
36665
36666			// Do we have more stuff to animate?
36667			if (me.animations.length > 0) {
36668				me.requestAnimationFrame();
36669			}
36670		},
36671
36672		/**
36673		 * @private
36674		 */
36675		advance: function(count) {
36676			var animations = this.animations;
36677			var animation, chart;
36678			var i = 0;
36679
36680			while (i < animations.length) {
36681				animation = animations[i];
36682				chart = animation.chart;
36683
36684				animation.currentStep = (animation.currentStep || 0) + count;
36685				animation.currentStep = Math.min(animation.currentStep, animation.numSteps);
36686
36687				helpers.callback(animation.render, [chart, animation], chart);
36688				helpers.callback(animation.onAnimationProgress, [animation], chart);
36689
36690				if (animation.currentStep >= animation.numSteps) {
36691					helpers.callback(animation.onAnimationComplete, [animation], chart);
36692					chart.animating = false;
36693					animations.splice(i, 1);
36694				} else {
36695					++i;
36696				}
36697			}
36698		}
36699	};
36700
36701	/**
36702	 * Provided for backward compatibility, use Chart.Animation instead
36703	 * @prop Chart.Animation#animationObject
36704	 * @deprecated since version 2.6.0
36705	 * @todo remove at version 3
36706	 */
36707	Object.defineProperty(Chart.Animation.prototype, 'animationObject', {
36708		get: function() {
36709			return this;
36710		}
36711	});
36712
36713	/**
36714	 * Provided for backward compatibility, use Chart.Animation#chart instead
36715	 * @prop Chart.Animation#chartInstance
36716	 * @deprecated since version 2.6.0
36717	 * @todo remove at version 3
36718	 */
36719	Object.defineProperty(Chart.Animation.prototype, 'chartInstance', {
36720		get: function() {
36721			return this.chart;
36722		},
36723		set: function(value) {
36724			this.chart = value;
36725		}
36726	});
36727
36728};
36729
36730},{"25":25,"26":26,"45":45}],23:[function(require,module,exports){
36731'use strict';
36732
36733var defaults = require(25);
36734var helpers = require(45);
36735var Interaction = require(28);
36736var layouts = require(30);
36737var platform = require(48);
36738var plugins = require(31);
36739
36740module.exports = function(Chart) {
36741
36742	// Create a dictionary of chart types, to allow for extension of existing types
36743	Chart.types = {};
36744
36745	// Store a reference to each instance - allowing us to globally resize chart instances on window resize.
36746	// Destroy method on the chart will remove the instance of the chart from this reference.
36747	Chart.instances = {};
36748
36749	// Controllers available for dataset visualization eg. bar, line, slice, etc.
36750	Chart.controllers = {};
36751
36752	/**
36753	 * Initializes the given config with global and chart default values.
36754	 */
36755	function initConfig(config) {
36756		config = config || {};
36757
36758		// Do NOT use configMerge() for the data object because this method merges arrays
36759		// and so would change references to labels and datasets, preventing data updates.
36760		var data = config.data = config.data || {};
36761		data.datasets = data.datasets || [];
36762		data.labels = data.labels || [];
36763
36764		config.options = helpers.configMerge(
36765			defaults.global,
36766			defaults[config.type],
36767			config.options || {});
36768
36769		return config;
36770	}
36771
36772	/**
36773	 * Updates the config of the chart
36774	 * @param chart {Chart} chart to update the options for
36775	 */
36776	function updateConfig(chart) {
36777		var newOptions = chart.options;
36778
36779		helpers.each(chart.scales, function(scale) {
36780			layouts.removeBox(chart, scale);
36781		});
36782
36783		newOptions = helpers.configMerge(
36784			Chart.defaults.global,
36785			Chart.defaults[chart.config.type],
36786			newOptions);
36787
36788		chart.options = chart.config.options = newOptions;
36789		chart.ensureScalesHaveIDs();
36790		chart.buildOrUpdateScales();
36791		// Tooltip
36792		chart.tooltip._options = newOptions.tooltips;
36793		chart.tooltip.initialize();
36794	}
36795
36796	function positionIsHorizontal(position) {
36797		return position === 'top' || position === 'bottom';
36798	}
36799
36800	helpers.extend(Chart.prototype, /** @lends Chart */ {
36801		/**
36802		 * @private
36803		 */
36804		construct: function(item, config) {
36805			var me = this;
36806
36807			config = initConfig(config);
36808
36809			var context = platform.acquireContext(item, config);
36810			var canvas = context && context.canvas;
36811			var height = canvas && canvas.height;
36812			var width = canvas && canvas.width;
36813
36814			me.id = helpers.uid();
36815			me.ctx = context;
36816			me.canvas = canvas;
36817			me.config = config;
36818			me.width = width;
36819			me.height = height;
36820			me.aspectRatio = height ? width / height : null;
36821			me.options = config.options;
36822			me._bufferedRender = false;
vendor: 10,788 bytes, lines 36823-37221
36823
36824			/**
36825			 * Provided for backward compatibility, Chart and Chart.Controller have been merged,
36826			 * the "instance" still need to be defined since it might be called from plugins.
36827			 * @prop Chart#chart
36828			 * @deprecated since version 2.6.0
36829			 * @todo remove at version 3
36830			 * @private
36831			 */
36832			me.chart = me;
36833			me.controller = me; // chart.chart.controller #inception
36834
36835			// Add the chart instance to the global namespace
36836			Chart.instances[me.id] = me;
36837
36838			// Define alias to the config data: `chart.data === chart.config.data`
36839			Object.defineProperty(me, 'data', {
36840				get: function() {
36841					return me.config.data;
36842				},
36843				set: function(value) {
36844					me.config.data = value;
36845				}
36846			});
36847
36848			if (!context || !canvas) {
36849				// The given item is not a compatible context2d element, let's return before finalizing
36850				// the chart initialization but after setting basic chart / controller properties that
36851				// can help to figure out that the chart is not valid (e.g chart.canvas !== null);
36852				// https://github.com/chartjs/Chart.js/issues/2807
36853				console.error("Failed to create chart: can't acquire context from the given item");
36854				return;
36855			}
36856
36857			me.initialize();
36858			me.update();
36859		},
36860
36861		/**
36862		 * @private
36863		 */
36864		initialize: function() {
36865			var me = this;
36866
36867			// Before init plugin notification
36868			plugins.notify(me, 'beforeInit');
36869
36870			helpers.retinaScale(me, me.options.devicePixelRatio);
36871
36872			me.bindEvents();
36873
36874			if (me.options.responsive) {
36875				// Initial resize before chart draws (must be silent to preserve initial animations).
36876				me.resize(true);
36877			}
36878
36879			// Make sure scales have IDs and are built before we build any controllers.
36880			me.ensureScalesHaveIDs();
36881			me.buildOrUpdateScales();
36882			me.initToolTip();
36883
36884			// After init plugin notification
36885			plugins.notify(me, 'afterInit');
36886
36887			return me;
36888		},
36889
36890		clear: function() {
36891			helpers.canvas.clear(this);
36892			return this;
36893		},
36894
36895		stop: function() {
36896			// Stops any current animation loop occurring
36897			Chart.animationService.cancelAnimation(this);
36898			return this;
36899		},
36900
36901		resize: function(silent) {
36902			var me = this;
36903			var options = me.options;
36904			var canvas = me.canvas;
36905			var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;
36906
36907			// the canvas render width and height will be casted to integers so make sure that
36908			// the canvas display style uses the same integer values to avoid blurring effect.
36909
36910			// Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collased
36911			var newWidth = Math.max(0, Math.floor(helpers.getMaximumWidth(canvas)));
36912			var newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas)));
36913
36914			if (me.width === newWidth && me.height === newHeight) {
36915				return;
36916			}
36917
36918			canvas.width = me.width = newWidth;
36919			canvas.height = me.height = newHeight;
36920			canvas.style.width = newWidth + 'px';
36921			canvas.style.height = newHeight + 'px';
36922
36923			helpers.retinaScale(me, options.devicePixelRatio);
36924
36925			if (!silent) {
36926				// Notify any plugins about the resize
36927				var newSize = {width: newWidth, height: newHeight};
36928				plugins.notify(me, 'resize', [newSize]);
36929
36930				// Notify of resize
36931				if (me.options.onResize) {
36932					me.options.onResize(me, newSize);
36933				}
36934
36935				me.stop();
36936				me.update(me.options.responsiveAnimationDuration);
36937			}
36938		},
36939
36940		ensureScalesHaveIDs: function() {
36941			var options = this.options;
36942			var scalesOptions = options.scales || {};
36943			var scaleOptions = options.scale;
36944
36945			helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) {
36946				xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index);
36947			});
36948
36949			helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) {
36950				yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index);
36951			});
36952
36953			if (scaleOptions) {
36954				scaleOptions.id = scaleOptions.id || 'scale';
36955			}
36956		},
36957
36958		/**
36959		 * Builds a map of scale ID to scale object for future lookup.
36960		 */
36961		buildOrUpdateScales: function() {
36962			var me = this;
36963			var options = me.options;
36964			var scales = me.scales || {};
36965			var items = [];
36966			var updated = Object.keys(scales).reduce(function(obj, id) {
36967				obj[id] = false;
36968				return obj;
36969			}, {});
36970
36971			if (options.scales) {
36972				items = items.concat(
36973					(options.scales.xAxes || []).map(function(xAxisOptions) {
36974						return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};
36975					}),
36976					(options.scales.yAxes || []).map(function(yAxisOptions) {
36977						return {options: yAxisOptions, dtype: 'linear', dposition: 'left'};
36978					})
36979				);
36980			}
36981
36982			if (options.scale) {
36983				items.push({
36984					options: options.scale,
36985					dtype: 'radialLinear',
36986					isDefault: true,
36987					dposition: 'chartArea'
36988				});
36989			}
36990
36991			helpers.each(items, function(item) {
36992				var scaleOptions = item.options;
36993				var id = scaleOptions.id;
36994				var scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype);
36995
36996				if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
36997					scaleOptions.position = item.dposition;
36998				}
36999
37000				updated[id] = true;
37001				var scale = null;
37002				if (id in scales && scales[id].type === scaleType) {
37003					scale = scales[id];
37004					scale.options = scaleOptions;
37005					scale.ctx = me.ctx;
37006					scale.chart = me;
37007				} else {
37008					var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
37009					if (!scaleClass) {
37010						return;
37011					}
37012					scale = new scaleClass({
37013						id: id,
37014						type: scaleType,
37015						options: scaleOptions,
37016						ctx: me.ctx,
37017						chart: me
37018					});
37019					scales[scale.id] = scale;
37020				}
37021
37022				scale.mergeTicksOptions();
37023
37024				// TODO(SB): I think we should be able to remove this custom case (options.scale)
37025				// and consider it as a regular scale part of the "scales"" map only! This would
37026				// make the logic easier and remove some useless? custom code.
37027				if (item.isDefault) {
37028					me.scale = scale;
37029				}
37030			});
37031			// clear up discarded scales
37032			helpers.each(updated, function(hasUpdated, id) {
37033				if (!hasUpdated) {
37034					delete scales[id];
37035				}
37036			});
37037
37038			me.scales = scales;
37039
37040			Chart.scaleService.addScalesToLayout(this);
37041		},
37042
37043		buildOrUpdateControllers: function() {
37044			var me = this;
37045			var types = [];
37046			var newControllers = [];
37047
37048			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
37049				var meta = me.getDatasetMeta(datasetIndex);
37050				var type = dataset.type || me.config.type;
37051
37052				if (meta.type && meta.type !== type) {
37053					me.destroyDatasetMeta(datasetIndex);
37054					meta = me.getDatasetMeta(datasetIndex);
37055				}
37056				meta.type = type;
37057
37058				types.push(meta.type);
37059
37060				if (meta.controller) {
37061					meta.controller.updateIndex(datasetIndex);
37062					meta.controller.linkScales();
37063				} else {
37064					var ControllerClass = Chart.controllers[meta.type];
37065					if (ControllerClass === undefined) {
37066						throw new Error('"' + meta.type + '" is not a chart type.');
37067					}
37068
37069					meta.controller = new ControllerClass(me, datasetIndex);
37070					newControllers.push(meta.controller);
37071				}
37072			}, me);
37073
37074			return newControllers;
37075		},
37076
37077		/**
37078		 * Reset the elements of all datasets
37079		 * @private
37080		 */
37081		resetElements: function() {
37082			var me = this;
37083			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
37084				me.getDatasetMeta(datasetIndex).controller.reset();
37085			}, me);
37086		},
37087
37088		/**
37089		* Resets the chart back to it's state before the initial animation
37090		*/
37091		reset: function() {
37092			this.resetElements();
37093			this.tooltip.initialize();
37094		},
37095
37096		update: function(config) {
37097			var me = this;
37098
37099			if (!config || typeof config !== 'object') {
37100				// backwards compatibility
37101				config = {
37102					duration: config,
37103					lazy: arguments[1]
37104				};
37105			}
37106
37107			updateConfig(me);
37108
37109			// plugins options references might have change, let's invalidate the cache
37110			// https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
37111			plugins._invalidate(me);
37112
37113			if (plugins.notify(me, 'beforeUpdate') === false) {
37114				return;
37115			}
37116
37117			// In case the entire data object changed
37118			me.tooltip._data = me.data;
37119
37120			// Make sure dataset controllers are updated and new controllers are reset
37121			var newControllers = me.buildOrUpdateControllers();
37122
37123			// Make sure all dataset controllers have correct meta data counts
37124			helpers.each(me.data.datasets, function(dataset, datasetIndex) {
37125				me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
37126			}, me);
37127
37128			me.updateLayout();
37129
37130			// Can only reset the new controllers after the scales have been updated
37131			if (me.options.animation && me.options.animation.duration) {
37132				helpers.each(newControllers, function(controller) {
37133					controller.reset();
37134				});
37135			}
37136
37137			me.updateDatasets();
37138
37139			// Need to reset tooltip in case it is displayed with elements that are removed
37140			// after update.
37141			me.tooltip.initialize();
37142
37143			// Last active contains items that were previously in the tooltip.
37144			// When we reset the tooltip, we need to clear it
37145			me.lastActive = [];
37146
37147			// Do this before render so that any plugins that need final scale updates can use it
37148			plugins.notify(me, 'afterUpdate');
37149
37150			if (me._bufferedRender) {
37151				me._bufferedRequest = {
37152					duration: config.duration,
37153					easing: config.easing,
37154					lazy: config.lazy
37155				};
37156			} else {
37157				me.render(config);
37158			}
37159		},
37160
37161		/**
37162		 * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`
37163		 * hook, in which case, plugins will not be called on `afterLayout`.
37164		 * @private
37165		 */
37166		updateLayout: function() {
37167			var me = this;
37168
37169			if (plugins.notify(me, 'beforeLayout') === false) {
37170				return;
37171			}
37172
37173			layouts.update(this, this.width, this.height);
37174
37175			/**
37176			 * Provided for backward compatibility, use `afterLayout` instead.
37177			 * @method IPlugin#afterScaleUpdate
37178			 * @deprecated since version 2.5.0
37179			 * @todo remove at version 3
37180			 * @private
37181			 */
37182			plugins.notify(me, 'afterScaleUpdate');
37183			plugins.notify(me, 'afterLayout');
37184		},
37185
37186		/**
37187		 * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`
37188		 * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.
37189		 * @private
37190		 */
37191		updateDatasets: function() {
37192			var me = this;
37193
37194			if (plugins.notify(me, 'beforeDatasetsUpdate') === false) {
37195				return;
37196			}
37197
37198			for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
37199				me.updateDataset(i);
37200			}
37201
37202			plugins.notify(me, 'afterDatasetsUpdate');
37203		},
37204
37205		/**
37206		 * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`
37207		 * hook, in which case, plugins will not be called on `afterDatasetUpdate`.
37208		 * @private
37209		 */
37210		updateDataset: function(index) {
37211			var me = this;
37212			var meta = me.getDatasetMeta(index);
37213			var args = {
37214				meta: meta,
37215				index: index
37216			};
37217
37218			if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {
37219				return;
37220			}
37221
37222			meta.controller.update();
37223
37224			plugins.notify(me, 'afterDatasetUpdate', [args]);
37225		},
37226
37227		render: function(config) {
37228			var me = this;
37229
37230			if (!config || typeof config !== 'object') {
37231				// backwards compatibility
37232				config = {
37233					duration: config,
37234					lazy: arguments[1]
37235				};
37236			}
37237
37238			var duration = config.duration;
37239			var lazy = config.lazy;
37240
37241			if (plugins.notify(me, 'beforeRender') === false) {
37242				return;
37243			}
37244
37245			var animationOptions = me.options.animation;
37246			var onComplete = function(animation) {
37247				plugins.notify(me, 'afterRender');
37248				helpers.callback(animationOptions && animationOptions.onComplete, [animation], me);
37249			};
37250
37251			if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) {
37252				var animation = new Chart.Animation({
37253					numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps
37254					easing: config.easing || animationOptions.easing,
37255
37256					render: function(chart, animationObject) {
37257						var easingFunction = helpers.easing.effects[animationObject.easing];
37258						var currentStep = animationObject.currentStep;
37259						var stepDecimal = currentStep / animationObject.numSteps;
37260
37261						chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);
37262					},
37263
37264					onAnimationProgress: animationOptions.onProgress,
37265					onAnimationComplete: onComplete
37266				});
37267
37268				Chart.animationService.addAnimation(me, animation, duration, lazy);
37269			} else {
37270				me.draw();
37271
37272				// See https://github.com/chartjs/Chart.js/issues/3781
37273				onComplete(new Chart.Animation({numSteps: 0, chart: me}));
37274			}
37275
37276			return me;
37277		},
37278
37279		draw: function(easingValue) {
37280			var me = this;
37281
37282			me.clear();
37283
37284			if (helpers.isNullOrUndef(easingValue)) {
37285				easingValue = 1;
37286			}
37287
37288			me.transition(easingValue);
37289
37290			if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) {
37291				return;
37292			}
37293
37294			// Draw all the scales
37295			helpers.each(me.boxes, function(box) {
37296				box.draw(me.chartArea);
37297			}, me);
37298
37299			if (me.scale) {
37300				me.scale.draw();
37301			}
37302
37303			me.drawDatasets(easingValue);
37304			me._drawTooltip(easingValue);
37305
37306			plugins.notify(me, 'afterDraw', [easingValue]);
37307		},
37308
37309		/**
37310		 * @private
37311		 */
37312		transition: function(easingValue) {
37313			var me = this;
37314
37315			for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) {
37316				if (me.isDatasetVisible(i)) {
37317					me.getDatasetMeta(i).controller.transition(easingValue);
37318				}
37319			}
37320
37321			me.tooltip.transition(easingValue);
37322		},
37323
37324		/**
37325		 * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
37326		 * hook, in which case, plugins will not be called on `afterDatasetsDraw`.
37327		 * @private
37328		 */
37329		drawDatasets: function(easingValue) {
37330			var me = this;
37331
37332			if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
37333				return;
37334			}
37335
37336			// Draw datasets reversed to support proper line stacking
37337			for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) {
37338				if (me.isDatasetVisible(i)) {
37339					me.drawDataset(i, easingValue);
37340				}
37341			}
37342
37343			plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
37344		},
37345
37346		/**
37347		 * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`
37348		 * hook, in which case, plugins will not be called on `afterDatasetDraw`.
37349		 * @private
37350		 */
37351		drawDataset: function(index, easingValue) {
37352			var me = this;
37353			var meta = me.getDatasetMeta(index);
37354			var args = {
37355				meta: meta,
37356				index: index,
37357				easingValue: easingValue
37358			};
37359
37360			if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {
37361				return;
37362			}
37363
37364			meta.controller.draw(easingValue);
37365
37366			plugins.notify(me, 'afterDatasetDraw', [args]);
37367		},
37368
37369		/**
37370		 * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw`
37371		 * hook, in which case, plugins will not be called on `afterTooltipDraw`.
37372		 * @private
37373		 */
37374		_drawTooltip: function(easingValue) {
37375			var me = this;
37376			var tooltip = me.tooltip;
37377			var args = {
37378				tooltip: tooltip,
37379				easingValue: easingValue
37380			};
37381
37382			if (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) {
37383				return;
37384			}
37385
37386			tooltip.draw();
37387
37388			plugins.notify(me, 'afterTooltipDraw', [args]);
37389		},
37390
37391		// Get the single element that was clicked on
vendor: 45,871 bytes, lines 37392-38996
37392		// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
37393		getElementAtEvent: function(e) {
37394			return Interaction.modes.single(this, e);
37395		},
37396
37397		getElementsAtEvent: function(e) {
37398			return Interaction.modes.label(this, e, {intersect: true});
37399		},
37400
37401		getElementsAtXAxis: function(e) {
37402			return Interaction.modes['x-axis'](this, e, {intersect: true});
37403		},
37404
37405		getElementsAtEventForMode: function(e, mode, options) {
37406			var method = Interaction.modes[mode];
37407			if (typeof method === 'function') {
37408				return method(this, e, options);
37409			}
37410
37411			return [];
37412		},
37413
37414		getDatasetAtEvent: function(e) {
37415			return Interaction.modes.dataset(this, e, {intersect: true});
37416		},
37417
37418		getDatasetMeta: function(datasetIndex) {
37419			var me = this;
37420			var dataset = me.data.datasets[datasetIndex];
37421			if (!dataset._meta) {
37422				dataset._meta = {};
37423			}
37424
37425			var meta = dataset._meta[me.id];
37426			if (!meta) {
37427				meta = dataset._meta[me.id] = {
37428					type: null,
37429					data: [],
37430					dataset: null,
37431					controller: null,
37432					hidden: null,			// See isDatasetVisible() comment
37433					xAxisID: null,
37434					yAxisID: null
37435				};
37436			}
37437
37438			return meta;
37439		},
37440
37441		getVisibleDatasetCount: function() {
37442			var count = 0;
37443			for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
37444				if (this.isDatasetVisible(i)) {
37445					count++;
37446				}
37447			}
37448			return count;
37449		},
37450
37451		isDatasetVisible: function(datasetIndex) {
37452			var meta = this.getDatasetMeta(datasetIndex);
37453
37454			// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
37455			// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
37456			return typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
37457		},
37458
37459		generateLegend: function() {
37460			return this.options.legendCallback(this);
37461		},
37462
37463		/**
37464		 * @private
37465		 */
37466		destroyDatasetMeta: function(datasetIndex) {
37467			var id = this.id;
37468			var dataset = this.data.datasets[datasetIndex];
37469			var meta = dataset._meta && dataset._meta[id];
37470
37471			if (meta) {
37472				meta.controller.destroy();
37473				delete dataset._meta[id];
37474			}
37475		},
37476
37477		destroy: function() {
37478			var me = this;
37479			var canvas = me.canvas;
37480			var i, ilen;
37481
37482			me.stop();
37483
37484			// dataset controllers need to cleanup associated data
37485			for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
37486				me.destroyDatasetMeta(i);
37487			}
37488
37489			if (canvas) {
37490				me.unbindEvents();
37491				helpers.canvas.clear(me);
37492				platform.releaseContext(me.ctx);
37493				me.canvas = null;
37494				me.ctx = null;
37495			}
37496
37497			plugins.notify(me, 'destroy');
37498
37499			delete Chart.instances[me.id];
37500		},
37501
37502		toBase64Image: function() {
37503			return this.canvas.toDataURL.apply(this.canvas, arguments);
37504		},
37505
37506		initToolTip: function() {
37507			var me = this;
37508			me.tooltip = new Chart.Tooltip({
37509				_chart: me,
37510				_chartInstance: me, // deprecated, backward compatibility
37511				_data: me.data,
37512				_options: me.options.tooltips
37513			}, me);
37514		},
37515
37516		/**
37517		 * @private
37518		 */
37519		bindEvents: function() {
37520			var me = this;
37521			var listeners = me._listeners = {};
37522			var listener = function() {
37523				me.eventHandler.apply(me, arguments);
37524			};
37525
37526			helpers.each(me.options.events, function(type) {
37527				platform.addEventListener(me, type, listener);
37528				listeners[type] = listener;
37529			});
37530
37531			// Elements used to detect size change should not be injected for non responsive charts.
37532			// See https://github.com/chartjs/Chart.js/issues/2210
37533			if (me.options.responsive) {
37534				listener = function() {
37535					me.resize();
37536				};
37537
37538				platform.addEventListener(me, 'resize', listener);
37539				listeners.resize = listener;
37540			}
37541		},
37542
37543		/**
37544		 * @private
37545		 */
37546		unbindEvents: function() {
37547			var me = this;
37548			var listeners = me._listeners;
37549			if (!listeners) {
37550				return;
37551			}
37552
37553			delete me._listeners;
37554			helpers.each(listeners, function(listener, type) {
37555				platform.removeEventListener(me, type, listener);
37556			});
37557		},
37558
37559		updateHoverStyle: function(elements, mode, enabled) {
37560			var method = enabled ? 'setHoverStyle' : 'removeHoverStyle';
37561			var element, i, ilen;
37562
37563			for (i = 0, ilen = elements.length; i < ilen; ++i) {
37564				element = elements[i];
37565				if (element) {
37566					this.getDatasetMeta(element._datasetIndex).controller[method](element);
37567				}
37568			}
37569		},
37570
37571		/**
37572		 * @private
37573		 */
37574		eventHandler: function(e) {
37575			var me = this;
37576			var tooltip = me.tooltip;
37577
37578			if (plugins.notify(me, 'beforeEvent', [e]) === false) {
37579				return;
37580			}
37581
37582			// Buffer any update calls so that renders do not occur
37583			me._bufferedRender = true;
37584			me._bufferedRequest = null;
37585
37586			var changed = me.handleEvent(e);
37587			// for smooth tooltip animations issue #4989
37588			// the tooltip should be the source of change
37589			// Animation check workaround:
37590			// tooltip._start will be null when tooltip isn't animating
37591			if (tooltip) {
37592				changed = tooltip._start
37593					? tooltip.handleEvent(e)
37594					: changed | tooltip.handleEvent(e);
37595			}
37596
37597			plugins.notify(me, 'afterEvent', [e]);
37598
37599			var bufferedRequest = me._bufferedRequest;
37600			if (bufferedRequest) {
37601				// If we have an update that was triggered, we need to do a normal render
37602				me.render(bufferedRequest);
37603			} else if (changed && !me.animating) {
37604				// If entering, leaving, or changing elements, animate the change via pivot
37605				me.stop();
37606
37607				// We only need to render at this point. Updating will cause scales to be
37608				// recomputed generating flicker & using more memory than necessary.
37609				me.render(me.options.hover.animationDuration, true);
37610			}
37611
37612			me._bufferedRender = false;
37613			me._bufferedRequest = null;
37614
37615			return me;
37616		},
37617
37618		/**
37619		 * Handle an event
37620		 * @private
37621		 * @param {IEvent} event the event to handle
37622		 * @return {Boolean} true if the chart needs to re-render
37623		 */
37624		handleEvent: function(e) {
37625			var me = this;
37626			var options = me.options || {};
37627			var hoverOptions = options.hover;
37628			var changed = false;
37629
37630			me.lastActive = me.lastActive || [];
37631
37632			// Find Active Elements for hover and tooltips
37633			if (e.type === 'mouseout') {
37634				me.active = [];
37635			} else {
37636				me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
37637			}
37638
37639			// Invoke onHover hook
37640			// Need to call with native event here to not break backwards compatibility
37641			helpers.callback(options.onHover || options.hover.onHover, [e.native, me.active], me);
37642
37643			if (e.type === 'mouseup' || e.type === 'click') {
37644				if (options.onClick) {
37645					// Use e.native here for backwards compatibility
37646					options.onClick.call(me, e.native, me.active);
37647				}
37648			}
37649
37650			// Remove styling for last active (even if it may still be active)
37651			if (me.lastActive.length) {
37652				me.updateHoverStyle(me.lastActive, hoverOptions.mode, false);
37653			}
37654
37655			// Built in hover styling
37656			if (me.active.length && hoverOptions.mode) {
37657				me.updateHoverStyle(me.active, hoverOptions.mode, true);
37658			}
37659
37660			changed = !helpers.arrayEquals(me.active, me.lastActive);
37661
37662			// Remember Last Actives
37663			me.lastActive = me.active;
37664
37665			return changed;
37666		}
37667	});
37668
37669	/**
37670	 * Provided for backward compatibility, use Chart instead.
37671	 * @class Chart.Controller
37672	 * @deprecated since version 2.6.0
37673	 * @todo remove at version 3
37674	 * @private
37675	 */
37676	Chart.Controller = Chart;
37677};
37678
37679},{"25":25,"28":28,"30":30,"31":31,"45":45,"48":48}],24:[function(require,module,exports){
37680'use strict';
37681
37682var helpers = require(45);
37683
37684module.exports = function(Chart) {
37685
37686	var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
37687
37688	/**
37689	 * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
37690	 * 'unshift') and notify the listener AFTER the array has been altered. Listeners are
37691	 * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
37692	 */
37693	function listenArrayEvents(array, listener) {
37694		if (array._chartjs) {
37695			array._chartjs.listeners.push(listener);
37696			return;
37697		}
37698
37699		Object.defineProperty(array, '_chartjs', {
37700			configurable: true,
37701			enumerable: false,
37702			value: {
37703				listeners: [listener]
37704			}
37705		});
37706
37707		arrayEvents.forEach(function(key) {
37708			var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
37709			var base = array[key];
37710
37711			Object.defineProperty(array, key, {
37712				configurable: true,
37713				enumerable: false,
37714				value: function() {
37715					var args = Array.prototype.slice.call(arguments);
37716					var res = base.apply(this, args);
37717
37718					helpers.each(array._chartjs.listeners, function(object) {
37719						if (typeof object[method] === 'function') {
37720							object[method].apply(object, args);
37721						}
37722					});
37723
37724					return res;
37725				}
37726			});
37727		});
37728	}
37729
37730	/**
37731	 * Removes the given array event listener and cleanup extra attached properties (such as
37732	 * the _chartjs stub and overridden methods) if array doesn't have any more listeners.
37733	 */
37734	function unlistenArrayEvents(array, listener) {
37735		var stub = array._chartjs;
37736		if (!stub) {
37737			return;
37738		}
37739
37740		var listeners = stub.listeners;
37741		var index = listeners.indexOf(listener);
37742		if (index !== -1) {
37743			listeners.splice(index, 1);
37744		}
37745
37746		if (listeners.length > 0) {
37747			return;
37748		}
37749
37750		arrayEvents.forEach(function(key) {
37751			delete array[key];
37752		});
37753
37754		delete array._chartjs;
37755	}
37756
37757	// Base class for all dataset controllers (line, bar, etc)
37758	Chart.DatasetController = function(chart, datasetIndex) {
37759		this.initialize(chart, datasetIndex);
37760	};
37761
37762	helpers.extend(Chart.DatasetController.prototype, {
37763
37764		/**
37765		 * Element type used to generate a meta dataset (e.g. Chart.element.Line).
37766		 * @type {Chart.core.element}
37767		 */
37768		datasetElementType: null,
37769
37770		/**
37771		 * Element type used to generate a meta data (e.g. Chart.element.Point).
37772		 * @type {Chart.core.element}
37773		 */
37774		dataElementType: null,
37775
37776		initialize: function(chart, datasetIndex) {
37777			var me = this;
37778			me.chart = chart;
37779			me.index = datasetIndex;
37780			me.linkScales();
37781			me.addElements();
37782		},
37783
37784		updateIndex: function(datasetIndex) {
37785			this.index = datasetIndex;
37786		},
37787
37788		linkScales: function() {
37789			var me = this;
37790			var meta = me.getMeta();
37791			var dataset = me.getDataset();
37792
37793			if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) {
37794				meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id;
37795			}
37796			if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) {
37797				meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id;
37798			}
37799		},
37800
37801		getDataset: function() {
37802			return this.chart.data.datasets[this.index];
37803		},
37804
37805		getMeta: function() {
37806			return this.chart.getDatasetMeta(this.index);
37807		},
37808
37809		getScaleForId: function(scaleID) {
37810			return this.chart.scales[scaleID];
37811		},
37812
37813		reset: function() {
37814			this.update(true);
37815		},
37816
37817		/**
37818		 * @private
37819		 */
37820		destroy: function() {
37821			if (this._data) {
37822				unlistenArrayEvents(this._data, this);
37823			}
37824		},
37825
37826		createMetaDataset: function() {
37827			var me = this;
37828			var type = me.datasetElementType;
37829			return type && new type({
37830				_chart: me.chart,
37831				_datasetIndex: me.index
37832			});
37833		},
37834
37835		createMetaData: function(index) {
37836			var me = this;
37837			var type = me.dataElementType;
37838			return type && new type({
37839				_chart: me.chart,
37840				_datasetIndex: me.index,
37841				_index: index
37842			});
37843		},
37844
37845		addElements: function() {
37846			var me = this;
37847			var meta = me.getMeta();
37848			var data = me.getDataset().data || [];
37849			var metaData = meta.data;
37850			var i, ilen;
37851
37852			for (i = 0, ilen = data.length; i < ilen; ++i) {
37853				metaData[i] = metaData[i] || me.createMetaData(i);
37854			}
37855
37856			meta.dataset = meta.dataset || me.createMetaDataset();
37857		},
37858
37859		addElementAndReset: function(index) {
37860			var element = this.createMetaData(index);
37861			this.getMeta().data.splice(index, 0, element);
37862			this.updateElement(element, index, true);
37863		},
37864
37865		buildOrUpdateElements: function() {
37866			var me = this;
37867			var dataset = me.getDataset();
37868			var data = dataset.data || (dataset.data = []);
37869
37870			// In order to correctly handle data addition/deletion animation (an thus simulate
37871			// real-time charts), we need to monitor these data modifications and synchronize
37872			// the internal meta data accordingly.
37873			if (me._data !== data) {
37874				if (me._data) {
37875					// This case happens when the user replaced the data array instance.
37876					unlistenArrayEvents(me._data, me);
37877				}
37878
37879				listenArrayEvents(data, me);
37880				me._data = data;
37881			}
37882
37883			// Re-sync meta data in case the user replaced the data array or if we missed
37884			// any updates and so make sure that we handle number of datapoints changing.
37885			me.resyncElements();
37886		},
37887
37888		update: helpers.noop,
37889
37890		transition: function(easingValue) {
37891			var meta = this.getMeta();
37892			var elements = meta.data || [];
37893			var ilen = elements.length;
37894			var i = 0;
37895
37896			for (; i < ilen; ++i) {
37897				elements[i].transition(easingValue);
37898			}
37899
37900			if (meta.dataset) {
37901				meta.dataset.transition(easingValue);
37902			}
37903		},
37904
37905		draw: function() {
37906			var meta = this.getMeta();
37907			var elements = meta.data || [];
37908			var ilen = elements.length;
37909			var i = 0;
37910
37911			if (meta.dataset) {
37912				meta.dataset.draw();
37913			}
37914
37915			for (; i < ilen; ++i) {
37916				elements[i].draw();
37917			}
37918		},
37919
37920		removeHoverStyle: function(element, elementOpts) {
37921			var dataset = this.chart.data.datasets[element._datasetIndex];
37922			var index = element._index;
37923			var custom = element.custom || {};
37924			var valueOrDefault = helpers.valueAtIndexOrDefault;
37925			var model = element._model;
37926
37927			model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
37928			model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
37929			model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
37930		},
37931
37932		setHoverStyle: function(element) {
37933			var dataset = this.chart.data.datasets[element._datasetIndex];
37934			var index = element._index;
37935			var custom = element.custom || {};
37936			var valueOrDefault = helpers.valueAtIndexOrDefault;
37937			var getHoverColor = helpers.getHoverColor;
37938			var model = element._model;
37939
37940			model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
37941			model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
37942			model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
37943		},
37944
37945		/**
37946		 * @private
37947		 */
37948		resyncElements: function() {
37949			var me = this;
37950			var meta = me.getMeta();
37951			var data = me.getDataset().data;
37952			var numMeta = meta.data.length;
37953			var numData = data.length;
37954
37955			if (numData < numMeta) {
37956				meta.data.splice(numData, numMeta - numData);
37957			} else if (numData > numMeta) {
37958				me.insertElements(numMeta, numData - numMeta);
37959			}
37960		},
37961
37962		/**
37963		 * @private
37964		 */
37965		insertElements: function(start, count) {
37966			for (var i = 0; i < count; ++i) {
37967				this.addElementAndReset(start + i);
37968			}
37969		},
37970
37971		/**
37972		 * @private
37973		 */
37974		onDataPush: function() {
37975			this.insertElements(this.getDataset().data.length - 1, arguments.length);
37976		},
37977
37978		/**
37979		 * @private
37980		 */
37981		onDataPop: function() {
37982			this.getMeta().data.pop();
37983		},
37984
37985		/**
37986		 * @private
37987		 */
37988		onDataShift: function() {
37989			this.getMeta().data.shift();
37990		},
37991
37992		/**
37993		 * @private
37994		 */
37995		onDataSplice: function(start, count) {
37996			this.getMeta().data.splice(start, count);
37997			this.insertElements(start, arguments.length - 2);
37998		},
37999
38000		/**
38001		 * @private
38002		 */
38003		onDataUnshift: function() {
38004			this.insertElements(0, arguments.length);
38005		}
38006	});
38007
38008	Chart.DatasetController.extend = helpers.inherits;
38009};
38010
38011},{"45":45}],25:[function(require,module,exports){
38012'use strict';
38013
38014var helpers = require(45);
38015
38016module.exports = {
38017	/**
38018	 * @private
38019	 */
38020	_set: function(scope, values) {
38021		return helpers.merge(this[scope] || (this[scope] = {}), values);
38022	}
38023};
38024
38025},{"45":45}],26:[function(require,module,exports){
38026'use strict';
38027
38028var color = require(3);
38029var helpers = require(45);
38030
38031function interpolate(start, view, model, ease) {
38032	var keys = Object.keys(model);
38033	var i, ilen, key, actual, origin, target, type, c0, c1;
38034
38035	for (i = 0, ilen = keys.length; i < ilen; ++i) {
38036		key = keys[i];
38037
38038		target = model[key];
38039
38040		// if a value is added to the model after pivot() has been called, the view
38041		// doesn't contain it, so let's initialize the view to the target value.
38042		if (!view.hasOwnProperty(key)) {
38043			view[key] = target;
38044		}
38045
38046		actual = view[key];
38047
38048		if (actual === target || key[0] === '_') {
38049			continue;
38050		}
38051
38052		if (!start.hasOwnProperty(key)) {
38053			start[key] = actual;
38054		}
38055
38056		origin = start[key];
38057
38058		type = typeof target;
38059
38060		if (type === typeof origin) {
38061			if (type === 'string') {
38062				c0 = color(origin);
38063				if (c0.valid) {
38064					c1 = color(target);
38065					if (c1.valid) {
38066						view[key] = c1.mix(c0, ease).rgbString();
38067						continue;
38068					}
38069				}
38070			} else if (type === 'number' && isFinite(origin) && isFinite(target)) {
38071				view[key] = origin + (target - origin) * ease;
38072				continue;
38073			}
38074		}
38075
38076		view[key] = target;
38077	}
38078}
38079
38080var Element = function(configuration) {
38081	helpers.extend(this, configuration);
38082	this.initialize.apply(this, arguments);
38083};
38084
38085helpers.extend(Element.prototype, {
38086
38087	initialize: function() {
38088		this.hidden = false;
38089	},
38090
38091	pivot: function() {
38092		var me = this;
38093		if (!me._view) {
38094			me._view = helpers.clone(me._model);
38095		}
38096		me._start = {};
38097		return me;
38098	},
38099
38100	transition: function(ease) {
38101		var me = this;
38102		var model = me._model;
38103		var start = me._start;
38104		var view = me._view;
38105
38106		// No animation -> No Transition
38107		if (!model || ease === 1) {
38108			me._view = model;
38109			me._start = null;
38110			return me;
38111		}
38112
38113		if (!view) {
38114			view = me._view = {};
38115		}
38116
38117		if (!start) {
38118			start = me._start = {};
38119		}
38120
38121		interpolate(start, view, model, ease);
38122
38123		return me;
38124	},
38125
38126	tooltipPosition: function() {
38127		return {
38128			x: this._model.x,
38129			y: this._model.y
38130		};
38131	},
38132
38133	hasValue: function() {
38134		return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
38135	}
38136});
38137
38138Element.extend = helpers.inherits;
38139
38140module.exports = Element;
38141
38142},{"3":3,"45":45}],27:[function(require,module,exports){
38143/* global window: false */
38144/* global document: false */
38145'use strict';
38146
38147var color = require(3);
38148var defaults = require(25);
38149var helpers = require(45);
38150
38151module.exports = function(Chart) {
38152
38153	// -- Basic js utility methods
38154
38155	helpers.configMerge = function(/* objects ... */) {
38156		return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {
38157			merger: function(key, target, source, options) {
38158				var tval = target[key] || {};
38159				var sval = source[key];
38160
38161				if (key === 'scales') {
38162					// scale config merging is complex. Add our own function here for that
38163					target[key] = helpers.scaleMerge(tval, sval);
38164				} else if (key === 'scale') {
38165					// used in polar area & radar charts since there is only one scale
38166					target[key] = helpers.merge(tval, [Chart.scaleService.getScaleDefaults(sval.type), sval]);
38167				} else {
38168					helpers._merger(key, target, source, options);
38169				}
38170			}
38171		});
38172	};
38173
38174	helpers.scaleMerge = function(/* objects ... */) {
38175		return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), {
38176			merger: function(key, target, source, options) {
38177				if (key === 'xAxes' || key === 'yAxes') {
38178					var slen = source[key].length;
38179					var i, type, scale;
38180
38181					if (!target[key]) {
38182						target[key] = [];
38183					}
38184
38185					for (i = 0; i < slen; ++i) {
38186						scale = source[key][i];
38187						type = helpers.valueOrDefault(scale.type, key === 'xAxes' ? 'category' : 'linear');
38188
38189						if (i >= target[key].length) {
38190							target[key].push({});
38191						}
38192
38193						if (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) {
38194							// new/untyped scale or type changed: let's apply the new defaults
38195							// then merge source scale to correctly overwrite the defaults.
38196							helpers.merge(target[key][i], [Chart.scaleService.getScaleDefaults(type), scale]);
38197						} else {
38198							// scales type are the same
38199							helpers.merge(target[key][i], scale);
38200						}
38201					}
38202				} else {
38203					helpers._merger(key, target, source, options);
38204				}
38205			}
38206		});
38207	};
38208
38209	helpers.where = function(collection, filterCallback) {
38210		if (helpers.isArray(collection) && Array.prototype.filter) {
38211			return collection.filter(filterCallback);
38212		}
38213		var filtered = [];
38214
38215		helpers.each(collection, function(item) {
38216			if (filterCallback(item)) {
38217				filtered.push(item);
38218			}
38219		});
38220
38221		return filtered;
38222	};
38223	helpers.findIndex = Array.prototype.findIndex ?
38224		function(array, callback, scope) {
38225			return array.findIndex(callback, scope);
38226		} :
38227		function(array, callback, scope) {
38228			scope = scope === undefined ? array : scope;
38229			for (var i = 0, ilen = array.length; i < ilen; ++i) {
38230				if (callback.call(scope, array[i], i, array)) {
38231					return i;
38232				}
38233			}
38234			return -1;
38235		};
38236	helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
38237		// Default to start of the array
38238		if (helpers.isNullOrUndef(startIndex)) {
38239			startIndex = -1;
38240		}
38241		for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
38242			var currentItem = arrayToSearch[i];
38243			if (filterCallback(currentItem)) {
38244				return currentItem;
38245			}
38246		}
38247	};
38248	helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
38249		// Default to end of the array
38250		if (helpers.isNullOrUndef(startIndex)) {
38251			startIndex = arrayToSearch.length;
38252		}
38253		for (var i = startIndex - 1; i >= 0; i--) {
38254			var currentItem = arrayToSearch[i];
38255			if (filterCallback(currentItem)) {
38256				return currentItem;
38257			}
38258		}
38259	};
38260
38261	// -- Math methods
38262	helpers.isNumber = function(n) {
38263		return !isNaN(parseFloat(n)) && isFinite(n);
38264	};
38265	helpers.almostEquals = function(x, y, epsilon) {
38266		return Math.abs(x - y) < epsilon;
38267	};
38268	helpers.almostWhole = function(x, epsilon) {
38269		var rounded = Math.round(x);
38270		return (((rounded - epsilon) < x) && ((rounded + epsilon) > x));
38271	};
38272	helpers.max = function(array) {
38273		return array.reduce(function(max, value) {
38274			if (!isNaN(value)) {
38275				return Math.max(max, value);
38276			}
38277			return max;
38278		}, Number.NEGATIVE_INFINITY);
38279	};
38280	helpers.min = function(array) {
38281		return array.reduce(function(min, value) {
38282			if (!isNaN(value)) {
38283				return Math.min(min, value);
38284			}
38285			return min;
38286		}, Number.POSITIVE_INFINITY);
38287	};
38288	helpers.sign = Math.sign ?
38289		function(x) {
38290			return Math.sign(x);
38291		} :
38292		function(x) {
38293			x = +x; // convert to a number
38294			if (x === 0 || isNaN(x)) {
38295				return x;
38296			}
38297			return x > 0 ? 1 : -1;
38298		};
38299	helpers.log10 = Math.log10 ?
38300		function(x) {
38301			return Math.log10(x);
38302		} :
38303		function(x) {
38304			var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.
38305			// Check for whole powers of 10,
38306			// which due to floating point rounding error should be corrected.
38307			var powerOf10 = Math.round(exponent);
38308			var isPowerOf10 = x === Math.pow(10, powerOf10);
38309
38310			return isPowerOf10 ? powerOf10 : exponent;
38311		};
38312	helpers.toRadians = function(degrees) {
38313		return degrees * (Math.PI / 180);
38314	};
38315	helpers.toDegrees = function(radians) {
38316		return radians * (180 / Math.PI);
38317	};
38318	// Gets the angle from vertical upright to the point about a centre.
38319	helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
38320		var distanceFromXCenter = anglePoint.x - centrePoint.x;
38321		var distanceFromYCenter = anglePoint.y - centrePoint.y;
38322		var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
38323
38324		var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
38325
38326		if (angle < (-0.5 * Math.PI)) {
38327			angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
38328		}
38329
38330		return {
38331			angle: angle,
38332			distance: radialDistanceFromCenter
38333		};
38334	};
38335	helpers.distanceBetweenPoints = function(pt1, pt2) {
38336		return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
38337	};
38338	helpers.aliasPixel = function(pixelWidth) {
38339		return (pixelWidth % 2 === 0) ? 0 : 0.5;
38340	};
38341	helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
38342		// Props to Rob Spencer at scaled innovation for his post on splining between points
38343		// http://scaledinnovation.com/analytics/splines/aboutSplines.html
38344
38345		// This function must also respect "skipped" points
38346
38347		var previous = firstPoint.skip ? middlePoint : firstPoint;
38348		var current = middlePoint;
38349		var next = afterPoint.skip ? middlePoint : afterPoint;
38350
38351		var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
38352		var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
38353
38354		var s01 = d01 / (d01 + d12);
38355		var s12 = d12 / (d01 + d12);
38356
38357		// If all points are the same, s01 & s02 will be inf
38358		s01 = isNaN(s01) ? 0 : s01;
38359		s12 = isNaN(s12) ? 0 : s12;
38360
38361		var fa = t * s01; // scaling factor for triangle Ta
38362		var fb = t * s12;
38363
38364		return {
38365			previous: {
38366				x: current.x - fa * (next.x - previous.x),
38367				y: current.y - fa * (next.y - previous.y)
38368			},
38369			next: {
38370				x: current.x + fb * (next.x - previous.x),
38371				y: current.y + fb * (next.y - previous.y)
38372			}
38373		};
38374	};
38375	helpers.EPSILON = Number.EPSILON || 1e-14;
38376	helpers.splineCurveMonotone = function(points) {
38377		// This function calculates Bézier control points in a similar way than |splineCurve|,
38378		// but preserves monotonicity of the provided data and ensures no local extremums are added
38379		// between the dataset discrete points due to the interpolation.
38380		// See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation
38381
38382		var pointsWithTangents = (points || []).map(function(point) {
38383			return {
38384				model: point._model,
38385				deltaK: 0,
38386				mK: 0
38387			};
38388		});
38389
38390		// Calculate slopes (deltaK) and initialize tangents (mK)
38391		var pointsLen = pointsWithTangents.length;
38392		var i, pointBefore, pointCurrent, pointAfter;
38393		for (i = 0; i < pointsLen; ++i) {
38394			pointCurrent = pointsWithTangents[i];
38395			if (pointCurrent.model.skip) {
38396				continue;
38397			}
38398
38399			pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
38400			pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
38401			if (pointAfter && !pointAfter.model.skip) {
38402				var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);
38403
38404				// In the case of two points that appear at the same x pixel, slopeDeltaX is 0
38405				pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;
38406			}
38407
38408			if (!pointBefore || pointBefore.model.skip) {
38409				pointCurrent.mK = pointCurrent.deltaK;
38410			} else if (!pointAfter || pointAfter.model.skip) {
38411				pointCurrent.mK = pointBefore.deltaK;
38412			} else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {
38413				pointCurrent.mK = 0;
38414			} else {
38415				pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;
38416			}
38417		}
38418
38419		// Adjust tangents to ensure monotonic properties
38420		var alphaK, betaK, tauK, squaredMagnitude;
38421		for (i = 0; i < pointsLen - 1; ++i) {
38422			pointCurrent = pointsWithTangents[i];
38423			pointAfter = pointsWithTangents[i + 1];
38424			if (pointCurrent.model.skip || pointAfter.model.skip) {
38425				continue;
38426			}
38427
38428			if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {
38429				pointCurrent.mK = pointAfter.mK = 0;
38430				continue;
38431			}
38432
38433			alphaK = pointCurrent.mK / pointCurrent.deltaK;
38434			betaK = pointAfter.mK / pointCurrent.deltaK;
38435			squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);
38436			if (squaredMagnitude <= 9) {
38437				continue;
38438			}
38439
38440			tauK = 3 / Math.sqrt(squaredMagnitude);
38441			pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;
38442			pointAfter.mK = betaK * tauK * pointCurrent.deltaK;
38443		}
38444
38445		// Compute control points
38446		var deltaX;
38447		for (i = 0; i < pointsLen; ++i) {
38448			pointCurrent = pointsWithTangents[i];
38449			if (pointCurrent.model.skip) {
38450				continue;
38451			}
38452
38453			pointBefore = i > 0 ? pointsWithTangents[i - 1] : null;
38454			pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;
38455			if (pointBefore && !pointBefore.model.skip) {
38456				deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;
38457				pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;
38458				pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;
38459			}
38460			if (pointAfter && !pointAfter.model.skip) {
38461				deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;
38462				pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;
38463				pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;
38464			}
38465		}
38466	};
38467	helpers.nextItem = function(collection, index, loop) {
38468		if (loop) {
38469			return index >= collection.length - 1 ? collection[0] : collection[index + 1];
38470		}
38471		return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
38472	};
38473	helpers.previousItem = function(collection, index, loop) {
38474		if (loop) {
38475			return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
38476		}
38477		return index <= 0 ? collection[0] : collection[index - 1];
38478	};
38479	// Implementation of the nice number algorithm used in determining where axis labels will go
38480	helpers.niceNum = function(range, round) {
38481		var exponent = Math.floor(helpers.log10(range));
38482		var fraction = range / Math.pow(10, exponent);
38483		var niceFraction;
38484
38485		if (round) {
38486			if (fraction < 1.5) {
38487				niceFraction = 1;
38488			} else if (fraction < 3) {
38489				niceFraction = 2;
38490			} else if (fraction < 7) {
38491				niceFraction = 5;
38492			} else {
38493				niceFraction = 10;
38494			}
38495		} else if (fraction <= 1.0) {
38496			niceFraction = 1;
38497		} else if (fraction <= 2) {
38498			niceFraction = 2;
38499		} else if (fraction <= 5) {
38500			niceFraction = 5;
38501		} else {
38502			niceFraction = 10;
38503		}
38504
38505		return niceFraction * Math.pow(10, exponent);
38506	};
38507	// Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
38508	helpers.requestAnimFrame = (function() {
38509		if (typeof window === 'undefined') {
38510			return function(callback) {
38511				callback();
38512			};
38513		}
38514		return window.requestAnimationFrame ||
38515			window.webkitRequestAnimationFrame ||
38516			window.mozRequestAnimationFrame ||
38517			window.oRequestAnimationFrame ||
38518			window.msRequestAnimationFrame ||
38519			function(callback) {
38520				return window.setTimeout(callback, 1000 / 60);
38521			};
38522	}());
38523	// -- DOM methods
38524	helpers.getRelativePosition = function(evt, chart) {
38525		var mouseX, mouseY;
38526		var e = evt.originalEvent || evt;
38527		var canvas = evt.currentTarget || evt.srcElement;
38528		var boundingRect = canvas.getBoundingClientRect();
38529
38530		var touches = e.touches;
38531		if (touches && touches.length > 0) {
38532			mouseX = touches[0].clientX;
38533			mouseY = touches[0].clientY;
38534
38535		} else {
38536			mouseX = e.clientX;
38537			mouseY = e.clientY;
38538		}
38539
38540		// Scale mouse coordinates into canvas coordinates
38541		// by following the pattern laid out by 'jerryj' in the comments of
38542		// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
38543		var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
38544		var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
38545		var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
38546		var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
38547		var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
38548		var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
38549
38550		// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
38551		// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
38552		mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
38553		mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
38554
38555		return {
38556			x: mouseX,
38557			y: mouseY
38558		};
38559
38560	};
38561
38562	// Private helper function to convert max-width/max-height values that may be percentages into a number
38563	function parseMaxStyle(styleValue, node, parentProperty) {
38564		var valueInPixels;
38565		if (typeof styleValue === 'string') {
38566			valueInPixels = parseInt(styleValue, 10);
38567
38568			if (styleValue.indexOf('%') !== -1) {
38569				// percentage * size in dimension
38570				valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
38571			}
38572		} else {
38573			valueInPixels = styleValue;
38574		}
38575
38576		return valueInPixels;
38577	}
38578
38579	/**
38580	 * Returns if the given value contains an effective constraint.
38581	 * @private
38582	 */
38583	function isConstrainedValue(value) {
38584		return value !== undefined && value !== null && value !== 'none';
38585	}
38586
38587	// Private helper to get a constraint dimension
38588	// @param domNode : the node to check the constraint on
38589	// @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight)
38590	// @param percentageProperty : property of parent to use when calculating width as a percentage
38591	// @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser
38592	function getConstraintDimension(domNode, maxStyle, percentageProperty) {
38593		var view = document.defaultView;
38594		var parentNode = domNode.parentNode;
38595		var constrainedNode = view.getComputedStyle(domNode)[maxStyle];
38596		var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];
38597		var hasCNode = isConstrainedValue(constrainedNode);
38598		var hasCContainer = isConstrainedValue(constrainedContainer);
38599		var infinity = Number.POSITIVE_INFINITY;
38600
38601		if (hasCNode || hasCContainer) {
38602			return Math.min(
38603				hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,
38604				hasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);
38605		}
38606
38607		return 'none';
38608	}
38609	// returns Number or undefined if no constraint
38610	helpers.getConstraintWidth = function(domNode) {
38611		return getConstraintDimension(domNode, 'max-width', 'clientWidth');
38612	};
38613	// returns Number or undefined if no constraint
38614	helpers.getConstraintHeight = function(domNode) {
38615		return getConstraintDimension(domNode, 'max-height', 'clientHeight');
38616	};
38617	helpers.getMaximumWidth = function(domNode) {
38618		var container = domNode.parentNode;
38619		if (!container) {
38620			return domNode.clientWidth;
38621		}
38622
38623		var paddingLeft = parseInt(helpers.getStyle(container, 'padding-left'), 10);
38624		var paddingRight = parseInt(helpers.getStyle(container, 'padding-right'), 10);
38625		var w = container.clientWidth - paddingLeft - paddingRight;
38626		var cw = helpers.getConstraintWidth(domNode);
38627		return isNaN(cw) ? w : Math.min(w, cw);
38628	};
38629	helpers.getMaximumHeight = function(domNode) {
38630		var container = domNode.parentNode;
38631		if (!container) {
38632			return domNode.clientHeight;
38633		}
38634
38635		var paddingTop = parseInt(helpers.getStyle(container, 'padding-top'), 10);
38636		var paddingBottom = parseInt(helpers.getStyle(container, 'padding-bottom'), 10);
38637		var h = container.clientHeight - paddingTop - paddingBottom;
38638		var ch = helpers.getConstraintHeight(domNode);
38639		return isNaN(ch) ? h : Math.min(h, ch);
38640	};
38641	helpers.getStyle = function(el, property) {
38642		return el.currentStyle ?
38643			el.currentStyle[property] :
38644			document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
38645	};
38646	helpers.retinaScale = function(chart, forceRatio) {
38647		var pixelRatio = chart.currentDevicePixelRatio = forceRatio || window.devicePixelRatio || 1;
38648		if (pixelRatio === 1) {
38649			return;
38650		}
38651
38652		var canvas = chart.canvas;
38653		var height = chart.height;
38654		var width = chart.width;
38655
38656		canvas.height = height * pixelRatio;
38657		canvas.width = width * pixelRatio;
38658		chart.ctx.scale(pixelRatio, pixelRatio);
38659
38660		// If no style has been set on the canvas, the render size is used as display size,
38661		// making the chart visually bigger, so let's enforce it to the "correct" values.
38662		// See https://github.com/chartjs/Chart.js/issues/3575
38663		if (!canvas.style.height && !canvas.style.width) {
38664			canvas.style.height = height + 'px';
38665			canvas.style.width = width + 'px';
38666		}
38667	};
38668	// -- Canvas methods
38669	helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
38670		return fontStyle + ' ' + pixelSize + 'px ' + fontFamily;
38671	};
38672	helpers.longestText = function(ctx, font, arrayOfThings, cache) {
38673		cache = cache || {};
38674		var data = cache.data = cache.data || {};
38675		var gc = cache.garbageCollect = cache.garbageCollect || [];
38676
38677		if (cache.font !== font) {
38678			data = cache.data = {};
38679			gc = cache.garbageCollect = [];
38680			cache.font = font;
38681		}
38682
38683		ctx.font = font;
38684		var longest = 0;
38685		helpers.each(arrayOfThings, function(thing) {
38686			// Undefined strings and arrays should not be measured
38687			if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
38688				longest = helpers.measureText(ctx, data, gc, longest, thing);
38689			} else if (helpers.isArray(thing)) {
38690				// if it is an array lets measure each element
38691				// to do maybe simplify this function a bit so we can do this more recursively?
38692				helpers.each(thing, function(nestedThing) {
38693					// Undefined strings and arrays should not be measured
38694					if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
38695						longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
38696					}
38697				});
38698			}
38699		});
38700
38701		var gcLen = gc.length / 2;
38702		if (gcLen > arrayOfThings.length) {
38703			for (var i = 0; i < gcLen; i++) {
38704				delete data[gc[i]];
38705			}
38706			gc.splice(0, gcLen);
38707		}
38708		return longest;
38709	};
38710	helpers.measureText = function(ctx, data, gc, longest, string) {
38711		var textWidth = data[string];
38712		if (!textWidth) {
38713			textWidth = data[string] = ctx.measureText(string).width;
38714			gc.push(string);
38715		}
38716		if (textWidth > longest) {
38717			longest = textWidth;
38718		}
38719		return longest;
38720	};
38721	helpers.numberOfLabelLines = function(arrayOfThings) {
38722		var numberOfLines = 1;
38723		helpers.each(arrayOfThings, function(thing) {
38724			if (helpers.isArray(thing)) {
38725				if (thing.length > numberOfLines) {
38726					numberOfLines = thing.length;
38727				}
38728			}
38729		});
38730		return numberOfLines;
38731	};
38732
38733	helpers.color = !color ?
38734		function(value) {
38735			console.error('Color.js not found!');
38736			return value;
38737		} :
38738		function(value) {
38739			/* global CanvasGradient */
38740			if (value instanceof CanvasGradient) {
38741				value = defaults.global.defaultColor;
38742			}
38743
38744			return color(value);
38745		};
38746
38747	helpers.getHoverColor = function(colorValue) {
38748		/* global CanvasPattern */
38749		return (colorValue instanceof CanvasPattern) ?
38750			colorValue :
38751			helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString();
38752	};
38753};
38754
38755},{"25":25,"3":3,"45":45}],28:[function(require,module,exports){
38756'use strict';
38757
38758var helpers = require(45);
38759
38760/**
38761 * Helper function to get relative position for an event
38762 * @param {Event|IEvent} event - The event to get the position for
38763 * @param {Chart} chart - The chart
38764 * @returns {Point} the event position
38765 */
38766function getRelativePosition(e, chart) {
38767	if (e.native) {
38768		return {
38769			x: e.x,
38770			y: e.y
38771		};
38772	}
38773
38774	return helpers.getRelativePosition(e, chart);
38775}
38776
38777/**
38778 * Helper function to traverse all of the visible elements in the chart
38779 * @param chart {chart} the chart
38780 * @param handler {Function} the callback to execute for each visible item
38781 */
38782function parseVisibleItems(chart, handler) {
38783	var datasets = chart.data.datasets;
38784	var meta, i, j, ilen, jlen;
38785
38786	for (i = 0, ilen = datasets.length; i < ilen; ++i) {
38787		if (!chart.isDatasetVisible(i)) {
38788			continue;
38789		}
38790
38791		meta = chart.getDatasetMeta(i);
38792		for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
38793			var element = meta.data[j];
38794			if (!element._view.skip) {
38795				handler(element);
38796			}
38797		}
38798	}
38799}
38800
38801/**
38802 * Helper function to get the items that intersect the event position
38803 * @param items {ChartElement[]} elements to filter
38804 * @param position {Point} the point to be nearest to
38805 * @return {ChartElement[]} the nearest items
38806 */
38807function getIntersectItems(chart, position) {
38808	var elements = [];
38809
38810	parseVisibleItems(chart, function(element) {
38811		if (element.inRange(position.x, position.y)) {
38812			elements.push(element);
38813		}
38814	});
38815
38816	return elements;
38817}
38818
38819/**
38820 * Helper function to get the items nearest to the event position considering all visible items in teh chart
38821 * @param chart {Chart} the chart to look at elements from
38822 * @param position {Point} the point to be nearest to
38823 * @param intersect {Boolean} if true, only consider items that intersect the position
38824 * @param distanceMetric {Function} function to provide the distance between points
38825 * @return {ChartElement[]} the nearest items
38826 */
38827function getNearestItems(chart, position, intersect, distanceMetric) {
38828	var minDistance = Number.POSITIVE_INFINITY;
38829	var nearestItems = [];
38830
38831	parseVisibleItems(chart, function(element) {
38832		if (intersect && !element.inRange(position.x, position.y)) {
38833			return;
38834		}
38835
38836		var center = element.getCenterPoint();
38837		var distance = distanceMetric(position, center);
38838
38839		if (distance < minDistance) {
38840			nearestItems = [element];
38841			minDistance = distance;
38842		} else if (distance === minDistance) {
38843			// Can have multiple items at the same distance in which case we sort by size
38844			nearestItems.push(element);
38845		}
38846	});
38847
38848	return nearestItems;
38849}
38850
38851/**
38852 * Get a distance metric function for two points based on the
38853 * axis mode setting
38854 * @param {String} axis the axis mode. x|y|xy
38855 */
38856function getDistanceMetricForAxis(axis) {
38857	var useX = axis.indexOf('x') !== -1;
38858	var useY = axis.indexOf('y') !== -1;
38859
38860	return function(pt1, pt2) {
38861		var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;
38862		var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;
38863		return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
38864	};
38865}
38866
38867function indexMode(chart, e, options) {
38868	var position = getRelativePosition(e, chart);
38869	// Default axis for index mode is 'x' to match old behaviour
38870	options.axis = options.axis || 'x';
38871	var distanceMetric = getDistanceMetricForAxis(options.axis);
38872	var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
38873	var elements = [];
38874
38875	if (!items.length) {
38876		return [];
38877	}
38878
38879	chart.data.datasets.forEach(function(dataset, datasetIndex) {
38880		if (chart.isDatasetVisible(datasetIndex)) {
38881			var meta = chart.getDatasetMeta(datasetIndex);
38882			var element = meta.data[items[0]._index];
38883
38884			// don't count items that are skipped (null data)
38885			if (element && !element._view.skip) {
38886				elements.push(element);
38887			}
38888		}
38889	});
38890
38891	return elements;
38892}
38893
38894/**
38895 * @interface IInteractionOptions
38896 */
38897/**
38898 * If true, only consider items that intersect the point
38899 * @name IInterfaceOptions#boolean
38900 * @type Boolean
38901 */
38902
38903/**
38904 * Contains interaction related functions
38905 * @namespace Chart.Interaction
38906 */
38907module.exports = {
38908	// Helper function for different modes
38909	modes: {
38910		single: function(chart, e) {
38911			var position = getRelativePosition(e, chart);
38912			var elements = [];
38913
38914			parseVisibleItems(chart, function(element) {
38915				if (element.inRange(position.x, position.y)) {
38916					elements.push(element);
38917					return elements;
38918				}
38919			});
38920
38921			return elements.slice(0, 1);
38922		},
38923
38924		/**
38925		 * @function Chart.Interaction.modes.label
38926		 * @deprecated since version 2.4.0
38927		 * @todo remove at version 3
38928		 * @private
38929		 */
38930		label: indexMode,
38931
38932		/**
38933		 * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
38934		 * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
38935		 * @function Chart.Interaction.modes.index
38936		 * @since v2.4.0
38937		 * @param chart {chart} the chart we are returning items from
38938		 * @param e {Event} the event we are find things at
38939		 * @param options {IInteractionOptions} options to use during interaction
38940		 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
38941		 */
38942		index: indexMode,
38943
38944		/**
38945		 * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
38946		 * If the options.intersect is false, we find the nearest item and return the items in that dataset
38947		 * @function Chart.Interaction.modes.dataset
38948		 * @param chart {chart} the chart we are returning items from
38949		 * @param e {Event} the event we are find things at
38950		 * @param options {IInteractionOptions} options to use during interaction
38951		 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
38952		 */
38953		dataset: function(chart, e, options) {
38954			var position = getRelativePosition(e, chart);
38955			options.axis = options.axis || 'xy';
38956			var distanceMetric = getDistanceMetricForAxis(options.axis);
38957			var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
38958
38959			if (items.length > 0) {
38960				items = chart.getDatasetMeta(items[0]._datasetIndex).data;
38961			}
38962
38963			return items;
38964		},
38965
38966		/**
38967		 * @function Chart.Interaction.modes.x-axis
38968		 * @deprecated since version 2.4.0. Use index mode and intersect == true
38969		 * @todo remove at version 3
38970		 * @private
38971		 */
38972		'x-axis': function(chart, e) {
38973			return indexMode(chart, e, {intersect: false});
38974		},
38975
38976		/**
38977		 * Point mode returns all elements that hit test based on the event position
38978		 * of the event
38979		 * @function Chart.Interaction.modes.intersect
38980		 * @param chart {chart} the chart we are returning items from
38981		 * @param e {Event} the event we are find things at
38982		 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
38983		 */
38984		point: function(chart, e) {
38985			var position = getRelativePosition(e, chart);
38986			return getIntersectItems(chart, position);
38987		},
38988
38989		/**
38990		 * nearest mode returns the element closest to the point
38991		 * @function Chart.Interaction.modes.intersect
38992		 * @param chart {chart} the chart we are returning items from
38993		 * @param e {Event} the event we are find things at
38994		 * @param options {IInteractionOptions} options to use
38995		 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
38996		 */
38997		nearest: function(chart, e, options) {
38998			var position = getRelativePosition(e, chart);
38999			options.axis = options.axis || 'xy';
39000			var distanceMetric = getDistanceMetricForAxis(options.axis);
39001			var nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric);
39002
39003			// We have multiple items at the same distance from the event. Now sort by smallest
39004			if (nearestItems.length > 1) {
39005				nearestItems.sort(function(a, b) {
39006					var sizeA = a.getArea();
39007					var sizeB = b.getArea();
39008					var ret = sizeA - sizeB;
39009
39010					if (ret === 0) {
39011						// if equal sort by dataset index
39012						ret = a._datasetIndex - b._datasetIndex;
39013					}
39014
39015					return ret;
39016				});
39017			}
39018
39019			// Return only 1 item
39020			return nearestItems.slice(0, 1);
39021		},
39022
39023		/**
39024		 * x mode returns the elements that hit-test at the current x coordinate
39025		 * @function Chart.Interaction.modes.x
39026		 * @param chart {chart} the chart we are returning items from
39027		 * @param e {Event} the event we are find things at
39028		 * @param options {IInteractionOptions} options to use
39029		 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
39030		 */
39031		x: function(chart, e, options) {
39032			var position = getRelativePosition(e, chart);
39033			var items = [];
39034			var intersectsItem = false;
39035
39036			parseVisibleItems(chart, function(element) {
39037				if (element.inXRange(position.x)) {
39038					items.push(element);
39039				}
39040
39041				if (element.inRange(position.x, position.y)) {
39042					intersectsItem = true;
39043				}
39044			});
39045
39046			// If we want to trigger on an intersect and we don't have any items
39047			// that intersect the position, return nothing
39048			if (options.intersect && !intersectsItem) {
39049				items = [];
39050			}
39051			return items;
39052		},
39053
39054		/**
39055		 * y mode returns the elements that hit-test at the current y coordinate
39056		 * @function Chart.Interaction.modes.y
39057		 * @param chart {chart} the chart we are returning items from
39058		 * @param e {Event} the event we are find things at
39059		 * @param options {IInteractionOptions} options to use
39060		 * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
39061		 */
39062		y: function(chart, e, options) {
39063			var position = getRelativePosition(e, chart);
39064			var items = [];
39065			var intersectsItem = false;
39066
39067			parseVisibleItems(chart, function(element) {
39068				if (element.inYRange(position.y)) {
39069					items.push(element);
39070				}
39071
39072				if (element.inRange(position.x, position.y)) {
39073					intersectsItem = true;
39074				}
39075			});
39076
39077			// If we want to trigger on an intersect and we don't have any items
39078			// that intersect the position, return nothing
39079			if (options.intersect && !intersectsItem) {
39080				items = [];
39081			}
39082			return items;
39083		}
39084	}
39085};
39086
39087},{"45":45}],29:[function(require,module,exports){
39088'use strict';
39089
39090var defaults = require(25);
39091
39092defaults._set('global', {
39093	responsive: true,
39094	responsiveAnimationDuration: 0,
39095	maintainAspectRatio: true,
39096	events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
39097	hover: {
39098		onHover: null,
39099		mode: 'nearest',
39100		intersect: true,
39101		animationDuration: 400
39102	},
39103	onClick: null,
39104	defaultColor: 'rgba(0,0,0,0.1)',
39105	defaultFontColor: '#666',
39106	defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
39107	defaultFontSize: 12,
39108	defaultFontStyle: 'normal',
39109	showLines: true,
39110
39111	// Element defaults defined in element extensions
39112	elements: {},
39113
39114	// Layout options such as padding
39115	layout: {
39116		padding: {
39117			top: 0,
39118			right: 0,
39119			bottom: 0,
39120			left: 0
39121		}
39122	}
39123});
39124
39125module.exports = function() {
39126
39127	// Occupy the global variable of Chart, and create a simple base class
39128	var Chart = function(item, config) {
39129		this.construct(item, config);
39130		return this;
39131	};
39132
39133	Chart.Chart = Chart;
39134
39135	return Chart;
39136};
39137
39138},{"25":25}],30:[function(require,module,exports){
39139'use strict';
39140
39141var helpers = require(45);
39142
39143function filterByPosition(array, position) {
39144	return helpers.where(array, function(v) {
39145		return v.position === position;
39146	});
39147}
39148
39149function sortByWeight(array, reverse) {
39150	array.forEach(function(v, i) {
39151		v._tmpIndex_ = i;
39152		return v;
39153	});
39154	array.sort(function(a, b) {
39155		var v0 = reverse ? b : a;
39156		var v1 = reverse ? a : b;
39157		return v0.weight === v1.weight ?
39158			v0._tmpIndex_ - v1._tmpIndex_ :
39159			v0.weight - v1.weight;
39160	});
39161	array.forEach(function(v) {
39162		delete v._tmpIndex_;
39163	});
39164}
39165
39166/**
39167 * @interface ILayoutItem
39168 * @prop {String} position - The position of the item in the chart layout. Possible values are
39169 * 'left', 'top', 'right', 'bottom', and 'chartArea'
39170 * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area
39171 * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down
39172 * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)
39173 * @prop {Function} update - Takes two parameters: width and height. Returns size of item
39174 * @prop {Function} getPadding -  Returns an object with padding on the edges
39175 * @prop {Number} width - Width of item. Must be valid after update()
39176 * @prop {Number} height - Height of item. Must be valid after update()
39177 * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update
39178 * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update
39179 * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update
39180 * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update
39181 */
39182
39183// The layout service is very self explanatory.  It's responsible for the layout within a chart.
39184// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
39185// It is this service's responsibility of carrying out that layout.
39186module.exports = {
39187	defaults: {},
39188
39189	/**
39190	 * Register a box to a chart.
39191	 * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.
39192	 * @param {Chart} chart - the chart to use
39193	 * @param {ILayoutItem} item - the item to add to be layed out
39194	 */
39195	addBox: function(chart, item) {
39196		if (!chart.boxes) {
39197			chart.boxes = [];
39198		}
39199
39200		// initialize item with default values
39201		item.fullWidth = item.fullWidth || false;
39202		item.position = item.position || 'top';
39203		item.weight = item.weight || 0;
39204
39205		chart.boxes.push(item);
39206	},
39207
39208	/**
39209	 * Remove a layoutItem from a chart
39210	 * @param {Chart} chart - the chart to remove the box from
39211	 * @param {Object} layoutItem - the item to remove from the layout
39212	 */
39213	removeBox: function(chart, layoutItem) {
39214		var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;
39215		if (index !== -1) {
39216			chart.boxes.splice(index, 1);
39217		}
39218	},
39219
39220	/**
39221	 * Sets (or updates) options on the given `item`.
39222	 * @param {Chart} chart - the chart in which the item lives (or will be added to)
39223	 * @param {Object} item - the item to configure with the given options
39224	 * @param {Object} options - the new item options.
39225	 */
39226	configure: function(chart, item, options) {
39227		var props = ['fullWidth', 'position', 'weight'];
39228		var ilen = props.length;
39229		var i = 0;
39230		var prop;
39231
39232		for (; i < ilen; ++i) {
39233			prop = props[i];
39234			if (options.hasOwnProperty(prop)) {
39235				item[prop] = options[prop];
39236			}
39237		}
39238	},
39239
39240	/**
39241	 * Fits boxes of the given chart into the given size by having each box measure itself
39242	 * then running a fitting algorithm
39243	 * @param {Chart} chart - the chart
39244	 * @param {Number} width - the width to fit into
39245	 * @param {Number} height - the height to fit into
39246	 */
39247	update: function(chart, width, height) {
39248		if (!chart) {
39249			return;
39250		}
39251
39252		var layoutOptions = chart.options.layout || {};
39253		var padding = helpers.options.toPadding(layoutOptions.padding);
39254		var leftPadding = padding.left;
39255		var rightPadding = padding.right;
39256		var topPadding = padding.top;
39257		var bottomPadding = padding.bottom;
39258
39259		var leftBoxes = filterByPosition(chart.boxes, 'left');
39260		var rightBoxes = filterByPosition(chart.boxes, 'right');
39261		var topBoxes = filterByPosition(chart.boxes, 'top');
39262		var bottomBoxes = filterByPosition(chart.boxes, 'bottom');
39263		var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea');
39264
39265		// Sort boxes by weight. A higher weight is further away from the chart area
39266		sortByWeight(leftBoxes, true);
39267		sortByWeight(rightBoxes, false);
39268		sortByWeight(topBoxes, true);
39269		sortByWeight(bottomBoxes, false);
39270
39271		// Essentially we now have any number of boxes on each of the 4 sides.
39272		// Our canvas looks like the following.
39273		// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
39274		// B1 is the bottom axis
39275		// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
39276		// These locations are single-box locations only, when trying to register a chartArea location that is already taken,
39277		// an error will be thrown.
39278		//
39279		// |----------------------------------------------------|
39280		// |                  T1 (Full Width)                   |
39281		// |----------------------------------------------------|
39282		// |    |    |                 T2                  |    |
39283		// |    |----|-------------------------------------|----|
39284		// |    |    | C1 |                           | C2 |    |
39285		// |    |    |----|                           |----|    |
39286		// |    |    |                                     |    |
39287		// | L1 | L2 |           ChartArea (C0)            | R1 |
39288		// |    |    |                                     |    |
39289		// |    |    |----|                           |----|    |
39290		// |    |    | C3 |                           | C4 |    |
39291		// |    |----|-------------------------------------|----|
39292		// |    |    |                 B1                  |    |
39293		// |----------------------------------------------------|
39294		// |                  B2 (Full Width)                   |
39295		// |----------------------------------------------------|
39296		//
39297		// What we do to find the best sizing, we do the following
39298		// 1. Determine the minimum size of the chart area.
39299		// 2. Split the remaining width equally between each vertical axis
39300		// 3. Split the remaining height equally between each horizontal axis
39301		// 4. Give each layout the maximum size it can be. The layout will return it's minimum size
39302		// 5. Adjust the sizes of each axis based on it's minimum reported size.
39303		// 6. Refit each axis
39304		// 7. Position each axis in the final location
39305		// 8. Tell the chart the final location of the chart area
39306		// 9. Tell any axes that overlay the chart area the positions of the chart area
39307
39308		// Step 1
39309		var chartWidth = width - leftPadding - rightPadding;
39310		var chartHeight = height - topPadding - bottomPadding;
39311		var chartAreaWidth = chartWidth / 2; // min 50%
39312		var chartAreaHeight = chartHeight / 2; // min 50%
39313
39314		// Step 2
39315		var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
39316
39317		// Step 3
39318		var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
39319
39320		// Step 4
39321		var maxChartAreaWidth = chartWidth;
39322		var maxChartAreaHeight = chartHeight;
39323		var minBoxSizes = [];
39324
39325		function getMinimumBoxSize(box) {
39326			var minSize;
39327			var isHorizontal = box.isHorizontal();
39328
39329			if (isHorizontal) {
39330				minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
39331				maxChartAreaHeight -= minSize.height;
39332			} else {
39333				minSize = box.update(verticalBoxWidth, maxChartAreaHeight);
39334				maxChartAreaWidth -= minSize.width;
39335			}
39336
39337			minBoxSizes.push({
39338				horizontal: isHorizontal,
39339				minSize: minSize,
39340				box: box,
39341			});
39342		}
39343
39344		helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
39345
39346		// If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478)
39347		var maxHorizontalLeftPadding = 0;
39348		var maxHorizontalRightPadding = 0;
39349		var maxVerticalTopPadding = 0;
39350		var maxVerticalBottomPadding = 0;
39351
39352		helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {
39353			if (horizontalBox.getPadding) {
39354				var boxPadding = horizontalBox.getPadding();
39355				maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);
39356				maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);
39357			}
39358		});
39359
39360		helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) {
39361			if (verticalBox.getPadding) {
39362				var boxPadding = verticalBox.getPadding();
39363				maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top);
39364				maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom);
39365			}
39366		});
39367
39368		// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
39369		// be if the axes are drawn at their minimum sizes.
39370		// Steps 5 & 6
39371		var totalLeftBoxesWidth = leftPadding;
39372		var totalRightBoxesWidth = rightPadding;
39373		var totalTopBoxesHeight = topPadding;
39374		var totalBottomBoxesHeight = bottomPadding;
39375
39376		// Function to fit a box
39377		function fitBox(box) {
39378			var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) {
39379				return minBox.box === box;
39380			});
39381
39382			if (minBoxSize) {
39383				if (box.isHorizontal()) {
39384					var scaleMargin = {
39385						left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
39386						right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
39387						top: 0,
39388						bottom: 0
39389					};
39390
39391					// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
39392					// on the margin. Sometimes they need to increase in size slightly
39393					box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
39394				} else {
39395					box.update(minBoxSize.minSize.width, maxChartAreaHeight);
39396				}
39397			}
39398		}
39399
39400		// Update, and calculate the left and right margins for the horizontal boxes
39401		helpers.each(leftBoxes.concat(rightBoxes), fitBox);
39402
39403		helpers.each(leftBoxes, function(box) {
39404			totalLeftBoxesWidth += box.width;
39405		});
39406
39407		helpers.each(rightBoxes, function(box) {
39408			totalRightBoxesWidth += box.width;
39409		});
39410
39411		// Set the Left and Right margins for the horizontal boxes
39412		helpers.each(topBoxes.concat(bottomBoxes), fitBox);
39413
39414		// Figure out how much margin is on the top and bottom of the vertical boxes
39415		helpers.each(topBoxes, function(box) {
39416			totalTopBoxesHeight += box.height;
39417		});
39418
39419		helpers.each(bottomBoxes, function(box) {
39420			totalBottomBoxesHeight += box.height;
39421		});
39422
39423		function finalFitVerticalBox(box) {
39424			var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) {
39425				return minSize.box === box;
39426			});
39427
39428			var scaleMargin = {
39429				left: 0,
39430				right: 0,
39431				top: totalTopBoxesHeight,
39432				bottom: totalBottomBoxesHeight
39433			};
39434
39435			if (minBoxSize) {
39436				box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
39437			}
39438		}
39439
39440		// Let the left layout know the final margin
39441		helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
39442
39443		// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
39444		totalLeftBoxesWidth = leftPadding;
39445		totalRightBoxesWidth = rightPadding;
39446		totalTopBoxesHeight = topPadding;
39447		totalBottomBoxesHeight = bottomPadding;
39448
39449		helpers.each(leftBoxes, function(box) {
39450			totalLeftBoxesWidth += box.width;
39451		});
39452
39453		helpers.each(rightBoxes, function(box) {
39454			totalRightBoxesWidth += box.width;
39455		});
39456
39457		helpers.each(topBoxes, function(box) {
39458			totalTopBoxesHeight += box.height;
39459		});
39460		helpers.each(bottomBoxes, function(box) {
39461			totalBottomBoxesHeight += box.height;
39462		});
39463
39464		// We may be adding some padding to account for rotated x axis labels
39465		var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);
39466		totalLeftBoxesWidth += leftPaddingAddition;
39467		totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);
39468
39469		var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0);
39470		totalTopBoxesHeight += topPaddingAddition;
39471		totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0);
39472
39473		// Figure out if our chart area changed. This would occur if the dataset layout label rotation
39474		// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
39475		// without calling `fit` again
39476		var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
39477		var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
39478
39479		if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
39480			helpers.each(leftBoxes, function(box) {
39481				box.height = newMaxChartAreaHeight;
39482			});
39483
39484			helpers.each(rightBoxes, function(box) {
39485				box.height = newMaxChartAreaHeight;
39486			});
39487
39488			helpers.each(topBoxes, function(box) {
39489				if (!box.fullWidth) {
39490					box.width = newMaxChartAreaWidth;
39491				}
39492			});
39493
39494			helpers.each(bottomBoxes, function(box) {
39495				if (!box.fullWidth) {
39496					box.width = newMaxChartAreaWidth;
39497				}
39498			});
39499
39500			maxChartAreaHeight = newMaxChartAreaHeight;
39501			maxChartAreaWidth = newMaxChartAreaWidth;
39502		}
39503
39504		// Step 7 - Position the boxes
39505		var left = leftPadding + leftPaddingAddition;
39506		var top = topPadding + topPaddingAddition;
39507
39508		function placeBox(box) {
39509			if (box.isHorizontal()) {
39510				box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth;
39511				box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;
39512				box.top = top;
39513				box.bottom = top + box.height;
39514
39515				// Move to next point
39516				top = box.bottom;
39517
39518			} else {
39519
39520				box.left = left;
39521				box.right = left + box.width;
39522				box.top = totalTopBoxesHeight;
39523				box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
39524
39525				// Move to next point
39526				left = box.right;
39527			}
39528		}
39529
39530		helpers.each(leftBoxes.concat(topBoxes), placeBox);
39531
39532		// Account for chart width and height
39533		left += maxChartAreaWidth;
39534		top += maxChartAreaHeight;
39535
39536		helpers.each(rightBoxes, placeBox);
39537		helpers.each(bottomBoxes, placeBox);
39538
39539		// Step 8
39540		chart.chartArea = {
39541			left: totalLeftBoxesWidth,
39542			top: totalTopBoxesHeight,
39543			right: totalLeftBoxesWidth + maxChartAreaWidth,
39544			bottom: totalTopBoxesHeight + maxChartAreaHeight
39545		};
39546
39547		// Step 9
39548		helpers.each(chartAreaBoxes, function(box) {
39549			box.left = chart.chartArea.left;
39550			box.top = chart.chartArea.top;
39551			box.right = chart.chartArea.right;
39552			box.bottom = chart.chartArea.bottom;
39553
39554			box.update(maxChartAreaWidth, maxChartAreaHeight);
39555		});
39556	}
39557};
39558
39559},{"45":45}],31:[function(require,module,exports){
39560'use strict';
39561
39562var defaults = require(25);
39563var helpers = require(45);
39564
39565defaults._set('global', {
39566	plugins: {}
39567});
39568
39569/**
39570 * The plugin service singleton
39571 * @namespace Chart.plugins
39572 * @since 2.1.0
39573 */
39574module.exports = {
39575	/**
39576	 * Globally registered plugins.
39577	 * @private
39578	 */
39579	_plugins: [],
39580
39581	/**
39582	 * This identifier is used to invalidate the descriptors cache attached to each chart
39583	 * when a global plugin is registered or unregistered. In this case, the cache ID is
39584	 * incremented and descriptors are regenerated during following API calls.
39585	 * @private
39586	 */
39587	_cacheId: 0,
39588
39589	/**
39590	 * Registers the given plugin(s) if not already registered.
39591	 * @param {Array|Object} plugins plugin instance(s).
39592	 */
39593	register: function(plugins) {
39594		var p = this._plugins;
39595		([]).concat(plugins).forEach(function(plugin) {
39596			if (p.indexOf(plugin) === -1) {
39597				p.push(plugin);
39598			}
39599		});
39600
39601		this._cacheId++;
39602	},
39603
39604	/**
39605	 * Unregisters the given plugin(s) only if registered.
39606	 * @param {Array|Object} plugins plugin instance(s).
39607	 */
39608	unregister: function(plugins) {
39609		var p = this._plugins;
39610		([]).concat(plugins).forEach(function(plugin) {
39611			var idx = p.indexOf(plugin);
39612			if (idx !== -1) {
39613				p.splice(idx, 1);
39614			}
39615		});
39616
39617		this._cacheId++;
39618	},
39619
39620	/**
39621	 * Remove all registered plugins.
39622	 * @since 2.1.5
39623	 */
39624	clear: function() {
39625		this._plugins = [];
39626		this._cacheId++;
39627	},
39628
39629	/**
39630	 * Returns the number of registered plugins?
39631	 * @returns {Number}
39632	 * @since 2.1.5
39633	 */
39634	count: function() {
39635		return this._plugins.length;
39636	},
39637
39638	/**
39639	 * Returns all registered plugin instances.
39640	 * @returns {Array} array of plugin objects.
39641	 * @since 2.1.5
39642	 */
39643	getAll: function() {
39644		return this._plugins;
39645	},
39646
39647	/**
39648	 * Calls enabled plugins for `chart` on the specified hook and with the given args.
39649	 * This method immediately returns as soon as a plugin explicitly returns false. The
39650	 * returned value can be used, for instance, to interrupt the current action.
39651	 * @param {Object} chart - The chart instance for which plugins should be called.
39652	 * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate').
39653	 * @param {Array} [args] - Extra arguments to apply to the hook call.
39654	 * @returns {Boolean} false if any of the plugins return false, else returns true.
39655	 */
39656	notify: function(chart, hook, args) {
39657		var descriptors = this.descriptors(chart);
39658		var ilen = descriptors.length;
39659		var i, descriptor, plugin, params, method;
39660
39661		for (i = 0; i < ilen; ++i) {
39662			descriptor = descriptors[i];
39663			plugin = descriptor.plugin;
39664			method = plugin[hook];
39665			if (typeof method === 'function') {
39666				params = [chart].concat(args || []);
39667				params.push(descriptor.options);
39668				if (method.apply(plugin, params) === false) {
39669					return false;
39670				}
39671			}
39672		}
39673
39674		return true;
39675	},
39676
39677	/**
39678	 * Returns descriptors of enabled plugins for the given chart.
39679	 * @returns {Array} [{ plugin, options }]
39680	 * @private
39681	 */
39682	descriptors: function(chart) {
39683		var cache = chart.$plugins || (chart.$plugins = {});
39684		if (cache.id === this._cacheId) {
39685			return cache.descriptors;
39686		}
39687
39688		var plugins = [];
39689		var descriptors = [];
39690		var config = (chart && chart.config) || {};
39691		var options = (config.options && config.options.plugins) || {};
39692
vendor: 9,411 bytes, lines 39693-39921
39693		this._plugins.concat(config.plugins || []).forEach(function(plugin) {
39694			var idx = plugins.indexOf(plugin);
39695			if (idx !== -1) {
39696				return;
39697			}
39698
39699			var id = plugin.id;
39700			var opts = options[id];
39701			if (opts === false) {
39702				return;
39703			}
39704
39705			if (opts === true) {
39706				opts = helpers.clone(defaults.global.plugins[id]);
39707			}
39708
39709			plugins.push(plugin);
39710			descriptors.push({
39711				plugin: plugin,
39712				options: opts || {}
39713			});
39714		});
39715
39716		cache.descriptors = descriptors;
39717		cache.id = this._cacheId;
39718		return descriptors;
39719	},
39720
39721	/**
39722	 * Invalidates cache for the given chart: descriptors hold a reference on plugin option,
39723	 * but in some cases, this reference can be changed by the user when updating options.
39724	 * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167
39725	 * @private
39726	 */
39727	_invalidate: function(chart) {
39728		delete chart.$plugins;
39729	}
39730};
39731
39732/**
39733 * Plugin extension hooks.
39734 * @interface IPlugin
39735 * @since 2.1.0
39736 */
39737/**
39738 * @method IPlugin#beforeInit
39739 * @desc Called before initializing `chart`.
39740 * @param {Chart.Controller} chart - The chart instance.
39741 * @param {Object} options - The plugin options.
39742 */
39743/**
39744 * @method IPlugin#afterInit
39745 * @desc Called after `chart` has been initialized and before the first update.
39746 * @param {Chart.Controller} chart - The chart instance.
39747 * @param {Object} options - The plugin options.
39748 */
39749/**
39750 * @method IPlugin#beforeUpdate
39751 * @desc Called before updating `chart`. If any plugin returns `false`, the update
39752 * is cancelled (and thus subsequent render(s)) until another `update` is triggered.
39753 * @param {Chart.Controller} chart - The chart instance.
39754 * @param {Object} options - The plugin options.
39755 * @returns {Boolean} `false` to cancel the chart update.
39756 */
39757/**
39758 * @method IPlugin#afterUpdate
39759 * @desc Called after `chart` has been updated and before rendering. Note that this
39760 * hook will not be called if the chart update has been previously cancelled.
39761 * @param {Chart.Controller} chart - The chart instance.
39762 * @param {Object} options - The plugin options.
39763 */
39764/**
39765 * @method IPlugin#beforeDatasetsUpdate
39766 * @desc Called before updating the `chart` datasets. If any plugin returns `false`,
39767 * the datasets update is cancelled until another `update` is triggered.
39768 * @param {Chart.Controller} chart - The chart instance.
39769 * @param {Object} options - The plugin options.
39770 * @returns {Boolean} false to cancel the datasets update.
39771 * @since version 2.1.5
39772*/
39773/**
39774 * @method IPlugin#afterDatasetsUpdate
39775 * @desc Called after the `chart` datasets have been updated. Note that this hook
39776 * will not be called if the datasets update has been previously cancelled.
39777 * @param {Chart.Controller} chart - The chart instance.
39778 * @param {Object} options - The plugin options.
39779 * @since version 2.1.5
39780 */
39781/**
39782 * @method IPlugin#beforeDatasetUpdate
39783 * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin
39784 * returns `false`, the datasets update is cancelled until another `update` is triggered.
39785 * @param {Chart} chart - The chart instance.
39786 * @param {Object} args - The call arguments.
39787 * @param {Number} args.index - The dataset index.
39788 * @param {Object} args.meta - The dataset metadata.
39789 * @param {Object} options - The plugin options.
39790 * @returns {Boolean} `false` to cancel the chart datasets drawing.
39791 */
39792/**
39793 * @method IPlugin#afterDatasetUpdate
39794 * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note
39795 * that this hook will not be called if the datasets update has been previously cancelled.
39796 * @param {Chart} chart - The chart instance.
39797 * @param {Object} args - The call arguments.
39798 * @param {Number} args.index - The dataset index.
39799 * @param {Object} args.meta - The dataset metadata.
39800 * @param {Object} options - The plugin options.
39801 */
39802/**
39803 * @method IPlugin#beforeLayout
39804 * @desc Called before laying out `chart`. If any plugin returns `false`,
39805 * the layout update is cancelled until another `update` is triggered.
39806 * @param {Chart.Controller} chart - The chart instance.
39807 * @param {Object} options - The plugin options.
39808 * @returns {Boolean} `false` to cancel the chart layout.
39809 */
39810/**
39811 * @method IPlugin#afterLayout
39812 * @desc Called after the `chart` has been layed out. Note that this hook will not
39813 * be called if the layout update has been previously cancelled.
39814 * @param {Chart.Controller} chart - The chart instance.
39815 * @param {Object} options - The plugin options.
39816 */
39817/**
39818 * @method IPlugin#beforeRender
39819 * @desc Called before rendering `chart`. If any plugin returns `false`,
39820 * the rendering is cancelled until another `render` is triggered.
39821 * @param {Chart.Controller} chart - The chart instance.
39822 * @param {Object} options - The plugin options.
39823 * @returns {Boolean} `false` to cancel the chart rendering.
39824 */
39825/**
39826 * @method IPlugin#afterRender
39827 * @desc Called after the `chart` has been fully rendered (and animation completed). Note
39828 * that this hook will not be called if the rendering has been previously cancelled.
39829 * @param {Chart.Controller} chart - The chart instance.
39830 * @param {Object} options - The plugin options.
39831 */
39832/**
39833 * @method IPlugin#beforeDraw
39834 * @desc Called before drawing `chart` at every animation frame specified by the given
39835 * easing value. If any plugin returns `false`, the frame drawing is cancelled until
39836 * another `render` is triggered.
39837 * @param {Chart.Controller} chart - The chart instance.
39838 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
39839 * @param {Object} options - The plugin options.
39840 * @returns {Boolean} `false` to cancel the chart drawing.
39841 */
39842/**
39843 * @method IPlugin#afterDraw
39844 * @desc Called after the `chart` has been drawn for the specific easing value. Note
39845 * that this hook will not be called if the drawing has been previously cancelled.
39846 * @param {Chart.Controller} chart - The chart instance.
39847 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
39848 * @param {Object} options - The plugin options.
39849 */
39850/**
39851 * @method IPlugin#beforeDatasetsDraw
39852 * @desc Called before drawing the `chart` datasets. If any plugin returns `false`,
39853 * the datasets drawing is cancelled until another `render` is triggered.
39854 * @param {Chart.Controller} chart - The chart instance.
39855 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
39856 * @param {Object} options - The plugin options.
39857 * @returns {Boolean} `false` to cancel the chart datasets drawing.
39858 */
39859/**
39860 * @method IPlugin#afterDatasetsDraw
39861 * @desc Called after the `chart` datasets have been drawn. Note that this hook
39862 * will not be called if the datasets drawing has been previously cancelled.
39863 * @param {Chart.Controller} chart - The chart instance.
39864 * @param {Number} easingValue - The current animation value, between 0.0 and 1.0.
39865 * @param {Object} options - The plugin options.
39866 */
39867/**
39868 * @method IPlugin#beforeDatasetDraw
39869 * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets
39870 * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing
39871 * is cancelled until another `render` is triggered.
39872 * @param {Chart} chart - The chart instance.
39873 * @param {Object} args - The call arguments.
39874 * @param {Number} args.index - The dataset index.
39875 * @param {Object} args.meta - The dataset metadata.
39876 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
39877 * @param {Object} options - The plugin options.
39878 * @returns {Boolean} `false` to cancel the chart datasets drawing.
39879 */
39880/**
39881 * @method IPlugin#afterDatasetDraw
39882 * @desc Called after the `chart` datasets at the given `args.index` have been drawn
39883 * (datasets are drawn in the reverse order). Note that this hook will not be called
39884 * if the datasets drawing has been previously cancelled.
39885 * @param {Chart} chart - The chart instance.
39886 * @param {Object} args - The call arguments.
39887 * @param {Number} args.index - The dataset index.
39888 * @param {Object} args.meta - The dataset metadata.
39889 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
39890 * @param {Object} options - The plugin options.
39891 */
39892/**
39893 * @method IPlugin#beforeTooltipDraw
39894 * @desc Called before drawing the `tooltip`. If any plugin returns `false`,
39895 * the tooltip drawing is cancelled until another `render` is triggered.
39896 * @param {Chart} chart - The chart instance.
39897 * @param {Object} args - The call arguments.
39898 * @param {Object} args.tooltip - The tooltip.
39899 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
39900 * @param {Object} options - The plugin options.
39901 * @returns {Boolean} `false` to cancel the chart tooltip drawing.
39902 */
39903/**
39904 * @method IPlugin#afterTooltipDraw
39905 * @desc Called after drawing the `tooltip`. Note that this hook will not
39906 * be called if the tooltip drawing has been previously cancelled.
39907 * @param {Chart} chart - The chart instance.
39908 * @param {Object} args - The call arguments.
39909 * @param {Object} args.tooltip - The tooltip.
39910 * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0.
39911 * @param {Object} options - The plugin options.
39912 */
39913/**
39914 * @method IPlugin#beforeEvent
39915 * @desc Called before processing the specified `event`. If any plugin returns `false`,
39916 * the event will be discarded.
39917 * @param {Chart.Controller} chart - The chart instance.
39918 * @param {IEvent} event - The event object.
39919 * @param {Object} options - The plugin options.
39920 */
39921/**
39922 * @method IPlugin#afterEvent
39923 * @desc Called after the `event` has been consumed. Note that this hook
39924 * will not be called if the `event` has been previously discarded.
39925 * @param {Chart.Controller} chart - The chart instance.
39926 * @param {IEvent} event - The event object.
39927 * @param {Object} options - The plugin options.
39928 */
39929/**
39930 * @method IPlugin#resize
39931 * @desc Called after the chart as been resized.
39932 * @param {Chart.Controller} chart - The chart instance.
39933 * @param {Number} size - The new canvas display size (eq. canvas.style width & height).
39934 * @param {Object} options - The plugin options.
39935 */
39936/**
39937 * @method IPlugin#destroy
39938 * @desc Called after the chart as been destroyed.
39939 * @param {Chart.Controller} chart - The chart instance.
39940 * @param {Object} options - The plugin options.
39941 */
39942
39943},{"25":25,"45":45}],32:[function(require,module,exports){
39944'use strict';
39945
39946var defaults = require(25);
39947var Element = require(26);
39948var helpers = require(45);
39949var Ticks = require(34);
39950
39951defaults._set('scale', {
39952	display: true,
39953	position: 'left',
39954	offset: false,
39955
39956	// grid line settings
39957	gridLines: {
39958		display: true,
39959		color: 'rgba(0, 0, 0, 0.1)',
39960		lineWidth: 1,
39961		drawBorder: true,
39962		drawOnChartArea: true,
39963		drawTicks: true,
39964		tickMarkLength: 10,
39965		zeroLineWidth: 1,
39966		zeroLineColor: 'rgba(0,0,0,0.25)',
39967		zeroLineBorderDash: [],
39968		zeroLineBorderDashOffset: 0.0,
39969		offsetGridLines: false,
39970		borderDash: [],
39971		borderDashOffset: 0.0
39972	},
39973
39974	// scale label
39975	scaleLabel: {
39976		// display property
39977		display: false,
39978
39979		// actual label
39980		labelString: '',
39981
39982		// line height
39983		lineHeight: 1.2,
39984
39985		// top/bottom padding
39986		padding: {
39987			top: 4,
39988			bottom: 4
39989		}
39990	},
39991
39992	// label settings
39993	ticks: {
39994		beginAtZero: false,
39995		minRotation: 0,
39996		maxRotation: 50,
39997		mirror: false,
39998		padding: 0,
39999		reverse: false,
40000		display: true,
40001		autoSkip: true,
40002		autoSkipPadding: 0,
40003		labelOffset: 0,
40004		// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
40005		callback: Ticks.formatters.values,
40006		minor: {},
40007		major: {}
40008	}
40009});
40010
40011function labelsFromTicks(ticks) {
40012	var labels = [];
40013	var i, ilen;
40014
40015	for (i = 0, ilen = ticks.length; i < ilen; ++i) {
40016		labels.push(ticks[i].label);
40017	}
40018
40019	return labels;
40020}
40021
40022function getLineValue(scale, index, offsetGridLines) {
40023	var lineValue = scale.getPixelForTick(index);
40024
40025	if (offsetGridLines) {
40026		if (index === 0) {
40027			lineValue -= (scale.getPixelForTick(1) - lineValue) / 2;
40028		} else {
40029			lineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2;
40030		}
40031	}
40032	return lineValue;
40033}
40034
40035module.exports = function(Chart) {
40036
40037	function computeTextSize(context, tick, font) {
40038		return helpers.isArray(tick) ?
40039			helpers.longestText(context, font, tick) :
40040			context.measureText(tick).width;
40041	}
40042
40043	function parseFontOptions(options) {
40044		var valueOrDefault = helpers.valueOrDefault;
40045		var globalDefaults = defaults.global;
40046		var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
40047		var style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
40048		var family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
40049
40050		return {
40051			size: size,
40052			style: style,
40053			family: family,
40054			font: helpers.fontString(size, style, family)
40055		};
40056	}
40057
40058	function parseLineHeight(options) {
40059		return helpers.options.toLineHeight(
40060			helpers.valueOrDefault(options.lineHeight, 1.2),
40061			helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize));
40062	}
40063
40064	Chart.Scale = Element.extend({
40065		/**
40066		 * Get the padding needed for the scale
40067		 * @method getPadding
40068		 * @private
40069		 * @returns {Padding} the necessary padding
40070		 */
40071		getPadding: function() {
40072			var me = this;
40073			return {
40074				left: me.paddingLeft || 0,
40075				top: me.paddingTop || 0,
40076				right: me.paddingRight || 0,
40077				bottom: me.paddingBottom || 0
40078			};
40079		},
40080
40081		/**
40082		 * Returns the scale tick objects ({label, major})
40083		 * @since 2.7
40084		 */
40085		getTicks: function() {
40086			return this._ticks;
40087		},
40088
40089		// These methods are ordered by lifecyle. Utilities then follow.
40090		// Any function defined here is inherited by all scale types.
40091		// Any function can be extended by the scale type
40092
40093		mergeTicksOptions: function() {
40094			var ticks = this.options.ticks;
40095			if (ticks.minor === false) {
40096				ticks.minor = {
40097					display: false
40098				};
40099			}
40100			if (ticks.major === false) {
40101				ticks.major = {
40102					display: false
40103				};
40104			}
40105			for (var key in ticks) {
40106				if (key !== 'major' && key !== 'minor') {
40107					if (typeof ticks.minor[key] === 'undefined') {
40108						ticks.minor[key] = ticks[key];
40109					}
40110					if (typeof ticks.major[key] === 'undefined') {
40111						ticks.major[key] = ticks[key];
40112					}
40113				}
40114			}
40115		},
40116		beforeUpdate: function() {
40117			helpers.callback(this.options.beforeUpdate, [this]);
40118		},
40119		update: function(maxWidth, maxHeight, margins) {
40120			var me = this;
40121			var i, ilen, labels, label, ticks, tick;
40122
40123			// Update Lifecycle - Probably don't want to ever extend or over
40123write this function ;)
40124			me.beforeUpdate();
40125
40126			// Absorb the master measurements
40127			me.maxWidth = maxWidth;
40128			me.maxHeight = maxHeight;
40129			me.margins = helpers.extend({
40130				left: 0,
40131				right: 0,
40132				top: 0,
40133				bottom: 0
40134			}, margins);
40135			me.longestTextCache = me.longestTextCache || {};
40136
40137			// Dimensions
40138			me.beforeSetDimensions();
40139			me.setDimensions();
40140			me.afterSetDimensions();
40141
40142			// Data min/max
40143			me.beforeDataLimits();
40144			me.determineDataLimits();
40145			me.afterDataLimits();
40146
40147			// Ticks - `this.ticks` is now DEPRECATED!
40148			// Internal ticks are now stored as objects in the PRIVATE `this._ticks` member
40149			// and must not be accessed directly from outside this class. `this.ticks` being
40150			// around for long time and not marked as private, we can't change its structure
40151			// without unexpected breaking changes. If you need to access the scale ticks,
40152			// use scale.getTicks() instead.
40153
40154			me.beforeBuildTicks();
40155
40156			// New implementations should return an array of objects but for BACKWARD COMPAT,
40157			// we still support no return (`this.ticks` internally set by calling this method).
40158			ticks = me.buildTicks() || [];
40159
40160			me.afterBuildTicks();
40161
40162			me.beforeTickToLabelConversion();
40163
40164			// New implementations should return the formatted tick labels but for BACKWARD
40165			// COMPAT, we still support no return (`this.ticks` internally changed by calling
40166			// this method and supposed to contain only string values).
40167			labels = me.convertTicksToLabels(ticks) || me.ticks;
40168
40169			me.afterTickToLabelConversion();
40170
40171			me.ticks = labels;   // BACKWARD COMPATIBILITY
40172
40173			// IMPORTANT: from this point, we consider that `this.ticks` will NEVER change!
40174
40175			// BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`)
40176			for (i = 0, ilen = labels.length; i < ilen; ++i) {
40177				label = labels[i];
40178				tick = ticks[i];
40179				if (!tick) {
40180					ticks.push(tick = {
40181						label: label,
40182						major: false
40183					});
40184				} else {
40185					tick.label = label;
40186				}
40187			}
40188
40189			me._ticks = ticks;
40190
40191			// Tick Rotation
40192			me.beforeCalculateTickRotation();
40193			me.calculateTickRotation();
40194			me.afterCalculateTickRotation();
40195			// Fit
40196			me.beforeFit();
40197			me.fit();
40198			me.afterFit();
40199			//
40200			me.afterUpdate();
40201
40202			return me.minSize;
40203
40204		},
40205		afterUpdate: function() {
40206			helpers.callback(this.options.afterUpdate, [this]);
40207		},
40208
40209		//
40210
40211		beforeSetDimensions: function() {
40212			helpers.callback(this.options.beforeSetDimensions, [this]);
40213		},
40214		setDimensions: function() {
40215			var me = this;
40216			// Set the unconstrained dimension before label rotation
40217			if (me.isHorizontal()) {
40218				// Reset position before calculating rotation
40219				me.width = me.maxWidth;
40220				me.left = 0;
40221				me.right = me.width;
40222			} else {
40223				me.height = me.maxHeight;
40224
40225				// Reset position before calculating rotation
40226				me.top = 0;
40227				me.bottom = me.height;
40228			}
40229
40230			// Reset padding
40231			me.paddingLeft = 0;
40232			me.paddingTop = 0;
40233			me.paddingRight = 0;
40234			me.paddingBottom = 0;
40235		},
40236		afterSetDimensions: function() {
40237			helpers.callback(this.options.afterSetDimensions, [this]);
40238		},
40239
40240		// Data limits
40241		beforeDataLimits: function() {
40242			helpers.callback(this.options.beforeDataLimits, [this]);
40243		},
40244		determineDataLimits: helpers.noop,
40245		afterDataLimits: function() {
40246			helpers.callback(this.options.afterDataLimits, [this]);
40247		},
40248
40249		//
40250		beforeBuildTicks: function() {
40251			helpers.callback(this.options.beforeBuildTicks, [this]);
40252		},
40253		buildTicks: helpers.noop,
40254		afterBuildTicks: function() {
40255			helpers.callback(this.options.afterBuildTicks, [this]);
40256		},
40257
40258		beforeTickToLabelConversion: function() {
40259			helpers.callback(this.options.beforeTickToLabelConversion, [this]);
40260		},
40261		convertTicksToLabels: function() {
40262			var me = this;
40263			// Convert ticks to strings
40264			var tickOpts = me.options.ticks;
40265			me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this);
40266		},
40267		afterTickToLabelConversion: function() {
40268			helpers.callback(this.options.afterTickToLabelConversion, [this]);
40269		},
40270
40271		//
40272
40273		beforeCalculateTickRotation: function() {
40274			helpers.callback(this.options.beforeCalculateTickRotation, [this]);
40275		},
40276		calculateTickRotation: function() {
40277			var me = this;
40278			var context = me.ctx;
40279			var tickOpts = me.options.ticks;
40280			var labels = labelsFromTicks(me._ticks);
40281
40282			// Get the width of each grid by calculating the difference
40283			// between x offsets between 0 and 1.
40284			var tickFont = parseFontOptions(tickOpts);
40285			context.font = tickFont.font;
40286
40287			var labelRotation = tickOpts.minRotation || 0;
40288
40289			if (labels.length && me.options.display && me.isHorizontal()) {
40290				var originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache);
40291				var labelWidth = originalLabelWidth;
40292				var cosRotation, sinRotation;
40293
40294				// Allow 3 pixels x2 padding either side for label readability
40295				var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6;
40296
40297				// Max label rotation can be set or default to 90 - also act as a loop counter
40298				while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) {
40299					var angleRadians = helpers.toRadians(labelRotation);
40300					cosRotation = Math.cos(angleRadians);
40301					sinRotation = Math.sin(angleRadians);
40302
40303					if (sinRotation * originalLabelWidth > me.maxHeight) {
40304						// go back one step
40305						labelRotation--;
40306						break;
40307					}
40308
40309					labelRotation++;
40310					labelWidth = cosRotation * originalLabelWidth;
40311				}
40312			}
40313
40314			me.labelRotation = labelRotation;
40315		},
40316		afterCalculateTickRotation: function() {
40317			helpers.callback(this.options.afterCalculateTickRotation, [this]);
40318		},
40319
40320		//
40321
40322		beforeFit: function() {
40323			helpers.callback(this.options.beforeFit, [this]);
40324		},
40325		fit: function() {
40326			var me = this;
40327			// Reset
40328			var minSize = me.minSize = {
40329				width: 0,
40330				height: 0
40331			};
40332
40333			var labels = labelsFromTicks(me._ticks);
40334
40335			var opts = me.options;
40336			var tickOpts = opts.ticks;
40337			var scaleLabelOpts = opts.scaleLabel;
40338			var gridLineOpts = opts.gridLines;
40339			var display = opts.display;
40340			var isHorizontal = me.isHorizontal();
40341
40342			var tickFont = parseFontOptions(tickOpts);
40343			var tickMarkLength = opts.gridLines.tickMarkLength;
40344
40345			// Width
40346			if (isHorizontal) {
40347				// subtract the margins to line up with the chartArea if we are a full width scale
40348				minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth;
40349			} else {
40350				minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
40351			}
40352
40353			// height
40354			if (isHorizontal) {
40355				minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0;
40356			} else {
40357				minSize.height = me.maxHeight; // fill all the height
40358			}
40359
40360			// Are we showing a title for the scale?
40361			if (scaleLabelOpts.display && display) {
40362				var scaleLabelLineHeight = parseLineHeight(scaleLabelOpts);
40363				var scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding);
40364				var deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height;
40365
40366				if (isHorizontal) {
40367					minSize.height += deltaHeight;
40368				} else {
40369					minSize.width += deltaHeight;
40370				}
40371			}
40372
40373			// Don't bother fitting the ticks if we are not showing them
40374			if (tickOpts.display && display) {
40375				var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache);
40376				var tallestLabelHeightInLines = helpers.numberOfLabelLines(labels);
40377				var lineSpace = tickFont.size * 0.5;
40378				var tickPadding = me.options.ticks.padding;
40379
40380				if (isHorizontal) {
40381					// A horizontal axis is more constrained by the height.
40382					me.longestLabelWidth = largestTextWidth;
40383
40384					var angleRadians = helpers.toRadians(me.labelRotation);
40385					var cosRotation = Math.cos(angleRadians);
40386					var sinRotation = Math.sin(angleRadians);
40387
40388					// TODO - improve this calculation
40389					var labelHeight = (sinRotation * largestTextWidth)
40390						+ (tickFont.size * tallestLabelHeightInLines)
40391						+ (lineSpace * (tallestLabelHeightInLines - 1))
40392						+ lineSpace; // padding
40393
40394					minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);
40395
40396					me.ctx.font = tickFont.font;
40397					var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font);
40398					var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font);
40399
40400					// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned
40401					// which means that the right padding is dominated by the font height
40402					if (me.labelRotation !== 0) {
40403						me.paddingLeft = opts.position === 'bottom' ? (cosRotation * firstLabelWidth) + 3 : (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges
40404						me.paddingRight = opts.position === 'bottom' ? (cosRotation * lineSpace) + 3 : (cosRotation * lastLabelWidth) + 3;
40405					} else {
40406						me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
40407						me.paddingRight = lastLabelWidth / 2 + 3;
40408					}
40409				} else {
40410					// A vertical axis is more constrained by the width. Labels are the
40411					// dominant factor here, so get that length first and account for padding
40412					if (tickOpts.mirror) {
40413						largestTextWidth = 0;
40414					} else {
40415						// use lineSpace for consistency with horizontal axis
40416						// tickPadding is not implemented for horizontal
40417						largestTextWidth += tickPadding + lineSpace;
40418					}
40419
40420					minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth);
40421
40422					me.paddingTop = tickFont.size / 2;
40423					me.paddingBottom = tickFont.size / 2;
40424				}
40425			}
40426
40427			me.handleMargins();
40428
40429			me.width = minSize.width;
40430			me.height = minSize.height;
40431		},
40432
40433		/**
40434		 * Handle margins and padding interactions
40435		 * @private
40436		 */
40437		handleMargins: function() {
40438			var me = this;
40439			if (me.margins) {
40440				me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0);
40441				me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0);
40442				me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0);
40443				me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0);
40444			}
40445		},
40446
40447		afterFit: function() {
40448			helpers.callback(this.options.afterFit, [this]);
40449		},
40450
40451		// Shared Methods
40452		isHorizontal: function() {
40453			return this.options.position === 'top' || this.options.position === 'bottom';
40454		},
40455		isFullWidth: function() {
40456			return (this.options.fullWidth);
40457		},
40458
40459		// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
40460		getRightValue: function(rawValue) {
40461			// Null and undefined values first
40462			if (helpers.isNullOrUndef(rawValue)) {
40463				return NaN;
40464			}
40465			// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values
40466			if (typeof rawValue === 'number' && !isFinite(rawValue)) {
40467				return NaN;
40468			}
40469			// If it is in fact an object, dive in one more level
40470			if (rawValue) {
40471				if (this.isHorizontal()) {
40472					if (rawValue.x !== undefined) {
40473						return this.getRightValue(rawValue.x);
40474					}
40475				} else if (rawValue.y !== undefined) {
40476					return this.getRightValue(rawValue.y);
40477				}
40478			}
40479
40480			// Value is good, return it
40481			return rawValue;
40482		},
40483
40484		/**
40485		 * Used to get the value to display in the tooltip for the data at the given index
40486		 * @param index
40487		 * @param datasetIndex
40488		 */
40489		getLabelForIndex: helpers.noop,
40490
40491		/**
40492		 * Returns the location of the given data point. Value can either be an index or a numerical value
40493		 * The coordinate (0, 0) is at the upper-left corner of the canvas
40494		 * @param value
40495		 * @param index
40496		 * @param datasetIndex
40497		 */
40498		getPixelForValue: helpers.noop,
40499
40500		/**
40501		 * Used to get the data value from a given pixel. This is the inverse of getPixelForValue
40502		 * The coordinate (0, 0) is at the upper-left corner of the canvas
40503		 * @param pixel
40504		 */
40505		getValueForPixel: helpers.noop,
40506
40507		/**
40508		 * Returns the location of the tick at the given index
40509		 * The coordinate (0, 0) is at the upper-left corner of the canvas
40510		 */
40511		getPixelForTick: function(index) {
40512			var me = this;
40513			var offset = me.options.offset;
40514			if (me.isHorizontal()) {
40515				var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
40516				var tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
40517				var pixel = (tickWidth * index) + me.paddingLeft;
40518
40519				if (offset) {
40520					pixel += tickWidth / 2;
40521				}
40522
40523				var finalVal = me.left + Math.round(pixel);
40524				finalVal += me.isFullWidth() ? me.margins.left : 0;
40525				return finalVal;
40526			}
40527			var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
40528			return me.top + (index * (innerHeight / (me._ticks.length - 1)));
40529		},
40530
40531		/**
40532		 * Utility for getting the pixel location of a percentage of scale
40533		 * The coordinate (0, 0) is at the upper-left corner of the canvas
40534		 */
40535		getPixelForDecimal: function(decimal) {
40536			var me = this;
40537			if (me.isHorizontal()) {
40538				var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
40539				var valueOffset = (innerWidth * decimal) + me.paddingLeft;
40540
40541				var finalVal = me.left + Math.round(valueOffset);
40542				finalVal += me.isFullWidth() ? me.margins.left : 0;
40543				return finalVal;
40544			}
40545			return me.top + (decimal * me.height);
40546		},
40547
40548		/**
40549		 * Returns the pixel for the minimum chart value
40550		 * The coordinate (0, 0) is at the upper-left corner of the canvas
40551		 */
40552		getBasePixel: function() {
40553			return this.getPixelForValue(this.getBaseValue());
40554		},
40555
40556		getBaseValue: function() {
40557			var me = this;
40558			var min = me.min;
40559			var max = me.max;
40560
40561			return me.beginAtZero ? 0 :
40562				min < 0 && max < 0 ? max :
40563				min > 0 && max > 0 ? min :
40564				0;
40565		},
40566
40567		/**
40568		 * Returns a subset of ticks to be plotted to avoid overlapping labels.
40569		 * @private
40570		 */
40571		_autoSkip: function(ticks) {
40572			var skipRatio;
40573			var me = this;
40574			var isHorizontal = me.isHorizontal();
40575			var optionTicks = me.options.ticks.minor;
40576			var tickCount = ticks.length;
40577			var labelRotationRadians = helpers.toRadians(me.labelRotation);
40578			var cosRotation = Math.cos(labelRotationRadians);
40579			var longestRotatedLabel = me.longestLabelWidth * cosRotation;
40580			var result = [];
40581			var i, tick, shouldSkip;
40582
40583			// figure out the maximum number of gridlines to show
40584			var maxTicks;
40585			if (optionTicks.maxTicksLimit) {
40586				maxTicks = optionTicks.maxTicksLimit;
40587			}
40588
40589			if (isHorizontal) {
40590				skipRatio = false;
40591
40592				if ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) {
40593					skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight)));
40594				}
40595
40596				// if they defined a max number of optionTicks,
40597				// increase skipRatio until that number is met
40598				if (maxTicks && tickCount > maxTicks) {
40599					skipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks));
40600				}
40601			}
40602
40603			for (i = 0; i < tickCount; i++) {
40604				tick = ticks[i];
40605
40606				// Since we always show the last tick,we need may need to hide the last shown one before
40607				shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount);
40608				if (shouldSkip && i !== tickCount - 1) {
40609					// leave tick in place but make sure it's not displayed (#4635)
40610					delete tick.label;
40611				}
40612				result.push(tick);
40613			}
40614			return result;
40615		},
40616
40617		// Actually draw the scale on the canvas
40618		// @param {rectangle} chartArea : the area of the chart to draw full grid lines on
40619		draw: function(chartArea) {
40620			var me = this;
40621			var options = me.options;
40622			if (!options.display) {
40623				return;
40624			}
40625
40626			var context = me.ctx;
40627			var globalDefaults = defaults.global;
40628			var optionTicks = options.ticks.minor;
40629			var optionMajorTicks = options.ticks.major || optionTicks;
40630			var gridLines = options.gridLines;
40631			var scaleLabel = options.scaleLabel;
40632
40633			var isRotated = me.labelRotation !== 0;
40634			var isHorizontal = me.isHorizontal();
40635
40636			var ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks();
40637			var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
40638			var tickFont = parseFontOptions(optionTicks);
40639			var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor);
40640			var majorTickFont = parseFontOptions(optionMajorTicks);
40641
40642			var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0;
40643
40644			var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
40645			var scaleLabelFont = parseFontOptions(scaleLabel);
40646			var scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding);
40647			var labelRotationRadians = helpers.toRadians(me.labelRotation);
40648
40649			var itemsToDraw = [];
40650
40651			var axisWidth = me.options.gridLines.lineWidth;
40652			var xTickStart = options.position === 'right' ? me.right : me.right - axisWidth - tl;
40653			var xTickEnd = options.position === 'right' ? me.right + tl : me.right;
40654			var yTickStart = options.position === 'bottom' ? me.top + axisWidth : me.bottom - tl - axisWidth;
40655			var yTickEnd = options.position === 'bottom' ? me.top + axisWidth + tl : me.bottom + axisWidth;
40656
40657			helpers.each(ticks, function(tick, index) {
40658				// autoskipper skipped this tick (#4635)
40659				if (helpers.isNullOrUndef(tick.label)) {
40660					return;
40661				}
40662
40663				var label = tick.label;
40664				var lineWidth, lineColor, borderDash, borderDashOffset;
40665				if (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) {
40666					// Draw the first index specially
40667					lineWidth = gridLines.zeroLineWidth;
40668					lineColor = gridLines.zeroLineColor;
40669					borderDash = gridLines.zeroLineBorderDash;
40670					borderDashOffset = gridLines.zeroLineBorderDashOffset;
40671				} else {
40672					lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index);
40673					lineColor = helpers.valueAtIndexOrDefault(gridLines.color, index);
40674					borderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
40675					borderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);
40676				}
40677
40678				// Common properties
40679				var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
40680				var textAlign = 'middle';
40681				var textBaseline = 'middle';
40682				var tickPadding = optionTicks.padding;
40683
40684				if (isHorizontal) {
40685					var labelYOffset = tl + tickPadding;
40686
40687					if (options.position === 'bottom') {
40688						// bottom
40689						textBaseline = !isRotated ? 'top' : 'middle';
40690						textAlign = !isRotated ? 'center' : 'right';
40691						labelY = me.top + labelYOffset;
40692					} else {
40693						// top
40694						textBaseline = !isRotated ? 'bottom' : 'middle';
40695						textAlign = !isRotated ? 'center' : 'left';
40696						labelY = me.bottom - labelYOffset;
40697					}
40698
40699					var xLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);
40700					if (xLineValue < me.left) {
40701						lineColor = 'rgba(0,0,0,0)';
40702					}
40703					xLineValue += helpers.aliasPixel(lineWidth);
40704
40705					labelX = me.getPixelForTick(index) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
40706
40707					tx1 = tx2 = x1 = x2 = xLineValue;
40708					ty1 = yTickStart;
40709					ty2 = yTickEnd;
40710					y1 = chartArea.top;
40711					y2 = chartArea.bottom + axisWidth;
40712				} else {
40713					var isLeft = options.position === 'left';
40714					var labelXOffset;
40715
40716					if (optionTicks.mirror) {
40717						textAlign = isLeft ? 'left' : 'right';
40718						labelXOffset = tickPadding;
40719					} else {
40720						textAlign = isLeft ? 'right' : 'left';
40721						labelXOffset = tl + tickPadding;
40722					}
40723
40724					labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset;
40725
40726					var yLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1);
40727					if (yLineValue < me.top) {
40728						lineColor = 'rgba(0,0,0,0)';
40729					}
40730					yLineValue += helpers.aliasPixel(lineWidth);
40731
40732					labelY = me.getPixelForTick(index) + optionTicks.labelOffset;
40733
40734					tx1 = xTickStart;
40735					tx2 = xTickEnd;
40736					x1 = chartArea.left;
40737					x2 = chartArea.right + axisWidth;
40738					ty1 = ty2 = y1 = y2 = yLineValue;
40739				}
40740
40741				itemsToDraw.push({
40742					tx1: tx1,
40743					ty1: ty1,
40744					tx2: tx2,
40745					ty2: ty2,
40746					x1: x1,
40747					y1: y1,
40748					x2: x2,
40749					y2: y2,
40750					labelX: labelX,
40751					labelY: labelY,
40752					glWidth: lineWidth,
40753					glColor: lineColor,
40754					glBorderDash: borderDash,
40755					glBorderDashOffset: borderDashOffset,
40756					rotation: -1 * labelRotationRadians,
40757					label: label,
40758					major: tick.major,
40759					textBaseline: textBaseline,
40760					textAlign: textAlign
40761				});
40762			});
40763
40764			// Draw all of the tick labels, tick marks, and grid lines at the correct places
40765			helpers.each(itemsToDraw, function(itemToDraw) {
40766				if (gridLines.display) {
40767					context.save();
40768					context.lineWidth = itemToDraw.glWidth;
40769					context.strokeStyle = itemToDraw.glColor;
40770					if (context.setLineDash) {
40771						context.setLineDash(itemToDraw.glBorderDash);
40772						context.lineDashOffset = itemToDraw.glBorderDashOffset;
40773					}
40774
40775					context.beginPath();
40776
40777					if (gridLines.drawTicks) {
40778						context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
40779						context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
40780					}
40781
40782					if (gridLines.drawOnChartArea) {
40783						context.moveTo(itemToDraw.x1, itemToDraw.y1);
40784						context.lineTo(itemToDraw.x2, itemToDraw.y2);
40785					}
40786
40787					context.stroke();
40788					context.restore();
40789				}
40790
40791				if (optionTicks.display) {
40792					// Make sure we draw text in the correct color and font
40793					context.save();
40794					context.translate(itemToDraw.labelX, itemToDraw.labelY);
40795					context.rotate(itemToDraw.rotation);
40796					context.font = itemToDraw.major ? majorTickFont.font : tickFont.font;
40797					context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor;
40798					context.textBaseline = itemToDraw.textBaseline;
40799					context.textAlign = itemToDraw.textAlign;
40800
40801					var label = itemToDraw.label;
40802					if (helpers.isArray(label)) {
40803						var lineCount = label.length;
40804						var lineHeight = tickFont.size * 1.5;
40805						var y = me.isHorizontal() ? 0 : -lineHeight * (lineCount - 1) / 2;
40806
40807						for (var i = 0; i < lineCount; ++i) {
40808							// We just make sure the multiline element is a string here..
40809							context.fillText('' + label[i], 0, y);
40810							// apply same lineSpacing as calculated @ L#320
40811							y += lineHeight;
40812						}
40813					} else {
40814						context.fillText(label, 0, 0);
40815					}
40816					context.restore();
40817				}
40818			});
40819
40820			if (scaleLabel.display) {
40821				// Draw the scale label
40822				var scaleLabelX;
40823				var scaleLabelY;
40824				var rotation = 0;
40825				var halfLineHeight = parseLineHeight(scaleLabel) / 2;
40826
40827				if (isHorizontal) {
40828					scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
40829					scaleLabelY = options.position === 'bottom'
40830						? me.bottom - halfLineHeight - scaleLabelPadding.bottom
40831						: me.top + halfLineHeight + scaleLabelPadding.top;
40832				} else {
40833					var isLeft = options.position === 'left';
40834					scaleLabelX = isLeft
40835						? me.left + halfLineHeight + scaleLabelPadding.top
40836						: me.right - halfLineHeight - scaleLabelPadding.top;
40837					scaleLabelY = me.top + ((me.bottom - me.top) / 2);
40838					rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
40839				}
40840
40841				context.save();
40842				context.translate(scaleLabelX, scaleLabelY);
40843				context.rotate(rotation);
40844				context.textAlign = 'center';
40845				context.textBaseline = 'middle';
40846				context.fillStyle = scaleLabelFontColor; // render in correct colour
40847				context.font = scaleLabelFont.font;
40848				context.fillText(scaleLabel.labelString, 0, 0);
40849				context.restore();
40850			}
40851
40852			if (gridLines.drawBorder) {
40853				// Draw the line at the edge of the axis
40854				context.lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, 0);
40855				context.strokeStyle = helpers.valueAtIndexOrDefault(gridLines.color, 0);
40856				var x1 = me.left;
40857				var x2 = me.right + axisWidth;
40858				var y1 = me.top;
40859				var y2 = me.bottom + axisWidth;
40860
40861				var aliasPixel = helpers.aliasPixel(context.lineWidth);
40862				if (isHorizontal) {
40863					y1 = y2 = options.position === 'top' ? me.bottom : me.top;
40864					y1 += aliasPixel;
40865					y2 += aliasPixel;
40866				} else {
40867					x1 = x2 = options.position === 'left' ? me.right : me.left;
40868					x1 += aliasPixel;
40869					x2 += aliasPixel;
40870				}
40871
40872				context.beginPath();
40873				context.moveTo(x1, y1);
40874				context.lineTo(x2, y2);
40875				context.stroke();
40876			}
40877		}
40878	});
40879};
40880
40881},{"25":25,"26":26,"34":34,"45":45}],33:[function(require,module,exports){
40882'use strict';
40883
40884var defaults = require(25);
40885var helpers = require(45);
40886var layouts = require(30);
40887
40888module.exports = function(Chart) {
40889
40890	Chart.scaleService = {
40891		// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
40892		// use the new chart options to grab the correct scale
40893		constructors: {},
40894		// Use a registration function so that we can move to an ES6 map when we no longer need to support
40895		// old browsers
40896
40897		// Scale config defaults
40898		defaults: {},
40899		registerScaleType: function(type, scaleConstructor, scaleDefaults) {
40900			this.constructors[type] = scaleConstructor;
40901			this.defaults[type] = helpers.clone(scaleDefaults);
40902		},
40903		getScaleConstructor: function(type) {
40904			return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
40905		},
40906		getScaleDefaults: function(type) {
40907			// Return the scale defaults merged with the global settings so that we always use the latest ones
40908			return this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {};
40909		},
40910		updateScaleDefaults: function(type, additions) {
40911			var me = this;
40912			if (me.defaults.hasOwnProperty(type)) {
40913				me.defaults[type] = helpers.extend(me.defaults[type], additions);
40914			}
40915		},
40916		addScalesToLayout: function(chart) {
40917			// Adds each scale to the chart.boxes array to be sized accordingly
40918			helpers.each(chart.scales, function(scale) {
40919				// Set ILayoutItem parameters for backwards compatibility
40920				scale.fullWidth = scale.options.fullWidth;
40921				scale.position = scale.options.position;
40922				scale.weight = scale.options.weight;
40923				layouts.addBox(chart, scale);
40924			});
40925		}
40926	};
40927};
40928
40929},{"25":25,"30":30,"45":45}],34:[function(require,module,exports){
40930'use strict';
40931
40932var helpers = require(45);
40933
40934/**
40935 * Namespace to hold static tick generation functions
40936 * @namespace Chart.Ticks
40937 */
40938module.exports = {
40939	/**
40940	 * Namespace to hold formatters for different types of ticks
40941	 * @namespace Chart.Ticks.formatters
40942	 */
40943	formatters: {
40944		/**
40945		 * Formatter for value labels
40946		 * @method Chart.Ticks.formatters.values
40947		 * @param value the value to display
40948		 * @return {String|Array} the label to display
40949		 */
40950		values: function(value) {
40951			return helpers.isArray(value) ? value : '' + value;
40952		},
40953
40954		/**
40955		 * Formatter for linear numeric ticks
40956		 * @method Chart.Ticks.formatters.linear
40957		 * @param tickValue {Number} the value to be formatted
40958		 * @param index {Number} the position of the tickValue parameter in the ticks array
40959		 * @param ticks {Array<Number>} the list of ticks being converted
40960		 * @return {String} string representation of the tickValue parameter
40961		 */
40962		linear: function(tickValue, index, ticks) {
40963			// If we have lots of ticks, don't use the ones
40964			var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
40965
40966			// If we have a number like 2.5 as the delta, figure out how many decimal places we need
40967			if (Math.abs(delta) > 1) {
40968				if (tickValue !== Math.floor(tickValue)) {
40969					// not an integer
40970					delta = tickValue - Math.floor(tickValue);
40971				}
40972			}
40973
40974			var logDelta = helpers.log10(Math.abs(delta));
40975			var tickString = '';
40976
40977			if (tickValue !== 0) {
40978				var numDecimal = -1 * Math.floor(logDelta);
40979				numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
40980				tickString = tickValue.toFixed(numDecimal);
40981			} else {
40982				tickString = '0'; // never show decimal places for 0
40983			}
40984
40985			return tickString;
40986		},
40987
40988		logarithmic: function(tickValue, index, ticks) {
40989			var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
40990
40991			if (tickValue === 0) {
40992				return '0';
40993			} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
40994				return tickValue.toExponential();
40995			}
40996			return '';
40997		}
40998	}
40999};
41000
41001},{"45":45}],35:[function(require,module,exports){
41002'use strict';
41003
41004var defaults = require(25);
41005var Element = require(26);
41006var helpers = require(45);
41007
41008defaults._set('global', {
41009	tooltips: {
41010		enabled: true,
41011		custom: null,
41012		mode: 'nearest',
41013		position: 'average',
41014		intersect: true,
41015		backgroundColor: 'rgba(0,0,0,0.8)',
41016		titleFontStyle: 'bold',
41017		titleSpacing: 2,
41018		titleMarginBottom: 6,
41019		titleFontColor: '#fff',
41020		titleAlign: 'left',
41021		bodySpacing: 2,
41022		bodyFontColor: '#fff',
41023		bodyAlign: 'left',
41024		footerFontStyle: 'bold',
41025		footerSpacing: 2,
41026		footerMarginTop: 6,
41027		footerFontColor: '#fff',
41028		footerAlign: 'left',
41029		yPadding: 6,
41030		xPadding: 6,
41031		caretPadding: 2,
41032		caretSize: 5,
41033		cornerRadius: 6,
41034		multiKeyBackground: '#fff',
41035		displayColors: true,
41036		borderColor: 'rgba(0,0,0,0)',
41037		borderWidth: 0,
41038		callbacks: {
41039			// Args are: (tooltipItems, data)
41040			beforeTitle: helpers.noop,
41041			title: function(tooltipItems, data) {
41042				// Pick first xLabel for now
41043				var title = '';
41044				var labels = data.labels;
41045				var labelCount = labels ? labels.length : 0;
41046
41047				if (tooltipItems.length > 0) {
41048					var item = tooltipItems[0];
41049
41050					if (item.xLabel) {
41051						title = item.xLabel;
41052					} else if (labelCount > 0 && item.index < labelCount) {
41053						title = labels[item.index];
41054					}
41055				}
41056
41057				return title;
41058			},
41059			afterTitle: helpers.noop,
41060
41061			// Args are: (tooltipItems, data)
41062			beforeBody: helpers.noop,
41063
41064			// Args are: (tooltipItem, data)
41065			beforeLabel: helpers.noop,
41066			label: function(tooltipItem, data) {
41067				var label = data.datasets[tooltipItem.datasetIndex].label || '';
41068
41069				if (label) {
41070					label += ': ';
41071				}
41072				label += tooltipItem.yLabel;
41073				return label;
41074			},
41075			labelColor: function(tooltipItem, chart) {
41076				var meta = chart.getDatasetMeta(tooltipItem.datasetIndex);
41077				var activeElement = meta.data[tooltipItem.index];
41078				var view = activeElement._view;
41079				return {
41080					borderColor: view.borderColor,
41081					backgroundColor: view.backgroundColor
41082				};
41083			},
41084			labelTextColor: function() {
41085				return this._options.bodyFontColor;
41086			},
41087			afterLabel: helpers.noop,
41088
41089			// Args are: (tooltipItems, data)
41090			afterBody: helpers.noop,
41091
41092			// Args are: (tooltipItems, data)
41093			beforeFooter: helpers.noop,
41094			footer: helpers.noop,
41095			afterFooter: helpers.noop
41096		}
41097	}
41098});
41099
41100module.exports = function(Chart) {
41101
41102	/**
41103 	 * Helper method to merge the opacity into a color
41104 	 */
vendor: 9,332 bytes, lines 41105-41408
41105	function mergeOpacity(colorString, opacity) {
41106		var color = helpers.color(colorString);
41107		return color.alpha(opacity * color.alpha()).rgbaString();
41108	}
41109
41110	// Helper to push or concat based on if the 2nd parameter is an array or not
41111	function pushOrConcat(base, toPush) {
41112		if (toPush) {
41113			if (helpers.isArray(toPush)) {
41114				// base = base.concat(toPush);
41115				Array.prototype.push.apply(base, toPush);
41116			} else {
41117				base.push(toPush);
41118			}
41119		}
41120
41121		return base;
41122	}
41123
41124	// Private helper to create a tooltip item model
41125	// @param element : the chart element (point, arc, bar) to create the tooltip item for
41126	// @return : new tooltip item
41127	function createTooltipItem(element) {
41128		var xScale = element._xScale;
41129		var yScale = element._yScale || element._scale; // handle radar || polarArea charts
41130		var index = element._index;
41131		var datasetIndex = element._datasetIndex;
41132
41133		return {
41134			xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
41135			yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
41136			index: index,
41137			datasetIndex: datasetIndex,
41138			x: element._model.x,
41139			y: element._model.y
41140		};
41141	}
41142
41143	/**
41144	 * Helper to get the reset model for the tooltip
41145	 * @param tooltipOpts {Object} the tooltip options
41146	 */
41147	function getBaseModel(tooltipOpts) {
41148		var globalDefaults = defaults.global;
41149		var valueOrDefault = helpers.valueOrDefault;
41150
41151		return {
41152			// Positioning
41153			xPadding: tooltipOpts.xPadding,
41154			yPadding: tooltipOpts.yPadding,
41155			xAlign: tooltipOpts.xAlign,
41156			yAlign: tooltipOpts.yAlign,
41157
41158			// Body
41159			bodyFontColor: tooltipOpts.bodyFontColor,
41160			_bodyFontFamily: valueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
41161			_bodyFontStyle: valueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
41162			_bodyAlign: tooltipOpts.bodyAlign,
41163			bodyFontSize: valueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
41164			bodySpacing: tooltipOpts.bodySpacing,
41165
41166			// Title
41167			titleFontColor: tooltipOpts.titleFontColor,
41168			_titleFontFamily: valueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
41169			_titleFontStyle: valueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
41170			titleFontSize: valueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
41171			_titleAlign: tooltipOpts.titleAlign,
41172			titleSpacing: tooltipOpts.titleSpacing,
41173			titleMarginBottom: tooltipOpts.titleMarginBottom,
41174
41175			// Footer
41176			footerFontColor: tooltipOpts.footerFontColor,
41177			_footerFontFamily: valueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
41178			_footerFontStyle: valueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
41179			footerFontSize: valueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
41180			_footerAlign: tooltipOpts.footerAlign,
41181			footerSpacing: tooltipOpts.footerSpacing,
41182			footerMarginTop: tooltipOpts.footerMarginTop,
41183
41184			// Appearance
41185			caretSize: tooltipOpts.caretSize,
41186			cornerRadius: tooltipOpts.cornerRadius,
41187			backgroundColor: tooltipOpts.backgroundColor,
41188			opacity: 0,
41189			legendColorBackground: tooltipOpts.multiKeyBackground,
41190			displayColors: tooltipOpts.displayColors,
41191			borderColor: tooltipOpts.borderColor,
41192			borderWidth: tooltipOpts.borderWidth
41193		};
41194	}
41195
41196	/**
41197	 * Get the size of the tooltip
41198	 */
41199	function getTooltipSize(tooltip, model) {
41200		var ctx = tooltip._chart.ctx;
41201
41202		var height = model.yPadding * 2; // Tooltip Padding
41203		var width = 0;
41204
41205		// Count of all lines in the body
41206		var body = model.body;
41207		var combinedBodyLength = body.reduce(function(count, bodyItem) {
41208			return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
41209		}, 0);
41210		combinedBodyLength += model.beforeBody.length + model.afterBody.length;
41211
41212		var titleLineCount = model.title.length;
41213		var footerLineCount = model.footer.length;
41214		var titleFontSize = model.titleFontSize;
41215		var bodyFontSize = model.bodyFontSize;
41216		var footerFontSize = model.footerFontSize;
41217
41218		height += titleLineCount * titleFontSize; // Title Lines
41219		height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing
41220		height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin
41221		height += combinedBodyLength * bodyFontSize; // Body Lines
41222		height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing
41223		height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin
41224		height += footerLineCount * (footerFontSize); // Footer Lines
41225		height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing
41226
41227		// Title width
41228		var widthPadding = 0;
41229		var maxLineWidth = function(line) {
41230			width = Math.max(width, ctx.measureText(line).width + widthPadding);
41231		};
41232
41233		ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
41234		helpers.each(model.title, maxLineWidth);
41235
41236		// Body width
41237		ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
41238		helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
41239
41240		// Body lines may include some extra width due to the color box
41241		widthPadding = model.displayColors ? (bodyFontSize + 2) : 0;
41242		helpers.each(body, function(bodyItem) {
41243			helpers.each(bodyItem.before, maxLineWidth);
41244			helpers.each(bodyItem.lines, maxLineWidth);
41245			helpers.each(bodyItem.after, maxLineWidth);
41246		});
41247
41248		// Reset back to 0
41249		widthPadding = 0;
41250
41251		// Footer width
41252		ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
41253		helpers.each(model.footer, maxLineWidth);
41254
41255		// Add padding
41256		width += 2 * model.xPadding;
41257
41258		return {
41259			width: width,
41260			height: height
41261		};
41262	}
41263
41264	/**
41265	 * Helper to get the alignment of a tooltip given the size
41266	 */
41267	function determineAlignment(tooltip, size) {
41268		var model = tooltip._model;
41269		var chart = tooltip._chart;
41270		var chartArea = tooltip._chart.chartArea;
41271		var xAlign = 'center';
41272		var yAlign = 'center';
41273
41274		if (model.y < size.height) {
41275			yAlign = 'top';
41276		} else if (model.y > (chart.height - size.height)) {
41277			yAlign = 'bottom';
41278		}
41279
41280		var lf, rf; // functions to determine left, right alignment
41281		var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
41282		var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
41283		var midX = (chartArea.left + chartArea.right) / 2;
41284		var midY = (chartArea.top + chartArea.bottom) / 2;
41285
41286		if (yAlign === 'center') {
41287			lf = function(x) {
41288				return x <= midX;
41289			};
41290			rf = function(x) {
41291				return x > midX;
41292			};
41293		} else {
41294			lf = function(x) {
41295				return x <= (size.width / 2);
41296			};
41297			rf = function(x) {
41298				return x >= (chart.width - (size.width / 2));
41299			};
41300		}
41301
41302		olf = function(x) {
41303			return x + size.width + model.caretSize + model.caretPadding > chart.width;
41304		};
41305		orf = function(x) {
41306			return x - size.width - model.caretSize - model.caretPadding < 0;
41307		};
41308		yf = function(y) {
41309			return y <= midY ? 'top' : 'bottom';
41310		};
41311
41312		if (lf(model.x)) {
41313			xAlign = 'left';
41314
41315			// Is tooltip too wide and goes over the right side of the chart.?
41316			if (olf(model.x)) {
41317				xAlign = 'center';
41318				yAlign = yf(model.y);
41319			}
41320		} else if (rf(model.x)) {
41321			xAlign = 'right';
41322
41323			// Is tooltip too wide and goes outside left edge of canvas?
41324			if (orf(model.x)) {
41325				xAlign = 'center';
41326				yAlign = yf(model.y);
41327			}
41328		}
41329
41330		var opts = tooltip._options;
41331		return {
41332			xAlign: opts.xAlign ? opts.xAlign : xAlign,
41333			yAlign: opts.yAlign ? opts.yAlign : yAlign
41334		};
41335	}
41336
41337	/**
41338	 * @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment
41339	 */
41340	function getBackgroundPoint(vm, size, alignment, chart) {
41341		// Background Position
41342		var x = vm.x;
41343		var y = vm.y;
41344
41345		var caretSize = vm.caretSize;
41346		var caretPadding = vm.caretPadding;
41347		var cornerRadius = vm.cornerRadius;
41348		var xAlign = alignment.xAlign;
41349		var yAlign = alignment.yAlign;
41350		var paddingAndSize = caretSize + caretPadding;
41351		var radiusAndPadding = cornerRadius + caretPadding;
41352
41353		if (xAlign === 'right') {
41354			x -= size.width;
41355		} else if (xAlign === 'center') {
41356			x -= (size.width / 2);
41357			if (x + size.width > chart.width) {
41358				x = chart.width - size.width;
41359			}
41360			if (x < 0) {
41361				x = 0;
41362			}
41363		}
41364
41365		if (yAlign === 'top') {
41366			y += paddingAndSize;
41367		} else if (yAlign === 'bottom') {
41368			y -= size.height + paddingAndSize;
41369		} else {
41370			y -= (size.height / 2);
41371		}
41372
41373		if (yAlign === 'center') {
41374			if (xAlign === 'left') {
41375				x += paddingAndSize;
41376			} else if (xAlign === 'right') {
41377				x -= paddingAndSize;
41378			}
41379		} else if (xAlign === 'left') {
41380			x -= radiusAndPadding;
41381		} else if (xAlign === 'right') {
41382			x += radiusAndPadding;
41383		}
41384
41385		return {
41386			x: x,
41387			y: y
41388		};
41389	}
41390
41391	Chart.Tooltip = Element.extend({
41392		initialize: function() {
41393			this._model = getBaseModel(this._options);
41394			this._lastActive = [];
41395		},
41396
41397		// Get the title
41398		// Args are: (tooltipItem, data)
41399		getTitle: function() {
41400			var me = this;
41401			var opts = me._options;
41402			var callbacks = opts.callbacks;
41403
41404			var beforeTitle = callbacks.beforeTitle.apply(me, arguments);
41405			var title = callbacks.title.apply(me, arguments);
41406			var afterTitle = callbacks.afterTitle.apply(me, arguments);
41407
41408			var lines = [];
41409			lines = pushOrConcat(lines, beforeTitle);
41410			lines = pushOrConcat(lines, title);
41411			lines = pushOrConcat(lines, afterTitle);
41412
41413			return lines;
41414		},
41415
41416		// Args are: (tooltipItem, data)
41417		getBeforeBody: function() {
41418			var lines = this._options.callbacks.beforeBody.apply(this, arguments);
41419			return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
41420		},
41421
41422		// Args are: (tooltipItem, data)
41423		getBody: function(tooltipItems, data) {
41424			var me = this;
41425			var callbacks = me._options.callbacks;
41426			var bodyItems = [];
41427
41428			helpers.each(tooltipItems, function(tooltipItem) {
41429				var bodyItem = {
41430					before: [],
41431					lines: [],
41432					after: []
41433				};
41434				pushOrConcat(bodyItem.before, callbacks.beforeLabel.call(me, tooltipItem, data));
41435				pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));
41436				pushOrConcat(bodyItem.after, callbacks.afterLabel.call(me, tooltipItem, data));
41437
41438				bodyItems.push(bodyItem);
41439			});
41440
41441			return bodyItems;
41442		},
41443
41444		// Args are: (tooltipItem, data)
41445		getAfterBody: function() {
41446			var lines = this._options.callbacks.afterBody.apply(this, arguments);
41447			return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
41448		},
41449
41450		// Get the footer and beforeFooter and afterFooter lines
41451		// Args are: (tooltipItem, data)
41452		getFooter: function() {
41453			var me = this;
41454			var callbacks = me._options.callbacks;
41455
41456			var beforeFooter = callbacks.beforeFooter.apply(me, arguments);
41457			var footer = callbacks.footer.apply(me, arguments);
41458			var afterFooter = callbacks.afterFooter.apply(me, arguments);
41459
41460			var lines = [];
41461			lines = pushOrConcat(lines, beforeFooter);
41462			lines = pushOrConcat(lines, footer);
41463			lines = pushOrConcat(lines, afterFooter);
41464
41465			return lines;
41466		},
41467
41468		update: function(changed) {
41469			var me = this;
41470			var opts = me._options;
41471
41472			// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition
41473			// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time
41474			// which breaks any animations.
41475			var existingModel = me._model;
41476			var model = me._model = getBaseModel(opts);
41477			var active = me._active;
41478
41479			var data = me._data;
41480
41481			// In the case where active.length === 0 we need to keep these at existing values for good animations
41482			var alignment = {
41483				xAlign: existingModel.xAlign,
41484				yAlign: existingModel.yAlign
41485			};
41486			var backgroundPoint = {
41487				x: existingModel.x,
41488				y: existingModel.y
41489			};
41490			var tooltipSize = {
41491				width: existingModel.width,
41492				height: existingModel.height
41493			};
41494			var tooltipPosition = {
41495				x: existingModel.caretX,
41496				y: existingModel.caretY
41497			};
41498
41499			var i, len;
41500
41501			if (active.length) {
41502				model.opacity = 1;
41503
41504				var labelColors = [];
41505				var labelTextColors = [];
41506				tooltipPosition = Chart.Tooltip.positioners[opts.position].call(me, active, me._eventPosition);
41507
41508				var tooltipItems = [];
41509				for (i = 0, len = active.length; i < len; ++i) {
41510					tooltipItems.push(createTooltipItem(active[i]));
41511				}
41512
41513				// If the user provided a filter function, use it to modify the tooltip items
41514				if (opts.filter) {
41515					tooltipItems = tooltipItems.filter(function(a) {
41516						return opts.filter(a, data);
41517					});
41518				}
41519
41520				// If the user provided a sorting function, use it to modify the tooltip items
41521				if (opts.itemSort) {
41522					tooltipItems = tooltipItems.sort(function(a, b) {
41523						return opts.itemSort(a, b, data);
41524					});
41525				}
41526
41527				// Determine colors for boxes
41528				helpers.each(tooltipItems, function(tooltipItem) {
41529					labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));
41530					labelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart));
41531				});
41532
41533
41534				// Build the Text Lines
41535				model.title = me.getTitle(tooltipItems, data);
41536				model.beforeBody = me.getBeforeBody(tooltipItems, data);
41537				model.body = me.getBody(tooltipItems, data);
41538				model.afterBody = me.getAfterBody(tooltipItems, data);
41539				model.footer = me.getFooter(tooltipItems, data);
41540
41541				// Initial positioning and colors
41542				model.x = Math.round(tooltipPosition.x);
41543				model.y = Math.round(tooltipPosition.y);
41544				model.caretPadding = opts.caretPadding;
41545				model.labelColors = labelColors;
41546				model.labelTextColors = labelTextColors;
41547
41548				// data points
41549				model.dataPoints = tooltipItems;
41550
41551				// We need to determine alignment of the tooltip
41552				tooltipSize = getTooltipSize(this, model);
41553				alignment = determineAlignment(this, tooltipSize);
41554				// Final Size and Position
41555				backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart);
41556			} else {
41557				model.opacity = 0;
41558			}
41559
41560			model.xAlign = alignment.xAlign;
41561			model.yAlign = alignment.yAlign;
41562			model.x = backgroundPoint.x;
41563			model.y = backgroundPoint.y;
41564			model.width = tooltipSize.width;
41565			model.height = tooltipSize.height;
41566
41567			// Point where the caret on the tooltip points to
41568			model.caretX = tooltipPosition.x;
41569			model.caretY = tooltipPosition.y;
41570
41571			me._model = model;
41572
41573			if (changed && opts.custom) {
41574				opts.custom.call(me, model);
41575			}
41576
41577			return me;
41578		},
41579		drawCaret: function(tooltipPoint, size) {
41580			var ctx = this._chart.ctx;
41581			var vm = this._view;
41582			var caretPosition = this.getCaretPosition(tooltipPoint, size, vm);
41583
41584			ctx.lineTo(caretPosition.x1, caretPosition.y1);
41585			ctx.lineTo(caretPosition.x2, caretPosition.y2);
41586			ctx.lineTo(caretPosition.x3, caretPosition.y3);
41587		},
41588		getCaretPosition: function(tooltipPoint, size, vm) {
41589			var x1, x2, x3, y1, y2, y3;
41590			var caretSize = vm.caretSize;
41591			var cornerRadius = vm.cornerRadius;
41592			var xAlign = vm.xAlign;
41593			var yAlign = vm.yAlign;
41594			var ptX = tooltipPoint.x;
41595			var ptY = tooltipPoint.y;
41596			var width = size.width;
41597			var height = size.height;
41598
41599			if (yAlign === 'center') {
41600				y2 = ptY + (height / 2);
41601
41602				if (xAlign === 'left') {
41603					x1 = ptX;
41604					x2 = x1 - caretSize;
41605					x3 = x1;
41606
41607					y1 = y2 + caretSize;
41608					y3 = y2 - caretSize;
41609				} else {
41610					x1 = ptX + width;
41611					x2 = x1 + caretSize;
41612					x3 = x1;
41613
41614					y1 = y2 - caretSize;
41615					y3 = y2 + caretSize;
41616				}
41617			} else {
41618				if (xAlign === 'left') {
41619					x2 = ptX + cornerRadius + (caretSize);
41620					x1 = x2 - caretSize;
41621					x3 = x2 + caretSize;
41622				} else if (xAlign === 'right') {
41623					x2 = ptX + width - cornerRadius - caretSize;
41624					x1 = x2 - caretSize;
41625					x3 = x2 + caretSize;
41626				} else {
41627					x2 = vm.caretX;
41628					x1 = x2 - caretSize;
41629					x3 = x2 + caretSize;
41630				}
41631				if (yAlign === 'top') {
41632					y1 = ptY;
41633					y2 = y1 - caretSize;
41634					y3 = y1;
41635				} else {
41636					y1 = ptY + height;
41637					y2 = y1 + caretSize;
41638					y3 = y1;
41639					// invert drawing order
41640					var tmp = x3;
41641					x3 = x1;
41642					x1 = tmp;
41643				}
41644			}
41645			return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
41646		},
41647		drawTitle: function(pt, vm, ctx, opacity) {
41648			var title = vm.title;
41649
41650			if (title.length) {
41651				ctx.textAlign = vm._titleAlign;
41652				ctx.textBaseline = 'top';
41653
41654				var titleFontSize = vm.titleFontSize;
41655				var titleSpacing = vm.titleSpacing;
41656
41657				ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
41658				ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
41659
41660				var i, len;
41661				for (i = 0, len = title.length; i < len; ++i) {
41662					ctx.fillText(title[i], pt.x, pt.y);
41663					pt.y += titleFontSize + titleSpacing; // Line Height and spacing
41664
41665					if (i + 1 === title.length) {
41666						pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
41667					}
41668				}
41669			}
41670		},
41671		drawBody: function(pt, vm, ctx, opacity) {
41672			var bodyFontSize = vm.bodyFontSize;
41673			var bodySpacing = vm.bodySpacing;
41674			var body = vm.body;
41675
41676			ctx.textAlign = vm._bodyAlign;
41677			ctx.textBaseline = 'top';
41678			ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
41679
41680			// Before Body
41681			var xLinePadding = 0;
41682			var fillLineOfText = function(line) {
41683				ctx.fillText(line, pt.x + xLinePadding, pt.y);
41684				pt.y += bodyFontSize + bodySpacing;
41685			};
41686
41687			// Before body lines
41688			ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity);
41689			helpers.each(vm.beforeBody, fillLineOfText);
41690
41691			var drawColorBoxes = vm.displayColors;
41692			xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
41693
41694			// Draw body lines now
41695			helpers.each(body, function(bodyItem, i) {
41696				var textColor = mergeOpacity(vm.labelTextColors[i], opacity);
41697				ctx.fillStyle = textColor;
41698				helpers.each(bodyItem.before, fillLineOfText);
41699
41700				helpers.each(bodyItem.lines, function(line) {
41701					// Draw Legend-like boxes if needed
41702					if (drawColorBoxes) {
41703						// Fill a white rect so that colours merge nicely if the opacity is < 1
41704						ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
41705						ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
41706
41707						// Border
41708						ctx.lineWidth = 1;
41709						ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
41710						ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
41711
41712						// Inner square
41713						ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
41714						ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
41715						ctx.fillStyle = textColor;
41716					}
41717
41718					fillLineOfText(line);
41719				});
41720
41721				helpers.each(bodyItem.after, fillLineOfText);
41722			});
41723
41724			// Reset back to 0 for after body
41725			xLinePadding = 0;
41726
41727			// After body lines
41728			helpers.each(vm.afterBody, fillLineOfText);
41729			pt.y -= bodySpacing; // Remove last body spacing
41730		},
41731		drawFooter: function(pt, vm, ctx, opacity) {
41732			var footer = vm.footer;
41733
41734			if (footer.length) {
41735				pt.y += vm.footerMarginTop;
41736
41737				ctx.textAlign = vm._footerAlign;
41738				ctx.textBaseline = 'top';
41739
41740				ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
41741				ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
41742
41743				helpers.each(footer, function(line) {
41744					ctx.fillText(line, pt.x, pt.y);
41745					pt.y += vm.footerFontSize + vm.footerSpacing;
41746				});
41747			}
41748		},
41749		drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
41750			ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
41751			ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
41752			ctx.lineWidth = vm.borderWidth;
41753			var xAlign = vm.xAlign;
41754			var yAlign = vm.yAlign;
41755			var x = pt.x;
41756			var y = pt.y;
41757			var width = tooltipSize.width;
41758			var height = tooltipSize.height;
41759			var radius = vm.cornerRadius;
41760
41761			ctx.beginPath();
41762			ctx.moveTo(x + radius, y);
41763			if (yAlign === 'top') {
41764				this.drawCaret(pt, tooltipSize);
41765			}
41766			ctx.lineTo(x + width - radius, y);
41767			ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
41768			if (yAlign === 'center' && xAlign === 'right') {
41769				this.drawCaret(pt, tooltipSize);
41770			}
41771			ctx.lineTo(x + width, y + height - radius);
41772			ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
41773			if (yAlign === 'bottom') {
41774				this.drawCaret(pt, tooltipSize);
41775			}
41776			ctx.lineTo(x + radius, y + height);
41777			ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
41778			if (yAlign === 'center' && xAlign === 'left') {
41779				this.drawCaret(pt, tooltipSize);
41780			}
41781			ctx.lineTo(x, y + radius);
41782			ctx.quadraticCurveTo(x, y, x + radius, y);
41783			ctx.closePath();
41784
41785			ctx.fill();
41786
41787			if (vm.borderWidth > 0) {
41788				ctx.stroke();
41789			}
41790		},
41791		draw: function() {
41792			var ctx = this._chart.ctx;
41793			var vm = this._view;
41794
41795			if (vm.opacity === 0) {
41796				return;
41797			}
41798
41799			var tooltipSize = {
41800				width: vm.width,
41801				height: vm.height
41802			};
41803			var pt = {
41804				x: vm.x,
41805				y: vm.y
41806			};
41807
41808			// IE11/Edge does not like very small opacities, so snap to 0
41809			var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
41810
41811			// Truthy/falsey value for empty tooltip
41812			var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
41813
41814			if (this._options.enabled && hasTooltipContent) {
41815				// Draw Background
41816				this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
41817
41818				// Draw Title, Body, and Footer
41819				pt.x += vm.xPadding;
41820				pt.y += vm.yPadding;
41821
41822				// Titles
41823				this.drawTitle(pt, vm, ctx, opacity);
41824
41825				// Body
41826				this.drawBody(pt, vm, ctx, opacity);
41827
41828				// Footer
41829				this.drawFooter(pt, vm, ctx, opacity);
41830			}
41831		},
41832
41833		/**
41834		 * Handle an event
41835		 * @private
41836		 * @param {IEvent} event - The event to handle
41837		 * @returns {Boolean} true if the tooltip changed
41838		 */
41839		handleEvent: function(e) {
41840			var me = this;
41841			var options = me._options;
41842			var changed = false;
41843
41844			me._lastActive = me._lastActive || [];
41845
41846			// Find Active Elements for tooltips
41847			if (e.type === 'mouseout') {
41848				me._active = [];
41849			} else {
41850				me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
41851			}
41852
41853			// Remember Last Actives
41854			changed = !helpers.arrayEquals(me._active, me._lastActive);
41855
41856			// Only handle target event on tooltip change
41857			if (changed) {
41858				me._lastActive = me._active;
41859
41860				if (options.enabled || options.custom) {
41861					me._eventPosition = {
41862						x: e.x,
41863						y: e.y
41864					};
41865
41866					me.update(true);
41867					me.pivot();
41868				}
41869			}
41870
41871			return changed;
41872		}
41873	});
41874
41875	/**
41876	 * @namespace Chart.Tooltip.positioners
41877	 */
41878	Chart.Tooltip.positioners = {
41879		/**
41880		 * Average mode places the tooltip at the average position of the elements shown
41881		 * @function Chart.Tooltip.positioners.average
41882		 * @param elements {ChartElement[]} the elements being displayed in the tooltip
41883		 * @returns {Point} tooltip position
41884		 */
41885		average: function(elements) {
41886			if (!elements.length) {
41887				return false;
41888			}
41889
41890			var i, len;
41891			var x = 0;
41892			var y = 0;
41893			var count = 0;
41894
41895			for (i = 0, len = elements.length; i < len; ++i) {
41896				var el = elements[i];
41897				if (el && el.hasValue()) {
41898					var pos = el.tooltipPosition();
41899					x += pos.x;
41900					y += pos.y;
41901					++count;
41902				}
41903			}
41904
41905			return {
41906				x: Math.round(x / count),
41907				y: Math.round(y / count)
41908			};
41909		},
41910
41911		/**
41912		 * Gets the tooltip position nearest of the item nearest to the event position
41913		 * @function Chart.Tooltip.positioners.nearest
41914		 * @param elements {Chart.Element[]} the tooltip elements
41915		 * @param eventPosition {Point} the position of the event in canvas coordinates
41916		 * @returns {Point} the tooltip position
41917		 */
41918		nearest: function(elements, eventPosition) {
41919			var x = eventPosition.x;
41920			var y = eventPosition.y;
41921			var minDistance = Number.POSITIVE_INFINITY;
41922			var i, len, nearestElement;
41923
41924			for (i = 0, len = elements.length; i < len; ++i) {
41925				var el = elements[i];
41926				if (el && el.hasValue()) {
41927					var center = el.getCenterPoint();
41928					var d = helpers.distanceBetweenPoints(eventPosition, center);
41929
41930					if (d < minDistance) {
41931						minDistance = d;
41932						nearestElement = el;
41933					}
41934				}
41935			}
41936
41937			if (nearestElement) {
41938				var tp = nearestElement.tooltipPosition();
41939				x = tp.x;
41940				y = tp.y;
41941			}
41942
41943			return {
41944				x: x,
41945				y: y
41946			};
41947		}
41948	};
41949};
41950
41951},{"25":25,"26":26,"45":45}],36:[function(require,module,exports){
41952'use strict';
41953
41954var defaults = require(25);
41955var Element = require(26);
41956var helpers = require(45);
41957
41958defaults._set('global', {
41959	elements: {
41960		arc: {
41961			backgroundColor: defaults.global.defaultColor,
41962			borderColor: '#fff',
41963			borderWidth: 2
41964		}
41965	}
41966});
41967
41968module.exports = Element.extend({
41969	inLabelRange: function(mouseX) {
41970		var vm = this._view;
41971
41972		if (vm) {
41973			return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
41974		}
41975		return false;
41976	},
41977
41978	inRange: function(chartX, chartY) {
41979		var vm = this._view;
41980
41981		if (vm) {
41982			var pointRelativePosition = helpers.getAngleFromPoint(vm, {x: chartX, y: chartY});
41983			var	angle = pointRelativePosition.angle;
41984			var distance = pointRelativePosition.distance;
41985
41986			// Sanitise angle range
41987			var startAngle = vm.startAngle;
41988			var endAngle = vm.endAngle;
41989			while (endAngle < startAngle) {
41990				endAngle += 2.0 * Math.PI;
41991			}
41992			while (angle > endAngle) {
41993				angle -= 2.0 * Math.PI;
41994			}
41995			while (angle < startAngle) {
41996				angle += 2.0 * Math.PI;
41997			}
41998
41999			// Check if within the range of the open/close angle
42000			var betweenAngles = (angle >= startAngle && angle <= endAngle);
42001			var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);
42002
42003			return (betweenAngles && withinRadius);
42004		}
42005		return false;
42006	},
42007
42008	getCenterPoint: function() {
42009		var vm = this._view;
42010		var halfAngle = (vm.startAngle + vm.endAngle) / 2;
42011		var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
42012		return {
42013			x: vm.x + Math.cos(halfAngle) * halfRadius,
42014			y: vm.y + Math.sin(halfAngle) * halfRadius
42015		};
42016	},
42017
42018	getArea: function() {
42019		var vm = this._view;
42020		return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
42021	},
42022
42023	tooltipPosition: function() {
42024		var vm = this._view;
42025		var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);
42026		var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
42027
42028		return {
42029			x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
42030			y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
42031		};
42032	},
42033
42034	draw: function() {
42035		var ctx = this._chart.ctx;
42036		var vm = this._view;
42037		var sA = vm.startAngle;
42038		var eA = vm.endAngle;
42039
42040		ctx.beginPath();
42041
42042		ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
42043		ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
42044
42045		ctx.closePath();
42046		ctx.strokeStyle = vm.borderColor;
42047		ctx.lineWidth = vm.borderWidth;
42048
42049		ctx.fillStyle = vm.backgroundColor;
42050
42051		ctx.fill();
42052		ctx.lineJoin = 'bevel';
42053
42054		if (vm.borderWidth) {
42055			ctx.stroke();
42056		}
42057	}
42058});
42059
42060},{"25":25,"26":26,"45":45}],37:[function(require,module,exports){
42061'use strict';
42062
42063var defaults = require(25);
42064var Element = require(26);
42065var helpers = require(45);
42066
42067var globalDefaults = defaults.global;
42068
42069defaults._set('global', {
42070	elements: {
42071		line: {
42072			tension: 0.4,
42073			backgroundColor: globalDefaults.defaultColor,
42074			borderWidth: 3,
42075			borderColor: globalDefaults.defaultColor,
42076			borderCapStyle: 'butt',
42077			borderDash: [],
42078			borderDashOffset: 0.0,
42079			borderJoinStyle: 'miter',
42080			capBezierPoints: true,
42081			fill: true, // do we fill in the area between the line and its base axis
42082		}
42083	}
42084});
42085
42086module.exports = Element.extend({
42087	draw: function() {
42088		var me = this;
42089		var vm = me._view;
42090		var ctx = me._chart.ctx;
42091		var spanGaps = vm.spanGaps;
42092		var points = me._children.slice(); // clone array
42093		var globalOptionLineElements = globalDefaults.elements.line;
42094		var lastDrawnIndex = -1;
42095		var index, current, previous, currentVM;
42096
42097		// If we are looping, adding the first point again
42098		if (me._loop && points.length) {
42099			points.push(points[0]);
42100		}
42101
42102		ctx.save();
42103
42104		// Stroke Line Options
42105		ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
42106
42107		// IE 9 and 10 do not support line dash
42108		if (ctx.setLineDash) {
42109			ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);
42110		}
42111
42112		ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset;
42113		ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
42114		ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
42115		ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
42116
42117		// Stroke Line
42118		ctx.beginPath();
42119		lastDrawnIndex = -1;
42120
42121		for (index = 0; index < points.length; ++index) {
42122			current = points[index];
42123			previous = helpers.previousItem(points, index);
42124			currentVM = current._view;
42125
42126			// First point moves to it's starting position no matter what
42127			if (index === 0) {
42128				if (!currentVM.skip) {
42129					ctx.moveTo(currentVM.x, currentVM.y);
42130					lastDrawnIndex = index;
42131				}
42132			} else {
42133				previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
42134
42135				if (!currentVM.skip) {
42136					if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
42137						// There was a gap and this is the first point after the gap
42138						ctx.moveTo(currentVM.x, currentVM.y);
42139					} else {
42140						// Line to next point
42141						helpers.canvas.lineTo(ctx, previous._view, current._view);
42142					}
42143					lastDrawnIndex = index;
42144				}
42145			}
42146		}
42147
42148		ctx.stroke();
42149		ctx.restore();
42150	}
42151});
42152
42153},{"25":25,"26":26,"45":45}],38:[function(require,module,exports){
42154'use strict';
42155
42156var defaults = require(25);
42157var Element = require(26);
42158var helpers = require(45);
42159
42160var defaultColor = defaults.global.defaultColor;
42161
42162defaults._set('global', {
42163	elements: {
42164		point: {
42165			radius: 3,
42166			pointStyle: 'circle',
42167			backgroundColor: defaultColor,
42168			borderColor: defaultColor,
42169			borderWidth: 1,
42170			// Hover
42171			hitRadius: 1,
42172			hoverRadius: 4,
42173			hoverBorderWidth: 1
42174		}
42175	}
42176});
42177
42178function xRange(mouseX) {
42179	var vm = this._view;
42180	return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;
42181}
42182
42183function yRange(mouseY) {
42184	var vm = this._view;
42185	return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;
42186}
42187
42188module.exports = Element.extend({
42189	inRange: function(mouseX, mouseY) {
42190		var vm = this._view;
42191		return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
42192	},
42193
42194	inLabelRange: xRange,
42195	inXRange: xRange,
42196	inYRange: yRange,
42197
42198	getCenterPoint: function() {
42199		var vm = this._view;
42200		return {
42201			x: vm.x,
42202			y: vm.y
42203		};
42204	},
42205
42206	getArea: function() {
42207		return Math.PI * Math.pow(this._view.radius, 2);
42208	},
42209
42210	tooltipPosition: function() {
42211		var vm = this._view;
42212		return {
42213			x: vm.x,
42214			y: vm.y,
42215			padding: vm.radius + vm.borderWidth
42216		};
42217	},
42218
42219	draw: function(chartArea) {
42220		var vm = this._view;
42221		var model = this._model;
42222		var ctx = this._chart.ctx;
42223		var pointStyle = vm.pointStyle;
42224		var radius = vm.radius;
42225		var x = vm.x;
42226		var y = vm.y;
42227		var color = helpers.color;
42228		var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.)
42229		var ratio = 0;
42230
42231		if (vm.skip) {
42232			return;
42233		}
42234
42235		ctx.strokeStyle = vm.borderColor || defaultColor;
42236		ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth);
42237		ctx.fillStyle = vm.backgroundColor || defaultColor;
42238
42239		// Cliping for Points.
42240		// going out from inner charArea?
42241		if ((chartArea !== undefined) && ((model.x < chartArea.left) || (chartArea.right * errMargin < model.x) || (model.y < chartArea.top) || (chartArea.bottom * errMargin < model.y))) {
42242			// Point fade out
42243			if (model.x < chartArea.left) {
42244				ratio = (x - model.x) / (chartArea.left - model.x);
42245			} else if (chartArea.right * errMargin < model.x) {
42246				ratio = (model.x - x) / (model.x - chartArea.right);
42247			} else if (model.y < chartArea.top) {
42248				ratio = (y - model.y) / (chartArea.top - model.y);
42249			} else if (chartArea.bottom * errMargin < model.y) {
42250				ratio = (model.y - y) / (model.y - chartArea.bottom);
42251			}
42252			ratio = Math.round(ratio * 100) / 100;
42253			ctx.strokeStyle = color(ctx.strokeStyle).alpha(ratio).rgbString();
42254			ctx.fillStyle = color(ctx.fillStyle).alpha(ratio).rgbString();
42255		}
42256
42257		helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y);
42258	}
42259});
42260
42261},{"25":25,"26":26,"45":45}],39:[function(require,module,exports){
42262'use strict';
42263
42264var defaults = require(25);
42265var Element = require(26);
42266
42267defaults._set('global', {
42268	elements: {
42269		rectangle: {
42270			backgroundColor: defaults.global.defaultColor,
42271			borderColor: defaults.global.defaultColor,
42272			borderSkipped: 'bottom',
42273			borderWidth: 0
42274		}
42275	}
42276});
42277
42278function isVertical(bar) {
42279	return bar._view.width !== undefined;
42280}
42281
42282/**
42283 * Helper function to get the bounds of the bar regardless of the orientation
42284 * @param bar {Chart.Element.Rectangle} the bar
42285 * @return {Bounds} bounds of the bar
42286 * @private
42287 */
42288function getBarBounds(bar) {
42289	var vm = bar._view;
42290	var x1, x2, y1, y2;
42291
42292	if (isVertical(bar)) {
42293		// vertical
42294		var halfWidth = vm.width / 2;
42295		x1 = vm.x - halfWidth;
42296		x2 = vm.x + halfWidth;
42297		y1 = Math.min(vm.y, vm.base);
42298		y2 = Math.max(vm.y, vm.base);
42299	} else {
42300		// horizontal bar
42301		var halfHeight = vm.height / 2;
42302		x1 = Math.min(vm.x, vm.base);
42303		x2 = Math.max(vm.x, vm.base);
42304		y1 = vm.y - halfHeight;
42305		y2 = vm.y + halfHeight;
42306	}
42307
42308	return {
42309		left: x1,
42310		top: y1,
42311		right: x2,
42312		bottom: y2
42313	};
42314}
42315
42316module.exports = Element.extend({
42317	draw: function() {
42318		var ctx = this._chart.ctx;
42319		var vm = this._view;
42320		var left, right, top, bottom, signX, signY, borderSkipped;
42321		var borderWidth = vm.borderWidth;
42322
42323		if (!vm.horizontal) {
42324			// bar
42325			left = vm.x - vm.width / 2;
42326			right = vm.x + vm.width / 2;
42327			top = vm.y;
42328			bottom = vm.base;
42329			signX = 1;
42330			signY = bottom > top ? 1 : -1;
42331			borderSkipped = vm.borderSkipped || 'bottom';
42332		} else {
42333			// horizontal bar
42334			left = vm.base;
42335			right = vm.x;
42336			top = vm.y - vm.height / 2;
42337			bottom = vm.y + vm.height / 2;
42338			signX = right > left ? 1 : -1;
42339			signY = 1;
42340			borderSkipped = vm.borderSkipped || 'left';
42341		}
42342
42343		// Canvas doesn't allow us to stroke inside the width so we can
42344		// adjust the sizes to fit if we're setting a stroke on the line
42345		if (borderWidth) {
42346			// borderWidth shold be less than bar width and bar height.
42347			var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
42348			borderWidth = borderWidth > barSize ? barSize : borderWidth;
42349			var halfStroke = borderWidth / 2;
42350			// Adjust borderWidth when bar top position is near vm.base(zero).
42351			var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);
42352			var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);
42353			var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);
42354			var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);
42355			// not become a vertical line?
42356			if (borderLeft !== borderRight) {
42357				top = borderTop;
42358				bottom = borderBottom;
42359			}
42360			// not become a horizontal line?
42361			if (borderTop !== borderBottom) {
42362				left = borderLeft;
42363				right = borderRight;
42364			}
42365		}
42366
42367		ctx.beginPath();
42368		ctx.fillStyle = vm.backgroundColor;
42369		ctx.strokeStyle = vm.borderColor;
42370		ctx.lineWidth = borderWidth;
42371
42372		// Corner points, from bottom-left to bottom-right clockwise
42373		// | 1 2 |
42374		// | 0 3 |
42375		var corners = [
42376			[left, bottom],
42377			[left, top],
42378			[right, top],
42379			[right, bottom]
42380		];
42381
42382		// Find first (starting) corner with fallback to 'bottom'
42383		var borders = ['bottom', 'left', 'top', 'right'];
42384		var startCorner = borders.indexOf(borderSkipped, 0);
42385		if (startCorner === -1) {
42386			startCorner = 0;
42387		}
42388
42389		function cornerAt(index) {
42390			return corners[(startCorner + index) % 4];
42391		}
42392
42393		// Draw rectangle from 'startCorner'
42394		var corner = cornerAt(0);
42395		ctx.moveTo(corner[0], corner[1]);
42396
42397		for (var i = 1; i < 4; i++) {
42398			corner = cornerAt(i);
42399			ctx.lineTo(corner[0], corner[1]);
42400		}
42401
42402		ctx.fill();
42403		if (borderWidth) {
42404			ctx.stroke();
42405		}
42406	},
42407
42408	height: function() {
42409		var vm = this._view;
42410		return vm.base - vm.y;
42411	},
42412
42413	inRange: function(mouseX, mouseY) {
42414		var inRange = false;
42415
42416		if (this._view) {
42417			var bounds = getBarBounds(this);
42418			inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom;
42419		}
42420
42421		return inRange;
42422	},
42423
42424	inLabelRange: function(mouseX, mouseY) {
42425		var me = this;
42426		if (!me._view) {
42427			return false;
42428		}
42429
42430		var inRange = false;
42431		var bounds = getBarBounds(me);
42432
42433		if (isVertical(me)) {
42434			inRange = mouseX >= bounds.left && mouseX <= bounds.right;
42435		} else {
42436			inRange = mouseY >= bounds.top && mouseY <= bounds.bottom;
42437		}
42438
42439		return inRange;
42440	},
42441
42442	inXRange: function(mouseX) {
42443		var bounds = getBarBounds(this);
42444		return mouseX >= bounds.left && mouseX <= bounds.right;
42445	},
42446
42447	inYRange: function(mouseY) {
42448		var bounds = getBarBounds(this);
42449		return mouseY >= bounds.top && mouseY <= bounds.bottom;
42450	},
42451
42452	getCenterPoint: function() {
42453		var vm = this._view;
42454		var x, y;
42455		if (isVertical(this)) {
42456			x = vm.x;
42457			y = (vm.y + vm.base) / 2;
42458		} else {
42459			x = (vm.x + vm.base) / 2;
42460			y = vm.y;
42461		}
42462
42463		return {x: x, y: y};
42464	},
42465
42466	getArea: function() {
42467		var vm = this._view;
42468		return vm.width * Math.abs(vm.y - vm.base);
42469	},
42470
42471	tooltipPosition: function() {
42472		var vm = this._view;
42473		return {
42474			x: vm.x,
42475			y: vm.y
42476		};
42477	}
42478});
42479
42480},{"25":25,"26":26}],40:[function(require,module,exports){
42481'use strict';
42482
42483module.exports = {};
42484module.exports.Arc = require(36);
42485module.exports.Line = require(37);
42486module.exports.Point = require(38);
42487module.exports.Rectangle = require(39);
42488
42489},{"36":36,"37":37,"38":38,"39":39}],41:[function(require,module,exports){
42490'use strict';
42491
42492var helpers = require(42);
42493
42494/**
42495 * @namespace Chart.helpers.canvas
42496 */
42497var exports = module.exports = {
42498	/**
42499	 * Clears the entire canvas associated to the given `chart`.
42500	 * @param {Chart} chart - The chart for which to clear the canvas.
42501	 */
42502	clear: function(chart) {
42503		chart.ctx.clearRect(0, 0, chart.width, chart.height);
42504	},
42505
42506	/**
42507	 * Creates a "path" for a rectangle with rounded corners at position (x, y) with a
42508	 * given size (width, height) and the same `radius` for all corners.
42509	 * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.
42510	 * @param {Number} x - The x axis of the coordinate for the rectangle starting point.
42511	 * @param {Number} y - The y axis of the coordinate for the rectangle starting point.
42512	 * @param {Number} width - The rectangle's width.
42513	 * @param {Number} height - The rectangle's height.
42514	 * @param {Number} radius - The rounded amount (in pixels) for the four corners.
42515	 * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?
42516	 */
42517	roundedRect: function(ctx, x, y, width, height, radius) {
42518		if (radius) {
42519			var rx = Math.min(radius, width / 2);
42520			var ry = Math.min(radius, height / 2);
42521
42522			ctx.moveTo(x + rx, y);
42523			ctx.lineTo(x + width - rx, y);
42524			ctx.quadraticCurveTo(x + width, y, x + width, y + ry);
42525			ctx.lineTo(x + width, y + height - ry);
42526			ctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
42527			ctx.lineTo(x + rx, y + height);
42528			ctx.quadraticCurveTo(x, y + height, x, y + height - ry);
42529			ctx.lineTo(x, y + ry);
42530			ctx.quadraticCurveTo(x, y, x + rx, y);
42531		} else {
42532			ctx.rect(x, y, width, height);
42533		}
42534	},
42535
42536	drawPoint: function(ctx, style, radius, x, y) {
42537		var type, edgeLength, xOffset, yOffset, height, size;
42538
42539		if (style && typeof style === 'object') {
42540			type = style.toString();
42541			if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
42542				ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height);
42543				return;
42544			}
42545		}
42546
42547		if (isNaN(radius) || radius <= 0) {
42548			return;
42549		}
42550
42551		switch (style) {
42552		// Default includes circle
42553		default:
42554			ctx.beginPath();
42555			ctx.arc(x, y, radius, 0, Math.PI * 2);
42556			ctx.closePath();
42557			ctx.fill();
42558			break;
42559		case 'triangle':
42560			ctx.beginPath();
42561			edgeLength = 3 * radius / Math.sqrt(3);
42562			height = edgeLength * Math.sqrt(3) / 2;
42563			ctx.moveTo(x - edgeLength / 2, y + height / 3);
42564			ctx.lineTo(x + edgeLength / 2, y + height / 3);
42565			ctx.lineTo(x, y - 2 * height / 3);
42566			ctx.closePath();
42567			ctx.fill();
42568			break;
42569		case 'rect':
42570			size = 1 / Math.SQRT2 * radius;
42571			ctx.beginPath();
42572			ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
42573			ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
42574			break;
42575		case 'rectRounded':
42576			var offset = radius / Math.SQRT2;
42577			var leftX = x - offset;
42578			var topY = y - offset;
42579			var sideSize = Math.SQRT2 * radius;
42580			ctx.beginPath();
42581			this.roundedRect(ctx, leftX, topY, sideSize, sideSize, radius / 2);
42582			ctx.closePath();
42583			ctx.fill();
42584			break;
42585		case 'rectRot':
42586			size = 1 / Math.SQRT2 * radius;
42587			ctx.beginPath();
42588			ctx.moveTo(x - size, y);
42589			ctx.lineTo(x, y + size);
42590			ctx.lineTo(x + size, y);
42591			ctx.lineTo(x, y - size);
42592			ctx.closePath();
42593			ctx.fill();
42594			break;
42595		case 'cross':
42596			ctx.beginPath();
42597			ctx.moveTo(x, y + radius);
42598			ctx.lineTo(x, y - radius);
42599			ctx.moveTo(x - radius, y);
42600			ctx.lineTo(x + radius, y);
42601			ctx.closePath();
42602			break;
42603		case 'crossRot':
42604			ctx.beginPath();
42605			xOffset = Math.cos(Math.PI / 4) * radius;
42606			yOffset = Math.sin(Math.PI / 4) * radius;
42607			ctx.moveTo(x - xOffset, y - yOffset);
42608			ctx.lineTo(x + xOffset, y + yOffset);
42609			ctx.moveTo(x - xOffset, y + yOffset);
42610			ctx.lineTo(x + xOffset, y - yOffset);
42611			ctx.closePath();
42612			break;
42613		case 'star':
42614			ctx.beginPath();
42615			ctx.moveTo(x, y + radius);
42616			ctx.lineTo(x, y - radius);
42617			ctx.moveTo(x - radius, y);
42618			ctx.lineTo(x + radius, y);
42619			xOffset = Math.cos(Math.PI / 4) * radius;
42620			yOffset = Math.sin(Math.PI / 4) * radius;
42621			ctx.moveTo(x - xOffset, y - yOffset);
42622			ctx.lineTo(x + xOffset, y + yOffset);
42623			ctx.moveTo(x - xOffset, y + yOffset);
42624			ctx.lineTo(x + xOffset, y - yOffset);
42625			ctx.closePath();
42626			break;
42627		case 'line':
42628			ctx.beginPath();
42629			ctx.moveTo(x - radius, y);
42630			ctx.lineTo(x + radius, y);
42631			ctx.closePath();
42632			break;
42633		case 'dash':
42634			ctx.beginPath();
42635			ctx.moveTo(x, y);
42636			ctx.lineTo(x + radius, y);
42637			ctx.closePath();
42638			break;
42639		}
42640
42641		ctx.stroke();
42642	},
42643
42644	clipArea: function(ctx, area) {
42645		ctx.save();
42646		ctx.beginPath();
42647		ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);
42648		ctx.clip();
42649	},
42650
42651	unclipArea: function(ctx) {
42652		ctx.restore();
42653	},
42654
42655	lineTo: function(ctx, previous, target, flip) {
42656		if (target.steppedLine) {
42657			if ((target.steppedLine === 'after' && !flip) || (target.steppedLine !== 'after' && flip)) {
42658				ctx.lineTo(previous.x, target.y);
42659			} else {
42660				ctx.lineTo(target.x, previous.y);
42661			}
42662			ctx.lineTo(target.x, target.y);
42663			return;
42664		}
42665
42666		if (!target.tension) {
42667			ctx.lineTo(target.x, target.y);
42668			return;
42669		}
42670
42671		ctx.bezierCurveTo(
42672			flip ? previous.controlPointPreviousX : previous.controlPointNextX,
42673			flip ? previous.controlPointPreviousY : previous.controlPointNextY,
42674			flip ? target.controlPointNextX : target.controlPointPreviousX,
42675			flip ? target.controlPointNextY : target.controlPointPreviousY,
42676			target.x,
42677			target.y);
42678	}
42679};
42680
42681// DEPRECATIONS
42682
42683/**
42684 * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.
42685 * @namespace Chart.helpers.clear
42686 * @deprecated since version 2.7.0
42687 * @todo remove at version 3
42688 * @private
42689 */
42690helpers.clear = exports.clear;
42691
42692/**
42693 * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.
42694 * @namespace Chart.helpers.drawRoundedRectangle
42695 * @deprecated since version 2.7.0
42696 * @todo remove at version 3
42697 * @private
42698 */
42699helpers.drawRoundedRectangle = function(ctx) {
42700	ctx.beginPath();
42701	exports.roundedRect.apply(exports, arguments);
42702	ctx.closePath();
42703};
42704
42705},{"42":42}],42:[function(require,module,exports){
42706'use strict';
42707
42708/**
42709 * @namespace Chart.helpers
42710 */
42711var helpers = {
42712	/**
42713	 * An empty function that can be used, for example, for optional callback.
42714	 */
42715	noop: function() {},
42716
42717	/**
42718	 * Returns a unique id, sequentially generated from a global variable.
42719	 * @returns {Number}
42720	 * @function
42721	 */
42722	uid: (function() {
42723		var id = 0;
42724		return function() {
42725			return id++;
42726		};
42727	}()),
42728
42729	/**
42730	 * Returns true if `value` is neither null nor undefined, else returns false.
42731	 * @param {*} value - The value to test.
42732	 * @returns {Boolean}
42733	 * @since 2.7.0
42734	 */
42735	isNullOrUndef: function(value) {
42736		return value === null || typeof value === 'undefined';
42737	},
42738
42739	/**
42740	 * Returns true if `value` is an array, else returns false.
42741	 * @param {*} value - The value to test.
42742	 * @returns {Boolean}
42743	 * @function
42744	 */
42745	isArray: Array.isArray ? Array.isArray : function(value) {
42746		return Object.prototype.toString.call(value) === '[object Array]';
42747	},
42748
42749	/**
42750	 * Returns true if `value` is an object (excluding null), else returns false.
42751	 * @param {*} value - The value to test.
42752	 * @returns {Boolean}
42753	 * @since 2.7.0
42754	 */
42755	isObject: function(value) {
42756		return value !== null && Object.prototype.toString.call(value) === '[object Object]';
42757	},
42758
42759	/**
42760	 * Returns `value` if defined, else returns `defaultValue`.
42761	 * @param {*} value - The value to return if defined.
42762	 * @param {*} defaultValue - The value to return if `value` is undefined.
42763	 * @returns {*}
42764	 */
42765	valueOrDefault: function(value, defaultValue) {
42766		return typeof value === 'undefined' ? defaultValue : value;
42767	},
42768
42769	/**
42770	 * Returns value at the given `index` in array if defined, else returns `defaultValue`.
42771	 * @param {Array} value - The array to lookup for value at `index`.
42772	 * @param {Number} index - The index in `value` to lookup for value.
42773	 * @param {*} defaultValue - The value to return if `value[index]` is undefined.
42774	 * @returns {*}
42775	 */
42776	valueAtIndexOrDefault: function(value, index, defaultValue) {
42777		return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);
42778	},
42779
42780	/**
42781	 * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the
42782	 * value returned by `fn`. If `fn` is not a function, this method returns undefined.
42783	 * @param {Function} fn - The function to call.
42784	 * @param {Array|undefined|null} args - The arguments with which `fn` should be called.
42785	 * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
42786	 * @returns {*}
42787	 */
42788	callback: function(fn, args, thisArg) {
42789		if (fn && typeof fn.call === 'function') {
42790			return fn.apply(thisArg, args);
42791		}
42792	},
42793
42794	/**
42795	 * Note(SB) for performance sake, this method should only be used when loopable type
42796	 * is unknown or in none intensive code (not called often and small loopable). Else
42797	 * it's preferable to use a regular for() loop and save extra function calls.
42798	 * @param {Object|Array} loopable - The object or array to be iterated.
42799	 * @param {Function} fn - The function to call for each item.
42800	 * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`.
42801	 * @param {Boolean} [reverse] - If true, iterates backward on the loopable.
42802	 */
42803	each: function(loopable, fn, thisArg, reverse) {
42804		var i, len, keys;
42805		if (helpers.isArray(loopable)) {
42806			len = loopable.length;
42807			if (reverse) {
42808				for (i = len - 1; i >= 0; i--) {
42809					fn.call(thisArg, loopable[i], i);
42810				}
42811			} else {
42812				for (i = 0; i < len; i++) {
42813					fn.call(thisArg, loopable[i], i);
42814				}
42815			}
42816		} else if (helpers.isObject(loopable)) {
42817			keys = Object.keys(loopable);
42818			len = keys.length;
42819			for (i = 0; i < len; i++) {
42820				fn.call(thisArg, loopable[keys[i]], keys[i]);
42821			}
42822		}
42823	},
42824
42825	/**
42826	 * Returns true if the `a0` and `a1` arrays have the same content, else returns false.
42827	 * @see http://stackoverflow.com/a/14853974
42828	 * @param {Array} a0 - The array to compare
42829	 * @param {Array} a1 - The array to compare
42830	 * @returns {Boolean}
42831	 */
42832	arrayEquals: function(a0, a1) {
42833		var i, ilen, v0, v1;
42834
42835		if (!a0 || !a1 || a0.length !== a1.length) {
42836			return false;
vendor: 10,367 bytes, lines 42837-43290
42837		}
42838
42839		for (i = 0, ilen = a0.length; i < ilen; ++i) {
42840			v0 = a0[i];
42841			v1 = a1[i];
42842
42843			if (v0 instanceof Array && v1 instanceof Array) {
42844				if (!helpers.arrayEquals(v0, v1)) {
42845					return false;
42846				}
42847			} else if (v0 !== v1) {
42848				// NOTE: two different object instances will never be equal: {x:20} != {x:20}
42849				return false;
42850			}
42851		}
42852
42853		return true;
42854	},
42855
42856	/**
42857	 * Returns a deep copy of `source` without keeping references on objects and arrays.
42858	 * @param {*} source - The value to clone.
42859	 * @returns {*}
42860	 */
42861	clone: function(source) {
42862		if (helpers.isArray(source)) {
42863			return source.map(helpers.clone);
42864		}
42865
42866		if (helpers.isObject(source)) {
42867			var target = {};
42868			var keys = Object.keys(source);
42869			var klen = keys.length;
42870			var k = 0;
42871
42872			for (; k < klen; ++k) {
42873				target[keys[k]] = helpers.clone(source[keys[k]]);
42874			}
42875
42876			return target;
42877		}
42878
42879		return source;
42880	},
42881
42882	/**
42883	 * The default merger when Chart.helpers.merge is called without merger option.
42884	 * Note(SB): this method is also used by configMerge and scaleMerge as fallback.
42885	 * @private
42886	 */
42887	_merger: function(key, target, source, options) {
42888		var tval = target[key];
42889		var sval = source[key];
42890
42891		if (helpers.isObject(tval) && helpers.isObject(sval)) {
42892			helpers.merge(tval, sval, options);
42893		} else {
42894			target[key] = helpers.clone(sval);
42895		}
42896	},
42897
42898	/**
42899	 * Merges source[key] in target[key] only if target[key] is undefined.
42900	 * @private
42901	 */
42902	_mergerIf: function(key, target, source) {
42903		var tval = target[key];
42904		var sval = source[key];
42905
42906		if (helpers.isObject(tval) && helpers.isObject(sval)) {
42907			helpers.mergeIf(tval, sval);
42908		} else if (!target.hasOwnProperty(key)) {
42909			target[key] = helpers.clone(sval);
42910		}
42911	},
42912
42913	/**
42914	 * Recursively deep copies `source` properties into `target` with the given `options`.
42915	 * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
42916	 * @param {Object} target - The target object in which all sources are merged into.
42917	 * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
42918	 * @param {Object} [options] - Merging options:
42919	 * @param {Function} [options.merger] - The merge method (key, target, source, options)
42920	 * @returns {Object} The `target` object.
42921	 */
42922	merge: function(target, source, options) {
42923		var sources = helpers.isArray(source) ? source : [source];
42924		var ilen = sources.length;
42925		var merge, i, keys, klen, k;
42926
42927		if (!helpers.isObject(target)) {
42928			return target;
42929		}
42930
42931		options = options || {};
42932		merge = options.merger || helpers._merger;
42933
42934		for (i = 0; i < ilen; ++i) {
42935			source = sources[i];
42936			if (!helpers.isObject(source)) {
42937				continue;
42938			}
42939
42940			keys = Object.keys(source);
42941			for (k = 0, klen = keys.length; k < klen; ++k) {
42942				merge(keys[k], target, source, options);
42943			}
42944		}
42945
42946		return target;
42947	},
42948
42949	/**
42950	 * Recursively deep copies `source` properties into `target` *only* if not defined in target.
42951	 * IMPORTANT: `target` is not cloned and will be updated with `source` properties.
42952	 * @param {Object} target - The target object in which all sources are merged into.
42953	 * @param {Object|Array(Object)} source - Object(s) to merge into `target`.
42954	 * @returns {Object} The `target` object.
42955	 */
42956	mergeIf: function(target, source) {
42957		return helpers.merge(target, source, {merger: helpers._mergerIf});
42958	},
42959
42960	/**
42961	 * Applies the contents of two or more objects together into the first object.
42962	 * @param {Object} target - The target object in which all objects are merged into.
42963	 * @param {Object} arg1 - Object containing additional properties to merge in target.
42964	 * @param {Object} argN - Additional objects containing properties to merge in target.
42965	 * @returns {Object} The `target` object.
42966	 */
42967	extend: function(target) {
42968		var setFn = function(value, key) {
42969			target[key] = value;
42970		};
42971		for (var i = 1, ilen = arguments.length; i < ilen; ++i) {
42972			helpers.each(arguments[i], setFn);
42973		}
42974		return target;
42975	},
42976
42977	/**
42978	 * Basic javascript inheritance based on the model created in Backbone.js
42979	 */
42980	inherits: function(extensions) {
42981		var me = this;
42982		var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {
42983			return me.apply(this, arguments);
42984		};
42985
42986		var Surrogate = function() {
42987			this.constructor = ChartElement;
42988		};
42989
42990		Surrogate.prototype = me.prototype;
42991		ChartElement.prototype = new Surrogate();
42992		ChartElement.extend = helpers.inherits;
42993
42994		if (extensions) {
42995			helpers.extend(ChartElement.prototype, extensions);
42996		}
42997
42998		ChartElement.__super__ = me.prototype;
42999		return ChartElement;
43000	}
43001};
43002
43003module.exports = helpers;
43004
43005// DEPRECATIONS
43006
43007/**
43008 * Provided for backward compatibility, use Chart.helpers.callback instead.
43009 * @function Chart.helpers.callCallback
43010 * @deprecated since version 2.6.0
43011 * @todo remove at version 3
43012 * @private
43013 */
43014helpers.callCallback = helpers.callback;
43015
43016/**
43017 * Provided for backward compatibility, use Array.prototype.indexOf instead.
43018 * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+
43019 * @function Chart.helpers.indexOf
43020 * @deprecated since version 2.7.0
43021 * @todo remove at version 3
43022 * @private
43023 */
43024helpers.indexOf = function(array, item, fromIndex) {
43025	return Array.prototype.indexOf.call(array, item, fromIndex);
43026};
43027
43028/**
43029 * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.
43030 * @function Chart.helpers.getValueOrDefault
43031 * @deprecated since version 2.7.0
43032 * @todo remove at version 3
43033 * @private
43034 */
43035helpers.getValueOrDefault = helpers.valueOrDefault;
43036
43037/**
43038 * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.
43039 * @function Chart.helpers.getValueAtIndexOrDefault
43040 * @deprecated since version 2.7.0
43041 * @todo remove at version 3
43042 * @private
43043 */
43044helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
43045
43046},{}],43:[function(require,module,exports){
43047'use strict';
43048
43049var helpers = require(42);
43050
43051/**
43052 * Easing functions adapted from Robert Penner's easing equations.
43053 * @namespace Chart.helpers.easingEffects
43054 * @see http://www.robertpenner.com/easing/
43055 */
43056var effects = {
43057	linear: function(t) {
43058		return t;
43059	},
43060
43061	easeInQuad: function(t) {
43062		return t * t;
43063	},
43064
43065	easeOutQuad: function(t) {
43066		return -t * (t - 2);
43067	},
43068
43069	easeInOutQuad: function(t) {
43070		if ((t /= 0.5) < 1) {
43071			return 0.5 * t * t;
43072		}
43073		return -0.5 * ((--t) * (t - 2) - 1);
43074	},
43075
43076	easeInCubic: function(t) {
43077		return t * t * t;
43078	},
43079
43080	easeOutCubic: function(t) {
43081		return (t = t - 1) * t * t + 1;
43082	},
43083
43084	easeInOutCubic: function(t) {
43085		if ((t /= 0.5) < 1) {
43086			return 0.5 * t * t * t;
43087		}
43088		return 0.5 * ((t -= 2) * t * t + 2);
43089	},
43090
43091	easeInQuart: function(t) {
43092		return t * t * t * t;
43093	},
43094
43095	easeOutQuart: function(t) {
43096		return -((t = t - 1) * t * t * t - 1);
43097	},
43098
43099	easeInOutQuart: function(t) {
43100		if ((t /= 0.5) < 1) {
43101			return 0.5 * t * t * t * t;
43102		}
43103		return -0.5 * ((t -= 2) * t * t * t - 2);
43104	},
43105
43106	easeInQuint: function(t) {
43107		return t * t * t * t * t;
43108	},
43109
43110	easeOutQuint: function(t) {
43111		return (t = t - 1) * t * t * t * t + 1;
43112	},
43113
43114	easeInOutQuint: function(t) {
43115		if ((t /= 0.5) < 1) {
43116			return 0.5 * t * t * t * t * t;
43117		}
43118		return 0.5 * ((t -= 2) * t * t * t * t + 2);
43119	},
43120
43121	easeInSine: function(t) {
43122		return -Math.cos(t * (Math.PI / 2)) + 1;
43123	},
43124
43125	easeOutSine: function(t) {
43126		return Math.sin(t * (Math.PI / 2));
43127	},
43128
43129	easeInOutSine: function(t) {
43130		return -0.5 * (Math.cos(Math.PI * t) - 1);
43131	},
43132
43133	easeInExpo: function(t) {
43134		return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));
43135	},
43136
43137	easeOutExpo: function(t) {
43138		return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;
43139	},
43140
43141	easeInOutExpo: function(t) {
43142		if (t === 0) {
43143			return 0;
43144		}
43145		if (t === 1) {
43146			return 1;
43147		}
43148		if ((t /= 0.5) < 1) {
43149			return 0.5 * Math.pow(2, 10 * (t - 1));
43150		}
43151		return 0.5 * (-Math.pow(2, -10 * --t) + 2);
43152	},
43153
43154	easeInCirc: function(t) {
43155		if (t >= 1) {
43156			return t;
43157		}
43158		return -(Math.sqrt(1 - t * t) - 1);
43159	},
43160
43161	easeOutCirc: function(t) {
43162		return Math.sqrt(1 - (t = t - 1) * t);
43163	},
43164
43165	easeInOutCirc: function(t) {
43166		if ((t /= 0.5) < 1) {
43167			return -0.5 * (Math.sqrt(1 - t * t) - 1);
43168		}
43169		return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);
43170	},
43171
43172	easeInElastic: function(t) {
43173		var s = 1.70158;
43174		var p = 0;
43175		var a = 1;
43176		if (t === 0) {
43177			return 0;
43178		}
43179		if (t === 1) {
43180			return 1;
43181		}
43182		if (!p) {
43183			p = 0.3;
43184		}
43185		if (a < 1) {
43186			a = 1;
43187			s = p / 4;
43188		} else {
43189			s = p / (2 * Math.PI) * Math.asin(1 / a);
43190		}
43191		return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
43192	},
43193
43194	easeOutElastic: function(t) {
43195		var s = 1.70158;
43196		var p = 0;
43197		var a = 1;
43198		if (t === 0) {
43199			return 0;
43200		}
43201		if (t === 1) {
43202			return 1;
43203		}
43204		if (!p) {
43205			p = 0.3;
43206		}
43207		if (a < 1) {
43208			a = 1;
43209			s = p / 4;
43210		} else {
43211			s = p / (2 * Math.PI) * Math.asin(1 / a);
43212		}
43213		return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;
43214	},
43215
43216	easeInOutElastic: function(t) {
43217		var s = 1.70158;
43218		var p = 0;
43219		var a = 1;
43220		if (t === 0) {
43221			return 0;
43222		}
43223		if ((t /= 0.5) === 2) {
43224			return 1;
43225		}
43226		if (!p) {
43227			p = 0.45;
43228		}
43229		if (a < 1) {
43230			a = 1;
43231			s = p / 4;
43232		} else {
43233			s = p / (2 * Math.PI) * Math.asin(1 / a);
43234		}
43235		if (t < 1) {
43236			return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
43237		}
43238		return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;
43239	},
43240	easeInBack: function(t) {
43241		var s = 1.70158;
43242		return t * t * ((s + 1) * t - s);
43243	},
43244
43245	easeOutBack: function(t) {
43246		var s = 1.70158;
43247		return (t = t - 1) * t * ((s + 1) * t + s) + 1;
43248	},
43249
43250	easeInOutBack: function(t) {
43251		var s = 1.70158;
43252		if ((t /= 0.5) < 1) {
43253			return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));
43254		}
43255		return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
43256	},
43257
43258	easeInBounce: function(t) {
43259		return 1 - effects.easeOutBounce(1 - t);
43260	},
43261
43262	easeOutBounce: function(t) {
43263		if (t < (1 / 2.75)) {
43264			return 7.5625 * t * t;
43265		}
43266		if (t < (2 / 2.75)) {
43267			return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;
43268		}
43269		if (t < (2.5 / 2.75)) {
43270			return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;
43271		}
43272		return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;
43273	},
43274
43275	easeInOutBounce: function(t) {
43276		if (t < 0.5) {
43277			return effects.easeInBounce(t * 2) * 0.5;
43278		}
43279		return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;
43280	}
43281};
43282
43283module.exports = {
43284	effects: effects
43285};
43286
43287// DEPRECATIONS
43288
43289/**
43290 * Provided for backward compatibility, use Chart.helpers.easing.effects instead.
43291 * @function Chart.helpers.easingEffects
43292 * @deprecated since version 2.7.0
43293 * @todo remove at version 3
43294 * @private
43295 */
43296helpers.easingEffects = effects;
43297
43298},{"42":42}],44:[function(require,module,exports){
43299'use strict';
43300
43301var helpers = require(42);
43302
43303/**
43304 * @alias Chart.helpers.options
43305 * @namespace
43306 */
43307module.exports = {
43308	/**
43309	 * Converts the given line height `value` in pixels for a specific font `size`.
43310	 * @param {Number|String} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').
43311	 * @param {Number} size - The font size (in pixels) used to resolve relative `value`.
43312	 * @returns {Number} The effective line height in pixels (size * 1.2 if value is invalid).
43313	 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
43314	 * @since 2.7.0
43315	 */
43316	toLineHeight: function(value, size) {
43317		var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);
43318		if (!matches || matches[1] === 'normal') {
43319			return size * 1.2;
43320		}
43321
43322		value = +matches[2];
43323
43324		switch (matches[3]) {
43325		case 'px':
43326			return value;
43327		case '%':
43328			value /= 100;
43329			break;
43330		default:
43331			break;
43332		}
43333
43334		return size * value;
43335	},
43336
43337	/**
43338	 * Converts the given value into a padding object with pre-computed width/height.
43339	 * @param {Number|Object} value - If a number, set the value to all TRBL component,
43340	 *  else, if and object, use defined properties and sets undefined ones to 0.
43341	 * @returns {Object} The padding values (top, right, bottom, left, width, height)
43342	 * @since 2.7.0
43343	 */
43344	toPadding: function(value) {
43345		var t, r, b, l;
43346
43347		if (helpers.isObject(value)) {
43348			t = +value.top || 0;
43349			r = +value.right || 0;
43350			b = +value.bottom || 0;
43351			l = +value.left || 0;
43352		} else {
43353			t = r = b = l = +value || 0;
43354		}
43355
43356		return {
43357			top: t,
43358			right: r,
43359			bottom: b,
43360			left: l,
43361			height: t + b,
43362			width: l + r
43363		};
43364	},
43365
43366	/**
43367	 * Evaluates the given `inputs` sequentially and returns the first defined value.
43368	 * @param {Array[]} inputs - An array of values, falling back to the last value.
43369	 * @param {Object} [context] - If defined and the current value is a function, the value
43370	 * is called with `context` as first argument and the result becomes the new input.
43371	 * @param {Number} [index] - If defined and the current value is an array, the value
43372	 * at `index` become the new input.
43373	 * @since 2.7.0
43374	 */
43375	resolve: function(inputs, context, index) {
43376		var i, ilen, value;
43377
43378		for (i = 0, ilen = inputs.length; i < ilen; ++i) {
43379			value = inputs[i];
43380			if (value === undefined) {
43381				continue;
43382			}
43383			if (context !== undefined && typeof value === 'function') {
43384				value = value(context);
43385			}
43386			if (index !== undefined && helpers.isArray(value)) {
43387				value = value[index];
43388			}
43389			if (value !== undefined) {
43390				return value;
43391			}
43392		}
43393	}
43394};
43395
43396},{"42":42}],45:[function(require,module,exports){
43397'use strict';
43398
43399module.exports = require(42);
43400module.exports.easing = require(43);
43401module.exports.canvas = require(41);
43402module.exports.options = require(44);
43403
43404},{"41":41,"42":42,"43":43,"44":44}],46:[function(require,module,exports){
43405/**
43406 * Platform fallback implementation (minimal).
43407 * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939
43408 */
43409
43410module.exports = {
43411	acquireContext: function(item) {
43412		if (item && item.canvas) {
43413			// Support for any object associated to a canvas (including a context2d)
43414			item = item.canvas;
43415		}
43416
43417		return item && item.getContext('2d') || null;
43418	}
43419};
43420
43421},{}],47:[function(require,module,exports){
43422/**
43423 * Chart.Platform implementation for targeting a web browser
43424 */
43425
43426'use strict';
43427
43428var helpers = require(45);
43429
43430var EXPANDO_KEY = '$chartjs';
43431var CSS_PREFIX = 'chartjs-';
43432var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';
43433var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';
43434var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];
43435
43436/**
43437 * DOM event types -> Chart.js event types.
43438 * Note: only events with different types are mapped.
43439 * @see https://developer.mozilla.org/en-US/docs/Web/Events
43440 */
43441var EVENT_TYPES = {
43442	touchstart: 'mousedown',
43443	touchmove: 'mousemove',
43444	touchend: 'mouseup',
43445	pointerenter: 'mouseenter',
43446	pointerdown: 'mousedown',
43447	pointermove: 'mousemove',
43448	pointerup: 'mouseup',
43449	pointerleave: 'mouseout',
43450	pointerout: 'mouseout'
43451};
43452
43453/**
43454 * The "used" size is the final value of a dimension property after all calculations have
43455 * been performed. This method uses the computed style of `element` but returns undefined
43456 * if the computed style is not expressed in pixels. That can happen in some cases where
43457 * `element` has a size relative to its parent and this last one is not yet displayed,
43458 * for example because of `display: none` on a parent node.
43459 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
43460 * @returns {Number} Size in pixels or undefined if unknown.
43461 */
43462function readUsedSize(element, property) {
43463	var value = helpers.getStyle(element, property);
43464	var matches = value && value.match(/^(\d+)(\.\d+)?px$/);
43465	return matches ? Number(matches[1]) : undefined;
43466}
43467
43468/**
43469 * Initializes the canvas style and render size without modifying the canvas display size,
43470 * since responsiveness is handled by the controller.resize() method. The config is used
43471 * to determine the aspect ratio to apply in case no explicit height has been specified.
43472 */
43473function initCanvas(canvas, config) {
43474	var style = canvas.style;
43475
43476	// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
43477	// returns null or '' if no explicit value has been set to the canvas attribute.
43478	var renderHeight = canvas.getAttribute('height');
43479	var renderWidth = canvas.getAttribute('width');
43480
43481	// Chart.js modifies some canvas values that we want to restore on de
43481stroy
43482	canvas[EXPANDO_KEY] = {
43483		initial: {
43484			height: renderHeight,
43485			width: renderWidth,
43486			style: {
43487				display: style.display,
43488				height: style.height,
43489				width: style.width
43490			}
43491		}
43492	};
43493
43494	// Force canvas to display as block to avoid extra space caused by inline
43495	// elements, which would interfere with the responsive resize process.
43496	// https://github.com/chartjs/Chart.js/issues/2538
43497	style.display = style.display || 'block';
43498
43499	if (renderWidth === null || renderWidth === '') {
43500		var displayWidth = readUsedSize(canvas, 'width');
43501		if (displayWidth !== undefined) {
43502			canvas.width = displayWidth;
43503		}
43504	}
43505
43506	if (renderHeight === null || renderHeight === '') {
43507		if (canvas.style.height === '') {
43508			// If no explicit render height and style height, let's apply the aspect ratio,
43509			// which one can be specified by the user but also by charts as default option
43510			// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
43511			canvas.height = canvas.width / (config.options.aspectRatio || 2);
43512		} else {
43513			var displayHeight = readUsedSize(canvas, 'height');
43514			if (displayWidth !== undefined) {
43515				canvas.height = displayHeight;
43516			}
43517		}
43518	}
43519
43520	return canvas;
43521}
43522
43523/**
43524 * Detects support for options object argument in addEventListener.
43525 * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
43526 * @private
43527 */
43528var supportsEventListenerOptions = (function() {
43529	var supports = false;
43530	try {
43531		var options = Object.defineProperty({}, 'passive', {
43532			get: function() {
43533				supports = true;
43534			}
43535		});
43536		window.addEventListener('e', null, options);
43537	} catch (e) {
43538		// continue regardless of error
43539	}
43540	return supports;
43541}());
43542
43543// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
43544// https://github.com/chartjs/Chart.js/issues/4287
43545var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;
43546
43547function addEventListener(node, type, listener) {
43548	node.addEventListener(type, listener, eventListenerOptions);
43549}
43550
43551function removeEventListener(node, type, listener) {
43552	node.removeEventListener(type, listener, eventListenerOptions);
43553}
43554
43555function createEvent(type, chart, x, y, nativeEvent) {
43556	return {
43557		type: type,
43558		chart: chart,
43559		native: nativeEvent || null,
43560		x: x !== undefined ? x : null,
43561		y: y !== undefined ? y : null,
43562	};
43563}
43564
43565function fromNativeEvent(event, chart) {
43566	var type = EVENT_TYPES[event.type] || event.type;
43567	var pos = helpers.getRelativePosition(event, chart);
43568	return createEvent(type, chart, pos.x, pos.y, event);
43569}
43570
43571function throttled(fn, thisArg) {
43572	var ticking = false;
43573	var args = [];
43574
43575	return function() {
43576		args = Array.prototype.slice.call(arguments);
43577		thisArg = thisArg || this;
43578
43579		if (!ticking) {
43580			ticking = true;
43581			helpers.requestAnimFrame.call(window, function() {
43582				ticking = false;
43583				fn.apply(thisArg, args);
43584			});
43585		}
43586	};
43587}
43588
43589// Implementation based on https://github.com/marcj/css-element-queries
43590function createResizer(handler) {
43591	var resizer = document.createElement('div');
43592	var cls = CSS_PREFIX + 'size-monitor';
43593	var maxSize = 1000000;
43594	var style =
43595		'position:absolute;' +
43596		'left:0;' +
43597		'top:0;' +
43598		'right:0;' +
43599		'bottom:0;' +
43600		'overflow:hidden;' +
43601		'pointer-events:none;' +
43602		'visibility:hidden;' +
43603		'z-index:-1;';
43604
43605	resizer.style.cssText = style;
43606	resizer.className = cls;
43607	resizer.innerHTML =
43608		'<div class="' + cls + '-expand" style="' + style + '">' +
43609			'<div style="' +
43610				'position:absolute;' +
43611				'width:' + maxSize + 'px;' +
43612				'height:' + maxSize + 'px;' +
43613				'left:0;' +
43614				'top:0">' +
43615			'</div>' +
43616		'</div>' +
43617		'<div class="' + cls + '-shrink" style="' + style + '">' +
43618			'<div style="' +
43619				'position:absolute;' +
43620				'width:200%;' +
43621				'height:200%;' +
43622				'left:0; ' +
43623				'top:0">' +
43624			'</div>' +
43625		'</div>';
43626
43627	var expand = resizer.childNodes[0];
43628	var shrink = resizer.childNodes[1];
43629
43630	resizer._reset = function() {
43631		expand.scrollLeft = maxSize;
43632		expand.scrollTop = maxSize;
43633		shrink.scrollLeft = maxSize;
43634		shrink.scrollTop = maxSize;
43635	};
43636	var onScroll = function() {
43637		resizer._reset();
43638		handler();
43639	};
43640
43641	addEventListener(expand, 'scroll', onScroll.bind(expand, 'expand'));
43642	addEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));
43643
43644	return resizer;
43645}
43646
43647// https://davidwalsh.name/detect-node-insertion
43648function watchForRender(node, handler) {
43649	var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
43650	var proxy = expando.renderProxy = function(e) {
43651		if (e.animationName === CSS_RENDER_ANIMATION) {
43652			handler();
43653		}
43654	};
43655
43656	helpers.each(ANIMATION_START_EVENTS, function(type) {
43657		addEventListener(node, type, proxy);
43658	});
43659
43660	// #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class
43661	// is removed then added back immediately (same animation frame?). Accessing the
43662	// `offsetParent` property will force a reflow and re-evaluate the CSS animation.
43663	// https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics
43664	// https://github.com/chartjs/Chart.js/issues/4737
43665	expando.reflow = !!node.offsetParent;
43666
43667	node.classList.add(CSS_RENDER_MONITOR);
43668}
43669
43670function unwatchForRender(node) {
43671	var expando = node[EXPANDO_KEY] || {};
43672	var proxy = expando.renderProxy;
43673
43674	if (proxy) {
43675		helpers.each(ANIMATION_START_EVENTS, function(type) {
43676			removeEventListener(node, type, proxy);
43677		});
43678
43679		delete expando.renderProxy;
43680	}
43681
43682	node.classList.remove(CSS_RENDER_MONITOR);
43683}
43684
43685function addResizeListener(node, listener, chart) {
43686	var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});
43687
43688	// Let's keep track of this added resizer and thus avoid DOM query when removing it.
43689	var resizer = expando.resizer = createResizer(throttled(function() {
43690		if (expando.resizer) {
43691			return listener(createEvent('resize', chart));
43692		}
43693	}));
43694
43695	// The resizer needs to be attached to the node parent, so we first need to be
43696	// sure that `node` is attached to the DOM before injecting the resizer element.
43697	watchForRender(node, function() {
43698		if (expando.resizer) {
43699			var container = node.parentNode;
43700			if (container && container !== resizer.parentNode) {
43701				container.insertBefore(resizer, container.firstChild);
43702			}
43703
43704			// The container size might have changed, let's reset the resizer state.
43705			resizer._reset();
43706		}
43707	});
43708}
43709
43710function removeResizeListener(node) {
43711	var expando = node[EXPANDO_KEY] || {};
43712	var resizer = expando.resizer;
43713
43714	delete expando.resizer;
43715	unwatchForRender(node);
43716
43717	if (resizer && resizer.parentNode) {
43718		resizer.parentNode.removeChild(resizer);
43719	}
43720}
43721
43722function injectCSS(platform, css) {
43723	// http://stackoverflow.com/q/3922139
43724	var style = platform._style || document.createElement('style');
43725	if (!platform._style) {
43726		platform._style = style;
43727		css = '/* Chart.js */\n' + css;
43728		style.setAttribute('type', 'text/css');
43729		document.getElementsByTagName('head')[0].appendChild(style);
43730	}
43731
43732	style.appendChild(document.createTextNode(css));
43733}
43734
43735module.exports = {
43736	/**
43737	 * This property holds whether this platform is enabled for the current environment.
43738	 * Currently used by platform.js to select the proper implementation.
43739	 * @private
43740	 */
43741	_enabled: typeof window !== 'undefined' && typeof document !== 'undefined',
43742
43743	initialize: function() {
43744		var keyframes = 'from{opacity:0.99}to{opacity:1}';
43745
43746		injectCSS(this,
43747			// DOM rendering detection
43748			// https://davidwalsh.name/detect-node-insertion
43749			'@-webkit-keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +
43750			'@keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' +
43751			'.' + CSS_RENDER_MONITOR + '{' +
43752				'-webkit-animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +
43753				'animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' +
43754			'}'
43755		);
43756	},
43757
43758	acquireContext: function(item, config) {
43759		if (typeof item === 'string') {
43760			item = document.getElementById(item);
43761		} else if (item.length) {
43762			// Support for array based queries (such as jQuery)
43763			item = item[0];
43764		}
43765
43766		if (item && item.canvas) {
43767			// Support for any object associated to a canvas (including a context2d)
43768			item = item.canvas;
43769		}
43770
43771		// To prevent canvas fingerprinting, some add-ons undefine the getContext
43772		// method, for example: https://github.com/kkapsner/CanvasBlocker
43773		// https://github.com/chartjs/Chart.js/issues/2807
43774		var context = item && item.getContext && item.getContext('2d');
43775
43776		// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is
43777		// inside an iframe or when running in a protected environment. We could guess the
43778		// types from their toString() value but let's keep things flexible and assume it's
43779		// a sufficient condition if the item has a context2D which has item as `canvas`.
43780		// https://github.com/chartjs/Chart.js/issues/3887
43781		// https://github.com/chartjs/Chart.js/issues/4102
43782		// https://github.com/chartjs/Chart.js/issues/4152
43783		if (context && context.canvas === item) {
43784			initCanvas(item, config);
43785			return context;
43786		}
43787
43788		return null;
43789	},
43790
43791	releaseContext: function(context) {
43792		var canvas = context.canvas;
43793		if (!canvas[EXPANDO_KEY]) {
43794			return;
43795		}
43796
43797		var initial = canvas[EXPANDO_KEY].initial;
43798		['height', 'width'].forEach(function(prop) {
43799			var value = initial[prop];
43800			if (helpers.isNullOrUndef(value)) {
43801				canvas.removeAttribute(prop);
43802			} else {
43803				canvas.setAttribute(prop, value);
43804			}
43805		});
43806
43807		helpers.each(initial.style || {}, function(value, key) {
43808			canvas.style[key] = value;
43809		});
43810
43811		// The canvas render size might have been changed (and thus the state stack discarded),
43812		// we can't use save() and restore() to restore the initial state. So make sure that at
43813		// least the canvas context is reset to the default state by setting the canvas width.
43814		// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html
43815		canvas.width = canvas.width;
43816
43817		delete canvas[EXPANDO_KEY];
43818	},
43819
43820	addEventListener: function(chart, type, listener) {
43821		var canvas = chart.canvas;
43822		if (type === 'resize') {
43823			// Note: the resize event is not supported on all browsers.
43824			addResizeListener(canvas, listener, chart);
43825			return;
43826		}
43827
43828		var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});
43829		var proxies = expando.proxies || (expando.proxies = {});
43830		var proxy = proxies[chart.id + '_' + type] = function(event) {
43831			listener(fromNativeEvent(event, chart));
43832		};
43833
43834		addEventListener(canvas, type, proxy);
43835	},
43836
43837	removeEventListener: function(chart, type, listener) {
43838		var canvas = chart.canvas;
43839		if (type === 'resize') {
43840			// Note: the resize event is not supported on all browsers.
43841			removeResizeListener(canvas, listener);
43842			return;
43843		}
43844
43845		var expando = listener[EXPANDO_KEY] || {};
43846		var proxies = expando.proxies || {};
43847		var proxy = proxies[chart.id + '_' + type];
43848		if (!proxy) {
43849			return;
43850		}
43851
43852		removeEventListener(canvas, type, proxy);
43853	}
43854};
43855
43856// DEPRECATIONS
43857
43858/**
43859 * Provided for backward compatibility, use EventTarget.addEventListener instead.
43860 * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+
43861 * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
43862 * @function Chart.helpers.addEvent
43863 * @deprecated since version 2.7.0
43864 * @todo remove at version 3
43865 * @private
43866 */
43867helpers.addEvent = addEventListener;
43868
43869/**
43870 * Provided for backward compatibility, use EventTarget.removeEventListener instead.
43871 * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+
43872 * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
43873 * @function Chart.helpers.removeEvent
43874 * @deprecated since version 2.7.0
43875 * @todo remove at version 3
43876 * @private
43877 */
43878helpers.removeEvent = removeEventListener;
43879
43880},{"45":45}],48:[function(require,module,exports){
43881'use strict';
43882
43883var helpers = require(45);
43884var basic = require(46);
43885var dom = require(47);
43886
43887// @TODO Make possible to select another platform at build time.
43888var implementation = dom._enabled ? dom : basic;
43889
43890/**
43891 * @namespace Chart.platform
43892 * @see https://chartjs.gitbooks.io/proposals/content/Platform.html
43893 * @since 2.4.0
43894 */
43895module.exports = helpers.extend({
43896	/**
43897	 * @since 2.7.0
43898	 */
43899	initialize: function() {},
43900
43901	/**
43902	 * Called at chart construction time, returns a context2d instance implementing
43903	 * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.
43904	 * @param {*} item - The native item from which to acquire context (platform specific)
43905	 * @param {Object} options - The chart options
43906	 * @returns {CanvasRenderingContext2D} context2d instance
43907	 */
43908	acquireContext: function() {},
43909
43910	/**
43911	 * Called at chart destruction time, releases any resources associated to the context
43912	 * previously returned by the acquireContext() method.
43913	 * @param {CanvasRenderingContext2D} context - The context2d instance
43914	 * @returns {Boolean} true if the method succeeded, else false
43915	 */
43916	releaseContext: function() {},
43917
43918	/**
43919	 * Registers the specified listener on the given chart.
43920	 * @param {Chart} chart - Chart from which to listen for event
43921	 * @param {String} type - The ({@link IEvent}) type to listen for
43922	 * @param {Function} listener - Receives a notification (an object that implements
43923	 * the {@link IEvent} interface) when an event of the specified type occurs.
43924	 */
43925	addEventListener: function() {},
43926
43927	/**
43928	 * Removes the specified listener previously registered with addEventListener.
43929	 * @param {Chart} chart -Chart from which to remove the listener
43930	 * @param {String} type - The ({@link IEvent}) type to remove
43931	 * @param {Function} listener - The listener function to remove from the event target.
43932	 */
43933	removeEventListener: function() {}
43934
43935}, implementation);
43936
43937/**
43938 * @interface IPlatform
43939 * Allows abstracting platform dependencies away from the chart
43940 * @borrows Chart.platform.acquireContext as acquireContext
43941 * @borrows Chart.platform.releaseContext as releaseContext
43942 * @borrows Chart.platform.addEventListener as addEventListener
43943 * @borrows Chart.platform.removeEventListener as removeEventListener
43944 */
43945
43946/**
43947 * @interface IEvent
43948 * @prop {String} type - The event type name, possible values are:
43949 * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout',
43950 * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize'
43951 * @prop {*} native - The original native event (null for emulated events, e.g. 'resize')
43952 * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events)
43953 * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events)
43954 */
43955
43956},{"45":45,"46":46,"47":47}],49:[function(require,module,exports){
43957'use strict';
43958
43959module.exports = {};
43960module.exports.filler = require(50);
43961module.exports.legend = require(51);
43962module.exports.title = require(52);
43963
43964},{"50":50,"51":51,"52":52}],50:[function(require,module,exports){
43965/**
43966 * Plugin based on discussion from the following Chart.js issues:
43967 * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569
43968 * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897
43969 */
43970
43971'use strict';
43972
43973var defaults = require(25);
43974var elements = require(40);
43975var helpers = require(45);
43976
43977defaults._set('global', {
43978	plugins: {
43979		filler: {
43980			propagate: true
43981		}
43982	}
43983});
43984
43985var mappers = {
43986	dataset: function(source) {
43987		var index = source.fill;
43988		var chart = source.chart;
43989		var meta = chart.getDatasetMeta(index);
43990		var visible = meta && chart.isDatasetVisible(index);
43991		var points = (visible && meta.dataset._children) || [];
43992		var length = points.length || 0;
43993
43994		return !length ? null : function(point, i) {
43995			return (i < length && points[i]._view) || null;
43996		};
43997	},
43998
43999	boundary: function(source) {
44000		var boundary = source.boundary;
44001		var x = boundary ? boundary.x : null;
44002		var y = boundary ? boundary.y : null;
44003
44004		return function(point) {
44005			return {
44006				x: x === null ? point.x : x,
44007				y: y === null ? point.y : y,
44008			};
44009		};
44010	}
44011};
44012
44013// @todo if (fill[0] === '#')
44014function decodeFill(el, index, count) {
44015	var model = el._model || {};
44016	var fill = model.fill;
44017	var target;
44018
44019	if (fill === undefined) {
44020		fill = !!model.backgroundColor;
44021	}
44022
44023	if (fill === false || fill === null) {
44024		return false;
44025	}
44026
44027	if (fill === true) {
44028		return 'origin';
44029	}
44030
44031	target = parseFloat(fill, 10);
44032	if (isFinite(target) && Math.floor(target) === target) {
44033		if (fill[0] === '-' || fill[0] === '+') {
44034			target = index + target;
44035		}
44036
44037		if (target === index || target < 0 || target >= count) {
44038			return false;
44039		}
44040
44041		return target;
44042	}
44043
44044	switch (fill) {
44045	// compatibility
44046	case 'bottom':
44047		return 'start';
44048	case 'top':
44049		return 'end';
44050	case 'zero':
44051		return 'origin';
44052	// supported boundaries
44053	case 'origin':
44054	case 'start':
44055	case 'end':
44056		return fill;
44057	// invalid fill values
44058	default:
44059		return false;
44060	}
44061}
44062
44063function computeBoundary(source) {
44064	var model = source.el._model || {};
44065	var scale = source.el._scale || {};
44066	var fill = source.fill;
44067	var target = null;
44068	var horizontal;
44069
44070	if (isFinite(fill)) {
44071		return null;
44072	}
44073
44074	// Backward compatibility: until v3, we still need to support boundary values set on
44075	// the model (scaleTop, scaleBottom and scaleZero) because some external plugins and
44076	// controllers might still use it (e.g. the Smith chart).
44077
44078	if (fill === 'start') {
44079		target = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom;
44080	} else if (fill === 'end') {
44081		target = model.scaleTop === undefined ? scale.top : model.scaleTop;
44082	} else if (model.scaleZero !== undefined) {
44083		target = model.scaleZero;
44084	} else if (scale.getBasePosition) {
44085		target = scale.getBasePosition();
44086	} else if (scale.getBasePixel) {
44087		target = scale.getBasePixel();
44088	}
44089
44090	if (target !== undefined && target !== null) {
44091		if (target.x !== undefined && target.y !== undefined) {
44092			return target;
44093		}
44094
44095		if (typeof target === 'number' && isFinite(target)) {
44096			horizontal = scale.isHorizontal();
44097			return {
44098				x: horizontal ? target : null,
44099				y: horizontal ? null : target
44100			};
44101		}
44102	}
44103
44104	return null;
44105}
44106
44107function resolveTarget(sources, index, propagate) {
44108	var source = sources[index];
44109	var fill = source.fill;
44110	var visited = [index];
44111	var target;
44112
44113	if (!propagate) {
44114		return fill;
44115	}
44116
44117	while (fill !== false && visited.indexOf(fill) === -1) {
44118		if (!isFinite(fill)) {
44119			return fill;
44120		}
44121
44122		target = sources[fill];
44123		if (!target) {
44124			return false;
44125		}
44126
44127		if (target.visible) {
44128			return fill;
44129		}
44130
44131		visited.push(fill);
44132		fill = target.fill;
44133	}
44134
44135	return false;
44136}
44137
44138function createMapper(source) {
44139	var fill = source.fill;
44140	var type = 'dataset';
44141
44142	if (fill === false) {
44143		return null;
44144	}
44145
44146	if (!isFinite(fill)) {
44147		type = 'boundary';
44148	}
44149
44150	return mappers[type](source);
44151}
44152
44153function isDrawable(point) {
44154	return point && !point.skip;
44155}
44156
44157function drawArea(ctx, curve0, curve1, len0, len1) {
44158	var i;
44159
44160	if (!len0 || !len1) {
44161		return;
44162	}
44163
44164	// building first area curve (normal)
44165	ctx.moveTo(curve0[0].x, curve0[0].y);
44166	for (i = 1; i < len0; ++i) {
44167		helpers.canvas.lineTo(ctx, curve0[i - 1], curve0[i]);
44168	}
44169
44170	// joining the two area curves
44171	ctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y);
44172
44173	// building opposite area curve (reverse)
44174	for (i = len1 - 1; i > 0; --i) {
44175		helpers.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true);
44176	}
44177}
44178
44179function doFill(ctx, points, mapper, view, color, loop) {
44180	var count = points.length;
44181	var span = view.spanGaps;
44182	var curve0 = [];
44183	var curve1 = [];
44184	var len0 = 0;
44185	var len1 = 0;
44186	var i, ilen, index, p0, p1, d0, d1;
44187
44188	ctx.beginPath();
44189
44190	for (i = 0, ilen = (count + !!loop); i < ilen; ++i) {
44191		index = i % count;
44192		p0 = points[index]._view;
44193		p1 = mapper(p0, index, view);
44194		d0 = isDrawable(p0);
44195		d1 = isDrawable(p1);
44196
44197		if (d0 && d1) {
44198			len0 = curve0.push(p0);
44199			len1 = curve1.push(p1);
44200		} else if (len0 && len1) {
44201			if (!span) {
44202				drawArea(ctx, curve0, curve1, len0, len1);
44203				len0 = len1 = 0;
44204				curve0 = [];
44205				curve1 = [];
44206			} else {
44207				if (d0) {
44208					curve0.push(p0);
44209				}
44210				if (d1) {
44211					curve1.push(p1);
44212				}
44213			}
44214		}
44215	}
44216
44217	drawArea(ctx, curve0, curve1, len0, len1);
44218
44219	ctx.closePath();
44220	ctx.fillStyle = color;
44221	ctx.fill();
44222}
44223
44224module.exports = {
44225	id: 'filler',
44226
44227	afterDatasetsUpdate: function(chart, options) {
44228		var count = (chart.data.datasets || []).length;
44229		var propagate = options.propagate;
44230		var sources = [];
44231		var meta, i, el, source;
44232
44233		for (i = 0; i < count; ++i) {
44234			meta = chart.getDatasetMeta(i);
44235			el = meta.dataset;
44236			source = null;
44237
44238			if (el && el._model && el instanceof elements.Line) {
44239				source = {
44240					visible: chart.isDatasetVisible(i),
44241					fill: decodeFill(el, i, count),
44242					chart: chart,
44243					el: el
44244				};
44245			}
44246
44247			meta.$filler = source;
44248			sources.push(source);
44249		}
44250
44251		for (i = 0; i < count; ++i) {
44252			source = sources[i];
44253			if (!source) {
44254				continue;
44255			}
44256
44257			source.fill = resolveTarget(sources, i, propagate);
44258			source.boundary = computeBoundary(source);
44259			source.mapper = createMapper(source);
44260		}
44261	},
44262
44263	beforeDatasetDraw: function(chart, args) {
44264		var meta = args.meta.$filler;
44265		if (!meta) {
44266			return;
44267		}
44268
44269		var ctx = chart.ctx;
44270		var el = meta.el;
44271		var view = el._view;
44272		var points = el._children || [];
44273		var mapper = meta.mapper;
44274		var color = view.backgroundColor || defaults.global.defaultColor;
44275
44276		if (mapper && color && points.length) {
44277			helpers.canvas.clipArea(ctx, chart.chartArea);
44278			doFill(ctx, points, mapper, view, color, el._loop);
44279			helpers.canvas.unclipArea(ctx);
44280		}
44281	}
44282};
44283
44284},{"25":25,"40":40,"45":45}],51:[function(require,module,exports){
44285'use strict';
44286
44287var defaults = require(25);
44288var Element = require(26);
44289var helpers = require(45);
44290var layouts = require(30);
44291
44292var noop = helpers.noop;
44293
44294defaults._set('global', {
44295	legend: {
44296		display: true,
44297		position: 'top',
44298		fullWidth: true,
44299		reverse: false,
44300		weight: 1000,
44301
44302		// a callback that will handle
44303		onClick: function(e, legendItem) {
44304			var index = legendItem.datasetIndex;
44305			var ci = this.chart;
44306			var meta = ci.getDatasetMeta(index);
44307
44308			// See controller.isDatasetVisible comment
44309			meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
44310
44311			// We hid a dataset ... rerender the chart
44312			ci.update();
44313		},
44314
44315		onHover: null,
44316
44317		labels: {
44318			boxWidth: 40,
44319			padding: 10,
44320			// Generates labels shown in the legend
44321			// Valid properties to return:
44322			// text : text to display
44323			// fillStyle : fill of coloured box
44324			// strokeStyle: stroke of coloured box
44325			// hidden : if this legend item refers to a hidden item
44326			// lineCap : cap style for line
44327			// lineDash
44328			// lineDashOffset :
44329			// lineJoin :
44330			// lineWidth :
44331			generateLabels: function(chart) {
44332				var data = chart.data;
44333				return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
44334					return {
44335						text: dataset.label,
44336						fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]),
44337						hidden: !chart.isDatasetVisible(i),
44338						lineCap: dataset.borderCapStyle,
44339						lineDash: dataset.borderDash,
44340						lineDashOffset: dataset.borderDashOffset,
44341						lineJoin: dataset.borderJoinStyle,
44342						lineWidth: dataset.borderWidth,
44343						strokeStyle: dataset.borderColor,
44344						pointStyle: dataset.pointStyle,
44345
44346						// Below is extra data used for toggling the datasets
44347						datasetIndex: i
44348					};
44349				}, this) : [];
44350			}
44351		}
44352	},
44353
44354	legendCallback: function(chart) {
44355		var text = [];
44356		text.push('<ul class="' + chart.id + '-legend">');
44357		for (var i = 0; i < chart.data.datasets.length; i++) {
44358			text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>');
44359			if (chart.data.datasets[i].label) {
44360				text.push(chart.data.datasets[i].label);
44361			}
44362			text.push('</li>');
44363		}
44364		text.push('</ul>');
44365		return text.join('');
44366	}
44367});
44368
44369/**
44370 * Helper function to get the box width based on the usePointStyle option
44371 * @param labelopts {Object} the label options on the legend
44372 * @param fontSize {Number} the label font size
44373 * @return {Number} width of the color box area
44374 */
44375function getBoxWidth(labelOpts, fontSize) {
44376	return labelOpts.usePointStyle ?
44377		fontSize * Math.SQRT2 :
44378		labelOpts.boxWidth;
44379}
44380
44381/**
44382 * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!
44383 */
44384var Legend = Element.extend({
44385
44386	initialize: function(config) {
44387		helpers.extend(this, config);
44388
44389		// Contains hit boxes for each dataset (in dataset order)
44390		this.legendHitBoxes = [];
44391
44392		// Are we in doughnut mode which has a different data type
44393		this.doughnutMode = false;
44394	},
44395
44396	// These methods are ordered by lifecycle. Utilities then follow.
44397	// Any function defined here is inherited by all legend types.
44398	// Any function can be extended by the legend type
44399
44400	beforeUpdate: noop,
44401	update: function(maxWidth, maxHeight, margins) {
44402		var me = this;
44403
44404		// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
44405		me.beforeUpdate();
44406
44407		// Absorb the master measurements
44408		me.maxWidth = maxWidth;
44409		me.maxHeight = maxHeight;
44410		me.margins = margins;
44411
44412		// Dimensions
44413		me.beforeSetDimensions();
44414		me.setDimensions();
44415		me.afterSetDimensions();
44416		// Labels
44417		me.beforeBuildLabels();
44418		me.buildLabels();
44419		me.afterBuildLabels();
44420
44421		// Fit
44422		me.beforeFit();
44423		me.fit();
44424		me.afterFit();
44425		//
44426		me.afterUpdate();
44427
44428		return me.minSize;
44429	},
44430	afterUpdate: noop,
44431
44432	//
44433
44434	beforeSetDimensions: noop,
44435	setDimensions: function() {
44436		var me = this;
44437		// Set the unconstrained dimension before label rotation
44438		if (me.isHorizontal()) {
44439			// Reset position before calculating rotation
44440			me.width = me.maxWidth;
44441			me.left = 0;
44442			me.right = me.width;
44443		} else {
44444			me.height = me.maxHeight;
44445
44446			// Reset position before calculating rotation
44447			me.top = 0;
44448			me.bottom = me.height;
44449		}
44450
44451		// Reset padding
44452		me.paddingLeft = 0;
44453		me.paddingTop = 0;
44454		me.paddingRight = 0;
44455		me.paddingBottom = 0;
44456
44457		// Reset minSize
44458		me.minSize = {
44459			width: 0,
44460			height: 0
44461		};
44462	},
44463	afterSetDimensions: noop,
44464
44465	//
44466
44467	beforeBuildLabels: noop,
44468	buildLabels: function() {
44469		var me = this;
44470		var labelOpts = me.options.labels || {};
44471		var legendItems = helpers.callback(labelOpts.generateLabels, [me.chart], me) || [];
44472
44473		if (labelOpts.filter) {
44474			legendItems = legendItems.filter(function(item) {
44475				return labelOpts.filter(item, me.chart.data);
44476			});
44477		}
44478
44479		if (me.options.reverse) {
44480			legendItems.reverse();
44481		}
44482
44483		me.legendItems = legendItems;
44484	},
44485	afterBuildLabels: noop,
44486
44487	//
44488
44489	beforeFit: noop,
44490	fit: function() {
44491		var me = this;
44492		var opts = me.options;
44493		var labelOpts = opts.labels;
44494		var display = opts.display;
44495
44496		var ctx = me.ctx;
44497
44498		var globalDefault = defaults.global;
44499		var valueOrDefault = helpers.valueOrDefault;
44500		var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
44501		var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
44502		var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
44503		var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
44504
44505		// Reset hit boxes
44506		var hitboxes = me.legendHitBoxes = [];
44507
44508		var minSize = me.minSize;
44509		var isHorizontal = me.isHorizontal();
44510
44511		if (isHorizontal) {
44512			minSize.width = me.maxWidth; // fill all the width
44513			minSize.height = display ? 10 : 0;
44514		} else {
44515			minSize.width = display ? 10 : 0;
44516			minSize.height = me.maxHeight; // fill all the height
44517		}
44518
44519		// Increase sizes here
44520		if (display) {
44521			ctx.font = labelFont;
44522
44523			if (isHorizontal) {
44524				// Labels
44525
44526				// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
44527				var lineWidths = me.lineWidths = [0];
44528				var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0;
44529
44530				ctx.textAlign = 'left';
44531				ctx.textBaseline = 'top';
44532
44533				helpers.each(me.legendItems, function(legendItem, i) {
44534					var boxWidth = getBoxWidth(labelOpts, fontSize);
44535					var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
44536
44537					if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
44538						totalHeight += fontSize + (labelOpts.padding);
44539						lineWidths[lineWidths.length] = me.left;
44540					}
44541
44542					// Store the hitbox width and height here. Final position will be updated in `draw`
44543					hitboxes[i] = {
44544						left: 0,
44545						top: 0,
44546						width: width,
44547						height: fontSize
44548					};
44549
44550					lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
44551				});
44552
44553				minSize.height += totalHeight;
44554
44555			} else {
44556				var vPadding = labelOpts.padding;
44557				var columnWidths = me.columnWidths = [];
44558				var totalWidth = labelOpts.padding;
44559				var currentColWidth = 0;
44560				var currentColHeight = 0;
44561				var itemHeight = fontSize + vPadding;
44562
44563				helpers.each(me.legendItems, function(legendItem, i) {
44564					var boxWidth = getBoxWidth(labelOpts, fontSize);
44565					var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
44566
44567					// If too tall, go to new column
44568					if (currentColHeight + itemHeight > minSize.height) {
44569						totalWidth += currentColWidth + labelOpts.padding;
44570						columnWidths.push(currentColWidth); // previous column width
44571
44572						currentColWidth = 0;
44573						currentColHeight = 0;
44574					}
44575
44576					// Get max width
44577					currentColWidth = Math.max(currentColWidth, itemWidth);
44578					currentColHeight += itemHeight;
44579
44580					// Store the hitbox width and height here. Final position will be updated in `draw`
44581					hitboxes[i] = {
44582						left: 0,
44583						top: 0,
44584						width: itemWidth,
44585						height: fontSize
44586					};
44587				});
44588
44589				totalWidth += currentColWidth;
44590				columnWidths.push(currentColWidth);
44591				minSize.width += totalWidth;
44592			}
44593		}
44594
44595		me.width = minSize.width;
44596		me.height = minSize.height;
44597	},
44598	afterFit: noop,
44599
44600	// Shared Methods
44601	isHorizontal: function() {
44602		return this.options.position === 'top' || this.options.position === 'bottom';
44603	},
44604
44605	// Actually draw the legend on the canvas
44606	draw: function() {
44607		var me = this;
44608		var opts = me.options;
44609		var labelOpts = opts.labels;
44610		var globalDefault = defaults.global;
44611		var lineDefault = globalDefault.elements.line;
44612		var legendWidth = me.width;
44613		var lineWidths = me.lineWidths;
44614
44615		if (opts.display) {
44616			var ctx = me.ctx;
44617			var valueOrDefault = helpers.valueOrDefault;
44618			var fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor);
44619			var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize);
44620			var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle);
44621			var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily);
44622			var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
44623			var cursor;
44624
44625			// Canvas setup
44626			ctx.textAlign = 'left';
44627			ctx.textBaseline = 'middle';
44628			ctx.lineWidth = 0.5;
44629			ctx.strokeStyle = fontColor; // for strikethrough effect
44630			ctx.fillStyle = fontColor; // render in correct colour
44631			ctx.font = labelFont;
44632
44633			var boxWidth = getBoxWidth(labelOpts, fontSize);
44634			var hitboxes = me.legendHitBoxes;
44635
44636			// current position
44637			var drawLegendBox = function(x, y, legendItem) {
44638				if (isNaN(boxWidth) || boxWidth <= 0) {
44639					return;
44640				}
44641
44642				// Set the ctx for the box
44643				ctx.save();
44644
44645				ctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor);
44646				ctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle);
44647				ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset);
44648				ctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle);
44649				ctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth);
44650				ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor);
44651				var isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0);
44652
44653				if (ctx.setLineDash) {
44654					// IE 9 and 10 do not support line dash
44655					ctx.setLineDash(valueOrDefault(legendItem.lineDash, lineDefault.borderDash));
44656				}
44657
44658				if (opts.labels && opts.labels.usePointStyle) {
44659					// Recalculate x and y for drawPoint() because its expecting
44660					// x and y to be center of figure (instead of top left)
44661					var radius = fontSize * Math.SQRT2 / 2;
44662					var offSet = radius / Math.SQRT2;
44663					var centerX = x + offSet;
44664					var centerY = y + offSet;
44665
44666					// Draw pointStyle as legend symbol
44667					helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
44668				} else {
44669					// Draw box as legend symbol
44670					if (!isLineWidthZero) {
44671						ctx.strokeRect(x, y, boxWidth, fontSize);
44672					}
44673					ctx.fillRect(x, y, boxWidth, fontSize);
44674				}
44675
44676				ctx.restore();
44677			};
44678			var fillText = function(x, y, legendItem, textWidth) {
44679				var halfFontSize = fontSize / 2;
44680				var xLeft = boxWidth + halfFontSize + x;
44681				var yMiddle = y + halfFontSize;
44682
44683				ctx.fillText(legendItem.text, xLeft, yMiddle);
44684
44685				if (legendItem.hidden) {
44686					// Strikethrough the text if hidden
44687					ctx.beginPath();
44688					ctx.lineWidth = 2;
44689					ctx.moveTo(xLeft, yMiddle);
44690					ctx.lineTo(xLeft + textWidth, yMiddle);
44691					ctx.stroke();
44692				}
44693			};
44694
44695			// Horizontal
44696			var isHorizontal = me.isHorizontal();
44697			if (isHorizontal) {
44698				cursor = {
44699					x: me.left + ((legendWidth - lineWidths[0]) / 2),
44700					y: me.top + labelOpts.padding,
44701					line: 0
44702				};
44703			} else {
44704				cursor = {
44705					x: me.left + labelOpts.padding,
44706					y: me.top + labelOpts.padding,
44707					line: 0
44708				};
44709			}
44710
44711			var itemHeight = fontSize + labelOpts.padding;
44712			helpers.each(me.legendItems, function(legendItem, i) {
44713				var textWidth = ctx.measureText(legendItem.text).width;
44714				var width = boxWidth + (fontSize / 2) + textWidth;
44715				var x = cursor.x;
44716				var y = cursor.y;
44717
44718				if (isHorizontal) {
44719					if (x + width >= legendWidth) {
44720						y = cursor.y += itemHeight;
44721						cursor.line++;
44722						x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
44723					}
44724				} else if (y + itemHeight > me.bottom) {
44725					x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
44726					y = cursor.y = me.top + labelOpts.padding;
44727					cursor.line++;
44728				}
44729
44730				drawLegendBox(x, y, legendItem);
44731
44732				hitboxes[i].left = x;
44733				hitboxes[i].top = y;
44734
44735				// Fill the actual label
44736				fillText(x, y, legendItem, textWidth);
44737
44738				if (isHorizontal) {
44739					cursor.x += width + (labelOpts.padding);
44740				} else {
44741					cursor.y += itemHeight;
44742				}
44743
44744			});
44745		}
44746	},
44747
44748	/**
44749	 * Handle an event
44750	 * @private
44751	 * @param {IEvent} event - The event to handle
44752	 * @return {Boolean} true if a change occured
44753	 */
44754	handleEvent: function(e) {
44755		var me = this;
44756		var opts = me.options;
44757		var type = e.type === 'mouseup' ? 'click' : e.type;
44758		var changed = false;
44759
44760		if (type === 'mousemove') {
44761			if (!opts.onHover) {
44762				return;
44763			}
44764		} else if (type === 'click') {
44765			if (!opts.onClick) {
44766				return;
44767			}
44768		} else {
44769			return;
44770		}
44771
44772		// Chart event already has relative position in it
44773		var x = e.x;
44774		var y = e.y;
44775
44776		if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {
44777			// See if we are touching one of the dataset boxes
44778			var lh = me.legendHitBoxes;
44779			for (var i = 0; i < lh.length; ++i) {
44780				var hitBox = lh[i];
44781
44782				if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
44783					// Touching an element
44784					if (type === 'click') {
44785						// use e.native for backwards compatibility
44786						opts.onClick.call(me, e.native, me.legendItems[i]);
44787						changed = true;
44788						break;
44789					} else if (type === 'mousemove') {
44790						// use e.native for backwards compatibility
44791						opts.onHover.call(me, e.native, me.legendItems[i]);
44792						changed = true;
44793						break;
44794					}
44795				}
44796			}
44797		}
44798
44799		return changed;
44800	}
44801});
44802
44803function createNewLegendAndAttach(chart, legendOpts) {
44804	var legend = new Legend({
44805		ctx: chart.ctx,
44806		options: legendOpts,
44807		chart: chart
44808	});
44809
44810	layouts.configure(chart, legend, legendOpts);
44811	layouts.addBox(chart, legend);
44812	chart.legend = legend;
44813}
44814
44815module.exports = {
44816	id: 'legend',
44817
44818	/**
44819	 * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making
44820	 * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of
44821	 * the plugin, which one will be re-exposed in the chart.js file.
44822	 * https://github.com/chartjs/Chart.js/pull/2640
44823	 * @private
44824	 */
44825	_element: Legend,
44826
44827	beforeInit: function(chart) {
44828		var legendOpts = chart.options.legend;
44829
44830		if (legendOpts) {
44831			createNewLegendAndAttach(chart, legendOpts);
44832		}
44833	},
44834
44835	beforeUpdate: function(chart) {
44836		var legendOpts = chart.options.legend;
44837		var legend = chart.legend;
44838
44839		if (legendOpts) {
44840			helpers.mergeIf(legendOpts, defaults.global.legend);
44841
44842			if (legend) {
44843				layouts.configure(chart, legend, legendOpts);
44844				legend.options = legendOpts;
44845			} else {
44846				createNewLegendAndAttach(chart, legendOpts);
44847			}
44848		} else if (legend) {
44849			layouts.removeBox(chart, legend);
44850			delete chart.legend;
44851		}
44852	},
44853
44854	afterEvent: function(chart, e) {
44855		var legend = chart.legend;
44856		if (legend) {
44857			legend.handleEvent(e);
44858		}
44859	}
44860};
44861
44862},{"25":25,"26":26,"30":30,"45":45}],52:[function(require,module,exports){
44863'use strict';
44864
44865var defaults = require(25);
44866var Element = require(26);
44867var helpers = require(45);
44868var layouts = require(30);
44869
44870var noop = helpers.noop;
44871
44872defaults._set('global', {
44873	title: {
44874		display: false,
44875		fontStyle: 'bold',
44876		fullWidth: true,
44877		lineHeight: 1.2,
44878		padding: 10,
44879		position: 'top',
44880		text: '',
44881		weight: 2000         // by default greater than legend (1000) to be above
44882	}
44883});
44884
44885/**
44886 * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!
44887 */
44888var Title = Element.extend({
44889	initialize: function(config) {
44890		var me = this;
44891		helpers.extend(me, config);
44892
44893		// Contains hit boxes for each dataset (in dataset order)
44894		me.legendHitBoxes = [];
44895	},
44896
44897	// These methods are ordered by lifecycle. Utilities then follow.
44898
44899	beforeUpdate: noop,
44900	update: function(maxWidth, maxHeight, margins) {
44901		var me = this;
44902
44903		// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
44904		me.beforeUpdate();
44905
44906		// Absorb the master measurements
44907		me.maxWidth = maxWidth;
44908		me.maxHeight = maxHeight;
44909		me.margins = margins;
44910
44911		// Dimensions
44912		me.beforeSetDimensions();
44913		me.setDimensions();
44914		me.afterSetDimensions();
44915		// Labels
44916		me.beforeBuildLabels();
44917		me.buildLabels();
44918		me.afterBuildLabels();
44919
44920		// Fit
44921		me.beforeFit();
44922		me.fit();
44923		me.afterFit();
44924		//
44925		me.afterUpdate();
44926
44927		return me.minSize;
44928
44929	},
44930	afterUpdate: noop,
44931
44932	//
44933
44934	beforeSetDimensions: noop,
44935	setDimensions: function() {
44936		var me = this;
44937		// Set the unconstrained dimension before label rotation
44938		if (me.isHorizontal()) {
44939			// Reset position before calculating rotation
44940			me.width = me.maxWidth;
44941			me.left = 0;
44942			me.right = me.width;
44943		} else {
44944			me.height = me.maxHeight;
44945
44946			// Reset position before calculating rotation
44947			me.top = 0;
44948			me.bottom = me.height;
44949		}
44950
44951		// Reset padding
44952		me.paddingLeft = 0;
44953		me.paddingTop = 0;
44954		me.paddingRight = 0;
44955		me.paddingBottom = 0;
44956
44957		// Reset minSize
44958		me.minSize = {
44959			width: 0,
44960			height: 0
44961		};
44962	},
44963	afterSetDimensions: noop,
44964
44965	//
44966
44967	beforeBuildLabels: noop,
44968	buildLabels: noop,
44969	afterBuildLabels: noop,
44970
44971	//
44972
44973	beforeFit: noop,
44974	fit: function() {
44975		var me = this;
44976		var valueOrDefault = helpers.valueOrDefault;
44977		var opts = me.options;
44978		var display = opts.display;
44979		var fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize);
44980		var minSize = me.minSize;
44981		var lineCount = helpers.isArray(opts.text) ? opts.text.length : 1;
44982		var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
44983		var textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0;
44984
44985		if (me.isHorizontal()) {
44986			minSize.width = me.maxWidth; // fill all the width
44987			minSize.height = textSize;
44988		} else {
44989			minSize.width = textSize;
44990			minSize.height = me.maxHeight; // fill all the height
44991		}
44992
44993		me.width = minSize.width;
44994		me.height = minSize.height;
44995
44996	},
44997	afterFit: noop,
44998
44999	// Shared Methods
45000	isHorizontal: function() {
45001		var pos = this.options.position;
45002		return pos === 'top' || pos === 'bottom';
45003	},
45004
45005	// Actually draw the title block on the canvas
45006	draw: function() {
45007		var me = this;
45008		var ctx = me.ctx;
45009		var valueOrDefault = helpers.valueOrDefault;
45010		var opts = me.options;
45011		var globalDefaults = defaults.global;
45012
45013		if (opts.display) {
45014			var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize);
45015			var fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle);
45016			var fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily);
45017			var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);
45018			var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize);
45019			var offset = lineHeight / 2 + opts.padding;
45020			var rotation = 0;
45021			var top = me.top;
45022			var left = me.left;
45023			var bottom = me.bottom;
45024			var right = me.right;
45025			var maxWidth, titleX, titleY;
45026
45027			ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
45028			ctx.font = titleFont;
45029
45030			// Horizontal
45031			if (me.isHorizontal()) {
45032				titleX = left + ((right - left) / 2); // midpoint of the width
45033				titleY = top + offset;
45034				maxWidth = right - left;
45035			} else {
45036				titleX = opts.position === 'left' ? left + offset : right - offset;
45037				titleY = top + ((bottom - top) / 2);
45038				maxWidth = bottom - top;
45039				rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
45040			}
45041
45042			ctx.save();
45043			ctx.translate(titleX, titleY);
45044			ctx.rotate(rotation);
45045			ctx.textAlign = 'center';
45046			ctx.textBaseline = 'middle';
45047
45048			var text = opts.text;
45049			if (helpers.isArray(text)) {
45050				var y = 0;
45051				for (var i = 0; i < text.length; ++i) {
45052					ctx.fillText(text[i], 0, y, maxWidth);
45053					y += lineHeight;
45054				}
45055			} else {
45056				ctx.fillText(text, 0, 0, maxWidth);
45057			}
45058
45059			ctx.restore();
45060		}
45061	}
45062});
45063
45064function createNewTitleBlockAndAttach(chart, titleOpts) {
45065	var title = new Title({
45066		ctx: chart.ctx,
45067		options: titleOpts,
45068		chart: chart
45069	});
45070
45071	layouts.configure(chart, title, titleOpts);
45072	layouts.addBox(chart, title);
45073	chart.titleBlock = title;
45074}
45075
45076module.exports = {
45077	id: 'title',
45078
45079	/**
45080	 * Backward compatibility: since 2.1.5, the title is registered as a plugin, making
45081	 * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of
45082	 * the plugin, which one will be re-exposed in the chart.js file.
45083	 * https://github.com/chartjs/Chart.js/pull/2640
45084	 * @private
45085	 */
45086	_element: Title,
45087
45088	beforeInit: function(chart) {
45089		var titleOpts = chart.options.title;
45090
45091		if (titleOpts) {
45092			createNewTitleBlockAndAttach(chart, titleOpts);
45093		}
45094	},
45095
45096	beforeUpdate: function(chart) {
45097		var titleOpts = chart.options.title;
45098		var titleBlock = chart.titleBlock;
45099
45100		if (titleOpts) {
45101			helpers.mergeIf(titleOpts, defaults.global.title);
45102
45103			if (titleBlock) {
45104				layouts.configure(chart, titleBlock, titleOpts);
45105				titleBlock.options = titleOpts;
45106			} else {
45107				createNewTitleBlockAndAttach(chart, titleOpts);
45108			}
45109		} else if (titleBlock) {
45110			layouts.removeBox(chart, titleBlock);
45111			delete chart.titleBlock;
45112		}
45113	}
45114};
45115
45116},{"25":25,"26":26,"30":30,"45":45}],53:[function(require,module,exports){
45117'use strict';
45118
45119module.exports = function(Chart) {
45120
45121	// Default config for a category scale
45122	var defaultConfig = {
45123		position: 'bottom'
45124	};
45125
45126	var DatasetScale = Chart.Scale.extend({
45127		/**
45128		* Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those
45129		* else fall back to data.labels
45130		* @private
45131		*/
45132		getLabels: function() {
45133			var data = this.chart.data;
45134			return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
45135		},
45136
45137		determineDataLimits: function() {
45138			var me = this;
45139			var labels = me.getLabels();
45140			me.minIndex = 0;
45141			me.maxIndex = labels.length - 1;
45142			var findIndex;
45143
45144			if (me.options.ticks.min !== undefined) {
45145				// user specified min value
45146				findIndex = labels.indexOf(me.options.ticks.min);
45147				me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
45148			}
45149
45150			if (me.options.ticks.max !== undefined) {
45151				// user specified max value
45152				findIndex = labels.indexOf(me.options.ticks.max);
45153				me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
45154			}
45155
45156			me.min = labels[me.minIndex];
45157			me.max = labels[me.maxIndex];
45158		},
45159
45160		buildTicks: function() {
45161			var me = this;
45162			var labels = me.getLabels();
45163			// If we are viewing some subset of labels, slice the original array
45164			me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
45165		},
45166
45167		getLabelForIndex: function(index, datasetIndex) {
45168			var me = this;
45169			var data = me.chart.data;
45170			var isHorizontal = me.isHorizontal();
45171
45172			if (data.yLabels && !isHorizontal) {
45173				return me.getRightValue(data.datasets[datasetIndex].data[index]);
45174			}
45175			return me.ticks[index - me.minIndex];
45176		},
45177
45178		// Used to get data value locations.  Value can either be an index or a numerical value
45179		getPixelForValue: function(value, index) {
45180			var me = this;
45181			var offset = me.options.offset;
45182			// 1 is added because we need the length but we have the indexes
45183			var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1);
45184
45185			// If value is a data object, then index is the index in the data array,
45186			// not the index of the scale. We need to change that.
45187			var valueCategory;
45188			if (value !== undefined && value !== null) {
45189				valueCategory = me.isHorizontal() ? value.x : value.y;
45190			}
45191			if (valueCategory !== undefined || (value !== undefined && isNaN(index))) {
45192				var labels = me.getLabels();
45193				value = valueCategory || value;
45194				var idx = labels.indexOf(value);
45195				index = idx !== -1 ? idx : index;
45196			}
45197
45198			if (me.isHorizontal()) {
45199				var valueWidth = me.width / offsetAmt;
45200				var widthOffset = (valueWidth * (index - me.minIndex));
45201
45202				if (offset) {
45203					widthOffset += (valueWidth / 2);
45204				}
45205
45206				return me.left + Math.round(widthOffset);
45207			}
45208			var valueHeight = me.height / offsetAmt;
45209			var heightOffset = (valueHeight * (index - me.minIndex));
45210
45211			if (offset) {
45212				heightOffset += (valueHeight / 2);
45213			}
45214
45215			return me.top + Math.round(heightOffset);
45216		},
45217		getPixelForTick: function(index) {
45218			return this.getPixelForValue(this.ticks[index], index + this.minIndex, null);
45219		},
45220		getValueForPixel: function(pixel) {
45221			var me = this;
45222			var offset = me.options.offset;
45223			var value;
45224			var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1);
45225			var horz = me.isHorizontal();
45226			var valueDimension = (horz ? me.width : me.height) / offsetAmt;
45227
45228			pixel -= horz ? me.left : me.top;
45229
45230			if (offset) {
45231				pixel -= (valueDimension / 2);
45232			}
45233
45234			if (pixel <= 0) {
45235				value = 0;
45236			} else {
45237				value = Math.round(pixel / valueDimension);
45238			}
45239
45240			return value + me.minIndex;
45241		},
45242		getBasePixel: function() {
45243			return this.bottom;
45244		}
45245	});
45246
45247	Chart.scaleService.registerScaleType('category', DatasetScale, defaultConfig);
45248
45249};
45250
45251},{}],54:[function(require,module,exports){
45252'use strict';
45253
45254var defaults = require(25);
45255var helpers = require(45);
45256var Ticks = require(34);
45257
45258module.exports = function(Chart) {
45259
45260	var defaultConfig = {
45261		position: 'left',
45262		ticks: {
45263			callback: Ticks.formatters.linear
45264		}
45265	};
45266
45267	var LinearScale = Chart.LinearScaleBase.extend({
45268
45269		determineDataLimits: function() {
45270			var me = this;
45271			var opts = me.options;
45272			var chart = me.chart;
45273			var data = chart.data;
45274			var datasets = data.datasets;
45275			var isHorizontal = me.isHorizontal();
45276			var DEFAULT_MIN = 0;
45277			var DEFAULT_MAX = 1;
45278
45279			function IDMatches(meta) {
45280				return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
45281			}
45282
45283			// First Calculate the range
45284			me.min = null;
45285			me.max = null;
45286
45287			var hasStacks = opts.stacked;
45288			if (hasStacks === undefined) {
45289				helpers.each(datasets, function(dataset, datasetIndex) {
45290					if (hasStacks) {
45291						return;
45292					}
45293
45294					var meta = chart.getDatasetMeta(datasetIndex);
45295					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
45296						meta.stack !== undefined) {
45297						hasStacks = true;
45298					}
45299				});
45300			}
45301
45302			if (opts.stacked || hasStacks) {
45303				var valuesPerStack = {};
45304
45305				helpers.each(datasets, function(dataset, datasetIndex) {
45306					var meta = chart.getDatasetMeta(datasetIndex);
45307					var key = [
45308						meta.type,
45309						// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
45310						((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
45311						meta.stack
45312					].join('.');
45313
45314					if (valuesPerStack[key] === undefined) {
45315						valuesPerStack[key] = {
45316							positiveValues: [],
45317							negativeValues: []
45318						};
45319					}
45320
45321					// Store these per type
45322					var positiveValues = valuesPerStack[key].positiveValues;
45323					var negativeValues = valuesPerStack[key].negativeValues;
45324
45325					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
45326						helpers.each(dataset.data, function(rawValue, index) {
45327							var value = +me.getRightValue(rawValue);
45328							if (isNaN(value) || meta.data[index].hidden) {
45329								return;
45330							}
45331
45332							positiveValues[index] = positiveValues[index] || 0;
45333							negativeValues[index] = negativeValues[index] || 0;
45334
45335							if (opts.relativePoints) {
45336								positiveValues[index] = 100;
45337							} else if (value < 0) {
45338								negativeValues[index] += value;
45339							} else {
45340								positiveValues[index] += value;
45341							}
45342						});
45343					}
45344				});
45345
45346				helpers.each(valuesPerStack, function(valuesForType) {
45347					var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
45348					var minVal = helpers.min(values);
45349					var maxVal = helpers.max(values);
45350					me.min = me.min === null ? minVal : Math.min(me.min, minVal);
45351					me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
45352				});
45353
45354			} else {
45355				helpers.each(datasets, function(dataset, datasetIndex) {
45356					var meta = chart.getDatasetMeta(datasetIndex);
45357					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
45358						helpers.each(dataset.data, function(rawValue, index) {
45359							var value = +me.getRightValue(rawValue);
45360							if (isNaN(value) || meta.data[index].hidden) {
45361								return;
45362							}
45363
45364							if (me.min === null) {
45365								me.min = value;
45366							} else if (value < me.min) {
45367								me.min = value;
45368							}
45369
45370							if (me.max === null) {
45371								me.max = value;
45372							} else if (value > me.max) {
45373								me.max = value;
45374							}
45375						});
45376					}
45377				});
45378			}
45379
45380			me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
45381			me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
45382
45383			// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
45384			this.handleTickRangeOptions();
45385		},
45386		getTickLimit: function() {
45387			var maxTicks;
45388			var me = this;
45389			var tickOpts = me.options.ticks;
45390
45391			if (me.isHorizontal()) {
45392				maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50));
45393			} else {
45394				// The factor of 2 used to scale the font size has been experimentally determined.
45395				var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize);
45396				maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize)));
45397			}
45398
45399			return maxTicks;
45400		},
45401		// Called after the ticks are built. We need
45402		handleDirectionalChanges: function() {
45403			if (!this.isHorizontal()) {
45404				// We are in a vertical orientation. The top value is the highest. So reverse the array
45405				this.ticks.reverse();
45406			}
45407		},
45408		getLabelForIndex: function(index, datasetIndex) {
45409			return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
45410		},
45411		// Utils
45412		getPixelForValue: function(value) {
45413			// This must be called after fit has been run so that
45414			// this.left, this.top, this.right, and this.bottom have been defined
45415			var me = this;
45416			var start = me.start;
45417
45418			var rightValue = +me.getRightValue(value);
45419			var pixel;
45420			var range = me.end - start;
45421
45422			if (me.isHorizontal()) {
45423				pixel = me.left + (me.width / range * (rightValue - start));
45424			} else {
45425				pixel = me.bottom - (me.height / range * (rightValue - start));
45426			}
45427			return pixel;
45428		},
45429		getValueForPixel: function(pixel) {
45430			var me = this;
45431			var isHorizontal = me.isHorizontal();
45432			var innerDimension = isHorizontal ? me.width : me.height;
45433			var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension;
45434			return me.start + ((me.end - me.start) * offset);
45435		},
45436		getPixelForTick: function(index) {
45437			return this.getPixelForValue(this.ticksAsNumbers[index]);
45438		}
45439	});
45440	Chart.scaleService.registerScaleType('linear', LinearScale, defaultConfig);
45441
45442};
45443
45444},{"25":25,"34":34,"45":45}],55:[function(require,module,exports){
45445'use strict';
45446
45447var helpers = require(45);
45448
45449/**
45450 * Generate a set of linear ticks
45451 * @param generationOptions the options used to generate the ticks
45452 * @param dataRange the range of the data
45453 * @returns {Array<Number>} array of tick values
45454 */
45455function generateTicks(generationOptions, dataRange) {
45456	var ticks = [];
45457	// To get a "nice" value for the tick spacing, we will use the appropriately named
45458	// "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
45459	// for details.
45460
45461	var spacing;
45462	if (generationOptions.stepSize && generationOptions.stepSize > 0) {
45463		spacing = generationOptions.stepSize;
45464	} else {
45465		var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);
45466		spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);
45467	}
45468	var niceMin = Math.floor(dataRange.min / spacing) * spacing;
45469	var niceMax = Math.ceil(dataRange.max / spacing) * spacing;
45470
45471	// If min, max and stepSize is set and they make an evenly spaced scale use it.
45472	if (generationOptions.min && generationOptions.max && generationOptions.stepSize) {
45473		// If very close to our whole number, use it.
45474		if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) {
45475			niceMin = generationOptions.min;
45476			niceMax = generationOptions.max;
45477		}
45478	}
45479
45480	var numSpaces = (niceMax - niceMin) / spacing;
45481	// If very close to our rounded value, use it.
45482	if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
45483		numSpaces = Math.round(numSpaces);
45484	} else {
45485		numSpaces = Math.ceil(numSpaces);
45486	}
45487
45488	var precision = 1;
45489	if (spacing < 1) {
45490		precision = Math.pow(10, spacing.toString().length - 2);
45491		niceMin = Math.round(niceMin * precision) / precision;
45492		niceMax = Math.round(niceMax * precision) / precision;
45493	}
45494	ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
45495	for (var j = 1; j < numSpaces; ++j) {
45496		ticks.push(Math.round((niceMin + j * spacing) * precision) / precision);
45497	}
45498	ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);
45499
45500	return ticks;
45501}
45502
45503
45504module.exports = function(Chart) {
45505
45506	var noop = helpers.noop;
45507
45508	Chart.LinearScaleBase = Chart.Scale.extend({
45509		getRightValue: function(value) {
45510			if (typeof value === 'string') {
45511				return +value;
45512			}
45513			return Chart.Scale.prototype.getRightValue.call(this, value);
45514		},
45515
45516		handleTickRangeOptions: function() {
45517			var me = this;
45518			var opts = me.options;
45519			var tickOpts = opts.ticks;
45520
45521			// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
45522			// do nothing since that would make the chart weird. If the user really wants a weird chart
45523			// axis, they can manually override it
45524			if (tickOpts.beginAtZero) {
45525				var minSign = helpers.sign(me.min);
45526				var maxSign = helpers.sign(me.max);
45527
45528				if (minSign < 0 && maxSign < 0) {
45529					// move the top up to 0
45530					me.max = 0;
45531				} else if (minSign > 0 && maxSign > 0) {
45532					// move the bottom down to 0
45533					me.min = 0;
45534				}
45535			}
45536
45537			var setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined;
45538			var setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined;
45539
45540			if (tickOpts.min !== undefined) {
45541				me.min = tickOpts.min;
45542			} else if (tickOpts.suggestedMin !== undefined) {
45543				if (me.min === null) {
45544					me.min = tickOpts.suggestedMin;
45545				} else {
45546					me.min = Math.min(me.min, tickOpts.suggestedMin);
45547				}
45548			}
45549
45550			if (tickOpts.max !== undefined) {
45551				me.max = tickOpts.max;
45552			} else if (tickOpts.suggestedMax !== undefined) {
45553				if (me.max === null) {
45554					me.max = tickOpts.suggestedMax;
45555				} else {
45556					me.max = Math.max(me.max, tickOpts.suggestedMax);
45557				}
45558			}
45559
45560			if (setMin !== setMax) {
45561				// We set the min or the max but not both.
45562				// So ensure that our range is good
45563				// Inverted or 0 length range can happen when
45564				// ticks.min is set, and no datasets are visible
45565				if (me.min >= me.max) {
45566					if (setMin) {
45567						me.max = me.min + 1;
45568					} else {
45569						me.min = me.max - 1;
45570					}
45571				}
45572			}
45573
45574			if (me.min === me.max) {
45575				me.max++;
45576
45577				if (!tickOpts.beginAtZero) {
45578					me.min--;
45579				}
45580			}
45581		},
45582		getTickLimit: noop,
45583		handleDirectionalChanges: noop,
45584
45585		buildTicks: function() {
45586			var me = this;
45587			var opts = me.options;
45588			var tickOpts = opts.ticks;
45589
45590			// Figure out what the max number of ticks we can support it is based on the size of
45591			// the axis area. For now, we say that the minimum tick spacing in pixels must be 50
45592			// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
45593			// the graph. Make sure we always have at least 2 ticks
45594			var maxTicks = me.getTickLimit();
45595			maxTicks = Math.max(2, maxTicks);
45596
45597			var numericGeneratorOptions = {
45598				maxTicks: maxTicks,
45599				min: tickOpts.min,
45600				max: tickOpts.max,
45601				stepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)
45602			};
45603			var ticks = me.ticks = generateTicks(numericGeneratorOptions, me);
45604
45605			me.handleDirectionalChanges();
45606
45607			// At this point, we need to update our max and min given the tick values since we have expanded the
45608			// range of the scale
45609			me.max = helpers.max(ticks);
45610			me.min = helpers.min(ticks);
45611
45612			if (tickOpts.reverse) {
45613				ticks.reverse();
45614
45615				me.start = me.max;
45616				me.end = me.min;
45617			} else {
45618				me.start = me.min;
45619				me.end = me.max;
45620			}
45621		},
45622		convertTicksToLabels: function() {
45623			var me = this;
45624			me.ticksAsNumbers = me.ticks.slice();
45625			me.zeroLineIndex = me.ticks.indexOf(0);
45626
45627			Chart.Scale.prototype.convertTicksToLabels.call(me);
45628		}
45629	});
45630};
45631
45632},{"45":45}],56:[function(require,module,exports){
45633'use strict';
45634
45635var helpers = require(45);
45636var Ticks = require(34);
45637
45638/**
45639 * Generate a set of logarithmic ticks
45640 * @param generationOptions the options used to generate the ticks
45641 * @param dataRange the range of the data
45642 * @returns {Array<Number>} array of tick values
45643 */
45644function generateTicks(generationOptions, dataRange) {
45645	var ticks = [];
45646	var valueOrDefault = helpers.valueOrDefault;
45647
45648	// Figure out what the max number of ticks we can support it is based on the size of
45649	// the axis area. For now, we say that the minimum tick spacing in pixels must be 50
45650	// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
45651	// the graph
45652	var tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));
45653
45654	var endExp = Math.floor(helpers.log10(dataRange.max));
45655	var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));
45656	var exp, significand;
45657
45658	if (tickVal === 0) {
45659		exp = Math.floor(helpers.log10(dataRange.minNotZero));
45660		significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));
45661
45662		ticks.push(tickVal);
45663		tickVal = significand * Math.pow(10, exp);
45664	} else {
45665		exp = Math.floor(helpers.log10(tickVal));
45666		significand = Math.floor(tickVal / Math.pow(10, exp));
45667	}
45668	var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;
45669
45670	do {
45671		ticks.push(tickVal);
45672
45673		++significand;
45674		if (significand === 10) {
45675			significand = 1;
45676			++exp;
45677			precision = exp >= 0 ? 1 : precision;
45678		}
45679
45680		tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;
45681	} while (exp < endExp || (exp === endExp && significand < endSignificand));
45682
45683	var lastTick = valueOrDefault(generationOptions.max, tickVal);
45684	ticks.push(lastTick);
45685
45686	return ticks;
45687}
45688
45689
45690module.exports = function(Chart) {
45691
45692	var defaultConfig = {
45693		position: 'left',
45694
45695		// label settings
45696		ticks: {
45697			callback: Ticks.formatters.logarithmic
45698		}
45699	};
45700
45701	var LogarithmicScale = Chart.Scale.extend({
45702		determineDataLimits: function() {
45703			var me = this;
45704			var opts = me.options;
45705			var chart = me.chart;
45706			var data = chart.data;
45707			var datasets = data.datasets;
45708			var isHorizontal = me.isHorizontal();
45709			function IDMatches(meta) {
45710				return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
45711			}
45712
45713			// Calculate Range
45714			me.min = null;
45715			me.max = null;
45716			me.minNotZero = null;
45717
45718			var hasStacks = opts.stacked;
45719			if (hasStacks === undefined) {
45720				helpers.each(datasets, function(dataset, datasetIndex) {
45721					if (hasStacks) {
45722						return;
45723					}
45724
45725					var meta = chart.getDatasetMeta(datasetIndex);
45726					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
45727						meta.stack !== undefined) {
45728						hasStacks = true;
45729					}
45730				});
45731			}
45732
45733			if (opts.stacked || hasStacks) {
45734				var valuesPerStack = {};
45735
45736				helpers.each(datasets, function(dataset, datasetIndex) {
45737					var meta = chart.getDatasetMeta(datasetIndex);
45738					var key = [
45739						meta.type,
45740						// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
45741						((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
45742						meta.stack
45743					].join('.');
45744
45745					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
45746						if (valuesPerStack[key] === undefined) {
45747							valuesPerStack[key] = [];
45748						}
45749
45750						helpers.each(dataset.data, function(rawValue, index) {
45751							var values = valuesPerStack[key];
45752							var value = +me.getRightValue(rawValue);
45753							// invalid, hidden and negative values are ignored
45754							if (isNaN(value) || meta.data[index].hidden || value < 0) {
45755								return;
45756							}
45757							values[index] = values[index] || 0;
45758							values[index] += value;
45759						});
45760					}
45761				});
45762
45763				helpers.each(valuesPerStack, function(valuesForType) {
45764					if (valuesForType.length > 0) {
45765						var minVal = helpers.min(valuesForType);
45766						var maxVal = helpers.max(valuesForType);
45767						me.min = me.min === null ? minVal : Math.min(me.min, minVal);
45768						me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
45769					}
45770				});
45771
45772			} else {
45773				helpers.each(datasets, function(dataset, datasetIndex) {
45774					var meta = chart.getDatasetMeta(datasetIndex);
45775					if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
45776						helpers.each(dataset.data, function(rawValue, index) {
45777							var value = +me.getRightValue(rawValue);
45778							// invalid, hidden and negative values are ignored
45779							if (isNaN(value) || meta.data[index].hidden || value < 0) {
45780								return;
45781							}
45782
45783							if (me.min === null) {
45784								me.min = value;
45785							} else if (value < me.min) {
45786								me.min = value;
45787							}
45788
45789							if (me.max === null) {
45790								me.max = value;
45791							} else if (value > me.max) {
45792								me.max = value;
45793							}
45794
45795							if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) {
45796								me.minNotZero = value;
45797							}
45798						});
45799					}
45800				});
45801			}
45802
45803			// Common base implementation to handle ticks.min, ticks.max
45804			this.handleTickRangeOptions();
45805		},
45806		handleTickRangeOptions: function() {
45807			var me = this;
45808			var opts = me.options;
45809			var tickOpts = opts.ticks;
45810			var valueOrDefault = helpers.valueOrDefault;
45811			var DEFAULT_MIN = 1;
45812			var DEFAULT_MAX = 10;
45813
45814			me.min = valueOrDefault(tickOpts.min, me.min);
45815			me.max = valueOrDefault(tickOpts.max, me.max);
45816
45817			if (me.min === me.max) {
45818				if (me.min !== 0 && me.min !== null) {
45819					me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1);
45820					me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1);
45821				} else {
45822					me.min = DEFAULT_MIN;
45823					me.max = DEFAULT_MAX;
45824				}
45825			}
45826			if (me.min === null) {
45827				me.min = Math.pow(10, Math.floor(helpers.log10(me.max)) - 1);
45828			}
45829			if (me.max === null) {
45830				me.max = me.min !== 0
45831					? Math.pow(10, Math.floor(helpers.log10(me.min)) + 1)
45832					: DEFAULT_MAX;
45833			}
45834			if (me.minNotZero === null) {
45835				if (me.min > 0) {
45836					me.minNotZero = me.min;
45837				} else if (me.max < 1) {
45838					me.minNotZero = Math.pow(10, Math.floor(helpers.log10(me.max)));
45839				} else {
45840					me.minNotZero = DEFAULT_MIN;
45841				}
45842			}
45843		},
45844		buildTicks: function() {
45845			var me = this;
45846			var opts = me.options;
45847			var tickOpts = opts.ticks;
45848			var reverse = !me.isHorizontal();
45849
45850			var generationOptions = {
45851				min: tickOpts.min,
45852				max: tickOpts.max
45853			};
45854			var ticks = me.ticks = generateTicks(generationOptions, me);
45855
45856			// At this point, we need to update our max and min given the tick values since we have expanded the
45857			// range of the scale
45858			me.max = helpers.max(ticks);
45859			me.min = helpers.min(ticks);
45860
45861			if (tickOpts.reverse) {
45862				reverse = !reverse;
45863				me.start = me.max;
45864				me.end = me.min;
45865			} else {
45866				me.start = me.min;
45867				me.end = me.max;
45868			}
45869			if (reverse) {
45870				ticks.reverse();
45871			}
45872		},
45873		convertTicksToLabels: function() {
45874			this.tickValues = this.ticks.slice();
45875
45876			Chart.Scale.prototype.convertTicksToLabels.call(this);
45877		},
45878		// Get the correct tooltip label
45879		getLabelForIndex: function(index, datasetIndex) {
45880			return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
45881		},
45882		getPixelForTick: function(index) {
45883			return this.getPixelForValue(this.tickValues[index]);
45884		},
45885		/**
45886		 * Returns the value of the first tick.
45887		 * @param {Number} value - The minimum not zero value.
45888		 * @return {Number} The first tick value.
45889		 * @private
45890		 */
45891		_getFirstTickValue: function(value) {
45892			var exp = Math.floor(helpers.log10(value));
45893			var significand = Math.floor(value / Math.pow(10, exp));
45894
45895			return significand * Math.pow(10, exp);
45896		},
45897		getPixelForValue: function(value) {
45898			var me = this;
45899			var reverse = me.options.ticks.reverse;
45900			var log10 = helpers.log10;
45901			var firstTickValue = me._getFirstTickValue(me.minNotZero);
45902			var offset = 0;
45903			var innerDimension, pixel, start, end, sign;
45904
45905			value = +me.getRightValue(value);
45906			if (reverse) {
45907				start = me.end;
45908				end = me.start;
45909				sign = -1;
45910			} else {
45911				start = me.start;
45912				end = me.end;
45913				sign = 1;
45914			}
45915			if (me.isHorizontal()) {
45916				innerDimension = me.width;
45917				pixel = reverse ? me.right : me.left;
45918			} else {
45919				innerDimension = me.height;
45920				sign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0)
45921				pixel = reverse ? me.top : me.bottom;
45922			}
45923			if (value !== start) {
45924				if (start === 0) { // include zero tick
45925					offset = helpers.getValueOrDefault(
45926						me.options.ticks.fontSize,
45927						Chart.defaults.global.defaultFontSize
45928					);
45929					innerDimension -= offset;
45930					start = firstTickValue;
45931				}
45932				if (value !== 0) {
45933					offset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start));
45934				}
45935				pixel += sign * offset;
45936			}
45937			return pixel;
45938		},
45939		getValueForPixel: function(pixel) {
45940			var me = this;
45941			var reverse = me.options.ticks.reverse;
45942			var log10 = helpers.log10;
45943			var firstTickValue = me._getFirstTickValue(me.minNotZero);
45944			var innerDimension, start, end, value;
45945
45946			if (reverse) {
45947				start = me.end;
45948				end = me.start;
45949			} else {
45950				start = me.start;
45951				end = me.end;
45952			}
45953			if (me.isHorizontal()) {
45954				innerDimension = me.width;
45955				value = reverse ? me.right - pixel : pixel - me.left;
45956			} else {
45957				innerDimension = me.height;
45958				value = reverse ? pixel - me.top : me.bottom - pixel;
45959			}
45960			if (value !== start) {
45961				if (start === 0) { // include zero tick
45962					var offset = helpers.getValueOrDefault(
45963						me.options.ticks.fontSize,
45964						Chart.defaults.global.defaultFontSize
45965					);
45966					value -= offset;
45967					innerDimension -= offset;
45968					start = firstTickValue;
45969				}
45970				value *= log10(end) - log10(start);
45971				value /= innerDimension;
45972				value = Math.pow(10, log10(start) + value);
45973			}
45974			return value;
45975		}
45976	});
45977	Chart.scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig);
45978
45979};
45980
45981},{"34":34,"45":45}],57:[function(require,module,exports){
45982'use strict';
45983
45984var defaults = require(25);
45985var helpers = require(45);
45986var Ticks = require(34);
45987
45988module.exports = function(Chart) {
45989
45990	var globalDefaults = defaults.global;
45991
45992	var defaultConfig = {
45993		display: true,
45994
45995		// Boolean - Whether to animate scaling the chart from the centre
45996		animate: true,
45997		position: 'chartArea',
45998
45999		angleLines: {
46000			display: true,
46001			color: 'rgba(0, 0, 0, 0.1)',
46002			lineWidth: 1
46003		},
46004
46005		gridLines: {
46006			circular: false
46007		},
46008
46009		// label settings
46010		ticks: {
46011			// Boolean - Show a backdrop to the scale label
46012			showLabelBackdrop: true,
46013
46014			// String - The colour of the label backdrop
46015			backdropColor: 'rgba(255,255,255,0.75)',
46016
46017			// Number - The backdrop padding above & below the label in pixels
46018			backdropPaddingY: 2,
46019
46020			// Number - The backdrop padding to the side of the label in pixels
46021			backdropPaddingX: 2,
46022
46023			callback: Ticks.formatters.linear
46024		},
46025
46026		pointLabels: {
46027			// Boolean - if true, show point labels
46028			display: true,
46029
46030			// Number - Point label font size in pixels
46031			fontSize: 10,
46032
46033			// Function - Used to convert point labels
46034			callback: function(label) {
46035				return label;
46036			}
46037		}
46038	};
46039
46040	function getValueCount(scale) {
46041		var opts = scale.options;
46042		return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0;
46043	}
46044
46045	function getPointLabelFontOptions(scale) {
46046		var pointLabelOptions = scale.options.pointLabels;
46047		var fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize);
46048		var fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle);
46049		var fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily);
46050		var font = helpers.fontString(fontSize, fontStyle, fontFamily);
46051
46052		return {
46053			size: fontSize,
46054			style: fontStyle,
46055			family: fontFamily,
46056			font: font
46057		};
46058	}
46059
46060	function measureLabelSize(ctx, fontSize, label) {
46061		if (helpers.isArray(label)) {
46062			return {
46063				w: helpers.longestText(ctx, ctx.font, label),
46064				h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize)
46065			};
46066		}
46067
46068		return {
46069			w: ctx.measureText(label).width,
46070			h: fontSize
46071		};
46072	}
46073
46074	function determineLimits(angle, pos, size, min, max) {
46075		if (angle === min || angle === max) {
46076			return {
46077				start: pos - (size / 2),
46078				end: pos + (size / 2)
46079			};
46080		} else if (angle < min || angle > max) {
46081			return {
46082				start: pos - size - 5,
46083				end: pos
46084			};
46085		}
46086
46087		return {
46088			start: pos,
46089			end: pos + size + 5
46090		};
46091	}
46092
46093	/**
46094	 * Helper function to fit a radial linear scale with point labels
46095	 */
46096	function fitWithPointLabels(scale) {
46097		/*
46098		 * Right, this is really confusing and there is a lot of maths going on here
46099		 * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
46100		 *
46101		 * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
46102		 *
46103		 * Solution:
46104		 *
46105		 * We assume the radius of the polygon is half the size of the canvas at first
46106		 * at each index we check if the text overlaps.
46107		 *
46108		 * Where it does, we store that angle and that index.
46109		 *
46110		 * After finding the largest index and angle we calculate how much we need to remove
46111		 * from the shape radius to move the point inwards by that x.
46112		 *
46113		 * We average the left and right distances to get the maximum shape radius that can fit in the box
46114		 * along with labels.
46115		 *
46116		 * Once we have that, we can find the centre point for the chart, by taking the x text protrusion
46117		 * on each side, removing that from the size, halving it and adding the left x protrusion width.
46118		 *
46119		 * This will mean we have a shape fitted to the canvas, as large as it can be with the labels
46120		 * and position it in the most space efficient manner
46121		 *
46122		 * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
46123		 */
46124
46125		var plFont = getPointLabelFontOptions(scale);
46126
46127		// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
46128		// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
46129		var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
46130		var furthestLimits = {
46131			r: scale.width,
46132			l: 0,
46133			t: scale.height,
46134			b: 0
46135		};
46136		var furthestAngles = {};
46137		var i, textSize, pointPosition;
46138
46139		scale.ctx.font = plFont.font;
46140		scale._pointLabelSizes = [];
46141
46142		var valueCount = getValueCount(scale);
46143		for (i = 0; i < valueCount; i++) {
46144			pointPosition = scale.getPointPosition(i, largestPossibleRadius);
46145			textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || '');
46146			scale._pointLabelSizes[i] = textSize;
46147
46148			// Add quarter circle to make degree 0 mean top of circle
46149			var angleRadians = scale.getIndexAngle(i);
46150			var angle = helpers.toDegrees(angleRadians) % 360;
46151			var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
46152			var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
46153
46154			if (hLimits.start < furthestLimits.l) {
46155				furthestLimits.l = hLimits.start;
46156				furthestAngles.l = angleRadians;
46157			}
46158
46159			if (hLimits.end > furthestLimits.r) {
46160				furthestLimits.r = hLimits.end;
46161				furthestAngles.r = angleRadians;
46162			}
46163
46164			if (vLimits.start < furthestLimits.t) {
46165				furthestLimits.t = vLimits.start;
46166				furthestAngles.t = angleRadians;
46167			}
46168
46169			if (vLimits.end > furthestLimits.b) {
46170				furthestLimits.b = vLimits.end;
46171				furthestAngles.b = angleRadians;
46172			}
46173		}
46174
46175		scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles);
46176	}
46177
46178	/**
46179	 * Helper function to fit a radial linear scale with no point labels
46180	 */
46181	function fit(scale) {
46182		var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2);
46183		scale.drawingArea = Math.round(largestPossibleRadius);
46184		scale.setCenterPoint(0, 0, 0, 0);
46185	}
46186
46187	function getTextAlignForAngle(angle) {
46188		if (angle === 0 || angle === 180) {
46189			return 'center';
46190		} else if (angle < 180) {
46191			return 'left';
46192		}
46193
46194		return 'right';
46195	}
46196
46197	function fillText(ctx, text, position, fontSize) {
46198		if (helpers.isArray(text)) {
46199			var y = position.y;
46200			var spacing = 1.5 * fontSize;
46201
46202			for (var i = 0; i < text.length; ++i) {
46203				ctx.fillText(text[i], position.x, y);
46204				y += spacing;
46205			}
46206		} else {
46207			ctx.fillText(text, position.x, position.y);
46208		}
46209	}
46210
46211	function adjustPointPositionForLabelHeight(angle, textSize, position) {
46212		if (angle === 90 || angle === 270) {
46213			position.y -= (textSize.h / 2);
46214		} else if (angle > 270 || angle < 90) {
46215			position.y -= textSize.h;
46216		}
46217	}
46218
46219	function drawPointLabels(scale) {
46220		var ctx = scale.ctx;
46221		var opts = scale.options;
46222		var angleLineOpts = opts.angleLines;
46223		var pointLabelOpts = opts.pointLabels;
46224
46225		ctx.lineWidth = angleLineOpts.lineWidth;
46226		ctx.strokeStyle = angleLineOpts.color;
46227
46228		var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
46229
46230		// Point Label Font
46231		var plFont = getPointLabelFontOptions(scale);
46232
46233		ctx.textBaseline = 'top';
46234
46235		for (var i = getValueCount(scale) - 1; i >= 0; i--) {
46236			if (angleLineOpts.display) {
46237				var outerPosition = scale.getPointPosition(i, outerDistance);
46238				ctx.beginPath();
46239				ctx.moveTo(scale.xCenter, scale.yCenter);
46240				ctx.lineTo(outerPosition.x, outerPosition.y);
46241				ctx.stroke();
46242				ctx.closePath();
46243			}
46244
46245			if (pointLabelOpts.display) {
46246				// Extra 3px out for some label spacing
46247				var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
46248
46249				// Keep this in loop since we may support array properties here
46250				var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor);
46251				ctx.font = plFont.font;
46252				ctx.fillStyle = pointLabelFontColor;
46253
46254				var angleRadians = scale.getIndexAngle(i);
46255				var angle = helpers.toDegrees(angleRadians);
46256				ctx.textAlign = getTextAlignForAngle(angle);
46257				adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);
46258				fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size);
46259			}
46260		}
46261	}
46262
46263	function drawRadiusLine(scale, gridLineOpts, radius, index) {
46264		var ctx = scale.ctx;
46265		ctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1);
46266		ctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1);
46267
46268		if (scale.options.gridLines.circular) {
46269			// Draw circular arcs between the points
46270			ctx.beginPath();
46271			ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);
46272			ctx.closePath();
46273			ctx.stroke();
46274		} else {
46275			// Draw straight lines connecting each index
46276			var valueCount = getValueCount(scale);
46277
46278			if (valueCount === 0) {
46279				return;
46280			}
46281
46282			ctx.beginPath();
46283			var pointPosition = scale.getPointPosition(0, radius);
46284			ctx.moveTo(pointPosition.x, pointPosition.y);
46285
46286			for (var i = 1; i < valueCount; i++) {
46287				pointPosition = scale.getPointPosition(i, radius);
46288				ctx.lineTo(pointPosition.x, pointPosition.y);
46289			}
46290
46291			ctx.closePath();
46292			ctx.stroke();
46293		}
46294	}
46295
46296	function numberOrZero(param) {
46297		return helpers.isNumber(param) ? param : 0;
46298	}
46299
46300	var LinearRadialScale = Chart.LinearScaleBase.extend({
46301		setDimensions: function() {
46302			var me = this;
46303			var opts = me.options;
46304			var tickOpts = opts.ticks;
46305			// Set the unconstrained dimension before label rotation
46306			me.width = me.maxWidth;
46307			me.height = me.maxHeight;
46308			me.xCenter = Math.round(me.width / 2);
46309			me.yCenter = Math.round(me.height / 2);
46310
46311			var minSize = helpers.min([me.height, me.width]);
46312			var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
46313			me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2);
46314		},
46315		determineDataLimits: function() {
46316			var me = this;
46317			var chart = me.chart;
46318			var min = Number.POSITIVE_INFINITY;
46319			var max = Number.NEGATIVE_INFINITY;
46320
46321			helpers.each(chart.data.datasets, function(dataset, datasetIndex) {
46322				if (chart.isDatasetVisible(datasetIndex)) {
46323					var meta = chart.getDatasetMeta(datasetIndex);
46324
46325					helpers.each(dataset.data, function(rawValue, index) {
46326						var value = +me.getRightValue(rawValue);
46327						if (isNaN(value) || meta.data[index].hidden) {
46328							return;
46329						}
46330
46331						min = Math.min(value, min);
46332						max = Math.max(value, max);
46333					});
46334				}
46335			});
46336
46337			me.min = (min === Number.POSITIVE_INFINITY ? 0 : min);
46338			me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);
46339
46340			// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
46341			me.handleTickRangeOptions();
46342		},
46343		getTickLimit: function() {
46344			var tickOpts = this.options.ticks;
46345			var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
46346			return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize)));
46347		},
46348		convertTicksToLabels: function() {
46349			var me = this;
46350
46351			Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me);
46352
46353			// Point labels
46354			me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me);
46355		},
46356		getLabelForIndex: function(index, datasetIndex) {
46357			return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
46358		},
46359		fit: function() {
46360			if (this.options.pointLabels.display) {
46361				fitWithPointLabels(this);
46362			} else {
46363				fit(this);
46364			}
46365		},
46366		/**
46367		 * Set radius reductions and determine new radius and center point
46368		 * @private
46369		 */
46370		setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {
46371			var me = this;
46372			var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
46373			var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);
46374			var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
46375			var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b);
46376
46377			radiusReductionLeft = numberOrZero(radiusReductionLeft);
46378			radiusReductionRight = numberOrZero(radiusReductionRight);
46379			radiusReductionTop = numberOrZero(radiusReductionTop);
46380			radiusReductionBottom = numberOrZero(radiusReductionBottom);
46381
46382			me.drawingArea = Math.min(
46383				Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),
46384				Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));
46385			me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
46386		},
46387		setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {
46388			var me = this;
46389			var maxRight = me.width - rightMovement - me.drawingArea;
46390			var maxLeft = leftMovement + me.drawingArea;
46391			var maxTop = topMovement + me.drawingArea;
46392			var maxBottom = me.height - bottomMovement - me.drawingArea;
46393
46394			me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left);
46395			me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top);
46396		},
46397
46398		getIndexAngle: function(index) {
46399			var angleMultiplier = (Math.PI * 2) / getValueCount(this);
46400			var startAngle = this.chart.options && this.chart.options.startAngle ?
46401				this.chart.options.startAngle :
46402				0;
46403
46404			var startAngleRadians = startAngle * Math.PI * 2 / 360;
46405
46406			// Start from the top instead of right, so remove a quarter of the circle
46407			return index * angleMultiplier + startAngleRadians;
46408		},
46409		getDistanceFromCenterForValue: function(value) {
46410			var me = this;
46411
46412			if (value === null) {
46413				return 0; // null always in center
46414			}
46415
46416			// Take into account half font size + the yPadding of the top value
46417			var scalingFactor = me.drawingArea / (me.max - me.min);
46418			if (me.options.ticks.reverse) {
46419				return (me.max - value) * scalingFactor;
46420			}
46421			return (value - me.min) * scalingFactor;
46422		},
46423		getPointPosition: function(index, distanceFromCenter) {
46424			var me = this;
46425			var thisAngle = me.getIndexAngle(index) - (Math.PI / 2);
46426			return {
46427				x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter,
46428				y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter
46429			};
46430		},
46431		getPointPositionForValue: function(index, value) {
46432			return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
46433		},
46434
46435		getBasePosition: function() {
46436			var me = this;
46437			var min = me.min;
46438			var max = me.max;
46439
46440			return me.getPointPositionForValue(0,
46441				me.beginAtZero ? 0 :
46442				min < 0 && max < 0 ? max :
46443				min > 0 && max > 0 ? min :
46444				0);
46445		},
46446
46447		draw: function() {
46448			var me = this;
46449			var opts = me.options;
46450			var gridLineOpts = opts.gridLines;
46451			var tickOpts = opts.ticks;
46452			var valueOrDefault = helpers.valueOrDefault;
46453
46454			if (opts.display) {
46455				var ctx = me.ctx;
46456				var startAngle = this.getIndexAngle(0);
46457
46458				// Tick Font
46459				var tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize);
46460				var tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle);
46461				var tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily);
46462				var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
46463
46464				helpers.each(me.ticks, function(label, index) {
46465					// Don't draw a centre value (if it is minimum)
46466					if (index > 0 || tickOpts.reverse) {
46467						var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);
46468
46469						// Draw circular lines around the scale
46470						if (gridLineOpts.display && index !== 0) {
46471							drawRadiusLine(me, gridLineOpts, yCenterOffset, index);
46472						}
46473
46474						if (tickOpts.display) {
46475							var tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor);
46476							ctx.font = tickLabelFont;
46477
46478							ctx.save();
46479							ctx.translate(me.xCenter, me.yCenter);
46480							ctx.rotate(startAngle);
46481
46482							if (tickOpts.showLabelBackdrop) {
46483								var labelWidth = ctx.measureText(label).width;
46484								ctx.fillStyle = tickOpts.backdropColor;
46485								ctx.fillRect(
46486									-labelWidth / 2 - tickOpts.backdropPaddingX,
46487									-yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY,
46488									labelWidth + tickOpts.backdropPaddingX * 2,
46489									tickFontSize + tickOpts.backdropPaddingY * 2
46490								);
46491							}
46492
46493							ctx.textAlign = 'center';
46494							ctx.textBaseline = 'middle';
46495							ctx.fillStyle = tickFontColor;
46496							ctx.fillText(label, 0, -yCenterOffset);
46497							ctx.restore();
46498						}
46499					}
46500				});
46501
46502				if (opts.angleLines.display || opts.pointLabels.display) {
46503					drawPointLabels(me);
46504				}
46505			}
46506		}
46507	});
46508	Chart.scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig);
46509
46510};
46511
46512},{"25":25,"34":34,"45":45}],58:[function(require,module,exports){
46513/* global window: false */
46514'use strict';
46515
46516var moment = require(1);
46517moment = typeof moment === 'function' ? moment : window.moment;
46518
46519var defaults = require(25);
46520var helpers = require(45);
46521
46522// Integer constants are from the ES6 spec.
46523var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;
46524var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
46525
46526var INTERVALS = {
46527	millisecond: {
46528		common: true,
46529		size: 1,
46530		steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
46531	},
46532	second: {
46533		common: true,
46534		size: 1000,
46535		steps: [1, 2, 5, 10, 30]
46536	},
46537	minute: {
46538		common: true,
46539		size: 60000,
46540		steps: [1, 2, 5, 10, 30]
46541	},
46542	hour: {
46543		common: true,
46544		size: 3600000,
46545		steps: [1, 2, 3, 6, 12]
46546	},
46547	day: {
46548		common: true,
46549		size: 86400000,
46550		steps: [1, 2, 5]
46551	},
46552	week: {
46553		common: false,
46554		size: 604800000,
46555		steps: [1, 2, 3, 4]
46556	},
46557	month: {
46558		common: true,
46559		size: 2.628e9,
46560		steps: [1, 2, 3]
46561	},
46562	quarter: {
46563		common: false,
46564		size: 7.884e9,
46565		steps: [1, 2, 3, 4]
46566	},
46567	year: {
46568		common: true,
46569		size: 3.154e10
46570	}
46571};
46572
46573var UNITS = Object.keys(INTERVALS);
46574
46575function sorter(a, b) {
46576	return a - b;
46577}
46578
46579function arrayUnique(items) {
46580	var hash = {};
46581	var out = [];
46582	var i, ilen, item;
46583
46584	for (i = 0, ilen = items.length; i < ilen; ++i) {
46585		item = items[i];
46586		if (!hash[item]) {
46587			hash[item] = true;
46588			out.push(item);
46589		}
46590	}
46591
46592	return out;
46593}
46594
46595/**
46596 * Returns an array of {time, pos} objects used to interpolate a specific `time` or position
46597 * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is
46598 * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other
46599 * extremity (left + width or top + height). Note that it would be more optimized to directly
46600 * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need
46601 * to create the lookup table. The table ALWAYS contains at least two items: min and max.
46602 *
46603 * @param {Number[]} timestamps - timestamps sorted from lowest to highest.
46604 * @param {String} distribution - If 'linear', timestamps will be spread linearly along the min
46605 * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}.
46606 * If 'series', timestamps will be positioned at the same distance from each other. In this
46607 * case, only timestamps that break the time linearity are registered, meaning that in the
46608 * best case, all timestamps are linear, the table contains only min and max.
46609 */
46610function buildLookupTable(timestamps, min, max, distribution) {
46611	if (distribution === 'linear' || !timestamps.length) {
46612		return [
46613			{time: min, pos: 0},
46614			{time: max, pos: 1}
46615		];
46616	}
46617
46618	var table = [];
46619	var items = [min];
46620	var i, ilen, prev, curr, next;
46621
46622	for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
46623		curr = timestamps[i];
46624		if (curr > min && curr < max) {
46625			items.push(curr);
46626		}
46627	}
46628
46629	items.push(max);
46630
46631	for (i = 0, ilen = items.length; i < ilen; ++i) {
46632		next = items[i + 1];
46633		prev = items[i - 1];
46634		curr = items[i];
46635
46636		// only add points that breaks the scale linearity
46637		if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) {
46638			table.push({time: curr, pos: i / (ilen - 1)});
46639		}
46640	}
46641
46642	return table;
46643}
46644
46645// @see adapted from http://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/
46646function lookup(table, key, value) {
46647	var lo = 0;
46648	var hi = table.length - 1;
46649	var mid, i0, i1;
46650
46651	while (lo >= 0 && lo <= hi) {
46652		mid = (lo + hi) >> 1;
46653		i0 = table[mid - 1] || null;
46654		i1 = table[mid];
46655
46656		if (!i0) {
46657			// given value is outside table (before first item)
46658			return {lo: null, hi: i1};
46659		} else if (i1[key] < value) {
46660			lo = mid + 1;
46661		} else if (i0[key] > value) {
46662			hi = mid - 1;
46663		} else {
46664			return {lo: i0, hi: i1};
46665		}
46666	}
46667
46668	// given value is outside table (after last item)
46669	return {lo: i1, hi: null};
46670}
46671
46672/**
46673 * Linearly interpolates the given source `value` using the table items `skey` values and
46674 * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos')
46675 * returns the position for a timestamp equal to 42. If value is out of bounds, values at
46676 * index [0, 1] or [n - 1, n] are used for the interpolation.
46677 */
46678function interpolate(table, skey, sval, tkey) {
46679	var range = lookup(table, skey, sval);
46680
46681	// Note: the lookup table ALWAYS contains at least 2 items (min and max)
46682	var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo;
46683	var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi;
46684
46685	var span = next[skey] - prev[skey];
46686	var ratio = span ? (sval - prev[skey]) / span : 0;
46687	var offset = (next[tkey] - prev[tkey]) * ratio;
46688
46689	return prev[tkey] + offset;
46690}
46691
46692/**
46693 * Convert the given value to a moment object using the given time options.
46694 * @see http://momentjs.com/docs/#/parsing/
46695 */
46696function momentify(value, options) {
46697	var parser = options.parser;
46698	var format = options.parser || options.format;
46699
46700	if (typeof parser === 'function') {
46701		return parser(value);
46702	}
46703
46704	if (typeof value === 'string' && typeof format === 'string') {
46705		return moment(value, format);
46706	}
46707
46708	if (!(value instanceof moment)) {
46709		value = moment(value);
46710	}
46711
46712	if (value.isValid()) {
46713		return value;
46714	}
46715
46716	// Labels are in an incompatible moment format and no `parser` has been provided.
46717	// The user might still use the deprecated `format` option to convert his inputs.
46718	if (typeof format === 'function') {
46719		return format(value);
46720	}
46721
46722	return value;
46723}
46724
46725function parse(input, scale) {
46726	if (helpers.isNullOrUndef(input)) {
46727		return null;
46728	}
46729
46730	var options = scale.options.time;
46731	var value = momentify(scale.getRightValue(input), options);
46732	if (!value.isValid()) {
46733		return null;
46734	}
46735
46736	if (options.round) {
46737		value.startOf(options.round);
46738	}
46739
46740	return value.valueOf();
46741}
46742
46743/**
46744 * Returns the number of unit to skip to be able to display up to `capacity` number of ticks
46745 * in `unit` for the given `min` / `max` range and respecting the interval steps constraints.
46746 */
46747function determineStepSize(min, max, unit, capacity) {
46748	var range = max - min;
46749	var interval = INTERVALS[unit];
46750	var milliseconds = interval.size;
46751	var steps = interval.steps;
46752	var i, ilen, factor;
46753
46754	if (!steps) {
46755		return Math.ceil(range / (capacity * milliseconds));
46756	}
46757
46758	for (i = 0, ilen = steps.length; i < ilen; ++i) {
46759		factor = steps[i];
46760		if (Math.ceil(range / (milliseconds * factor)) <= capacity) {
46761			break;
46762		}
46763	}
46764
46765	return factor;
46766}
46767
46768/**
46769 * Figures out what unit results in an appropriate number of auto-generated ticks
46770 */
46771function determineUnitForAutoTicks(minUnit, min, max, capacity) {
46772	var ilen = UNITS.length;
46773	var i, interval, factor;
46774
46775	for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {
46776		interval = INTERVALS[UNITS[i]];
46777		factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER;
46778
46779		if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {
46780			return UNITS[i];
46781		}
46782	}
46783
46784	return UNITS[ilen - 1];
46785}
46786
46787/**
46788 * Figures out what unit to format a set of ticks with
46789 */
46790function determineUnitForFormatting(ticks, minUnit, min, max) {
46791	var duration = moment.duration(moment(max).diff(moment(min)));
46792	var ilen = UNITS.length;
46793	var i, unit;
46794
46795	for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) {
46796		unit = UNITS[i];
46797		if (INTERVALS[unit].common && duration.as(unit) >= ticks.length) {
46798			return unit;
46799		}
46800	}
46801
46802	return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];
46803}
46804
46805function determineMajorUnit(unit) {
46806	for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {
46807		if (INTERVALS[UNITS[i]].common) {
46808			return UNITS[i];
46809		}
46810	}
46811}
46812
46813/**
46814 * Generates a maximum of `capacity` timestamps between min and max, rounded to the
46815 * `minor` unit, aligned on the `major` unit and using the given scale time `options`.
46816 * Important: this method can return ticks outside the min and max range, it's the
46817 * responsibility of the calling code to clamp values if needed.
46818 */
46819function generate(min, max, capacity, options) {
46820	var timeOpts = options.time;
46821	var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity);
46822	var major = determineMajorUnit(minor);
46823	var stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize);
46824	var weekday = minor === 'week' ? timeOpts.isoWeekday : false;
46825	var majorTicksEnabled = options.ticks.major.enabled;
46826	var interval = INTERVALS[minor];
46827	var first = moment(min);
46828	var last = moment(max);
46829	var ticks = [];
46830	var time;
46831
46832	if (!stepSize) {
46833		stepSize = determineStepSize(min, max, minor, capacity);
46834	}
46835
46836	// For 'week' unit, handle the first day of week option
46837	if (weekday) {
46838		first = first.isoWeekday(weekday);
46839		last = last.isoWeekday(weekday);
46840	}
46841
46842	// Align first/last ticks on unit
46843	first = first.startOf(weekday ? 'day' : minor);
46844	last = last.startOf(weekday ? 'day' : minor);
46845
46846	// Make sure that the last tick include max
46847	if (last < max) {
46848		last.add(1, minor);
46849	}
46850
46851	time = moment(first);
46852
46853	if (majorTicksEnabled && major && !weekday && !timeOpts.round) {
46854		// Align the first tick on the previous `minor` unit aligned on the `major` unit:
46855		// we first aligned time on the previous `major` unit then add the number of full
46856		// stepSize there is between first and the previous major time.
46857		time.startOf(major);
46858		time.add(~~((first - time) / (interval.size * stepSize)) * stepSize, minor);
46859	}
46860
46861	for (; time < last; time.add(stepSize, minor)) {
46862		ticks.push(+time);
46863	}
46864
46865	ticks.push(+time);
46866
46867	return ticks;
46868}
46869
46870/**
46871 * Returns the right and left offsets from edges in the form of {left, right}.
46872 * Offsets are added when the `offset` option is true.
46873 */
46874function computeOffsets(table, ticks, min, max, options) {
46875	var left = 0;
46876	var right = 0;
46877	var upper, lower;
46878
46879	if (options.offset && ticks.length) {
46880		if (!options.time.min) {
46881			upper = ticks.length > 1 ? ticks[1] : max;
46882			lower = ticks[0];
46883			left = (
46884				interpolate(table, 'time', upper, 'pos') -
46885				interpolate(table, 'time', lower, 'pos')
46886			) / 2;
46887		}
46888		if (!options.time.max) {
46889			upper = ticks[ticks.length - 1];
46890			lower = ticks.length > 1 ? ticks[ticks.length - 2] : min;
46891			right = (
46892				interpolate(table, 'time', upper, 'pos') -
46893				interpolate(table, 'time', lower, 'pos')
46894			) / 2;
46895		}
46896	}
46897
46898	return {left: left, right: right};
46899}
46900
46901function ticksFromTimestamps(values, majorUnit) {
46902	var ticks = [];
46903	var i, ilen, value, major;
46904
46905	for (i = 0, ilen = values.length; i < ilen; ++i) {
46906		value = values[i];
46907		major = majorUnit ? value === +moment(value).startOf(majorUnit) : false;
46908
46909		ticks.push({
46910			value: value,
46911			major: major
46912		});
46913	}
46914
46915	return ticks;
46916}
46917
46918function determineLabelFormat(data, timeOpts) {
46919	var i, momentDate, hasTime;
46920	var ilen = data.length;
46921
46922	// find the label with the most parts (milliseconds, minutes, etc.)
46923	// format all labels with the same level of detail as the most specific label
46924	for (i = 0; i < ilen; i++) {
46925		momentDate = momentify(data[i], timeOpts);
46926		if (momentDate.millisecond() !== 0) {
46927			return 'MMM D, YYYY h:mm:ss.SSS a';
46928		}
46929		if (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) {
46930			hasTime = true;
46931		}
46932	}
46933	if (hasTime) {
46934		return 'MMM D, YYYY h:mm:ss a';
46935	}
46936	return 'MMM D, YYYY';
46937}
46938
46939module.exports = function(Chart) {
46940
46941	var defaultConfig = {
46942		position: 'bottom',
46943
46944		/**
46945		 * Data distribution along the scale:
46946		 * - 'linear': data are spread according to their time (distances can vary),
46947		 * - 'series': data are spread at the same distance from each other.
46948		 * @see https://github.com/chartjs/Chart.js/pull/4507
46949		 * @since 2.7.0
46950		 */
46951		distribution: 'linear',
46952
46953		/**
46954		 * Scale boundary strategy (bypassed by min/max time options)
46955		 * - `data`: make sure data are fully visible, ticks outside are removed
46956		 * - `ticks`: make sure ticks are fully visible, data outside are truncated
46957		 * @see https://github.com/chartjs/Chart.js/pull/4556
46958		 * @since 2.7.0
46959		 */
46960		bounds: 'data',
46961
46962		time: {
46963			parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment
46964			format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/
46965			unit: false, // false == automatic or override with week, month, year, etc.
46966			round: false, // none, or override with week, month, year, etc.
46967			displayFormat: false, // DEPRECATED
46968			isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/
46969			minUnit: 'millisecond',
46970
46971			// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
46972			displayFormats: {
46973				millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM,
46974				second: 'h:mm:ss a', // 11:20:01 AM
46975				minute: 'h:mm a', // 11:20 AM
46976				hour: 'hA', // 5PM
46977				day: 'MMM D', // Sep 4
46978				week: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
46979				month: 'MMM YYYY', // Sept 2015
46980				quarter: '[Q]Q - YYYY', // Q3
46981				year: 'YYYY' // 2015
46982			},
46983		},
46984		ticks: {
46985			autoSkip: false,
46986
46987			/**
46988			 * Ticks generation input values:
46989			 * - 'auto': generates "optimal" ticks based on scale size and time options.
46990			 * - 'data': generates ticks from data (including labels from data {t|x|y} objects).
46991			 * - 'labels': generates ticks from user given `data.labels` values ONLY.
46992			 * @see https://github.com/chartjs/Chart.js/pull/4507
46993			 * @since 2.7.0
46994			 */
46995			source: 'auto',
46996
46997			major: {
46998				enabled: false
46999			}
47000		}
47001	};
47002
47003	var TimeScale = Chart.Scale.extend({
47004		initialize: function() {
47005			if (!moment) {
47006				throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com');
47007			}
47008
47009			this.mergeTicksOptions();
47010
47011			Chart.Scale.prototype.initialize.call(this);
47012		},
47013
47014		update: function() {
47015			var me = this;
47016			var options = me.options;
47017
47018			// DEPRECATIONS: output a message only one time per update
47019			if (options.time && options.time.format) {
47020				console.warn('options.time.format is deprecated and replaced by options.time.parser.');
47021			}
47022
47023			return Chart.Scale.prototype.update.apply(me, arguments);
47024		},
47025
47026		/**
47027		 * Allows data to be referenced via 't' attribute
47028		 */
47029		getRightValue: function(rawValue) {
47030			if (rawValue && rawValue.t !== undefined) {
47031				rawValue = rawValue.t;
47032			}
47033			return Chart.Scale.prototype.getRightValue.call(this, rawValue);
47034		},
47035
47036		determineDataLimits: function() {
47037			var me = this;
47038			var chart = me.chart;
47039			var timeOpts = me.options.time;
47040			var unit = timeOpts.unit || 'day';
47041			var min = MAX_INTEGER;
47042			var max = MIN_INTEGER;
47043			var timestamps = [];
47044			var datasets = [];
47045			var labels = [];
47046			var i, j, ilen, jlen, data, timestamp;
47047
47048			// Convert labels to timestamps
47049			for (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) {
47050				labels.push(parse(chart.data.labels[i], me));
47051			}
47052
47053			// Convert data to timestamps
47054			for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
47055				if (chart.isDatasetVisible(i)) {
47056					data = chart.data.datasets[i].data;
47057
47058					// Let's consider that all data have the same format.
47059					if (helpers.isObject(data[0])) {
47060						datasets[i] = [];
47061
47062						for (j = 0, jlen = data.length; j < jlen; ++j) {
47063							timestamp = parse(data[j], me);
47064							timestamps.push(timestamp);
47065							datasets[i][j] = timestamp;
47066						}
47067					} else {
47068						timestamps.push.apply(timestamps, labels);
47069						datasets[i] = labels.slice(0);
47070					}
47071				} else {
47072					datasets[i] = [];
47073				}
47074			}
47075
47076			if (labels.length) {
47077				// Sort labels **after** data have been converted
47078				labels = arrayUnique(labels).sort(sorter);
47079				min = Math.min(min, labels[0]);
47080				max = Math.max(max, labels[labels.length - 1]);
47081			}
47082
47083			if (timestamps.length) {
47084				timestamps = arrayUnique(timestamps).sort(sorter);
47085				min = Math.min(min, timestamps[0]);
47086				max = Math.max(max, timestamps[timestamps.length - 1]);
47087			}
47088
47089			min = parse(timeOpts.min, me) || min;
47090			max = parse(timeOpts.max, me) || max;
47091
47092			// In case there is no valid min/max, set limits based on unit time option
47093			min = min === MAX_INTEGER ? +moment().startOf(unit) : min;
47094			max = max === MIN_INTEGER ? +moment().endOf(unit) + 1 : max;
47095
47096			// Make sure that max is strictly higher than min (required by the lookup table)
47097			me.min = Math.min(min, max);
47098			me.max = Math.max(min + 1, max);
47099
47100			// PRIVATE
47101			me._horizontal = me.isHorizontal();
47102			me._table = [];
47103			me._timestamps = {
47104				data: timestamps,
47105				datasets: datasets,
47106				labels: labels
47107			};
47108		},
47109
47110		buildTicks: function() {
47111			var me = this;
47112			var min = me.min;
47113			var max = me.max;
47114			var options = me.options;
47115			var timeOpts = options.time;
47116			var timestamps = [];
47117			var ticks = [];
47118			var i, ilen, timestamp;
47119
47120			switch (options.ticks.source) {
47121			case 'data':
47122				timestamps = me._timestamps.data;
47123				break;
47124			case 'labels':
47125				timestamps = me._timestamps.labels;
47126				break;
47127			case 'auto':
47128			default:
47129				timestamps = generate(min, max, me.getLabelCapacity(min), options);
47130			}
47131
47132			if (options.bounds === 'ticks' && timestamps.length) {
47133				min = timestamps[0];
47134				max = timestamps[timestamps.length - 1];
47135			}
47136
47137			// Enforce limits with user min/max options
47138			min = parse(timeOpts.min, me) || min;
47139			max = parse(timeOpts.max, me) || max;
47140
47141			// Remove ticks outside the min/max range
47142			for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
47143				timestamp = timestamps[i];
47144				if (timestamp >= min && timestamp <= max) {
47145					ticks.push(timestamp);
47146				}
47147			}
47148
47149			me.min = min;
47150			me.max = max;
47151
47152			// PRIVATE
47153			me._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max);
47154			me._majorUnit = determineMajorUnit(me._unit);
47155			me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution);
47156			me._offsets = computeOffsets(me._table, ticks, min, max, options);
47157			me._labelFormat = determineLabelFormat(me._timestamps.data, timeOpts);
47158
47159			return ticksFromTimestamps(ticks, me._majorUnit);
47160		},
47161
47162		getLabelForIndex: function(index, datasetIndex) {
47163			var me = this;
47164			var data = me.chart.data;
47165			var timeOpts = me.options.time;
47166			var label = data.labels && index < data.labels.length ? data.labels[index] : '';
47167			var value = data.datasets[datasetIndex].data[index];
47168
47169			if (helpers.isObject(value)) {
47170				label = me.getRightValue(value);
47171			}
47172			if (timeOpts.tooltipFormat) {
47173				return momentify(label, timeOpts).format(timeOpts.tooltipFormat);
47174			}
47175			if (typeof label === 'string') {
47176				return label;
47177			}
47178
47179			return momentify(label, timeOpts).format(me._labelFormat);
47180		},
47181
47182		/**
47183		 * Function to format an individual tick mark
47184		 * @private
47185		 */
47186		tickFormatFunction: function(tick, index, ticks, formatOverride) {
47187			var me = this;
47188			var options = me.options;
47189			var time = tick.valueOf();
47190			var formats = options.time.displayFormats;
47191			var minorFormat = formats[me._unit];
47192			var majorUnit = me._majorUnit;
47193			var majorFormat = formats[majorUnit];
47194			var majorTime = tick.clone().startOf(majorUnit).valueOf();
47195			var majorTickOpts = options.ticks.major;
47196			var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime;
47197			var label = tick.format(formatOverride ? formatOverride : major ? majorFormat : minorFormat);
47198			var tickOpts = major ? majorTickOpts : options.ticks.minor;
47199			var formatter = helpers.valueOrDefault(tickOpts.callback, tickOpts.userCallback);
47200
47201			return formatter ? formatter(label, index, ticks) : label;
47202		},
47203
47204		convertTicksToLabels: function(ticks) {
47205			var labels = [];
47206			var i, ilen;
47207
47208			for (i = 0, ilen = ticks.length; i < ilen; ++i) {
47209				labels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks));
47210			}
47211
47212			return labels;
47213		},
47214
47215		/**
47216		 * @private
47217		 */
47218		getPixelForOffset: function(time) {
47219			var me = this;
47220			var size = me._horizontal ? me.width : me.height;
47221			var start = me._horizontal ? me.left : me.top;
47222			var pos = interpolate(me._table, 'time', time, 'pos');
47223
47224			return start + size * (me._offsets.left + pos) / (me._offsets.left + 1 + me._offsets.right);
47225		},
47226
47227		getPixelForValue: function(value, index, datasetIndex) {
47228			var me = this;
47229			var time = null;
47230
47231			if (index !== undefined && datasetIndex !== undefined) {
47232				time = me._timestamps.datasets[datasetIndex][index];
47233			}
47234
47235			if (time === null) {
47236				time = parse(value, me);
47237			}
47238
47239			if (time !== null) {
47240				return me.getPixelForOffset(time);
47241			}
47242		},
47243
47244		getPixelForTick: function(index) {
47245			var ticks = this.getTicks();
47246			return index >= 0 && index < ticks.length ?
47247				this.getPixelForOffset(ticks[index].value) :
47248				null;
47249		},
47250
47251		getValueForPixel: function(pixel) {
47252			var me = this;
47253			var size = me._horizontal ? me.width : me.height;
47254			var start = me._horizontal ? me.left : me.top;
47255			var pos = (size ? (pixel - start) / size : 0) * (me._offsets.left + 1 + me._offsets.left) - me._offsets.right;
47256			var time = interpolate(me._table, 'pos', pos, 'time');
47257
47258			return moment(time);
47259		},
47260
47261		/**
47262		 * Crude approximation of what the label width might be
47263		 * @private
47264		 */
47265		getLabelWidth: function(label) {
47266			var me = this;
47267			var ticksOpts = me.options.ticks;
47268			var tickLabelWidth = me.ctx.measureText(label).width;
47269			var angle = helpers.toRadians(ticksOpts.maxRotation);
47270			var cosRotation = Math.cos(angle);
47271			var sinRotation = Math.sin(angle);
vendor: 10,627 bytes, lines 47272-47537
47272			var tickFontSize = helpers.valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize);
47273
47274			return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation);
47275		},
47276
47277		/**
47278		 * @private
47279		 */
47280		getLabelCapacity: function(exampleTime) {
47281			var me = this;
47282
47283			var formatOverride = me.options.time.displayFormats.millisecond;	// Pick the longest format for guestimation
47284
47285			var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, [], formatOverride);
47286			var tickLabelWidth = me.getLabelWidth(exampleLabel);
47287			var innerWidth = me.isHorizontal() ? me.width : me.height;
47288
47289			var capacity = Math.floor(innerWidth / tickLabelWidth);
47290			return capacity > 0 ? capacity : 1;
47291		}
47292	});
47293
47294	Chart.scaleService.registerScaleType('time', TimeScale, defaultConfig);
47295};
47296
47297},{"1":1,"25":25,"45":45}]},{},[7])(7)
47298});
47299/*
47300 * printThis v1.5
47301 * @desc Printing plug-in for jQuery
47302 * @author Jason Day
47303 *
47304 * Resources (based on) :
47305 *              jPrintArea: http://plugins.jquery.com/project/jPrintArea
47306 *              jqPrint: https://github.com/permanenttourist/jquery.jqprint
47307 *              Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
47308 *
47309 * Licensed under the MIT licence:
47310 *              http://www.opensource.org/licenses/mit-license.php
47311 *
47312 * (c) Jason Day 2015
47313 *
47314 * Usage:
47315 *
47316 *  $("#mySelector").printThis({
47317 *      debug: false,               * show the iframe for debugging
47318 *      importCSS: true,            * import page CSS
47319 *      importStyle: false,         * import style tags
47320 *      printContainer: true,       * grab outer container as well as the contents of the selector
47321 *      loadCSS: "path/to/my.css",  * path to additional css file - us an array [] for multiple
47322 *      pageTitle: "",              * add title to print page
47323 *      removeInline: false,        * remove all inline styles from print elements
47324 *      printDelay: 333,            * variable print delay
47325 *      header: null,               * prefix to html
47326 *      formValues: true            * preserve input/form values
47327 *  });
47328 *
47329 * Notes:
47330 *  - the loadCSS will load additional css (with or without @media print) into the iframe, adjusting layout
47331 */
47332
47333;
47334(function($) {
47335    var opt;
47336    $.fn.printThis = function(options) {
47337        opt = $.extend({}, $.fn.printThis.defaults, options);
47338        var $element = this instanceof jQuery ? this : $(this);
47339
47340        var strFrameName = "printThis-" + (new Date()).getTime();
47341
47342        if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {
47343            // Ugly IE hacks due to IE not inheriting document.domain from parent
47344            // checks if document.domain is set by comparing the host name against document.domain
47345            var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</script></head><body></body>\")";
47346            var printI = document.createElement('iframe');
47347            printI.name = "printIframe";
47348            printI.id = strFrameName;
47349            printI.className = "MSIE";
47350            document.body.appendChild(printI);
47351            printI.src = iframeSrc;
47352
47353        } else {
47354            // other browsers inherit document.domain, and IE works if document.domain is not explicitly set
47355            var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />");
47356            $frame.appendTo("body");
47357        }
47358
47359
47360        var $iframe = $("#" + strFrameName);
47361
47362        // show frame if in debug mode
47363        if (!opt.debug) $iframe.css({
47364            position: "absolute",
47365            width: "0px",
47366            height: "0px",
47367            left: "-600px",
47368            top: "-600px"
47369        });
47370
47371
47372        // $iframe.ready() and $iframe.load were inconsistent between browsers    
47373        setTimeout(function() {
47374
47375            // Add doctype to fix the style difference between printing and render
47376            function setDocType($iframe,doctype){
47377                var win, doc;
47378                win = $iframe.get(0);
47379                win = win.contentWindow || win.contentDocument || win;
47380                doc = win.document || win.contentDocument || win;
47381                doc.open();
47382                doc.write(doctype);
47383                doc.close();
47384            }
47385            if(opt.doctypeString){
47386                setDocType($iframe,opt.doctypeString);
47387            }
47388
47389            var $doc = $iframe.contents(),
47390                $head = $doc.find("head"),
47391                $body = $doc.find("body");
47392
47393            // add base tag to ensure elements use the parent domain
47394            $head.append('<base href="' + document.location.protocol + '//' + document.location.host + '">');
47395
47396            // import page stylesheets
47397            if (opt.importCSS) $("link[rel=stylesheet]").each(function() {
47398                var href = $(this).attr("href");
47399                if (href) {
47400                    var media = $(this).attr("media") || "all";
47401                    $head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>")
47402                }
47403            });
47404            
47405            // import style tags
47406            if (opt.importStyle) $("style").each(function() {
47407                $(this).clone().appendTo($head);
47408                //$head.append($(this));
47409            });
47410
47411            //add title of the page
47412            if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>");
47413
47414            // import additional stylesheet(s)
47415            if (opt.loadCSS) {
47416               if( $.isArray(opt.loadCSS)) {
47417                    jQuery.each(opt.loadCSS, function(index, value) {
47418                       $head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>");
47419                    });
47420                } else {
47421                    $head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
47422                }
47423            }
47424
47425            // print header
47426            if (opt.header) $body.append(opt.header);
47427
47428            // grab $.selector as container
47429            if (opt.printContainer) $body.append($element.outer());
47430
47431            // otherwise just print interior elements of container
47432            else $element.each(function() {
47433                $body.append($(this).html());
47434            });
47435
47436            // capture form/field values
47437            if (opt.formValues) {
47438                // loop through inputs
47439                var $input = $element.find('input');
47440                if ($input.length) {
47441                    $input.each(function() {
47442                        var $this = $(this),
47443                            $name = $(this).attr('name'),
47444                            $checker = $this.is(':checkbox') || $this.is(':radio'),
47445                            $iframeInput = $doc.find('input[name="' + $name + '"]'),
47446                            $value = $this.val();
47447
47448                        //order matters here
47449                        if (!$checker) {
47450                            $iframeInput.val($value);
47451                        } else if ($this.is(':checked')) {
47452                            if ($this.is(':checkbox')) {
47453                                $iframeInput.attr('checked', 'checked');
47454                            } else if ($this.is(':radio')) {
47455                                $doc.find('input[name="' + $name + '"][value=' + $value + ']').attr('checked', 'checked');
47456                            }
47457                        }
47458
47459                    });
47460                }
47461
47462                //loop through selects
47463                var $select = $element.find('select');
47464                if ($select.length) {
47465                    $select.each(function() {
47466                        var $this = $(this),
47467                            $name = $(this).attr('name'),
47468                            $value = $this.val();
47469                        $doc.find('select[name="' + $name + '"]').val($value);
47470                    });
47471                }
47472
47473                //loop through textareas
47474                var $textarea = $element.find('textarea');
47475                if ($textarea.length) {
47476                    $textarea.each(function() {
47477                        var $this = $(this),
47478                            $name = $(this).attr('name'),
47479                            $value = $this.val();
47480                        $doc.find('textarea[name="' + $name + '"]').val($value);
47481                    });
47482                }
47483            } // end capture form/field values
47484
47485            // remove inline styles
47486            if (opt.removeInline) {
47487                // $.removeAttr available jQuery 1.7+
47488                if ($.isFunction($.removeAttr)) {
47489                    $doc.find("body *").removeAttr("style");
47490                } else {
47491                    $doc.find("body *").attr("style", "");
47492                }
47493            }
47494
47495            setTimeout(function() {
47496                if ($iframe.hasClass("MSIE")) {
47497                    // check if the iframe was created with the ugly hack
47498                    // and perform another ugly hack out of neccessity
47499                    window.frames["printIframe"].focus();
47500                    $head.append("<script>  window.print(); </script>");
47501                } else {
47502                    // proper method
47503                    if (document.queryCommandSupported("print")) {
47504                        $iframe[0].contentWindow.document.execCommand("print", false, null);
47505                    } else {
47506                        $iframe[0].contentWindow.focus();
47507                        $iframe[0].contentWindow.print();
47508                    }
47509                }
47510
47511                //remove iframe after print
47512                // NOTE: removed - do NOT remove iframe as iOS will then print a blank page if you're not quick enough
47513
47514                // if (!opt.debug) {
47515                //     setTimeout(function() {
47516                //         $iframe.remove();
47517                //     }, 1000);
47518                // }
47519
47520            }, opt.printDelay);
47521
47522        }, 333);
47523
47524    };
47525
47526    // defaults
47527    $.fn.printThis.defaults = {
47528        debug: false,           // show the iframe for debugging
47529        importCSS: true,        // import parent page css
47530        importStyle: false,     // import style tags
47531        printContainer: true,   // print outer container/$.selector
47532        loadCSS: "",            // load an additional css file - load multiple stylesheets with an array []
47533        pageTitle: "",          // add title to print page
47534        removeInline: false,    // remove all inline styles
47535        printDelay: 333,        // variable print delay
47536        header: null,           // prefix to html
47537        formValues: true,        // preserve input/form values
vendor: 11,066 bytes, lines 47538-47548
47538        doctypeString: '<!DOCTYPE html>' // html doctype
47539    };
47540
47541    // $.selector container
47542    jQuery.fn.outer = function() {
47543        return $($("<div></div>").html(this.clone())).html()
47544    }
47545})(jQuery);
47546/* flatpickr v4.5.2,, @license MIT */
47547
47548!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.flatpickr=t()}(this,function(){"use strict";var X=function(e){return("0"+e).slice(-2)},ee=function(e){return!0===e?1:0};function te(n,a,i){var o;return void 0===i&&(i=!1),function(){var e=this,t=arguments;null!==o&&clearTimeout(o),o=window.setTimeout(function(){o=null,i||n.apply(e,t)},a),i&&!o&&n.apply(e,t)}}var ne=function(e){return e instanceof Array?e:[e]},e=function(){},ae=function(e,t,n){return n.months[t?"shorthand":"longhand"][e]},w={D:e,F:function(e,t,n){e.setMonth(n.months.longhand.indexOf(t))},G:function(e,t){e.setHours(parseFloat(t))},H:function(e,t){e.setHours(parseFloat(t))},J:function(e,t){e.setDate(parseFloat(t))},K:function(e,t,n){e.setHours(e.getHours()%12+12*ee(new RegExp(n.amPM[1],"i").test(t)))},M:function(e,t,n){e.setMonth(n.months.shorthand.indexOf(t))},S:function(e,t){e.setSeconds(parseFloat(t))},U:function(e,t){return new Date(1e3*parseFloat(t))},W:function(e,t){var n=parseInt(t);return new Date(e.getFullYear(),0,2+7*(n-1),0,0,0,0)},Y:function(e,t){e.setFullYear(parseFloat(t))},Z:function(e,t){return new Date(t)},d:function(e,t){e.setDate(parseFloat(t))},h:function(e,t){e.setHours(parseFloat(t))},i:function(e,t){e.setMinutes(parseFloat(t))},j:function(e,t){e.setDate(parseFloat(t))},l:e,m:function(e,t){e.setMonth(parseFloat(t)-1)},n:function(e,t){e.setMonth(parseFloat(t)-1)},s:function(e,t){e.setSeconds(parseFloat(t))},w:e,y:function(e,t){e.setFullYear(2e3+parseFloat(t))}},ie={D:"(\\w+)",F:"(\\w+)",G:"(\\d\\d|\\d)",H:"(\\d\\d|\\d)",J:"(\\d\\d|\\d)\\w+",K:"",M:"(\\w+)",S:"(\\d\\d|\\d)",U:"(.+)",W:"(\\d\\d|\\d)",Y:"(\\d{4})",Z:"(.+)",d:"(\\d\\d|\\d)",h:"(\\d\\d|\\d)",i:"(\\d\\d|\\d)",j:"(\\d\\d|\\d)",l:"(\\w+)",m:"(\\d\\d|\\d)",n:"(\\d\\d|\\d)",s:"(\\d\\d|\\d)",w:"(\\d\\d|\\d)",y:"(\\d{2})"},l={Z:function(e){return e.toISOString()},D:function(e,t,n){return t.weekdays.shorthand[l.w(e,t,n)]},F:function(e,t,n){return ae(l.n(e,t,n)-1,!1,t)},G:function(e,t,n){return X(l.h(e,t,n))},H:function(e){return X(e.getHours())},J:function(e,t){return void 0!==t.ordinal?e.getDate()+t.ordinal(e.getDate()):e.getDate()},K:function(e,t){return t.amPM[ee(11<e.getHours())]},M:function(e,t){return ae(e.getMonth(),!0,t)},S:function(e){return X(e.getSeconds())},U:function(e){return e.getTime()/1e3},W:function(e,t,n){return n.getWeek(e)},Y:function(e){return e.getFullYear()},d:function(e){return X(e.getDate())},h:function(e){return e.getHours()%12?e.getHours()%12:12},i:function(e){return X(e.getMinutes())},j:function(e){return e.getDate()},l:function(e,t){return t.weekdays.longhand[e.getDay()]},m:function(e){return X(e.getMonth()+1)},n:function(e){return e.getMonth()+1},s:function(e){return e.getSeconds()},w:function(e){return e.getDay()},y:function(e){return String(e.getFullYear()).substring(2)}},oe={weekdays:{shorthand:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],longhand:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},months:{shorthand:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],longhand:["January","February","March","April","May","June","July","August","September","October","November","December"]},daysInMonth:[31,28,31,30,31,30,31,31,30,31,30,31],firstDayOfWeek:0,ordinal:function(e){var t=e%100;if(3<t&&t<21)return"th";switch(t%10){case 1:return"st";case 2:return"nd";case 3:return"rd";default:return"th"}},rangeSeparator:" to ",weekAbbreviation:"Wk",scrollTitle:"Scroll to increment",toggleTitle:"Click to toggle",amPM:["AM","PM"],yearAriaLabel:"Year"},re=function(e){var t=e.config,o=void 0===t?C:t,n=e.l10n,r=void 0===n?oe:n;return function(a,e,t){var i=t||r;return void 0!==o.formatDate?o.formatDate(a,e,i):e.split("").map(function(e,t,n){return l[e]&&"\\"!==n[t-1]?l[e](a,i,o):"\\"!==e?e:""}).join("")}},le=function(e){var t=e.config,D=void 0===t?C:t,n=e.l10n,b=void 0===n?oe:n;return function(e,t,n,a){if(0===e||e){var i,o=a||b,r=e;if(e instanceof Date)i=new Date(e.getTime());else if("string"!=typeof e&&void 0!==e.toFixed)i=new Date(e);else if("string"==typeof e){var l=t||(D||C).dateFormat,c=String(e).trim();if("today"===c)i=new Date,n=!0;else if(/Z$/.test(c)||/GMT$/.test(c))i=new Date(e);else if(D&&D.parseDate)i=D.parseDate(e,l);else{i=D&&D.noCalendar?new Date((new Date).setHours(0,0,0,0)):new Date((new Date).getFullYear(),0,1,0,0,0,0);for(var d,s=[],u=0,f=0,m="";u<l.length;u++){var g=l[u],p="\\"===g,h="\\"===l[u-1]||p;if(ie[g]&&!h){m+=ie[g];var v=new RegExp(m).exec(e);v&&(d=!0)&&s["Y"!==g?"push":"unshift"]({fn:w[g],val:v[++f]})}else p||(m+=".");s.forEach(function(e){var t=e.fn,n=e.val;return i=t(i,n,o)||i})}i=d?i:void 0}}if(i instanceof Date&&!isNaN(i.getTime()))return!0===n&&i.setHours(0,0,0,0),i;D.errorHandler(new Error("Invalid date provided: "+r))}}};function ce(e,t,n){return void 0===n&&(n=!0),!1!==n?new Date(e.getTime()).setHours(0,0,0,0)-new Date(t.getTime()).setHours(0,0,0,0):e.getTime()-t.getTime()}var de=function(e,t,n){return e>Math.min(t,n)&&e<Math.max(t,n)},se={DAY:864e5},ue=["onChange","onClose","onDayCreate","onDestroy","onKeyDown","onMonthChange","onOpen","onParseConfig","onReady","onValueUpdate","onYearChange","onPreCalendarPosition"],C={_disable:[],_enable:[],allowInput:!1,altFormat:"F j, Y",altInput:!1,altInputClass:"form-control input",animate:"object"==typeof window&&-1===window.navigator.userAgent.indexOf("MSIE"),ariaDateFormat:"F j, Y",clickOpens:!0,closeOnSelect:!0,conjunction:", ",dateFormat:"Y-m-d",defaultHour:12,defaultMinute:0,defaultSeconds:0,disable:[],disableMobile:!1,enable:[],enableSeconds:!1,enableTime:!1,errorHandler:function(e){return"undefined"!=typeof console&&console.warn(e)},getWeek:function(e){var t=new Date(e.getTime());t.setHours(0,0,0,0),t.setDate(t.getDate()+3-(t.getDay()+6)%7);var n=new Date(t.getFullYear(),0,4);return 1+Math.round(((t.getTime()-n.getTime())/864e5-3+(n.getDay()+6)%7)/7)},hourIncrement:1,ignoredFocusElements:[],inline:!1,locale:"default",minuteIncrement:5,mode:"single",nextArrow:"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",noCalendar:!1,now:new Date,onChange:[],onClose:[],onDayCreate:[],onDestroy:[],onKeyDown:[],onMonthChange:[],onOpen:[],onParseConfig:[],onReady:[],onValueUpdate:[],onYearChange:[],onPreCalendarPosition:[],plugins:[],position:"auto",positionElement:void 0,prevArrow:"<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",shorthandCurrentMonth:!1,showMonths:1,static:!1,time_24hr:!1,weekNumbers:!1,wrap:!1};function fe(e,t,n){if(!0===n)return e.classList.add(t);e.classList.remove(t)}function me(e,t,n){var a=window.document.createElement(e);return t=t||"",n=n||"",a.className=t,void 0!==n&&(a.textContent=n),a}function ge(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function pe(e,t){var n=me("div","numInputWrapper"),a=me("input","numInput "+e),i=me("span","arrowUp"),o=me("span","arrowDown");if(a.type="text",a.pattern="\\d*",void 0!==t)for(var r in t)a.setAttribute(r,t[r]);return n.appendChild(a),n.appendChild(i),n.appendChild(o),n}"function"!=typeof Object.assign&&(Object.assign=function(n){if(!n)throw TypeError("Cannot convert undefined or null to object");for(var e=arguments.length,a=new Array(1<e?e-1:0),t=1;t<e;t++)a[t-1]=arguments[t];for(var i=function(){var t=a[o];t&&Object.keys(t).forEach(function(e){return n[e]=t[e]})},o=0;o<a.length;o++)i();return n});var he=300;function r(d,s){var h={config:Object.assign({},ve.defaultConfig),l10n:oe};function u(e){return e.bind(h)}function t(){var t=h.config;!1===t.weekNumbers&&1===t.showMonths||!0!==t.noCalendar&&window.requestAnimationFrame(function(){if(h.calendarContainer.style.visibility="hidden",h.calendarContainer.style.display="block",void 0!==h.daysContainer){var e=(h.days.offsetWidth+1)*t.showMonths;h.daysContainer.style.width=e+"px",h.calendarContainer.style.width=e+(void 0!==h.weekWrapper?h.weekWrapper.offsetWidth:0)+"px",h.calendarContainer.style.removeProperty("visibility"),h.calendarContainer.style.removeProperty("display")}})}function f(e){if(0!==h.selectedDates.length){void 0!==e&&"blur"!==e.type&&function(e){e.preventDefault();var t="keydown"===e.type,n=e.target;void 0!==h.amPM&&e.target===h.amPM&&(h.amPM.textContent=h.l10n.amPM[ee(h.amPM.textContent===h.l10n.amPM[0])]);var a=parseFloat(n.getAttribute("data-min")),i=parseFloat(n.getAttribute("data-max")),o=parseFloat(n.getAttribute("data-step")),r=parseInt(n.value,10),l=e.delta||(t?38===e.which?1:-1:0),c=r+o*l;if(void 0!==n.value&&2===n.value.length){var d=n===h.hourElement,s=n===h.minuteElement;c<a?(c=i+c+ee(!d)+(ee(d)&&ee(!h.amPM)),s&&v(void 0,-1,h.hourElement)):i<c&&(c=n===h.hourElement?c-i-ee(!h.amPM):a,s&&v(void 0,1,h.hourElement)),h.amPM&&d&&(1===o?c+r===23:Math.abs(c-r)>o)&&(h.amPM.textContent=h.l10n.amPM[ee(h.amPM.textContent===h.l10n.amPM[0])]),n.value=X(c)}}(e);var t=h._input.value;m(),Z(),h._input.value!==t&&h._debouncedChange()}}function m(){if(void 0!==h.hourElement&&void 0!==h.minuteElement){var e,t,n=(parseInt(h.hourElement.value.slice(-2),10)||0)%24,a=(parseInt(h.minuteElement.value,10)||0)%60,i=void 0!==h.secondElement?(parseInt(h.secondElement.value,10)||0)%60:0;void 0!==h.amPM&&(e=n,t=h.amPM.textContent,n=e%12+12*ee(t===h.l10n.amPM[1]));var o=void 0!==h.config.minTime||h.config.minDate&&h.minDateHasTime&&h.latestSelectedDateObj&&0===ce(h.latestSelectedDateObj,h.config.minDate,!0);if(void 0!==h.config.maxTime||h.config.maxDate&&h.maxDateHasTime&&h.latestSelectedDateObj&&0===ce(h.latestSelectedDateObj,h.config.maxDate,!0)){var r=void 0!==h.config.maxTime?h.config.maxTime:h.config.maxDate;(n=Math.min(n,r.getHours()))===r.getHours()&&(a=Math.min(a,r.getMinutes())),a===r.getMinutes()&&(i=Math.min(i,r.getSeconds()))}if(o){var l=void 0!==h.config.minTime?h.config.minTime:h.config.minDate;(n=Math.max(n,l.getHours()))===l.getHours()&&(a=Math.max(a,l.getMinutes())),a===l.getMinutes()&&(i=Math.max(i,l.getSeconds()))}c(n,a,i)}}function i(e){var t=e||h.latestSelectedDateObj;t&&c(t.getHours(),t.getMinutes(),t.getSeconds())}function a(){var e=h.config.defaultHour,t=h.config.defaultMinute,n=h.config.defaultSeconds;if(void 0!==h.config.minDate){var a=h.config.minDate.getHours(),i=h.config.minDate.getMinutes();(e=Math.max(e,a))===a&&(t=Math.max(i,t)),e===a&&t===i&&(n=h.config.minDate.getSeconds())}if(void 0!==h.config.maxDate){var o=h.config.maxDate.getHours(),r=h.config.maxDate.getMinutes();(e=Math.min(e,o))===o&&(t=Math.min(r,t)),e===o&&t===r&&(n=h.config.maxDate.getSeconds())}c(e,t,n)}
47548function c(e,t,n){void 0!==h.latestSelectedDateObj&&h.latestSelectedDateObj.setHours(e%24,t,n||0,0),h.hourElement&&h.minuteElement&&!h.isMobile&&(h.hourElement.value=X(h.config.time_24hr?e:(12+e)%12+12*ee(e%12==0)),h.minuteElement.value=X(t),void 0!==h.amPM&&(h.amPM.textContent=h.l10n.amPM[ee(12<=e)]),void 0!==h.secondElement&&(h.secondElement.value=X(n)))}function n(e){var t=parseInt(e.target.value)+(e.delta||0);(1<t/1e3||"Enter"===e.key&&!/[^\d]/.test(t.toString()))&&_(t)}function o(t,n,a,i){return n instanceof Array?n.forEach(function(e){return o(t,e,a,i)}):t instanceof Array?t.forEach(function(e){return o(e,n,a,i)}):(t.addEventListener(n,a,i),void h._handlers.push({element:t,event:n,handler:a,options:i}))}function r(t){return function(e){1===e.which&&t(e)}}function g(){q("onChange")}function l(e){var t=void 0!==e?h.parseDate(e):h.latestSelectedDateObj||(h.config.minDate&&h.config.minDate>h.now?h.config.minDate:h.config.maxDate&&h.config.maxDate<h.now?h.config.maxDate:h.now);try{void 0!==t&&(h.currentYear=t.getFullYear(),h.currentMonth=t.getMonth())}catch(e){e.message="Invalid date supplied: "+t,h.config.errorHandler(e)}h.redraw()}function p(e){~e.target.className.indexOf("arrow")&&v(e,e.target.classList.contains("arrowUp")?1:-1)}function v(e,t,n){var a=e&&e.target,i=n||a&&a.parentNode&&a.parentNode.firstChild,o=$("increment");o.delta=t,i&&i.dispatchEvent(o)}function D(e,t,n,a){var i,o=N(t,!0),r=me("span","flatpickr-day "+e,t.getDate().toString());return r.dateObj=t,r.$i=a,r.setAttribute("aria-label",h.formatDate(t,h.config.ariaDateFormat)),-1===e.indexOf("hidden")&&0===ce(t,h.now)&&((h.todayDateElem=r).classList.add("today"),r.setAttribute("aria-current","date")),o?(r.tabIndex=-1,z(t)&&(r.classList.add("selected"),h.selectedDateElem=r,"range"===h.config.mode&&(fe(r,"startRange",h.selectedDates[0]&&0===ce(t,h.selectedDates[0],!0)),fe(r,"endRange",h.selectedDates[1]&&0===ce(t,h.selectedDates[1],!0)),"nextMonthDay"===e&&r.classList.add("inRange")))):r.classList.add("disabled"),"range"===h.config.mode&&(i=t,!("range"!==h.config.mode||h.selectedDates.length<2)&&0<=ce(i,h.selectedDates[0])&&ce(i,h.selectedDates[1])<=0&&!z(t)&&r.classList.add("inRange")),h.weekNumbers&&1===h.config.showMonths&&"prevMonthDay"!==e&&n%7==1&&h.weekNumbers.insertAdjacentHTML("beforeend","<span class='flatpickr-day'>"+h.config.getWeek(t)+"</span>"),q("onDayCreate",r),r}function b(e){e.focus(),"range"===h.config.mode&&P(e)}function w(e){for(var t=0<e?0:h.config.showMonths-1,n=0<e?h.config.showMonths:-1,a=t;a!=n;a+=e)for(var i=h.daysContainer.children[a],o=0<e?0:i.children.length-1,r=0<e?i.children.length:-1,l=o;l!=r;l+=e){var c=i.children[l];if(-1===c.className.indexOf("hidden")&&N(c.dateObj))return c}}function C(e,t){var n=F(document.activeElement||document.body),a=void 0!==e?e:n?document.activeElement:void 0!==h.selectedDateElem&&F(h.selectedDateElem)?h.selectedDateElem:void 0!==h.todayDateElem&&F(h.todayDateElem)?h.todayDateElem:w(0<t?1:-1);return void 0===a?h._input.focus():n?void function(e,t){for(var n=-1===e.className.indexOf("Month")?e.dateObj.getMonth():h.currentMonth,a=0<t?h.config.showMonths:-1,i=0<t?1:-1,o=n-h.currentMonth;o!=a;o+=i)for(var r=h.daysContainer.children[o],l=n-h.currentMonth===o?e.$i+t:t<0?r.children.length-1:0,c=r.children.length,d=l;0<=d&&d<c&&d!=(0<t?c:-1);d+=i){var s=r.children[d];if(-1===s.className.indexOf("hidden")&&N(s.dateObj)&&Math.abs(e.$i-d)>=Math.abs(t))return b(s)}h.changeMonth(i),C(w(i),0)}(a,t):b(a)}function y(e,t){for(var n=(new Date(e,t,1).getDay()-h.l10n.firstDayOfWeek+7)%7,a=h.utils.getDaysInMonth((t-1+12)%12),i=h.utils.getDaysInMonth(t),o=window.document.createDocumentFragment(),r=1<h.config.showMonths,l=r?"prevMonthDay hidden":"prevMonthDay",c=r?"nextMonthDay hidden":"nextMonthDay",d=a+1-n,s=0;d<=a;d++,s++)o.appendChild(D(l,new Date(e,t-1,d),d,s));for(d=1;d<=i;d++,s++)o.appendChild(D("",new Date(e,t,d),d,s));for(var u=i+1;u<=42-n&&(1===h.config.showMonths||s%7!=0);u++,s++)o.appendChild(D(c,new Date(e,t+1,u%i),u,s));var f=me("div","dayContainer");return f.appendChild(o),f}function M(){if(void 0!==h.daysContainer){ge(h.daysContainer),h.weekNumbers&&ge(h.weekNumbers);for(var e=document.createDocumentFragment(),t=0;t<h.config.showMonths;t++){var n=new Date(h.currentYear,h.currentMonth,1);n.setMonth(h.currentMonth+t),e.appendChild(y(n.getFullYear(),n.getMonth()))}h.daysContainer.appendChild(e),h.days=h.daysContainer.firstChild,"range"===h.config.mode&&1===h.selectedDates.length&&P()}}function x(){var e=me("div","flatpickr-month"),t=window.document.createDocumentFragment(),n=me("span","cur-month"),a=pe("cur-year",{tabindex:"-1"}),i=a.getElementsByTagName("input")[0];i.setAttribute("aria-label",h.l10n.yearAriaLabel),h.config.minDate&&i.setAttribute("data-min",h.config.minDate.getFullYear().toString()),h.config.maxDate&&(i.setAttribute("data-max",h.config.maxDate.getFullYear().toString()),i.disabled=!!h.config.minDate&&h.config.minDate.getFullYear()===h.config.maxDate.getFullYear());var o=me("div","flatpickr-current-month");return o.appendChild(n),o.appendChild(a),t.appendChild(o),e.appendChild(t),{container:e,yearElement:i,monthElement:n}}function E(){ge(h.monthNav),h.monthNav.appendChild(h.prevMonthNav);for(var e=h.config.showMonths;e--;){var t=x();h.yearElements.push(t.yearElement),h.monthElements.push(t.monthElement),h.monthNav.appendChild(t.container)}h.monthNav.appendChild(h.nextMonthNav)}function T(){h.weekdayContainer?ge(h.weekdayContainer):h.weekdayContainer=me("div","flatpickr-weekdays");for(var e=h.config.showMonths;e--;){var t=me("div","flatpickr-weekdaycontainer");h.weekdayContainer.appendChild(t)}return k(),h.weekdayContainer}function k(){var e=h.l10n.firstDayOfWeek,t=h.l10n.weekdays.shorthand.concat();
475480<e&&e<t.length&&(t=t.splice(e,t.length).concat(t.splice(0,e)));for(var n=h.config.showMonths;n--;)h.weekdayContainer.children[n].innerHTML="\n      <span class=flatpickr-weekday>\n        "+t.join("</span><span class=flatpickr-weekday>")+"\n      </span>\n      "}function I(e,t){void 0===t&&(t=!0);var n=t?e:e-h.currentMonth;n<0&&!0===h._hidePrevMonthArrow||0<n&&!0===h._hideNextMonthArrow||(h.currentMonth+=n,(h.currentMonth<0||11<h.currentMonth)&&(h.currentYear+=11<h.currentMonth?1:-1,h.currentMonth=(h.currentMonth+12)%12,q("onYearChange")),M(),q("onMonthChange"),G())}function O(e){return!(!h.config.appendTo||!h.config.appendTo.contains(e))||h.calendarContainer.contains(e)}function S(t){if(h.isOpen&&!h.config.inline){var e=O(t.target),n=t.target===h.input||t.target===h.altInput||h.element.contains(t.target)||t.path&&t.path.indexOf&&(~t.path.indexOf(h.input)||~t.path.indexOf(h.altInput)),a="blur"===t.type?n&&t.relatedTarget&&!O(t.relatedTarget):!n&&!e,i=!h.config.ignoredFocusElements.some(function(e){return e.contains(t.target)});a&&i&&(h.close(),"range"===h.config.mode&&1===h.selectedDates.length&&(h.clear(!1),h.redraw()))}}function _(e){if(!(!e||h.config.minDate&&e<h.config.minDate.getFullYear()||h.config.maxDate&&e>h.config.maxDate.getFullYear())){var t=e,n=h.currentYear!==t;h.currentYear=t||h.currentYear,h.config.maxDate&&h.currentYear===h.config.maxDate.getFullYear()?h.currentMonth=Math.min(h.config.maxDate.getMonth(),h.currentMonth):h.config.minDate&&h.currentYear===h.config.minDate.getFullYear()&&(h.currentMonth=Math.max(h.config.minDate.getMonth(),h.currentMonth)),n&&(h.redraw(),q("onYearChange"))}}function N(e,t){void 0===t&&(t=!0);var n=h.parseDate(e,void 0,t);if(h.config.minDate&&n&&ce(n,h.config.minDate,void 0!==t?t:!h.minDateHasTime)<0||h.config.maxDate&&n&&0<ce(n,h.config.maxDate,void 0!==t?t:!h.maxDateHasTime))return!1;if(0===h.config.enable.length&&0===h.config.disable.length)return!0;if(void 0===n)return!1;for(var a,i=0<h.config.enable.length,o=i?h.config.enable:h.config.disable,r=0;r<o.length;r++){if("function"==typeof(a=o[r])&&a(n))return i;if(a instanceof Date&&void 0!==n&&a.getTime()===n.getTime())return i;if("string"==typeof a&&void 0!==n){var l=h.parseDate(a,void 0,!0);return l&&l.getTime()===n.getTime()?i:!i}if("object"==typeof a&&void 0!==n&&a.from&&a.to&&n.getTime()>=a.from.getTime()&&n.getTime()<=a.to.getTime())return i}return!i}function F(e){return void 0!==h.daysContainer&&(-1===e.className.indexOf("hidden")&&h.daysContainer.contains(e))}function A(e){var t=e.target===h._input,n=h.config.allowInput,a=h.isOpen&&(!n||!t),i=h.config.inline&&t&&!n;if(13===e.keyCode&&t){if(n)return h.setDate(h._input.value,!0,e.target===h.altInput?h.config.altFormat:h.config.dateFormat),e.target.blur();h.open()}else if(O(e.target)||a||i){var o=!!h.timeContainer&&h.timeContainer.contains(e.target);switch(e.keyCode){case 13:o?f():B(e);break;case 27:e.preventDefault(),R();break;case 8:case 46:t&&!h.config.allowInput&&(e.preventDefault(),h.clear());break;case 37:case 39:if(o)h.hourElement&&h.hourElement.focus();else if(e.preventDefault(),void 0!==h.daysContainer&&(!1===n||F(document.activeElement))){var r=39===e.keyCode?1:-1;e.ctrlKey?(I(r),C(w(1),0)):C(void 0,r)}break;case 38:case 40:e.preventDefault();var l=40===e.keyCode?1:-1;h.daysContainer&&void 0!==e.target.$i?e.ctrlKey?(_(h.currentYear-l),C(w(1),0)):o||C(void 0,7*l):h.config.enableTime&&(!o&&h.hourElement&&h.hourElement.focus(),f(e),h._debouncedChange());break;case 9:if(!o){h.element.focus();break}var c=[h.hourElement,h.minuteElement,h.secondElement,h.amPM].filter(function(e){return e}),d=c.indexOf(e.target);if(-1!==d){var s=c[d+(e.shiftKey?-1:1)];void 0!==s?(e.preventDefault(),s.focus()):h.element.focus()}}}if(void 0!==h.amPM&&e.target===h.amPM)switch(e.key){case h.l10n.amPM[0].charAt(0):case h.l10n.amPM[0].charAt(0).toLowerCase():h.amPM.textContent=h.l10n.amPM[0],m(),Z();break;case h.l10n.amPM[1].charAt(0):case h.l10n.amPM[1].charAt(0).toLowerCase():h.amPM.textContent=h.l10n.amPM[1],m(),Z()}q("onKeyDown",e)}function P(o){if(1===h.selectedDates.length&&(!o||o.classList.contains("flatpickr-day")&&!o.classList.contains("disabled"))){for(var r=o?o.dateObj.getTime():h.days.firstElementChild.dateObj.getTime(),l=h.parseDate(h.selectedDates[0],void 0,!0).getTime(),e=Math.min(r,h.selectedDates[0].getTime()),t=Math.max(r,h.selectedDates[0].getTime()),n=h.daysContainer.lastChild.lastChild.dateObj.getTime(),c=!1,d=0,s=0,a=e;a<n;a+=se.DAY)N(new Date(a),!0)||(c=c||e<a&&a<t,a<l&&(!d||d<a)?d=a:l<a&&(!s||a<s)&&(s=a));for(var u=0;u<h.config.showMonths;u++)for(var f=h.daysContainer.children[u],m=h.daysContainer.children[u-1],i=function(e,t){var n=f.children[e],a=n.dateObj.getTime(),i=0<d&&a<d||0<s&&s<a;return i?(n.classList.add("notAllowed"),["inRange","startRange","endRange"].forEach(function(e){n.classList.remove(e)}),"continue"):c&&!i?"continue":(["startRange","inRange","endRange","notAllowed"].forEach(function(e){n.classList.remove(e)}),void(void 0!==o&&(o.classList.add(r<h.selectedDates[0].getTime()?"startRange":"endRange"),!f.contains(o)&&0<u&&m&&m.lastChild.dateObj.getTime()>=a||(l<r&&a===l?n.classList.add("startRange"):r<l&&a===l&&n.classList.add("endRange"),d<=a&&(0===s||a<=s)&&de(a,l,r)&&n.classList.add("inRange")))))},g=0,p=f.children.length;g<p;g++)i(g)}}
47548function j(){!h.isOpen||h.config.static||h.config.inline||L()}function Y(a){return function(e){var t=h.config["_"+a+"Date"]=h.parseDate(e,h.config.dateFormat),n=h.config["_"+("min"===a?"max":"min")+"Date"];void 0!==t&&(h["min"===a?"minDateHasTime":"maxDateHasTime"]=0<t.getHours()||0<t.getMinutes()||0<t.getSeconds()),h.selectedDates&&(h.selectedDates=h.selectedDates.filter(function(e){return N(e)}),h.selectedDates.length||"min"!==a||i(t),Z()),h.daysContainer&&(W(),void 0!==t?h.currentYearElement[a]=t.getFullYear().toString():h.currentYearElement.removeAttribute(a),h.currentYearElement.disabled=!!n&&void 0!==t&&n.getFullYear()===t.getFullYear())}}function H(){"object"!=typeof h.config.locale&&void 0===ve.l10ns[h.config.locale]&&h.config.errorHandler(new Error("flatpickr: invalid locale "+h.config.locale)),h.l10n=Object.assign({},ve.l10ns.default,"object"==typeof h.config.locale?h.config.locale:"default"!==h.config.locale?ve.l10ns[h.config.locale]:void 0),ie.K="("+h.l10n.amPM[0]+"|"+h.l10n.amPM[1]+"|"+h.l10n.amPM[0].toLowerCase()+"|"+h.l10n.amPM[1].toLowerCase()+")",h.formatDate=re(h),h.parseDate=le({config:h.config,l10n:h.l10n})}function L(e){if(void 0!==h.calendarContainer){q("onPreCalendarPosition");var t=e||h._positionElement,n=Array.prototype.reduce.call(h.calendarContainer.children,function(e,t){return e+t.offsetHeight},0),a=h.calendarContainer.offsetWidth,i=h.config.position.split(" "),o=i[0],r=1<i.length?i[1]:null,l=t.getBoundingClientRect(),c=window.innerHeight-l.bottom,d="above"===o||"below"!==o&&c<n&&l.top>n,s=window.pageYOffset+l.top+(d?-n-2:t.offsetHeight+2);if(fe(h.calendarContainer,"arrowTop",!d),fe(h.calendarContainer,"arrowBottom",d),!h.config.inline){var u=window.pageXOffset+l.left-(null!=r&&"center"===r?(a-l.width)/2:0),f=window.document.body.offsetWidth-l.right,m=u+a>window.document.body.offsetWidth;fe(h.calendarContainer,"rightMost",m),h.config.static||(h.calendarContainer.style.top=s+"px",m?(h.calendarContainer.style.left="auto",h.calendarContainer.style.right=f+"px"):(h.calendarContainer.style.left=u+"px",h.calendarContainer.style.right="auto"))}}}function W(){h.config.noCalendar||h.isMobile||(G(),M())}function R(){h._input.focus(),-1!==window.navigator.userAgent.indexOf("MSIE")||void 0!==navigator.msMaxTouchPoints?setTimeout(h.close,0):h.close()}function B(e){e.preventDefault(),e.stopPropagation();var t=function e(t,n){return n(t)?t:t.parentNode?e(t.parentNode,n):void 0}(e.target,function(e){return e.classList&&e.classList.contains("flatpickr-day")&&!e.classList.contains("disabled")&&!e.classList.contains("notAllowed")});if(void 0!==t){var n=t,a=h.latestSelectedDateObj=new Date(n.dateObj.getTime()),i=(a.getMonth()<h.currentMonth||a.getMonth()>h.currentMonth+h.config.showMonths-1)&&"range"!==h.config.mode;if(h.selectedDateElem=n,"single"===h.config.mode)h.selectedDates=[a];else if("multiple"===h.config.mode){var o=z(a);o?h.selectedDates.splice(parseInt(o),1):h.selectedDates.push(a)}else"range"===h.config.mode&&(2===h.selectedDates.length&&h.clear(!1),h.selectedDates.push(a),0!==ce(a,h.selectedDates[0],!0)&&h.selectedDates.sort(function(e,t){return e.getTime()-t.getTime()}));if(m(),i){var r=h.currentYear!==a.getFullYear();h.currentYear=a.getFullYear(),h.currentMonth=a.getMonth(),r&&q("onYearChange"),q("onMonthChange")}if(G(),M(),Z(),h.config.enableTime&&setTimeout(function(){return h.showTimeInput=!0},50),i||"range"===h.config.mode||1!==h.config.showMonths?h.selectedDateElem&&h.selectedDateElem.focus():b(n),void 0!==h.hourElement&&setTimeout(function(){return void 0!==h.hourElement&&h.hourElement.select()},451),h.config.closeOnSelect){var l="single"===h.config.mode&&!h.config.enableTime,c="range"===h.config.mode&&2===h.selectedDates.length&&!h.config.enableTime;(l||c)&&R()}g()}}h.parseDate=le({config:h.config,l10n:h.l10n}),h._handlers=[],h._bind=o,h._setHoursFromDate=i,h._positionCalendar=L,h.changeMonth=I,h.changeYear=_,h.clear=function(e){void 0===e&&(e=!0);h.input.value="",void 0!==h.altInput&&(h.altInput.value="");void 0!==h.mobileInput&&(h.mobileInput.value="");h.selectedDates=[],h.latestSelectedDateObj=void 0,!(h.showTimeInput=!1)===h.config.enableTime&&a();h.redraw(),e&&q("onChange")},h.close=function(){h.isOpen=!1,h.isMobile||(h.calendarContainer.classList.remove("open"),h._input.classList.remove("active"));q("onClose")},h._createElement=me,h.destroy=function(){void 0!==h.config&&q("onDestroy");for(var e=h._handlers.length;e--;){var t=h._handlers[e];t.element.removeEventListener(t.event,t.handler,t.options)}if(h._handlers=[],h.mobileInput)h.mobileInput.parentNode&&h.mobileInput.parentNode.removeChild(h.mobileInput),h.mobileInput=void 0;else if(h.calendarContainer&&h.calendarContainer.parentNode)if(h.config.static&&h.calendarContainer.parentNode){var n=h.calendarContainer.parentNode;if(n.lastChild&&n.removeChild(n.lastChild),n.parentNode){for(;n.firstChild;)n.parentNode.insertBefore(n.firstChild,n);n.parentNode.removeChild(n)}}else h.calendarContainer.parentNode.removeChild(h.calendarContainer);h.altInput&&(h.input.type="text",h.altInput.parentNode&&h.altInput.parentNode.removeChild(h.altInput),delete h.altInput);h.input&&(h.input.type=h.input._type,h.input.classList.remove("flatpickr-input"),h.input.removeAttribute("readonly"),h.input.value="");["_showTimeInput","latestSelectedDateObj","_hideNextMonthArrow","_hidePrevMonthArrow","__hideNextMonthArrow","__hidePrevMonthArrow","isMobile","
47548isOpen","selectedDateElem","minDateHasTime","maxDateHasTime","days","daysContainer","_input","_positionElement","innerContainer","rContainer","monthNav","todayDateElem","calendarContainer","weekdayContainer","prevMonthNav","nextMonthNav","currentMonthElement","currentYearElement","navigationCurrentMonth","selectedDateElem","config"].forEach(function(e){try{delete h[e]}catch(e){}})},h.isEnabled=N,h.jumpToDate=l,h.open=function(e,t){void 0===t&&(t=h._positionElement);if(!0===h.isMobile)return e&&(e.preventDefault(),e.target&&e.target.blur()),void 0!==h.mobileInput&&(h.mobileInput.focus(),h.mobileInput.click()),void q("onOpen");if(h._input.disabled||h.config.inline)return;var n=h.isOpen;h.isOpen=!0,n||(h.calendarContainer.classList.add("open"),h._input.classList.add("active"),q("onOpen"),L(t));!0===h.config.enableTime&&!0===h.config.noCalendar&&(0===h.selectedDates.length&&(h.setDate(void 0!==h.config.minDate?new Date(h.config.minDate.getTime()):new Date,!1),a(),Z()),!1!==h.config.allowInput||void 0!==e&&h.timeContainer.contains(e.relatedTarget)||setTimeout(function(){return h.hourElement.select()},50))},h.redraw=W,h.set=function(e,t){null!==e&&"object"==typeof e?Object.assign(h.config,e):(h.config[e]=t,void 0!==K[e]?K[e].forEach(function(e){return e()}):-1<ue.indexOf(e)&&(h.config[e]=ne(t)));h.redraw(),l(),Z(!1)},h.setDate=function(e,t,n){void 0===t&&(t=!1);void 0===n&&(n=h.config.dateFormat);if(0!==e&&!e||e instanceof Array&&0===e.length)return h.clear(t);J(e,n),h.showTimeInput=0<h.selectedDates.length,h.latestSelectedDateObj=h.selectedDates[0],h.redraw(),l(),i(),Z(t),t&&q("onChange")},h.toggle=function(e){if(!0===h.isOpen)return h.close();h.open(e)};var K={locale:[H,k],showMonths:[E,t,T]};function J(e,t){var n=[];if(e instanceof Array)n=e.map(function(e){return h.parseDate(e,t)});else if(e instanceof Date||"number"==typeof e)n=[h.parseDate(e,t)];else if("string"==typeof e)switch(h.config.mode){case"single":case"time":n=[h.parseDate(e,t)];break;case"multiple":n=e.split(h.config.conjunction).map(function(e){return h.parseDate(e,t)});break;case"range":n=e.split(h.l10n.rangeSeparator).map(function(e){return h.parseDate(e,t)})}else h.config.errorHandler(new Error("Invalid date supplied: "+JSON.stringify(e)));h.selectedDates=n.filter(function(e){return e instanceof Date&&N(e,!1)}),"range"===h.config.mode&&h.selectedDates.sort(function(e,t){return e.getTime()-t.getTime()})}function U(e){return e.slice().map(function(e){return"string"==typeof e||"number"==typeof e||e instanceof Date?h.parseDate(e,void 0,!0):e&&"object"==typeof e&&e.from&&e.to?{from:h.parseDate(e.from,void 0),to:h.parseDate(e.to,void 0)}:e}).filter(function(e){return e})}function q(e,t){if(void 0!==h.config){var n=h.config[e];if(void 0!==n&&0<n.length)for(var a=0;n[a]&&a<n.length;a++)n[a](h.selectedDates,h.input.value,h,t);"onChange"===e&&(h.input.dispatchEvent($("change")),h.input.dispatchEvent($("input")))}}function $(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!0),t}function z(e){for(var t=0;t<h.selectedDates.length;t++)if(0===ce(h.selectedDates[t],e))return""+t;return!1}function G(){h.config.noCalendar||h.isMobile||!h.monthNav||(h.yearElements.forEach(function(e,t){var n=new Date(h.currentYear,h.currentMonth,1);n.setMonth(h.currentMonth+t),h.monthElements[t].textContent=ae(n.getMonth(),h.config.shorthandCurrentMonth,h.l10n)+" ",e.value=n.getFullYear().toString()}),h._hidePrevMonthArrow=void 0!==h.config.minDate&&(h.currentYear===h.config.minDate.getFullYear()?h.currentMonth<=h.config.minDate.getMonth():h.currentYear<h.config.minDate.getFullYear()),h._hideNextMonthArrow=void 0!==h.config.maxDate&&(h.currentYear===h.config.maxDate.getFullYear()?h.currentMonth+1>h.config.maxDate.getMonth():h.currentYear>h.config.maxDate.getFullYear()))}function V(t){return h.selectedDates.map(function(e){return h.formatDate(e,t)}).filter(function(e,t,n){return"range"!==h.config.mode||h.config.enableTime||n.indexOf(e)===t}).join("range"!==h.config.mode?h.config.conjunction:h.l10n.rangeSeparator)}function Z(e){if(void 0===e&&(e=!0),0===h.selectedDates.length)return h.clear(e);void 0!==h.mobileInput&&h.mobileFormatStr&&(h.mobileInput.value=void 0!==h.latestSelectedDateObj?h.formatDate(h.latestSelectedDateObj,h.mobileFormatStr):""),h.input.value=V(h.config.dateFormat),void 0!==h.altInput&&(h.altInput.value=V(h.config.altFormat)),!1!==e&&q("onValueUpdate")}function Q(e){e.preventDefault();var t=h.prevMonthNav.contains(e.target),n=h.nextMonthNav.contains(e.target);t||n?I(t?-1:1):0<=h.yearElements.indexOf(e.target)?e.target.select():e.target.classList.contains("arrowUp")?h.changeYear(h.currentYear+1):e.target.classList.contains("arrowDown")&&h.changeYear(h.currentYear-1)}return function(){h.element=h.input=d,h.isOpen=!1,function(){var e=["wrap","weekNumbers","allowInput","clickOpens","time_24hr","enableTime","noCalendar","altInput","shorthandCurrentMonth","inline","static","enableSeconds","disableMobile"],t=Object.assign({},s,JSON.parse(JSON.stringify(d.dataset||{}))),n={};h.config.parseDate=t.parseDate,h.config.formatDate=t.formatDate,Object.defineProperty(h.config,"enable",{get:function(){return h.config._enable},set:function(e){h.config._enable=U(e)}}),Object.defineProperty(h.config,"disable",{get:function(){return h.config._disable},set:function(e){h.config._disable=U(e)}});var a="time"===t.mode;t.dateFormat||!t.enableTime&&!a||(n.dateFormat=t.noCalendar||a?"H:i"+(t.enableSeconds?":S":""):ve.defaultConfig.dateFormat+" H:i"+(t.enableSeconds?":S":"")),t.altInput&&(t.enableTime||a)&&!t.altFormat&&(n.altFormat=t.noCalendar||a?"h:i"+(t.enableSeconds?":S K":" K"):ve.defaultConfig.altFormat+" h:i"+(t.enableSeconds?":S":"")+" K"),Object.defineProperty(h.config,"minDate",{get:function(){return h.config._minDate},set:Y("min")}),Object.defineProperty(h.config,"maxDate",{get:function(){return h.config._maxDate},set:Y("max")}
vendor: 5,300 bytes, line 47548
47548);var i=function(t){return function(e){h.config["min"===t?"_minTime":"_maxTime"]=h.parseDate(e,"H:i")}};Object.defineProperty(h.config,"minTime",{get:function(){return h.config._minTime},set:i("min")}),Object.defineProperty(h.config,"maxTime",{get:function(){return h.config._maxTime},set:i("max")}),"time"===t.mode&&(h.config.noCalendar=!0,h.config.enableTime=!0),Object.assign(h.config,n,t);for(var o=0;o<e.length;o++)h.config[e[o]]=!0===h.config[e[o]]||"true"===h.config[e[o]];ue.filter(function(e){return void 0!==h.config[e]}).forEach(function(e){h.config[e]=ne(h.config[e]||[]).map(u)}),h.isMobile=!h.config.disableMobile&&!h.config.inline&&"single"===h.config.mode&&!h.config.disable.length&&!h.config.enable.length&&!h.config.weekNumbers&&/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);for(var r=0;r<h.config.plugins.length;r++){var l=h.config.plugins[r](h)||{};for(var c in l)-1<ue.indexOf(c)?h.config[c]=ne(l[c]).map(u).concat(h.config[c]):void 0===t[c]&&(h.config[c]=l[c])}q("onParseConfig")}(),H(),function(){if(h.input=h.config.wrap?d.querySelector("[data-input]"):d,!h.input)return h.config.errorHandler(new Error("Invalid input element specified"));h.input._type=h.input.type,h.input.type="text",h.input.classList.add("flatpickr-input"),h._input=h.input,h.config.altInput&&(h.altInput=me(h.input.nodeName,h.input.className+" "+h.config.altInputClass),h._input=h.altInput,h.altInput.placeholder=h.input.placeholder,h.altInput.disabled=h.input.disabled,h.altInput.required=h.input.required,h.altInput.tabIndex=h.input.tabIndex,h.altInput.type="text",h.input.setAttribute("type","hidden"),!h.config.static&&h.input.parentNode&&h.input.parentNode.insertBefore(h.altInput,h.input.nextSibling)),h.config.allowInput||h._input.setAttribute("readonly","readonly"),h._positionElement=h.config.positionElement||h._input}(),function(){h.selectedDates=[],h.now=h.parseDate(h.config.now)||new Date;var e=h.config.defaultDate||("INPUT"!==h.input.nodeName&&"TEXTAREA"!==h.input.nodeName||!h.input.placeholder||h.input.value!==h.input.placeholder?h.input.value:null);e&&J(e,h.config.dateFormat);var t=0<h.selectedDates.length?h.selectedDates[0]:h.config.minDate&&h.config.minDate.getTime()>h.now.getTime()?h.config.minDate:h.config.maxDate&&h.config.maxDate.getTime()<h.now.getTime()?h.config.maxDate:h.now;h.currentYear=t.getFullYear(),h.currentMonth=t.getMonth(),0<h.selectedDates.length&&(h.latestSelectedDateObj=h.selectedDates[0]),void 0!==h.config.minTime&&(h.config.minTime=h.parseDate(h.config.minTime,"H:i")),void 0!==h.config.maxTime&&(h.config.maxTime=h.parseDate(h.config.maxTime,"H:i")),h.minDateHasTime=!!h.config.minDate&&(0<h.config.minDate.getHours()||0<h.config.minDate.getMinutes()||0<h.config.minDate.getSeconds()),h.maxDateHasTime=!!h.config.maxDate&&(0<h.config.maxDate.getHours()||0<h.config.maxDate.getMinutes()||0<h.config.maxDate.getSeconds()),Object.defineProperty(h,"showTimeInput",{get:function(){return h._showTimeInput},set:function(e){h._showTimeInput=e,h.calendarContainer&&fe(h.calendarContainer,"showTimeInput",e),h.isOpen&&L()}})}(),h.utils={getDaysInMonth:function(e,t){return void 0===e&&(e=h.currentMonth),void 0===t&&(t=h.currentYear),1===e&&(t%4==0&&t%100!=0||t%400==0)?29:h.l10n.daysInMonth[e]}},h.isMobile||function(){var e=window.document.createDocumentFragment();if(h.calendarContainer=me("div","flatpickr-calendar"),h.calendarContainer.tabIndex=-1,!h.config.noCalendar){if(e.appendChild((h.monthNav=me("div","flatpickr-months"),h.yearElements=[],h.monthElements=[],h.prevMonthNav=me("span","flatpickr-prev-month"),h.prevMonthNav.innerHTML=h.config.prevArrow,h.nextMonthNav=me("span","flatpickr-next-month"),h.nextMonthNav.innerHTML=h.config.nextArrow,E(),Object.defineProperty(h,"_hidePrevMonthArrow",{get:function(){return h.__hidePrevMonthArrow},set:function(e){h.__hidePrevMonthArrow!==e&&(fe(h.prevMonthNav,"disabled",e),h.__hidePrevMonthArrow=e)}}),Object.defineProperty(h,"_hideNextMonthArrow",{get:function(){return h.__hideNextMonthArrow},set:function(e){h.__hideNextMonthArrow!==e&&(fe(h.nextMonthNav,"disabled",e),h.__hideNextMonthArrow=e)}}),h.currentYearElement=h.yearElements[0],G(),h.monthNav)),h.innerContainer=me("div","flatpickr-innerContainer"),h.config.weekNumbers){var t=function(){h.calendarContainer.classList.add("hasWeeks");var e=me("div","flatpickr-weekwrapper");e.appendChild(me("span","flatpickr-weekday",h.l10n.weekAbbreviation));var t=me("div","flatpickr-weeks");return e.appendChild(t),{weekWrapper:e,weekNumbers:t}}(),n=t.weekWrapper,a=t.weekNumbers;h.innerContainer.appendChild(n),h.weekNumbers=a,h.weekWrapper=n}h.rContainer=me("div","flatpickr-rContainer"),h.rContainer.appendChild(T()),h.daysContainer||(h.daysContainer=me("div","flatpickr-days"),h.daysContainer.tabIndex=-1),M(),h.rContainer.appendChild(h.daysContainer),h.innerContainer.appendChild(h.rContainer),e.appendChild(h.innerContainer)}h.config.enableTime&&e.appendChild(function(){h.calendarContainer.classList.add("hasTime"),h.config.noCalendar&&h.calendarContainer.classList.add("noCalendar"),h.timeContainer=me("div","flatpickr-time"),h.timeContainer.tabIndex=-1;var e=me("span","flatpickr-time-separator",":"),t=pe("flatpickr-hour");h.hourElement=t.getElementsByTagName("input")[0];var n=pe("flatpickr-minute");
47548if(h.minuteElement=n.getElementsByTagName("input")[0],h.hourElement.tabIndex=h.minuteElement.tabIndex=-1,h.hourElement.value=X(h.latestSelectedDateObj?h.latestSelectedDateObj.getHours():h.config.time_24hr?h.config.defaultHour:function(e){switch(e%24){case 0:case 12:return 12;default:return e%12}}(h.config.defaultHour)),h.minuteElement.value=X(h.latestSelectedDateObj?h.latestSelectedDateObj.getMinutes():h.config.defaultMinute),h.hourElement.setAttribute("data-step",h.config.hourIncrement.toString()),h.minuteElement.setAttribute("data-step",h.config.minuteIncrement.toString()),h.hourElement.setAttribute("data-min",h.config.time_24hr?"0":"1"),h.hourElement.setAttribute("data-max",h.config.time_24hr?"23":"12"),h.minuteElement.setAttribute("data-min","0"),h.minuteElement.setAttribute("data-max","59"),h.timeContainer.appendChild(t),h.timeContainer.appendChild(e),h.timeContainer.appendChild(n),h.config.time_24hr&&h.timeContainer.classList.add("time24hr"),h.config.enableSeconds){h.timeContainer.classList.add("hasSeconds");var a=pe("flatpickr-second");h.secondElement=a.getElementsByTagName("input")[0],h.secondElement.value=X(h.latestSelectedDateObj?h.latestSelectedDateObj.getSeconds():h.config.defaultSeconds),h.secondElement.setAttribute("data-step",h.minuteElement.getAttribute("data-step")),h.secondElement.setAttribute("data-min",h.minuteElement.getAttribute("data-min")),h.secondElement.setAttribute("data-max",h.minuteElement.getAttribute("data-max")),h.timeContainer.appendChild(me("span","flatpickr-time-separator",":")),h.timeContainer.appendChild(a)}return h.config.time_24hr||(h.amPM=me("span","flatpickr-am-pm",h.l10n.amPM[ee(11<(h.latestSelectedDateObj?h.hourElement.value:h.config.defaultHour))]),h.amPM.title=h.l10n.toggleTitle,h.amPM.tabIndex=-1,h.timeContainer.appendChild(h.amPM)),h.timeContainer}()),fe(h.calendarContainer,"rangeMode","range"===h.config.mode),fe(h.calendarContainer,"animate",!0===h.config.animate),fe(h.calendarContainer,"multiMonth",1<h.config.showMonths),h.calendarContainer.appendChild(e);var i=void 0!==h.config.appendTo&&void 0!==h.config.appendTo.nodeType;if((h.config.inline||h.config.static)&&(h.calendarContainer.classList.add(h.config.inline?"inline":"static"),h.config.inline&&(!i&&h.element.parentNode?h.element.parentNode.insertBefore(h.calendarContainer,h._input.nextSibling):void 0!==h.config.appendTo&&h.config.appendTo.appendChild(h.calendarContainer)),h.config.static)){var o=me("div","flatpickr-wrapper");h.element.parentNode&&h.element.parentNode.insertBefore(o,h.element),o.appendChild(h.element),h.altInput&&o.appendChild(h.altInput),o.appendChild(h.calendarContainer)}h.config.static||h.config.inline||(void 0!==h.config.appendTo?h.config.appendTo:window.document.body).appendChild(h.calendarContainer)}(),function(){if(h.config.wrap&&["open","close","toggle","clear"].forEach(function(t){Array.prototype.forEach.call(h.element.querySelectorAll("[data-"+t+"]"),function(e){return o(e,"click",h[t])})}),h.isMobile)return function(){var e=h.config.enableTime?h.config.noCalendar?"time":"datetime-local":"date";h.mobileInput=me("input",h.input.className+" flatpickr-mobile"),h.mobileInput.step=h.input.getAttribute("step")||"any",h.mobileInput.tabIndex=1,h.mobileInput.type=e,h.mobileInput.disabled=h.input.disabled,h.mobileInput.required=h.input.required,h.mobileInput.placeholder=h.input.placeholder,h.mobileFormatStr="datetime-local"===e?"Y-m-d\\TH:i:S":"date"===e?"Y-m-d":"H:i:S",0<h.selectedDates.length&&(h.mobileInput.defaultValue=h.mobileInput.value=h.formatDate(h.selectedDates[0],h.mobileFormatStr)),h.config.minDate&&(h.mobileInput.min=h.formatDate(h.config.minDate,"Y-m-d")),h.config.maxDate&&(h.mobileInput.max=h.formatDate(h.config.maxDate,"Y-m-d")),h.input.type="hidden",void 0!==h.altInput&&(h.altInput.type="hidden");try{h.input.parentNode&&h.input.parentNode.insertBefore(h.mobileInput,h.input.nextSibling)}catch(e){}o(h.mobileInput,"change",function(e){h.setDate(e.target.value,!1,h.mobileFormatStr),q("onChange"),q("onClose")})}();var e=te(j,50);h._debouncedChange=te(g,he),h.daysContainer&&!/iPhone|iPad|iPod/i.test(navigator.userAgent)&&o(h.daysContainer,"mouseover",function(e){"range"===h.config.mode&&P(e.target)}),o(window.document.body,"keydown",A),h.config.static||o(h._input,"keydown",A),h.config.inline||h.config.static||o(window,"resize",e),void 0!==window.ontouchstart?o(window.document,"click",S):o(window.document,"mousedown",r(S)),o(window.document,"focus",S,{capture:!0}),!0===h.config.clickOpens&&(o(h._input,"focus",h.open),o(h._input,"mousedown",r(h.open))),void 0!==h.daysContainer&&(o(h.monthNav,"mousedown",r(Q)),o(h.monthNav,["keyup","increment"],n),o(h.daysContainer,"mousedown",r(B))),void 0!==h.timeContainer&&void 0!==h.minuteElement&&void 0!==h.hourElement&&(o(h.timeContainer,["increment"],f),o(h.timeContainer,"blur",f,{capture:!0}),o(h.timeContainer,"mousedown",r(p)),o([h.hourElement,h.minuteElement],["focus","click"],function(e){return e.target.select()}),void 0!==h.secondElement&&o(h.secondElement,"focus",function(){return h.secondElement&&h.secondElement.select()}),void 0!==h.amPM&&o(h.amPM,"mousedown",r(function(e){f(e),g()})))}(),(h.selectedDates.length||h.config.noCalendar)&&(h.config.enableTime&&i(h.config.noCalendar?h.latestSelectedDateObj||h.
47548config.minDate:void 0),Z(!1)),t(),h.showTimeInput=0<h.selectedDates.length||h.config.noCalendar;var e=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);!h.isMobile&&e&&L(),q("onReady")}(),h}function n(e,t){for(var n=Array.prototype.slice.call(e),a=[],i=0;i<n.length;i++){var o=n[i];try{if(null!==o.getAttribute("data-fp-omit"))continue;void 0!==o._flatpickr&&(o._flatpickr.destroy(),o._flatpickr=void 0),o._flatpickr=r(o,t||{}),a.push(o._flatpickr)}catch(e){console.error(e)}}return 1===a.length?a[0]:a}"undefined"!=typeof HTMLElement&&(HTMLCollection.prototype.flatpickr=NodeList.prototype.flatpickr=function(e){return n(this,e)},HTMLElement.prototype.flatpickr=function(e){return n([this],e)});var ve=function(e,t){return e instanceof NodeList?n(e,t):n("string"==typeof e?window.document.querySelectorAll(e):[e],t)};return ve.defaultConfig=C,ve.l10ns={en:Object.assign({},oe),default:Object.assign({},oe)},ve.localize=function(e){ve.l10ns.default=Object.assign({},ve.l10ns.default,e)},ve.setDefaults=function(e){ve.defaultConfig=Object.assign({},ve.defaultConfig,e)},ve.parseDate=le({}),ve.formatDate=re({}),ve.compareDates=ce,"undefined"!=typeof jQuery&&(jQuery.fn.flatpickr=function(e){return n(this,e)}),Date.prototype.fp_incr=function(e){return new Date(this.getFullYear(),this.getMonth(),this.getDate()+("string"==typeof e?parseInt(e,10):e))},"undefined"!=typeof window&&(window.flatpickr=ve),ve});
47549// Source: http://tympanus.net/codrops/2012/10/04/custom-drop-down-list-styling/
47550
47551function DropDown(el) {
47552  this.dd = el;
47553  this.placeholder = this.dd.find('.dropdown-label');
47554  this.opts = this.dd.find('.dropdown > li');
47555  this.val = '';
47556  this.index = -1;
47557  this.initEvents();
47558}
47559
47560DropDown.prototype = {
47561  initEvents : function() {
47562    var obj = this;
47563
47564    obj.dd.on('click', function(event){
47565      $(this).toggleClass('active');
47566      event.stopPropagation();
47567    });
47568
47569    obj.placeholder.on('click', function(event) {
47570      event.preventDefault();
47571    })
47572
47573    obj.opts.on('click',function(){
47574      var opt = $(this);
47575      obj.val = opt.text();
47576      obj.index = opt.index();
47577      obj.placeholder.text(obj.val);
47578
47579      $(obj).trigger('change');
47580    });
47581  },
47582  getValue : function() {
47583    return this.val;
47584  },
47585  getIndex : function() {
47586    return this.index;
47587  }
47588}
47589
47590$(function() {
47591
47592  $(document).click(function() {
47593    $('.dropdown-wrapper').removeClass('active');
47594  });
47595
47596});
47597var SuperCat = SuperCat || {};
47598SuperCat.EcatCheckout = SuperCat.EcatCheckout || {};
47599
47600_.assign(SuperCat.EcatCheckout, (function () {
47601
47602  // When a user clicks a suggested address verification address,
47603  // we will not update the email and phone fields. Values previously entered
47604  // in those fields will not change.
47605  var addressVerificationFields = ['code', 'line1', 'line2', 'city', 'state', 'zip', 'country'];
47606  var selectShippingFields = addressVerificationFields.concat(['email', 'phone']);
47607
47608  var populateShipto = function (evt) {
47609    var address = $(evt.target).find(':selected').data('address-info');
47610    populateAddress('ship_to_', address, selectShippingFields);
47611  };
47612
47613  var addressVerificationPopulateShipto = function (evt) {
47614    var address = $(evt.target).data('address-info');
47615    populateAddress('ship_to_', address, addressVerificationFields);
47616  };
47617
47618  var addressVerificationPopulateBillto = function (evt) {
47619    var address = $(evt.target).data('address-info');
47620    populateAddress('bill_to_', address, addressVerificationFields);
47621  };
47622
47623  var populateAddress = function(prefix, address, fields) {
47624    if (address) {
47625      _.forEach(fields,
47626                function (suffix) {
47627                  var key = prefix + suffix;
47628                  $('#order_' + key).val(address[key]);
47629                });
47630    }
47631  };
47632
47633  var registerAddressVerification = function() {
47634    $('#shipping-address-validation-warning_use-suggested').click(addressVerificationPopulateShipto);
47635    $('#billing-address-validation-warning_use-suggested').click(addressVerificationPopulateBillto);
47636
47637  };
47638
47639  var init = function () {
47640    $('#sl-obj-select').change(populateShipto);
47641    registerAddressVerification();
47642  };
47643
47644  return {
47645    init : init
47646  };
47647}()));
47648var SuperCat = SuperCat || {};
47649SuperCat.EcatOrderPreview = SuperCat.EcatOrderPreview || {};
47650
47651_.assign(SuperCat.EcatOrderPreview, (function () {
47652  var submitDialog = function (evt) {
47653    SuperCat.EcatQtyNotes.submitQtyNotesForm(evt,
47654                           function (data) {
47655                             var qty = data.qty;
47656                             var notes = data.line_notes;
47657                             var row_id = '#cart_item_' + data.obj_id;
47658                             $(row_id + ' .line-notes-display').html(notes);
47659                             $(row_id + ' .line-notes-link').data('quantity', qty);
47660                             $(row_id + ' .line-notes-link').data('line-notes', notes);
47661
47662                             $(row_id + ' .quantity-display').html(qty);
47663                             $(row_id + ' .quantity-link').data('quantity', qty);
47664                             $(row_id + ' .quantity-link').data('line-notes', notes);
47665
47666 		             messages = data['messages'];
47667
47668                             if (messages && messages !== '') {
47669                               alert(messages);
47670                             }  
47671
47672                             location.reload();
47673                           });
47674  };
47675
47676  var init = function() {
47677    $(document).on('click', '.qty-notes-submit', submitDialog);
47678  };
47679
47680  return {
47681    init : init
47682  };
47683}()));
47684var SuperCat = SuperCat || {};
47685SuperCat.EcatProducts = SuperCat.EcatProducts || {};
47686
47687function getUrlParameter(name) {
47688  name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
47689  var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
47690  var results = regex.exec(location.search);
47691  return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
47692};
47693
47694_.assign(SuperCat.EcatProducts, (function () {
47695  var submitDialog = function (evt) {
47696    evt.preventDefault();
47697    SuperCat.EcatQtyNotes.submitQtyNotesForm(evt,
47698                           function (data) {
47699                             messages = data['messages'];
47700
47701                             $('#order-preview-menu-item').show();
47702
47703                             if (messages && messages !== '') {
47704                               alert(messages);
47705                             }  
47706                           });
47707  };
47708
47709  var setWaypoints = function () {
47710    // var context = ($(window).width() > 900) ? document.getElementsByTagName('body')[0] : window;
47711    var waypoints = $('#my-waypoint').waypoint({
47712      handler: function(direction) {
47713        if (direction === 'down') {
47714          loadMore();
47715        }
47716      },
47717      offset: 'bottom-in-view'
47718    });
47719  };
47720
47721  var selectSearchField = function(){
47722    var query = getUrlParameter('query');
47723    if(!!query){ $('#query').select() }
47724  };
47725
47726  var page_num = 0;
47727  var load_more_url = null;
47728  var recaptchaToken;
47729
47730  var initializeLoadMore = function () {
47731    $('#catalog-load-more').click(loadMore);
47732
47733    var url = window.location.href;
47734
47735    if (url.match(".*[?].+$")) {
47736      // URL contains ? and something after it
47737      load_more_url = url + '&';
47738    } else if (url.match(".*[?]$")) {
47739      // URL ends in ? (odd, but possible I suppose)
47740      load_more_url = url;
47741    } else if (url.match(".*[#]$")) {
47742      // URL ends in # (left after closing Filters)
47743      load_more_url = url.replace('#', '?');
47744    } else {
47745      // URL doesn't contain ?
47746      load_more_url = url + '?';
47747    }
47748
47749    prepareReCaptchaParam();
47750  };
47751
47752  var prepareReCaptchaParam = function(){
47753    if(!!recaptchaToken){
47754      load_more_url = replaceUrlParam(load_more_url, 'recaptcha_token', recaptchaToken)
47755    }
47756  };
47757
47758  // If the param does not exist it will be added
47759  // If it exists it will be replaced
47760  // Other params in the URL are preserved
47761  var replaceUrlParam = function(url, paramName, paramValue){
47762    if (paramValue == null) {
47763      paramValue = '';
47764    }
47765    var pattern = new RegExp('\\b('+paramName+'=).*?(&|#|$)');
47766    if (url.search(pattern)>=0) {
47767      return url.replace(pattern,'$1' + paramValue + '$2');
47768    }
47769    url = url.replace(/[?#]$/,'');
47770    return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
47771  };
47772
47773  var loadMore = function () {
47774    $('#catalog-load-more').hide();
47775    $('#loading-button').show();
47776    page_num += 1;
47777    load_more_url = replaceUrlParam(load_more_url, 'page', page_num)
47778
47779    $.get(load_more_url).
47780      done(function (data) {
47781        obj = jQuery.parseJSON(data);
47782        $('ul.catalog-items').append(obj.html);
47783        if (obj.current_page < obj.total_pages) {
47784          $('#catalog-load-more').show();
47785        }
47786        $('#loading-button').hide();
47787
47788        // Reinitialize products since more are now added
47789        SUPERCAT.catalog.init();
47790
47791        Waypoint.refreshAll();
47792      })
47793  };
47794
47795  var setRecaptchaTokenValue = function(options){
47796    if(!!options){
47797      var reCaptchaTokenId = options['recaptcha_token_id']['id'];
47798      var selector         = '#'.concat(reCaptchaTokenId);
47799      recaptchaToken       = $(selector)[0].value;
47800    };
47801  };
47802
47803  var init = function(options){
47804    setRecaptchaTokenValue(options);
47805
47806    initializeLoadMore();
47807    setWaypoints();
47808    selectSearchField();
47809  };
47810
47811  return {
47812    init : init,
47813    submitDialog : submitDialog,
47814  };
47815}()));
47816var SUPERCAT = SUPERCAT || {};
47817
47818_.assign(SUPERCAT, (function() {
47819  var init = function() {
47820    $(document).on('click', '.menu-bar-form-submit', function(e) {
47821      e.preventDefault();
47822      if($(this).data('submitting') != 'true') {
47823        $(this).text('Submitting...')
47824               .css('opacity', .5)
47825               .data('submitting', 'true')
47826               .parents('.menu-bar-form').submit();
47827      }
47828    });
47829  };
47830
47831  init();
47832}()));
47833
47834
47835var SuperCat = SuperCat || {};
47836SuperCat.Login = SuperCat.Login || {};
47837
47838_.assign(SuperCat.Login, (function () {
47839
47840  var displayForm = function(){
47841    var urlParams = new URLSearchParams(window.location.search)
47842    var showForm  = urlParams.get('show');
47843
47844    if(showForm == 'forgot-password') {
47845      $('.login-form').addClass('is-hidden');
47846      $('.forgot-password-form').removeClass('is-hidden');
47847    }
47848  };
47849
47850  function initialize(){
47851    displayForm();
47852  };
47853
47854  return {
47855    initialize: initialize,
47856  };
47857}()));
47858/*!
47859Waypoints - 4.0.1
47860Copyright © 2011-2016 Caleb Troughton
47861Licensed under the MIT license.
47862https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
47863*/
47864
47865(function() {
47866  'use strict'
47867
47868  var keyCounter = 0
47869  var allWaypoints = {}
47870
47871  /* http://imakewebthings.com/waypoints/api/waypoint */
47872  function Waypoint(options) {
47873    if (!options) {
47874      throw new Error('No options passed to Waypoint constructor')
47875    }
47876    if (!options.element) {
47877      throw new Error('No element option passed to Waypoint constructor')
47878    }
47879    if (!options.handler) {
47880      throw new Error('No handler option passed to Waypoint constructor')
47881    }
47882
47883    this.key = 'waypoint-' + keyCounter
47884    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
47885    this.element = this.options.element
47886    this.adapter = new Waypoint.Adapter(this.element)
47887    this.callback = options.handler
47888    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
47889    this.enabled = this.options.enabled
47890    this.triggerPoint = null
47891    this.group = Waypoint.Group.findOrCreate({
47892      name: this.options.group,
47893      axis: this.axis
47894    })
47895    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
47896
47897    if (Waypoint.offsetAliases[this.options.offset]) {
47898      this.options.offset = Waypoint.offsetAliases[this.options.offset]
47899    }
47900    this.group.add(this)
47901    this.context.add(this)
47902    allWaypoints[this.key] = this
47903    keyCounter += 1
47904  }
47905
47906  /* Private */
47907  Waypoint.prototype.queueTrigger = function(direction) {
47908    this.group.queueTrigger(this, direction)
47909  }
47910
47911  /* Private */
47912  Waypoint.prototype.trigger = function(args) {
47913    if (!this.enabled) {
47914      return
47915    }
47916    if (this.callback) {
47917      this.callback.apply(this, args)
47918    }
47919  }
47920
47921  /* Public */
47922  /* http://imakewebthings.com/waypoints/api/destroy */
47923  Waypoint.prototype.destroy = function() {
47924    this.context.remove(this)
47925    this.group.remove(this)
47926    delete allWaypoints[this.key]
47927  }
47928
47929  /* Public */
47930  /* http://imakewebthings.com/waypoints/api/disable */
47931  Waypoint.prototype.disable = function() {
47932    this.enabled = false
47933    return this
47934  }
47935
47936  /* Public */
47937  /* http://imakewebthings.com/waypoints/api/enable */
47938  Waypoint.prototype.enable = function() {
47939    this.context.refresh()
47940    this.enabled = true
47941    return this
47942  }
47943
47944  /* Public */
47945  /* http://imakewebthings.com/waypoints/api/next */
47946  Waypoint.prototype.next = function() {
47947    return this.group.next(this)
47948  }
47949
47950  /* Public */
47951  /* http://imakewebthings.com/waypoints/api/previous */
47952  Waypoint.prototype.previous = function() {
47953    return this.group.previous(this)
47954  }
47955
47956  /* Private */
47957  Waypoint.invokeAll = function(method) {
47958    var allWaypointsArray = []
47959    for (var waypointKey in allWaypoints) {
47960      allWaypointsArray.push(allWaypoints[waypointKey])
47961    }
47962    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
47963      allWaypointsArray[i][method]()
47964    }
47965  }
47966
47967  /* Public */
47968  /* http://imakewebthings.com/waypoints/api/destroy-all */
47969  Waypoint.destroyAll = function() {
47970    Waypoint.invokeAll('destroy')
47971  }
47972
47973  /* Public */
47974  /* http://imakewebthings.com/waypoints/api/disable-all */
47975  Waypoint.disableAll = function() {
47976    Waypoint.invokeAll('disable')
47977  }
47978
47979  /* Public */
47980  /* http://imakewebthings.com/waypoints/api/enable-all */
47981  Waypoint.enableAll = function() {
47982    Waypoint.Context.refreshAll()
47983    for (var waypointKey in allWaypoints) {
47984      allWaypoints[waypointKey].enabled = true
47985    }
47986    return this
47987  }
47988
47989  /* Public */
47990  /* http://imakewebthings.com/waypoints/api/refresh-all */
47991  Waypoint.refreshAll = function() {
47992    Waypoint.Context.refreshAll()
47993  }
47994
47995  /* Public */
47996  /* http://imakewebthings.com/waypoints/api/viewport-height */
47997  Waypoint.viewportHeight = function() {
47998    return window.innerHeight || document.documentElement.clientHeight
47999  }
48000
48001  /* Public */
48002  /* http://imakewebthings.com/waypoints/api/viewport-width */
48003  Waypoint.viewportWidth = function() {
48004    return document.documentElement.clientWidth
48005  }
48006
48007  Waypoint.adapters = []
48008
48009  Waypoint.defaults = {
48010    context: window,
48011    continuous: true,
48012    enabled: true,
48013    group: 'default',
48014    horizontal: false,
48015    offset: 0
48016  }
48017
48018  Waypoint.offsetAliases = {
48019    'bottom-in-view': function() {
48020      return this.context.innerHeight() - this.adapter.outerHeight()
48021    },
48022    'right-in-view': function() {
48023      return this.context.innerWidth() - this.adapter.outerWidth()
48024    }
48025  }
48026
48027  window.Waypoint = Waypoint
48028}())
48029;(function() {
48030  'use strict'
48031
48032  function requestAnimationFrameShim(callback) {
48033    window.setTimeout(callback, 1000 / 60)
48034  }
48035
48036  var keyCounter = 0
48037  var contexts = {}
48038  var Waypoint = window.Waypoint
48039  var oldWindowLoad = window.onload
48040
48041  /* http://imakewebthings.com/waypoints/api/context */
48042  function Context(element) {
48043    this.element = element
48044    this.Adapter = Waypoint.Adapter
48045    this.adapter = new this.Adapter(element)
48046    this.key = 'waypoint-context-' + keyCounter
48047    this.didScroll = false
48048    this.didResize = false
48049    this.oldScroll = {
48050      x: this.adapter.scrollLeft(),
48051      y: this.adapter.scrollTop()
48052    }
48053    this.waypoints = {
48054      vertical: {},
48055      horizontal: {}
48056    }
48057
48058    element.waypointContextKey = this.key
48059    contexts[element.waypointContextKey] = this
48060    keyCounter += 1
48061    if (!Waypoint.windowContext) {
48062      Waypoint.windowContext = true
48063      Waypoint.windowContext = new Context(window)
48064    }
48065
48066    this.createThrottledScrollHandler()
48067    this.createThrottledResizeHandler()
48068  }
48069
48070  /* Private */
48071  Context.prototype.add = function(waypoint) {
48072    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
48073    this.waypoints[axis][waypoint.key] = waypoint
48074    this.refresh()
48075  }
48076
48077  /* Private */
48078  Context.prototype.checkEmpty = function() {
48079    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
48080    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
48081    var isWindow = this.element == this.element.window
48082    if (horizontalEmpty && verticalEmpty && !isWindow) {
48083      this.adapter.off('.waypoints')
48084      delete contexts[this.key]
48085    }
48086  }
48087
48088  /* Private */
48089  Context.prototype.createThrottledResizeHandler = function() {
48090    var self = this
48091
48092    function resizeHandler() {
48093      self.handleResize()
48094      self.didResize = false
48095    }
48096
48097    this.adapter.on('resize.waypoints', function() {
48098      if (!self.didResize) {
48099        self.didResize = true
48100        Waypoint.requestAnimationFrame(resizeHandler)
48101      }
48102    })
48103  }
48104
48105  /* Private */
48106  Context.prototype.createThrottledScrollHandler = function() {
48107    var self = this
48108    function scrollHandler() {
48109      self.handleScroll()
48110      self.didScroll = false
48111    }
48112
48113    this.adapter.on('scroll.waypoints', function() {
48114      if (!self.didScroll || Waypoint.isTouch) {
48115        self.didScroll = true
48116        Waypoint.requestAnimationFrame(scrollHandler)
48117      }
48118    })
48119  }
48120
48121  /* Private */
48122  Context.prototype.handleResize = function() {
48123    Waypoint.Context.refreshAll()
48124  }
48125
48126  /* Private */
48127  Context.prototype.handleScroll = function() {
48128    var triggeredGroups = {}
48129    var axes = {
48130      horizontal: {
48131        newScroll: this.adapter.scrollLeft(),
48132        oldScroll: this.oldScroll.x,
48133        forward: 'right',
48134        backward: 'left'
48135      },
48136      vertical: {
48137        newScroll: this.adapter.scrollTop(),
48138        oldScroll: this.oldScroll.y,
48139        forward: 'down',
48140        backward: 'up'
48141      }
48142    }
48143
48144    for (var axisKey in axes) {
48145      var axis = axes[axisKey]
48146      var isForward = axis.newScroll > axis.oldScroll
48147      var direction = isForward ? axis.forward : axis.backward
48148
48149      for (var waypointKey in this.waypoints[axisKey]) {
48150        var waypoint = this.waypoints[axisKey][waypointKey]
48151        if (waypoint.triggerPoint === null) {
48152          continue
48153        }
48154        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
48155        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
48156        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
48157        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
48158        if (crossedForward || crossedBackward) {
48159          waypoint.queueTrigger(direction)
48160          triggeredGroups[waypoint.group.id] = waypoint.group
48161        }
48162      }
48163    }
48164
48165    for (var groupKey in triggeredGroups) {
48166      triggeredGroups[groupKey].flushTriggers()
48167    }
48168
48169    this.oldScroll = {
48170      x: axes.horizontal.newScroll,
48171      y: axes.vertical.newScroll
48172    }
48173  }
48174
48175  /* Private */
48176  Context.prototype.innerHeight = function() {
48177    /*eslint-disable eqeqeq */
48178    if (this.element == this.element.window) {
48179      return Waypoint.viewportHeight()
48180    }
48181    /*eslint-enable eqeqeq */
48182    return this.adapter.innerHeight()
48183  }
48184
48185  /* Private */
48186  Context.prototype.remove = function(waypoint) {
48187    delete this.waypoints[waypoint.axis][waypoint.key]
48188    this.checkEmpty()
48189  }
48190
48191  /* Private */
48192  Context.prototype.innerWidth = function() {
48193    /*eslint-disable eqeqeq */
48194    if (this.element == this.element.window) {
48195      return Waypoint.viewportWidth()
48196    }
48197    /*eslint-enable eqeqeq */
48198    return this.adapter.innerWidth()
48199  }
48200
48201  /* Public */
48202  /* http://imakewebthings.com/waypoints/api/context-destroy */
48203  Context.prototype.destroy = function() {
48204    var allWaypoints = []
48205    for (var axis in this.waypoints) {
48206      for (var waypointKey in this.waypoints[axis]) {
48207        allWaypoints.push(this.waypoints[axis][waypointKey])
48208      }
48209    }
48210    for (var i = 0, end = allWaypoints.length; i < end; i++) {
48211      allWaypoints[i].destroy()
48212    }
48213  }
48214
48215  /* Public */
48216  /* http://imakewebthings.com/waypoints/api/context-refresh */
48217  Context.prototype.refresh = function() {
48218    /*eslint-disable eqeqeq */
48219    var isWindow = this.element == this.element.window
48220    /*eslint-enable eqeqeq */
48221    var contextOffset = isWindow ? undefined : this.adapter.offset()
48222    var triggeredGroups = {}
48223    var axes
48224
48225    this.handleScroll()
48226    axes = {
48227      horizontal: {
48228        contextOffset: isWindow ? 0 : contextOffset.left,
48229        contextScroll: isWindow ? 0 : this.oldScroll.x,
48230        contextDimension: this.innerWidth(),
48231        oldScroll: this.oldScroll.x,
48232        forward: 'right',
48233        backward: 'left',
48234        offsetProp: 'left'
48235      },
48236      vertical: {
48237        contextOffset: isWindow ? 0 : contextOffset.top,
48238        contextScroll: isWindow ? 0 : this.oldScroll.y,
48239        contextDimension: this.innerHeight(),
48240        oldScroll: this.oldScroll.y,
48241        forward: 'down',
48242        backward: 'up',
48243        offsetProp: 'top'
48244      }
48245    }
48246
48247    for (var axisKey in axes) {
48248      var axis = axes[axisKey]
48249      for (var waypointKey in this.waypoints[axisKey]) {
48250        var waypoint = this.waypoints[axisKey][waypointKey]
48251        var adjustment = waypoint.options.offset
48252        var oldTriggerPoint = waypoint.triggerPoint
48253        var elementOffset = 0
48254        var freshWaypoint = oldTriggerPoint == null
48255        var contextModifier, wasBeforeScroll, nowAfterScroll
48256        var triggeredBackward, triggeredForward
48257
48258        if (waypoint.element !== waypoint.element.window) {
48259          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
48260        }
48261
48262        if (typeof adjustment === 'function') {
48263          adjustment = adjustment.apply(waypoint)
48264        }
48265        else if (typeof adjustment === 'string') {
48266          adjustment = parseFloat(adjustment)
48267          if (waypoint.options.offset.indexOf('%') > - 1) {
48268            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
48269          }
48270        }
48271
48272        contextModifier = axis.contextScroll - axis.contextOffset
48273        waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
48274        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
48275        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
48276        triggeredBackward = wasBeforeScroll && nowAfterScroll
48277        triggeredForward = !wasBeforeScroll && !nowAfterScroll
48278
48279        if (!freshWaypoint && triggeredBackward) {
48280          waypoint.queueTrigger(axis.backward)
48281          triggeredGroups[waypoint.group.id] = waypoint.group
48282        }
48283        else if (!freshWaypoint && triggeredForward) {
48284          waypoint.queueTrigger(axis.forward)
48285          triggeredGroups[waypoint.group.id] = waypoint.group
48286        }
48287        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
48288          waypoint.queueTrigger(axis.forward)
48289          triggeredGroups[waypoint.group.id] = waypoint.group
48290        }
48291      }
48292    }
48293
48294    Waypoint.requestAnimationFrame(function() {
48295      for (var groupKey in triggeredGroups) {
48296        triggeredGroups[groupKey].flushTriggers()
48297      }
48298    })
48299
48300    return this
48301  }
48302
48303  /* Private */
48304  Context.findOrCreateByElement = function(element) {
48305    return Context.findByElement(element) || new Context(element)
48306  }
48307
48308  /* Private */
48309  Context.refreshAll = function() {
48310    for (var contextId in contexts) {
48311      contexts[contextId].refresh()
48312    }
48313  }
48314
48315  /* Public */
48316  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
48317  Context.findByElement = function(element) {
48318    return contexts[element.waypointContextKey]
48319  }
48320
48321  window.onload = function() {
48322    if (oldWindowLoad) {
48323      oldWindowLoad()
48324    }
48325    Context.refreshAll()
48326  }
48327
48328
48329  Waypoint.requestAnimationFrame = function(callback) {
48330    var requestFn = window.requestAnimationFrame ||
48331      window.mozRequestAnimationFrame ||
48332      window.webkitRequestAnimationFrame ||
48333      requestAnimationFrameShim
48334    requestFn.call(window, callback)
48335  }
48336  Waypoint.Context = Context
48337}())
48338;(function() {
48339  'use strict'
48340
48341  function byTriggerPoint(a, b) {
48342    return a.triggerPoint - b.triggerPoint
48343  }
48344
48345  function byReverseTriggerPoint(a, b) {
48346    return b.triggerPoint - a.triggerPoint
48347  }
48348
48349  var groups = {
48350    vertical: {},
48351    horizontal: {}
48352  }
48353  var Waypoint = window.Waypoint
48354
48355  /* http://imakewebthings.com/waypoints/api/group */
48356  function Group(options) {
48357    this.name = options.name
48358    this.axis = options.axis
48359    this.id = this.name + '-' + this.axis
48360    this.waypoints = []
48361    this.clearTriggerQueues()
48362    groups[this.axis][this.name] = this
48363  }
48364
48365  /* Private */
48366  Group.prototype.add = function(waypoint) {
48367    this.waypoints.push(waypoint)
48368  }
48369
48370  /* Private */
48371  Group.prototype.clearTriggerQueues = function() {
48372    this.triggerQueues = {
48373      up: [],
48374      down: [],
48375      left: [],
48376      right: []
48377    }
48378  }
48379
48380  /* Private */
48381  Group.prototype.flushTriggers = function() {
48382    for (var direction in this.triggerQueues) {
48383      var waypoints = this.triggerQueues[direction]
48384      var reverse = direction === 'up' || direction === 'left'
48385      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
48386      for (var i = 0, end = waypoints.length; i < end; i += 1) {
48387        var waypoint = waypoints[i]
48388        if (waypoint.options.continuous || i === waypoints.length - 1) {
48389          waypoint.trigger([direction])
48390        }
48391      }
48392    }
48393    this.clearTriggerQueues()
48394  }
48395
48396  /* Private */
48397  Group.prototype.next = function(waypoint) {
48398    this.waypoints.sort(byTriggerPoint)
48399    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
48400    var isLast = index === this.waypoints.length - 1
48401    return isLast ? null : this.waypoints[index + 1]
48402  }
48403
48404  /* Private */
48405  Group.prototype.previous = function(waypoint) {
48406    this.waypoints.sort(byTriggerPoint)
48407    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
48408    return index ? this.waypoints[index - 1] : null
48409  }
48410
48411  /* Private */
48412  Group.prototype.queueTrigger = function(waypoint, direction) {
48413    this.triggerQueues[direction].push(waypoint)
48414  }
48415
48416  /* Private */
48417  Group.prototype.remove = function(waypoint) {
48418    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
48419    if (index > -1) {
48420      this.waypoints.splice(index, 1)
48421    }
48422  }
48423
48424  /* Public */
48425  /* http://imakewebthings.com/waypoints/api/first */
48426  Group.prototype.first = function() {
48427    return this.waypoints[0]
48428  }
48429
48430  /* Public */
48431  /* http://imakewebthings.com/waypoints/api/last */
48432  Group.prototype.last = function() {
48433    return this.waypoints[this.waypoints.length - 1]
48434  }
48435
48436  /* Private */
48437  Group.findOrCreate = function(options) {
48438    return groups[options.axis][options.name] || new Group(options)
48439  }
48440
48441  Waypoint.Group = Group
48442}())
48443;(function() {
48444  'use strict'
48445
48446  var $ = window.jQuery
48447  var Waypoint = window.Waypoint
48448
48449  function JQueryAdapter(element) {
48450    this.$element = $(element)
48451  }
48452
48453  $.each([
48454    'innerHeight',
48455    'innerWidth',
48456    'off',
48457    'offset',
48458    'on',
48459    'outerHeight',
48460    'outerWidth',
48461    'scrollLeft',
48462    'scrollTop'
48463  ], function(i, method) {
48464    JQueryAdapter.prototype[method] = function() {
48465      var args = Array.prototype.slice.call(arguments)
48466      return this.$element[method].apply(this.$element, args)
48467    }
48468  })
48469
48470  $.each([
48471    'extend',
48472    'inArray',
48473    'isEmptyObject'
48474  ], function(i, method) {
48475    JQueryAdapter[method] = $[method]
48476  })
48477
48478  Waypoint.adapters.push({
48479    name: 'jquery',
48480    Adapter: JQueryAdapter
48481  })
48482  Waypoint.Adapter = JQueryAdapter
48483}())
48484;(function() {
48485  'use strict'
48486
48487  var Waypoint = window.Waypoint
48488
48489  function createExtension(framework) {
48490    return function() {
48491      var waypoints = []
48492      var overrides = arguments[0]
48493
48494      if (framework.isFunction(arguments[0])) {
48495        overrides = framework.extend({}, arguments[1])
48496        overrides.handler = arguments[0]
48497      }
48498
48499      this.each(function() {
48500        var options = framework.extend({}, overrides, {
48501          element: this
48502        })
48503        if (typeof options.context === 'string') {
48504          options.context = framework(this).closest(options.context)[0]
48505        }
48506        waypoints.push(new Waypoint(options))
48507      })
48508
48509      return waypoints
48510    }
48511  }
48512
48513  if (window.jQuery) {
48514    window.jQuery.fn.waypoint = createExtension(window.jQuery)
48515  }
48516  if (window.Zepto) {
48517    window.Zepto.fn.waypoint = createExtension(window.Zepto)
48518  }
48519}())
48520;
48521/*!
48522Waypoints Infinite Scroll Shortcut - 4.0.1
48523Copyright © 2011-2016 Caleb Troughton
48524Licensed under the MIT license.
48525https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
48526*/
48527
48528(function() {
48529  'use strict'
48530
48531  var $ = window.jQuery
48532  var Waypoint = window.Waypoint
48533
48534  /* http://imakewebthings.com/waypoints/shortcuts/infinite-scroll */
48535  function Infinite(options) {
48536    this.options = $.extend({}, Infinite.defaults, options)
48537    this.container = this.options.element
48538    if (this.options.container !== 'auto') {
48539      this.container = this.options.container
48540    }
48541    this.$container = $(this.container)
48542    this.$more = $(this.options.more)
48543
48544    if (this.$more.length) {
48545      this.setupHandler()
48546      this.waypoint = new Waypoint(this.options)
48547    }
48548  }
48549
48550  /* Private */
48551  Infinite.prototype.setupHandler = function() {
48552    this.options.handler = $.proxy(function() {
48553      this.options.onBeforePageLoad()
48554      this.destroy()
48555      this.$container.addClass(this.options.loadingClass)
48556
48557      $.get($(this.options.more).attr('href'), $.proxy(function(data) {
48558        var $data = $($.parseHTML(data))
48559        var $newMore = $data.find(this.options.more)
48560
48561        var $items = $data.find(this.options.items)
48562        if (!$items.length) {
48563          $items = $data.filter(this.options.items)
48564        }
48565
48566        this.$container.append($items)
48567        this.$container.removeClass(this.options.loadingClass)
48568
48569        if (!$newMore.length) {
48570          $newMore = $data.filter(this.options.more)
48571        }
48572        if ($newMore.length) {
48573          this.$more.replaceWith($newMore)
48574          this.$more = $newMore
48575          this.waypoint = new Waypoint(this.options)
48576        }
48577        else {
48578          this.$more.remove()
48579        }
48580
48581        this.options.onAfterPageLoad($items)
48582      }, this))
48583    }, this)
48584  }
48585
48586  /* Public */
48587  Infinite.prototype.destroy = function() {
48588    if (this.waypoint) {
48589      this.waypoint.destroy()
48590    }
48591  }
48592
48593  Infinite.defaults = {
48594    container: 'auto',
48595    items: '.infinite-item',
48596    more: '.infinite-more-link',
48597    offset: 'bottom-in-view',
48598    loadingClass: 'infinite-loading',
48599    onBeforePageLoad: $.noop,
48600    onAfterPageLoad: $.noop
48601  }
48602
48603  Waypoint.Infinite = Infinite
48604}())
48605;
48606var SuperCat = SuperCat || {};
48607SuperCat.SocialMediaButtons = SuperCat.SocialMediaButtons || {};
48608
48609_.assign(SuperCat.SocialMediaButtons, (function () {
48610  var reloadTwitter = function(){
48611    if($('#twitter-btn a span').length == 0){
48612      $.ajax({ url: 'https://platform.twitter.com/widgets.js', dataType: 'script', cache: true});
48613    }
48614  };
48615
48616  var reloadPinterest = function(){
48617    if(typeof(window.parsePinBtns) == 'function'){
48618      window.parsePinBtns(document.getElementById('pinterest-btn'));
48619    }
48620  };
48621
48622  var reloadFacebook = function(){
48623    if(typeof(FB) == 'object'){ FB.XFBML.parse(); }
48624  };
48625
48626  var initializeTwitter = function(){
48627    window.twttr = (function(d, s, id) {
48628      var js, fjs = d.getElementsByTagName(s)[0],
48629        t = window.twttr || {};
48630      if (d.getElementById(id)) return t;
48631      js = d.createElement(s);
48632      js.id = id;
48633      js.src = "https://platform.twitter.com/widgets.js";
48634      fjs.parentNode.insertBefore(js, fjs);
48635
48636      t._e = [];
48637      t.ready = function(f) {
48638        t._e.push(f);
48639      };
48640
48641      return t;
48642    }(document, "script", "twitter-wjs"));
48643  };
48644
48645  var initializePinterest = function(){
48646    (function(d){
48647      var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
48648      p.type = 'text/javascript';
48649      p.async = true;
48650      p.src = '//assets.pinterest.com/js/pinit.js';
48651      p.setAttribute('data-pin-build', 'parsePinBtns');
48652      f.parentNode.insertBefore(p, f);
48653    }(document));
48654  };
48655
48656  var initializeFacebook = function(){
48657    (function(d, s, id) {
48658      var js, fjs = d.getElementsByTagName(s)[0];
48659      if (d.getElementById(id)) return;
48660      js = d.createElement(s); js.id = id;
48661      js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.0";
48662      fjs.parentNode.insertBefore(js, fjs);
48663    }(document, 'script', 'facebook-jssdk'));
48664  };
48665
48666  var reload = function(options) {
48667    if(options["facebook"]){ reloadFacebook(); }
48668    if(options["twitter"]){ reloadTwitter(); }
48669    if(options["pinterest"]){ reloadPinterest(); }
48670  };
48671
48672  return {
48673    initializeTwitter: initializeTwitter,
48674    initializeFacebook: initializeFacebook,
48675    initializePinterest: initializePinterest,
48676    reload : reload
48677  };
48678}()));
48679var SuperCat = SuperCat || {};
48680SuperCat.PhotosColumn = SuperCat.PhotosColumn || {};
48681
48682_.assign(SuperCat.PhotosColumn, (function () {
48683  var state;
48684  var ordersLink;
48685  var invoicesLink;
48686  var baseUrl;
48687
48688  var toggleStateValue = {
48689    'true'  : 'false',
48690    'false' : 'true',
48691  };
48692  var toggleLinkText = {
48693    'hide' : 'Hide photos',
48694    'show' : 'Show photos',
48695  };
48696
48697  function toggleState(){
48698    state = toggleStateValue[state];
48699  };
48700
48701  function toggleColumn(){
48702    $('.item-photo').toggle();
48703  };
48704
48705  function toggleLink(selector){
48706    if($('.item-photo').css('display') == 'none'){
48707      state = 'false';
48708      $(selector).text(toggleLinkText['show']);
48709    } else {
48710      state = 'true';
48711      $(selector).text(toggleLinkText['hide']);
48712    }
48713  };
48714
48715  function toggleDOMElements(selector){
48716    $.when(toggleColumn()).done(toggleLink(selector));
48717  };
48718
48719  function updateSessionValue(){
48720    $.post(baseUrl, {state: state}, function(response) {
48721      // This is almost impossible to happen,
48722      // but if so, revert links and status
48723      if(response.status != 'ok'){
48724        toggleColumn();
48725        toggleLink();
48726        toggleState();
48727      }
48728    })
48729    .fail(function(){
48730      toggleState();
48731    });
48732  };
48733
48734  function bindClickEventForSelector(element){
48735    if(!!element){
48736      var selector = '.' + element.selector;
48737
48738      $(document).on('click', selector, function(event) {
48739        event.preventDefault();
48740        toggleDOMElements(selector);
48741        updateSessionValue();
48742      });
48743    }
48744  };
48745
48746  function initialize(options){
48747    state        = options.initialState;
48748    ordersLink   = options.ordersLink;
48749    invoicesLink = options.invoicesLink;
48750    baseUrl      = options.baseUrl;
48751
48752    bindClickEventForSelector(ordersLink);
48753    bindClickEventForSelector(invoicesLink);
48754  };
48755
48756  return {
48757    initialize: initialize,
48758  }
48759}()));
48760var SuperCat = SuperCat || {};
48761SuperCat.ProductPhotos = SuperCat.ProductPhotos || {};
48762
48763_.assign(SuperCat.ProductPhotos, (function () {
48764
48765  function initPhotosCarousel() {
48766    const photosWrapper = document.querySelector('.item-images-alt-wrapper');
48767    if (!photosWrapper) return;
48768
48769    const photosScroller = photosWrapper.querySelector('.item-images-alt');
48770    const nextBtn = photosWrapper.querySelector('.scroll-next');
48771    const prevBtn = photosWrapper.querySelector('.scroll-prev');
48772
48773    nextBtn.addEventListener('click', scrollToNextItem);
48774    prevBtn.addEventListener('click', scrollToPrevItem);
48775
48776    if (photosScroller.scrollHeight <= photosWrapper.clientHeight && photosScroller.scrollWidth <= photosWrapper.clientWidth) {
48777      nextBtn.style.display = 'none';
48778      prevBtn.style.display = 'none';
48779    }
48780  };
48781
48782  function scrollToNextItem() {
48783    const photosScroller = document.querySelector('.item-images-alt');
48784    const scrollerWidth = photosScroller.clientWidth;
48785    const itemWidth = photosScroller.querySelector('.item-images-alt-thumb').clientWidth;
48786    const distance = itemWidth;
48787
48788    if (photosScroller.scrollWidth > photosScroller.scrollHeight) {
48789      photosScroller.scrollBy({left: distance, top: 0, behavior: 'smooth'});
48790    } else {
48791      photosScroller.scrollBy({left: 0, top: distance, behavior: 'smooth'});
48792    }
48793  };
48794
48795  function scrollToPrevItem() {
48796    const photosScroller = document.querySelector('.item-images-alt');
48797    const scrollerWidth = photosScroller.clientWidth;
48798    const itemWidth = photosScroller.querySelector('.item-images-alt-thumb').clientWidth;
48799    const distance = -1*itemWidth;
48800
48801    if (photosScroller.scrollWidth > photosScroller.scrollHeight) {
48802      photosScroller.scrollBy({left: distance, top: 0, behavior: 'smooth'});
48803    } else {
48804      photosScroller.scrollBy({left: 0, top: distance, behavior: 'smooth'});
48805    }
48806  };
48807
48808  return {
48809    initPhotosCarousel: initPhotosCarousel,
48810    scrollToNextItem: scrollToNextItem,
48811    scrollToPrevItem: scrollToPrevItem
48812  };
48813}()));
48814window.$ = window.$ || {};(function() { if ($ && $.fn && $.fn.select2 && $.fn.select2.amd) { define = $.fn.select2.amd.define; require = $.fn.select2.amd.require; }/**
48815 * @license almond 0.2.9 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
48816 * Available via the MIT or new BSD license.
48817 * see: http://github.com/jrburke/almond for details
48818 */
48819//Going sloppy to avoid 'use strict' string cost, but strict practices should
48820//be followed.
48821/*jslint sloppy: true */
48822/*global setTimeout: false */
48823
48824var requirejs, require, define;
48825(function (undef) {
48826    var main, req, makeMap, handlers,
48827        defined = {},
48828        waiting = {},
48829        config = {},
48830        defining = {},
48831        hasOwn = Object.prototype.hasOwnProperty,
48832        aps = [].slice,
48833        jsSuffixRegExp = /\.js$/;
48834
48835    function hasProp(obj, prop) {
48836        return hasOwn.call(obj, prop);
48837    }
48838
48839    /**
48840     * Given a relative module name, like ./something, normalize it to
48841     * a real name that can be mapped to a path.
48842     * @param {String} name the relative name
48843     * @param {String} baseName a real name that the name arg is relative
48844     * to.
48845     * @returns {String} normalized name
48846     */
48847    function normalize(name, baseName) {
48848        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
48849            foundI, foundStarMap, starI, i, j, part,
48850            baseParts = baseName && baseName.split("/"),
48851            map = config.map,
48852            starMap = (map && map['*']) || {};
48853
48854        //Adjust any relative paths.
48855        if (name && name.charAt(0) === ".") {
48856            //If have a base name, try to normalize against it,
48857            //otherwise, assume it is a top-level require that will
48858            //be relative to baseUrl in the end.
48859            if (baseName) {
48860                //Convert baseName to array, and lop off the last part,
48861                //so that . matches that "directory" and not name of the baseName's
48862                //module. For instance, baseName of "one/two/three", maps to
48863                //"one/two/three.js", but we want the directory, "one/two" for
48864                //this normalization.
48865                baseParts = baseParts.slice(0, baseParts.length - 1);
48866                name = name.split('/');
48867                lastIndex = name.length - 1;
48868
48869                // Node .js allowance:
48870                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
48871                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
48872                }
48873
48874                name = baseParts.concat(name);
48875
48876                //start trimDots
48877                for (i = 0; i < name.length; i += 1) {
48878                    part = name[i];
48879                    if (part === ".") {
48880                        name.splice(i, 1);
48881                        i -= 1;
48882                    } else if (part === "..") {
48883                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {
48884                            //End of the line. Keep at least one non-dot
48885                            //path segment at the front so it can be mapped
48886                            //correctly to disk. Otherwise, there is likely
48887                            //no path mapping for a path starting with '..'.
48888                            //This can still fail, but catches the most reasonable
48889                            //uses of ..
48890                            break;
48891                        } else if (i > 0) {
48892                            name.splice(i - 1, 2);
48893                            i -= 2;
48894                        }
48895                    }
48896                }
48897                //end trimDots
48898
48899                name = name.join("/");
48900            } else if (name.indexOf('./') === 0) {
48901                // No baseName, so this is ID is resolved relative
48902                // to baseUrl, pull off the leading dot.
48903                name = name.substring(2);
48904            }
48905        }
48906
48907        //Apply map config if available.
48908        if ((baseParts || starMap) && map) {
vendor: 8,533 bytes, lines 48909-49154
48909            nameParts = name.split('/');
48910
48911            for (i = nameParts.length; i > 0; i -= 1) {
48912                nameSegment = nameParts.slice(0, i).join("/");
48913
48914                if (baseParts) {
48915                    //Find the longest baseName segment match in the config.
48916                    //So, do joins on the biggest to smallest lengths of baseParts.
48917                    for (j = baseParts.length; j > 0; j -= 1) {
48918                        mapValue = map[baseParts.slice(0, j).join('/')];
48919
48920                        //baseName segment has  config, find if it has one for
48921                        //this name.
48922                        if (mapValue) {
48923                            mapValue = mapValue[nameSegment];
48924                            if (mapValue) {
48925                                //Match, update name to the new value.
48926                                foundMap = mapValue;
48927                                foundI = i;
48928                                break;
48929                            }
48930                        }
48931                    }
48932                }
48933
48934                if (foundMap) {
48935                    break;
48936                }
48937
48938                //Check for a star map match, but just hold on to it,
48939                //if there is a shorter segment match later in a matching
48940                //config, then favor over this star map.
48941                if (!foundStarMap && starMap && starMap[nameSegment]) {
48942                    foundStarMap = starMap[nameSegment];
48943                    starI = i;
48944                }
48945            }
48946
48947            if (!foundMap && foundStarMap) {
48948                foundMap = foundStarMap;
48949                foundI = starI;
48950            }
48951
48952            if (foundMap) {
48953                nameParts.splice(0, foundI, foundMap);
48954                name = nameParts.join('/');
48955            }
48956        }
48957
48958        return name;
48959    }
48960
48961    function makeRequire(relName, forceSync) {
48962        return function () {
48963            //A version of a require function that passes a moduleName
48964            //value for items that may need to
48965            //look up paths relative to the moduleName
48966            return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));
48967        };
48968    }
48969
48970    function makeNormalize(relName) {
48971        return function (name) {
48972            return normalize(name, relName);
48973        };
48974    }
48975
48976    function makeLoad(depName) {
48977        return function (value) {
48978            defined[depName] = value;
48979        };
48980    }
48981
48982    function callDep(name) {
48983        if (hasProp(waiting, name)) {
48984            var args = waiting[name];
48985            delete waiting[name];
48986            defining[name] = true;
48987            main.apply(undef, args);
48988        }
48989
48990        if (!hasProp(defined, name) && !hasProp(defining, name)) {
48991            throw new Error('No ' + name);
48992        }
48993        return defined[name];
48994    }
48995
48996    //Turns a plugin!resource to [plugin, resource]
48997    //with the plugin being undefined if the name
48998    //did not have a plugin prefix.
48999    function splitPrefix(name) {
49000        var prefix,
49001            index = name ? name.indexOf('!') : -1;
49002        if (index > -1) {
49003            prefix = name.substring(0, index);
49004            name = name.substring(index + 1, name.length);
49005        }
49006        return [prefix, name];
49007    }
49008
49009    /**
49010     * Makes a name map, normalizing the name, and using a plugin
49011     * for normalization if necessary. Grabs a ref to plugin
49012     * too, as an optimization.
49013     */
49014    makeMap = function (name, relName) {
49015        var plugin,
49016            parts = splitPrefix(name),
49017            prefix = parts[0];
49018
49019        name = parts[1];
49020
49021        if (prefix) {
49022            prefix = normalize(prefix, relName);
49023            plugin = callDep(prefix);
49024        }
49025
49026        //Normalize according
49027        if (prefix) {
49028            if (plugin && plugin.normalize) {
49029                name = plugin.normalize(name, makeNormalize(relName));
49030            } else {
49031                name = normalize(name, relName);
49032            }
49033        } else {
49034            name = normalize(name, relName);
49035            parts = splitPrefix(name);
49036            prefix = parts[0];
49037            name = parts[1];
49038            if (prefix) {
49039                plugin = callDep(prefix);
49040            }
49041        }
49042
49043        //Using ridiculous property names for space reasons
49044        return {
49045            f: prefix ? prefix + '!' + name : name, //fullName
49046            n: name,
49047            pr: prefix,
49048            p: plugin
49049        };
49050    };
49051
49052    function makeConfig(name) {
49053        return function () {
49054            return (config && config.config && config.config[name]) || {};
49055        };
49056    }
49057
49058    handlers = {
49059        require: function (name) {
49060            return makeRequire(name);
49061        },
49062        exports: function (name) {
49063            var e = defined[name];
49064            if (typeof e !== 'undefined') {
49065                return e;
49066            } else {
49067                return (defined[name] = {});
49068            }
49069        },
49070        module: function (name) {
49071            return {
49072                id: name,
49073                uri: '',
49074                exports: defined[name],
49075                config: makeConfig(name)
49076            };
49077        }
49078    };
49079
49080    main = function (name, deps, callback, relName) {
49081        var cjsModule, depName, ret, map, i,
49082            args = [],
49083            callbackType = typeof callback,
49084            usingExports;
49085
49086        //Use name if no relName
49087        relName = relName || name;
49088
49089        //Call the callback to define the module, if necessary.
49090        if (callbackType === 'undefined' || callbackType === 'function') {
49091            //Pull out the defined dependencies and pass the ordered
49092            //values to the callback.
49093            //Default to [require, exports, module] if no deps
49094            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
49095            for (i = 0; i < deps.length; i += 1) {
49096                map = makeMap(deps[i], relName);
49097                depName = map.f;
49098
49099                //Fast path CommonJS standard dependencies.
49100                if (depName === "require") {
49101                    args[i] = handlers.require(name);
49102                } else if (depName === "exports") {
49103                    //CommonJS module spec 1.1
49104                    args[i] = handlers.exports(name);
49105                    usingExports = true;
49106                } else if (depName === "module") {
49107                    //CommonJS module spec 1.1
49108                    cjsModule = args[i] = handlers.module(name);
49109                } else if (hasProp(defined, depName) ||
49110                           hasProp(waiting, depName) ||
49111                           hasProp(defining, depName)) {
49112                    args[i] = callDep(depName);
49113                } else if (map.p) {
49114                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
49115                    args[i] = defined[depName];
49116                } else {
49117                    throw new Error(name + ' missing ' + depName);
49118                }
49119            }
49120
49121            ret = callback ? callback.apply(defined[name], args) : undefined;
49122
49123            if (name) {
49124                //If setting exports via "module" is in play,
49125                //favor that over return value and exports. After that,
49126                //favor a non-undefined return value over exports use.
49127                if (cjsModule && cjsModule.exports !== undef &&
49128                        cjsModule.exports !== defined[name]) {
49129                    defined[name] = cjsModule.exports;
49130                } else if (ret !== undef || !usingExports) {
49131                    //Use the return value from the function.
49132                    defined[name] = ret;
49133                }
49134            }
49135        } else if (name) {
49136            //May just be an object definition for the module. Only
49137            //worry about defining if have a module name.
49138            defined[name] = callback;
49139        }
49140    };
49141
49142    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
49143        if (typeof deps === "string") {
49144            if (handlers[deps]) {
49145                //callback in this case is really relName
49146                return handlers[deps](callback);
49147            }
49148            //Just return the module wanted. In this scenario, the
49149            //deps arg is the module name, and second arg (if passed)
49150            //is just the relName.
49151            //Normalize module name, if it contains . or ..
49152            return callDep(makeMap(deps, callback).f);
49153        } else if (!deps.splice) {
49154            //deps is a config object, not an array.
vendor: 15,213 bytes, lines 49155-49767
49155            config = deps;
49156            if (config.deps) {
49157                req(config.deps, config.callback);
49158            }
49159            if (!callback) {
49160                return;
49161            }
49162
49163            if (callback.splice) {
49164                //callback is an array, which means it is a dependency list.
49165                //Adjust args if there are dependencies
49166                deps = callback;
49167                callback = relName;
49168                relName = null;
49169            } else {
49170                deps = undef;
49171            }
49172        }
49173
49174        //Support require(['a'])
49175        callback = callback || function () {};
49176
49177        //If relName is a function, it is an errback handler,
49178        //so remove it.
49179        if (typeof relName === 'function') {
49180            relName = forceSync;
49181            forceSync = alt;
49182        }
49183
49184        //Simulate async callback;
49185        if (forceSync) {
49186            main(undef, deps, callback, relName);
49187        } else {
49188            //Using a non-zero value because of concern for what old browsers
49189            //do, and latest browsers "upgrade" to 4 if lower value is used:
49190            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
49191            //If want a value immediately, use require('id') instead -- something
49192            //that works in almond on the global level, but not guaranteed and
49193            //unlikely to work in other AMD implementations.
49194            setTimeout(function () {
49195                main(undef, deps, callback, relName);
49196            }, 4);
49197        }
49198
49199        return req;
49200    };
49201
49202    /**
49203     * Just drops the config on the floor, but returns req in case
49204     * the config return value is used.
49205     */
49206    req.config = function (cfg) {
49207        return req(cfg);
49208    };
49209
49210    /**
49211     * Expose module registry for debugging and tooling
49212     */
49213    requirejs._defined = defined;
49214
49215    define = function (name, deps, callback) {
49216
49217        //This module may not have dependencies
49218        if (!deps.splice) {
49219            //deps is not an array, so probably means
49220            //an object literal or factory function for
49221            //the value. Adjust args.
49222            callback = deps;
49223            deps = [];
49224        }
49225
49226        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
49227            waiting[name] = [name, deps, callback];
49228        }
49229    };
49230
49231    define.amd = {
49232        jQuery: true
49233    };
49234}());
49235
49236define("almond", function(){});
49237
49238define('jquery',[],function () {
49239    return jQuery;
49240});
49241
49242define('select2/utils',[], function () {
49243  var Utils = {};
49244
49245  Utils.Extend = function (ChildClass, SuperClass) {
49246    var __hasProp = {}.hasOwnProperty;
49247
49248    function BaseConstructor () {
49249      this.constructor = ChildClass;
49250    }
49251
49252    for (var key in SuperClass) {
49253      if (__hasProp.call(SuperClass, key)) {
49254        ChildClass[key] = SuperClass[key];
49255      }
49256    }
49257
49258    BaseConstructor.prototype = SuperClass.prototype;
49259    ChildClass.prototype = new BaseConstructor();
49260    ChildClass.__super__ = SuperClass.prototype;
49261
49262    return ChildClass;
49263  };
49264
49265  function getMethods (theClass) {
49266    var proto = theClass.prototype;
49267
49268    var methods = [];
49269
49270    for (var methodName in proto) {
49271      var m = proto[methodName];
49272
49273      if (typeof m !== 'function') {
49274        continue;
49275      }
49276
49277      if (methodName === 'constructor') {
49278        continue;
49279      }
49280
49281      methods.push(methodName);
49282    }
49283
49284    return methods;
49285  }
49286
49287  Utils.Decorate = function (SuperClass, DecoratorClass) {
49288    var decoratedMethods = getMethods(DecoratorClass);
49289    var superMethods = getMethods(SuperClass);
49290
49291    function DecoratedClass () {
49292      var unshift = Array.prototype.unshift;
49293
49294      var argCount = DecoratorClass.prototype.constructor.length;
49295
49296      var calledConstructor = SuperClass.prototype.constructor;
49297
49298      if (argCount > 0) {
49299        unshift.call(arguments, SuperClass.prototype.constructor);
49300
49301        calledConstructor = DecoratorClass.prototype.constructor;
49302      }
49303
49304      calledConstructor.apply(this, arguments);
49305    }
49306
49307    DecoratorClass.displayName = SuperClass.displayName;
49308
49309    function ctr () {
49310      this.constructor = DecoratedClass;
49311    }
49312
49313    DecoratedClass.prototype = new ctr();
49314
49315    for (var m = 0; m < superMethods.length; m++) {
49316        var superMethod = superMethods[m];
49317
49318        DecoratedClass.prototype[superMethod] =
49319          SuperClass.prototype[superMethod];
49320    }
49321
49322    var calledMethod = function (methodName) {
49323      // Stub out the original method if it's not decorating an actual method
49324      var originalMethod = function () {};
49325
49326      if (methodName in DecoratedClass.prototype) {
49327        originalMethod = DecoratedClass.prototype[methodName];
49328      }
49329
49330      var decoratedMethod = DecoratorClass.prototype[methodName];
49331
49332      return function () {
49333        var unshift = Array.prototype.unshift;
49334
49335        unshift.call(arguments, originalMethod);
49336
49337        return decoratedMethod.apply(this, arguments);
49338      };
49339    };
49340
49341    for (var d = 0; d < decoratedMethods.length; d++) {
49342      var decoratedMethod = decoratedMethods[d];
49343
49344      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
49345    }
49346
49347    return DecoratedClass;
49348  };
49349
49350  var Observable = function () {
49351    this.listeners = {};
49352  };
49353
49354  Observable.prototype.on = function (event, callback) {
49355    this.listeners = this.listeners || {};
49356
49357    if (event in this.listeners) {
49358      this.listeners[event].push(callback);
49359    } else {
49360      this.listeners[event] = [callback];
49361    }
49362  };
49363
49364  Observable.prototype.trigger = function (event) {
49365    var slice = Array.prototype.slice;
49366
49367    this.listeners = this.listeners || {};
49368
49369    if (event in this.listeners) {
49370      this.invoke(this.listeners[event], slice.call(arguments, 1));
49371    }
49372
49373    if ('*' in this.listeners) {
49374      this.invoke(this.listeners['*'], arguments);
49375    }
49376  };
49377
49378  Observable.prototype.invoke = function (listeners, params) {
49379    for (var i = 0, len = listeners.length; i < len; i++) {
49380      listeners[i].apply(this, params);
49381    }
49382  };
49383
49384  Utils.Observable = Observable;
49385
49386  Utils.generateChars = function (length) {
49387    var chars = '';
49388
49389    for (var i = 0; i < length; i++) {
49390      var randomChar = Math.floor(Math.random() * 36);
49391      chars += randomChar.toString(36);
49392    }
49393
49394    return chars;
49395  };
49396
49397  Utils.bind = function (func, context) {
49398    return function () {
49399      func.apply(context, arguments);
49400    };
49401  };
49402
49403  return Utils;
49404});
49405
49406define('select2/results',[
49407  'jquery',
49408  './utils'
49409], function ($, Utils) {
49410  function Results ($element, options, dataAdapter) {
49411    this.$element = $element;
49412    this.data = dataAdapter;
49413    this.options = options;
49414
49415    Results.__super__.constructor.call(this);
49416  }
49417
49418  Utils.Extend(Results, Utils.Observable);
49419
49420  Results.prototype.render = function () {
49421    var $results = $(
49422      '<ul class="select2-results__options" role="tree"></ul>'
49423    );
49424
49425    if (this.options.get('multiple')) {
49426      $results.attr('aria-multiselectable', 'true');
49427    }
49428
49429    this.$results = $results;
49430
49431    return $results;
49432  };
49433
49434  Results.prototype.clear = function () {
49435    this.$results.empty();
49436  };
49437
49438  Results.prototype.displayMessage = function (params) {
49439    this.clear();
49440    this.hideLoading();
49441
49442    var $message = $(
49443      '<li role="treeitem" class="select2-results__option"></li>'
49444    );
49445
49446    var message = this.options.get('translations').get(params.message);
49447
49448    $message.text(message(params.args));
49449
49450    this.$results.append($message);
49451  };
49452
49453  Results.prototype.append = function (data) {
49454    this.hideLoading();
49455
49456    var $options = [];
49457
49458    if (data.results == null || data.results.length === 0) {
49459      if (this.$results.children().length === 0) {
49460        this.trigger('results:message', {
49461          message: 'noResults'
49462        });
49463      }
49464
49465      return;
49466    }
49467
49468    data.results = this.sort(data.results);
49469
49470    for (var d = 0; d < data.results.length; d++) {
49471      var item = data.results[d];
49472
49473      var $option = this.option(item);
49474
49475      $options.push($option);
49476    }
49477
49478    this.$results.append($options);
49479  };
49480
49481  Results.prototype.position = function ($results, $dropdown) {
49482    var $resultsContainer = $dropdown.find('.select2-results');
49483    $resultsContainer.append($results);
49484  };
49485
49486  Results.prototype.sort = function (data) {
49487    var sorter = this.options.get('sorter');
49488
49489    return sorter(data);
49490  };
49491
49492  Results.prototype.setClasses = function () {
49493    var self = this;
49494
49495    this.data.current(function (selected) {
49496      var selectedIds = $.map(selected, function (s) {
49497        return s.id.toString();
49498      });
49499
49500      var $options = self.$results
49501        .find('.select2-results__option[aria-selected]');
49502
49503      $options.each(function () {
49504        var $option = $(this);
49505
49506        var item = $.data(this, 'data');
49507
49508        if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
49509          $option.attr('aria-selected', 'true');
49510        } else {
49511          $option.attr('aria-selected', 'false');
49512        }
49513      });
49514
49515      var $selected = $options.filter('[aria-selected=true]');
49516
49517      // Check if there are any selected options
49518      if ($selected.length > 0) {
49519        // If there are selected options, highlight the first
49520        $selected.first().trigger('mouseenter');
49521      } else {
49522        // If there are no selected options, highlight the first option
49523        // in the dropdown
49524        $options.first().trigger('mouseenter');
49525      }
49526    });
49527  };
49528
49529  Results.prototype.showLoading = function (params) {
49530    this.hideLoading();
49531
49532    var loadingMore = this.options.get('translations').get('searching');
49533
49534    var loading = {
49535      disabled: true,
49536      loading: true,
49537      text: loadingMore(params)
49538    };
49539    var $loading = this.option(loading);
49540    $loading.className += ' loading-results';
49541
49542    this.$results.prepend($loading);
49543  };
49544
49545  Results.prototype.hideLoading = function () {
49546    this.$results.find('.loading-results').remove();
49547  };
49548
49549  Results.prototype.option = function (data) {
49550    var option = document.createElement('li');
49551    option.className = 'select2-results__option';
49552
49553    var attrs = {
49554      'role': 'treeitem',
49555      'aria-selected': 'false'
49556    };
49557
49558    if (data.disabled) {
49559      delete attrs['aria-selected'];
49560      attrs['aria-disabled'] = 'true';
49561    }
49562
49563    if (data.id == null) {
49564      delete attrs['aria-selected'];
49565    }
49566
49567    if (data._resultId != null) {
49568      option.id = data._resultId;
49569    }
49570
49571    if (data.children) {
49572      attrs.role = 'group';
49573      attrs['aria-label'] = data.text;
49574      delete attrs['aria-selected'];
49575    }
49576
49577    for (var attr in attrs) {
49578      var val = attrs[attr];
49579
49580      option.setAttribute(attr, val);
49581    }
49582
49583    if (data.children) {
49584      var $option = $(option);
49585
49586      var label = document.createElement('strong');
49587      label.className = 'select2-results__group';
49588
49589      var $label = $(label);
49590      this.template(data, label);
49591
49592      var $children = [];
49593
49594      for (var c = 0; c < data.children.length; c++) {
49595        var child = data.children[c];
49596
49597        var $child = this.option(child);
49598
49599        $children.push($child);
49600      }
49601
49602      var $childrenContainer = $('<ul></ul>', {
49603        'class': 'select2-results__options select2-results__options--nested'
49604      });
49605
49606      $childrenContainer.append($children);
49607
49608      $option.append(label);
49609      $option.append($childrenContainer);
49610    } else {
49611      this.template(data, option);
49612    }
49613
49614    $.data(option, 'data', data);
49615
49616    return option;
49617  };
49618
49619  Results.prototype.bind = function (container, $container) {
49620    var self = this;
49621
49622    var id = container.id + '-results';
49623
49624    this.$results.attr('id', id);
49625
49626    container.on('results:all', function (params) {
49627      self.clear();
49628      self.append(params.data);
49629
49630      if (container.isOpen()) {
49631        self.setClasses();
49632      }
49633    });
49634
49635    container.on('results:append', function (params) {
49636      self.append(params.data);
49637
49638      if (container.isOpen()) {
49639        self.setClasses();
49640      }
49641    });
49642
49643    container.on('query', function (params) {
49644      self.showLoading(params);
49645    });
49646
49647    container.on('select', function () {
49648      if (!container.isOpen()) {
49649        return;
49650      }
49651
49652      self.setClasses();
49653    });
49654
49655    container.on('unselect', function () {
49656      if (!container.isOpen()) {
49657        return;
49658      }
49659
49660      self.setClasses();
49661    });
49662
49663    container.on('open', function () {
49664      // When the dropdown is open, aria-expended="true"
49665      self.$results.attr('aria-expanded', 'true');
49666      self.$results.attr('aria-hidden', 'false');
49667
49668      self.setClasses();
49669      self.ensureHighlightVisible();
49670    });
49671
49672    container.on('close', function () {
49673      // When the dropdown is closed, aria-expended="false"
49674      self.$results.attr('aria-expanded', 'false');
49675      self.$results.attr('aria-hidden', 'true');
49676      self.$results.removeAttr('aria-activedescendant');
49677    });
49678
49679    container.on('results:select', function () {
49680      var $highlighted = self.getHighlightedResults();
49681
49682      if ($highlighted.length === 0) {
49683        return;
49684      }
49685
49686      var data = $highlighted.data('data');
49687
49688      if ($highlighted.attr('aria-selected') == 'true') {
49689        self.trigger('unselect', {
49690          data: data
49691        });
49692      } else {
49693        self.trigger('select', {
49694          data: data
49695        });
49696      }
49697    });
49698
49699    container.on('results:previous', function () {
49700      var $highlighted = self.getHighlightedResults();
49701
49702      var $options = self.$results.find('[aria-selected]');
49703
49704      var currentIndex = $options.index($highlighted);
49705
49706      // If we are already at te top, don't move further
49707      if (currentIndex === 0) {
49708        return;
49709      }
49710
49711      var nextIndex = currentIndex - 1;
49712
49713      // If none are highlighted, highlight the first
49714      if ($highlighted.length === 0) {
49715        nextIndex = 0;
49716      }
49717
49718      var $next = $options.eq(nextIndex);
49719
49720      $next.trigger('mouseenter');
49721
49722      var currentOffset = self.$results.offset().top;
49723      var nextTop = $next.offset().top;
49724      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
49725
49726      if (nextIndex === 0) {
49727        self.$results.scrollTop(0);
49728      } else if (nextTop - currentOffset < 0) {
49729        self.$results.scrollTop(nextOffset);
49730      }
49731    });
49732
49733    container.on('results:next', function () {
49734      var $highlighted = self.getHighlightedResults();
49735
49736      var $options = self.$results.find('[aria-selected]');
49737
49738      var currentIndex = $options.index($highlighted);
49739
49740      var nextIndex = currentIndex + 1;
49741
49742      // If we are at the last option, stay there
49743      if (nextIndex >= $options.length) {
49744        return;
49745      }
49746
49747      var $next = $options.eq(nextIndex);
49748
49749      $next.trigger('mouseenter');
49750
49751      var currentOffset = self.$results.offset().top +
49752        self.$results.outerHeight(false);
49753      var nextBottom = $next.offset().top + $next.outerHeight(false);
49754      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
49755
49756      if (nextIndex === 0) {
49757        self.$results.scrollTop(0);
49758      } else if (nextBottom > currentOffset) {
49759        self.$results.scrollTop(nextOffset);
49760      }
49761    });
49762
49763    container.on('results:focus', function (params) {
49764      params.element.addClass('select2-results__option--highlighted');
49765    });
49766
49767    container.on('results:message', function (params) {
49768      self.displayMessage(params);
49769    });
49770
49771    if ($.fn.mousewheel) {
49772      this.$results.on('mousewheel', function (e) {
49773        var top = self.$results.scrollTop();
49774
49775        var bottom = (
49776          self.$results.get(0).scrollHeight -
49777          self.$results.scrollTop() +
49778          e.deltaY
49779        );
49780
49781        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
49782        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
49783
49784        if (isAtTop) {
49785          self.$results.scrollTop(0);
49786
49787          e.preventDefault();
49788          e.stopPropagation();
49789        } else if (isAtBottom) {
49790          self.$results.scrollTop(
49791            self.$results.get(0).scrollHeight - self.$results.height()
49792          );
49793
49794          e.preventDefault();
49795          e.stopPropagation();
49796        }
49797      });
49798    }
49799
49800    this.$results.on('mouseup', '.select2-results__option[aria-selected]',
49801      function (evt) {
49802      var $this = $(this);
49803
49804      var data = $this.data('data');
49805
49806      if ($this.attr('aria-selected') === 'true') {
49807        self.trigger('unselect', {
49808          originalEvent: evt,
49809          data: data
49810        });
49811
49812        return;
49813      }
49814
49815      self.trigger('select', {
49816        originalEvent: evt,
49817        data: data
49818      });
49819    });
49820
49821    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
49822      function (evt) {
49823      var data = $(this).data('data');
49824
49825      self.getHighlightedResults()
49826          .removeClass('select2-results__option--highlighted');
49827
49828      self.trigger('results:focus', {
49829        data: data,
49830        element: $(this)
49831      });
49832    });
49833  };
49834
49835  Results.prototype.getHighlightedResults = function () {
49836    var $highlighted = this.$results
49837    .find('.select2-results__option--highlighted');
49838
49839    return $highlighted;
49840  };
49841
49842  Results.prototype.destroy = function () {
49843    this.$results.remove();
49844  };
49845
49846  Results.prototype.ensureHighlightVisible = function () {
49847    var $highlighted = this.getHighlightedResults();
49848
49849    if ($highlighted.length === 0) {
49850      return;
49851    }
49852
49853    var $options = this.$results.find('[aria-selected]');
49854
49855    var currentIndex = $options.index($highlighted);
49856
49857    var currentOffset = this.$results.offset().top;
49858    var nextTop = $highlighted.offset().top;
49859    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
49860
49861    var offsetDelta = nextTop - currentOffset;
49862    nextOffset -= $highlighted.outerHeight(false) * 2;
49863
49864    if (currentIndex <= 2) {
49865      this.$results.scrollTop(0);
49866    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
49867      this.$results.scrollTop(nextOffset);
49868    }
49869  };
49870
49871  Results.prototype.template = function (result, container) {
49872    var template = this.options.get('templateResult');
49873
49874    container.innerHTML = template(result);
49875  };
49876
49877  return Results;
49878});
49879
49880define('select2/keys',[
49881
49882], function () {
49883  var KEYS = {
49884    BACKSPACE: 8,
49885    TAB: 9,
49886    ENTER: 13,
49887    SHIFT: 16,
49888    CTRL: 17,
49889    ALT: 18,
49890    ESC: 27,
49891    SPACE: 32,
49892    PAGE_UP: 33,
49893    PAGE_DOWN: 34,
49894    END: 35,
49895    HOME: 36,
49896    LEFT: 37,
49897    UP: 38,
49898    RIGHT: 39,
49899    DOWN: 40,
49900    DELETE: 46,
49901
49902    isArrow: function (k) {
49903        k = k.which ? k.which : k;
49904
49905        switch (k) {
49906        case KEY.LEFT:
49907        case KEY.RIGHT:
49908        case KEY.UP:
49909        case KEY.DOWN:
49910            return true;
49911        }
49912
49913        return false;
49914    }
49915  };
49916
49917  return KEYS;
49918});
49919
49920define('select2/selection/base',[
49921  '../utils',
49922  '../keys'
49923], function (Utils, KEYS) {
49924  function BaseSelection ($element, options) {
49925    this.$element = $element;
49926    this.options = options;
49927
49928    BaseSelection.__super__.constructor.call(this);
49929  }
49930
49931  Utils.Extend(BaseSelection, Utils.Observable);
49932
49933  BaseSelection.prototype.render = function () {
49934    throw new Error('The `render` method must be defined in child classes.');
49935  };
49936
49937  BaseSelection.prototype.bind = function (container, $container) {
49938    var self = this;
49939
49940    var id = container.id + '-container';
49941    var resultsId = container.id + '-results';
49942
49943    this.container = container;
49944
49945    this.$selection.attr('aria-owns', resultsId);
49946
49947    this.$selection.on('keydown', function (evt) {
49948      self.trigger('keypress', evt);
49949
49950      if (evt.which === KEYS.SPACE) {
49951        evt.preventDefault();
49952      }
49953    });
49954
49955    container.on('results:focus', function (params) {
49956      self.$selection.attr('aria-activedescendant', params.data._resultId);
49957    });
49958
49959    container.on('selection:update', function (params) {
49960      self.update(params.data);
49961    });
49962
49963    container.on('open', function () {
49964      // When the dropdown is open, aria-expanded="true"
49965      self.$selection.attr('aria-expanded', 'true');
49966
49967      self._attachCloseHandler(container);
49968    });
49969
49970    container.on('close', function () {
49971      // When the dropdown is closed, aria-expanded="false"
49972      self.$selection.attr('aria-expanded', 'false');
49973      self.$selection.removeAttr('aria-activedescendant');
49974
49975      self.$selection.focus();
49976
49977      self._detachCloseHandler(container);
49978    });
49979  };
49980
49981  BaseSelection.prototype._attachCloseHandler = function (container) {
49982    var self = this;
49983
49984    $(document.body).on('mousedown.select2.' + container.id, function (e) {
49985      var $target = $(e.target);
49986
49987      var $select = $target.closest('.select2');
49988
49989      var $all = $('.select2.select2-container--open');
49990
49991      $all.each(function () {
49992        var $this = $(this);
49993
49994        if (this == $select[0]) {
49995          return;
49996        }
49997
49998        var $element = $this.data('element');
49999
50000        $element.select2('close');
50001      });
50002    });
50003
vendor: 25,075 bytes, lines 50004-51165
50004    $(window).on('scroll.select2.' + container.id, function (e) {
50005      self.trigger('close');
50006    });
50007  };
50008
50009  BaseSelection.prototype._detachCloseHandler = function (container) {
50010    $(document.body).off('mousedown.select2.' + container.id);
50011    $(window).off('scroll.select2.' + container.id);
50012  };
50013
50014  BaseSelection.prototype.position = function ($selection, $container) {
50015    var $selectionContainer = $container.find('.selection');
50016    $selectionContainer.append($selection);
50017  };
50018
50019  BaseSelection.prototype.destroy = function () {
50020    this._detachCloseHandler(this.container);
50021  };
50022
50023  BaseSelection.prototype.update = function (data) {
50024    throw new Error('The `update` method must be defined in child classes.');
50025  };
50026
50027  return BaseSelection;
50028});
50029
50030define('select2/selection/single',[
50031  './base',
50032  '../utils',
50033  '../keys'
50034], function (BaseSelection, Utils, KEYS) {
50035  function SingleSelection () {
50036    SingleSelection.__super__.constructor.apply(this, arguments);
50037  }
50038
50039  Utils.Extend(SingleSelection, BaseSelection);
50040
50041  SingleSelection.prototype.render = function () {
50042    var $selection = $(
50043      '<span class="select2-selection select2-selection--single" tabindex="0"' +
50044        ' role="combobox" aria-autocomplete="list" aria-haspopup="true"' +
50045        ' aria-expanded="false">' +
50046        '<span class="select2-selection__rendered"></span>' +
50047        '<span class="select2-selection__arrow" role="presentation">' +
50048          '<b role="presentation"></b>' +
50049        '</span>' +
50050      '</span>'
50051    );
50052
50053    $selection.attr('title', this.$element.attr('title'));
50054
50055    this.$selection = $selection;
50056
50057    return $selection;
50058  };
50059
50060  SingleSelection.prototype.bind = function (container, $container) {
50061    var self = this;
50062
50063    SingleSelection.__super__.bind.apply(this, arguments);
50064
50065    var id = container.id + '-container';
50066
50067    this.$selection.find('.select2-selection__rendered').attr('id', id);
50068    this.$selection.attr('aria-labelledby', id);
50069
50070    this.$selection.on('mousedown', function (evt) {
50071      // Only respond to left clicks
50072      if (evt.which !== 1) {
50073        return;
50074      }
50075
50076      self.trigger('toggle', {
50077        originalEvent: evt
50078      });
50079    });
50080
50081    this.$selection.on('focus', function (evt) {
50082      // User focuses on the container
50083    });
50084
50085    this.$selection.on('blur', function (evt) {
50086      // User exits the container
50087    });
50088
50089    container.on('enable', function () {
50090      self.$selection.attr('tabindex', '0');
50091    });
50092
50093    container.on('disable', function () {
50094      self.$selection.attr('tabindex', '-1');
50095    });
50096
50097    container.on('selection:update', function (params) {
50098      self.update(params.data);
50099    });
50100  };
50101
50102  SingleSelection.prototype.clear = function () {
50103    this.$selection.find('.select2-selection__rendered').empty();
50104  };
50105
50106  SingleSelection.prototype.display = function (data) {
50107    var template = this.options.get('templateSelection');
50108
50109    return template(data);
50110  };
50111
50112  SingleSelection.prototype.selectionContainer = function () {
50113    return $('<span></span>');
50114  };
50115
50116  SingleSelection.prototype.update = function (data) {
50117    if (data.length === 0) {
50118      this.clear();
50119      return;
50120    }
50121
50122    var selection = data[0];
50123
50124    var formatted = this.display(selection);
50125
50126    this.$selection.find('.select2-selection__rendered').html(formatted);
50127  };
50128
50129  return SingleSelection;
50130});
50131
50132define('select2/selection/multiple',[
50133  './base',
50134  '../utils'
50135], function (BaseSelection, Utils) {
50136  function MultipleSelection ($element, options) {
50137    MultipleSelection.__super__.constructor.apply(this, arguments);
50138  }
50139
50140  Utils.Extend(MultipleSelection, BaseSelection);
50141
50142  MultipleSelection.prototype.render = function () {
50143    var $selection = $(
50144      '<span class="select2-selection select2-selection--multiple"' +
50145        ' tabindex="0" role="combobox" aria-autocomplete="list"' +
50146        ' aria-haspopup="true" aria-expanded="false">' +
50147        '<ul class="select2-selection__rendered"></ul>' +
50148      '</span>'
50149    );
50150
50151    $selection.attr('title', this.$element.attr('title'));
50152
50153    this.$selection = $selection;
50154
50155    return $selection;
50156  };
50157
50158  MultipleSelection.prototype.bind = function (container, $container) {
50159    var self = this;
50160
50161    MultipleSelection.__super__.bind.apply(this, arguments);
50162
50163    this.$selection.on('click', function (evt) {
50164      self.trigger('toggle', {
50165        originalEvent: evt
50166      });
50167    });
50168
50169    this.$selection.on('click', '.select2-selection__choice__remove',
50170      function (evt) {
50171      var $remove = $(this);
50172      var $selection = $remove.parent();
50173
50174      var data = $selection.data('data');
50175
50176      self.trigger('unselect', {
50177        originalEvent: evt,
50178        data: data
50179      });
50180    });
50181
50182    container.on('enable', function () {
50183      self.$selection.attr('tabindex', '0');
50184    });
50185
50186    container.on('disable', function () {
50187      self.$selection.attr('tabindex', '-1');
50188    });
50189  };
50190
50191  MultipleSelection.prototype.clear = function () {
50192    this.$selection.find('.select2-selection__rendered').empty();
50193  };
50194
50195  MultipleSelection.prototype.display = function (data) {
50196    var template = this.options.get('templateSelection');
50197
50198    return template(data);
50199  };
50200
50201  MultipleSelection.prototype.selectionContainer = function () {
50202    var $container = $(
50203      '<li class="select2-selection__choice">' +
50204        '<span class="select2-selection__choice__remove" role="presentation">' +
50205          '&times;' +
50206        '</span>' +
50207      '</li>'
50208    );
50209
50210    return $container;
50211  };
50212
50213  MultipleSelection.prototype.update = function (data) {
50214    this.clear();
50215
50216    if (data.length === 0) {
50217      return;
50218    }
50219
50220    var $selections = [];
50221
50222    for (var d = 0; d < data.length; d++) {
50223      var selection = data[d];
50224
50225      var formatted = this.display(selection);
50226      var $selection = this.selectionContainer();
50227
50228      $selection.append(formatted);
50229      $selection.data('data', selection);
50230
50231      $selections.push($selection);
50232    }
50233
50234    this.$selection.find('.select2-selection__rendered').append($selections);
50235  };
50236
50237  return MultipleSelection;
50238});
50239
50240define('select2/selection/placeholder',[
50241  '../utils'
50242], function (Utils) {
50243  function Placeholder (decorated, $element, options) {
50244    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
50245
50246    decorated.call(this, $element, options);
50247  }
50248
50249  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
50250    if (typeof placeholder === 'string') {
50251      placeholder = {
50252        id: '',
50253        text: placeholder
50254      };
50255    }
50256
50257    return placeholder;
50258  };
50259
50260  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
50261    var $placeholder = this.selectionContainer();
50262
50263    $placeholder.html(this.display(placeholder));
50264    $placeholder.addClass('select2-selection__placeholder')
50265                .removeClass('select2-selection__choice');
50266
50267    return $placeholder;
50268  };
50269
50270  Placeholder.prototype.update = function (decorated, data) {
50271    var singlePlaceholder = (
50272      data.length == 1 && data[0].id != this.placeholder.id
50273    );
50274    var multipleSelections = data.length > 1;
50275
50276    if (multipleSelections || singlePlaceholder) {
50277      return decorated.call(this, data);
50278    }
50279
50280    this.clear();
50281
50282    var $placeholder = this.createPlaceholder(this.placeholder);
50283
50284    this.$selection.find('.select2-selection__rendered').append($placeholder);
50285  };
50286
50287  return Placeholder;
50288});
50289
50290define('select2/selection/allowClear',[
50291
50292], function () {
50293  function AllowClear () { }
50294
50295  AllowClear.prototype.bind = function (decorated, container, $container) {
50296    var self = this;
50297
50298    decorated.call(this, container, $container);
50299
50300    this.$selection.on('mousedown', '.select2-selection__clear',
50301      function (evt) {
50302        // Ignore the event if it is disabled
50303        if (self.options.get('disabled')) {
50304          return;
50305        }
50306
50307        evt.stopPropagation();
50308
50309        self.$element.val(self.placeholder.id).trigger('change');
50310
50311        self.trigger('toggle');
50312    });
50313  };
50314
50315  AllowClear.prototype.update = function (decorated, data) {
50316    decorated.call(this, data);
50317
50318    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
50319        data.length === 0) {
50320      return;
50321    }
50322
50323    var $remove = $(
50324      '<span class="select2-selection__clear">' +
50325        '&times;' +
50326      '</span>'
50327    );
50328
50329    this.$selection.find('.select2-selection__rendered').append($remove);
50330  };
50331
50332  return AllowClear;
50333});
50334
50335define('select2/selection/search',[
50336  '../utils',
50337  '../keys'
50338], function (Utils, KEYS) {
50339  function Search (decorated, $element, options) {
50340    decorated.call(this, $element, options);
50341  }
50342
50343  Search.prototype.render = function (decorated) {
50344    var $search = $(
50345      '<li class="select2-search select2-search--inline">' +
50346        '<input class="select2-search__field" type="search" tabindex="-1"' +
50347          ' role="textbox" />' +
50348      '</li>'
50349    );
50350
50351    this.$searchContainer = $search;
50352    this.$search = $search.find('input');
50353
50354    var $rendered = decorated.call(this);
50355
50356    return $rendered;
50357  };
50358
50359  Search.prototype.bind = function (decorated, container, $container) {
50360    var self = this;
50361
50362    decorated.call(this, container, $container);
50363
50364    container.on('open', function () {
50365      self.$search.attr('tabindex', 0);
50366
50367      self.$search.focus();
50368    });
50369
50370    container.on('close', function () {
50371      self.$search.attr('tabindex', -1);
50372
50373      self.$search.val('');
50374    });
50375
50376    container.on('enable', function () {
50377      self.$search.prop('disabled', false);
50378    });
50379
50380    container.on('disable', function () {
50381      self.$search.prop('disabled', true);
50382    });
50383
50384    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
50385      evt.stopPropagation();
50386
50387      self.trigger('keypress', evt);
50388
50389      self._keyUpPrevented = evt.isDefaultPrevented();
50390
50391      var key = evt.which;
50392
50393      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
50394        var $previousChoice = self.$searchContainer
50395          .prev('.select2-selection__choice');
50396
50397        if ($previousChoice.length > 0) {
50398          var item = $previousChoice.data('data');
50399
50400          self.searchRemoveChoice(item);
50401        }
50402      }
50403    });
50404
50405    this.$selection.on('keyup', '.select2-search--inline', function (evt) {
50406      self.handleSearch(evt);
50407    });
50408  };
50409
50410  Search.prototype.createPlaceholder = function (decorated, placeholder) {
50411    this.$search.attr('placeholder', placeholder.text);
50412  };
50413
50414  Search.prototype.update = function (decorated, data) {
50415    this.$search.attr('placeholder', '');
50416
50417    decorated.call(this, data);
50418
50419    this.$selection.find('.select2-selection__rendered')
50420                   .append(this.$searchContainer);
50421
50422    this.resizeSearch();
50423  };
50424
50425  Search.prototype.handleSearch = function () {
50426    this.resizeSearch();
50427
50428    if (!this._keyUpPrevented) {
50429      var input = this.$search.val();
50430
50431      this.trigger('query', {
50432        term: input
50433      });
50434    }
50435
50436    this._keyUpPrevented = false;
50437  };
50438
50439  Search.prototype.searchRemoveChoice = function (decorated, item) {
50440    this.trigger('unselect', {
50441      data: item
50442    });
50443
50444    this.trigger('open');
50445
50446    this.$search.val(item.text + ' ');
50447  };
50448
50449  Search.prototype.resizeSearch = function () {
50450    this.$search.css('width', '25px');
50451
50452    var width = '';
50453
50454    if (this.$search.attr('placeholder') !== '') {
50455      width = this.$selection.find('.select2-selection__rendered').innerWidth();
50456    } else {
50457      var minimumWidth = this.$search.val().length + 1;
50458
50459      width = (minimumWidth * 0.75) + 'em';
50460    }
50461
50462    this.$search.css('width', width);
50463  };
50464
50465  return Search;
50466});
50467
50468define('select2/selection/eventRelay',[
50469  'jquery'
50470], function ($) {
50471  function EventRelay () { }
50472
50473  EventRelay.prototype.bind = function (decorated, container, $container) {
50474    var self = this;
50475    var relayEvents = [
50476      'open', 'opening',
50477      'close', 'closing',
50478      'select', 'selecting',
50479      'unselect', 'unselecting'
50480    ];
50481
50482    var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
50483
50484    decorated.call(this, container, $container);
50485
50486    container.on('*', function (name, params) {
50487      // Ignore events that should not be relayed
50488      if (relayEvents.indexOf(name) === -1) {
50489        return;
50490      }
50491
50492      // The parameters should always be an object
50493      params = params || {};
50494
50495      // Generate the jQuery event for the Select2 event
50496      var evt = $.Event('select2:' + name, {
50497        params: params
50498      });
50499
50500      self.$element.trigger(evt);
50501
50502      // Only handle preventable events if it was one
50503      if (preventableEvents.indexOf(name) === -1) {
50504        return;
50505      }
50506
50507      params.prevented = evt.isDefaultPrevented();
50508    });
50509  };
50510
50511  return EventRelay;
50512});
50513
50514define('select2/translation',[
50515
50516], function () {
50517  function Translation (dict) {
50518    this.dict = dict || {};
50519  }
50520
50521  Translation.prototype.all = function () {
50522    return this.dict;
50523  };
50524
50525  Translation.prototype.get = function (key) {
50526    return this.dict[key];
50527  };
50528
50529  Translation.prototype.extend = function (translation) {
50530    this.dict = $.extend({}, translation.all(), this.dict);
50531  };
50532
50533  // Static functions
50534
50535  Translation._cache = {};
50536
50537  Translation.loadPath = function (path) {
50538    if (!(path in Translation._cache)) {
50539      var translations = require(path);
50540
50541      Translation._cache[path] = translations;
50542    }
50543
50544    return new Translation(Translation._cache[path]);
50545  };
50546
50547  return Translation;
50548});
50549
50550define('select2/diacritics',[
50551
50552], function () {
50553  var diacritics = {
50554    '\u24B6': 'A',
50555    '\uFF21': 'A',
50556    '\u00C0': 'A',
50557    '\u00C1': 'A',
50558    '\u00C2': 'A',
50559    '\u1EA6': 'A',
50560    '\u1EA4': 'A',
50561    '\u1EAA': 'A',
50562    '\u1EA8': 'A',
50563    '\u00C3': 'A',
50564    '\u0100': 'A',
50565    '\u0102': 'A',
50566    '\u1EB0': 'A',
50567    '\u1EAE': 'A',
50568    '\u1EB4': 'A',
50569    '\u1EB2': 'A',
50570    '\u0226': 'A',
50571    '\u01E0': 'A',
50572    '\u00C4': 'A',
50573    '\u01DE': 'A',
50574    '\u1EA2': 'A',
50575    '\u00C5': 'A',
50576    '\u01FA': 'A',
50577    '\u01CD': 'A',
50578    '\u0200': 'A',
50579    '\u0202': 'A',
50580    '\u1EA0': 'A',
50581    '\u1EAC': 'A',
50582    '\u1EB6': 'A',
50583    '\u1E00': 'A',
50584    '\u0104': 'A',
50585    '\u023A': 'A',
50586    '\u2C6F': 'A',
50587    '\uA732': 'AA',
50588    '\u00C6': 'AE',
50589    '\u01FC': 'AE',
50590    '\u01E2': 'AE',
50591    '\uA734': 'AO',
50592    '\uA736': 'AU',
50593    '\uA738': 'AV',
50594    '\uA73A': 'AV',
50595    '\uA73C': 'AY',
50596    '\u24B7': 'B',
50597    '\uFF22': 'B',
50598    '\u1E02': 'B',
50599    '\u1E04': 'B',
50600    '\u1E06': 'B',
50601    '\u0243': 'B',
50602    '\u0182': 'B',
50603    '\u0181': 'B',
50604    '\u24B8': 'C',
50605    '\uFF23': 'C',
50606    '\u0106': 'C',
50607    '\u0108': 'C',
50608    '\u010A': 'C',
50609    '\u010C': 'C',
50610    '\u00C7': 'C',
50611    '\u1E08': 'C',
50612    '\u0187': 'C',
50613    '\u023B': 'C',
50614    '\uA73E': 'C',
50615    '\u24B9': 'D',
50616    '\uFF24': 'D',
50617    '\u1E0A': 'D',
50618    '\u010E': 'D',
50619    '\u1E0C': 'D',
50620    '\u1E10': 'D',
50621    '\u1E12': 'D',
50622    '\u1E0E': 'D',
50623    '\u0110': 'D',
50624    '\u018B': 'D',
50625    '\u018A': 'D',
50626    '\u0189': 'D',
50627    '\uA779': 'D',
50628    '\u01F1': 'DZ',
50629    '\u01C4': 'DZ',
50630    '\u01F2': 'Dz',
50631    '\u01C5': 'Dz',
50632    '\u24BA': 'E',
50633    '\uFF25': 'E',
50634    '\u00C8': 'E',
50635    '\u00C9': 'E',
50636    '\u00CA': 'E',
50637    '\u1EC0': 'E',
50638    '\u1EBE': 'E',
50639    '\u1EC4': 'E',
50640    '\u1EC2': 'E',
50641    '\u1EBC': 'E',
50642    '\u0112': 'E',
50643    '\u1E14': 'E',
50644    '\u1E16': 'E',
50645    '\u0114': 'E',
50646    '\u0116': 'E',
50647    '\u00CB': 'E',
50648    '\u1EBA': 'E',
50649    '\u011A': 'E',
50650    '\u0204': 'E',
50651    '\u0206': 'E',
50652    '\u1EB8': 'E',
50653    '\u1EC6': 'E',
50654    '\u0228': 'E',
50655    '\u1E1C': 'E',
50656    '\u0118': 'E',
50657    '\u1E18': 'E',
50658    '\u1E1A': 'E',
50659    '\u0190': 'E',
50660    '\u018E': 'E',
50661    '\u24BB': 'F',
50662    '\uFF26': 'F',
50663    '\u1E1E': 'F',
50664    '\u0191': 'F',
50665    '\uA77B': 'F',
50666    '\u24BC': 'G',
50667    '\uFF27': 'G',
50668    '\u01F4': 'G',
50669    '\u011C': 'G',
50670    '\u1E20': 'G',
50671    '\u011E': 'G',
50672    '\u0120': 'G',
50673    '\u01E6': 'G',
50674    '\u0122': 'G',
50675    '\u01E4': 'G',
50676    '\u0193': 'G',
50677    '\uA7A0': 'G',
50678    '\uA77D': 'G',
50679    '\uA77E': 'G',
50680    '\u24BD': 'H',
50681    '\uFF28': 'H',
50682    '\u0124': 'H',
50683    '\u1E22': 'H',
50684    '\u1E26': 'H',
50685    '\u021E': 'H',
50686    '\u1E24': 'H',
50687    '\u1E28': 'H',
50688    '\u1E2A': 'H',
50689    '\u0126': 'H',
50690    '\u2C67': 'H',
50691    '\u2C75': 'H',
50692    '\uA78D': 'H',
50693    '\u24BE': 'I',
50694    '\uFF29': 'I',
50695    '\u00CC': 'I',
50696    '\u00CD': 'I',
50697    '\u00CE': 'I',
50698    '\u0128': 'I',
50699    '\u012A': 'I',
50700    '\u012C': 'I',
50701    '\u0130': 'I',
50702    '\u00CF': 'I',
50703    '\u1E2E': 'I',
50704    '\u1EC8': 'I',
50705    '\u01CF': 'I',
50706    '\u0208': 'I',
50707    '\u020A': 'I',
50708    '\u1ECA': 'I',
50709    '\u012E': 'I',
50710    '\u1E2C': 'I',
50711    '\u0197': 'I',
50712    '\u24BF': 'J',
50713    '\uFF2A': 'J',
50714    '\u0134': 'J',
50715    '\u0248': 'J',
50716    '\u24C0': 'K',
50717    '\uFF2B': 'K',
50718    '\u1E30': 'K',
50719    '\u01E8': 'K',
50720    '\u1E32': 'K',
50721    '\u0136': 'K',
50722    '\u1E34': 'K',
50723    '\u0198': 'K',
50724    '\u2C69': 'K',
50725    '\uA740': 'K',
50726    '\uA742': 'K',
50727    '\uA744': 'K',
50728    '\uA7A2': 'K',
50729    '\u24C1': 'L',
50730    '\uFF2C': 'L',
50731    '\u013F': 'L',
50732    '\u0139': 'L',
50733    '\u013D': 'L',
50734    '\u1E36': 'L',
50735    '\u1E38': 'L',
50736    '\u013B': 'L',
50737    '\u1E3C': 'L',
50738    '\u1E3A': 'L',
50739    '\u0141': 'L',
50740    '\u023D': 'L',
50741    '\u2C62': 'L',
50742    '\u2C60': 'L',
50743    '\uA748': 'L',
50744    '\uA746': 'L',
50745    '\uA780': 'L',
50746    '\u01C7': 'LJ',
50747    '\u01C8': 'Lj',
50748    '\u24C2': 'M',
50749    '\uFF2D': 'M',
50750    '\u1E3E': 'M',
50751    '\u1E40': 'M',
50752    '\u1E42': 'M',
50753    '\u2C6E': 'M',
50754    '\u019C': 'M',
50755    '\u24C3': 'N',
50756    '\uFF2E': 'N',
50757    '\u01F8': 'N',
50758    '\u0143': 'N',
50759    '\u00D1': 'N',
50760    '\u1E44': 'N',
50761    '\u0147': 'N',
50762    '\u1E46': 'N',
50763    '\u0145': 'N',
50764    '\u1E4A': 'N',
50765    '\u1E48': 'N',
50766    '\u0220': 'N',
50767    '\u019D': 'N',
50768    '\uA790': 'N',
50769    '\uA7A4': 'N',
50770    '\u01CA': 'NJ',
50771    '\u01CB': 'Nj',
50772    '\u24C4': 'O',
50773    '\uFF2F': 'O',
50774    '\u00D2': 'O',
50775    '\u00D3': 'O',
50776    '\u00D4': 'O',
50777    '\u1ED2': 'O',
50778    '\u1ED0': 'O',
50779    '\u1ED6': 'O',
50780    '\u1ED4': 'O',
50781    '\u00D5': 'O',
50782    '\u1E4C': 'O',
50783    '\u022C': 'O',
50784    '\u1E4E': 'O',
50785    '\u014C': 'O',
50786    '\u1E50': 'O',
50787    '\u1E52': 'O',
50788    '\u014E': 'O',
50789    '\u022E': 'O',
50790    '\u0230': 'O',
50791    '\u00D6': 'O',
50792    '\u022A': 'O',
50793    '\u1ECE': 'O',
50794    '\u0150': 'O',
50795    '\u01D1': 'O',
50796    '\u020C': 'O',
50797    '\u020E': 'O',
50798    '\u01A0': 'O',
50799    '\u1EDC': 'O',
50800    '\u1EDA': 'O',
50801    '\u1EE0': 'O',
50802    '\u1EDE': 'O',
50803    '\u1EE2': 'O',
50804    '\u1ECC': 'O',
50805    '\u1ED8': 'O',
50806    '\u01EA': 'O',
50807    '\u01EC': 'O',
50808    '\u00D8': 'O',
50809    '\u01FE': 'O',
50810    '\u0186': 'O',
50811    '\u019F': 'O',
50812    '\uA74A': 'O',
50813    '\uA74C': 'O',
50814    '\u01A2': 'OI',
50815    '\uA74E': 'OO',
50816    '\u0222': 'OU',
50817    '\u24C5': 'P',
50818    '\uFF30': 'P',
50819    '\u1E54': 'P',
50820    '\u1E56': 'P',
50821    '\u01A4': 'P',
50822    '\u2C63': 'P',
50823    '\uA750': 'P',
50824    '\uA752': 'P',
50825    '\uA754': 'P',
50826    '\u24C6': 'Q',
50827    '\uFF31': 'Q',
50828    '\uA756': 'Q',
50829    '\uA758': 'Q',
50830    '\u024A': 'Q',
50831    '\u24C7': 'R',
50832    '\uFF32': 'R',
50833    '\u0154': 'R',
50834    '\u1E58': 'R',
50835    '\u0158': 'R',
50836    '\u0210': 'R',
50837    '\u0212': 'R',
50838    '\u1E5A': 'R',
50839    '\u1E5C': 'R',
50840    '\u0156': 'R',
50841    '\u1E5E': 'R',
50842    '\u024C': 'R',
50843    '\u2C64': 'R',
50844    '\uA75A': 'R',
50845    '\uA7A6': 'R',
50846    '\uA782': 'R',
50847    '\u24C8': 'S',
50848    '\uFF33': 'S',
50849    '\u1E9E': 'S',
50850    '\u015A': 'S',
50851    '\u1E64': 'S',
50852    '\u015C': 'S',
50853    '\u1E60': 'S',
50854    '\u0160': 'S',
50855    '\u1E66': 'S',
50856    '\u1E62': 'S',
50857    '\u1E68': 'S',
50858    '\u0218': 'S',
50859    '\u015E': 'S',
50860    '\u2C7E': 'S',
50861    '\uA7A8': 'S',
50862    '\uA784': 'S',
50863    '\u24C9': 'T',
50864    '\uFF34': 'T',
50865    '\u1E6A': 'T',
50866    '\u0164': 'T',
50867    '\u1E6C': 'T',
50868    '\u021A': 'T',
50869    '\u0162': 'T',
50870    '\u1E70': 'T',
50871    '\u1E6E': 'T',
50872    '\u0166': 'T',
50873    '\u01AC': 'T',
50874    '\u01AE': 'T',
50875    '\u023E': 'T',
50876    '\uA786': 'T',
50877    '\uA728': 'TZ',
50878    '\u24CA': 'U',
50879    '\uFF35': 'U',
50880    '\u00D9': 'U',
50881    '\u00DA': 'U',
50882    '\u00DB': 'U',
50883    '\u0168': 'U',
50884    '\u1E78': 'U',
50885    '\u016A': 'U',
50886    '\u1E7A': 'U',
50887    '\u016C': 'U',
50888    '\u00DC': 'U',
50889    '\u01DB': 'U',
50890    '\u01D7': 'U',
50891    '\u01D5': 'U',
50892    '\u01D9': 'U',
50893    '\u1EE6': 'U',
50894    '\u016E': 'U',
50895    '\u0170': 'U',
50896    '\u01D3': 'U',
50897    '\u0214': 'U',
50898    '\u0216': 'U',
50899    '\u01AF': 'U',
50900    '\u1EEA': 'U',
50901    '\u1EE8': 'U',
50902    '\u1EEE': 'U',
50903    '\u1EEC': 'U',
50904    '\u1EF0': 'U',
50905    '\u1EE4': 'U',
50906    '\u1E72': 'U',
50907    '\u0172': 'U',
50908    '\u1E76': 'U',
50909    '\u1E74': 'U',
50910    '\u0244': 'U',
50911    '\u24CB': 'V',
50912    '\uFF36': 'V',
50913    '\u1E7C': 'V',
50914    '\u1E7E': 'V',
50915    '\u01B2': 'V',
50916    '\uA75E': 'V',
50917    '\u0245': 'V',
50918    '\uA760': 'VY',
50919    '\u24CC': 'W',
50920    '\uFF37': 'W',
50921    '\u1E80': 'W',
50922    '\u1E82': 'W',
50923    '\u0174': 'W',
50924    '\u1E86': 'W',
50925    '\u1E84': 'W',
50926    '\u1E88': 'W',
50927    '\u2C72': 'W',
50928    '\u24CD': 'X',
50929    '\uFF38': 'X',
50930    '\u1E8A': 'X',
50931    '\u1E8C': 'X',
50932    '\u24CE': 'Y',
50933    '\uFF39': 'Y',
50934    '\u1EF2': 'Y',
50935    '\u00DD': 'Y',
50936    '\u0176': 'Y',
50937    '\u1EF8': 'Y',
50938    '\u0232': 'Y',
50939    '\u1E8E': 'Y',
50940    '\u0178': 'Y',
50941    '\u1EF6': 'Y',
50942    '\u1EF4': 'Y',
50943    '\u01B3': 'Y',
50944    '\u024E': 'Y',
50945    '\u1EFE': 'Y',
50946    '\u24CF': 'Z',
50947    '\uFF3A': 'Z',
50948    '\u0179': 'Z',
50949    '\u1E90': 'Z',
50950    '\u017B': 'Z',
50951    '\u017D': 'Z',
50952    '\u1E92': 'Z',
50953    '\u1E94': 'Z',
50954    '\u01B5': 'Z',
50955    '\u0224': 'Z',
50956    '\u2C7F': 'Z',
50957    '\u2C6B': 'Z',
50958    '\uA762': 'Z',
50959    '\u24D0': 'a',
50960    '\uFF41': 'a',
50961    '\u1E9A': 'a',
50962    '\u00E0': 'a',
50963    '\u00E1': 'a',
50964    '\u00E2': 'a',
50965    '\u1EA7': 'a',
50966    '\u1EA5': 'a',
50967    '\u1EAB': 'a',
50968    '\u1EA9': 'a',
50969    '\u00E3': 'a',
50970    '\u0101': 'a',
50971    '\u0103': 'a',
50972    '\u1EB1': 'a',
50973    '\u1EAF': 'a',
50974    '\u1EB5': 'a',
50975    '\u1EB3': 'a',
50976    '\u0227': 'a',
50977    '\u01E1': 'a',
50978    '\u00E4': 'a',
50979    '\u01DF': 'a',
50980    '\u1EA3': 'a',
50981    '\u00E5': 'a',
50982    '\u01FB': 'a',
50983    '\u01CE': 'a',
50984    '\u0201': 'a',
50985    '\u0203': 'a',
50986    '\u1EA1': 'a',
50987    '\u1EAD': 'a',
50988    '\u1EB7': 'a',
50989    '\u1E01': 'a',
50990    '\u0105': 'a',
50991    '\u2C65': 'a',
50992    '\u0250': 'a',
50993    '\uA733': 'aa',
50994    '\u00E6': 'ae',
50995    '\u01FD': 'ae',
50996    '\u01E3': 'ae',
50997    '\uA735': 'ao',
50998    '\uA737': 'au',
50999    '\uA739': 'av',
51000    '\uA73B': 'av',
51001    '\uA73D': 'ay',
51002    '\u24D1': 'b',
51003    '\uFF42': 'b',
51004    '\u1E03': 'b',
51005    '\u1E05': 'b',
51006    '\u1E07': 'b',
51007    '\u0180': 'b',
51008    '\u0183': 'b',
51009    '\u0253': 'b',
51010    '\u24D2': 'c',
51011    '\uFF43': 'c',
51012    '\u0107': 'c',
51013    '\u0109': 'c',
51014    '\u010B': 'c',
51015    '\u010D': 'c',
51016    '\u00E7': 'c',
51017    '\u1E09': 'c',
51018    '\u0188': 'c',
51019    '\u023C': 'c',
51020    '\uA73F': 'c',
51021    '\u2184': 'c',
51022    '\u24D3': 'd',
51023    '\uFF44': 'd',
51024    '\u1E0B': 'd',
51025    '\u010F': 'd',
51026    '\u1E0D': 'd',
51027    '\u1E11': 'd',
51028    '\u1E13': 'd',
51029    '\u1E0F': 'd',
51030    '\u0111': 'd',
51031    '\u018C': 'd',
51032    '\u0256': 'd',
51033    '\u0257': 'd',
51034    '\uA77A': 'd',
51035    '\u01F3': 'dz',
51036    '\u01C6': 'dz',
51037    '\u24D4': 'e',
51038    '\uFF45': 'e',
51039    '\u00E8': 'e',
51040    '\u00E9': 'e',
51041    '\u00EA': 'e',
51042    '\u1EC1': 'e',
51043    '\u1EBF': 'e',
51044    '\u1EC5': 'e',
51045    '\u1EC3': 'e',
51046    '\u1EBD': 'e',
51047    '\u0113': 'e',
51048    '\u1E15': 'e',
51049    '\u1E17': 'e',
51050    '\u0115': 'e',
51051    '\u0117': 'e',
51052    '\u00EB': 'e',
51053    '\u1EBB': 'e',
51054    '\u011B': 'e',
51055    '\u0205': 'e',
51056    '\u0207': 'e',
51057    '\u1EB9': 'e',
51058    '\u1EC7': 'e',
51059    '\u0229': 'e',
51060    '\u1E1D': 'e',
51061    '\u0119': 'e',
51062    '\u1E19': 'e',
51063    '\u1E1B': 'e',
51064    '\u0247': 'e',
51065    '\u025B': 'e',
51066    '\u01DD': 'e',
51067    '\u24D5': 'f',
51068    '\uFF46': 'f',
51069    '\u1E1F': 'f',
51070    '\u0192': 'f',
51071    '\uA77C': 'f',
51072    '\u24D6': 'g',
51073    '\uFF47': 'g',
51074    '\u01F5': 'g',
51075    '\u011D': 'g',
51076    '\u1E21': 'g',
51077    '\u011F': 'g',
51078    '\u0121': 'g',
51079    '\u01E7': 'g',
51080    '\u0123': 'g',
51081    '\u01E5': 'g',
51082    '\u0260': 'g',
51083    '\uA7A1': 'g',
51084    '\u1D79': 'g',
51085    '\uA77F': 'g',
51086    '\u24D7': 'h',
51087    '\uFF48': 'h',
51088    '\u0125': 'h',
51089    '\u1E23': 'h',
51090    '\u1E27': 'h',
51091    '\u021F': 'h',
51092    '\u1E25': 'h',
51093    '\u1E29': 'h',
51094    '\u1E2B': 'h',
51095    '\u1E96': 'h',
51096    '\u0127': 'h',
51097    '\u2C68': 'h',
51098    '\u2C76': 'h',
51099    '\u0265': 'h',
51100    '\u0195': 'hv',
51101    '\u24D8': 'i',
51102    '\uFF49': 'i',
51103    '\u00EC': 'i',
51104    '\u00ED': 'i',
51105    '\u00EE': 'i',
51106    '\u0129': 'i',
51107    '\u012B': 'i',
51108    '\u012D': 'i',
51109    '\u00EF': 'i',
51110    '\u1E2F': 'i',
51111    '\u1EC9': 'i',
51112    '\u01D0': 'i',
51113    '\u0209': 'i',
51114    '\u020B': 'i',
51115    '\u1ECB': 'i',
51116    '\u012F': 'i',
51117    '\u1E2D': 'i',
51118    '\u0268': 'i',
51119    '\u0131': 'i',
51120    '\u24D9': 'j',
51121    '\uFF4A': 'j',
51122    '\u0135': 'j',
51123    '\u01F0': 'j',
51124    '\u0249': 'j',
51125    '\u24DA': 'k',
51126    '\uFF4B': 'k',
51127    '\u1E31': 'k',
51128    '\u01E9': 'k',
51129    '\u1E33': 'k',
51130    '\u0137': 'k',
51131    '\u1E35': 'k',
51132    '\u0199': 'k',
51133    '\u2C6A': 'k',
51134    '\uA741': 'k',
51135    '\uA743': 'k',
51136    '\uA745': 'k',
51137    '\uA7A3': 'k',
51138    '\u24DB': 'l',
51139    '\uFF4C': 'l',
51140    '\u0140': 'l',
51141    '\u013A': 'l',
51142    '\u013E': 'l',
51143    '\u1E37': 'l',
51144    '\u1E39': 'l',
51145    '\u013C': 'l',
51146    '\u1E3D': 'l',
51147    '\u1E3B': 'l',
51148    '\u017F': 'l',
51149    '\u0142': 'l',
51150    '\u019A': 'l',
51151    '\u026B': 'l',
51152    '\u2C61': 'l',
51153    '\uA749': 'l',
51154    '\uA781': 'l',
51155    '\uA747': 'l',
51156    '\u01C9': 'lj',
51157    '\u24DC': 'm',
51158    '\uFF4D': 'm',
51159    '\u1E3F': 'm',
51160    '\u1E41': 'm',
51161    '\u1E43': 'm',
51162    '\u0271': 'm',
51163    '\u026F': 'm',
51164    '\u24DD': 'n',
51165    '\uFF4E': 'n',
51166    '\u01F9': 'n',
51167    '\u0144': 'n',
51168    '\u00F1': 'n',
51169    '\u1E45': 'n',
51170    '\u0148': 'n',
51171    '\u1E47': 'n',
51172    '\u0146': 'n',
51173    '\u1E4B': 'n',
51174    '\u1E49': 'n',
51175    '\u019E': 'n',
51176    '\u0272': 'n',
51177    '\u0149': 'n',
51178    '\uA791': 'n',
51179    '\uA7A5': 'n',
51180    '\u01CC': 'nj',
51181    '\u24DE': 'o',
51182    '\uFF4F': 'o',
51183    '\u00F2': 'o',
51184    '\u00F3': 'o',
51185    '\u00F4': 'o',
51186    '\u1ED3': 'o',
51187    '\u1ED1': 'o',
51188    '\u1ED7': 'o',
51189    '\u1ED5': 'o',
51190    '\u00F5': 'o',
51191    '\u1E4D': 'o',
51192    '\u022D': 'o',
51193    '\u1E4F': 'o',
51194    '\u014D': 'o',
51195    '\u1E51': 'o',
51196    '\u1E53': 'o',
51197    '\u014F': 'o',
51198    '\u022F': 'o',
51199    '\u0231': 'o',
51200    '\u00F6': 'o',
51201    '\u022B': 'o',
51202    '\u1ECF': 'o',
51203    '\u0151': 'o',
51204    '\u01D2': 'o',
51205    '\u020D': 'o',
51206    '\u020F': 'o',
51207    '\u01A1': 'o',
51208    '\u1EDD': 'o',
51209    '\u1EDB': 'o',
51210    '\u1EE1': 'o',
51211    '\u1EDF': 'o',
51212    '\u1EE3': 'o',
51213    '\u1ECD': 'o',
51214    '\u1ED9': 'o',
51215    '\u01EB': 'o',
51216    '\u01ED': 'o',
51217    '\u00F8': 'o',
51218    '\u01FF': 'o',
51219    '\u0254': 'o',
51220    '\uA74B': 'o',
51221    '\uA74D': 'o',
51222    '\u0275': 'o',
51223    '\u01A3': 'oi',
51224    '\u0223': 'ou',
51225    '\uA74F': 'oo',
51226    '\u24DF': 'p',
51227    '\uFF50': 'p',
51228    '\u1E55': 'p',
51229    '\u1E57': 'p',
51230    '\u01A5': 'p',
51231    '\u1D7D': 'p',
51232    '\uA751': 'p',
51233    '\uA753': 'p',
51234    '\uA755': 'p',
51235    '\u24E0': 'q',
51236    '\uFF51': 'q',
51237    '\u024B': 'q',
51238    '\uA757': 'q',
51239    '\uA759': 'q',
51240    '\u24E1': 'r',
51241    '\uFF52': 'r',
51242    '\u0155': 'r',
51243    '\u1E59': 'r',
51244    '\u0159': 'r',
51245    '\u0211': 'r',
51246    '\u0213': 'r',
51247    '\u1E5B': 'r',
51248    '\u1E5D': 'r',
51249    '\u0157': 'r',
51250    '\u1E5F': 'r',
51251    '\u024D': 'r',
51252    '\u027D': 'r',
51253    '\uA75B': 'r',
51254    '\uA7A7': 'r',
51255    '\uA783': 'r',
51256    '\u24E2': 's',
51257    '\uFF53': 's',
51258    '\u00DF': 's',
51259    '\u015B': 's',
51260    '\u1E65': 's',
51261    '\u015D': 's',
51262    '\u1E61': 's',
51263    '\u0161': 's',
51264    '\u1E67': 's',
51265    '\u1E63': 's',
51266    '\u1E69': 's',
51267    '\u0219': 's',
51268    '\u015F': 's',
51269    '\u023F': 's',
51270    '\uA7A9': 's',
51271    '\uA785': 's',
51272    '\u1E9B': 's',
51273    '\u24E3': 't',
51274    '\uFF54': 't',
51275    '\u1E6B': 't',
51276    '\u1E97': 't',
51277    '\u0165': 't',
51278    '\u1E6D': 't',
51279    '\u021B': 't',
51280    '\u0163': 't',
51281    '\u1E71': 't',
51282    '\u1E6F': 't',
51283    '\u0167': 't',
51284    '\u01AD': 't',
51285    '\u0288': 't',
51286    '\u2C66': 't',
51287    '\uA787': 't',
51288    '\uA729': 'tz',
51289    '\u24E4': 'u',
51290    '\uFF55': 'u',
51291    '\u00F9': 'u',
51292    '\u00FA': 'u',
51293    '\u00FB': 'u',
51294    '\u0169': 'u',
51295    '\u1E79': 'u',
51296    '\u016B': 'u',
51297    '\u1E7B': 'u',
51298    '\u016D': 'u',
51299    '\u00FC': 'u',
51300    '\u01DC': 'u',
51301    '\u01D8': 'u',
51302    '\u01D6': 'u',
51303    '\u01DA': 'u',
51304    '\u1EE7': 'u',
51305    '\u016F': 'u',
51306    '\u0171': 'u',
51307    '\u01D4': 'u',
51308    '\u0215': 'u',
51309    '\u0217': 'u',
51310    '\u01B0': 'u',
51311    '\u1EEB': 'u',
51312    '\u1EE9': 'u',
51313    '\u1EEF': 'u',
51314    '\u1EED': 'u',
51315    '\u1EF1': 'u',
51316    '\u1EE5': 'u',
51317    '\u1E73': 'u',
51318    '\u0173': 'u',
51319    '\u1E77': 'u',
51320    '\u1E75': 'u',
51321    '\u0289': 'u',
51322    '\u24E5': 'v',
51323    '\uFF56': 'v',
51324    '\u1E7D': 'v',
51325    '\u1E7F': 'v',
51326    '\u028B': 'v',
51327    '\uA75F': 'v',
51328    '\u028C': 'v',
51329    '\uA761': 'vy',
51330    '\u24E6': 'w',
51331    '\uFF57': 'w',
51332    '\u1E81': 'w',
51333    '\u1E83': 'w',
51334    '\u0175': 'w',
51335    '\u1E87': 'w',
51336    '\u1E85': 'w',
51337    '\u1E98': 'w',
51338    '\u1E89': 'w',
51339    '\u2C73': 'w',
51340    '\u24E7': 'x',
51341    '\uFF58': 'x',
51342    '\u1E8B': 'x',
51343    '\u1E8D': 'x',
51344    '\u24E8': 'y',
51345    '\uFF59': 'y',
51346    '\u1EF3': 'y',
51347    '\u00FD': 'y',
51348    '\u0177': 'y',
51349    '\u1EF9': 'y',
51350    '\u0233': 'y',
51351    '\u1E8F': 'y',
51352    '\u00FF': 'y',
51353    '\u1EF7': 'y',
51354    '\u1E99': 'y',
51355    '\u1EF5': 'y',
51356    '\u01B4': 'y',
51357    '\u024F': 'y',
51358    '\u1EFF': 'y',
51359    '\u24E9': 'z',
51360    '\uFF5A': 'z',
51361    '\u017A': 'z',
51362    '\u1E91': 'z',
51363    '\u017C': 'z',
51364    '\u017E': 'z',
51365    '\u1E93': 'z',
51366    '\u1E95': 'z',
51367    '\u01B6': 'z',
51368    '\u0225': 'z',
51369    '\u0240': 'z',
51370    '\u2C6C': 'z',
51371    '\uA763': 'z',
51372    '\u0386': '\u0391',
51373    '\u0388': '\u0395',
51374    '\u0389': '\u0397',
51375    '\u038A': '\u0399',
51376    '\u03AA': '\u0399',
51377    '\u038C': '\u039F',
51378    '\u038E': '\u03A5',
51379    '\u03AB': '\u03A5',
51380    '\u038F': '\u03A9',
51381    '\u03AC': '\u03B1',
51382    '\u03AD': '\u03B5',
51383    '\u03AE': '\u03B7',
51384    '\u03AF': '\u03B9',
51385    '\u03CA': '\u03B9',
51386    '\u0390': '\u03B9',
51387    '\u03CC': '\u03BF',
51388    '\u03CD': '\u03C5',
51389    '\u03CB': '\u03C5',
51390    '\u03B0': '\u03C5',
51391    '\u03C9': '\u03C9',
51392    '\u03C2': '\u03C3'
51393  };
51394
51395  return diacritics;
51396});
51397
51398define('select2/data/base',[
51399  '../utils'
51400], function (Utils) {
51401  function BaseAdapter ($element, options) {
51402    BaseAdapter.__super__.constructor.call(this);
51403  }
51404
51405  Utils.Extend(BaseAdapter, Utils.Observable);
51406
51407  BaseAdapter.prototype.current = function (callback) {
51408    throw new Error('The `current` method must be defined in child classes.');
51409  };
51410
51411  BaseAdapter.prototype.query = function (params, callback) {
51412    throw new Error('The `query` method must be defined in child classes.');
51413  };
51414
51415  BaseAdapter.prototype.bind = function (container, $container) {
51416    // Can be implemented in subclasses
51417  };
51418
51419  BaseAdapter.prototype.destroy = function () {
51420    // Can be implemented in subclasses
51421  };
51422
51423  BaseAdapter.prototype.generateResultId = function (container, data) {
51424    var id = container.id + '-result-';
51425
51426    id += Utils.generateChars(4);
51427
51428    if (data.id != null) {
51429      id += '-' + data.id.toString();
51430    } else {
51431      id += '-' + Utils.generateChars(4);
51432    }
51433    return id;
51434  };
51435
51436  return BaseAdapter;
51437});
51438
51439define('select2/data/select',[
51440  './base',
51441  '../utils',
51442  'jquery'
51443], function (BaseAdapter, Utils, $) {
51444  function SelectAdapter ($element, options) {
51445    this.$element = $element;
51446    this.options = options;
51447
51448    SelectAdapter.__super__.constructor.call(this);
51449  }
51450
51451  Utils.Extend(SelectAdapter, BaseAdapter);
51452
51453  SelectAdapter.prototype.current = function (callback) {
51454    var data = [];
51455    var self = this;
51456
51457    this.$element.find(':selected').each(function () {
51458      var $option = $(this);
51459
51460      var option = self.item($option);
51461
51462      data.push(option);
51463    });
51464
51465    callback(data);
51466  };
51467
51468  SelectAdapter.prototype.select = function (data) {
51469    var self = this;
51470
51471    // If data.element is a DOM nose, use it instead
51472    if ($(data.element).is('option')) {
51473      data.element.selected = true;
51474
51475      this.$element.trigger('change');
51476
51477      return;
51478    }
51479
51480    if (this.$element.prop('multiple')) {
51481      this.current(function (currentData) {
51482        var val = [];
51483
51484        data = [data];
51485        data.push.apply(data, currentData);
51486
51487        for (var d = 0; d < data.length; d++) {
51488          id = data[d].id;
51489
51490          if (val.indexOf(id) === -1) {
51491            val.push(id);
51492          }
51493        }
51494
51495        self.$element.val(val);
51496        self.$element.trigger('change');
51497      });
51498    } else {
51499      var val = data.id;
51500
51501      this.$element.val(val);
51502
51503      this.$element.trigger('change');
51504    }
51505  };
51506
51507  SelectAdapter.prototype.unselect = function (data) {
51508    var self = this;
51509
51510    if (!this.$element.prop('multiple')) {
51511      return;
51512    }
51513
51514    if ($(data.element).is('option')) {
51515      data.element.selected = false;
vendor: 24,656 bytes, lines 51516-52596
51516
51517      this.$element.trigger('change');
51518
51519      return;
51520    }
51521
51522    this.current(function (currentData) {
51523      var val = [];
51524
51525      for (var d = 0; d < currentData.length; d++) {
51526        id = currentData[d].id;
51527
51528        if (id !== data.id && val.indexOf(id) === -1) {
51529          val.push(id);
51530        }
51531      }
51532
51533      self.$element.val(val);
51534
51535      self.$element.trigger('change');
51536    });
51537  };
51538
51539  SelectAdapter.prototype.bind = function (container, $container) {
51540    var self = this;
51541
51542    this.container = container;
51543
51544    container.on('select', function (params) {
51545      self.select(params.data);
51546    });
51547
51548    container.on('unselect', function (params) {
51549      self.unselect(params.data);
51550    });
51551  };
51552
51553  SelectAdapter.prototype.destroy = function () {
51554    // Remove anything added to child elements
51555    this.$element.find('*').each(function () {
51556      // Remove any custom data set by Select2
51557      $.removeData(this, 'data');
51558    });
51559  };
51560
51561  SelectAdapter.prototype.query = function (params, callback) {
51562    var data = [];
51563    var self = this;
51564
51565    var $options = this.$element.children();
51566
51567    $options.each(function () {
51568      var $option = $(this);
51569
51570      if (!$option.is('option') && !$option.is('optgroup')) {
51571        return;
51572      }
51573
51574      var option = self.item($option);
51575
51576      var matches = self.matches(params, option);
51577
51578      if (matches !== null) {
51579        data.push(matches);
51580      }
51581    });
51582
51583    callback({
51584      results: data
51585    });
51586  };
51587
51588  SelectAdapter.prototype.option = function (data) {
51589    var option;
51590
51591    if (data.children) {
51592      option = document.createElement('optgroup');
51593      option.label = data.text;
51594    } else {
51595      option = document.createElement('option');
51596      option.innerText = data.text;
51597    }
51598
51599    if (data.id) {
51600      option.value = data.id;
51601    }
51602
51603    if (data.disabled) {
51604      option.disabled = true;
51605    }
51606
51607    if (data.selected) {
51608      option.selected = true;
51609    }
51610
51611    var $option = $(option);
51612
51613    var normalizedData = this._normalizeItem(data);
51614    normalizedData.element = option;
51615
51616    // Override the option's data with the combined data
51617    $.data(option, 'data', normalizedData);
51618
51619    return $option;
51620  };
51621
51622  SelectAdapter.prototype.item = function ($option) {
51623    var data = {};
51624
51625    data = $.data($option[0], 'data');
51626
51627    if (data != null) {
51628      return data;
51629    }
51630
51631    if ($option.is('option')) {
51632      data = {
51633        id: $option.val(),
51634        text: $option.html(),
51635        disabled: $option.prop('disabled'),
51636        selected: $option.prop('selected')
51637      };
51638    } else if ($option.is('optgroup')) {
51639      data = {
51640        text: $option.prop('label'),
51641        children: []
51642      };
51643
51644      var $children = $option.children('option');
51645      var children = [];
51646
51647      for (var c = 0; c < $children.length; c++) {
51648        var $child = $($children[c]);
51649
51650        var child = this.item($child);
51651
51652        children.push(child);
51653      }
51654
51655      data.children = children;
51656    }
51657
51658    data = this._normalizeItem(data);
51659    data.element = $option[0];
51660
51661    $.data($option[0], 'data', data);
51662
51663    return data;
51664  };
51665
51666  SelectAdapter.prototype._normalizeItem = function (item) {
51667    if (!$.isPlainObject(item)) {
51668      item = {
51669        id: item,
51670        text: item
51671      };
51672    }
51673
51674    item = $.extend({}, {
51675      text: ''
51676    }, item);
51677
51678    var defaults = {
51679      selected: false,
51680      disabled: false
51681    };
51682
51683    if (item.id != null) {
51684      item.id = item.id.toString();
51685    }
51686
51687    if (item.text != null) {
51688      item.text = item.text.toString();
51689    }
51690
51691    if (item._resultId == null && item.id && this.container != null) {
51692      item._resultId = this.generateResultId(this.container, item);
51693    }
51694
51695    return $.extend({}, defaults, item);
51696  };
51697
51698  SelectAdapter.prototype.matches = function (params, data) {
51699    var matcher = this.options.get('matcher');
51700
51701    return matcher(params, data);
51702  };
51703
51704  return SelectAdapter;
51705});
51706
51707define('select2/data/array',[
51708  './select',
51709  '../utils',
51710  'jquery'
51711], function (SelectAdapter, Utils, $) {
51712  function ArrayAdapter ($element, options) {
51713    var data = options.get('data');
51714
51715    ArrayAdapter.__super__.constructor.call(this, $element, options);
51716
51717    $element.append(this.convertToOptions(data));
51718  }
51719
51720  Utils.Extend(ArrayAdapter, SelectAdapter);
51721
51722  ArrayAdapter.prototype.select = function (data) {
51723    var $option = this.$element.find('option[value="' + data.id + '"]');
51724
51725    if ($option.length === 0) {
51726      $option = this.option(data);
51727
51728      this.$element.append($option);
51729    }
51730
51731    ArrayAdapter.__super__.select.call(this, data);
51732  };
51733
51734  ArrayAdapter.prototype.convertToOptions = function (data) {
51735    var self = this;
51736
51737    var $existing = this.$element.find('option');
51738    var existingIds = $existing.map(function () {
51739      return self.item($(this)).id;
51740    }).get();
51741
51742    var $options = [];
51743
51744    // Filter out all items except for the one passed in the argument
51745    function onlyItem (item) {
51746      return function () {
51747        return $(this).val() == item.id;
51748      };
51749    }
51750
51751    for (var d = 0; d < data.length; d++) {
51752      var item = this._normalizeItem(data[d]);
51753
51754      // Skip items which were pre-loaded, only merge the data
51755      if (existingIds.indexOf(item.id) >= 0) {
51756        var $existingOption = $existing.filter(onlyItem(item));
51757
51758        var existingData = this.item($existingOption);
51759        var newData = $.extend(true, {}, existingData, item);
51760
51761        var $newOption = this.option(existingData);
51762
51763        $existingOption.replaceWith($newOption);
51764
51765        continue;
51766      }
51767
51768      var $option = this.option(item);
51769
51770      if (item.children) {
51771        var $children = this.convertToOptions(item.children);
51772
51773        $option.append($children);
51774      }
51775
51776      $options.push($option);
51777    }
51778
51779    return $options;
51780  };
51781
51782  return ArrayAdapter;
51783});
51784
51785define('select2/data/ajax',[
51786  './array',
51787  '../utils',
51788  'jquery'
51789], function (ArrayAdapter, Utils, $) {
51790  function AjaxAdapter ($element, options) {
51791    this.ajaxOptions = options.get('ajax');
51792
51793    if (this.ajaxOptions.processResults != null) {
51794      this.processResults = this.ajaxOptions.processResults;
51795    }
51796
51797    ArrayAdapter.__super__.constructor.call(this, $element, options);
51798  }
51799
51800  Utils.Extend(AjaxAdapter, ArrayAdapter);
51801
51802  AjaxAdapter.prototype.processResults = function (results) {
51803    return results;
51804  };
51805
51806  AjaxAdapter.prototype.query = function (params, callback) {
51807    var matches = [];
51808    var self = this;
51809
51810    if (this._request) {
51811      this._request.abort();
51812      this._request = null;
51813    }
51814
51815    var options = $.extend({
51816      type: 'GET'
51817    }, this.ajaxOptions);
51818
51819    if (typeof options.url === 'function') {
51820      options.url = options.url(params);
51821    }
51822
51823    if (typeof options.data === 'function') {
51824      options.data = options.data(params);
51825    }
51826
51827    function request () {
51828      var $request = $.ajax(options);
51829
51830      $request.success(function (data) {
51831        var results = self.processResults(data, params);
51832
51833        callback(results);
51834      });
51835
51836      self._request = $request;
51837    }
51838
51839    if (this.ajaxOptions.delay && params.term !== '') {
51840      if (this._queryTimeout) {
51841        window.clearTimeout(this._queryTimeout);
51842      }
51843
51844      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
51845    } else {
51846      request();
51847    }
51848  };
51849
51850  return AjaxAdapter;
51851});
51852
51853define('select2/data/tags',[
51854
51855], function () {
51856  function Tags (decorated, $element, options) {
51857    var tags = options.get('tags');
51858
51859    var createTag = options.get('createTag');
51860
51861    if (createTag !== undefined) {
51862      this.createTag = createTag;
51863    }
51864
51865    decorated.call(this, $element, options);
51866
51867    if ($.isArray(tags)) {
51868      for (var t = 0; t < tags.length; t++) {
51869        var tag = tags[t];
51870        var item = this._normalizeItem(tag);
51871
51872        var $option = this.option(item);
51873
51874        this.$element.append($option);
51875      }
51876    }
51877  }
51878
51879  Tags.prototype.query = function (decorated, params, callback) {
51880    var self = this;
51881
51882    this._removeOldTags();
51883
51884    if (params.term == null || params.term === '' || params.page != null) {
51885      decorated.call(this, params, callback);
51886      return;
51887    }
51888
51889    function wrapper (obj, child) {
51890      var data = obj.results;
51891
51892      for (var i = 0; i < data.length; i++) {
51893        var option = data[i];
51894
51895        var checkChildren = (
51896          option.children != null &&
51897          !wrapper({
51898            results: option.children
51899          }, true)
51900        );
51901
51902        var checkText = option.text === params.term;
51903
51904        if (checkText || checkChildren) {
51905          if (child) {
51906            return false;
51907          }
51908
51909          obj.data = data;
51910          callback(obj);
51911
51912          return;
51913        }
51914      }
51915
51916      if (child) {
51917        return true;
51918      }
51919
51920      var tag = self.createTag(params);
51921
51922      if (tag != null) {
51923        var $option = self.option(tag);
51924        $option.attr('data-select2-tag', true);
51925
51926        self.$element.append($option);
51927
51928        self.insertTag(data, tag);
51929      }
51930
51931      obj.results = data;
51932
51933      callback(obj);
51934    }
51935
51936    decorated.call(this, params, wrapper);
51937  };
51938
51939  Tags.prototype.createTag = function (decorated, params) {
51940    return {
51941      id: params.term,
51942      text: params.term
51943    };
51944  };
51945
51946  Tags.prototype.insertTag = function (_, data, tag) {
51947    data.unshift(tag);
51948  };
51949
51950  Tags.prototype._removeOldTags = function (_) {
51951    var tag = this._lastTag;
51952
51953    var $options = this.$element.find('option[data-select2-tag]');
51954
51955    $options.each(function () {
51956      if (this.selected) {
51957        return;
51958      }
51959
51960      $(this).remove();
51961    });
51962  };
51963
51964  return Tags;
51965});
51966
51967define('select2/data/tokenizer',[
51968
51969], function () {
51970  function Tokenizer (decorated, $element, options) {
51971    var tokenizer = options.get('tokenizer');
51972
51973    if (tokenizer !== undefined) {
51974      this.tokenizer = tokenizer;
51975    }
51976
51977    decorated.call(this, $element, options);
51978  }
51979
51980  Tokenizer.prototype.bind = function (decorated, container, $container) {
51981    decorated.call(this, container, $container);
51982
51983    this.$search =  container.dropdown.$search || container.selection.$search ||
51984      $container.find('.select2-search__field');
51985  };
51986
51987  Tokenizer.prototype.query = function (decorated, params, callback) {
51988    var self = this;
51989
51990    function select (data) {
51991      self.select(data);
51992    }
51993
51994    params.term = params.term || '';
51995
51996    var tokenData = this.tokenizer(params, this.options, select);
51997
51998    if (tokenData.term !== params.term) {
51999      // Replace the search term if we have the search box
52000      if (this.$search.length) {
52001        this.$search.val(tokenData.term);
52002        this.$search.focus();
52003      }
52004
52005      params.term = tokenData.term;
52006    }
52007
52008    decorated.call(this, params, callback);
52009  };
52010
52011  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
52012    var separators = options.get('tokenSeparators') || [];
52013    var term = params.term;
52014    var i = 0;
52015
52016    var createTag = this.createTag || function (params) {
52017      return {
52018        id: params.term,
52019        text: params.term
52020      };
52021    };
52022
52023    while (i < term.length) {
52024      var termChar = term[i];
52025
52026      if (separators.indexOf(termChar) === -1) {
52027        i++;
52028
52029        continue;
52030      }
52031
52032      var part = term.substr(0, i);
52033      var partParams = $.extend({}, params, {
52034        term: part
52035      });
52036
52037      var data = createTag(partParams);
52038
52039      callback(data);
52040
52041      // Reset the term to not include the tokenized portion
52042      term = term.substr(i + 1) || '';
52043      i = 0;
52044    }
52045
52046    return {
52047      term: term
52048    };
52049  };
52050
52051  return Tokenizer;
52052});
52053
52054define('select2/data/minimumInputLength',[
52055
52056], function () {
52057  function MinimumInputLength (decorated, $e, options) {
52058    this.minimumInputLength = options.get('minimumInputLength');
52059
52060    decorated.call(this, $e, options);
52061  }
52062
52063  MinimumInputLength.prototype.query = function (decorated, params, callback) {
52064    params.term = params.term || '';
52065
52066    if (params.term.length < this.minimumInputLength) {
52067      this.trigger('results:message', {
52068        message: 'inputTooShort',
52069        args: {
52070          minimum: this.minimumInputLength,
52071          input: params.term,
52072          params: params
52073        }
52074      });
52075
52076      return;
52077    }
52078
52079    decorated.call(this, params, callback);
52080  };
52081
52082  return MinimumInputLength;
52083});
52084
52085define('select2/data/maximumInputLength',[
52086
52087], function () {
52088  function MaximumInputLength (decorated, $e, options) {
52089    this.maximumInputLength = options.get('maximumInputLength');
52090
52091    decorated.call(this, $e, options);
52092  }
52093
52094  MaximumInputLength.prototype.query = function (decorated, params, callback) {
52095    params.term = params.term || '';
52096
52097    if (this.maximumInputLength > 0 &&
52098        params.term.length > this.maximumInputLength) {
52099      this.trigger('results:message', {
52100        message: 'inputTooLong',
52101        args: {
52102          minimum: this.maximumInputLength,
52103          input: params.term,
52104          params: params
52105        }
52106      });
52107
52108      return;
52109    }
52110
52111    decorated.call(this, params, callback);
52112  };
52113
52114  return MaximumInputLength;
52115});
52116
52117define('select2/data/maximumSelectionLength',[
52118
52119], function (){
52120  function MaximumSelectionLength (decorated, $e, options) {
52121    this.maximumSelectionLength = options.get('maximumSelectionLength');
52122
52123    decorated.call(this, $e, options);
52124  }
52125
52126  MaximumSelectionLength.prototype.query =
52127    function (decorated, params, callback) {
52128      var self = this;
52129
52130      this.current(function (currentData) {
52131        var count = currentData != null ? currentData.length : 0;
52132        if (self.maximumSelectionLength > 0 &&
52133          count >= self.maximumSelectionLength) {
52134          self.trigger('results:message', {
52135            message: 'maximumSelected',
52136            args: {
52137              maximum: self.maximumSelectionLength
52138            }
52139          });
52140          return;
52141        }
52142        decorated.call(self, params, callback);
52143      });
52144  };
52145
52146  return MaximumSelectionLength;
52147});
52148
52149define('select2/dropdown',[
52150  './utils'
52151], function (Utils) {
52152  function Dropdown ($element, options) {
52153    this.$element = $element;
52154    this.options = options;
52155
52156    Dropdown.__super__.constructor.call(this);
52157  }
52158
52159  Utils.Extend(Dropdown, Utils.Observable);
52160
52161  Dropdown.prototype.render = function () {
52162    var $dropdown = $(
52163      '<span class="select2-dropdown">' +
52164        '<span class="select2-results"></span>' +
52165      '</span>'
52166    );
52167
52168    $dropdown.attr('dir', this.options.get('dir'));
52169
52170    this.$dropdown = $dropdown;
52171
52172    return $dropdown;
52173  };
52174
52175  Dropdown.prototype.position = function ($dropdown, $container) {
52176    // Should be implmented in subclasses
52177  };
52178
52179  Dropdown.prototype.destroy = function () {
52180    // Remove the dropdown from the DOM
52181    this.$dropdown.remove();
52182  };
52183
52184  Dropdown.prototype.bind = function (container, $container) {
52185    var self = this;
52186
52187    container.on('select', function (params) {
52188      self._onSelect(params);
52189    });
52190
52191    container.on('unselect', function (params) {
52192      self._onUnSelect(params);
52193    });
52194  };
52195
52196  Dropdown.prototype._onSelect = function () {
52197    this.trigger('close');
52198  };
52199
52200  Dropdown.prototype._onUnSelect = function () {
52201    this.trigger('close');
52202  };
52203
52204  return Dropdown;
52205});
52206
52207define('select2/dropdown/search',[
52208  '../utils'
52209], function (Utils) {
52210  function Search () { }
52211
52212  Search.prototype.render = function (decorated) {
52213    var $rendered = decorated.call(this);
52214
52215    var $search = $(
52216      '<span class="select2-search select2-search--dropdown">' +
52217        '<input class="select2-search__field" type="search" tabindex="-1"' +
52218        ' role="textbox" />' +
52219      '</span>'
52220    );
52221
52222    this.$searchContainer = $search;
52223    this.$search = $search.find('input');
52224
52225    $rendered.prepend($search);
52226
52227    return $rendered;
52228  };
52229
52230  Search.prototype.bind = function (decorated, container, $container) {
52231    var self = this;
52232
52233    decorated.call(this, container, $container);
52234
52235    this.$search.on('keydown', function (evt) {
52236      self.trigger('keypress', evt);
52237
52238      self._keyUpPrevented = evt.isDefaultPrevented();
52239    });
52240
52241    this.$search.on('keyup', function (evt) {
52242      self.handleSearch(evt);
52243    });
52244
52245    container.on('open', function () {
52246      self.$search.attr('tabindex', 0);
52247
52248      self.$search.focus();
52249
52250      window.setTimeout(function () {
52251        self.$search.focus();
52252      }, 0);
52253    });
52254
52255    container.on('close', function () {
52256      self.$search.attr('tabindex', -1);
52257
52258      self.$search.val('');
52259    });
52260
52261    container.on('results:all', function (params) {
52262      if (params.query.term == null || params.query.term === '') {
52263        var showSearch = self.showSearch(params);
52264
52265        if (showSearch) {
52266          self.$searchContainer.removeClass('select2-search--hide');
52267        } else {
52268          self.$searchContainer.addClass('select2-search--hide');
52269        }
52270      }
52271    });
52272  };
52273
52274  Search.prototype.handleSearch = function (evt) {
52275    if (!this._keyUpPrevented) {
52276      var input = this.$search.val();
52277
52278      this.trigger('query', {
52279        term: input
52280      });
52281    }
52282
52283    this._keyUpPrevented = false;
52284  };
52285
52286  Search.prototype.showSearch = function (_, params) {
52287    return true;
52288  };
52289
52290  return Search;
52291});
52292
52293define('select2/dropdown/hidePlaceholder',[
52294
52295], function () {
52296  function HidePlaceholder (decorated, $element, options, dataAdapter) {
52297    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
52298
52299    decorated.call(this, $element, options, dataAdapter);
52300  }
52301
52302  HidePlaceholder.prototype.append = function (decorated, data) {
52303    data.results = this.removePlaceholder(data.results);
52304
52305    decorated.call(this, data);
52306  };
52307
52308  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
52309    if (typeof placeholder === 'string') {
52310      placeholder = {
52311        id: '',
52312        text: placeholder
52313      };
52314    }
52315
52316    return placeholder;
52317  };
52318
52319  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
52320    var modifiedData = data.slice(0);
52321
52322    for (var d = data.length - 1; d >= 0; d--) {
52323      var item = data[d];
52324
52325      if (this.placeholder.id === item.id) {
52326        modifiedData.splice(d, 1);
52327      }
52328    }
52329
52330    return modifiedData;
52331  };
52332
52333  return HidePlaceholder;
52334});
52335
52336define('select2/dropdown/infiniteScroll',[
52337  'jquery'
52338], function ($) {
52339  function InfiniteScroll (decorated, $element, options, dataAdapter) {
52340    this.lastParams = {};
52341
52342    decorated.call(this, $element, options, dataAdapter);
52343
52344    this.$loadingMore = this.createLoadingMore();
52345    this.loading = false;
52346  }
52347
52348  InfiniteScroll.prototype.append = function (decorated, data) {
52349    this.$loadingMore.remove();
52350    this.loading = false;
52351
52352    decorated.call(this, data);
52353
52354    if (this.showLoadingMore(data)) {
52355      this.$results.append(this.$loadingMore);
52356    }
52357  };
52358
52359  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
52360    var self = this;
52361
52362    decorated.call(this, container, $container);
52363
52364    container.on('query', function (params) {
52365      self.lastParams = params;
52366      self.loading = true;
52367    });
52368
52369    container.on('query:append', function (params) {
52370      self.lastParams = params;
52371      self.loading = true;
52372    });
52373
52374    this.$results.on('scroll', function () {
52375      var isLoadMoreVisible = $.contains(
52376        document.documentElement,
52377        self.$loadingMore[0]
52378      );
52379
52380      if (self.loading || !isLoadMoreVisible) {
52381        return;
52382      }
52383
52384      var currentOffset = self.$results.offset().top +
52385        self.$results.outerHeight(false);
52386      var loadingMoreOffset = self.$loadingMore.offset().top +
52387        self.$loadingMore.outerHeight(false);
52388
52389      if (currentOffset + 50 >= loadingMoreOffset) {
52390        self.loadMore();
52391      }
52392    });
52393  };
52394
52395  InfiniteScroll.prototype.loadMore = function () {
52396    this.loading = true;
52397
52398    var params = $.extend({}, {page: 1}, this.lastParams);
52399
52400    params.page++;
52401
52402    this.trigger('query:append', params);
52403  };
52404
52405  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
52406    return data.pagination && data.pagination.more;
52407  };
52408
52409  InfiniteScroll.prototype.createLoadingMore = function () {
52410    var $option = $(
52411      '<li class="option load-more" role="treeitem"></li>'
52412    );
52413
52414    var message = this.options.get('translations').get('loadingMore');
52415
52416    $option.html(message(this.lastParams));
52417
52418    return $option;
52419  };
52420
52421  return InfiniteScroll;
52422});
52423
52424define('select2/dropdown/attachBody',[
52425
52426], function () {
52427  function AttachBody (decorated, $element, options) {
52428    this.$dropdownParent = options.get('dropdownParent') || document.body;
52429
52430    decorated.call(this, $element, options);
52431  }
52432
52433  AttachBody.prototype.bind = function (decorated, container, $container) {
52434    var self = this;
52435
52436    var setupResultsEvents = false;
52437
52438    decorated.call(this, container, $container);
52439
52440    container.on('open', function () {
52441      self._showDropdown();
52442
52443      if (!setupResultsEvents) {
52444        setupResultsEvents = true;
52445
52446        container.on('results:all', function () {
52447          self._positionDropdown();
52448        });
52449
52450        container.on('results:append', function () {
52451          self._positionDropdown();
52452        });
52453      }
52454    });
52455
52456    container.on('close', function () {
52457      self._hideDropdown();
52458    });
52459
52460    this.$dropdownContainer.on('mousedown', function (evt) {
52461      evt.stopPropagation();
52462    });
52463  };
52464
52465  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
52466    // Clone all of the container classes
52467    $dropdown.attr('class', $container.attr('class'));
52468
52469    $dropdown.removeClass('select2');
52470    $dropdown.addClass('select2-container--open');
52471
52472    $dropdown.css({
52473      position: 'absolute',
52474      top: -999999
52475    });
52476
52477    $dropdown.width($container.outerWidth(false));
52478
52479    this.$container = $container;
52480  };
52481
52482  AttachBody.prototype.render = function (decorated) {
52483    var $container = $('<span></span>');
52484
52485    var $dropdown = decorated.call(this);
52486    $container.append($dropdown);
52487
52488    this.$dropdownContainer = $container;
52489
52490    return $container;
52491  };
52492
52493  AttachBody.prototype._hideDropdown = function (decorated) {
52494    this.$dropdownContainer.detach();
52495  };
52496
52497  AttachBody.prototype._positionDropdown = function () {
52498    var $window = $(window);
52499
52500    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
52501    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
52502
52503    var newDirection = null;
52504
52505    var position = this.$container.position();
52506    var offset = this.$container.offset();
52507
52508    offset.bottom = offset.top + this.$container.outerHeight(false);
52509
52510    var container = {
52511      height: this.$container.outerHeight(false)
52512    };
52513
52514    container.top = offset.top;
52515    container.bottom = offset.top + container.height;
52516
52517    var dropdown = {
52518      height: this.$dropdown.outerHeight(false)
52519    };
52520
52521    var viewport = {
52522      top: $window.scrollTop(),
52523      bottom: $window.scrollTop() + $window.height()
52524    };
52525
52526    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
52527    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
52528
52529    var css = {
52530      left: offset.left,
52531      top: container.bottom
52532    };
52533
52534    if (!isCurrentlyAbove && !isCurrentlyBelow) {
52535      newDirection = 'below';
52536    }
52537
52538    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
52539      newDirection = 'above';
52540    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
52541      newDirection = 'below';
52542    }
52543
52544    if (newDirection == 'above' || isCurrentlyAbove) {
52545      css.top = container.top - dropdown.height;
52546    }
52547
52548    if (newDirection != null) {
52549      this.$dropdown
52550        .removeClass('select2-dropdown--below select2-dropdown--above')
52551        .addClass('select2-dropdown--' + newDirection);
52552      this.$container
52553        .removeClass('select2-container--below select2-container--above')
52554        .addClass('select2-container--' + newDirection);
52555    }
52556
52557    this.$dropdownContainer.css(css);
52558  };
52559
52560  AttachBody.prototype._showDropdown = function (decorated) {
52561    this.$dropdownContainer.appendTo(this.$dropdownParent);
52562
52563    this._positionDropdown();
52564  };
52565
52566  return AttachBody;
52567});
52568
52569define('select2/dropdown/minimumResultsForSearch',[
52570
52571], function () {
52572  function countResults (data) {
52573    count = 0;
52574
52575    for (var d = 0; d < data.length; d++) {
52576      var item = data[d];
52577
52578      if (item.children) {
52579        count += countResults(item.children);
52580      } else {
52581        count++;
52582      }
52583    }
52584
52585    return count;
52586  }
52587
52588  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
52589    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
52590
52591    decorated.call(this, $element, options, dataAdapter);
52592  }
52593
52594  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
52595    if (countResults(params.data.results) < this.minimumResultsForSearch) {
52596      return false;
vendor: 4,704 bytes, lines 52597-52795
52597    }
52598
52599    return decorated.call(this, params);
52600  };
52601
52602  return MinimumResultsForSearch;
52603});
52604
52605define('select2/dropdown/selectOnClose',[
52606
52607], function () {
52608  function SelectOnClose () { }
52609
52610  SelectOnClose.prototype.bind = function (decorated, container, $container) {
52611    var self = this;
52612
52613    decorated.call(this, container, $container);
52614
52615    container.on('close', function () {
52616      self._handleSelectOnClose();
52617    });
52618  };
52619
52620  SelectOnClose.prototype._handleSelectOnClose = function () {
52621    var $highlightedResults = this.getHighlightedResults();
52622
52623    if ($highlightedResults.length < 1) {
52624      return;
52625    }
52626
52627    $highlightedResults.trigger('mouseup');
52628  };
52629
52630  return SelectOnClose;
52631});
52632
52633define('select2/i18n/en',[],function () {
52634  // English
52635  return {
52636    errorLoading: function () {
52637      return 'The results could not be loaded.';
52638    },
52639    inputTooLong: function (args) {
52640      var overChars = args.input.length - args.maximum;
52641
52642      var message = 'Please delete ' + overChars + ' character';
52643
52644      if (overChars != 1) {
52645        message += 's';
52646      }
52647
52648      return message;
52649    },
52650    inputTooShort: function (args) {
52651      var remainingChars = args.minimum - args.input.length;
52652
52653      var message = 'Please enter ' + remainingChars + ' or more characters';
52654
52655      return message;
52656    },
52657    loadingMore: function () {
52658      return 'Loading more results…';
52659    },
52660    maximumSelected: function (args) {
52661      var message = 'You can only select ' + args.maximum + ' item';
52662
52663      if (args.maximum != 1) {
52664        message += 's';
52665      }
52666
52667      return message;
52668    },
52669    noResults: function () {
52670      return 'No results found';
52671    },
52672    searching: function () {
52673      return 'Searching…';
52674    }
52675  };
52676});
52677
52678define('select2/defaults',[
52679  'jquery',
52680  './results',
52681
52682  './selection/single',
52683  './selection/multiple',
52684  './selection/placeholder',
52685  './selection/allowClear',
52686  './selection/search',
52687  './selection/eventRelay',
52688
52689  './utils',
52690  './translation',
52691  './diacritics',
52692
52693  './data/select',
52694  './data/array',
52695  './data/ajax',
52696  './data/tags',
52697  './data/tokenizer',
52698  './data/minimumInputLength',
52699  './data/maximumInputLength',
52700  './data/maximumSelectionLength',
52701
52702  './dropdown',
52703  './dropdown/search',
52704  './dropdown/hidePlaceholder',
52705  './dropdown/infiniteScroll',
52706  './dropdown/attachBody',
52707  './dropdown/minimumResultsForSearch',
52708  './dropdown/selectOnClose',
52709
52710  './i18n/en'
52711], function ($, ResultsList,
52712
52713             SingleSelection, MultipleSelection, Placeholder, AllowClear,
52714             SelectionSearch, EventRelay,
52715
52716             Utils, Translation, DIACRITICS,
52717
52718             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
52719             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
52720
52721             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
52722             AttachBody, MinimumResultsForSearch, SelectOnClose,
52723
52724             EnglishTranslation) {
52725  function Defaults () {
52726    this.reset();
52727  }
52728
52729  Defaults.prototype.apply = function (options) {
52730    options = $.extend({}, this.defaults, options);
52731
52732    if (options.dataAdapter == null) {
52733      if (options.ajax != null) {
52734        options.dataAdapter = AjaxData;
52735      } else if (options.data != null) {
52736        options.dataAdapter = ArrayData;
52737      } else {
52738        options.dataAdapter = SelectData;
52739      }
52740
52741      if (options.minimumInputLength > 0) {
52742        options.dataAdapter = Utils.Decorate(
52743          options.dataAdapter,
52744          MinimumInputLength
52745        );
52746      }
52747
52748      if (options.maximumInputLength > 0) {
52749        options.dataAdapter = Utils.Decorate(
52750          options.dataAdapter,
52751          MaximumInputLength
52752        );
52753      }
52754
52755      if (options.maximumSelectionLength > 0) {
52756        options.dataAdapter = Utils.Decorate(
52757          options.dataAdapter,
52758          MaximumSelectionLength
52759        );
52760      }
52761
52762      if (options.tags != null) {
52763        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
52764      }
52765
52766      if (options.tokenSeparators != null || options.tokenizer != null) {
52767        options.dataAdapter = Utils.Decorate(
52768          options.dataAdapter,
52769          Tokenizer
52770        );
52771      }
52772    }
52773
52774    if (options.resultsAdapter == null) {
52775      options.resultsAdapter = ResultsList;
52776
52777      if (options.ajax != null) {
52778        options.resultsAdapter = Utils.Decorate(
52779          options.resultsAdapter,
52780          InfiniteScroll
52781        );
52782      }
52783
52784      if (options.placeholder != null) {
52785        options.resultsAdapter = Utils.Decorate(
52786          options.resultsAdapter,
52787          HidePlaceholder
52788        );
52789      }
52790    }
52791
52792    if (options.dropdownAdapter == null) {
52793      if (options.multiple) {
52794        options.dropdownAdapter = Dropdown;
52795      } else {
52796        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
52797
52798        options.dropdownAdapter = SearchableDropdown;
52799      }
52800
52801      if (options.minimumResultsForSearch > 0) {
52802        options.dropdownAdapter = Utils.Decorate(
52803          options.dropdownAdapter,
52804          MinimumResultsForSearch
52805        );
52806      }
52807
52808      if (options.selectOnClose) {
52809        options.dropdownAdapter = Utils.Decorate(
52810          options.dropdownAdapter,
52811          SelectOnClose
52812        );
52813      }
52814
52815      options.dropdownAdapter = Utils.Decorate(
52816        options.dropdownAdapter,
52817        AttachBody
52818      );
52819    }
52820
52821    if (options.selectionAdapter == null) {
52822      if (options.multiple) {
52823        options.selectionAdapter = MultipleSelection;
52824      } else {
52825        options.selectionAdapter = SingleSelection;
52826      }
52827
52828      // Add the placeholder mixin if a placeholder was specified
52829      if (options.placeholder != null) {
52830        options.selectionAdapter = Utils.Decorate(
52831          options.selectionAdapter,
52832          Placeholder
52833        );
52834
52835        if (options.allowClear) {
52836          options.selectionAdapter = Utils.Decorate(
52837            options.selectionAdapter,
52838            AllowClear
52839          );
52840        }
52841      }
52842
52843      if (options.multiple) {
52844        options.selectionAdapter = Utils.Decorate(
52845          options.selectionAdapter,
52846          SelectionSearch
52847        );
52848      }
52849
52850      options.selectionAdapter = Utils.Decorate(
52851        options.selectionAdapter,
52852        EventRelay
52853      );
52854    }
52855
52856    if (typeof options.language === 'string') {
52857      options.language = [options.language];
52858    }
52859
52860    if ($.isArray(options.language)) {
52861      var languages = new Translation();
52862      options.language.push('en');
52863
52864      var languageNames = options.language;
52865
52866      for (var l = 0; l < languageNames.length; l++) {
52867        var name = languageNames[l];
52868        var language = {};
52869
52870        try {
52871          // Try to load it with the original name
52872          language = Translation.loadPath(name);
52873        } catch (e) {
52874          // If we couldn't load it, check if it wasn't the full path
52875          name = this.defaults.amdLanguageBase + name;
52876          language = Translation.loadPath(name);
52877        }
52878
52879        languages.extend(language);
52880      }
52881
52882      options.translations = languages;
52883    } else {
52884      options.translations = new Translation(options.language);
52885    }
52886
52887    return options;
52888  };
52889
52890  Defaults.prototype.reset = function () {
52891    function stripDiacritics (text) {
52892      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
52893      function match(a) {
52894        return DIACRITICS[a] || a;
52895      }
52896
vendor: 16,384 bytes, lines 52897-53572
52897      return text.replace(/[^\u0000-\u007E]/g, match);
52898    }
52899
52900    function matcher (params, data) {
52901      // Always return the object if there is nothing to compare
52902      if ($.trim(params.term) === '') {
52903        return data;
52904      }
52905
52906      // Do a recursive check for options with children
52907      if (data.children && data.children.length > 0) {
52908        // Clone the data object if there are children
52909        // This is required as we modify the object to remove any non-matches
52910        var match = $.extend(true, {}, data);
52911
52912        // Check each child of the option
52913        for (var c = data.children.length - 1; c >= 0; c--) {
52914          var child = data.children[c];
52915
52916          var matches = matcher(params, child);
52917
52918          // If there wasn't a match, remove the object in the array
52919          if (matches == null) {
52920            match.children.splice(c, 1);
52921          }
52922        }
52923
52924        // If any children matched, return the new object
52925        if (match.children.length > 0) {
52926          return match;
52927        }
52928
52929        // If there were no matching children, check just the plain object
52930        return matcher(params, match);
52931      }
52932
52933      var original = stripDiacritics(data.text).toUpperCase();
52934      var term = stripDiacritics(params.term).toUpperCase();
52935
52936      // Check if the text contains the term
52937      if (original.indexOf(term) > -1) {
52938        return data;
52939      }
52940
52941      // If it doesn't contain the term, don't return anything
52942      return null;
52943    }
52944
52945    this.defaults = {
52946      amdBase: 'select2/',
52947      amdLanguageBase: 'select2/i18n/',
52948      language: EnglishTranslation,
52949      matcher: matcher,
52950      minimumInputLength: 0,
52951      maximumInputLength: 0,
52952      maximumSelectionLength: 0,
52953      minimumResultsForSearch: 0,
52954      selectOnClose: false,
52955      sorter: function (data) {
52956        return data;
52957      },
52958      templateResult: function (result) {
52959        return result.text;
52960      },
52961      templateSelection: function (selection) {
52962        return selection.text;
52963      },
52964      theme: 'default',
52965      width: 'resolve'
52966    };
52967  };
52968
52969  var defaults = new Defaults();
52970
52971  return defaults;
52972});
52973
52974define('select2/options',[
52975  'jquery',
52976  './defaults'
52977], function ($, Defaults) {
52978  function Options (options, $element) {
52979    this.options = options;
52980
52981    if ($element != null) {
52982      this.fromElement($element);
52983    }
52984
52985    this.options = Defaults.apply(this.options);
52986  }
52987
52988  Options.prototype.fromElement = function ($e) {
52989    var excludedData = ['select2'];
52990
52991    if (this.options.multiple == null) {
52992      this.options.multiple = $e.prop('multiple');
52993    }
52994
52995    if (this.options.disabled == null) {
52996      this.options.disabled = $e.prop('disabled');
52997    }
52998
52999    if (this.options.language == null) {
53000      if ($e.prop('lang')) {
53001        this.options.language = $e.prop('lang').toLowerCase();
53002      } else if ($e.closest('[lang]').prop('lang')) {
53003        this.options.language = $e.closest('[lang]').prop('lang');
53004      }
53005    }
53006
53007    if (this.options.dir == null) {
53008      if ($e.prop('dir')) {
53009        this.options.dir = $e.prop('dir');
53010      } else if ($e.closest('[dir]').prop('dir')) {
53011        this.options.dir = $e.closest('[dir]').prop('dir');
53012      } else {
53013        this.options.dir = 'ltr';
53014      }
53015    }
53016
53017    $e.prop('disabled', this.options.disabled);
53018    $e.prop('multiple', this.options.multiple);
53019
53020    if ($e.data('select2-tags')) {
53021      if (console && console.warn) {
53022        console.warn(
53023          'Select2: The `data-select2-tags` attribute has been changed to ' +
53024          'use the `data-data` and `data-tags="true"` attributes and will be ' +
53025          'removed in future versions of Select2.'
53026        );
53027      }
53028
53029      $e.data('data', $e.data('select2-tags'));
53030      $e.data('tags', true);
53031    }
53032
53033    if ($e.data('ajax-url')) {
53034      if (console && console.warn) {
53035        console.warn(
53036          'Select2: The `data-ajax-attribute` has been changed to ' +
53037          '`data-ajax--url` and support for the old attribute will be removed' +
53038          ' in future versions of Select2.'
53039        );
53040      }
53041
53042      $e.data('ajax--url', $e.data('ajax-url'));
53043    }
53044
53045    var data = $e.data();
53046
53047    function convertData (data) {
53048      for (var originalKey in data) {
53049        var keys = originalKey.split('-');
53050
53051        var dataLevel = data;
53052
53053        if (keys.length === 1) {
53054          continue;
53055        }
53056
53057        for (var k = 0; k < keys.length; k++) {
53058          var key = keys[k];
53059
53060          // Lowercase the first letter
53061          // By default, dash-separated becomes camelCase
53062          key = key.substring(0, 1).toLowerCase() + key.substring(1);
53063
53064          if (!(key in dataLevel)) {
53065            dataLevel[key] = {};
53066          }
53067
53068          if (k == keys.length - 1) {
53069            dataLevel[key] = data[originalKey];
53070          }
53071
53072          dataLevel = dataLevel[key];
53073        }
53074
53075        delete data[originalKey];
53076      }
53077
53078      return data;
53079    }
53080
53081    data = convertData(data);
53082
53083    for (var key in data) {
53084      if (excludedData.indexOf(key) > -1) {
53085        continue;
53086      }
53087
53088      if ($.isPlainObject(this.options[key])) {
53089        $.extend(this.options[key], data[key]);
53090      } else {
53091        this.options[key] = data[key];
53092      }
53093    }
53094
53095    return this;
53096  };
53097
53098  Options.prototype.get = function (key) {
53099    return this.options[key];
53100  };
53101
53102  Options.prototype.set = function (key, val) {
53103    this.options[key] = val;
53104  };
53105
53106  return Options;
53107});
53108
53109define('select2/core',[
53110  'jquery',
53111  './options',
53112  './utils',
53113  './keys'
53114], function ($, Options, Utils, KEYS) {
53115  var Select2 = function ($element, options) {
53116    if ($element.data('select2') != null) {
53117      $element.data('select2').destroy();
53118    }
53119
53120    this.$element = $element;
53121
53122    this.id = this._generateId($element);
53123
53124    options = options || {};
53125
53126    this.options = new Options(options, $element);
53127
53128    Select2.__super__.constructor.call(this);
53129
53130    // Set up containers and adapters
53131
53132    var DataAdapter = this.options.get('dataAdapter');
53133    this.data = new DataAdapter($element, this.options);
53134
53135    var $container = this.render();
53136
53137    this._placeContainer($container);
53138
53139    var SelectionAdapter = this.options.get('selectionAdapter');
53140    this.selection = new SelectionAdapter($element, this.options);
53141    this.$selection = this.selection.render();
53142
53143    this.selection.position(this.$selection, $container);
53144
53145    var DropdownAdapter = this.options.get('dropdownAdapter');
53146    this.dropdown = new DropdownAdapter($element, this.options);
53147    this.$dropdown = this.dropdown.render();
53148
53149    this.dropdown.position(this.$dropdown, $container);
53150
53151    var ResultsAdapter = this.options.get('resultsAdapter');
53152    this.results = new ResultsAdapter($element, this.options, this.data);
53153    this.$results = this.results.render();
53154
53155    this.results.position(this.$results, this.$dropdown);
53156
53157    // Bind events
53158
53159    var self = this;
53160
53161    // Bind the container to all of the adapters
53162    this._bindAdapters();
53163
53164    // Register any DOM event handlers
53165    this._registerDomEvents();
53166
53167    // Register any internal event handlers
53168    this._registerDataEvents();
53169    this._registerSelectionEvents();
53170    this._registerDropdownEvents();
53171    this._registerResultsEvents();
53172    this._registerEvents();
53173
53174    // Set the initial state
53175    this.data.current(function (initialData) {
53176      self.trigger('selection:update', {
53177        data: initialData
53178      });
53179    });
53180
53181    // Hide the original select
53182    $element.hide();
53183
53184    // Synchronize any monitored attributes
53185    this._syncAttributes();
53186
53187    this._tabindex = $element.attr('tabindex') || 0;
53188
53189    $element.attr('tabindex', '-1');
53190
53191    $element.data('select2', this);
53192  };
53193
53194  Utils.Extend(Select2, Utils.Observable);
53195
53196  Select2.prototype._generateId = function ($element) {
53197    var id = '';
53198
53199    if ($element.attr('id') != null) {
53200      id = $element.attr('id');
53201    } else if ($element.attr('name') != null) {
53202      id = $element.attr('name') + '-' + Utils.generateChars(2);
53203    } else {
53204      id = Utils.generateChars(4);
53205    }
53206
53207    id = 'select2-' + id;
53208
53209    return id;
53210  };
53211
53212  Select2.prototype._placeContainer = function ($container) {
53213    $container.insertAfter(this.$element);
53214
53215    var width = this._resolveWidth(this.$element, this.options.get('width'));
53216
53217    if (width != null) {
53218      $container.css('width', width);
53219    }
53220  };
53221
53222  Select2.prototype._resolveWidth = function ($element, method) {
53223    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
53224
53225    if (method == 'resolve') {
53226      var styleWidth = this._resolveWidth($element, 'style');
53227
53228      if (styleWidth != null) {
53229        return styleWidth;
53230      }
53231
53232      return this._resolveWidth($element, 'element');
53233    }
53234
53235    if (method == 'element') {
53236      var elementWidth = $element.outerWidth(false);
53237
53238      if (elementWidth <= 0) {
53239        return 'auto';
53240      }
53241
53242      return elementWidth + 'px';
53243    }
53244
53245    if (method == 'style') {
53246      var style = $element.attr('style');
53247
53248      if (typeof(style) !== 'string') {
53249        return null;
53250      }
53251
53252      var attrs = style.split(';');
53253
53254      for (i = 0, l = attrs.length; i < l; i = i + 1) {
53255        attr = attrs[i].replace(/\s/g, '');
53256        var matches = attr.match(WIDTH);
53257
53258        if (matches !== null && matches.length >= 1) {
53259          return matches[1];
53260        }
53261      }
53262    }
53263
53264    return method;
53265  };
53266
53267  Select2.prototype._bindAdapters = function () {
53268    this.data.bind(this, this.$container);
53269    this.selection.bind(this, this.$container);
53270
53271    this.dropdown.bind(this, this.$container);
53272    this.results.bind(this, this.$container);
53273  };
53274
53275  Select2.prototype._registerDomEvents = function () {
53276    var self = this;
53277
53278    this.$element.on('change.select2', function () {
53279      self.data.current(function (data) {
53280        self.trigger('selection:update', {
53281          data: data
53282        });
53283      });
53284    });
53285
53286    this._sync = Utils.bind(this._syncAttributes, this);
53287
53288    if (this.$element[0].attachEvent) {
53289      this.$element[0].attachEvent('onpropertychange', this._sync);
53290    }
53291
53292    var observer = window.MutationObserver ||
53293      window.WebKitMutationObserver ||
53294      window.MozMutationObserver
53295    ;
53296
53297    if (observer != null) {
53298      this._observer = new observer(function (mutations) {
53299        $.each(mutations, self._sync);
53300      });
53301      this._observer.observe(this.$element[0], {
53302        attributes: true,
53303        subtree: false
53304      });
53305    }
53306  };
53307
53308  Select2.prototype._registerDataEvents = function () {
53309    var self = this;
53310
53311    this.data.on('*', function (name, params) {
53312      self.trigger(name, params);
53313    });
53314  };
53315
53316  Select2.prototype._registerSelectionEvents = function () {
53317    var self = this;
53318    var nonRelayEvents = ['toggle'];
53319
53320    this.selection.on('toggle', function () {
53321      self.toggleDropdown();
53322    });
53323
53324    this.selection.on('*', function (name, params) {
53325      if (nonRelayEvents.indexOf(name) !== -1) {
53326        return;
53327      }
53328
53329      self.trigger(name, params);
53330    });
53331  };
53332
53333  Select2.prototype._registerDropdownEvents = function () {
53334    var self = this;
53335
53336    this.dropdown.on('*', function (name, params) {
53337      self.trigger(name, params);
53338    });
53339  };
53340
53341  Select2.prototype._registerResultsEvents = function () {
53342    var self = this;
53343
53344    this.results.on('*', function (name, params) {
53345      self.trigger(name, params);
53346    });
53347  };
53348
53349  Select2.prototype._registerEvents = function () {
53350    var self = this;
53351
53352    this.on('open', function () {
53353      self.$container.addClass('select2-container--open');
53354    });
53355
53356    this.on('close', function () {
53357      self.$container.removeClass('select2-container--open');
53358    });
53359
53360    this.on('enable', function () {
53361      self.$container.removeClass('select2-container--disabled');
53362    });
53363
53364    this.on('disable', function () {
53365      self.$container.addClass('select2-container--disabled');
53366    });
53367
53368    this.on('query', function (params) {
53369      this.data.query(params, function (data) {
53370        self.trigger('results:all', {
53371          data: data,
53372          query: params
53373        });
53374      });
53375    });
53376
53377    this.on('query:append', function (params) {
53378      this.data.query(params, function (data) {
53379        self.trigger('results:append', {
53380          data: data,
53381          query: params
53382        });
53383      });
53384    });
53385
53386    this.on('keypress', function (evt) {
53387      var key = evt.which;
53388
53389      if (self.isOpen()) {
53390        if (key === KEYS.ENTER) {
53391          self.trigger('results:select');
53392
53393          evt.preventDefault();
53394        } else if (key === KEYS.UP) {
53395          self.trigger('results:previous');
53396
53397          evt.preventDefault();
53398        } else if (key === KEYS.DOWN) {
53399          self.trigger('results:next');
53400
53401          evt.preventDefault();
53402        } else if (key === KEYS.ESC || key === KEYS.TAB) {
53403          self.close();
53404
53405          evt.preventDefault();
53406        }
53407      } else {
53408        if (key === KEYS.ENTER || key === KEYS.SPACE ||
53409            ((key === KEYS.DOWN || key === KEYS.UP) && evt.altKey)) {
53410          self.open();
53411
53412          evt.preventDefault();
53413        }
53414      }
53415    });
53416  };
53417
53418  Select2.prototype._syncAttributes = function () {
53419    this.options.set('disabled', this.$element.prop('disabled'));
53420
53421    if (this.options.get('disabled')) {
53422      if (this.isOpen()) {
53423        this.close();
53424      }
53425
53426      this.trigger('disable');
53427    } else {
53428      this.trigger('enable');
53429    }
53430  };
53431
53432  /**
53433   * Override the trigger method to automatically trigger pre-events when
53434   * there are events that can be prevented.
53435   */
53436  Select2.prototype.trigger = function (name, args) {
53437    var actualTrigger = Select2.__super__.trigger;
53438    var preTriggerMap = {
53439      'open': 'opening',
53440      'close': 'closing',
53441      'select': 'selecting',
53442      'unselect': 'unselecting'
53443    };
53444
53445    if (name in preTriggerMap) {
53446      var preTriggerName = preTriggerMap[name];
53447      var preTriggerArgs = {
53448        prevented: false,
53449        name: name,
53450        args: args
53451      };
53452
53453      actualTrigger.call(this, preTriggerName, preTriggerArgs);
53454
53455      if (preTriggerArgs.prevented) {
53456        args.prevented = true;
53457
53458        return;
53459      }
53460    }
53461
53462    actualTrigger.call(this, name, args);
53463  };
53464
53465  Select2.prototype.toggleDropdown = function () {
53466    if (this.options.get('disabled')) {
53467      return;
53468    }
53469
53470    if (this.isOpen()) {
53471      this.close();
53472    } else {
53473      this.open();
53474    }
53475  };
53476
53477  Select2.prototype.open = function () {
53478    if (this.isOpen()) {
53479      return;
53480    }
53481
53482    this.trigger('query', {});
53483
53484    this.trigger('open');
53485  };
53486
53487  Select2.prototype.close = function () {
53488    if (!this.isOpen()) {
53489      return;
53490    }
53491
53492    this.trigger('close');
53493  };
53494
53495  Select2.prototype.isOpen = function () {
53496    return this.$container.hasClass('select2-container--open');
53497  };
53498
53499  Select2.prototype.enable = function (args) {
53500    if (console && console.warn) {
53501      console.warn(
53502        'Select2: The `select2("enable")` method has been deprecated and will' +
53503        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
53504        ' instead.'
53505      );
53506    }
53507
53508    if (args.length === 0) {
53509      args = [true];
53510    }
53511
53512    var disabled = !args[0];
53513
53514    this.$element.prop('disabled', disabled);
53515  };
53516
53517  Select2.prototype.val = function (args) {
53518    if (console && console.warn) {
53519      console.warn(
53520        'Select2: The `select2("val")` method has been deprecated and will be' +
53521        ' removed in later Select2 versions. Use $element.val() instead.'
53522      );
53523    }
53524
53525    if (args.length === 0) {
53526      return this.$element.val();
53527    }
53528
53529    var newVal = args[0];
53530
53531    if ($.isArray(newVal)) {
53532      newVal = $.map(newVal, function (obj) {
53533        return obj.toString();
53534      });
53535    }
53536
53537    this.$element.val(newVal).trigger('change');
53538  };
53539
53540  Select2.prototype.destroy = function () {
53541    this.$container.remove();
53542
53543    if (this.$element[0].detachEvent) {
53544      this.$element[0].detachEvent('onpropertychange', this._sync);
53545    }
53546
53547    if (this._observer != null) {
53548      this._observer.disconnect();
53549      this._observer = null;
53550    }
53551
53552    this._sync = null;
53553
53554    this.$element.off('.select2');
53555    this.$element.attr('tabindex', this._tabindex);
53556
53557    this.$element.show();
53558    this.$element.removeData('select2');
53559
53560    this.data.destroy();
53561    this.selection.destroy();
53562    this.dropdown.destroy();
53563    this.results.destroy();
53564
53565    this.data = null;
53566    this.selection = null;
53567    this.dropdown = null;
53568    this.results = null;
53569  };
53570
53571  Select2.prototype.render = function () {
53572    var $container =
53572 $(
53573      '<span class="select2 select2-container">' +
53574        '<span class="selection"></span>' +
53575        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
53576      '</span>'
53577    );
53578
53579    $container.attr('dir', this.options.get('dir'));
53580
53581    this.$container = $container;
53582
53583    this.$container.addClass('select2-container--' + this.options.get('theme'));
53584
53585    $container.data('element', this.$element);
53586
53587    return $container;
53588  };
53589
53590  return Select2;
53591});
53592
53593define('jquery.select2',[
53594  'jquery',
53595  './select2/core'
53596], function ($, Select2) {
53597  // Force jQuery.mousewheel to be loaded if it hasn't already
53598  try {
53599    require('jquery.mousewheel');
53600  } catch (Exception) { }
53601
53602  if ($.fn.select2 == null) {
53603    $.fn.select2 = function (options) {
53604      options = options || {};
53605
53606      if (typeof options === 'object') {
53607        this.each(function () {
53608          var instanceOptions = $.extend({}, options, true);
53609
53610          var instance = new Select2($(this), instanceOptions);
53611        });
53612
53613        return this;
53614      } else if (typeof options === 'string') {
53615        var instance = this.data('select2');
53616        var args = Array.prototype.slice.call(arguments, 1);
53617
53618        return instance[options](args);
53619      } else {
53620        throw new Error('Invalid arguments for Select2: ' + options);
53621      }
53622    };
53623  }
53624
53625  return Select2;
53626});
53627
53628require('jquery.select2'); $.fn.select2.amd = { define: define, require: require };}());
53629// This is a manifest file that'll be compiled into application.js, which will include all the files
53630// listed below.
53631//
53632// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
53633// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
53634//
53635// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
53636// the compiled file.
53637//
53638// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
53639// GO AFTER THE REQUIRES BELOW.
53640//
53641
53642
53643
53644
53645
53646
53647
53648
53649
53650
53651
53652
53653
53654
53655
53656
53657
53658
53659
53660
53661
53662
53663
53664
53665
53666
53667
53668
53669
53670
53671
53672
53673
53674
53675
53676
53677
53678
53679
53680;

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.