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 '&': '&', 388 '<': '<', 389 '>': '>', 390 '"': '"', 391 "'": ''' 392 }; 393 394 /** Used to map HTML entities to characters. */ 395 var htmlUnescapes = { 396 '&': '&', 397 '<': '<', 398 '>': '>', 399 '"': '"', 400 ''': "'" 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, & 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, & 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><script></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 * `&`, `<`, `>`, `"`, and `'` 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, & 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…" + 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 '×' + 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 '×' + 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.