UNPKG

1.22 MBJavaScriptView Raw
1/**
2 * polyfill for Function
3 */
4
5// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
6if (!Function.prototype.bind) {
7 Function.prototype.bind = function (oThis) {
8 if (typeof this !== 'function') {
9 throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
10 }
11 var args = Array.prototype.slice.call(arguments, 1);
12 var fToBind = this;
13 var fNOP = function () {};
14 var fBound = function () {
15 return fToBind.apply(this instanceof fNOP ? this : oThis, args.concat(Array.prototype.slice.call(arguments)));
16 };
17
18 if (this.prototype) {
19 fNOP.prototype = this.prototype;
20 }
21 fBound.prototype = new fNOP();
22 return fBound;
23 };
24}
25/**
26 * polyfill for Object
27 */
28
29// from https://github.com/es-shims/es5-shim/blob/master/es5-sham.js
30(function () {
31 var prototypeOfObject = Object.prototype;
32 var call = Function.call;
33 var owns = call.bind(prototypeOfObject.hasOwnProperty);
34 var isEnumerable = call.bind(prototypeOfObject.propertyIsEnumerable);
35 var toStr = call.bind(prototypeOfObject.toString);
36
37 var defineGetter;
38 var defineSetter;
39 var lookupGetter;
40 var lookupSetter;
41 var supportsAccessors = owns(prototypeOfObject, '__defineGetter__');
42 if (supportsAccessors) {
43 /* eslint-disable no-underscore-dangle, no-restricted-properties */
44 defineGetter = call.bind(prototypeOfObject.__defineGetter__);
45 defineSetter = call.bind(prototypeOfObject.__defineSetter__);
46 lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
47 lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
48 /* eslint-enable no-underscore-dangle, no-restricted-properties */
49 }
50
51 var isPrimitive = function isPrimitive(o) {
52 return o == null || (typeof o !== 'object' && typeof o !== 'function');
53 };
54
55 if (!Object.getPrototypeOf) {
56 Object.getPrototypeOf = function getPrototypeOf(object) {
57 var proto = object.__proto__;
58 if (proto || proto === null) {
59 return proto;
60 }
61 if (toStr(object.constructor) === '[object Function]') {
62 return object.constructor.prototype;
63 }
64 if (object instanceof Object) {
65 return prototypeOfObject;
66 }
67 return null;
68 };
69 }
70
71 if (!Object.keys) {
72 Object.keys = (function() {
73 var hasOwnProperty = Object.prototype.hasOwnProperty;
74 var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
75 var dontEnums = [
76 'toString',
77 'toLocaleString',
78 'valueOf',
79 'hasOwnProperty',
80 'isPrototypeOf',
81 'propertyIsEnumerable',
82 'constructor'
83 ];
84 var dontEnumsLength = dontEnums.length;
85
86 return function (obj) {
87 if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
88 throw new TypeError('Object.keys called on non-object');
89 }
90 var result = [], prop, i;
91
92 for (prop in obj) {
93 if (hasOwnProperty.call(obj, prop)) {
94 result.push(prop);
95 }
96 }
97 if (hasDontEnumBug) {
98 for (i = 0; i < dontEnumsLength; i++) {
99 if (hasOwnProperty.call(obj, dontEnums[i])) {
100 result.push(dontEnums[i]);
101 }
102 }
103 }
104 return result;
105 };
106 }());
107 }
108
109 if (!Object.getOwnPropertyNames) {
110 Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
111 if (object !== Object(object)) {
112 throw TypeError('Object.getOwnPropertyNames called on non-object: ' + object);
113 }
114 return Object.keys(object);
115 };
116 }
117
118 var doesGetOwnPropertyDescriptorWork = function doesGetOwnPropertyDescriptorWork(object) {
119 try {
120 object.sentinel = 0;
121 return Object.getOwnPropertyDescriptor(object, 'sentinel').value === 0;
122 } catch (err) {
123 return false;
124 }
125 };
126 var getOwnPropertyDescriptorFallback;
127 if (Object.defineProperty) {
128 var getOwnPropertyDescriptorWorksOnObject = doesGetOwnPropertyDescriptorWork({});
129 var getOwnPropertyDescriptorWorksOnDom = typeof document === 'undefined' ||
130 doesGetOwnPropertyDescriptorWork(document.createElement('div'));
131 if (!getOwnPropertyDescriptorWorksOnDom || !getOwnPropertyDescriptorWorksOnObject) {
132 getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor;
133 }
134 }
135 if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) {
136 var ERR_NON_OBJECT = 'Object.getOwnPropertyDescriptor called on a non-object: ';
137 Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
138 if (isPrimitive(object)) {
139 throw new TypeError(ERR_NON_OBJECT + object);
140 }
141 if (getOwnPropertyDescriptorFallback) {
142 try {
143 return getOwnPropertyDescriptorFallback.call(Object, object, property);
144 } catch (err) {
145
146 }
147 }
148 var descriptor;
149 if (!owns(object, property)) {
150 return descriptor;
151 }
152 descriptor = {
153 enumerable: isEnumerable(object, property),
154 configurable: true
155 };
156 if (supportsAccessors) {
157 var prototype = object.__proto__;
158 var notPrototypeOfObject = object !== prototypeOfObject;
159 if (notPrototypeOfObject) {
160 object.__proto__ = prototypeOfObject;
161 }
162 var getter = lookupGetter(object, property);
163 var setter = lookupSetter(object, property);
164 if (notPrototypeOfObject) {
165 object.__proto__ = prototype;
166 }
167 if (getter || setter) {
168 if (getter) {
169 descriptor.get = getter;
170 }
171 if (setter) {
172 descriptor.set = setter;
173 }
174 return descriptor;
175 }
176 }
177 descriptor.value = object[property];
178 descriptor.writable = true;
179 return descriptor;
180 };
181 }
182
183 var doesDefinePropertyWork = function doesDefinePropertyWork(object) {
184 try {
185 Object.defineProperty(object, 'sentinel', {});
186 return 'sentinel' in object;
187 } catch (exception) {
188 return false;
189 }
190 };
191
192 if (Object.defineProperty) {
193 var definePropertyWorksOnObject = doesDefinePropertyWork({});
194 var definePropertyWorksOnDom = typeof document === 'undefined' ||
195 doesDefinePropertyWork(document.createElement('div'));
196 if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
197 var definePropertyFallback = Object.defineProperty;
198 var definePropertiesFallback = Object.defineProperties;
199 }
200 }
201
202 if (!Object.defineProperty || definePropertyFallback) {
203 var ERR_NON_OBJECT_DESCRIPTOR = 'Property description must be an object: ';
204 var ERR_NON_OBJECT_TARGET = 'Object.defineProperty called on non-object: ';
205 var ERR_ACCESSORS_NOT_SUPPORTED = 'getters & setters can not be defined on this javascript engine';
206 Object.defineProperty = function defineProperty(object, property, descriptor) {
207 if (isPrimitive(object)) {
208 throw new TypeError(ERR_NON_OBJECT_TARGET + object);
209 }
210 if (isPrimitive(descriptor)) {
211 throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
212 }
213 if (definePropertyFallback) {
214 try {
215 return definePropertyFallback.call(Object, object, property, descriptor);
216 } catch (exception) {
217 }
218 }
219 if ('value' in descriptor) {
220 if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) {
221 var prototype = object.__proto__;
222 object.__proto__ = prototypeOfObject;
223 delete object[property];
224 object[property] = descriptor.value;
225 object.__proto__ = prototype;
226 } else {
227 object[property] = descriptor.value;
228 }
229 } else {
230 var hasGetter = 'get' in descriptor;
231 var hasSetter = 'set' in descriptor;
232 if (!supportsAccessors && (hasGetter || hasSetter)) {
233 return object;
234 }
235 // If we got that far then getters and setters can be defined !!
236 if (hasGetter) {
237 defineGetter(object, property, descriptor.get);
238 }
239 if (hasSetter) {
240 defineSetter(object, property, descriptor.set);
241 }
242 }
243 return object;
244 };
245 }
246
247 if (!Object.defineProperties || definePropertiesFallback) {
248 Object.defineProperties = function defineProperties(object, properties) {
249 if (definePropertiesFallback) {
250 try {
251 return definePropertiesFallback.call(Object, object, properties);
252 } catch (exception) {
253 }
254 }
255 var keys = Object.keys(properties);
256 for (var i = 0; i < keys.length; i++) {
257 var property = keys[i];
258 if (property !== '__proto__') {
259 Object.defineProperty(object, property, properties[property]);
260 }
261 }
262 return object;
263 };
264 }
265
266 if (!Object.create) {
267 var createEmpty;
268 var supportsProto = !({ __proto__: null } instanceof Object);
269 /* global ActiveXObject */
270 var shouldUseActiveX = function () {
271 if (!document.domain) {
272 return false;
273 }
274 try {
275 return !!new ActiveXObject('htmlfile');
276 } catch (exception) {
277 return false;
278 }
279 };
280
281 var getEmptyViaActiveX = function () {
282 var empty;
283 var xDoc;
284 xDoc = new ActiveXObject('htmlfile');
285 var script = 'script';
286 xDoc.write('<' + script + '></' + script + '>');
287 xDoc.close();
288
289 empty = xDoc.parentWindow.Object.prototype;
290 xDoc = null;
291
292 return empty;
293 };
294
295 var getEmptyViaIFrame = function () {
296 var iframe = document.createElement('iframe');
297 var parent = document.body || document.documentElement;
298 var empty;
299
300 iframe.style.display = 'none';
301 parent.appendChild(iframe);
302 // eslint-disable-next-line no-script-url
303 iframe.src = 'javascript:';
304
305 empty = iframe.contentWindow.Object.prototype;
306 parent.removeChild(iframe);
307 iframe = null;
308
309 return empty;
310 };
311
312 /* global document */
313 if (supportsProto || typeof document === 'undefined') {
314 createEmpty = function () {
315 return { __proto__: null };
316 };
317 } else {
318 createEmpty = function () {
319 var empty = shouldUseActiveX() ? getEmptyViaActiveX() : getEmptyViaIFrame();
320
321 delete empty.constructor;
322 delete empty.hasOwnProperty;
323 delete empty.propertyIsEnumerable;
324 delete empty.isPrototypeOf;
325 delete empty.toLocaleString;
326 delete empty.toString;
327 delete empty.valueOf;
328
329 var Empty = function Empty() { };
330 Empty.prototype = empty;
331 // short-circuit future calls
332 createEmpty = function () {
333 return new Empty();
334 };
335 return new Empty();
336 };
337 }
338
339 Object.create = function create (prototype, properties) {
340 var object;
341 var Type = function () { };
342 if (prototype === null) {
343 object = createEmpty();
344 } else {
345 if (prototype !== null && isPrimitive(prototype)) {
346 throw new TypeError('Object prototype may only be an Object or null');
347 }
348 Type.prototype = prototype;
349 object = new Type();
350 object.__proto__ = prototype;
351 }
352
353 if (properties !== void 0) {
354 Object.defineProperties(object, properties);
355 }
356
357 return object;
358 };
359 }
360
361 if (!Object.seal) {
362 Object.seal = function seal(object) {
363 if (Object(object) !== object) {
364 throw new TypeError('Object.seal can only be called on Objects.');
365 }
366 return object;
367 };
368 }
369
370 if (!Object.freeze) {
371 Object.freeze = function freeze(object) {
372 if (Object(object) !== object) {
373 throw new TypeError('Object.freeze can only be called on Objects.');
374 }
375 return object;
376 };
377 }
378
379 try {
380 Object.freeze(function () { });
381 } catch (exception) {
382 Object.freeze = (function (freezeObject) {
383 return function freeze(object) {
384 if (typeof object === 'function') {
385 return object;
386 }
387 return freezeObject(object);
388 };
389 })(Object.freeze);
390 }
391
392 if (!Object.preventExtensions) {
393 Object.preventExtensions = function preventExtensions(object) {
394 if (Object(object) !== object) {
395 throw new TypeError('Object.preventExtensions can only be called on Objects.');
396 }
397 return object;
398 };
399 }
400
401 if (!Object.isSealed) {
402 Object.isSealed = function isSealed(object) {
403 if (Object(object) !== object) {
404 throw new TypeError('Object.isSealed can only be called on Objects.');
405 }
406 return false;
407 };
408 }
409
410 if (!Object.isFrozen) {
411 Object.isFrozen = function isFrozen(object) {
412 if (Object(object) !== object) {
413 throw new TypeError('Object.isFrozen can only be called on Objects.');
414 }
415 return false;
416 };
417 }
418
419 if (!Object.isExtensible) {
420 Object.isExtensible = function isExtensible(object) {
421 if (Object(object) !== object) {
422 throw new TypeError('Object.isExtensible can only be called on Objects.');
423 }
424 var name = '';
425 while (owns(object, name)) {
426 name += '?';
427 }
428 object[name] = true;
429 var returnValue = owns(object, name);
430 delete object[name];
431 return returnValue;
432 };
433 }
434})();
435
436/**
437 * polyfill for Array
438 */
439
440// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
441if (!Array.isArray) {
442 Array.isArray = function (arg) {
443 return Object.prototype.toString.call(arg) === '[object Array]';
444 };
445}
446
447// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
448if (!Array.prototype.forEach) {
449 Array.prototype.forEach = function (callback, thisArg) {
450 var T, k;
451 if (this === void 0 || this === null) {
452 throw new TypeError('Array.prototype.forEach called on null or undefined');
453 }
454 var O = Object(this);
455 var len = O.length >>> 0;
456 if (Object.prototype.toString.call(callback) != '[object Function]') {
457 throw new TypeError(callback + ' is not a function');
458 }
459 if (arguments.length > 1) {
460 T = thisArg;
461 }
462 k = 0;
463 while (k < len) {
464 var kValue;
465 if (k in O) {
466 kValue = O[k];
467 callback.call(T, kValue, k, O);
468 }
469 k++;
470 }
471 };
472}
473
474// form https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/every
475if (!Array.prototype.every) {
476 Array.prototype.every = function (callback) {
477 if (this === void 0 || this === null) {
478 throw new TypeError('Array.prototype.every called on null or undefined');
479 }
480
481 var O = Object(this);
482 var len = O.length >>> 0;
483 if (Object.prototype.toString.call(callback) != '[object Function]') {
484 throw new TypeError(callback + ' is not a function');
485 }
486 var ctx = arguments.length >= 2 ? arguments[1] : void 0;
487 for (var i = 0; i < len; i++) {
488 if (i in O && !callback.call(ctx, O[i], i, O)) {
489 return false;
490 }
491 }
492
493 return true;
494 };
495}
496
497// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/fill
498if (!Array.prototype.fill) {
499 Array.prototype.fill = function (value) {
500 if (this === void 0 || this === null) {
501 throw new TypeError('Array.prototype.fill called on null or undefined');
502 }
503 var O = Object(this);
504 var len = O.length >>> 0;
505 var start = arguments[1];
506 var relativeStart = start >> 0;
507 var k = relativeStart < 0 ?
508 Math.max(len + relativeStart, 0) :
509 Math.min(relativeStart, len);
510
511 var end = arguments[2];
512 var relativeEnd = end === undefined ? len : end >> 0;
513 var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
514 while (k < final) {
515 O[k] = value;
516 k++;
517 }
518
519 return O;
520 };
521}
522
523// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
524if (!Array.prototype.filter) {
525 Array.prototype.filter = function (callback) {
526 if (this === void 0 || this === null) {
527 throw new TypeError('Array.prototype.filter called on null or undefined');
528 }
529 var O = Object(this);
530 var len = O.length >>> 0;
531 if (Object.prototype.toString.call(callback) != '[object Function]') {
532 throw new TypeError(callback + ' is not a function');
533 }
534 var res = [];
535 var ctx = arguments.length >= 2 ? arguments[1] : void 0;
536 for (var i = 0; i < len; i++) {
537 if (i in O) {
538 var val = O[i];
539 if (callback.call(ctx, val, i, O)) {
540 res.push(val);
541 }
542 }
543 }
544 return res;
545 };
546}
547
548// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
549if (!Array.prototype.indexOf) {
550 Array.prototype.indexOf = function (searchElement, fromIndex) {
551 if (this === void 0 || this === null) {
552 throw new TypeError('Array.prototype.indexOf called on null or undefined');
553 }
554 var k;
555 var O = Object(this);
556 var len = O.length >>> 0;
557 if (len === 0) {
558 return -1;
559 }
560 var n = fromIndex | 0;
561 if (n >= len) {
562 return -1;
563 }
564 k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
565 while (k < len) {
566 if (k in O && O[k] === searchElement) {
567 return k;
568 }
569 k++;
570 }
571 return -1;
572 };
573}
574
575// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf
576if (!Array.prototype.lastIndexOf) {
577 Array.prototype.lastIndexOf = function(searchElement) {
578 if (this === void 0 || this === null) {
579 throw new TypeError('Array.prototype.lastIndexOf called on null or undefined');
580 }
581 var n, k;
582 var t = Object(this);
583 var len = t.length >>> 0;
584 if (len === 0) {
585 return -1;
586 }
587 n = len - 1;
588 if (arguments.length > 1) {
589 n = Number(arguments[1]);
590 if (n !== n) {
591 n = 0;
592 } else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) {
593 n = (n > 0 || -1) * Math.floor(Math.abs(n));
594 }
595 }
596 k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n);
597 for (;k >= 0; k--) {
598 if (k in t && t[k] === searchElement) {
599 return k;
600 }
601 }
602 return -1;
603 };
604}
605
606// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map
607if (!Array.prototype.map) {
608 Array.prototype.map = function (callback, thisArg) {
609 if (this === void 0 || this === null) {
610 throw new TypeError('Array.prototype.map called on null or undefined');
611 }
612 var T, A, k;
613 var O = Object(this);
614 var len = O.length >>> 0;
615 if (Object.prototype.toString.call(callback) !== '[object Function]') {
616 throw new TypeError(callback + ' is not a function');
617 }
618 if (thisArg) {
619 T = thisArg;
620 }
621 A = new Array(len);
622 k = 0;
623 while (k < len) {
624 var kValue, mappedValue;
625 if (k in O) {
626 kValue = O[k];
627 mappedValue = callback.call(T, kValue, k, O);
628 A[ k ] = mappedValue;
629 }
630 k++;
631 }
632 return A;
633 };
634}
635
636// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
637if (!Array.prototype.reduce) {
638 Array.prototype.reduce = function (callback) {
639 if (this === void 0 || this === null) {
640 throw new TypeError('Array.prototype.reduce called on null or undefined');
641 }
642 if (Object.prototype.toString.call(callback) !== '[object Function]') {
643 throw new TypeError(callback + ' is not a function');
644 }
645 var t = Object(this), len = t.length >>> 0, k = 0, value;
646 if (arguments.length >= 2) {
647 value = arguments[1];
648 } else {
649 while (k < len && !(k in t)) {
650 k++;
651 }
652 if (k >= len) {
653 throw new TypeError('Reduce of empty array with no initial value');
654 }
655 value = t[k++];
656 }
657 for (; k < len; k++) {
658 if (k in t) {
659 value = callback(value, t[k], k, t);
660 }
661 }
662 return value;
663 };
664}
665
666// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
667if (!Array.prototype.reduceRight) {
668 Array.prototype.reduceRight = function (callback) {
669 if (this === void 0 || this === null) {
670 throw new TypeError('Array.prototype.reduceRight called on null or undefined');
671 }
672 if (Object.prototype.toString.call(callback) !== '[object Function]') {
673 throw new TypeError(callback + ' is not a function');
674 }
675 var t = Object(this), len = t.length >>> 0, k = len - 1, value;
676 if (arguments.length >= 2) {
677 value = arguments[1];
678 } else {
679 while (k >= 0 && !(k in t)) {
680 k--;
681 }
682 if (k < 0) {
683 throw new TypeError('Reduce of empty array with no initial value');
684 }
685 value = t[k--];
686 }
687 for (; k >= 0; k--) {
688 if (k in t) {
689 value = callback(value, t[k], k, t);
690 }
691 }
692 return value;
693 };
694}
695
696// from https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some
697if (!Array.prototype.some) {
698 Array.prototype.some = function (callback) {
699 if (this === void 0 || this === null) {
700 throw new TypeError('Array.prototype.reduceRight called on null or undefined');
701 }
702 if (Object.prototype.toString.call(callback) !== '[object Function]') {
703 throw new TypeError(callback + ' is not a function');
704 }
705 var t = Object(this);
706 var len = t.length >>> 0;
707 var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
708 for (var i = 0; i < len; i++) {
709 if (i in t && callback.call(thisArg, t[i], i, t)) {
710 return true;
711 }
712 }
713 return false;
714 };
715}
716
717//----------------------------------------------------------------------
718//
719// CSSOM View Module
720// https://dev.w3.org/csswg/cssom-view/
721//
722//----------------------------------------------------------------------
723
724// Fix for IE8-'s Element.getBoundingClientRect()
725(function (global) {
726 if (!global) { return; }
727 if ('TextRectangle' in global && !('width' in global.TextRectangle.prototype)) {
728 Object.defineProperties(global.TextRectangle.prototype, {
729 'width': { get: function () { return this.right - this.left; } },
730 'height': { get: function () { return this.bottom - this.top; } }
731 });
732 }
733})((typeof self === 'object' && self.self === self && self) ||
734 (typeof global === 'object' && global.global === global && global) ||
735 this);
736/**
737 * polyfill for Date
738 */
739
740// from https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date/now
741if (!Date.now) {
742 Date.now = function now () {
743 return new Date().getTime();
744 };
745}
746
747// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
748if (!Date.prototype.toISOString) {
749 (function() {
750 function pad(number) {
751 if (number < 10) {
752 return '0' + number;
753 }
754 return number;
755 }
756 Date.prototype.toISOString = function () {
757 return this.getUTCFullYear() +
758 '-' + pad(this.getUTCMonth() + 1) +
759 '-' + pad(this.getUTCDate()) +
760 'T' + pad(this.getUTCHours()) +
761 ':' + pad(this.getUTCMinutes()) +
762 ':' + pad(this.getUTCSeconds()) +
763 '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) +
764 'Z';
765 };
766 }());
767}
768/**
769 * polyfill for DOM
770 */
771
772(function (global) {
773
774 if (!global) { return; }
775
776 if (!('document' in global)) {
777 return;
778 }
779
780 var document = global.document;
781
782 // IE8- document.getElementsByClassName
783 if (!document.getElementsByClassName && document.querySelectorAll) {
784 var getElementsByClassName = function (classNames) {
785 classNames = String(classNames).replace(/^|\s+/g, '.');
786 return this.querySelectorAll(classNames);
787 };
788 void [HTMLDocument, Element].forEach(function (o) {
789 o.prototype.getElementsByClassName = getElementsByClassName;
790 });
791 }
792
793 // IE CustomEvent
794 if (!('CustomEvent' in global) || typeof global.CustomEvent !== 'function') {
795 var CustomEvent = function (event, params) {
796 params = params || { bubbles: false, cancelable: false, detail: undefined };
797 var evt = document.createEvent('CustomEvent');
798 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
799 return evt;
800 };
801 CustomEvent.prototype = global.Event.prototype;
802 global.CustomEvent = CustomEvent;
803 }
804
805 // Element.matches
806 // from https://developer.mozilla.org/en/docs/Web/API/Element/matches
807 (function () {
808 if (!('Element' in global) || Element.prototype.matches) {
809 return;
810 }
811 var matchesVenders = ['ms', 'o', 'moz', 'webkit'];
812 var matchesSelectorSuffix = 'MatchesSelector';
813 for (var i = 0; i < matchesVenders.length; i++) {
814 var matchesSelector = matchesVenders[i] + matchesSelectorSuffix;
815 if (matchesSelector in Element.prototype) {
816 Element.prototype.matches = Element.prototype[matchesSelector];
817 return;
818 }
819 }
820 if (document.querySelectorAll) {
821 Element.prototype.matches = function matches(selector) {
822 var matches = (this.document || this.ownerDocument).querySelectorAll(selector);
823 var i = matches.length;
824 while (--i >= 0 && matches.item(i) !== this) { }
825 return i > -1;
826 };
827 }
828 })();
829
830 // Node.textContent
831 if (Object.defineProperty
832 && Object.getOwnPropertyDescriptor
833 && Object.getOwnPropertyDescriptor(Element.prototype, 'textContent')
834 && !Object.getOwnPropertyDescriptor(Element.prototype, 'textContent').get) {
835 (function () {
836 var innerText = Object.getOwnPropertyDescriptor(Element.prototype, 'innerText');
837 Object.defineProperty(Element.prototype, 'textContent', {
838 get: function () {
839 return innerText.get.call(this);
840 },
841 set: function (s) {
842 return innerText.set.call(this, s);
843 }
844 });
845 })();
846 }
847
848})((typeof self === 'object' && self.self === self && self) ||
849 (typeof global === 'object' && global.global === global && global) ||
850 this);
851
852/**
853 * polyfill for DOM Event
854 */
855
856// from https://github.com/Financial-Times/polyfill-service/blob/master/polyfills/Event/polyfill.js
857(function (global) {
858
859 if (!global) { return; }
860
861 if (!("Window" in global) || !("HTMLDocument" in global) || !("Element" in global)) {
862 return;
863 }
864
865 if (('Event' in global) && typeof global.Event === 'function') {
866 return;
867 }
868
869 var unlistenableWindowEvents = {
870 click: 1,
871 dblclick: 1,
872 keyup: 1,
873 keypress: 1,
874 keydown: 1,
875 mousedown: 1,
876 mouseup: 1,
877 mousemove: 1,
878 mouseover: 1,
879 mouseenter: 1,
880 mouseleave: 1,
881 mouseout: 1,
882 storage: 1,
883 storagecommit: 1,
884 textinput: 1
885 };
886 var existingProto = (global.Event && global.Event.prototype) || null;
887 global.Event = Window.prototype.Event = function Event(type, eventInitDict) {
888 if (!type) {
889 throw new Error('Not enough arguments');
890 }
891 var event;
892 if ('createEvent' in document) {
893 event = document.createEvent('Event');
894 var bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false;
895 var cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false;
896 event.initEvent(type, bubbles, cancelable);
897 return event;
898 }
899 event = document.createEventObject();
900 event.type = type;
901 event.bubbles = eventInitDict && eventInitDict.bubbles !== undefined ? eventInitDict.bubbles : false;
902 event.cancelable = eventInitDict && eventInitDict.cancelable !== undefined ? eventInitDict.cancelable : false;
903 return event;
904 };
905 if (existingProto) {
906 Object.defineProperty(global.Event, 'prototype', {
907 configurable: false,
908 enumerable: false,
909 writable: true,
910 value: existingProto
911 });
912 }
913 if (!('createEvent' in document)) {
914 var addEventListener = function (type, listener) {
915 var element = this;
916 if (element === global && type in unlistenableWindowEvents) {
917 throw new Error('In IE8 the event: ' + type + ' is not available on the window object.');
918 }
919 if (!element._events) {
920 element._events = {};
921 }
922 if (!element._events[type]) {
923 element._events[type] = function (event) {
924 var list = element._events[event.type].list;
925 var events = list.slice();
926 var index = -1;
927 var length = events.length;
928 var eventElement;
929 event.preventDefault = function preventDefault() {
930 if (event.cancelable !== false) {
931 event.returnValue = false;
932 }
933 };
934 event.stopPropagation = function stopPropagation() {
935 event.cancelBubble = true;
936 };
937 event.stopImmediatePropagation = function stopImmediatePropagation() {
938 event.cancelBubble = true;
939 event.cancelImmediate = true;
940 };
941 event.currentTarget = element;
942 event.target = event.target || event.srcElement || element;
943 event.relatedTarget = event.fromElement ? (event.fromElement === event.target) ? event.toElement : event.fromElement : null;
944 event.timeStamp = new Date().getTime();
945 if (event.clientX) {
946 event.pageX = event.clientX + document.documentElement.scrollLeft;
947 event.pageY = event.clientY + document.documentElement.scrollTop;
948 }
949 while (++index < length && !event.cancelImmediate) {
950 if (index in events) {
951 eventElement = events[index];
952 if (list.indexOf(eventElement) !== -1 && typeof eventElement === 'function') {
953 eventElement.call(element, event);
954 }
955 }
956 }
957 };
958 element._events[type].list = [];
959 if (element.attachEvent) {
960 element.attachEvent('on' + type, element._events[type]);
961 }
962 }
963 element._events[type].list.push(listener);
964 };
965
966 var removeEventListener = function (type, listener) {
967 var element = this;
968 var index;
969 if (element._events && element._events[type] && element._events[type].list) {
970 index = element._events[type].list.indexOf(listener);
971 if (index !== -1) {
972 element._events[type].list.splice(index, 1);
973 if (!element._events[type].list.length) {
974 if (element.detachEvent) {
975 element.detachEvent('on' + type, element._events[type]);
976 }
977 delete element._events[type];
978 }
979 }
980 }
981 };
982
983 var dispatchEvent = function (event) {
984 if (!arguments.length) {
985 throw new Error('Not enough arguments');
986 }
987 if (!event || typeof event.type !== 'string') {
988 throw new Error('DOM Events Exception 0');
989 }
990 var element = this, type = event.type;
991 try {
992 if (!event.bubbles) {
993 event.cancelBubble = true;
994 var cancelBubbleEvent = function (event) {
995 event.cancelBubble = true;
996 (element || window).detachEvent('on' + type, cancelBubbleEvent);
997 };
998 this.attachEvent('on' + type, cancelBubbleEvent);
999 }
1000 this.fireEvent('on' + type, event);
1001 } catch (error) {
1002 event.target = element;
1003 do {
1004 event.currentTarget = element;
1005 if ('_events' in element && typeof element._events[type] === 'function') {
1006 element._events[type].call(element, event);
1007 }
1008 if (typeof element['on' + type] === 'function') {
1009 element['on' + type].call(element, event);
1010 }
1011 element = element.nodeType === 9 ? element.parentWindow : element.parentNode;
1012 } while (element && !event.cancelBubble);
1013 }
1014 return true;
1015 };
1016
1017 void [Window, HTMLDocument, Element].forEach(function (o) {
1018 o.prototype.addEventListener = addEventListener;
1019 o.prototype.removeEventListener = removeEventListener;
1020 o.prototype.dispatchEvent = dispatchEvent;
1021 });
1022
1023 // 添加DOMContentLoaded事件
1024 document.attachEvent('onreadystatechange', function () {
1025 if (document.readyState === 'complete') {
1026 document.dispatchEvent(new Event('DOMContentLoaded', {
1027 bubbles: true
1028 }));
1029 }
1030 });
1031 }
1032})((typeof self === 'object' && self.self === self && self) ||
1033 (typeof global === 'object' && global.global === global && global) ||
1034 this);
1035
1036/**
1037 * polyfill for getComputedStyle
1038 */
1039
1040// from https://github.com/Financial-Times/polyfill-service/blob/master/polyfills/getComputedStyle/polyfill.js
1041(function (global) {
1042
1043 if (!global) { return; }
1044
1045
1046 if (!('document' in global)) {
1047 return;
1048 }
1049
1050 if ('getComputedStyle' in global && typeof global.getComputedStyle === 'function') {
1051 return;
1052 }
1053 function getPixelSize(element, style, property, fontSize) {
1054 var sizeWithSuffix = style[property];
1055 var size = parseFloat(sizeWithSuffix);
1056 var suffix = sizeWithSuffix.split(/\d/)[0];
1057 var rootSize;
1058 fontSize = (fontSize !== null) ? fontSize :
1059 (/%|em/.test(suffix) && element.parentElement) ?
1060 getPixelSize(element.parentElement, element.parentElement.currentStyle, 'fontSize', null) : 16;
1061 rootSize = property === 'fontSize' ? fontSize :
1062 /width/i.test(property) ? element.clientWidth : element.clientHeight;
1063 return (suffix === 'em') ? size * fontSize :
1064 (suffix === 'in') ? size * 96 :
1065 (suffix === 'pt') ? size * 96 / 72 :
1066 (suffix === '%') ? size / 100 * rootSize : size;
1067 }
1068
1069 function setShortStyleProperty(style, property) {
1070 var borderSuffix = property === 'border' ? 'Width' : '';
1071 var t = property + 'Top' + borderSuffix;
1072 var r = property + 'Right' + borderSuffix;
1073 var b = property + 'Bottom' + borderSuffix;
1074 var l = property + 'Left' + borderSuffix;
1075 style[property] = (style[t] == style[r] == style[b] == style[l] ? [style[t]]
1076 : style[t] == style[b] && style[l] == style[r] ? [style[t], style[r]]
1077 : style[l] == style[r] ? [style[t], style[r], style[b]]
1078 : [style[t], style[r], style[b], style[l]]).join(' ');
1079 }
1080
1081 function CSSStyleDeclaration(element) {
1082 var currentStyle = element.currentStyle || {};
1083 var style = this;
1084 var fontSize = getPixelSize(element, currentStyle, 'fontSize', null);
1085 for (var property in currentStyle) {
1086 if (/width|height|margin.|padding.|border.+W/.test(property) && style[property] !== 'auto') {
1087 style[property] = getPixelSize(element, currentStyle, property, fontSize) + 'px';
1088 } else if (property === 'styleFloat') {
1089 style['float'] = currentStyle[property];
1090 } else {
1091 style[property] = currentStyle[property];
1092 }
1093 }
1094 setShortStyleProperty(style, 'margin');
1095 setShortStyleProperty(style, 'padding');
1096 setShortStyleProperty(style, 'border');
1097 style.fontSize = fontSize + 'px';
1098 return style;
1099 }
1100
1101 CSSStyleDeclaration.prototype = {
1102 constructor: CSSStyleDeclaration,
1103 getPropertyPriority: function () { },
1104 getPropertyValue: function (prop) {
1105 return this[prop] || '';
1106 },
1107 item: function () { },
1108 removeProperty: function () { },
1109 setProperty: function () { },
1110 getPropertyCSSValue: function () { }
1111 };
1112 global.getComputedStyle = function (node) {
1113 return new CSSStyleDeclaration(node);
1114 };
1115})((typeof self === 'object' && self.self === self && self) ||
1116 (typeof global === 'object' && global.global === global && global) ||
1117 this);
1118/**
1119 * polyfill for IE8 in HTML
1120 * https://html.spec.whatwg.org
1121 */
1122(function (global) {
1123
1124 if (!global) { return; }
1125
1126 if (!('document' in global)) {
1127 return;
1128 }
1129 // document.head
1130 document.head = document.head || document.getElementsByTagName('head')[0];
1131
1132 // HTML Tag shiv
1133 void [
1134 'abbr', 'article', 'aside', 'audio', 'bdi', 'canvas', 'data', 'datalist',
1135 'details', 'dialog', 'figcaption', 'figure', 'footer', 'header', 'hgroup',
1136 'main', 'mark', 'meter', 'nav', 'output', 'picture', 'progress', 'section',
1137 'summary', 'template', 'time', 'video'
1138 ].forEach(function (tag) {
1139 document.createElement(tag);
1140 });
1141
1142})((typeof self === 'object' && self.self === self && self) ||
1143 (typeof global === 'object' && global.global === global && global) ||
1144 this);
1145/**
1146 * polyfill for String
1147 */
1148
1149if (!String.prototype.trim) {
1150 String.prototype.trim = function () {
1151 return String(this).replace(/^\s+/, '').replace(/\s+$/, '');
1152 };
1153}
1154/**
1155 * Polyfill for Viewport
1156 */
1157
1158(function (global) {
1159
1160
1161 if (!global) { return; }
1162
1163 if (!('document' in global)) {
1164 return;
1165 }
1166
1167 if ('innerWidth' in global && 'innerHeight' in global && 'pageXOffset' in global && 'pageYOffset' in global) {
1168 return;
1169 }
1170 var doc = global.document;
1171 var docEl = doc.documentElement;
1172 var body = doc.body || doc.createElement('body');
1173
1174 function scrollX() {
1175 return (docEl.scrollLeft || body.scrollLeft || 0) - (docEl.clientLeft || body.clientLeft || 0);
1176 }
1177
1178 function scrollY() {
1179 return (docEl.scrollTop || body.scrollTop || 0) - (docEl.clientTop || body.clientTop || 0);
1180 }
1181
1182 Object.defineProperties(global, {
1183 innerWidth: {
1184 get: function () {
1185 return docEl.clientWidth;
1186 }
1187 },
1188 innerHeight: {
1189 get: function () {
1190 return docEl.clientHeight;
1191 }
1192 },
1193 pageXOffset: {
1194 get: scrollX
1195 },
1196 pageYOffset: {
1197 get: scrollY
1198 },
1199 scrollX: {
1200 get: scrollX
1201 },
1202 scrollY: {
1203 get: scrollY
1204 }
1205 });
1206})((typeof self === 'object' && self.self === self && self) ||
1207 (typeof global === 'object' && global.global === global && global) ||
1208 this); /* fb-core.js | 2019-12-15T23:23:20+08:00 | lincong1987@gmail.com */
1209
1210 /*@add(fb-polyfill)*/
1211
1212
1213(function (global, factory) {
1214
1215
1216
1217 /* fb loader wrapper start */
1218
1219 if(typeof fb !== "undefined") {
1220
1221 define(function (require, exports, module) {
1222 var _exports = {};
1223 factory(_exports);
1224 module.exports = _exports;
1225 });
1226
1227 } else {
1228 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global['fb-core'] = {})));
1229 }
1230 /* fb loader wrapper end */
1231
1232}(this, function (exports) { 'use strict';
1233
1234 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
1235
1236 function unwrapExports (x) {
1237 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x["default"] : x;
1238 }
1239
1240 function createCommonjsModule(fn, module) {
1241 return module = { exports: {} }, fn(module, module.exports), module.exports;
1242 }
1243
1244 function getCjsExportFromNamespace (n) {
1245 return n && n["default"] || n;
1246 }
1247
1248 var yox = createCommonjsModule(function (module, exports) {
1249 /**
1250 * yox.js v1.0.0-alpha.118
1251 * (c) 2017-2019 musicode
1252 * Released under the MIT License.
1253 */
1254 (function (global, factory) {
1255 module.exports = factory();
1256 })(commonjsGlobal, function () {
1257
1258 var SYNTAX_IF = '#if';
1259 var SYNTAX_ELSE = 'else';
1260 var SYNTAX_ELSE_IF = 'else if';
1261 var SYNTAX_EACH = '#each';
1262 var SYNTAX_PARTIAL = '#partial';
1263 var SYNTAX_IMPORT = '>';
1264 var SYNTAX_SPREAD = '...';
1265 var SYNTAX_COMMENT = /^!(?:\s|--)/;
1266 var SLOT_DATA_PREFIX = '$slot_';
1267 var SLOT_NAME_DEFAULT = 'children';
1268 var HINT_STRING = 1;
1269 var HINT_NUMBER = 2;
1270 var HINT_BOOLEAN = 3;
1271 var DIRECTIVE_ON = 'on';
1272 var DIRECTIVE_LAZY = 'lazy';
1273 var DIRECTIVE_MODEL = 'model';
1274 var DIRECTIVE_EVENT = 'event';
1275 var DIRECTIVE_BINDING = 'binding';
1276 var DIRECTIVE_CUSTOM = 'f';
1277 var MODIFER_NATIVE = 'native';
1278 var MODEL_PROP_DEFAULT = 'value';
1279 var NAMESPACE_HOOK = '.hook';
1280 var HOOK_BEFORE_CREATE = 'beforeCreate';
1281 var HOOK_AFTER_CREATE = 'afterCreate';
1282 var HOOK_BEFORE_MOUNT = 'beforeMount';
1283 var HOOK_AFTER_MOUNT = 'afterMount';
1284 var HOOK_BEFORE_UPDATE = 'beforeUpdate';
1285 var HOOK_AFTER_UPDATE = 'afterUpdate';
1286 var HOOK_BEFORE_DESTROY = 'beforeDestroy';
1287 var HOOK_AFTER_DESTROY = 'afterDestroy';
1288 var HOOK_BEFORE_PROPS_UPDATE = 'beforePropsUpdate';
1289 /**
1290 * 为了压缩,定义的常量
1291 */
1292
1293 var TRUE = true;
1294 var FALSE = false;
1295 var NULL = null;
1296 var UNDEFINED;
1297 var MINUS_ONE = -1;
1298 var RAW_TRUE = 'true';
1299 var RAW_FALSE = 'false';
1300 var RAW_NULL = 'null';
1301 var RAW_UNDEFINED = 'undefined';
1302 var RAW_KEY = 'key';
1303 var RAW_REF = 'ref';
1304 var RAW_SLOT = 'slot';
1305 var RAW_NAME = 'name';
1306 var RAW_FILTER = 'filter';
1307 var RAW_PARTIAL = 'partial';
1308 var RAW_COMPONENT = 'component';
1309 var RAW_DIRECTIVE = 'directive';
1310 var RAW_TRANSITION = 'transition';
1311 var RAW_THIS = 'this';
1312 var RAW_VALUE = 'value';
1313 var RAW_LENGTH = 'length';
1314 var RAW_FUNCTION = 'function';
1315 var RAW_TEMPLATE = 'template';
1316 var RAW_WILDCARD = '*';
1317 var RAW_DOT = '.';
1318 var RAW_SLASH = '/';
1319 var KEYPATH_PARENT = '..';
1320 var KEYPATH_CURRENT = RAW_THIS;
1321 /**
1322 * Single instance for window in browser
1323 */
1324
1325 var WINDOW = typeof window !== RAW_UNDEFINED ? window : UNDEFINED;
1326 /**
1327 * Single instance for document in browser
1328 */
1329
1330 var DOCUMENT = typeof document !== RAW_UNDEFINED ? document : UNDEFINED;
1331 /**
1332 * Single instance for global in nodejs or browser
1333 */
1334
1335 var GLOBAL = typeof commonjsGlobal !== RAW_UNDEFINED ? commonjsGlobal : WINDOW;
1336 /**
1337 * tap 事件
1338 *
1339 * 非常有用的抽象事件,比如 pc 端是 click 事件,移动端是 touchend 事件
1340 *
1341 * 这样只需 on-tap="handler" 就可以完美兼容各端
1342 *
1343 * 框架未实现此事件,通过 Yox.dom.addSpecialEvent 提供给外部扩展
1344 *
1345 */
1346
1347 var EVENT_TAP = 'tap';
1348 /**
1349 * 点击事件
1350 */
1351
1352 var EVENT_CLICK = 'click';
1353 /**
1354 * 输入事件
1355 */
1356
1357 var EVENT_INPUT = 'input';
1358 /**
1359 * 变化事件
1360 */
1361
1362 var EVENT_CHANGE = 'change';
1363 /**
1364 * 唯一内置的特殊事件:model
1365 */
1366
1367 var EVENT_MODEL = 'model';
1368 /**
1369 * Single instance for noop function
1370 */
1371
1372 var EMPTY_FUNCTION = function () {
1373 /** yox */
1374 };
1375 /**
1376 * 空对象,很多地方会用到,比如 `a || EMPTY_OBJECT` 确保是个对象
1377 */
1378
1379
1380 var EMPTY_OBJECT = {};
1381 /**
1382 * 空数组
1383 */
1384
1385 var EMPTY_ARRAY = [];
1386 /**
1387 * 空字符串
1388 */
1389
1390 var EMPTY_STRING = '';
1391 /**
1392 * Check if value is a function.
1393 *
1394 * @param value
1395 * @return
1396 */
1397
1398 function func(value) {
1399 return typeof value === RAW_FUNCTION;
1400 }
1401 /**
1402 * Check if value is an array.
1403 *
1404 * @param value
1405 * @return
1406 */
1407
1408
1409 function array(value) {
1410 return Array.isArray(value);
1411 }
1412 /**
1413 * Check if value is an object.
1414 *
1415 * @param value
1416 * @return
1417 */
1418
1419
1420 function object(value) {
1421 // 低版本 IE 会把 null 当作 object
1422 return value !== NULL && typeof value === 'object';
1423 }
1424 /**
1425 * Check if value is a string.
1426 *
1427 * @param value
1428 * @return
1429 */
1430
1431
1432 function string(value) {
1433 return typeof value === 'string';
1434 }
1435 /**
1436 * Check if value is a number.
1437 *
1438 * @param value
1439 * @return
1440 */
1441
1442
1443 function number(value) {
1444 return typeof value === 'number' && !isNaN(value);
1445 }
1446 /**
1447 * Check if value is boolean.
1448 *
1449 * @param value
1450 * @return
1451 */
1452
1453
1454 function boolean(value) {
1455 return typeof value === 'boolean';
1456 }
1457 /**
1458 * Check if value is numeric.
1459 *
1460 * @param value
1461 * @return
1462 */
1463
1464
1465 function numeric(value) {
1466 return number(value) || string(value) && !isNaN(parseFloat(value)) && isFinite(value);
1467 }
1468
1469 var is =
1470 /*#__PURE__*/
1471 {
1472 func: func,
1473 array: array,
1474 object: object,
1475 string: string,
1476 number: number,
1477 "boolean": boolean,
1478 numeric: numeric
1479 };
1480 /**
1481 * 任性地执行一个函数,不管它有没有、是不是
1482 *
1483 * @param fn 调用的函数
1484 * @param context 执行函数时的 this 指向
1485 * @param args 调用函数的参数,多参数时传入数组
1486 * @return 调用函数的返回值
1487 */
1488
1489 function execute(fn, context, args) {
1490 if (func(fn)) {
1491 return array(args) ? fn.apply(context, args) : context !== UNDEFINED ? fn.call(context, args) : args !== UNDEFINED ? fn(args) : fn();
1492 }
1493 }
1494
1495 var CustomEvent =
1496 /** @class */
1497 function () {
1498 /**
1499 * 构造函数
1500 *
1501 * 可以传事件名称,也可以传原生事件对象
1502 */
1503 function CustomEvent(type, originalEvent) {
1504 // 这里不设置命名空间
1505 // 因为有没有命名空间取决于 Emitter 的构造函数有没有传 true
1506 // CustomEvent 自己无法决定
1507 this.type = type;
1508 this.phase = CustomEvent.PHASE_CURRENT;
1509
1510 if (originalEvent) {
1511 this.originalEvent = this.e = originalEvent;
1512 }
1513 }
1514 /**
1515 * 阻止事件的默认行为
1516 */
1517
1518
1519 CustomEvent.prototype.preventDefault = function () {
1520 var instance = this;
1521
1522 if (!instance.isPrevented) {
1523 var originalEvent = instance.originalEvent;
1524
1525 if (originalEvent) {
1526 originalEvent.preventDefault();
1527 }
1528
1529 instance.isPrevented = TRUE;
1530 }
1531
1532 return instance;
1533 };
1534 /**
1535 * 停止事件广播
1536 */
1537
1538
1539 CustomEvent.prototype.stopPropagation = function () {
1540 var instance = this;
1541
1542 if (!instance.isStoped) {
1543 var originalEvent = instance.originalEvent;
1544
1545 if (originalEvent) {
1546 originalEvent.stopPropagation();
1547 }
1548
1549 instance.isStoped = TRUE;
1550 }
1551
1552 return instance;
1553 };
1554
1555 CustomEvent.prototype.prevent = function () {
1556 return this.preventDefault();
1557 };
1558
1559 CustomEvent.prototype.stop = function () {
1560 return this.stopPropagation();
1561 };
1562
1563 CustomEvent.PHASE_CURRENT = 0;
1564 CustomEvent.PHASE_UPWARD = 1;
1565 CustomEvent.PHASE_DOWNWARD = MINUS_ONE;
1566 return CustomEvent;
1567 }();
1568 /**
1569 * 遍历数组
1570 *
1571 * @param array
1572 * @param callback 返回 false 可停止遍历
1573 * @param reversed 是否逆序遍历
1574 */
1575
1576
1577 function each(array, callback, reversed) {
1578 var length = array.length;
1579
1580 if (length) {
1581 if (reversed) {
1582 for (var i = length - 1; i >= 0; i--) {
1583 if (callback(array[i], i) === FALSE) {
1584 break;
1585 }
1586 }
1587 } else {
1588 for (var i = 0; i < length; i++) {
1589 if (callback(array[i], i) === FALSE) {
1590 break;
1591 }
1592 }
1593 }
1594 }
1595 }
1596
1597 function nativePush(array, item) {
1598 array[array.length] = item;
1599 }
1600
1601 function nativeUnshift(array, item) {
1602 array.unshift(item);
1603 }
1604 /**
1605 * 添加
1606 *
1607 * @param array
1608 * @param value
1609 * @param action
1610 */
1611
1612
1613 function addItem(array$1, value, action) {
1614 if (array(value)) {
1615 each(value, function (item) {
1616 action(array$1, item);
1617 });
1618 } else {
1619 action(array$1, value);
1620 }
1621 }
1622 /**
1623 * 往后加
1624 *
1625 * @param array
1626 * @param target
1627 */
1628
1629
1630 function push(array, target) {
1631 addItem(array, target, nativePush);
1632 }
1633 /**
1634 * 往前加
1635 *
1636 * @param array
1637 * @param target
1638 */
1639
1640
1641 function unshift(array, target) {
1642 addItem(array, target, nativeUnshift);
1643 }
1644 /**
1645 * 数组项在数组中的位置
1646 *
1647 * @param array 数组
1648 * @param target 数组项
1649 * @param strict 是否全等判断,默认是全等
1650 * @return 如果未找到,返回 -1
1651 */
1652
1653
1654 function indexOf(array, target, strict) {
1655 var result = MINUS_ONE;
1656 each(array, function (item, index) {
1657 if (strict === FALSE ? item == target : item === target) {
1658 result = index;
1659 return FALSE;
1660 }
1661 });
1662 return result;
1663 }
1664 /**
1665 * 获取数组最后一项
1666 *
1667 * @param array 数组
1668 * @return
1669 */
1670
1671
1672 function last(array) {
1673 var length = array.length;
1674
1675 if (length > 0) {
1676 return array[length - 1];
1677 }
1678 }
1679 /**
1680 * 弹出数组最后一项
1681 *
1682 * 项目里用的太多,仅用于节省字符...
1683 *
1684 * @param array 数组
1685 * @return 弹出的数组项
1686 */
1687
1688
1689 function pop(array) {
1690 var length = array.length;
1691
1692 if (length > 0) {
1693 return array.pop();
1694 }
1695 }
1696 /**
1697 * 删除数组项
1698 *
1699 * @param array 数组
1700 * @param item 待删除项
1701 * @param strict 是否全等判断,默认是全等
1702 * @return 删除的数量
1703 */
1704
1705
1706 function remove(array, target, strict) {
1707 var result = 0;
1708 each(array, function (item, index) {
1709 if (strict === FALSE ? item == target : item === target) {
1710 array.splice(index, 1);
1711 result++;
1712 }
1713 }, TRUE);
1714 return result;
1715 }
1716 /**
1717 * 数组是否包含 item
1718 *
1719 * @param array 数组
1720 * @param target 可能包含的数组项
1721 * @param strict 是否全等判断,默认是全等
1722 * @return
1723 */
1724
1725
1726 function has(array, target, strict) {
1727 return indexOf(array, target, strict) >= 0;
1728 }
1729 /**
1730 * 把类数组转成数组
1731 *
1732 * @param array 类数组
1733 * @return
1734 */
1735
1736
1737 function toArray(array$1) {
1738 return array(array$1) ? array$1 : execute(EMPTY_ARRAY.slice, array$1);
1739 }
1740 /**
1741 * 把数组转成对象
1742 *
1743 * @param array 数组
1744 * @param key 数组项包含的字段名称,如果数组项是基本类型,可不传
1745 * @param value
1746 * @return
1747 */
1748
1749
1750 function toObject(array, key, value) {
1751 var result = {};
1752 each(array, function (item) {
1753 result[key ? item[key] : item] = value || item;
1754 });
1755 return result;
1756 }
1757 /**
1758 * 把数组合并成字符串
1759 *
1760 * @param array
1761 * @param separator
1762 * @return
1763 */
1764
1765
1766 function join(array, separator) {
1767 return array.join(separator);
1768 }
1769 /**
1770 * 用于判断长度大于 0 的数组
1771 *
1772 * @param array
1773 * @return
1774 */
1775
1776
1777 function falsy(array$1) {
1778 return !array(array$1) || !array$1.length;
1779 }
1780
1781 var array$1 =
1782 /*#__PURE__*/
1783 {
1784 each: each,
1785 push: push,
1786 unshift: unshift,
1787 indexOf: indexOf,
1788 last: last,
1789 pop: pop,
1790 remove: remove,
1791 has: has,
1792 toArray: toArray,
1793 toObject: toObject,
1794 join: join,
1795 falsy: falsy
1796 };
1797 var camelizePattern = /-([a-z])/gi,
1798 hyphenatePattern = /\B([A-Z])/g,
1799 capitalizePattern = /^[a-z]/,
1800 camelizeCache = {},
1801 hyphenateCache = {},
1802 capitalizeCache = {};
1803 /**
1804 * 连字符转成驼峰
1805 *
1806 * @param str
1807 * @return 驼峰格式的字符串
1808 */
1809
1810 function camelize(str) {
1811 if (!camelizeCache[str]) {
1812 camelizeCache[str] = str.replace(camelizePattern, function ($0, $1) {
1813 return upper($1);
1814 });
1815 }
1816
1817 return camelizeCache[str];
1818 }
1819 /**
1820 * 驼峰转成连字符
1821 *
1822 * @param str
1823 * @return 连字符格式的字符串
1824 */
1825
1826
1827 function hyphenate(str) {
1828 if (!hyphenateCache[str]) {
1829 hyphenateCache[str] = str.replace(hyphenatePattern, function ($0, $1) {
1830 return '-' + lower($1);
1831 });
1832 }
1833
1834 return hyphenateCache[str];
1835 }
1836 /**
1837 * 首字母大写
1838 *
1839 * @param str
1840 * @return
1841 */
1842
1843
1844 function capitalize(str) {
1845 if (!capitalizeCache[str]) {
1846 capitalizeCache[str] = str.replace(capitalizePattern, upper);
1847 }
1848
1849 return capitalizeCache[str];
1850 }
1851 /**
1852 * 清除两侧空白符
1853 *
1854 * @param str
1855 * @return 清除两侧空白符的字符串
1856 */
1857
1858
1859 function trim(str) {
1860 return falsy$1(str) ? EMPTY_STRING : str.trim();
1861 }
1862 /**
1863 * 截取字符串
1864 *
1865 * @param str
1866 * @param start
1867 * @param end
1868 * @return
1869 */
1870
1871
1872 function slice(str, start, end) {
1873 return number(end) ? start === end ? EMPTY_STRING : str.slice(start, end) : str.slice(start);
1874 }
1875 /**
1876 * 获取子串的起始位置
1877 *
1878 * @param str
1879 * @param part
1880 * @param start
1881 * @return
1882 */
1883
1884
1885 function indexOf$1(str, part, start) {
1886 return str.indexOf(part, start !== UNDEFINED ? start : 0);
1887 }
1888 /**
1889 * 获取子串的起始位置
1890 *
1891 * @param str
1892 * @param part
1893 * @param end
1894 * @return
1895 */
1896
1897
1898 function lastIndexOf(str, part, end) {
1899 return str.lastIndexOf(part, end !== UNDEFINED ? end : str.length);
1900 }
1901 /**
1902 * str 是否以 part 开头
1903 *
1904 * @param str
1905 * @param part
1906 * @return
1907 */
1908
1909
1910 function startsWith(str, part) {
1911 return indexOf$1(str, part) === 0;
1912 }
1913 /**
1914 * str 是否以 part 结束
1915 *
1916 * @param str
1917 * @param part
1918 * @return
1919 */
1920
1921
1922 function endsWith(str, part) {
1923 var offset = str.length - part.length;
1924 return offset >= 0 && lastIndexOf(str, part) === offset;
1925 }
1926 /**
1927 * 获取某个位置的字符
1928 */
1929
1930
1931 function charAt(str, index) {
1932 return str.charAt(index || 0);
1933 }
1934 /**
1935 * 获取某个位置的字符编码
1936 */
1937
1938
1939 function codeAt(str, index) {
1940 return str.charCodeAt(index || 0);
1941 }
1942 /**
1943 * 大写格式
1944 */
1945
1946
1947 function upper(str) {
1948 return str.toUpperCase();
1949 }
1950 /**
1951 * 小写格式
1952 */
1953
1954
1955 function lower(str) {
1956 return str.toLowerCase();
1957 }
1958 /**
1959 * str 是否包含 part
1960 *
1961 * @param str
1962 * @param part
1963 * @return 是否包含
1964 */
1965
1966
1967 function has$1(str, part) {
1968 return indexOf$1(str, part) >= 0;
1969 }
1970 /**
1971 * 判断长度大于 0 的字符串
1972 *
1973 * @param str
1974 * @return
1975 */
1976
1977
1978 function falsy$1(str) {
1979 return !string(str) || !str.length;
1980 }
1981
1982 var string$1 =
1983 /*#__PURE__*/
1984 {
1985 camelize: camelize,
1986 hyphenate: hyphenate,
1987 capitalize: capitalize,
1988 trim: trim,
1989 slice: slice,
1990 indexOf: indexOf$1,
1991 lastIndexOf: lastIndexOf,
1992 startsWith: startsWith,
1993 endsWith: endsWith,
1994 charAt: charAt,
1995 codeAt: codeAt,
1996 upper: upper,
1997 lower: lower,
1998 has: has$1,
1999 falsy: falsy$1
2000 };
2001 var dotPattern = /\./g,
2002 asteriskPattern = /\*/g,
2003 doubleAsteriskPattern = /\*\*/g,
2004 splitCache = {},
2005 patternCache = {};
2006 /**
2007 * 判断 keypath 是否以 prefix 开头,如果是,返回匹配上的前缀长度,否则返回 -1
2008 *
2009 * @param keypath
2010 * @param prefix
2011 * @return
2012 */
2013
2014 function match(keypath, prefix) {
2015 if (keypath === prefix) {
2016 return prefix.length;
2017 }
2018
2019 prefix += RAW_DOT;
2020 return startsWith(keypath, prefix) ? prefix.length : MINUS_ONE;
2021 }
2022 /**
2023 * 遍历 keypath 的每个部分
2024 *
2025 * @param keypath
2026 * @param callback 返回 false 可中断遍历
2027 */
2028
2029
2030 function each$1(keypath, callback) {
2031 // 如果 keypath 是 toString 之类的原型字段
2032 // splitCache[keypath] 会取到原型链上的对象
2033 // is.array() 比 splitCache.hasOwnProperty(keypath) 快一些
2034 // 虽然不如后者严谨,但在这里够用了
2035 var list;
2036
2037 if (array(splitCache[keypath])) {
2038 list = splitCache[keypath];
2039 } else {
2040 if (indexOf$1(keypath, RAW_DOT) < 0) {
2041 list = [keypath];
2042 } else {
2043 list = keypath.split(RAW_DOT);
2044 }
2045
2046 splitCache[keypath] = list;
2047 }
2048
2049 for (var i = 0, lastIndex = list.length - 1; i <= lastIndex; i++) {
2050 if (callback(list[i], i, lastIndex) === FALSE) {
2051 break;
2052 }
2053 }
2054 }
2055 /**
2056 * 遍历 keypath 的每个部分
2057 *
2058 * @param keypath1
2059 * @param keypath2
2060 */
2061
2062
2063 function join$1(keypath1, keypath2) {
2064 return keypath1 && keypath2 ? keypath1 + RAW_DOT + keypath2 : keypath1 || keypath2;
2065 }
2066 /**
2067 * 是否模糊匹配
2068 *
2069 * @param keypath
2070 */
2071
2072
2073 function isFuzzy(keypath) {
2074 return has$1(keypath, RAW_WILDCARD);
2075 }
2076 /**
2077 * 模糊匹配 keypath
2078 *
2079 * @param keypath
2080 * @param pattern
2081 */
2082
2083
2084 function matchFuzzy(keypath, pattern) {
2085 var cache = patternCache[pattern];
2086
2087 if (!cache) {
2088 var str = pattern.replace(dotPattern, '\\.').replace(asteriskPattern, '(\\w+)').replace(doubleAsteriskPattern, '([\.\\w]+?)');
2089 cache = patternCache[pattern] = new RegExp("^" + str + "$");
2090 }
2091
2092 var result = keypath.match(cache);
2093
2094 if (result) {
2095 return result[1];
2096 }
2097 }
2098 /**
2099 * 全局 value holder,避免频繁的创建临时对象
2100 */
2101
2102
2103 var holder = {
2104 value: UNDEFINED
2105 };
2106 /**
2107 * 获取对象的 key 的数组
2108 *
2109 * @param object
2110 * @return
2111 */
2112
2113 function keys(object) {
2114 return Object.keys(object);
2115 }
2116 /**
2117 * 遍历对象
2118 *
2119 * @param object
2120 * @param callback 返回 false 可停止遍历
2121 */
2122
2123
2124 function each$2(object, callback) {
2125 for (var key in object) {
2126 if (callback(object[key], key) === FALSE) {
2127 break;
2128 }
2129 }
2130 }
2131 /**
2132 * 清空对象所有的键值对
2133 *
2134 * @param object
2135 */
2136
2137
2138 function clear(object) {
2139 each$2(object, function (_, key) {
2140 delete object[key];
2141 });
2142 }
2143 /**
2144 * 扩展对象
2145 *
2146 * @return
2147 */
2148
2149
2150 function extend(original, object) {
2151 each$2(object, function (value, key) {
2152 original[key] = value;
2153 });
2154 return original;
2155 }
2156 /**
2157 * 合并对象
2158 *
2159 * @return
2160 */
2161
2162
2163 function merge(object1, object2) {
2164 return object1 && object2 ? extend(extend({}, object1), object2) : object1 || object2;
2165 }
2166 /**
2167 * 拷贝对象
2168 *
2169 * @param object
2170 * @param deep 是否需要深拷贝
2171 * @return
2172 */
2173
2174
2175 function copy(object$1, deep) {
2176 var result = object$1;
2177
2178 if (array(object$1)) {
2179 if (deep) {
2180 result = [];
2181 each(object$1, function (item, index) {
2182 result[index] = copy(item, deep);
2183 });
2184 } else {
2185 result = object$1.slice();
2186 }
2187 } else if (object(object$1)) {
2188 result = {};
2189 each$2(object$1, function (value, key) {
2190 result[key] = deep ? copy(value, deep) : value;
2191 });
2192 }
2193
2194 return result;
2195 }
2196 /**
2197 * 从对象中查找一个 keypath
2198 *
2199 * 返回值是空时,表示没找到值
2200 *
2201 * @param object
2202 * @param keypath
2203 * @return
2204 */
2205
2206
2207 function get(object, keypath) {
2208 each$1(keypath, function (key, index, lastIndex) {
2209 if (object != NULL) {
2210 // 先直接取值
2211 var value = object[key],
2212 // 紧接着判断值是否存在
2213 // 下面会处理计算属性的值,不能在它后面设置 hasValue
2214 hasValue = value !== UNDEFINED; // 如果是计算属性,取计算属性的值
2215
2216 if (value && func(value.get)) {
2217 value = value.get();
2218 }
2219
2220 if (index === lastIndex) {
2221 if (hasValue) {
2222 holder.value = value;
2223 object = holder;
2224 } else {
2225 object = UNDEFINED;
2226 }
2227 } else {
2228 object = value;
2229 }
2230 } else {
2231 object = UNDEFINED;
2232 return FALSE;
2233 }
2234 });
2235 return object;
2236 }
2237 /**
2238 * 为对象设置一个键值对
2239 *
2240 * @param object
2241 * @param keypath
2242 * @param value
2243 * @param autofill 是否自动填充不存在的对象,默认自动填充
2244 */
2245
2246
2247 function set(object, keypath, value, autofill) {
2248 each$1(keypath, function (key, index, lastIndex) {
2249 if (index === lastIndex) {
2250 object[key] = value;
2251 } else if (object[key]) {
2252 object = object[key];
2253 } else if (autofill) {
2254 object = object[key] = {};
2255 } else {
2256 return FALSE;
2257 }
2258 });
2259 }
2260 /**
2261 * 对象是否包含某个 key
2262 *
2263 * @param object
2264 * @param key
2265 * @return
2266 */
2267
2268
2269 function has$2(object, key) {
2270 // 不用 hasOwnProperty,性能差
2271 return object[key] !== UNDEFINED;
2272 }
2273 /**
2274 * 是否是空对象
2275 *
2276 * @param object
2277 * @return
2278 */
2279
2280
2281 function falsy$2(object$1) {
2282 return !object(object$1) || array(object$1) || !keys(object$1).length;
2283 }
2284
2285 var object$1 =
2286 /*#__PURE__*/
2287 {
2288 keys: keys,
2289 each: each$2,
2290 clear: clear,
2291 extend: extend,
2292 merge: merge,
2293 copy: copy,
2294 get: get,
2295 set: set,
2296 has: has$2,
2297 falsy: falsy$2
2298 };
2299
2300 function toString(target, defaultValue) {
2301 return target != NULL && target.toString ? target.toString() : defaultValue !== UNDEFINED ? defaultValue : EMPTY_STRING;
2302 }
2303
2304 var DEBUG = 1;
2305 var INFO = 2;
2306 var WARN = 3;
2307 var ERROR = 4;
2308 var FATAL = 5;
2309 /**
2310 * 是否有原生的日志特性,没有必要单独实现
2311 */
2312
2313 var nativeConsole = typeof console !== RAW_UNDEFINED ? console : NULL,
2314
2315 /**
2316 * 当前是否是源码调试,如果开启了代码压缩,empty function 里的注释会被干掉
2317 * 源码模式默认选 INFO,因为 DEBUG 输出的日志太多,会导致性能急剧下降
2318 */
2319 defaultLogLevel = /yox/.test(toString(EMPTY_FUNCTION)) ? INFO : WARN,
2320
2321 /**
2322 * console 样式前缀
2323 * ie 和 edge 不支持 console.log 样式
2324 */
2325 stylePrefix = WINDOW && /edge|msie|trident/i.test(WINDOW.navigator.userAgent) ? EMPTY_STRING : '%c',
2326
2327 /**
2328 * 日志打印函数
2329 */
2330 printLog = nativeConsole ? stylePrefix ? function (tag, msg, style) {
2331 nativeConsole.log(stylePrefix + tag, style, msg);
2332 } : function (tag, msg) {
2333 nativeConsole.log(tag, msg);
2334 } : EMPTY_FUNCTION;
2335 /**
2336 * 全局调试开关
2337 */
2338
2339 function getLogLevel() {
2340 if (GLOBAL) {
2341 var logLevel = GLOBAL['DEBUG_LEVEL'];
2342
2343 if (logLevel >= DEBUG && logLevel <= FATAL) {
2344 return logLevel;
2345 }
2346 }
2347
2348 return defaultLogLevel;
2349 }
2350
2351 function getStyle(backgroundColor) {
2352 return "background-color:" + backgroundColor + ";border-radius:12px;color:#fff;font-size:10px;padding:3px 6px;";
2353 }
2354 /**
2355 * 打印 debug 日志
2356 *
2357 * @param msg
2358 */
2359
2360
2361 function debug(msg, tag) {
2362 if (getLogLevel() <= DEBUG) {
2363 printLog(tag || 'debug', msg, getStyle('#999'));
2364 }
2365 }
2366 /**
2367 * 打印 info 日志
2368 *
2369 * @param msg
2370 */
2371
2372
2373 function info(msg, tag) {
2374 if (getLogLevel() <= INFO) {
2375 printLog(tag || 'info', msg, getStyle('#2db7f5'));
2376 }
2377 }
2378 /**
2379 * 打印 warn 日志
2380 *
2381 * @param msg
2382 */
2383
2384
2385 function warn(msg, tag) {
2386 if (getLogLevel() <= WARN) {
2387 printLog(tag || 'warn', msg, getStyle('#f90'));
2388 }
2389 }
2390 /**
2391 * 打印 error 日志
2392 *
2393 * @param msg
2394 */
2395
2396
2397 function error(msg, tag) {
2398 if (getLogLevel() <= ERROR) {
2399 printLog(tag || 'error', msg, getStyle('#ed4014'));
2400 }
2401 }
2402 /**
2403 * 致命错误,中断程序
2404 *
2405 * @param msg
2406 */
2407
2408
2409 function fatal(msg, tag) {
2410 if (getLogLevel() <= FATAL) {
2411 throw new Error("[" + (tag || 'fatal') + "]: " + msg);
2412 }
2413 }
2414
2415 var logger =
2416 /*#__PURE__*/
2417 {
2418 DEBUG: DEBUG,
2419 INFO: INFO,
2420 WARN: WARN,
2421 ERROR: ERROR,
2422 FATAL: FATAL,
2423 debug: debug,
2424 info: info,
2425 warn: warn,
2426 error: error,
2427 fatal: fatal
2428 };
2429
2430 var Emitter =
2431 /** @class */
2432 function () {
2433 function Emitter(ns) {
2434 this.ns = ns || FALSE;
2435 this.listeners = {};
2436 }
2437 /**
2438 * 发射事件
2439 *
2440 * @param type 事件名称或命名空间
2441 * @param args 事件处理函数的参数列表
2442 * @param filter 自定义过滤器
2443 */
2444
2445
2446 Emitter.prototype.fire = function (type, args, filter) {
2447 var instance = this,
2448 namespace = string(type) ? instance.parse(type) : type,
2449 list = instance.listeners[namespace.type],
2450 isComplete = TRUE;
2451
2452 if (list) {
2453 // 避免遍历过程中,数组发生变化,比如增删了
2454 list = copy(list); // 判断是否是发射事件
2455 // 如果 args 的第一个参数是 CustomEvent 类型,表示发射事件
2456 // 因为事件处理函数的参数列表是 (event, data)
2457
2458 var event = args && args[0] instanceof CustomEvent ? args[0] : UNDEFINED; // 这里不用 array.each,减少函数调用
2459
2460 for (var i = 0, length = list.length; i < length; i++) {
2461 var options = list[i]; // 命名空间不匹配
2462
2463 if (!matchNamespace(namespace.ns, options) // 在 fire 过程中被移除了
2464 || !has(list, options) // 传了 filter,则用 filter 判断是否过滤此 options
2465 || filter && !filter(namespace, args, options)) {
2466 continue;
2467 } // 为 event 对象加上当前正在处理的 listener
2468 // 这样方便业务层移除事件绑定
2469 // 比如 on('xx', function) 这样定义了匿名 listener
2470 // 在这个 listener 里面获取不到当前 listener 的引用
2471 // 为了能引用到,有时候会先定义 var listener = function
2472 // 然后再 on('xx', listener) 这样其实是没有必要的
2473
2474
2475 if (event) {
2476 event.listener = options.fn;
2477 }
2478
2479 var result = execute(options.fn, options.ctx, args);
2480
2481 if (event) {
2482 event.listener = UNDEFINED;
2483 } // 执行次数
2484
2485
2486 options.num = options.num ? options.num + 1 : 1; // 注册的 listener 可以指定最大执行次数
2487
2488 if (options.num === options.max) {
2489 instance.off(namespace, options.fn);
2490 } // 如果没有返回 false,而是调用了 event.stop 也算是返回 false
2491
2492
2493 if (event) {
2494 if (result === FALSE) {
2495 event.prevent().stop();
2496 } else if (event.isStoped) {
2497 result = FALSE;
2498 }
2499 }
2500
2501 if (result === FALSE) {
2502 isComplete = FALSE;
2503 break;
2504 }
2505 }
2506 }
2507
2508 return isComplete;
2509 };
2510 /**
2511 * 注册监听
2512 *
2513 * @param type
2514 * @param listener
2515 */
2516
2517
2518 Emitter.prototype.on = function (type, listener) {
2519 var instance = this,
2520 listeners = instance.listeners,
2521 options = func(listener) ? {
2522 fn: listener
2523 } : listener;
2524
2525 if (object(options) && func(options.fn)) {
2526 var namespace = string(type) ? instance.parse(type) : type;
2527 options.ns = namespace.ns;
2528 push(listeners[namespace.type] || (listeners[namespace.type] = []), options);
2529 } else {
2530 fatal("emitter.on(type, listener) invoke failed\uFF1A\n\n\"listener\" is expected to be a Function or an EmitterOptions.\n");
2531 }
2532 };
2533 /**
2534 * 取消监听
2535 *
2536 * @param type
2537 * @param listener
2538 */
2539
2540
2541 Emitter.prototype.off = function (type, listener) {
2542 var instance = this,
2543 listeners = instance.listeners;
2544
2545 if (type) {
2546 var namespace = string(type) ? instance.parse(type) : type,
2547 name = namespace.type,
2548 ns_1 = namespace.ns,
2549 matchListener_1 = createMatchListener(listener),
2550 each$1 = function (list, name) {
2551 each(list, function (options, index) {
2552 if (matchListener_1(options) && matchNamespace(ns_1, options)) {
2553 list.splice(index, 1);
2554 }
2555 }, TRUE);
2556
2557 if (!list.length) {
2558 delete listeners[name];
2559 }
2560 };
2561
2562 if (name) {
2563 if (listeners[name]) {
2564 each$1(listeners[name], name);
2565 }
2566 } else if (ns_1) {
2567 each$2(listeners, each$1);
2568 } // 在开发阶段进行警告,比如传了 listener 进来,listener 是个空值
2569 // 但你不知道它是空值
2570
2571
2572 {
2573 if (arguments.length > 1 && listener == NULL) {
2574 warn("emitter.off(type, listener) is invoked, but \"listener\" is " + listener + ".");
2575 }
2576 }
2577 } else {
2578 // 清空
2579 instance.listeners = {}; // 在开发阶段进行警告,比如传了 type 进来,type 是个空值
2580 // 但你不知道它是空值
2581
2582 {
2583 if (arguments.length > 0) {
2584 warn("emitter.off(type) is invoked, but \"type\" is " + type + ".");
2585 }
2586 }
2587 }
2588 };
2589 /**
2590 * 是否已监听某个事件
2591 *
2592 * @param type
2593 * @param listener
2594 */
2595
2596
2597 Emitter.prototype.has = function (type, listener) {
2598 var instance = this,
2599 listeners = instance.listeners,
2600 namespace = string(type) ? instance.parse(type) : type,
2601 name = namespace.type,
2602 ns = namespace.ns,
2603 result = TRUE,
2604 matchListener = createMatchListener(listener),
2605 each$1 = function (list) {
2606 each(list, function (options) {
2607 if (matchListener(options) && matchNamespace(ns, options)) {
2608 return result = FALSE;
2609 }
2610 });
2611 return result;
2612 };
2613
2614 if (name) {
2615 if (listeners[name]) {
2616 each$1(listeners[name]);
2617 }
2618 } else if (ns) {
2619 each$2(listeners, each$1);
2620 }
2621
2622 return !result;
2623 };
2624 /**
2625 * 把事件类型解析成命名空间格式
2626 *
2627 * @param type
2628 */
2629
2630
2631 Emitter.prototype.parse = function (type) {
2632 // 这里 ns 必须为字符串
2633 // 用于区分 event 对象是否已完成命名空间的解析
2634 var result = {
2635 type: type,
2636 ns: EMPTY_STRING
2637 }; // 是否开启命名空间
2638
2639 if (this.ns) {
2640 var index = indexOf$1(type, RAW_DOT);
2641
2642 if (index >= 0) {
2643 result.type = slice(type, 0, index);
2644 result.ns = slice(type, index + 1);
2645 }
2646 }
2647
2648 return result;
2649 };
2650
2651 return Emitter;
2652 }();
2653
2654 function matchTrue() {
2655 return TRUE;
2656 }
2657 /**
2658 * 外部会传入 Function 或 EmitterOptions 或 空
2659 *
2660 * 这里根据传入值的不同类型,创建不同的判断函数
2661 *
2662 * 如果传入的是 EmitterOptions,则全等判断
2663 *
2664 * 如果传入的是 Function,则判断函数是否全等
2665 *
2666 * 如果传入的是空,则直接返回 true
2667 *
2668 * @param listener
2669 */
2670
2671
2672 function createMatchListener(listener) {
2673 return func(listener) ? function (options) {
2674 return listener === options.fn;
2675 } : matchTrue;
2676 }
2677 /**
2678 * 判断 options 是否能匹配命名空间
2679 *
2680 * 如果 namespace 和 options.ns 都不为空,则需完全匹配
2681 *
2682 * 如果他们两个其中任何一个为空,则不判断命名空间
2683 *
2684 * @param namespace
2685 * @param options
2686 */
2687
2688
2689 function matchNamespace(namespace, options) {
2690 var ns = options.ns;
2691 return ns && namespace ? ns === namespace : TRUE;
2692 }
2693
2694 function isNative(target) {
2695 return func(target) && has$1(toString(target), '[native code]');
2696 }
2697
2698 var nextTick; // IE (10+) 和 node
2699
2700 if (typeof setImmediate === RAW_FUNCTION && isNative(setImmediate)) {
2701 nextTick = setImmediate;
2702 } // 用 MessageChannel 去做 setImmediate 的 polyfill
2703 // 原理是将新的 message 事件加入到原有的 dom events 之后
2704 // 兼容性 IE10+ 和其他标准浏览器
2705
2706
2707 if (typeof MessageChannel === RAW_FUNCTION && isNative(MessageChannel)) {
2708 nextTick = function (fn) {
2709 var channel = new MessageChannel();
2710 channel.port1.onmessage = fn;
2711 channel.port2.postMessage(1);
2712 };
2713 } else {
2714 nextTick = setTimeout;
2715 }
2716
2717 var nextTick$1 = nextTick;
2718 var shared;
2719
2720 var NextTask =
2721 /** @class */
2722 function () {
2723 function NextTask() {
2724 this.tasks = [];
2725 }
2726 /**
2727 * 全局单例
2728 */
2729
2730
2731 NextTask.shared = function () {
2732 return shared || (shared = new NextTask());
2733 };
2734 /**
2735 * 在队尾添加异步任务
2736 */
2737
2738
2739 NextTask.prototype.append = function (func, context) {
2740 var instance = this,
2741 tasks = instance.tasks;
2742 push(tasks, {
2743 fn: func,
2744 ctx: context
2745 });
2746
2747 if (tasks.length === 1) {
2748 nextTick$1(function () {
2749 instance.run();
2750 });
2751 }
2752 };
2753 /**
2754 * 在队首添加异步任务
2755 */
2756
2757
2758 NextTask.prototype.prepend = function (func, context) {
2759 var instance = this,
2760 tasks = instance.tasks;
2761 unshift(tasks, {
2762 fn: func,
2763 ctx: context
2764 });
2765
2766 if (tasks.length === 1) {
2767 nextTick$1(function () {
2768 instance.run();
2769 });
2770 }
2771 };
2772 /**
2773 * 清空异步队列
2774 */
2775
2776
2777 NextTask.prototype.clear = function () {
2778 this.tasks.length = 0;
2779 };
2780 /**
2781 * 立即执行异步任务,并清空队列
2782 */
2783
2784
2785 NextTask.prototype.run = function () {
2786 var tasks = this.tasks;
2787
2788 if (tasks.length) {
2789 this.tasks = [];
2790 each(tasks, function (task) {
2791 execute(task.fn, task.ctx);
2792 });
2793 }
2794 };
2795
2796 return NextTask;
2797 }(); // vnode.data 内部使用的几个字段
2798
2799
2800 var ID = '$id';
2801 var VNODE = '$vnode';
2802 var LOADING = '$loading';
2803 var COMPONENT = '$component';
2804 var LEAVING = '$leaving';
2805
2806 function update(api, vnode, oldVnode) {
2807 var node = vnode.node,
2808 nativeAttrs = vnode.nativeAttrs,
2809 oldNativeAttrs = oldVnode && oldVnode.nativeAttrs;
2810
2811 if (nativeAttrs || oldNativeAttrs) {
2812 var newValue = nativeAttrs || EMPTY_OBJECT,
2813 oldValue = oldNativeAttrs || EMPTY_OBJECT;
2814
2815 for (var name in newValue) {
2816 if (oldValue[name] === UNDEFINED || newValue[name] !== oldValue[name]) {
2817 api.attr(node, name, newValue[name]);
2818 }
2819 }
2820
2821 for (var name in oldValue) {
2822 if (newValue[name] === UNDEFINED) {
2823 api.removeAttr(node, name);
2824 }
2825 }
2826 }
2827 }
2828
2829 function update$1(api, vnode, oldVnode) {
2830 var node = vnode.node,
2831 nativeProps = vnode.nativeProps,
2832 oldNativeProps = oldVnode && oldVnode.nativeProps;
2833
2834 if (nativeProps || oldNativeProps) {
2835 var newValue = nativeProps || EMPTY_OBJECT,
2836 oldValue = oldNativeProps || EMPTY_OBJECT;
2837
2838 for (var name in newValue) {
2839 if (oldValue[name] === UNDEFINED || newValue[name] !== oldValue[name]) {
2840 api.prop(node, name, newValue[name]);
2841 }
2842 }
2843
2844 for (var name in oldValue) {
2845 if (newValue[name] === UNDEFINED) {
2846 api.removeProp(node, name);
2847 }
2848 }
2849 }
2850 }
2851
2852 function update$2(vnode, oldVnode) {
2853 var data = vnode.data,
2854 directives = vnode.directives,
2855 oldDirectives = oldVnode && oldVnode.directives;
2856
2857 if (directives || oldDirectives) {
2858 var node = data[COMPONENT] || vnode.node,
2859 isKeypathChange = oldVnode && vnode.keypath !== oldVnode.keypath,
2860 newValue = directives || EMPTY_OBJECT,
2861 oldValue = oldDirectives || EMPTY_OBJECT;
2862
2863 for (var name in newValue) {
2864 var directive = newValue[name],
2865 _a = directive.hooks,
2866 once = _a.once,
2867 bind = _a.bind,
2868 unbind = _a.unbind;
2869
2870 if (!oldValue[name]) {
2871 bind(node, directive, vnode);
2872 } else if (once || directive.value !== oldValue[name].value || isKeypathChange) {
2873 if (unbind) {
2874 unbind(node, oldValue[name], oldVnode);
2875 }
2876
2877 bind(node, directive, vnode);
2878 }
2879 }
2880
2881 for (var name in oldValue) {
2882 if (!newValue[name]) {
2883 var unbind = oldValue[name].hooks.unbind;
2884
2885 if (unbind) {
2886 unbind(node, oldValue[name], oldVnode);
2887 }
2888 }
2889 }
2890 }
2891 }
2892
2893 function remove$1(vnode) {
2894 var directives = vnode.directives;
2895
2896 if (directives) {
2897 var node = vnode.data[COMPONENT] || vnode.node;
2898
2899 for (var name in directives) {
2900 var unbind = directives[name].hooks.unbind;
2901
2902 if (unbind) {
2903 unbind(node, directives[name], vnode);
2904 }
2905 }
2906 }
2907 }
2908
2909 function update$3(vnode, oldVnode) {
2910 var data = vnode.data,
2911 ref = vnode.ref,
2912 props = vnode.props,
2913 slots = vnode.slots,
2914 directives = vnode.directives,
2915 context = vnode.context,
2916 node;
2917
2918 if (vnode.isComponent) {
2919 node = data[COMPONENT]; // 更新时才要 set
2920 // 因为初始化时,所有这些都经过构造函数完成了
2921
2922 if (oldVnode) {
2923 var model = directives && directives[DIRECTIVE_MODEL];
2924
2925 if (model) {
2926 if (!props) {
2927 props = {};
2928 }
2929
2930 props[node.$model] = model.value;
2931 }
2932
2933 {
2934 if (props) {
2935 each$2(props, function (value, key) {
2936 node.checkProp(key, value);
2937 });
2938 }
2939 }
2940 var result = merge(props, slots);
2941
2942 if (result) {
2943 node.forceUpdate(result);
2944 }
2945 }
2946 } else {
2947 node = vnode.node;
2948 }
2949
2950 if (ref) {
2951 var refs = context.$refs;
2952
2953 if (refs) {
2954 refs[ref] = node;
2955 }
2956 }
2957 }
2958
2959 function isPatchable(vnode, oldVnode) {
2960 return vnode.tag === oldVnode.tag && vnode.key === oldVnode.key;
2961 }
2962
2963 function createKeyToIndex(vnodes, startIndex, endIndex) {
2964 var result, vnode, key;
2965
2966 while (startIndex <= endIndex) {
2967 vnode = vnodes[startIndex];
2968
2969 if (vnode && (key = vnode.key)) {
2970 if (!result) {
2971 result = {};
2972 }
2973
2974 result[key] = startIndex;
2975 }
2976
2977 startIndex++;
2978 }
2979
2980 return result || EMPTY_OBJECT;
2981 }
2982
2983 function insertBefore(api, parentNode, node, referenceNode) {
2984 if (referenceNode) {
2985 api.before(parentNode, node, referenceNode);
2986 } else {
2987 api.append(parentNode, node);
2988 }
2989 }
2990
2991 function createComponent(vnode, options) {
2992 var child = (vnode.parent || vnode.context).createComponent(options, vnode);
2993 vnode.data[COMPONENT] = child;
2994 vnode.data[LOADING] = FALSE;
2995 update$3(vnode);
2996 update$2(vnode);
2997 return child;
2998 }
2999
3000 var guid = 0;
3001
3002 function createData() {
3003 var data = {};
3004 data[ID] = ++guid;
3005 return data;
3006 }
3007
3008 function createVnode(api, vnode) {
3009 var tag = vnode.tag,
3010 node = vnode.node,
3011 data = vnode.data,
3012 isComponent = vnode.isComponent,
3013 isComment = vnode.isComment,
3014 isText = vnode.isText,
3015 isStyle = vnode.isStyle,
3016 isOption = vnode.isOption,
3017 children = vnode.children,
3018 text = vnode.text,
3019 html = vnode.html,
3020 context = vnode.context;
3021
3022 if (node && data) {
3023 return;
3024 }
3025
3026 data = createData();
3027 vnode.data = data;
3028
3029 if (isText) {
3030 vnode.node = api.createText(text);
3031 return;
3032 }
3033
3034 if (isComment) {
3035 vnode.node = api.createComment(text);
3036 return;
3037 }
3038
3039 if (isComponent) {
3040 var componentOptions_1 = UNDEFINED; // 动态组件,tag 可能为空
3041
3042 if (tag) {
3043 context.loadComponent(tag, function (options) {
3044 if (has$2(data, LOADING)) {
3045 // 异步组件
3046 if (data[LOADING]) {
3047 // 尝试使用最新的 vnode
3048 if (data[VNODE]) {
3049 vnode = data[VNODE]; // 用完就删掉
3050
3051 delete data[VNODE];
3052 }
3053
3054 enterVnode(vnode, createComponent(vnode, options));
3055 }
3056 } // 同步组件
3057 else {
3058 componentOptions_1 = options;
3059 }
3060 });
3061 } // 不论是同步还是异步组件,都需要一个占位元素
3062
3063
3064 vnode.node = api.createComment(RAW_COMPONENT);
3065
3066 if (componentOptions_1) {
3067 createComponent(vnode, componentOptions_1);
3068 } else {
3069 data[LOADING] = TRUE;
3070 }
3071 } else {
3072 node = vnode.node = api.createElement(vnode.tag, vnode.isSvg);
3073
3074 if (children) {
3075 addVnodes(api, node, children);
3076 } else if (text) {
3077 api.text(node, text, isStyle, isOption);
3078 } else if (html) {
3079 api.html(node, html, isStyle, isOption);
3080 }
3081
3082 update(api, vnode);
3083 update$1(api, vnode);
3084 update$3(vnode);
3085 update$2(vnode);
3086 }
3087 }
3088
3089 function addVnodes(api, parentNode, vnodes, startIndex, endIndex, before) {
3090 var vnode,
3091 start = startIndex || 0,
3092 end = endIndex !== UNDEFINED ? endIndex : vnodes.length - 1;
3093
3094 while (start <= end) {
3095 vnode = vnodes[start];
3096 createVnode(api, vnode);
3097 insertVnode(api, parentNode, vnode, before);
3098 start++;
3099 }
3100 }
3101
3102 function insertVnode(api, parentNode, vnode, before) {
3103 var node = vnode.node,
3104 data = vnode.data,
3105 context = vnode.context,
3106 hasParent = api.parent(node); // 这里不调用 insertBefore,避免判断两次
3107
3108 if (before) {
3109 api.before(parentNode, node, before.node);
3110 } else {
3111 api.append(parentNode, node);
3112 } // 普通元素和组件的占位节点都会走到这里
3113 // 但是占位节点不用 enter,而是等组件加载回来之后再调 enter
3114
3115
3116 if (!hasParent) {
3117 var enter = UNDEFINED;
3118
3119 if (vnode.isComponent) {
3120 var component_1 = data[COMPONENT];
3121
3122 if (component_1) {
3123 enter = function () {
3124 enterVnode(vnode, component_1);
3125 };
3126 }
3127 } else if (!vnode.isStatic && !vnode.isText && !vnode.isComment) {
3128 enter = function () {
3129 enterVnode(vnode);
3130 };
3131 }
3132
3133 if (enter) {
3134 // 执行到这时,组件还没有挂载到 DOM 树
3135 // 如果此时直接触发 enter,外部还需要做多余的工作,比如 setTimeout
3136 // 索性这里直接等挂载到 DOM 数之后再触发
3137 // 注意:YoxInterface 没有声明 $observer,因为不想让外部访问,
3138 // 但是这里要用一次,所以加了 as any
3139 context.$observer.nextTask.prepend(enter);
3140 }
3141 }
3142 }
3143
3144 function removeVnodes(api, parentNode, vnodes, startIndex, endIndex) {
3145 var vnode,
3146 start = startIndex || 0,
3147 end = endIndex !== UNDEFINED ? endIndex : vnodes.length - 1;
3148
3149 while (start <= end) {
3150 vnode = vnodes[start];
3151
3152 if (vnode) {
3153 removeVnode(api, parentNode, vnode);
3154 }
3155
3156 start++;
3157 }
3158 }
3159
3160 function removeVnode(api, parentNode, vnode) {
3161 var node = vnode.node;
3162
3163 if (vnode.isStatic || vnode.isText || vnode.isComment) {
3164 api.remove(parentNode, node);
3165 } else {
3166 var done = function () {
3167 destroyVnode(api, vnode);
3168 api.remove(parentNode, node);
3169 },
3170 component_2;
3171
3172 if (vnode.isComponent) {
3173 component_2 = vnode.data[COMPONENT]; // 异步组件,还没加载成功就被删除了
3174
3175 if (!component_2) {
3176 done();
3177 return;
3178 }
3179 }
3180
3181 leaveVnode(vnode, component_2, done);
3182 }
3183 }
3184
3185 function destroyVnode(api, vnode) {
3186 /**
3187 * 如果一个子组件的模板是这样写的:
3188 *
3189 * <div>
3190 * {{#if visible}}
3191 * <slot name="children"/>
3192 * {{/if}}
3193 * </div>
3194 *
3195 * 当 visible 从 true 变为 false 时,不能销毁 slot 导入的任何 vnode
3196 * 不论是组件或是元素,都不能销毁,只能简单的 remove,
3197 * 否则子组件下一次展现它们时,会出问题
3198 */
3199 var data = vnode.data,
3200 children = vnode.children,
3201 parent = vnode.parent,
3202 slot = vnode.slot; // 销毁插槽组件
3203 // 如果宿主组件正在销毁,$vnode 属性会在调 destroy() 之前被删除
3204 // 这里表示的是宿主组件还没被销毁
3205 // 如果宿主组件被销毁了,则它的一切都要进行销毁
3206
3207 if (slot && parent && parent.$vnode) {
3208 // 如果更新时,父组件没有传入该 slot,则子组件需要销毁该 slot
3209 var slots = parent.get(slot); // slots 要么没有,要么是数组,不可能是别的
3210
3211 if (slots && has(slots, vnode)) {
3212 return;
3213 }
3214 }
3215
3216 if (vnode.isComponent) {
3217 var component_3 = data[COMPONENT];
3218
3219 if (component_3) {
3220 remove$1(vnode);
3221 component_3.destroy();
3222 } else {
3223 [data[LOADING] = FALSE];
3224 }
3225 } else {
3226 remove$1(vnode);
3227
3228 if (children) {
3229 each(children, function (child) {
3230 destroyVnode(api, child);
3231 });
3232 }
3233 }
3234 }
3235 /**
3236 * vnode 触发 enter hook 时,外部一般会做一些淡入动画
3237 */
3238
3239
3240 function enterVnode(vnode, component) {
3241 // 如果组件根元素和组件本身都写了 transition
3242 // 优先用外面定义的
3243 // 因为这明确是在覆盖配置
3244 var data = vnode.data,
3245 transition = vnode.transition;
3246
3247 if (component && !transition) {
3248 // 再看组件根元素是否有 transition
3249 transition = component.$vnode.transition;
3250 }
3251
3252 execute(data[LEAVING]);
3253
3254 if (transition) {
3255 var enter = transition.enter;
3256
3257 if (enter) {
3258 enter(vnode.node);
3259 return;
3260 }
3261 }
3262 }
3263 /**
3264 * vnode 触发 leave hook 时,外部一般会做一些淡出动画
3265 * 动画结束后才能移除节点,否则无法产生动画
3266 * 这里由外部调用 done 来通知内部动画结束
3267 */
3268
3269
3270 function leaveVnode(vnode, component, done) {
3271 // 如果组件根元素和组件本身都写了 transition
3272 // 优先用外面定义的
3273 // 因为这明确是在覆盖配置
3274 var data = vnode.data,
3275 transition = vnode.transition;
3276
3277 if (component && !transition) {
3278 // 再看组件根元素是否有 transition
3279 transition = component.$vnode.transition;
3280 }
3281
3282 if (transition) {
3283 var leave = transition.leave;
3284
3285 if (leave) {
3286 leave(vnode.node, data[LEAVING] = function () {
3287 if (data[LEAVING]) {
3288 done();
3289 data[LEAVING] = UNDEFINED;
3290 }
3291 });
3292 return;
3293 }
3294 } // 如果没有淡出动画,直接结束
3295
3296
3297 done();
3298 }
3299
3300 function updateChildren(api, parentNode, children, oldChildren) {
3301 var startIndex = 0,
3302 endIndex = children.length - 1,
3303 startVnode = children[startIndex],
3304 endVnode = children[endIndex],
3305 oldStartIndex = 0,
3306 oldEndIndex = oldChildren.length - 1,
3307 oldStartVnode = oldChildren[oldStartIndex],
3308 oldEndVnode = oldChildren[oldEndIndex],
3309 oldKeyToIndex,
3310 oldIndex;
3311
3312 while (oldStartIndex <= oldEndIndex && startIndex <= endIndex) {
3313 // 下面有设为 UNDEFINED 的逻辑
3314 if (!startVnode) {
3315 startVnode = children[++startIndex];
3316 } else if (!endVnode) {
3317 endVnode = children[--endIndex];
3318 } else if (!oldStartVnode) {
3319 oldStartVnode = oldChildren[++oldStartIndex];
3320 } else if (!oldEndVnode) {
3321 oldEndVnode = oldChildren[--oldEndIndex];
3322 } // 从头到尾比较,位置相同且值得 patch
3323 else if (isPatchable(startVnode, oldStartVnode)) {
3324 patch(api, startVnode, oldStartVnode);
3325 startVnode = children[++startIndex];
3326 oldStartVnode = oldChildren[++oldStartIndex];
3327 } // 从尾到头比较,位置相同且值得 patch
3328 else if (isPatchable(endVnode, oldEndVnode)) {
3329 patch(api, endVnode, oldEndVnode);
3330 endVnode = children[--endIndex];
3331 oldEndVnode = oldChildren[--oldEndIndex];
3332 } // 比较完两侧的节点,剩下就是 位置发生改变的节点 和 全新的节点
3333 // 当 endVnode 和 oldStartVnode 值得 patch
3334 // 说明元素被移到右边了
3335 else if (isPatchable(endVnode, oldStartVnode)) {
3336 patch(api, endVnode, oldStartVnode);
3337 insertBefore(api, parentNode, oldStartVnode.node, api.next(oldEndVnode.node));
3338 endVnode = children[--endIndex];
3339 oldStartVnode = oldChildren[++oldStartIndex];
3340 } // 当 oldEndVnode 和 startVnode 值得 patch
3341 // 说明元素被移到左边了
3342 else if (isPatchable(startVnode, oldEndVnode)) {
3343 patch(api, startVnode, oldEndVnode);
3344 insertBefore(api, parentNode, oldEndVnode.node, oldStartVnode.node);
3345 startVnode = children[++startIndex];
3346 oldEndVnode = oldChildren[--oldEndIndex];
3347 } // 尝试同级元素的 key
3348 else {
3349 if (!oldKeyToIndex) {
3350 oldKeyToIndex = createKeyToIndex(oldChildren, oldStartIndex, oldEndIndex);
3351 } // 新节点之前的位置
3352
3353
3354 oldIndex = startVnode.key ? oldKeyToIndex[startVnode.key] : UNDEFINED; // 移动元素
3355
3356 if (oldIndex !== UNDEFINED) {
3357 patch(api, startVnode, oldChildren[oldIndex]);
3358 oldChildren[oldIndex] = UNDEFINED;
3359 } // 新元素
3360 else {
3361 createVnode(api, startVnode);
3362 }
3363
3364 insertVnode(api, parentNode, startVnode, oldStartVnode);
3365 startVnode = children[++startIndex];
3366 }
3367 }
3368
3369 if (oldStartIndex > oldEndIndex) {
3370 addVnodes(api, parentNode, children, startIndex, endIndex, children[endIndex + 1]);
3371 } else if (startIndex > endIndex) {
3372 removeVnodes(api, parentNode, oldChildren, oldStartIndex, oldEndIndex);
3373 }
3374 }
3375
3376 function patch(api, vnode, oldVnode) {
3377 if (vnode === oldVnode) {
3378 return;
3379 }
3380
3381 var node = oldVnode.node,
3382 data = oldVnode.data; // 如果不能 patch,则删除重建
3383
3384 if (!isPatchable(vnode, oldVnode)) {
3385 // 同步加载的组件,初始化时不会传入占位节点
3386 // 它内部会自动生成一个注释节点,当它的根 vnode 和注释节点对比时,必然无法 patch
3387 // 于是走进此分支,为新组件创建一个 DOM 节点,然后继续 createComponent 后面的流程
3388 var parentNode = api.parent(node);
3389 createVnode(api, vnode);
3390
3391 if (parentNode) {
3392 insertVnode(api, parentNode, vnode, oldVnode);
3393 removeVnode(api, parentNode, oldVnode);
3394 }
3395
3396 return;
3397 }
3398
3399 vnode.node = node;
3400 vnode.data = data; // 组件正在异步加载,更新为最新的 vnode
3401 // 当异步加载完成时才能用上最新的 vnode
3402
3403 if (oldVnode.isComponent && data[LOADING]) {
3404 data[VNODE] = vnode;
3405 return;
3406 }
3407
3408 update(api, vnode, oldVnode);
3409 update$1(api, vnode, oldVnode);
3410 update$3(vnode, oldVnode);
3411 update$2(vnode, oldVnode);
3412 var text = vnode.text,
3413 html = vnode.html,
3414 children = vnode.children,
3415 isStyle = vnode.isStyle,
3416 isOption = vnode.isOption,
3417 oldText = oldVnode.text,
3418 oldHtml = oldVnode.html,
3419 oldChildren = oldVnode.children;
3420
3421 if (string(text)) {
3422 if (text !== oldText) {
3423 api.text(node, text, isStyle, isOption);
3424 }
3425 } else if (string(html)) {
3426 if (html !== oldHtml) {
3427 api.html(node, html, isStyle, isOption);
3428 }
3429 } // 两个都有需要 diff
3430 else if (children && oldChildren) {
3431 if (children !== oldChildren) {
3432 updateChildren(api, node, children, oldChildren);
3433 }
3434 } // 有新的没旧的 - 新增节点
3435 else if (children) {
3436 if (string(oldText) || string(oldHtml)) {
3437 api.text(node, EMPTY_STRING, isStyle);
3438 }
3439
3440 addVnodes(api, node, children);
3441 } // 有旧的没新的 - 删除节点
3442 else if (oldChildren) {
3443 removeVnodes(api, node, oldChildren);
3444 } // 有旧的 text 没有新的 text
3445 else if (string(oldText) || string(oldHtml)) {
3446 api.text(node, EMPTY_STRING, isStyle);
3447 }
3448 }
3449
3450 function create(api, node, context, keypath) {
3451 return {
3452 tag: api.tag(node),
3453 data: createData(),
3454 node: node,
3455 context: context,
3456 keypath: keypath
3457 };
3458 }
3459
3460 function destroy(api, vnode, isRemove) {
3461 if (isRemove) {
3462 var parentNode = api.parent(vnode.node);
3463
3464 if (parentNode) {
3465 removeVnode(api, parentNode, vnode);
3466 } else {
3467 fatal("The vnode can't be destroyed without a parent node.");
3468 }
3469 } else {
3470 destroyVnode(api, vnode);
3471 }
3472 }
3473 /**
3474 * 元素 节点
3475 */
3476
3477
3478 var ELEMENT = 1;
3479 /**
3480 * 属性 节点
3481 */
3482
3483 var ATTRIBUTE = 2;
3484 /**
3485 * 指令 节点
3486 */
3487
3488 var DIRECTIVE = 3;
3489 /**
3490 * 属性 节点
3491 */
3492
3493 var PROPERTY = 4;
3494 /**
3495 * 文本 节点
3496 */
3497
3498 var TEXT = 5;
3499 /**
3500 * if 节点
3501 */
3502
3503 var IF = 6;
3504 /**
3505 * else if 节点
3506 */
3507
3508 var ELSE_IF = 7;
3509 /**
3510 * else 节点
3511 */
3512
3513 var ELSE = 8;
3514 /**
3515 * each 节点
3516 */
3517
3518 var EACH = 9;
3519 /**
3520 * partial 节点
3521 */
3522
3523 var PARTIAL = 10;
3524 /**
3525 * import 节点
3526 */
3527
3528 var IMPORT = 11;
3529 /**
3530 * 表达式 节点
3531 */
3532
3533 var EXPRESSION = 12;
3534 /**
3535 * 延展操作 节点
3536 */
3537
3538 var SPREAD = 13; // 特殊标签
3539
3540 var specialTags = {}; // 特殊属性
3541
3542 var specialAttrs = {}; // 名称 -> 类型的映射
3543
3544 var name2Type = {};
3545 specialTags[RAW_SLOT] = specialTags[RAW_TEMPLATE] = specialAttrs[RAW_KEY] = specialAttrs[RAW_REF] = specialAttrs[RAW_SLOT] = TRUE;
3546 name2Type['if'] = IF;
3547 name2Type['each'] = EACH;
3548 name2Type['partial'] = PARTIAL;
3549
3550 function createAttribute(name) {
3551 return {
3552 type: ATTRIBUTE,
3553 isStatic: TRUE,
3554 name: name
3555 };
3556 }
3557
3558 function createDirective(name, ns, modifier) {
3559 return {
3560 type: DIRECTIVE,
3561 ns: ns,
3562 name: name,
3563 key: join$1(ns, name),
3564 modifier: modifier
3565 };
3566 }
3567
3568 function createProperty(name, hint, value, expr, children) {
3569 return {
3570 type: PROPERTY,
3571 isStatic: TRUE,
3572 name: name,
3573 hint: hint,
3574 value: value,
3575 expr: expr,
3576 children: children
3577 };
3578 }
3579
3580 function createEach(from, to, equal, index) {
3581 return {
3582 type: EACH,
3583 from: from,
3584 to: to,
3585 equal: equal,
3586 index: index,
3587 isComplex: TRUE
3588 };
3589 }
3590
3591 function createElement(tag, isSvg, isStyle, isComponent) {
3592 return {
3593 type: ELEMENT,
3594 tag: tag,
3595 isSvg: isSvg,
3596 isStyle: isStyle,
3597 // 只有 <option> 没有 value 属性时才为 true
3598 isOption: FALSE,
3599 isComponent: isComponent,
3600 isStatic: !isComponent && tag !== RAW_SLOT
3601 };
3602 }
3603
3604 function createElse() {
3605 return {
3606 type: ELSE
3607 };
3608 }
3609
3610 function createElseIf(expr) {
3611 return {
3612 type: ELSE_IF,
3613 expr: expr
3614 };
3615 }
3616
3617 function createExpression(expr, safe) {
3618 return {
3619 type: EXPRESSION,
3620 expr: expr,
3621 safe: safe,
3622 isLeaf: TRUE
3623 };
3624 }
3625
3626 function createIf(expr) {
3627 return {
3628 type: IF,
3629 expr: expr
3630 };
3631 }
3632
3633 function createImport(name) {
3634 return {
3635 type: IMPORT,
3636 name: name,
3637 isComplex: TRUE,
3638 isLeaf: TRUE
3639 };
3640 }
3641
3642 function createPartial(name) {
3643 return {
3644 type: PARTIAL,
3645 name: name,
3646 isComplex: TRUE
3647 };
3648 }
3649
3650 function createSpread(expr, binding) {
3651 return {
3652 type: SPREAD,
3653 expr: expr,
3654 binding: binding,
3655 isLeaf: TRUE
3656 };
3657 }
3658
3659 function createText(text) {
3660 return {
3661 type: TEXT,
3662 text: text,
3663 isStatic: TRUE,
3664 isLeaf: TRUE
3665 };
3666 } // 首字母大写,或中间包含 -
3667
3668
3669 var componentNamePattern = /^[$A-Z]|-/,
3670 // HTML 实体(中间最多 6 位,没见过更长的)
3671 htmlEntityPattern = /&[#\w\d]{2,6};/,
3672 // 常见的自闭合标签
3673 selfClosingTagNames = 'area,base,embed,track,source,param,input,col,img,br,hr'.split(','),
3674 // 常见的 svg 标签
3675 svgTagNames = 'svg,g,defs,desc,metadata,symbol,use,image,path,rect,circle,line,ellipse,polyline,polygon,text,tspan,tref,textpath,marker,pattern,clippath,mask,filter,cursor,view,animate,font,font-face,glyph,missing-glyph,foreignObject'.split(','),
3676 // 常见的字符串类型的属性
3677 // 注意:autocomplete,autocapitalize 不是布尔类型
3678 stringProperyNames = 'id,class,name,value,for,accesskey,title,style,src,type,href,target,alt,placeholder,preload,poster,wrap,accept,pattern,dir,autocomplete,autocapitalize'.split(','),
3679 // 常见的数字类型的属性
3680 numberProperyNames = 'min,minlength,max,maxlength,step,width,height,size,rows,cols,tabindex'.split(','),
3681 // 常见的布尔类型的属性
3682 booleanProperyNames = 'disabled,checked,required,multiple,readonly,autofocus,autoplay,controls,loop,muted,novalidate,draggable,hidden,spellcheck'.split(','),
3683 // 某些属性 attribute name 和 property name 不同
3684 attr2Prop = {}; // 列举几个常见的
3685
3686 attr2Prop['for'] = 'htmlFor';
3687 attr2Prop['class'] = 'className';
3688 attr2Prop['accesskey'] = 'accessKey';
3689 attr2Prop['style'] = 'style.cssText';
3690 attr2Prop['novalidate'] = 'noValidate';
3691 attr2Prop['readonly'] = 'readOnly';
3692 attr2Prop['tabindex'] = 'tabIndex';
3693 attr2Prop['minlength'] = 'minLength';
3694 attr2Prop['maxlength'] = 'maxLength';
3695
3696 function isSelfClosing(tagName) {
3697 return has(selfClosingTagNames, tagName);
3698 }
3699
3700 function createAttribute$1(element, name) {
3701 // 组件用驼峰格式
3702 if (element.isComponent) {
3703 return createAttribute(camelize(name));
3704 } // 原生 dom 属性
3705 else {
3706 // 把 attr 优化成 prop
3707 var lowerName = lower(name); // <slot> 、<template> 或 svg 中的属性不用识别为 property
3708
3709 if (specialTags[element.tag] || element.isSvg) {
3710 return createAttribute(name);
3711 } // 尝试识别成 property
3712 else if (has(stringProperyNames, lowerName)) {
3713 return createProperty(attr2Prop[lowerName] || lowerName, HINT_STRING);
3714 } else if (has(numberProperyNames, lowerName)) {
3715 return createProperty(attr2Prop[lowerName] || lowerName, HINT_NUMBER);
3716 } else if (has(booleanProperyNames, lowerName)) {
3717 return createProperty(attr2Prop[lowerName] || lowerName, HINT_BOOLEAN);
3718 } // 没辙,还是个 attribute
3719
3720
3721 return createAttribute(name);
3722 }
3723 }
3724
3725 function getAttributeDefaultValue(element, name) {
3726 // 比如 <Dog isLive>
3727 if (element.isComponent) {
3728 return TRUE;
3729 } // <div data-name checked>
3730 else {
3731 return startsWith(name, 'data-') ? EMPTY_STRING : name;
3732 }
3733 }
3734
3735 function createElement$1(tagName) {
3736 var isSvg = has(svgTagNames, tagName),
3737 isComponent = FALSE; // 是 svg 就不可能是组件
3738 // 加这个判断的原因是,svg 某些标签含有 连字符 和 大写字母,比较蛋疼
3739
3740 if (!isSvg && componentNamePattern.test(tagName)) {
3741 isComponent = TRUE;
3742 }
3743
3744 return createElement(tagName, isSvg, tagName === 'style', isComponent);
3745 }
3746
3747 function compatElement(element) {
3748 var tag = element.tag,
3749 attrs = element.attrs,
3750 hasType = FALSE,
3751 hasValue = FALSE;
3752
3753 if (attrs) {
3754 each(attrs, function (attr) {
3755 var name = attr.type === PROPERTY ? attr.name : UNDEFINED;
3756
3757 if (name === 'type') {
3758 hasType = TRUE;
3759 } else if (name === RAW_VALUE) {
3760 hasValue = TRUE;
3761 }
3762 });
3763 } // 补全 style 标签的 type
3764 // style 如果没有 type 则加一个 type="text/css"
3765 // 因为低版本 IE 没这个属性,没法正常渲染样式
3766
3767
3768 if (element.isStyle && !hasType) {
3769 push(element.attrs || (element.attrs = []), createProperty('type', HINT_STRING, 'text/css'));
3770 } // 低版本 IE 需要给 option 标签强制加 value
3771 else if (tag === 'option' && !hasValue) {
3772 element.isOption = TRUE;
3773 }
3774 }
3775
3776 function setElementText(element, text) {
3777 if (htmlEntityPattern.test(text)) {
3778 element.html = text;
3779 return TRUE;
3780 }
3781 }
3782
3783 function toNumber(target, defaultValue) {
3784 return numeric(target) ? +target : defaultValue !== UNDEFINED ? defaultValue : 0;
3785 }
3786 /**
3787 * 字面量
3788 */
3789
3790
3791 var LITERAL = 1;
3792 /**
3793 * 标识符
3794 */
3795
3796 var IDENTIFIER = 2;
3797 /**
3798 * 对象属性或数组下标
3799 */
3800
3801 var MEMBER = 3;
3802 /**
3803 * 一元表达式,如 - a
3804 */
3805
3806 var UNARY = 4;
3807 /**
3808 * 二元表达式,如 a + b
3809 */
3810
3811 var BINARY = 5;
3812 /**
3813 * 三元表达式,如 a ? b : c
3814 */
3815
3816 var TERNARY = 6;
3817 /**
3818 * 数组表达式,如 [ 1, 2, 3 ]
3819 */
3820
3821 var ARRAY = 7;
3822 /**
3823 * 对象表达式,如 { name: 'yox' }
3824 */
3825
3826 var OBJECT = 8;
3827 /**
3828 * 函数调用表达式,如 a()
3829 */
3830
3831 var CALL = 9;
3832
3833 function isDef(target) {
3834 return target !== UNDEFINED;
3835 }
3836
3837 function createArray(nodes, raw) {
3838 return {
3839 type: ARRAY,
3840 raw: raw,
3841 nodes: nodes
3842 };
3843 }
3844
3845 function createBinary(left, operator, right, raw) {
3846 return {
3847 type: BINARY,
3848 raw: raw,
3849 left: left,
3850 operator: operator,
3851 right: right
3852 };
3853 }
3854
3855 function createCall(name, args, raw) {
3856 return {
3857 type: CALL,
3858 raw: raw,
3859 name: name,
3860 args: args
3861 };
3862 }
3863
3864 function createIdentifier(raw, name, isProp) {
3865 var lookup = TRUE,
3866 offset = 0;
3867
3868 if (name === KEYPATH_CURRENT || name === KEYPATH_PARENT) {
3869 lookup = FALSE;
3870
3871 if (name === KEYPATH_PARENT) {
3872 offset = 1;
3873 }
3874
3875 name = EMPTY_STRING;
3876 } // 对象属性需要区分 a.b 和 a[b]
3877 // 如果不借用 Literal 无法实现这个判断
3878 // 同理,如果用了这种方式,就无法区分 a.b 和 a['b'],但是无所谓,这两种表示法本就一个意思
3879
3880
3881 return isProp ? createLiteral(name, raw) : createIdentifierInner(raw, name, lookup, offset);
3882 }
3883
3884 function createLiteral(value, raw) {
3885 return {
3886 type: LITERAL,
3887 raw: raw,
3888 value: value
3889 };
3890 }
3891
3892 function createObject(keys, values, raw) {
3893 return {
3894 type: OBJECT,
3895 raw: raw,
3896 keys: keys,
3897 values: values
3898 };
3899 }
3900
3901 function createTernary(test, yes, no, raw) {
3902 return {
3903 type: TERNARY,
3904 raw: raw,
3905 test: test,
3906 yes: yes,
3907 no: no
3908 };
3909 }
3910
3911 function createUnary(operator, node, raw) {
3912 return {
3913 type: UNARY,
3914 raw: raw,
3915 operator: operator,
3916 node: node
3917 };
3918 }
3919 /**
3920 * 通过判断 nodes 来决定是否需要创建 Member
3921 *
3922 * 创建 Member 至少需要 nodes 有两个节点
3923 */
3924
3925
3926 function createMemberIfNeeded(raw, nodes) {
3927 // 第一个节点要特殊处理
3928 var firstNode = nodes.shift(),
3929 // 是否向上查找
3930 lookup = TRUE,
3931 // 偏移量,默认从当前 context 开始查找
3932 offset = 0; // 表示传入的 nodes 至少有两个节点(弹出了一个)
3933
3934 if (nodes.length > 0) {
3935 // 处理剩下的 nodes
3936 // 这里要做两手准备:
3937 // 1. 如果全是 literal 节点,则编译时 join
3938 // 2. 如果不全是 literal 节点,则运行时 join
3939 // 是否全是 Literal 节点
3940 var isLiteral_1 = TRUE,
3941 // 静态节点
3942 staticNodes_1 = [],
3943 // 对于 this.a.b[c] 这样的
3944 // 要还原静态部分 this.a.b 的 raw
3945 // 虽然 raw 没什么大用吧,谁让我是洁癖呢
3946 staticRaw_1 = EMPTY_STRING,
3947 // 动态节点
3948 dynamicNodes_1 = [];
3949 each(nodes, function (node) {
3950 if (isLiteral_1) {
3951 if (node.type === LITERAL) {
3952 if (node.raw === KEYPATH_PARENT) {
3953 offset += 1;
3954 staticRaw_1 = staticRaw_1 ? staticRaw_1 + RAW_SLASH + KEYPATH_PARENT : KEYPATH_PARENT;
3955 return;
3956 }
3957
3958 if (node.raw !== KEYPATH_CURRENT) {
3959 var value = toString(node.value);
3960 push(staticNodes_1, value);
3961
3962 if (staticRaw_1) {
3963 staticRaw_1 += endsWith(staticRaw_1, KEYPATH_PARENT) ? RAW_SLASH : RAW_DOT;
3964 }
3965
3966 staticRaw_1 += value;
3967 }
3968 } else {
3969 isLiteral_1 = FALSE;
3970 }
3971 }
3972
3973 if (!isLiteral_1) {
3974 push(dynamicNodes_1, node);
3975 }
3976 }); // lookup 要求第一位元素是 Identifier,且它的 lookup 是 true 才为 true
3977 // 其他情况都为 false,如 "11".length 第一位元素是 Literal,不存在向上寻找的需求
3978 // 优化 1:计算 keypath
3979 //
3980 // 计算 keypath 的唯一方式是,第一位元素是 Identifier,后面都是 Literal
3981 // 否则就表示中间包含动态元素,这会导致无法计算静态路径
3982 // 如 a.b.c 可以算出 static keypath,而 a[b].c 则不行,因为 b 是动态的
3983 // 优化 2:计算 offset 并智能转成 Identifier
3984 //
3985 // 比如 xx 这样的表达式,应优化成 offset = 2,并转成 Identifier
3986 // 处理第一个节点
3987
3988 if (firstNode.type === IDENTIFIER) {
3989 lookup = firstNode.lookup;
3990 offset += firstNode.offset;
3991 var firstName = firstNode.name; // 不是 KEYPATH_THIS 或 KEYPATH_PARENT
3992
3993 if (firstName) {
3994 unshift(staticNodes_1, firstName);
3995 } // 转成 Identifier
3996
3997
3998 firstName = join(staticNodes_1, RAW_DOT); // a.b.c
3999
4000 if (isLiteral_1) {
4001 firstNode = createIdentifierInner(raw, firstName, lookup, offset);
4002 } // a[b]
4003 // this.a[b]
4004 else {
4005 // 当 isLiteral 为 false 时
4006 // 需要为 lead 节点创建合适的 raw
4007 var firstRaw = firstNode.raw;
4008
4009 if (staticRaw_1) {
4010 firstRaw += (firstRaw === KEYPATH_PARENT ? RAW_SLASH : RAW_DOT) + staticRaw_1;
4011 }
4012
4013 firstNode = createMemberInner(raw, createIdentifierInner(firstRaw, firstName, lookup, offset), UNDEFINED, dynamicNodes_1, lookup, offset);
4014 }
4015 } else {
4016 // 例子:
4017 // "xxx".length
4018 // format().a.b
4019 if (isLiteral_1) {
4020 firstNode = createMemberInner(raw, firstNode, join(staticNodes_1, RAW_DOT), UNDEFINED, lookup, offset);
4021 } // 例子:
4022 // "xxx"[length]
4023 // format()[a]
4024 else {
4025 firstNode = createMemberInner(raw, firstNode, UNDEFINED, dynamicNodes_1, lookup, offset);
4026 }
4027 }
4028 }
4029
4030 return firstNode;
4031 }
4032
4033 function createIdentifierInner(raw, name, lookup, offset) {
4034 return {
4035 type: IDENTIFIER,
4036 raw: raw,
4037 name: name,
4038 lookup: lookup,
4039 offset: offset
4040 };
4041 }
4042
4043 function createMemberInner(raw, lead, keypath, nodes, lookup, offset) {
4044 return {
4045 type: MEMBER,
4046 raw: raw,
4047 lead: lead,
4048 keypath: keypath,
4049 nodes: nodes,
4050 lookup: lookup,
4051 offset: offset
4052 };
4053 }
4054
4055 var unary = {
4056 '+': TRUE,
4057 '-': TRUE,
4058 '~': TRUE,
4059 '!': TRUE,
4060 '!!': TRUE
4061 }; // 参考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
4062
4063 var binary = {
4064 '*': 14,
4065 '/': 14,
4066 '%': 14,
4067 '+': 13,
4068 '-': 13,
4069 '<<': 12,
4070 '>>': 12,
4071 '>>>': 12,
4072 '<': 11,
4073 '<=': 11,
4074 '>': 11,
4075 '>=': 11,
4076 '==': 10,
4077 '!=': 10,
4078 '===': 10,
4079 '!==': 10,
4080 '&': 9,
4081 '^': 8,
4082 '|': 7,
4083 '&&': 6,
4084 '||': 5
4085 };
4086
4087 function compile(content) {
4088 if (!cache[content]) {
4089 var parser = new Parser(content);
4090 cache[content] = parser.scanTernary(CODE_EOF);
4091 }
4092
4093 return cache[content];
4094 }
4095
4096 var Parser =
4097 /** @class */
4098 function () {
4099 function Parser(content) {
4100 var instance = this,
4101 length = content.length;
4102 instance.index = MINUS_ONE;
4103 instance.end = length;
4104 instance.code = CODE_EOF;
4105 instance.content = content;
4106 instance.go();
4107 }
4108 /**
4109 * 移动一个字符
4110 */
4111
4112
4113 Parser.prototype.go = function (step) {
4114 var instance = this,
4115 index = instance.index,
4116 end = instance.end;
4117 index += step || 1;
4118
4119 if (index >= 0 && index < end) {
4120 instance.code = codeAt(instance.content, index);
4121 instance.index = index;
4122 } else {
4123 instance.code = CODE_EOF;
4124 instance.index = index < 0 ? MINUS_ONE : end;
4125 }
4126 };
4127 /**
4128 * 跳过空白符
4129 */
4130
4131
4132 Parser.prototype.skip = function (step) {
4133 var instance = this,
4134 reversed = step && step < 0; // 如果表达式是 " xyz ",到达结尾后,如果希望 skip(-1) 回到最后一个非空白符
4135 // 必须先判断最后一个字符是空白符,否则碰到 "xyz" 这样结尾不是空白符的,其实不应该回退
4136
4137 if (instance.code === CODE_EOF) {
4138 var oldIndex = instance.index;
4139 instance.go(step); // 如果跳一位之后不是空白符,还原,然后返回
4140
4141 if (!isWhitespace(instance.code)) {
4142 instance.go(oldIndex - instance.index);
4143 return;
4144 }
4145 } // 逆向时,只有位置真的发生过变化才需要在停止时正向移动一位
4146 // 比如 (a) 如果调用 skip 前位于 ),调用 skip(-1) ,结果应该是原地不动
4147 // 为了解决这个问题,应该首先判断当前是不是空白符,如果不是,直接返回
4148 else if (!isWhitespace(instance.code)) {
4149 return;
4150 } // 如果是正向的,停在第一个非空白符左侧
4151 // 如果是逆向的,停在第一个非空白符右侧
4152
4153
4154 while (TRUE) {
4155 if (isWhitespace(instance.code)) {
4156 instance.go(step);
4157 } else {
4158 if (reversed) {
4159 instance.go();
4160 }
4161
4162 break;
4163 }
4164 }
4165 };
4166 /**
4167 * 判断当前字符
4168 */
4169
4170
4171 Parser.prototype.is = function (code) {
4172 return this.code === code;
4173 };
4174 /**
4175 * 截取一段字符串
4176 */
4177
4178
4179 Parser.prototype.pick = function (startIndex, endIndex) {
4180 return slice(this.content, startIndex, isDef(endIndex) ? endIndex : this.index);
4181 };
4182 /**
4183 * 尝试解析下一个 token
4184 */
4185
4186
4187 Parser.prototype.scanToken = function () {
4188 var instance = this,
4189 code = instance.code,
4190 index = instance.index;
4191
4192 if (isIdentifierStart(code)) {
4193 return instance.scanTail(index, [instance.scanIdentifier(index)]);
4194 }
4195
4196 if (isDigit(code)) {
4197 return instance.scanNumber(index);
4198 }
4199
4200 switch (code) {
4201 case CODE_EOF:
4202 return;
4203 // 'x' "x"
4204
4205 case CODE_SQUOTE:
4206 case CODE_DQUOTE:
4207 return instance.scanTail(index, [instance.scanString(index, code)]);
4208 // .1 ./ ../
4209
4210 case CODE_DOT:
4211 instance.go();
4212 return isDigit(instance.code) ? instance.scanNumber(index) : instance.scanPath(index);
4213 // (xx)
4214
4215 case CODE_OPAREN:
4216 instance.go();
4217 return instance.scanTernary(CODE_CPAREN);
4218 // [xx, xx]
4219
4220 case CODE_OBRACK:
4221 return instance.scanTail(index, [createArray(instance.scanTuple(index, CODE_CBRACK), instance.pick(index))]);
4222 // { a: 'x', b: 'x' }
4223
4224 case CODE_OBRACE:
4225 return instance.scanObject(index);
4226 } // 因为 scanOperator 会导致 index 发生变化,只能放在最后尝试
4227
4228
4229 var operator = instance.scanOperator(index);
4230
4231 if (operator && unary[operator]) {
4232 var node = instance.scanTernary();
4233
4234 if (node) {
4235 if (node.type === LITERAL) {
4236 var value = node.value;
4237
4238 if (number(value)) {
4239 // 类似 ' -1 ' 这样的右侧有空格,需要撤回来
4240 instance.skip(MINUS_ONE);
4241 return createLiteral(-value, instance.pick(index));
4242 }
4243 } // 类似 ' -a ' 这样的右侧有空格,需要撤回来
4244
4245
4246 instance.skip(MINUS_ONE);
4247 return createUnary(operator, node, instance.pick(index));
4248 }
4249
4250 {
4251 // 一元运算只有操作符没有表达式?
4252 instance.fatal(index, "Expression expected.");
4253 }
4254 }
4255 };
4256 /**
4257 * 扫描数字
4258 *
4259 * 支持整数和小数
4260 *
4261 * @param startIndex
4262 * @return
4263 */
4264
4265
4266 Parser.prototype.scanNumber = function (startIndex) {
4267 var instance = this;
4268
4269 while (isNumber(instance.code)) {
4270 instance.go();
4271 }
4272
4273 var raw = instance.pick(startIndex); // 尝试转型,如果转型失败,则确定是个错误的数字
4274
4275 if (numeric(raw)) {
4276 return createLiteral(+raw, raw);
4277 }
4278
4279 {
4280 instance.fatal(startIndex, "Number expected.");
4281 }
4282 };
4283 /**
4284 * 扫描字符串
4285 *
4286 * 支持反斜线转义引号
4287 *
4288 * @param startIndex
4289 * @param endCode
4290 */
4291
4292
4293 Parser.prototype.scanString = function (startIndex, endCode) {
4294 var instance = this;
4295
4296 loop: while (TRUE) {
4297 // 这句有两个作用:
4298 // 1. 跳过开始的引号
4299 // 2. 驱动 index 前进
4300 instance.go();
4301
4302 switch (instance.code) {
4303 // \" \'
4304 case CODE_BACKSLASH:
4305 instance.go();
4306 break;
4307
4308 case endCode:
4309 instance.go();
4310 break loop;
4311
4312 case CODE_EOF:
4313 {
4314 // 到头了,字符串还没解析完呢?
4315 instance.fatal(startIndex, 'Unexpected end of text.');
4316 }
4317 break loop;
4318 }
4319 } // new Function 处理字符转义
4320
4321
4322 var raw = instance.pick(startIndex);
4323 return createLiteral(new Function("return " + raw)(), raw);
4324 };
4325 /**
4326 * 扫描对象字面量
4327 *
4328 * @param startIndex
4329 */
4330
4331
4332 Parser.prototype.scanObject = function (startIndex) {
4333 var instance = this,
4334 keys = [],
4335 values = [],
4336 isKey = TRUE,
4337 node; // 跳过 {
4338
4339 instance.go();
4340
4341 loop: while (TRUE) {
4342 switch (instance.code) {
4343 case CODE_CBRACE:
4344 instance.go();
4345 {
4346 // 对象的 keys 和 values 的长度不一致
4347 if (keys.length !== values.length) {
4348 instance.fatal(startIndex, 'The number of keys and values must be equal.');
4349 }
4350 }
4351 break loop;
4352
4353 case CODE_EOF:
4354 {
4355 // 到头了,对象还没解析完呢?
4356 instance.fatal(startIndex, 'Unexpected end of text.');
4357 }
4358 break loop;
4359 // :
4360
4361 case CODE_COLON:
4362 instance.go();
4363 isKey = FALSE;
4364 break;
4365 // ,
4366
4367 case CODE_COMMA:
4368 instance.go();
4369 isKey = TRUE;
4370 break;
4371
4372 default:
4373 // 解析 key 的时候,node 可以为空,如 { } 或 { name: 'xx', }
4374 // 解析 value 的时候,node 不能为空
4375 node = instance.scanTernary();
4376
4377 if (isKey) {
4378 if (node) {
4379 // 处理 { key : value } key 后面的空格
4380 instance.skip();
4381
4382 if (node.type === IDENTIFIER) {
4383 push(keys, node.name);
4384 } else if (node.type === LITERAL) {
4385 push(keys, node.value);
4386 } else {
4387 {
4388 // 对象的 key 必须是字面量或标识符
4389 instance.fatal(startIndex, 'The key of an object must be a literal or identifier.');
4390 }
4391 break loop;
4392 }
4393 }
4394 } else if (node) {
4395 // 处理 { key : value } value 后面的空格
4396 instance.skip();
4397 push(values, node);
4398 } // 类似这样 { key: }
4399 else {
4400 {
4401 // 对象的值没找到
4402 instance.fatal(startIndex, "The value of the object was not found.");
4403 }
4404 break loop;
4405 }
4406
4407 }
4408 }
4409
4410 return createObject(keys, values, instance.pick(startIndex));
4411 };
4412 /**
4413 * 扫描元组,即 `a, b, c` 这种格式,可以是参数列表,也可以是数组
4414 *
4415 * @param startIndex
4416 * @param endCode 元组的结束字符编码
4417 */
4418
4419
4420 Parser.prototype.scanTuple = function (startIndex, endCode) {
4421 var instance = this,
4422 nodes = [],
4423 node; // 跳过开始字符,如 [ 和 (
4424
4425 instance.go();
4426
4427 loop: while (TRUE) {
4428 switch (instance.code) {
4429 case endCode:
4430 instance.go();
4431 break loop;
4432
4433 case CODE_EOF:
4434 {
4435 // 到头了,tuple 还没解析完呢?
4436 instance.fatal(startIndex, 'Unexpected end of text.');
4437 }
4438 break loop;
4439
4440 case CODE_COMMA:
4441 instance.go();
4442 break;
4443
4444 default:
4445 // 1. ( )
4446 // 2. (1, 2, )
4447 // 这三个例子都会出现 scanTernary 为空的情况
4448 // 但是不用报错
4449 node = instance.scanTernary();
4450
4451 if (node) {
4452 // 为了解决 1 , 2 , 3 这样的写法
4453 // 当解析出值后,先跳过后面的空格
4454 instance.skip();
4455 push(nodes, node);
4456 }
4457
4458 }
4459 }
4460
4461 return nodes;
4462 };
4463 /**
4464 * 扫描路径,如 `./` 和 `../`
4465 *
4466 * 路径必须位于开头,如 ./../ 或 ,不存在 a/../b/../c 这样的情况,因为路径是用来切换或指定 context 的
4467 *
4468 * @param startIndex
4469 * @param prevNode
4470 */
4471
4472
4473 Parser.prototype.scanPath = function (startIndex) {
4474 var instance = this,
4475 nodes = [],
4476 name; // 进入此函数时,已确定前一个 code 是 CODE_DOT
4477 // 此时只需判断接下来是 ./ 还是 / 就行了
4478
4479 while (TRUE) {
4480 // 要么是 current 要么是 parent
4481 name = KEYPATH_CURRENT; // ../
4482
4483 if (instance.is(CODE_DOT)) {
4484 instance.go();
4485 name = KEYPATH_PARENT;
4486 }
4487
4488 push(nodes, createIdentifier(name, name, nodes.length > 0)); // 如果以 / 结尾,则命中 ./ 或 ../
4489
4490 if (instance.is(CODE_SLASH)) {
4491 instance.go(); // 没写错,这里不必强调 isIdentifierStart,数字开头也可以吧
4492
4493 if (isIdentifierPart(instance.code)) {
4494 push(nodes, instance.scanIdentifier(instance.index, TRUE));
4495 return instance.scanTail(startIndex, nodes);
4496 } else if (instance.is(CODE_DOT)) {
4497 // 先跳过第一个 .
4498 instance.go(); // 继续循环
4499 } else {
4500 // 类似 ./ 或 ../ 这样后面不跟标识符是想干嘛?报错可好?
4501 {
4502 instance.fatal(startIndex, last(nodes).raw + "/ must be followed by an identifier.");
4503 }
4504 break;
4505 }
4506 } // 类似 . 或 ..,可能就是想读取层级对象
4507 // 此处不用关心后面跟的具体是什么字符,那是其他函数的事情,就算报错也让别的函数去报
4508 // 此处也不用关心延展操作符,即 ...object,因为表达式引擎管不了这事,它没法把对象变成 attr1=value1 attr2=value2 的格式
4509 // 这应该是模板引擎该做的事
4510 else {
4511 break;
4512 }
4513 }
4514 };
4515 /**
4516 * 扫描变量
4517 */
4518
4519
4520 Parser.prototype.scanTail = function (startIndex, nodes) {
4521 var instance = this,
4522 node;
4523 /**
4524 * 标识符后面紧着的字符,可以是 ( . [,此外还存在各种组合,感受一下:
4525 *
4526 * a.b.c().length
4527 * a[b].c()()
4528 * a[b][c]()[d](e, f, g).length
4529 * [].length
4530 */
4531
4532 loop: while (TRUE) {
4533 switch (instance.code) {
4534 // a(x)
4535 case CODE_OPAREN:
4536 nodes = [createCall(createMemberIfNeeded(instance.pick(startIndex), nodes), instance.scanTuple(instance.index, CODE_CPAREN), instance.pick(startIndex))];
4537 break;
4538 // a.x
4539
4540 case CODE_DOT:
4541 instance.go(); // 接下来的字符,可能是数字,也可能是标识符,如果不是就报错
4542
4543 if (isIdentifierPart(instance.code)) {
4544 // 无需识别关键字
4545 push(nodes, instance.scanIdentifier(instance.index, TRUE));
4546 break;
4547 } else {
4548 {
4549 // . 后面跟的都是啥玩意啊
4550 instance.fatal(startIndex, 'Identifier or number expected.');
4551 }
4552 break loop;
4553 }
4554
4555 // a[]
4556
4557 case CODE_OBRACK:
4558 // 过掉 [
4559 instance.go();
4560 node = instance.scanTernary(CODE_CBRACK);
4561
4562 if (node) {
4563 push(nodes, node);
4564 break;
4565 } else {
4566 // [] 内部不能为空
4567 {
4568 instance.fatal(startIndex, "[] is not allowed.");
4569 }
4570 break loop;
4571 }
4572
4573 default:
4574 break loop;
4575 }
4576 }
4577
4578 return createMemberIfNeeded(instance.pick(startIndex), nodes);
4579 };
4580 /**
4581 * 扫描标识符
4582 *
4583 * @param startIndex
4584 * @param isProp 是否是对象的属性
4585 * @return
4586 */
4587
4588
4589 Parser.prototype.scanIdentifier = function (startIndex, isProp) {
4590 var instance = this;
4591
4592 while (isIdentifierPart(instance.code)) {
4593 instance.go();
4594 }
4595
4596 var raw = instance.pick(startIndex);
4597 return !isProp && raw in keywordLiterals ? createLiteral(keywordLiterals[raw], raw) : createIdentifier(raw, raw, isProp);
4598 };
4599 /**
4600 * 扫描运算符
4601 *
4602 * @param startIndex
4603 */
4604
4605
4606 Parser.prototype.scanOperator = function (startIndex) {
4607 var instance = this;
4608
4609 switch (instance.code) {
4610 // /、%、~、^
4611 case CODE_DIVIDE:
4612 case CODE_MODULO:
4613 case CODE_WAVE:
4614 case CODE_XOR:
4615 instance.go();
4616 break;
4617 // *
4618
4619 case CODE_MULTIPLY:
4620 instance.go();
4621 break;
4622 // +
4623
4624 case CODE_PLUS:
4625 instance.go();
4626 {
4627 // ++
4628 if (instance.is(CODE_PLUS)) {
4629 instance.fatal(startIndex, 'The operator "++" is not supported.');
4630 }
4631 }
4632 break;
4633 // -
4634
4635 case CODE_MINUS:
4636 instance.go();
4637 {
4638 // --
4639 if (instance.is(CODE_MINUS)) {
4640 instance.fatal(startIndex, 'The operator "--" is not supported.');
4641 }
4642 }
4643 break;
4644 // !、!!、!=、!==
4645
4646 case CODE_NOT:
4647 instance.go();
4648
4649 if (instance.is(CODE_NOT)) {
4650 instance.go();
4651 } else if (instance.is(CODE_EQUAL)) {
4652 instance.go();
4653
4654 if (instance.is(CODE_EQUAL)) {
4655 instance.go();
4656 }
4657 }
4658
4659 break;
4660 // &、&&
4661
4662 case CODE_AND:
4663 instance.go();
4664
4665 if (instance.is(CODE_AND)) {
4666 instance.go();
4667 }
4668
4669 break;
4670 // |、||
4671
4672 case CODE_OR:
4673 instance.go();
4674
4675 if (instance.is(CODE_OR)) {
4676 instance.go();
4677 }
4678
4679 break;
4680 // ==、===
4681
4682 case CODE_EQUAL:
4683 instance.go();
4684
4685 if (instance.is(CODE_EQUAL)) {
4686 instance.go();
4687
4688 if (instance.is(CODE_EQUAL)) {
4689 instance.go();
4690 }
4691 } // 一个等号要报错
4692 else {
4693 instance.fatal(startIndex, 'Assignment statements are not supported.');
4694 }
4695
4696 break;
4697 // <、<=、<<
4698
4699 case CODE_LESS:
4700 instance.go();
4701
4702 if (instance.is(CODE_EQUAL) || instance.is(CODE_LESS)) {
4703 instance.go();
4704 }
4705
4706 break;
4707 // >、>=、>>、>>>
4708
4709 case CODE_GREAT:
4710 instance.go();
4711
4712 if (instance.is(CODE_EQUAL)) {
4713 instance.go();
4714 } else if (instance.is(CODE_GREAT)) {
4715 instance.go();
4716
4717 if (instance.is(CODE_GREAT)) {
4718 instance.go();
4719 }
4720 }
4721
4722 break;
4723 }
4724
4725 if (instance.index > startIndex) {
4726 return instance.pick(startIndex);
4727 }
4728 };
4729 /**
4730 * 扫描二元运算
4731 */
4732
4733
4734 Parser.prototype.scanBinary = function (startIndex) {
4735 // 二元运算,如 a + b * c / d,这里涉及运算符的优先级
4736 // 算法参考 https://en.wikipedia.org/wiki/Shunting-yard_algorithm
4737 var instance = this,
4738 // 格式为 [ index1, node1, index2, node2, ... ]
4739 output = [],
4740 token,
4741 index,
4742 operator,
4743 operatorPrecedence,
4744 lastOperator,
4745 lastOperatorPrecedence;
4746
4747 while (TRUE) {
4748 instance.skip();
4749 push(output, instance.index);
4750 token = instance.scanToken();
4751
4752 if (token) {
4753 push(output, token);
4754 push(output, instance.index);
4755 instance.skip();
4756 operator = instance.scanOperator(instance.index); // 必须是二元运算符,一元不行
4757
4758 if (operator && (operatorPrecedence = binary[operator])) {
4759 // 比较前一个运算符
4760 index = output.length - 4; // 如果前一个运算符的优先级 >= 现在这个,则新建 Binary
4761 // 如 a + b * c / d,当从左到右读取到 / 时,发现和前一个 * 优先级相同,则把 b * c 取出用于创建 Binary
4762
4763 if ((lastOperator = output[index]) && (lastOperatorPrecedence = binary[lastOperator]) && lastOperatorPrecedence >= operatorPrecedence) {
4764 output.splice(index - 2, 5, createBinary(output[index - 2], lastOperator, output[index + 2], instance.pick(output[index - 3], output[index + 3])));
4765 }
4766
4767 push(output, operator);
4768 continue;
4769 } else {
4770 operator = UNDEFINED;
4771 }
4772 } // 比如不支持的表达式,a++ 之类的
4773 else {
4774 if (operator) {
4775 instance.fatal(startIndex, 'Invalid syntax.');
4776 }
4777 } // 没匹配到 token 或 operator 则跳出循环
4778
4779
4780 break;
4781 } // 类似 a + b * c 这种走到这会有 11 个
4782 // 此时需要从后往前遍历,因为确定后面的优先级肯定大于前面的
4783
4784
4785 while (TRUE) {
4786 // 最少的情况是 a + b,它有 7 个元素
4787 if (output.length >= 7) {
4788 index = output.length - 4;
4789 output.splice(index - 2, 5, createBinary(output[index - 2], output[index], output[index + 2], instance.pick(output[index - 3], output[index + 3])));
4790 } else {
4791 return output[1];
4792 }
4793 }
4794 };
4795 /**
4796 * 扫描三元运算
4797 *
4798 * @param endCode
4799 */
4800
4801
4802 Parser.prototype.scanTernary = function (endCode) {
4803 /**
4804 * https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
4805 *
4806 * ?: 运算符的优先级几乎是最低的,比它低的只有四种: 赋值、yield、延展、逗号
4807 * 我们不支持这四种,因此可认为 ?: 优先级最低
4808 */
4809 var instance = this;
4810 instance.skip();
4811 var index = instance.index,
4812 test = instance.scanBinary(index),
4813 yes,
4814 no;
4815
4816 if (instance.is(CODE_QUESTION)) {
4817 // 跳过 ?
4818 instance.go();
4819 yes = instance.scanTernary();
4820
4821 if (instance.is(CODE_COLON)) {
4822 // 跳过 :
4823 instance.go();
4824 no = instance.scanTernary();
4825 }
4826
4827 if (test && yes && no) {
4828 // 类似 ' a ? 1 : 0 ' 这样的右侧有空格,需要撤回来
4829 instance.skip(MINUS_ONE);
4830 test = createTernary(test, yes, no, instance.pick(index));
4831 } else {
4832 // 三元表达式语法错误
4833 instance.fatal(index, "Invalid ternary syntax.");
4834 }
4835 } // 过掉结束字符
4836
4837
4838 if (isDef(endCode)) {
4839 instance.skip();
4840
4841 if (instance.is(endCode)) {
4842 instance.go();
4843 } // 没匹配到结束字符要报错
4844 else {
4845 instance.fatal(index, "\"" + String.fromCharCode(endCode) + "\" expected, \"" + String.fromCharCode(instance.code) + "\" actually.");
4846 }
4847 }
4848
4849 return test;
4850 };
4851
4852 Parser.prototype.fatal = function (start, message) {
4853 {
4854 fatal("Error compiling expression\n\n" + this.content + "\n\nmessage: " + message + "\n");
4855 }
4856 };
4857
4858 return Parser;
4859 }();
4860
4861 var cache = {},
4862 CODE_EOF = 0,
4863 //
4864 CODE_DOT = 46,
4865 // .
4866 CODE_COMMA = 44,
4867 // ,
4868 CODE_SLASH = 47,
4869 // /
4870 CODE_BACKSLASH = 92,
4871 // \
4872 CODE_SQUOTE = 39,
4873 // '
4874 CODE_DQUOTE = 34,
4875 // "
4876 CODE_OPAREN = 40,
4877 // (
4878 CODE_CPAREN = 41,
4879 // )
4880 CODE_OBRACK = 91,
4881 // [
4882 CODE_CBRACK = 93,
4883 // ]
4884 CODE_OBRACE = 123,
4885 // {
4886 CODE_CBRACE = 125,
4887 // }
4888 CODE_QUESTION = 63,
4889 // ?
4890 CODE_COLON = 58,
4891 // :
4892 CODE_PLUS = 43,
4893 // +
4894 CODE_MINUS = 45,
4895 // -
4896 CODE_MULTIPLY = 42,
4897 // *
4898 CODE_DIVIDE = 47,
4899 // /
4900 CODE_MODULO = 37,
4901 // %
4902 CODE_WAVE = 126,
4903 // ~
4904 CODE_AND = 38,
4905 // &
4906 CODE_OR = 124,
4907 // |
4908 CODE_XOR = 94,
4909 // ^
4910 CODE_NOT = 33,
4911 // !
4912 CODE_LESS = 60,
4913 // <
4914 CODE_EQUAL = 61,
4915 // =
4916 CODE_GREAT = 62,
4917 // >
4918
4919 /**
4920 * 区分关键字和普通变量
4921 * 举个例子:a === true
4922 * 从解析器的角度来说,a 和 true 是一样的 token
4923 */
4924 keywordLiterals = {};
4925 keywordLiterals[RAW_TRUE] = TRUE;
4926 keywordLiterals[RAW_FALSE] = FALSE;
4927 keywordLiterals[RAW_NULL] = NULL;
4928 keywordLiterals[RAW_UNDEFINED] = UNDEFINED;
4929 /**
4930 * 是否是空白符,用下面的代码在浏览器测试一下
4931 *
4932 * ```
4933 * for (var i = 0; i < 200; i++) {
4934 * console.log(i, String.fromCharCode(i))
4935 * }
4936 * ```
4937 *
4938 * 从 0 到 32 全是空白符,100 往上分布比较散且较少用,唯一需要注意的是 160
4939 *
4940 * 160 表示 non-breaking space
4941 * http://www.adamkoch.com/2009/07/25/white-space-and-character-160/
4942 */
4943
4944 function isWhitespace(code) {
4945 return code > 0 && code < 33 || code === 160;
4946 }
4947 /**
4948 * 是否是数字
4949 */
4950
4951
4952 function isDigit(code) {
4953 return code > 47 && code < 58; // 0...9
4954 }
4955 /**
4956 * 是否是数字
4957 */
4958
4959
4960 function isNumber(code) {
4961 return isDigit(code) || code === CODE_DOT;
4962 }
4963 /**
4964 * 变量开始字符必须是 字母、下划线、$
4965 */
4966
4967
4968 function isIdentifierStart(code) {
4969 return code === 36 // $
4970 || code === 95 // _
4971 || code > 96 && code < 123 // a...z
4972 || code > 64 && code < 91; // A...Z
4973 }
4974 /**
4975 * 变量剩余的字符必须是 字母、下划线、$、数字
4976 */
4977
4978
4979 function isIdentifierPart(code) {
4980 return isIdentifierStart(code) || isDigit(code);
4981 } // 当前不位于 block 之间
4982
4983
4984 var BLOCK_MODE_NONE = 1,
4985 // {{ x }}
4986 BLOCK_MODE_SAFE = 2,
4987 // {{{ x }}}
4988 BLOCK_MODE_UNSAFE = 3,
4989 // 缓存编译正则
4990 patternCache$1 = {},
4991 // 指令分隔符,如 on-click 和 lazy-click
4992 directiveSeparator = '-',
4993 // 调用的方法
4994 methodPattern = /^[_$a-z]([\w]+)?$/,
4995 // 没有命名空间的事件
4996 eventPattern = /^[_$a-z]([\w]+)?$/i,
4997 // 有命名空间的事件
4998 eventNamespacePattern = /^[_$a-z]([\w]+)?\.[_$a-z]([\w]+)?$/i,
4999 // 换行符
5000 // 比较神奇是,有时候你明明看不到换行符,却真的存在一个,那就是 \r
5001 breaklinePattern = /^\s*[\n\r]\s*|\s*[\n\r]\s*$/g,
5002 // 区间遍历
5003 rangePattern = /\s*(=>|->)\s*/,
5004 // 标签
5005 tagPattern = /<(\/)?([$a-z][-a-z0-9]*)/i,
5006 // 注释
5007 commentPattern = /<!--[\s\S]*?-->/g,
5008 // 开始注释
5009 openCommentPattern = /^([\s\S]*?)<!--/,
5010 // 结束注释
5011 closeCommentPattern = /-->([\s\S]*?)$/,
5012 // 属性的 name
5013 // 支持 on-click.namespace="" 或 on-get-out="" 或 xml:xx=""
5014 attributePattern = /^\s*([-$.:\w]+)(['"])?(?:=(['"]))?/,
5015 // 自闭合标签
5016 selfClosingTagPattern = /^\s*(\/)?>/;
5017 /**
5018 * 截取前缀之后的字符串
5019 */
5020
5021 function slicePrefix(str, prefix) {
5022 return trim(slice(str, prefix.length));
5023 }
5024
5025 function compile$1(content) {
5026 var nodeList = [],
5027 nodeStack = [],
5028 // 持有 if/elseif/else 节点
5029 ifStack = [],
5030 currentElement,
5031 currentAttribute,
5032 length = content.length,
5033 // 当前处理的位置
5034 index = 0,
5035 // 下一段开始的位置
5036 nextIndex = 0,
5037 // 开始定界符的位置,表示的是 {{ 的右侧位置
5038 openBlockIndex = 0,
5039 // 结束定界符的位置,表示的是 }} 的左侧位置
5040 closeBlockIndex = 0,
5041 // 当前正在处理或即将处理的 block 类型
5042 blockMode = BLOCK_MODE_NONE,
5043 // mustache 注释可能出现嵌套插值的情况
5044 blockStack = [],
5045 indexList = [],
5046 code,
5047 startQuote,
5048 fatal$1 = function (msg) {
5049 {
5050 fatal("Error compiling template\n\n" + content + "\n\nmessage: " + msg);
5051 }
5052 },
5053
5054 /**
5055 * 常见的两种情况:
5056 *
5057 * <div>
5058 * <input>1
5059 * </div>
5060 *
5061 * <div>
5062 * <input>
5063 * </div>
5064 */
5065 popSelfClosingElementIfNeeded = function (popingTagName) {
5066 var lastNode = last(nodeStack);
5067
5068 if (lastNode && lastNode.type === ELEMENT) {
5069 var element = lastNode;
5070
5071 if (element.tag !== popingTagName && isSelfClosing(element.tag)) {
5072 popStack(element.type, element.tag);
5073 }
5074 }
5075 },
5076 popStack = function (type, tagName) {
5077 var node = pop(nodeStack);
5078
5079 if (node && node.type === type) {
5080 var children = node.children,
5081 // 优化单个子节点
5082 child = children && children.length === 1 && children[0],
5083 isElement = type === ELEMENT,
5084 isAttribute = type === ATTRIBUTE,
5085 isProperty = type === PROPERTY,
5086 isDirective = type === DIRECTIVE;
5087 var currentBranch = last(nodeStack);
5088
5089 if (currentBranch) {
5090 if (currentBranch.isStatic && !node.isStatic) {
5091 currentBranch.isStatic = FALSE;
5092 }
5093
5094 if (!currentBranch.isComplex) {
5095 if (node.isComplex || isElement) {
5096 currentBranch.isComplex = TRUE;
5097 } // <div {{#if xx}} xx{{/if}}>
5098 else if (currentElement && currentElement !== currentBranch && (isAttribute || isProperty || isDirective)) {
5099 currentBranch.isComplex = TRUE;
5100 }
5101 }
5102 }
5103
5104 {
5105 if (isElement) {
5106 var element = node;
5107
5108 if (tagName && element.tag !== tagName) {
5109 fatal$1("End tag is \"" + tagName + "\"\uFF0Cbut start tag is \"" + element.tag + "\".");
5110 }
5111 }
5112 } // 除了 helper.specialAttrs 里指定的特殊属性,attrs 里的任何节点都不能单独拎出来赋给 element
5113 // 因为 attrs 可能存在 if,所以每个 attr 最终都不一定会存在
5114
5115 if (child) {
5116 switch (child.type) {
5117 case TEXT:
5118 // 属性的值如果是纯文本,直接获取文本值
5119 // 减少渲染时的遍历
5120 if (isElement) {
5121 processElementSingleText(node, child);
5122 } else if (isAttribute) {
5123 processAttributeSingleText(node, child);
5124 } else if (isProperty) {
5125 processPropertySingleText(node, child);
5126 } else if (isDirective) {
5127 processDirectiveSingleText(node, child);
5128 }
5129
5130 break;
5131
5132 case EXPRESSION:
5133 if (isElement) {
5134 processElementSingleExpression(node, child);
5135 } else if (isAttribute) {
5136 processAttributeSingleExpression(node, child);
5137 } else if (isProperty) {
5138 processPropertySingleExpression(node, child);
5139 } else if (isDirective) {
5140 processDirectiveSingleExpression();
5141 }
5142
5143 break;
5144 }
5145 } // 大于 1 个子节点,即有插值或 if 写法
5146 else if (children) {
5147 if (isDirective) {
5148 processDirectiveMultiChildren();
5149 } // 元素层级
5150 else if (!currentElement) {
5151 removeComment(children);
5152
5153 if (!children.length) {
5154 node.children = UNDEFINED;
5155 }
5156 }
5157 } // 0 个子节点
5158 else if (currentElement) {
5159 if (isAttribute) {
5160 processAttributeEmptyChildren(currentElement, node);
5161 } else if (isProperty) {
5162 processPropertyEmptyChildren(currentElement, node);
5163 } else if (isDirective) {
5164 processDirectiveEmptyChildren(currentElement, node);
5165 }
5166 }
5167
5168 if (type === EACH) {
5169 checkEach(node);
5170 } else if (type === PARTIAL) {
5171 checkPartial(node);
5172 } else if (isElement) {
5173 checkElement(node);
5174 } else if (currentElement) {
5175 if (isAttribute) {
5176 if (isSpecialAttr(currentElement, node)) {
5177 bindSpecialAttr(currentElement, node);
5178 }
5179 } else if (isDirective) {
5180 checkDirective(currentElement, node);
5181 }
5182 }
5183
5184 return node;
5185 } // 出栈节点类型不匹配
5186
5187
5188 {
5189 fatal$1("The type of poping node is not expected.");
5190 }
5191 },
5192 removeComment = function (children) {
5193 // 类似 <!-- xx {{name}} yy {{age}} zz --> 这样的注释里包含插值
5194 // 按照目前的解析逻辑,是根据定界符进行模板分拆
5195 // 一旦出现插值,children 长度必然大于 1
5196 var openIndex = MINUS_ONE,
5197 openText = EMPTY_STRING,
5198 closeIndex = MINUS_ONE,
5199 closeText = EMPTY_STRING;
5200 each(children, function (child, index) {
5201 if (child.type === TEXT) {
5202 // 有了结束 index,这里的任务是配对开始 index
5203 if (closeIndex >= 0) {
5204 openText = child.text; // 处理 <!-- <!-- 这样有多个的情况
5205
5206 while (openCommentPattern.test(openText)) {
5207 openText = RegExp.$1;
5208 openIndex = index;
5209 }
5210
5211 if (openIndex >= 0) {
5212 // openIndex 肯定小于 closeIndex,因为完整的注释在解析过程中会被干掉
5213 // 只有包含插值的注释才会走进这里
5214 var startIndex = openIndex,
5215 endIndex = closeIndex; // 现在要确定开始和结束的文本节点,是否包含正常文本
5216
5217 if (openText) {
5218 children[openIndex].text = openText;
5219 startIndex++;
5220 }
5221
5222 if (closeText) {
5223 // 合并开始和结束文本,如 1<!-- {{x}}{{y}} -->2
5224 // 这里要把 1 和 2 两个文本节点合并成一个
5225 if (openText) {
5226 children[openIndex].text += closeText;
5227 } else {
5228 children[closeIndex].text = closeText;
5229 endIndex--;
5230 }
5231 }
5232
5233 children.splice(startIndex, endIndex - startIndex + 1); // 重置,再继续寻找结束 index
5234
5235 openIndex = closeIndex = MINUS_ONE;
5236 }
5237 } else {
5238 // 从后往前遍历
5239 // 一旦发现能匹配 --> 就可以断定这是注释的结束 index
5240 // 剩下的就是找开始 index
5241 closeText = child.text; // 处理 --> --> 这样有多个的情况
5242
5243 while (closeCommentPattern.test(closeText)) {
5244 closeText = RegExp.$1;
5245 closeIndex = index;
5246 }
5247 }
5248 }
5249 }, TRUE);
5250 },
5251 processDirectiveMultiChildren = function () {
5252 // 不支持 on-click="1{{xx}}2" 或是 on-click="1{{#if x}}x{{else}}y{{/if}}2"
5253 // 1. 很难做性能优化
5254 // 2. 全局搜索不到事件名,不利于代码维护
5255 // 3. 不利于编译成静态函数
5256 {
5257 fatal$1('For performance, "{{" and "}}" are not allowed in directive value.');
5258 }
5259 },
5260 processElementSingleText = function (element, child) {
5261 // processElementSingleText 和 processElementSingleExpression
5262 // 不把元素子节点智能转换为 textContent property
5263 // 因为子节点还有 <div>1{{a}}{{b}}</div> 这样的情况
5264 // 还是在序列化的时候统一处理比较好
5265 // 唯独需要在这特殊处理的是 html 实体
5266 // 但这只是 WEB 平台的特殊逻辑,所以丢给 platform 处理
5267 if (!element.isComponent && !specialTags[element.tag] && setElementText(element, child.text)) {
5268 element.children = UNDEFINED;
5269 }
5270 },
5271 processElementSingleExpression = function (element, child) {
5272 if (!element.isComponent && !specialTags[element.tag] && !child.safe) {
5273 element.html = child.expr;
5274 element.children = UNDEFINED;
5275 }
5276 },
5277 processPropertyEmptyChildren = function (element, prop) {
5278 if (prop.hint === HINT_BOOLEAN) {
5279 prop.value = TRUE;
5280 } else {
5281 // string 或 number 类型的属性,如果不写值,直接忽略
5282 replaceChild(prop);
5283 }
5284 },
5285 processPropertySingleText = function (prop, child) {
5286 var text = child.text; // 这里需要严格校验格式,比如 width="100%" 要打印报错信息,提示用户类型错误
5287
5288 if (prop.hint === HINT_NUMBER) {
5289 {
5290 if (numeric(text)) {
5291 prop.value = +text;
5292 } else {
5293 fatal$1("The value of \"" + prop.name + "\" is not a number: " + text + ".");
5294 }
5295 }
5296 } else if (prop.hint === HINT_BOOLEAN) {
5297 prop.value = text === RAW_TRUE || text === prop.name;
5298 } else {
5299 prop.value = text;
5300 }
5301
5302 prop.children = UNDEFINED;
5303 },
5304 processPropertySingleExpression = function (prop, child) {
5305 var expr = child.expr;
5306 prop.expr = expr;
5307 prop.children = UNDEFINED; // 对于有静态路径的表达式,可转为单向绑定指令,可实现精确更新视图,如下
5308 // <div class="{{className}}">
5309
5310 if (expr.type === IDENTIFIER) {
5311 prop.binding = TRUE;
5312 }
5313 },
5314 processAttributeEmptyChildren = function (element, attr) {
5315 if (isSpecialAttr(element, attr)) {
5316 {
5317 fatal$1("The value of \"" + attr.name + "\" is empty.");
5318 }
5319 } else {
5320 attr.value = getAttributeDefaultValue(element, attr.name);
5321 }
5322 },
5323 processAttributeSingleText = function (attr, child) {
5324 attr.value = child.text;
5325 attr.children = UNDEFINED;
5326 },
5327 processAttributeSingleExpression = function (attr, child) {
5328 var expr = child.expr;
5329 attr.expr = expr;
5330 attr.children = UNDEFINED; // 对于有静态路径的表达式,可转为单向绑定指令,可实现精确更新视图,如下
5331 // <div class="{{className}}">
5332
5333 if (expr.type === IDENTIFIER) {
5334 attr.binding = TRUE;
5335 }
5336 },
5337 processDirectiveEmptyChildren = function (element, directive) {
5338 directive.value = TRUE;
5339 },
5340 processDirectiveSingleText = function (directive, child) {
5341 var text = child.text,
5342 // model="xx" model="this.x" 值只能是标识符或 Member
5343 isModel = directive.ns === DIRECTIVE_MODEL,
5344 // lazy 的值必须是大于 0 的数字
5345 isLazy = directive.ns === DIRECTIVE_LAZY,
5346 // 校验事件名称
5347 // 且命名空间不能用 native
5348 isEvent = directive.ns === DIRECTIVE_EVENT,
5349 // 自定义指令运行不合法的表达式
5350 isCustom = directive.ns === DIRECTIVE_CUSTOM,
5351 // 指令的值是纯文本,可以预编译表达式,提升性能
5352 expr,
5353 error;
5354
5355 try {
5356 expr = compile(text);
5357 } catch (e) {
5358 error = e;
5359 }
5360
5361 if (expr) {
5362 {
5363 var raw = expr.raw;
5364
5365 if (isLazy) {
5366 if (expr.type !== LITERAL || !number(expr.value) || expr.value <= 0) {
5367 fatal$1('The value of lazy must be a number greater than 0.');
5368 }
5369 } // 如果指令表达式是函数调用,则只能调用方法(难道还有别的可以调用的吗?)
5370 else if (expr.type === CALL) {
5371 var methodName = expr.name;
5372
5373 if (methodName.type !== IDENTIFIER) {
5374 fatal$1('Invalid method name.');
5375 } // 函数调用调用方法,因此不能是 a.b() 的形式
5376 else if (!methodPattern.test(methodName.name)) {
5377 fatal$1('Invalid method name.');
5378 }
5379 } // 上面检测过方法调用,接下来事件指令只需要判断是否以下两种格式:
5380 // on-click="name" 或 on-click="name.namespace"
5381 else if (isEvent) {
5382 if (eventPattern.test(raw) || eventNamespacePattern.test(raw)) {
5383 // native 有特殊用处,不能给业务层用
5384 if (eventNamespacePattern.test(raw) && raw.split(RAW_DOT)[1] === MODIFER_NATIVE) {
5385 fatal$1("The event namespace \"" + MODIFER_NATIVE + "\" is not permitted.");
5386 } // <Button on-click="click"> 这种写法没有意义
5387
5388
5389 if (currentElement && currentElement.isComponent && directive.name === raw) {
5390 fatal$1("The event name listened and fired can't be the same.");
5391 }
5392 } // 事件转换名称只能是 [name] 或 [name.namespace] 格式
5393 else {
5394 fatal$1('The event name and namespace must be an identifier.');
5395 }
5396 }
5397
5398 if (isModel && expr.type !== IDENTIFIER) {
5399 fatal$1('The value of the model must be an identifier.');
5400 }
5401 }
5402 directive.expr = expr;
5403 directive.value = expr.type === LITERAL ? expr.value : text;
5404 } else {
5405 // 自定义指令支持错误的表达式
5406 // 反正是自定义的规则,爱怎么写就怎么写
5407 {
5408 if (!isCustom) {
5409 throw error;
5410 }
5411 }
5412 directive.value = text;
5413 }
5414
5415 directive.children = UNDEFINED;
5416 },
5417 processDirectiveSingleExpression = function (directive, child) {
5418 {
5419 fatal$1('For performance, "{{" and "}}" are not allowed in directive value.');
5420 }
5421 },
5422 checkCondition = function (condition) {
5423 var currentNode = condition,
5424 prevNode,
5425 hasChildren,
5426 hasNext;
5427
5428 while (TRUE) {
5429 if (currentNode.children) {
5430 if (!hasNext) {
5431 if (currentNode.next) {
5432 delete currentNode.next;
5433 }
5434 }
5435
5436 hasChildren = hasNext = TRUE;
5437 }
5438
5439 prevNode = currentNode.prev;
5440
5441 if (prevNode) {
5442 // prev 仅仅用在 checkCondition 函数中
5443 // 用完就可以删掉了
5444 delete currentNode.prev;
5445 currentNode = prevNode;
5446 } else {
5447 break;
5448 }
5449 } // 每个条件都是空内容,则删掉整个 if
5450
5451
5452 if (!hasChildren) {
5453 replaceChild(currentNode);
5454 }
5455 },
5456 checkEach = function (each) {
5457 // 没内容就干掉
5458 if (!each.children) {
5459 replaceChild(each);
5460 }
5461 },
5462 checkPartial = function (partial) {
5463 // 没内容就干掉
5464 if (!partial.children) {
5465 replaceChild(partial);
5466 }
5467 },
5468 checkElement = function (element) {
5469 var tag = element.tag,
5470 slot = element.slot,
5471 isTemplate = tag === RAW_TEMPLATE;
5472 {
5473 if (isTemplate) {
5474 if (element.key) {
5475 fatal$1("The \"key\" is not supported in <template>.");
5476 } else if (element.ref) {
5477 fatal$1("The \"ref\" is not supported in <template>.");
5478 } else if (element.attrs) {
5479 fatal$1("The attributes and directives are not supported in <template>.");
5480 } else if (!slot) {
5481 fatal$1("The \"slot\" is required in <template>.");
5482 }
5483 }
5484 } // 没有子节点,则意味着这个插槽没任何意义
5485
5486 if (isTemplate && slot && !element.children) {
5487 replaceChild(element);
5488 } // <slot /> 如果没写 name,自动加上默认名称
5489 else if (tag === RAW_SLOT && !element.name) {
5490 element.name = SLOT_NAME_DEFAULT;
5491 } else {
5492 compatElement(element);
5493 }
5494 },
5495 checkDirective = function (element, directive) {
5496 {
5497 // model 不能写在 if 里,影响节点的静态结构
5498 if (directive.ns === DIRECTIVE_MODEL) {
5499 if (last(nodeStack) !== element) {
5500 fatal$1("The \"model\" can't be used in an if block.");
5501 }
5502 }
5503 }
5504 },
5505 bindSpecialAttr = function (element, attr) {
5506 var name = attr.name,
5507 value = attr.value,
5508 // 这三个属性值要求是字符串
5509 isStringValueRequired = name === RAW_NAME || name === RAW_SLOT;
5510 {
5511 // 因为要拎出来给 element,所以不能用 if
5512 if (last(nodeStack) !== element) {
5513 fatal$1("The \"" + name + "\" can't be used in an if block.");
5514 } // 对于所有特殊属性来说,空字符串是肯定不行的,没有任何意义
5515
5516
5517 if (value === EMPTY_STRING) {
5518 fatal$1("The value of \"" + name + "\" is empty.");
5519 } else if (isStringValueRequired && falsy$1(value)) {
5520 fatal$1("The value of \"" + name + "\" can only be a string literal.");
5521 }
5522 }
5523 element[name] = isStringValueRequired ? value : attr;
5524 replaceChild(attr);
5525 },
5526 isSpecialAttr = function (element, attr) {
5527 return specialAttrs[attr.name] || element.tag === RAW_SLOT && attr.name === RAW_NAME;
5528 },
5529 replaceChild = function (oldNode, newNode) {
5530 var currentBranch = last(nodeStack),
5531 isAttr,
5532 list,
5533 index;
5534
5535 if (currentBranch) {
5536 isAttr = currentElement && currentElement === currentBranch;
5537 list = isAttr ? currentBranch.attrs : currentBranch.children;
5538 } else {
5539 list = nodeList;
5540 }
5541
5542 if (list) {
5543 index = indexOf(list, oldNode);
5544
5545 if (index >= 0) {
5546 if (newNode) {
5547 list[index] = newNode;
5548 } else {
5549 list.splice(index, 1);
5550
5551 if (currentBranch && !list.length) {
5552 if (isAttr) {
5553 delete currentBranch.attrs;
5554 } else {
5555 currentBranch.children = UNDEFINED;
5556 }
5557 }
5558 }
5559 }
5560 }
5561 },
5562 addChild = function (node) {
5563 /**
5564 * <div>
5565 * <input>
5566 * <div></div>
5567 * </div>
5568 *
5569 * <div>
5570 * <input>xxx
5571 * </div>
5572 */
5573 if (!currentElement) {
5574 popSelfClosingElementIfNeeded();
5575 }
5576
5577 var type = node.type,
5578 currentBranch = last(nodeStack); // else 系列只是 if 的递进节点,不需要加入 nodeList
5579
5580 if (type === ELSE || type === ELSE_IF) {
5581 var lastNode = pop(ifStack);
5582
5583 if (lastNode) {
5584 // 方便 checkCondition 逆向遍历
5585 node.prev = lastNode; // lastNode 只能是 if 或 else if 节点
5586
5587 if (lastNode.type === ELSE_IF || lastNode.type === IF) {
5588 lastNode.next = node;
5589 popStack(lastNode.type);
5590 push(ifStack, node);
5591 } else if (type === ELSE_IF) {
5592 {
5593 fatal$1('The "else" block must not be followed by an "else if" block.');
5594 }
5595 } else {
5596 fatal$1("The \"else\" block can't appear more than once in a conditional statement.");
5597 }
5598 } else {
5599 fatal$1('The "if" block is required.');
5600 }
5601 } else {
5602 if (currentBranch) {
5603 // 这里不能写 currentElement && !currentAttribute,举个例子
5604 //
5605 // <div id="x" {{#if}} name="xx" alt="xx" {{/if}}
5606 //
5607 // 当 name 属性结束后,条件满足,但此时已不是元素属性层级了
5608 if (currentElement && currentBranch.type === ELEMENT) {
5609 // 属性层级不能使用危险插值
5610 {
5611 if (type === EXPRESSION && !node.safe) {
5612 fatal$1('The dangerous interpolation must be the only child of a HTML element.');
5613 }
5614 } // node 没法转型,一堆可能的类型怎么转啊...
5615
5616 push(currentElement.attrs || (currentElement.attrs = []), node);
5617 } else {
5618 var children = currentBranch.children || (currentBranch.children = []),
5619 lastChild = last(children); // 如果表达式是安全插值的字面量,可以优化成字符串
5620
5621 if (type === EXPRESSION // 在元素的子节点中,则直接转成字符串
5622 && (!currentElement // 在元素的属性中,如果同级节点大于 0 个(即已经存在一个),则可以转成字符串
5623 || currentAttribute && children.length > 0)) {
5624 var textNode = toTextNode(node);
5625
5626 if (textNode) {
5627 node = textNode;
5628 type = textNode.type;
5629 }
5630 } // 连续添加文本节点,则直接合并
5631
5632
5633 if (lastChild && type === TEXT) {
5634 // 合并两个文本节点
5635 if (lastChild.type === TEXT) {
5636 lastChild.text += node.text;
5637 return;
5638 } // 前一个是字面量的表达式,也可以合并节点
5639
5640
5641 if (lastChild.type === EXPRESSION) {
5642 var textNode = toTextNode(lastChild);
5643
5644 if (textNode) {
5645 children[children.length - 1] = textNode;
5646 textNode.text += node.text;
5647 return;
5648 }
5649 }
5650 }
5651
5652 {
5653 if (type === EXPRESSION && !node.safe) {
5654 // 前面不能有别的 child,危险插值必须独占父元素
5655 if (lastChild) {
5656 fatal$1('The dangerous interpolation must be the only child of a HTML element.');
5657 } // 危险插值的父节点必须是 html element
5658 else if (currentBranch.type !== ELEMENT || currentBranch.isComponent || specialTags[currentBranch.tag]) {
5659 fatal$1('The dangerous interpolation must be the only child of a HTML element.');
5660 }
5661 } // 后面不能有别的 child,危险插值必须独占父元素
5662 else if (lastChild && lastChild.type === EXPRESSION && !lastChild.safe) {
5663 fatal$1('The dangerous interpolation must be the only child of a HTML element.');
5664 }
5665 }
5666 push(children, node);
5667 }
5668 } else {
5669 {
5670 if (type === EXPRESSION && !node.safe) {
5671 fatal$1('The dangerous interpolation must be under a HTML element.');
5672 }
5673 }
5674 push(nodeList, node);
5675 }
5676
5677 if (type === IF) {
5678 // 只要是 if 节点,并且和 element 同级,就加上 stub
5679 // 方便 virtual dom 进行对比
5680 // 这个跟 virtual dom 的实现原理密切相关,不加 stub 会有问题
5681 if (!currentElement) {
5682 node.stub = // stub 会在运行时可能创建注释节点,使得父元素变成复杂节点
5683 node.isComplex = TRUE;
5684 }
5685
5686 push(ifStack, node);
5687 }
5688 }
5689
5690 if (node.isLeaf) {
5691 // 当前树枝节点如果是静态的,一旦加入了一个非静态子节点,改变当前树枝节点的 isStatic
5692 // 这里不处理树枝节点的进栈,因为当树枝节点出栈时,还有一次处理机会,那时它的 isStatic 已确定下来,不会再变
5693 if (currentBranch) {
5694 if (currentBranch.isStatic && !node.isStatic) {
5695 currentBranch.isStatic = FALSE;
5696 } // 当前树枝节点是简单节点,一旦加入了一个复杂子节点,当前树枝节点变为复杂节点
5697
5698
5699 if (!currentBranch.isComplex && node.isComplex) {
5700 currentBranch.isComplex = TRUE;
5701 }
5702 }
5703 } else {
5704 push(nodeStack, node);
5705 }
5706 },
5707 addTextChild = function (text) {
5708 // [注意]
5709 // 这里不能随便删掉
5710 // 因为收集组件的子节点会受影响,举个例子:
5711 // <Component>
5712 //
5713 // </Component>
5714 // 按现在的逻辑,这样的组件是没有子节点的,因为在这里过滤掉了,因此该组件没有 slot
5715 // 如果这里放开了,组件就会有一个 slot
5716 // trim 文本开始和结束位置的换行符
5717 text = text.replace(breaklinePattern, EMPTY_STRING);
5718
5719 if (text) {
5720 addChild(createText(text));
5721 }
5722 },
5723 toTextNode = function (node) {
5724 if (node.safe && node.expr.type === LITERAL) {
5725 return createText(toString(node.expr.value));
5726 }
5727 },
5728 htmlParsers = [function (content) {
5729 if (!currentElement) {
5730 var match = content.match(tagPattern); // 必须以 <tag 开头才能继续
5731 // 如果 <tag 前面有别的字符,会走进第四个 parser
5732
5733 if (match && match.index === 0) {
5734 var tag = match[2];
5735
5736 if (match[1] === RAW_SLASH) {
5737 /**
5738 * 处理可能存在的自闭合元素,如下
5739 *
5740 * <div>
5741 * <input>
5742 * </div>
5743 */
5744 popSelfClosingElementIfNeeded(tag);
5745 popStack(ELEMENT, tag);
5746 } else {
5747 /**
5748 * template 只能写在组件的第一级,如下:
5749 *
5750 * <Component>
5751 * <template slot="xx">
5752 * 111
5753 * </template>
5754 * </Component>
5755 */
5756 {
5757 if (tag === RAW_TEMPLATE) {
5758 var lastNode = last(nodeStack);
5759
5760 if (!lastNode || !lastNode.isComponent) {
5761 fatal$1('<template> can only be used within an component children.');
5762 }
5763 }
5764 }
5765 var node = createElement$1(tag);
5766 addChild(node);
5767 currentElement = node;
5768 }
5769
5770 return match[0];
5771 }
5772 }
5773 }, // 处理标签的 > 或 />,不论开始还是结束标签
5774 function (content) {
5775 var match = content.match(selfClosingTagPattern);
5776
5777 if (match) {
5778 // 处理开始标签的 > 或 />
5779 if (currentElement && !currentAttribute) {
5780 // 自闭合标签
5781 if (match[1] === RAW_SLASH) {
5782 popStack(currentElement.type, currentElement.tag);
5783 }
5784
5785 currentElement = UNDEFINED;
5786 } // 处理结束标签的 >
5787
5788
5789 return match[0];
5790 }
5791 }, // 处理 attribute directive 的 name 部分
5792 function (content) {
5793 // 当前在 element 层级
5794 if (currentElement && !currentAttribute) {
5795 var match = content.match(attributePattern);
5796
5797 if (match) {
5798 // <div class="11 name="xxx"></div>
5799 // 这里会匹配上 xxx",match[2] 就是那个引号
5800 {
5801 if (match[2]) {
5802 fatal$1("The previous attribute is not end.");
5803 }
5804 }
5805 var node,
5806 name = match[1];
5807
5808 if (name === DIRECTIVE_MODEL || name === RAW_TRANSITION) {
5809 node = createDirective(EMPTY_STRING, name);
5810 } // 这里要用 on- 判断前缀,否则 on 太容易重名了
5811 else if (startsWith(name, DIRECTIVE_ON + directiveSeparator)) {
5812 var event = slicePrefix(name, DIRECTIVE_ON + directiveSeparator);
5813 {
5814 if (!event) {
5815 fatal$1('The event name is required.');
5816 }
5817 }
5818
5819 var _a = camelize(event).split(RAW_DOT),
5820 directiveName = _a[0],
5821 diectiveModifier = _a[1],
5822 extra = _a[2];
5823
5824 node = createDirective(directiveName, DIRECTIVE_EVENT, diectiveModifier); // on-a.b.c
5825
5826 {
5827 if (string(extra)) {
5828 fatal$1('Invalid event namespace.');
5829 }
5830 }
5831 } // 当一个元素绑定了多个事件时,可分别指定每个事件的 lazy
5832 // 当只有一个事件时,可简写成 lazy
5833 // <div on-click="xx" lazy-click
5834 else if (startsWith(name, DIRECTIVE_LAZY)) {
5835 var lazy = slicePrefix(name, DIRECTIVE_LAZY);
5836
5837 if (startsWith(lazy, directiveSeparator)) {
5838 lazy = slicePrefix(lazy, directiveSeparator);
5839 }
5840
5841 node = createDirective(lazy ? camelize(lazy) : EMPTY_STRING, DIRECTIVE_LAZY);
5842 } // 这里要用 o- 判断前缀,否则 o 太容易重名了
5843 else if (startsWith(name, DIRECTIVE_CUSTOM + directiveSeparator)) {
5844 var custom = slicePrefix(name, DIRECTIVE_CUSTOM + directiveSeparator);
5845 {
5846 if (!custom) {
5847 fatal$1('The directive name is required.');
5848 }
5849 }
5850
5851 var _b = camelize(custom).split(RAW_DOT),
5852 directiveName = _b[0],
5853 diectiveModifier = _b[1],
5854 extra = _b[2];
5855
5856 node = createDirective(directiveName, DIRECTIVE_CUSTOM, diectiveModifier); // o-a.b.c
5857
5858 {
5859 if (string(extra)) {
5860 fatal$1('Invalid directive modifier.');
5861 }
5862 }
5863 } else {
5864 node = createAttribute$1(currentElement, name);
5865 }
5866
5867 addChild(node); // 这里先记下,下一个 handler 要匹配结束引号
5868
5869 startQuote = match[3]; // 有属性值才需要设置 currentAttribute,便于后续收集属性值
5870
5871 if (startQuote) {
5872 currentAttribute = node;
5873 } else {
5874 popStack(node.type);
5875 }
5876
5877 return match[0];
5878 }
5879 }
5880 }, function (content) {
5881 var text, match; // 处理 attribute directive 的 value 部分
5882
5883 if (currentAttribute && startQuote) {
5884 match = content.match(patternCache$1[startQuote] || (patternCache$1[startQuote] = new RegExp(startQuote))); // 有结束引号
5885
5886 if (match) {
5887 text = slice(content, 0, match.index);
5888 addTextChild(text);
5889 text += startQuote; // attribute directive 结束了
5890 // 此时如果一个值都没收集到,需设置一个空字符串
5891 // 否则无法区分 <div a b=""> 中的 a 和 b
5892
5893 if (!currentAttribute.children) {
5894 addChild(createText(EMPTY_STRING));
5895 }
5896
5897 popStack(currentAttribute.type);
5898 currentAttribute = UNDEFINED;
5899 } // 没有结束引号,整段匹配
5900 // 如 id="1{{x}}2" 中的 1
5901 else if (blockMode !== BLOCK_MODE_NONE) {
5902 text = content;
5903 addTextChild(text);
5904 } // 没找到结束引号
5905 else {
5906 fatal$1("Unterminated quoted string in \"" + currentAttribute.name + "\".");
5907 }
5908 } // 如果不加判断,类似 <div {{...obj}}> 这样写,会把空格当做一个属性
5909 // 收集文本只有两处:属性值、元素内容
5910 // 属性值通过上面的 if 处理过了,这里只需要处理元素内容
5911 else if (!currentElement) {
5912 // 获取 <tag 前面的字符
5913 match = content.match(tagPattern); // 元素层级的注释都要删掉
5914
5915 if (match) {
5916 text = slice(content, 0, match.index);
5917
5918 if (text) {
5919 addTextChild(text.replace(commentPattern, EMPTY_STRING));
5920 }
5921 } else {
5922 text = content;
5923 addTextChild(text.replace(commentPattern, EMPTY_STRING));
5924 }
5925 } else {
5926 {
5927 if (trim(content)) {
5928 fatal$1("Invalid character is found in <" + currentElement.tag + "> attribute level.");
5929 }
5930 }
5931 text = content;
5932 }
5933
5934 return text;
5935 }],
5936 blockParsers = [// {{#each xx:index}}
5937 function (source) {
5938 if (startsWith(source, SYNTAX_EACH)) {
5939 {
5940 if (currentElement) {
5941 fatal$1(currentAttribute ? "The \"each\" block can't be appear in an attribute value." : "The \"each\" block can't be appear in attribute level.");
5942 }
5943 }
5944 source = slicePrefix(source, SYNTAX_EACH);
5945 var terms = source.replace(/\s+/g, EMPTY_STRING).split(':');
5946
5947 if (terms[0]) {
5948 var literal = trim(terms[0]),
5949 index_1 = terms[1] ? trim(terms[1]) : UNDEFINED,
5950 match = literal.match(rangePattern);
5951
5952 if (match) {
5953 var parts = literal.split(rangePattern),
5954 from = compile(parts[0]),
5955 to = compile(parts[2]);
5956
5957 if (from && to) {
5958 return createEach(from, to, trim(match[1]) === '=>', index_1);
5959 }
5960 } else {
5961 var expr = compile(literal);
5962
5963 if (expr) {
5964 return createEach(expr, UNDEFINED, FALSE, index_1);
5965 }
5966 }
5967 }
5968
5969 {
5970 fatal$1("Invalid each");
5971 }
5972 }
5973 }, // {{#import name}}
5974 function (source) {
5975 if (startsWith(source, SYNTAX_IMPORT)) {
5976 source = slicePrefix(source, SYNTAX_IMPORT);
5977
5978 if (source) {
5979 if (!currentElement) {
5980 return createImport(source);
5981 } else {
5982 fatal$1(currentAttribute ? "The \"import\" block can't be appear in an attribute value." : "The \"import\" block can't be appear in attribute level.");
5983 }
5984 }
5985
5986 {
5987 fatal$1("Invalid import");
5988 }
5989 }
5990 }, // {{#partial name}}
5991 function (source) {
5992 if (startsWith(source, SYNTAX_PARTIAL)) {
5993 source = slicePrefix(source, SYNTAX_PARTIAL);
5994
5995 if (source) {
5996 if (!currentElement) {
5997 return createPartial(source);
5998 } else {
5999 fatal$1(currentAttribute ? "The \"partial\" block can't be appear in an attribute value." : "The \"partial\" block can't be appear in attribute level.");
6000 }
6001 }
6002
6003 {
6004 fatal$1("Invalid partial");
6005 }
6006 }
6007 }, // {{#if expr}}
6008 function (source) {
6009 if (startsWith(source, SYNTAX_IF)) {
6010 source = slicePrefix(source, SYNTAX_IF);
6011 var expr = compile(source);
6012
6013 if (expr) {
6014 return createIf(expr);
6015 }
6016
6017 {
6018 fatal$1("Invalid if");
6019 }
6020 }
6021 }, // {{else if expr}}
6022 function (source) {
6023 if (startsWith(source, SYNTAX_ELSE_IF)) {
6024 source = slicePrefix(source, SYNTAX_ELSE_IF);
6025 var expr = compile(source);
6026
6027 if (expr) {
6028 return createElseIf(expr);
6029 }
6030
6031 {
6032 fatal$1("Invalid else if");
6033 }
6034 }
6035 }, // {{else}}
6036 function (source) {
6037 if (startsWith(source, SYNTAX_ELSE)) {
6038 source = slicePrefix(source, SYNTAX_ELSE);
6039
6040 if (!trim(source)) {
6041 return createElse();
6042 }
6043
6044 {
6045 fatal$1("The \"else\" must not be followed by anything.");
6046 }
6047 }
6048 }, // {{...obj}}
6049 function (source) {
6050 if (startsWith(source, SYNTAX_SPREAD)) {
6051 source = slicePrefix(source, SYNTAX_SPREAD);
6052 var expr = compile(source);
6053
6054 if (expr) {
6055 if (currentElement && currentElement.isComponent) {
6056 return createSpread(expr, expr.type === IDENTIFIER);
6057 } else {
6058 fatal$1("The spread can only be used by a component.");
6059 }
6060 }
6061
6062 {
6063 fatal$1("Invalid spread");
6064 }
6065 }
6066 }, // {{expr}}
6067 function (source) {
6068 if (!SYNTAX_COMMENT.test(source)) {
6069 source = trim(source);
6070 var expr = compile(source);
6071
6072 if (expr) {
6073 return createExpression(expr, blockMode === BLOCK_MODE_SAFE);
6074 }
6075
6076 {
6077 fatal$1("Invalid expression");
6078 }
6079 }
6080 }],
6081 parseHtml = function (code) {
6082 while (code) {
6083 each(htmlParsers, function (parse) {
6084 var match = parse(code);
6085
6086 if (match) {
6087 code = slice(code, match.length);
6088 return FALSE;
6089 }
6090 });
6091 }
6092 },
6093 parseBlock = function (code) {
6094 if (charAt(code) === RAW_SLASH) {
6095 /**
6096 * 处理可能存在的自闭合元素,如下
6097 *
6098 * {{#if xx}}
6099 * <input>
6100 * {{/if}}
6101 */
6102 popSelfClosingElementIfNeeded();
6103 var name = slice(code, 1);
6104 var type = name2Type[name],
6105 isCondition = FALSE;
6106
6107 if (type === IF) {
6108 var node_1 = pop(ifStack);
6109
6110 if (node_1) {
6111 type = node_1.type;
6112 isCondition = TRUE;
6113 } else {
6114 fatal$1("The \"if\" block is closing, but it's not open yet.");
6115 }
6116 }
6117
6118 var node = popStack(type);
6119
6120 if (node && isCondition) {
6121 checkCondition(node);
6122 }
6123 } else {
6124 // 开始下一个 block 或表达式
6125 each(blockParsers, function (parse) {
6126 var node = parse(code);
6127
6128 if (node) {
6129 addChild(node);
6130 return FALSE;
6131 }
6132 });
6133 }
6134 },
6135 closeBlock = function () {
6136 // 确定开始和结束定界符能否配对成功,即 {{ 对 }},{{{ 对 }}}
6137 // 这里不能动 openBlockIndex 和 closeBlockIndex,因为等下要用他俩 slice
6138 index = closeBlockIndex + 2; // 这里要用 <=,因为很可能到头了
6139
6140 if (index <= length) {
6141 if (index < length && charAt(content, index) === '}') {
6142 if (blockMode === BLOCK_MODE_UNSAFE) {
6143 nextIndex = index + 1;
6144 } else {
6145 fatal$1("{{ and }}} is not a pair.");
6146 }
6147 } else {
6148 if (blockMode === BLOCK_MODE_SAFE) {
6149 nextIndex = index;
6150 } else {
6151 fatal$1("{{{ and }} is not a pair.");
6152 }
6153 }
6154
6155 pop(blockStack); // }} 左侧的位置
6156
6157 addIndex(closeBlockIndex);
6158 openBlockIndex = indexOf$1(content, '{{', nextIndex);
6159 closeBlockIndex = indexOf$1(content, '}}', nextIndex); // 如果碰到连续的结束定界符,继续 close
6160
6161 if (closeBlockIndex >= nextIndex && (openBlockIndex < 0 || closeBlockIndex < openBlockIndex)) {
6162 return closeBlock();
6163 }
6164 } else {
6165 // 到头了
6166 return TRUE;
6167 }
6168 },
6169 addIndex = function (index) {
6170 if (!blockStack.length) {
6171 push(indexList, index);
6172 }
6173 }; // 因为存在 mustache 注释内包含插值的情况
6174 // 这里把流程设计为先标记切片的位置,标记过程中丢弃无效的 block
6175 // 最后处理有效的 block
6176
6177
6178 while (TRUE) {
6179 addIndex(nextIndex);
6180 openBlockIndex = indexOf$1(content, '{{', nextIndex);
6181
6182 if (openBlockIndex >= nextIndex) {
6183 blockMode = BLOCK_MODE_SAFE; // {{ 左侧的位置
6184
6185 addIndex(openBlockIndex); // 跳过 {{
6186
6187 openBlockIndex += 2; // {{ 后面总得有内容吧
6188
6189 if (openBlockIndex < length) {
6190 if (charAt(content, openBlockIndex) === '{') {
6191 blockMode = BLOCK_MODE_UNSAFE;
6192 openBlockIndex++;
6193 } // {{ 右侧的位置
6194
6195
6196 addIndex(openBlockIndex); // block 是否安全
6197
6198 addIndex(blockMode); // 打开一个 block 就入栈一个
6199
6200 push(blockStack, TRUE);
6201
6202 if (openBlockIndex < length) {
6203 closeBlockIndex = indexOf$1(content, '}}', openBlockIndex);
6204
6205 if (closeBlockIndex >= openBlockIndex) {
6206 // 注释可以嵌套,如 {{! {{xx}} {{! {{xx}} }} }}
6207 nextIndex = indexOf$1(content, '{{', openBlockIndex);
6208
6209 if (nextIndex < 0 || closeBlockIndex < nextIndex) {
6210 if (closeBlock()) {
6211 break;
6212 }
6213 }
6214 } else {
6215 fatal$1('The end delimiter is not found.');
6216 }
6217 } else {
6218 // {{{ 后面没字符串了?
6219 fatal$1('Unterminated template literal.');
6220 }
6221 } else {
6222 // {{ 后面没字符串了?
6223 fatal$1('Unterminated template literal.');
6224 }
6225 } else {
6226 break;
6227 }
6228 }
6229
6230 for (var i = 0, length_1 = indexList.length; i < length_1; i += 5) {
6231 index = indexList[i]; // {{ 左侧的位置
6232
6233 openBlockIndex = indexList[i + 1];
6234
6235 if (openBlockIndex) {
6236 parseHtml(slice(content, index, openBlockIndex));
6237 } // {{ 右侧的位置
6238
6239
6240 openBlockIndex = indexList[i + 2];
6241 blockMode = indexList[i + 3];
6242 closeBlockIndex = indexList[i + 4];
6243
6244 if (closeBlockIndex) {
6245 code = trim(slice(content, openBlockIndex, closeBlockIndex)); // 不用处理 {{ }} 和 {{{ }}} 这种空 block
6246
6247 if (code) {
6248 parseBlock(code);
6249 }
6250 } else {
6251 blockMode = BLOCK_MODE_NONE;
6252 parseHtml(slice(content, index));
6253 }
6254 }
6255
6256 if (nodeStack.length) {
6257 /**
6258 * 处理可能存在的自闭合元素,如下
6259 *
6260 * <input>
6261 */
6262 popSelfClosingElementIfNeeded();
6263 {
6264 if (nodeStack.length) {
6265 fatal$1('Some nodes is still in the stack.');
6266 }
6267 }
6268 }
6269
6270 if (nodeList.length > 0) {
6271 removeComment(nodeList);
6272 }
6273
6274 return nodeList;
6275 }
6276
6277 function isUndef(target) {
6278 return target === UNDEFINED;
6279 }
6280
6281 var UNDEFINED$1 = '$0';
6282 var NULL$1 = '$1';
6283 var TRUE$1 = '$2';
6284 var FALSE$1 = '$3';
6285 var COMMA = ',';
6286 var COLON = ':';
6287 var PLUS = '+';
6288 var AND = '&&';
6289 var QUESTION = '?';
6290 var NOT = '!';
6291 var EMPTY = '""';
6292 var RETURN = 'return ';
6293 /**
6294 * 目的是 保证调用参数顺序稳定,减少运行时判断
6295 *
6296 * [a, undefined, undefined] => [a]
6297 * [a, undefined, b, undefined] => [a, undefined, b]
6298 */
6299
6300 function trimArgs(list) {
6301 var args = [],
6302 removable = TRUE;
6303 each(list, function (arg) {
6304 if (isDef(arg)) {
6305 removable = FALSE;
6306 unshift(args, arg);
6307 } else if (!removable) {
6308 unshift(args, UNDEFINED$1);
6309 }
6310 }, TRUE);
6311 return args;
6312 }
6313 /**
6314 * 确保表达式的优先级是正确的
6315 */
6316
6317
6318 function toGroup(code) {
6319 // 数组不用加括号
6320 if (/^\[[^\]]+\]$/.test(code) // 对象不用加括号
6321 || /^{[^\}]+}$/.test(code) // 字符串不用加括号
6322 || /^"[^"]+\"$/.test(code) // 一元表达式不用加括号
6323 || /^(?:[-+~!]|!!)(?:[\$\w]+|\([\$\w]+\))$/.test(code) // 函数调用不用加括号
6324 || /^\w+\([^\)\{\}]*\)$/.test(code) // 避免重复加括号
6325 || /^\([^\)]+\)$/.test(code)) {
6326 return code;
6327 }
6328
6329 return /[-+*\/%<>=!&^|,?:]/.test(code) ? "(" + code + ")" : code;
6330 }
6331 /**
6332 * 把 [ 'key1:value1', 'key2:value2' ] 格式转成 `{key1:value1,key2:value2}`
6333 */
6334
6335
6336 function toObject$1(fields) {
6337 return "{" + join(fields, COMMA) + "}";
6338 }
6339 /**
6340 * 把 [ 'item1', 'item2' ] 格式转成 `['item1','item2']`
6341 */
6342
6343
6344 function toArray$1(items) {
6345 return "[" + join(items, COMMA) + "]";
6346 }
6347 /**
6348 * 输出函数调用的格式
6349 */
6350
6351
6352 function toCall(name, args) {
6353 var code = args ? join(trimArgs(args), COMMA) : EMPTY_STRING;
6354 return name + "(" + code + ")";
6355 }
6356 /**
6357 * 输出为字符串格式
6358 */
6359
6360
6361 function toString$1(value) {
6362 return value === TRUE ? TRUE$1 : value === FALSE ? FALSE$1 : value === NULL ? NULL$1 : value === UNDEFINED ? UNDEFINED$1 : JSON.stringify(value);
6363 }
6364 /**
6365 * 输出为匿名函数格式
6366 */
6367
6368
6369 function toFunction(args, code) {
6370 return RAW_FUNCTION + "(" + args + "){var " + UNDEFINED$1 + "=void 0," + NULL$1 + "=null," + TRUE$1 + "=!0," + FALSE$1 + "=!1;" + RETURN + code + "}";
6371 }
6372
6373 function generate(node, renderIdentifier, renderMemberKeypath, renderMemberLiteral, renderCall, holder, depIgnore, stack, inner) {
6374 var value,
6375 isSpecialNode = FALSE,
6376 // 如果是内部临时值,不需要 holder
6377 needHolder = holder && !inner,
6378 generateChildNode = function (node) {
6379 return generate(node, renderIdentifier, renderMemberKeypath, renderMemberLiteral, renderCall, holder, depIgnore, stack, TRUE);
6380 };
6381
6382 switch (node.type) {
6383 case LITERAL:
6384 value = toString$1(node.value);
6385 break;
6386
6387 case UNARY:
6388 value = node.operator + generateChildNode(node.node);
6389 break;
6390
6391 case BINARY:
6392 value = toGroup(generateChildNode(node.left)) + node.operator + toGroup(generateChildNode(node.right));
6393 break;
6394
6395 case TERNARY:
6396 // 虽然三元表达式优先级最低,但无法保证表达式内部没有 ,
6397 value = toGroup(generateChildNode(node.test)) + QUESTION + toGroup(generateChildNode(node.yes)) + COLON + toGroup(generateChildNode(node.no));
6398 break;
6399
6400 case ARRAY:
6401 var items = node.nodes.map(generateChildNode);
6402 value = toArray$1(items);
6403 break;
6404
6405 case OBJECT:
6406 var fields_1 = [];
6407 each(node.keys, function (key, index) {
6408 push(fields_1, toString$1(key) + COLON + generateChildNode(node.values[index]));
6409 });
6410 value = toObject$1(fields_1);
6411 break;
6412
6413 case IDENTIFIER:
6414 isSpecialNode = TRUE;
6415 var identifier = node;
6416 value = toCall(renderIdentifier, [toString$1(identifier.name), toString$1(identifier.lookup), identifier.offset > 0 ? toString$1(identifier.offset) : UNDEFINED, needHolder ? TRUE$1 : UNDEFINED, depIgnore ? TRUE$1 : UNDEFINED, stack ? stack : UNDEFINED]);
6417 break;
6418
6419 case MEMBER:
6420 isSpecialNode = TRUE;
6421 var _a = node,
6422 lead = _a.lead,
6423 keypath = _a.keypath,
6424 nodes = _a.nodes,
6425 lookup = _a.lookup,
6426 offset = _a.offset,
6427 stringifyNodes = nodes ? nodes.map(generateChildNode) : [];
6428
6429 if (lead.type === IDENTIFIER) {
6430 // 只能是 a[b] 的形式,因为 a.b 已经在解析时转换成 Identifier 了
6431 value = toCall(renderIdentifier, [toCall(renderMemberKeypath, [toString$1(lead.name), toArray$1(stringifyNodes)]), toString$1(lookup), offset > 0 ? toString$1(offset) : UNDEFINED, needHolder ? TRUE$1 : UNDEFINED, depIgnore ? TRUE$1 : UNDEFINED, stack ? stack : UNDEFINED]);
6432 } else if (nodes) {
6433 // "xx"[length]
6434 // format()[a][b]
6435 value = toCall(renderMemberLiteral, [generateChildNode(lead), UNDEFINED, toArray$1(stringifyNodes), needHolder ? TRUE$1 : UNDEFINED]);
6436 } else {
6437 // "xx".length
6438 // format().a.b
6439 value = toCall(renderMemberLiteral, [generateChildNode(lead), toString$1(keypath), UNDEFINED, needHolder ? TRUE$1 : UNDEFINED]);
6440 }
6441
6442 break;
6443
6444 default:
6445 isSpecialNode = TRUE;
6446 var args = node.args;
6447 value = toCall(renderCall, [generateChildNode(node.name), args.length ? toArray$1(args.map(generateChildNode)) : UNDEFINED, needHolder ? TRUE$1 : UNDEFINED]);
6448 break;
6449 }
6450
6451 if (!needHolder) {
6452 return value;
6453 } // 最外层的值,且 holder 为 true
6454
6455
6456 return isSpecialNode ? value : toObject$1([RAW_VALUE + COLON + value]);
6457 }
6458 /**
6459 * 这里的难点在于处理 Element 的 children,举个例子:
6460 *
6461 * ['1', _x(expr), _l(expr, index, generate), _x(expr) ? ['1', _x(expr), _l(expr, index, generate)] : y]
6462 *
6463 * children 用数组表示,其中表达式求出的值可能是任意类型,比如数组或对象,我们无法控制表达式的值最终会是什么类型
6464 *
6465 * 像 each 或 import 这样的语法,内部其实会产生一个 vnode 数组,这里就出现了两个难点:
6466 *
6467 * 1. 如何区分 each 或其他语法产生的数组和表达式求值的数组
6468 * 2. 如何避免频繁的创建数组
6469 *
6470 * 我能想到的解决方案是,根据当前节点类型,如果是元素,则确保 children 的每一项的值序列化后都是函数调用的形式
6471 *
6472 * 这样能确保是从左到右依次执行,也就便于在内部创建一个公共数组,执行一个函数就收集一个值,而不管那个值到底是什么类型
6473 *
6474 */
6475 // 是否要执行 join 操作
6476
6477
6478 var joinStack = [],
6479 // 是否正在收集子节点
6480 collectStack = [],
6481 nodeGenerator = {},
6482 RENDER_EXPRESSION_IDENTIFIER = 'a',
6483 RENDER_EXPRESSION_MEMBER_KEYPATH = 'b',
6484 RENDER_EXPRESSION_MEMBER_LITERAL = 'c',
6485 RENDER_EXPRESSION_CALL = 'd',
6486 RENDER_TEXT_VNODE = 'e',
6487 RENDER_ATTRIBUTE_VNODE = 'f',
6488 RENDER_PROPERTY_VNODE = 'g',
6489 RENDER_LAZY_VNODE = 'h',
6490 RENDER_TRANSITION_VNODE = 'i',
6491 RENDER_BINDING_VNODE = 'j',
6492 RENDER_MODEL_VNODE = 'k',
6493 RENDER_EVENT_METHOD_VNODE = 'l',
6494 RENDER_EVENT_NAME_VNODE = 'm',
6495 RENDER_DIRECTIVE_VNODE = 'n',
6496 RENDER_SPREAD_VNODE = 'o',
6497 RENDER_COMMENT_VNODE = 'p',
6498 RENDER_ELEMENT_VNODE = 'q',
6499 RENDER_COMPONENT_VNODE = 'r',
6500 RENDER_SLOT = 's',
6501 RENDER_PARTIAL = 't',
6502 RENDER_IMPORT = 'u',
6503 RENDER_EACH = 'v',
6504 RENDER_RANGE = 'w',
6505 RENDER_EQUAL_RANGE = 'x',
6506 TO_STRING = 'y',
6507 ARG_STACK = 'z'; // 序列化代码的参数列表
6508
6509 var codeArgs, // 表达式求值是否要求返回字符串类型
6510 isStringRequired;
6511
6512 function renderExpression(expr, holder, depIgnore, stack) {
6513 return generate(expr, RENDER_EXPRESSION_IDENTIFIER, RENDER_EXPRESSION_MEMBER_KEYPATH, RENDER_EXPRESSION_MEMBER_LITERAL, RENDER_EXPRESSION_CALL, holder, depIgnore, stack);
6514 }
6515
6516 function stringifyObject(obj) {
6517 var fields = [];
6518 each$2(obj, function (value, key) {
6519 if (isDef(value)) {
6520 push(fields, toString$1(key) + COLON + value);
6521 }
6522 });
6523 return toObject$1(fields);
6524 }
6525
6526 function stringifyFunction(result, arg) {
6527 return RAW_FUNCTION + "(" + (arg || EMPTY_STRING) + "){" + (result || EMPTY_STRING) + "}";
6528 }
6529
6530 function stringifyExpression(expr, toString) {
6531 var value = renderExpression(expr);
6532 return toString ? toCall(TO_STRING, [value]) : value;
6533 }
6534
6535 function stringifyExpressionVnode(expr, toString) {
6536 return toCall(RENDER_TEXT_VNODE, [stringifyExpression(expr, toString)]);
6537 }
6538
6539 function stringifyExpressionArg(expr) {
6540 return renderExpression(expr, FALSE, FALSE, ARG_STACK);
6541 }
6542
6543 function stringifyValue(value, expr, children) {
6544 if (isDef(value)) {
6545 return toString$1(value);
6546 } // 只有一个表达式时,保持原始类型
6547
6548
6549 if (expr) {
6550 return stringifyExpression(expr);
6551 } // 多个值拼接时,要求是字符串
6552
6553
6554 if (children) {
6555 // 求值时要标识 isStringRequired
6556 // 求完后复原
6557 // 常见的应用场景是序列化 HTML 元素属性值,处理值时要求字符串,在处理属性名这个级别,不要求字符串
6558 var oldValue = isStringRequired;
6559 isStringRequired = children.length > 1;
6560 var result = stringifyChildren(children);
6561 isStringRequired = oldValue;
6562 return result;
6563 }
6564 }
6565
6566 function stringifyChildren(children, isComplex) {
6567 // 如果是复杂节点的 children,则每个 child 的序列化都是函数调用的形式
6568 // 因此最后可以拼接为 fn1(), fn2(), fn3() 这样依次调用,而不用再多此一举的使用数组,
6569 // 因为在 renderer 里也用不上这个数组
6570 // children 大于一个时,才有 join 的可能,单个值 join 啥啊...
6571 var isJoin = children.length > 1 && !isComplex;
6572 push(joinStack, isJoin);
6573 var value = join(children.map(function (child) {
6574 return nodeGenerator[child.type](child);
6575 }), isJoin ? PLUS : COMMA);
6576 pop(joinStack);
6577 return value;
6578 }
6579
6580 function stringifyConditionChildren(children, isComplex) {
6581 if (children) {
6582 var result = stringifyChildren(children, isComplex);
6583 return children.length > 1 && isComplex ? toGroup(result) : result;
6584 }
6585 }
6586
6587 function stringifyIf(node, stub) {
6588 var children = node.children,
6589 isComplex = node.isComplex,
6590 next = node.next,
6591 test = stringifyExpression(node.expr),
6592 yes = stringifyConditionChildren(children, isComplex),
6593 no,
6594 result;
6595
6596 if (next) {
6597 no = next.type === ELSE ? stringifyConditionChildren(next.children, next.isComplex) : stringifyIf(next, stub);
6598 } // 到达最后一个条件,发现第一个 if 语句带有 stub,需创建一个注释标签占位
6599 else if (stub) {
6600 no = toCall(RENDER_COMMENT_VNODE);
6601 }
6602
6603 if (isDef(yes) || isDef(no)) {
6604 if (isStringRequired) {
6605 if (isUndef(yes)) {
6606 yes = EMPTY;
6607 }
6608
6609 if (isUndef(no)) {
6610 no = EMPTY;
6611 }
6612 } // 避免出现 a||b&&c 的情况
6613 // 应该输出 (a||b)&&c
6614
6615
6616 if (isUndef(no)) {
6617 result = toGroup(test) + AND + yes;
6618 } else if (isUndef(yes)) {
6619 result = toGroup(NOT + test) + AND + no;
6620 } else {
6621 // 虽然三元表达式优先级最低,但无法保证表达式内部没有 ,
6622 result = toGroup(test) + QUESTION + toGroup(yes) + COLON + toGroup(no);
6623 } // 如果是连接操作,因为 ?: 优先级最低,因此要加 ()
6624
6625
6626 return last(joinStack) ? toGroup(result) : result;
6627 }
6628
6629 return EMPTY;
6630 }
6631
6632 function getComponentSlots(children) {
6633 var result = {},
6634 slots = {},
6635 addSlot = function (name, nodes) {
6636 if (!falsy(nodes)) {
6637 name = SLOT_DATA_PREFIX + name;
6638 push(slots[name] || (slots[name] = []), nodes);
6639 }
6640 };
6641
6642 each(children, function (child) {
6643 // 找到具名 slot
6644 if (child.type === ELEMENT) {
6645 var element = child;
6646
6647 if (element.slot) {
6648 addSlot(element.slot, element.tag === RAW_TEMPLATE ? element.children : [element]);
6649 return;
6650 }
6651 } // 匿名 slot,名称统一为 children
6652
6653
6654 addSlot(SLOT_NAME_DEFAULT, [child]);
6655 });
6656 each$2(slots, function (children, name) {
6657 // 强制为复杂节点,因为 slot 的子节点不能用字符串拼接的方式来渲染
6658 result[name] = stringifyFunction(stringifyChildren(children, TRUE));
6659 });
6660
6661 if (!falsy$2(result)) {
6662 return stringifyObject(result);
6663 }
6664 }
6665
6666 nodeGenerator[ELEMENT] = function (node) {
6667 var tag = node.tag,
6668 isComponent = node.isComponent,
6669 isComplex = node.isComplex,
6670 ref = node.ref,
6671 key = node.key,
6672 html = node.html,
6673 attrs = node.attrs,
6674 children = node.children,
6675 staticTag,
6676 dynamicTag,
6677 outputAttrs,
6678 outputText,
6679 outputHTML,
6680 outputChilds,
6681 outputSlots,
6682 outputStatic,
6683 outputOption,
6684 outputStyle,
6685 outputSvg,
6686 outputRef,
6687 outputKey;
6688
6689 if (tag === RAW_SLOT) {
6690 var args = [toString$1(SLOT_DATA_PREFIX + node.name)];
6691
6692 if (children) {
6693 push(args, stringifyFunction(stringifyChildren(children, TRUE)));
6694 }
6695
6696 return toCall(RENDER_SLOT, args);
6697 } // 如果以 $ 开头,表示动态组件
6698
6699
6700 if (codeAt(tag) === 36) {
6701 dynamicTag = toString$1(slice(tag, 1));
6702 } else {
6703 staticTag = toString$1(tag);
6704 }
6705
6706 push(collectStack, FALSE);
6707
6708 if (attrs) {
6709 var list_1 = [];
6710 each(attrs, function (attr) {
6711 push(list_1, nodeGenerator[attr.type](attr));
6712 });
6713
6714 if (list_1.length) {
6715 outputAttrs = stringifyFunction(join(list_1, COMMA));
6716 }
6717 }
6718
6719 if (children) {
6720 if (isComponent) {
6721 collectStack[collectStack.length - 1] = TRUE;
6722 outputSlots = getComponentSlots(children);
6723 } else {
6724 var oldValue = isStringRequired;
6725 isStringRequired = TRUE;
6726 collectStack[collectStack.length - 1] = isComplex;
6727 outputChilds = stringifyChildren(children, isComplex);
6728
6729 if (isComplex) {
6730 outputChilds = stringifyFunction(outputChilds);
6731 } else {
6732 outputText = outputChilds;
6733 outputChilds = UNDEFINED;
6734 }
6735
6736 isStringRequired = oldValue;
6737 }
6738 }
6739
6740 pop(collectStack);
6741
6742 if (html) {
6743 outputHTML = string(html) ? toString$1(html) : stringifyExpression(html, TRUE);
6744 }
6745
6746 outputStatic = node.isStatic ? TRUE$1 : UNDEFINED;
6747 outputOption = node.isOption ? TRUE$1 : UNDEFINED;
6748 outputStyle = node.isStyle ? TRUE$1 : UNDEFINED;
6749 outputSvg = node.isSvg ? TRUE$1 : UNDEFINED;
6750 outputRef = ref ? stringifyValue(ref.value, ref.expr, ref.children) : UNDEFINED;
6751 outputKey = key ? stringifyValue(key.value, key.expr, key.children) : UNDEFINED;
6752
6753 if (isComponent) {
6754 return toCall(RENDER_COMPONENT_VNODE, // 最常用 => 最不常用排序
6755 [staticTag, outputAttrs, outputSlots, outputRef, outputKey, dynamicTag]);
6756 }
6757
6758 return toCall(RENDER_ELEMENT_VNODE, // 最常用 => 最不常用排序
6759 [staticTag, outputAttrs, outputChilds, outputText, outputStatic, outputOption, outputStyle, outputSvg, outputHTML, outputRef, outputKey]);
6760 };
6761
6762 nodeGenerator[ATTRIBUTE] = function (node) {
6763 var value = node.binding ? toCall(RENDER_BINDING_VNODE, [toString$1(node.name), renderExpression(node.expr, TRUE, TRUE)]) : stringifyValue(node.value, node.expr, node.children);
6764 return toCall(RENDER_ATTRIBUTE_VNODE, [toString$1(node.name), value]);
6765 };
6766
6767 nodeGenerator[PROPERTY] = function (node) {
6768 var value = node.binding ? toCall(RENDER_BINDING_VNODE, [toString$1(node.name), renderExpression(node.expr, TRUE, TRUE), toString$1(node.hint)]) : stringifyValue(node.value, node.expr, node.children);
6769 return toCall(RENDER_PROPERTY_VNODE, [toString$1(node.name), value]);
6770 };
6771
6772 nodeGenerator[DIRECTIVE] = function (node) {
6773 var ns = node.ns,
6774 name = node.name,
6775 key = node.key,
6776 value = node.value,
6777 expr = node.expr,
6778 modifier = node.modifier;
6779
6780 if (ns === DIRECTIVE_LAZY) {
6781 return toCall(RENDER_LAZY_VNODE, [toString$1(name), toString$1(value)]);
6782 } // <div transition="name">
6783
6784
6785 if (ns === RAW_TRANSITION) {
6786 return toCall(RENDER_TRANSITION_VNODE, [toString$1(value)]);
6787 } // <input model="id">
6788
6789
6790 if (ns === DIRECTIVE_MODEL) {
6791 return toCall(RENDER_MODEL_VNODE, [renderExpression(expr, TRUE, TRUE)]);
6792 }
6793
6794 var renderName = RENDER_DIRECTIVE_VNODE,
6795 args = [toString$1(name), toString$1(key), toString$1(modifier), toString$1(value)]; // 尽可能把表达式编译成函数,这样对外界最友好
6796 //
6797 // 众所周知,事件指令会编译成函数,对于自定义指令来说,也要尽可能编译成函数
6798 //
6799 // 比如 o-tap="method()" 或 o-log="{'id': '11'}"
6800 // 前者会编译成 handler(调用方法),后者会编译成 getter(取值)
6801
6802 if (expr) {
6803 // 如果表达式明确是在调用方法,则序列化成 method + args 的形式
6804 if (expr.type === CALL) {
6805 if (ns === DIRECTIVE_EVENT) {
6806 renderName = RENDER_EVENT_METHOD_VNODE;
6807 } // compiler 保证了函数调用的 name 是标识符
6808
6809
6810 push(args, toString$1(expr.name.name)); // 为了实现运行时动态收集参数,这里序列化成函数
6811
6812 if (!falsy(expr.args)) {
6813 // args 函数在触发事件时调用,调用时会传入它的作用域,因此这里要加一个参数
6814 push(args, stringifyFunction(RETURN + toArray$1(expr.args.map(stringifyExpressionArg)), ARG_STACK));
6815 }
6816 } // 不是调用方法,就是事件转换
6817 else if (ns === DIRECTIVE_EVENT) {
6818 renderName = RENDER_EVENT_NAME_VNODE;
6819 push(args, toString$1(expr.raw));
6820 } else if (ns === DIRECTIVE_CUSTOM) {
6821 // 取值函数
6822 // getter 函数在触发事件时调用,调用时会传入它的作用域,因此这里要加一个参数
6823 if (expr.type !== LITERAL) {
6824 push(args, UNDEFINED); // method
6825
6826 push(args, UNDEFINED); // args
6827
6828 push(args, stringifyFunction(RETURN + stringifyExpressionArg(expr), ARG_STACK));
6829 }
6830 }
6831 }
6832
6833 return toCall(renderName, args);
6834 };
6835
6836 nodeGenerator[SPREAD] = function (node) {
6837 return toCall(RENDER_SPREAD_VNODE, [renderExpression(node.expr, TRUE, node.binding)]);
6838 };
6839
6840 nodeGenerator[TEXT] = function (node) {
6841 var result = toString$1(node.text);
6842
6843 if (last(collectStack) && !last(joinStack)) {
6844 return toCall(RENDER_TEXT_VNODE, [result]);
6845 }
6846
6847 return result;
6848 };
6849
6850 nodeGenerator[EXPRESSION] = function (node) {
6851 // 强制保留 isStringRequired 参数,减少运行时判断参数是否存在
6852 // 因为还有 stack 参数呢,各种判断真的很累
6853 if (last(collectStack) && !last(joinStack)) {
6854 return stringifyExpressionVnode(node.expr, isStringRequired);
6855 }
6856
6857 return stringifyExpression(node.expr, isStringRequired);
6858 };
6859
6860 nodeGenerator[IF] = function (node) {
6861 return stringifyIf(node, node.stub);
6862 };
6863
6864 nodeGenerator[EACH] = function (node) {
6865 // compiler 保证了 children 一定有值
6866 var children = stringifyFunction(stringifyChildren(node.children, node.isComplex)); // 遍历区间
6867
6868 if (node.to) {
6869 if (node.equal) {
6870 return toCall(RENDER_EQUAL_RANGE, [children, renderExpression(node.from), renderExpression(node.to), toString$1(node.index)]);
6871 }
6872
6873 return toCall(RENDER_RANGE, [children, renderExpression(node.from), renderExpression(node.to), toString$1(node.index)]);
6874 } // 遍历数组和对象
6875
6876
6877 return toCall(RENDER_EACH, [children, renderExpression(node.from, TRUE), toString$1(node.index)]);
6878 };
6879
6880 nodeGenerator[PARTIAL] = function (node) {
6881 return toCall(RENDER_PARTIAL, [toString$1(node.name), // compiler 保证了 children 一定有值
6882 stringifyFunction(stringifyChildren(node.children, node.isComplex))]);
6883 };
6884
6885 nodeGenerator[IMPORT] = function (node) {
6886 return toCall(RENDER_IMPORT, [toString$1(node.name)]);
6887 };
6888
6889 function generate$1(node) {
6890 if (!codeArgs) {
6891 codeArgs = join([RENDER_EXPRESSION_IDENTIFIER, RENDER_EXPRESSION_MEMBER_KEYPATH, RENDER_EXPRESSION_MEMBER_LITERAL, RENDER_EXPRESSION_CALL, RENDER_TEXT_VNODE, RENDER_ATTRIBUTE_VNODE, RENDER_PROPERTY_VNODE, RENDER_LAZY_VNODE, RENDER_TRANSITION_VNODE, RENDER_BINDING_VNODE, RENDER_MODEL_VNODE, RENDER_EVENT_METHOD_VNODE, RENDER_EVENT_NAME_VNODE, RENDER_DIRECTIVE_VNODE, RENDER_SPREAD_VNODE, RENDER_COMMENT_VNODE, RENDER_ELEMENT_VNODE, RENDER_COMPONENT_VNODE, RENDER_SLOT, RENDER_PARTIAL, RENDER_IMPORT, RENDER_EACH, RENDER_RANGE, RENDER_EQUAL_RANGE, TO_STRING], COMMA);
6892 }
6893
6894 return toFunction(codeArgs, nodeGenerator[node.type](node));
6895 }
6896
6897 function setPair(target, name, key, value) {
6898 var data = target[name] || (target[name] = {});
6899 data[key] = value;
6900 }
6901
6902 var KEY_DIRECTIVES = 'directives';
6903
6904 function render(context, observer, template, filters, partials, directives, transitions) {
6905 var $scope = {
6906 $keypath: EMPTY_STRING
6907 },
6908 $stack = [$scope],
6909 $vnode,
6910 vnodeStack = [],
6911 localPartials = {},
6912 renderedSlots = {},
6913 findValue = function (stack, index, key, lookup, depIgnore, defaultKeypath) {
6914 var scope = stack[index],
6915 keypath = join$1(scope.$keypath, key),
6916 value = stack,
6917 holder$1 = holder; // 如果最后还是取不到值,用回最初的 keypath
6918
6919 if (defaultKeypath === UNDEFINED) {
6920 defaultKeypath = keypath;
6921 } // 如果取的是 scope 上直接有的数据,如 $keypath
6922
6923
6924 if (scope[key] !== UNDEFINED) {
6925 value = scope[key];
6926 } // 如果取的是数组项,则要更进一步
6927 else if (scope.$item !== UNDEFINED) {
6928 scope = scope.$item; // 到这里 scope 可能为空
6929 // 比如 new Array(10) 然后遍历这个数组,每一项肯定是空
6930 // 取 this
6931
6932 if (key === EMPTY_STRING) {
6933 value = scope;
6934 } // 取 this.xx
6935 else if (scope != NULL && scope[key] !== UNDEFINED) {
6936 value = scope[key];
6937 }
6938 }
6939
6940 if (value === stack) {
6941 // 正常取数据
6942 value = observer.get(keypath, stack, depIgnore);
6943
6944 if (value === stack) {
6945 if (lookup && index > 0) {
6946 {
6947 debug("该路径 "+ keypath +" 的数据无法在本context中找到。");
6948 }
6949 return findValue(stack, index - 1, key, lookup, depIgnore, defaultKeypath);
6950 } // 到头了,最后尝试过滤器
6951
6952
6953 var result = get(filters, key);
6954
6955 if (result) {
6956 holder$1 = result;
6957 holder$1.keypath = key;
6958 } else {
6959 holder$1.value = UNDEFINED;
6960 holder$1.keypath = defaultKeypath;
6961 }
6962
6963 return holder$1;
6964 }
6965 }
6966
6967 holder$1.value = value;
6968 holder$1.keypath = keypath;
6969 return holder$1;
6970 },
6971 createEventListener = function (type) {
6972 return function (event, data) {
6973 // 事件名称相同的情况,只可能是监听 DOM 事件,比如写一个 Button 组件
6974 // <button on-click="click"> 纯粹的封装了一个原生 click 事件
6975 if (type !== event.type) {
6976 event = new CustomEvent(type, event);
6977 }
6978
6979 context.fire(event, data);
6980 };
6981 },
6982 createMethodListener = function (name, args, stack) {
6983 return function (event, data) {
6984 var method = context[name];
6985
6986 if (event instanceof CustomEvent) {
6987 var result = UNDEFINED;
6988
6989 if (args) {
6990 var scope = last(stack);
6991
6992 if (scope) {
6993 scope.$event = event;
6994 scope.$data = data;
6995 result = execute(method, context, args(stack));
6996 scope.$event = scope.$data = UNDEFINED;
6997 }
6998 } else {
6999 result = execute(method, context, data ? [event, data] : event);
7000 }
7001
7002 return result;
7003 } else {
7004 execute(method, context, args ? args(stack) : UNDEFINED);
7005 }
7006 };
7007 },
7008 createGetter = function (getter, stack) {
7009 return function () {
7010 return getter(stack);
7011 };
7012 },
7013 renderTextVnode = function (text) {
7014 var vnodeList = last(vnodeStack);
7015
7016 if (vnodeList) {
7017 var lastVnode = last(vnodeList);
7018
7019 if (lastVnode && lastVnode.isText) {
7020 lastVnode.text += text;
7021 } else {
7022 // 注释节点标签名是 '!',这里区分一下
7023 var textVnode = {
7024 tag: '#',
7025 isText: TRUE,
7026 text: text,
7027 context: context,
7028 keypath: $scope.$keypath
7029 };
7030 push(vnodeList, textVnode);
7031 }
7032 }
7033 },
7034 renderAttributeVnode = function (name, value) {
7035 setPair($vnode, $vnode.isComponent ? 'props' : 'nativeAttrs', name, value);
7036 },
7037 renderPropertyVnode = function (name, value) {
7038 setPair($vnode, 'nativeProps', name, value);
7039 },
7040 renderLazyVnode = function (name, value) {
7041 setPair($vnode, 'lazy', name, value);
7042 },
7043 renderTransitionVnode = function (name) {
7044 $vnode.transition = transitions[name];
7045 {
7046 if (!$vnode.transition) {
7047 fatal("The transition \"" + name + "\" can't be found.");
7048 }
7049 }
7050 },
7051 renderBindingVnode = function (name, holder, hint) {
7052 var key = join$1(DIRECTIVE_BINDING, name);
7053 setPair($vnode, KEY_DIRECTIVES, key, {
7054 ns: DIRECTIVE_BINDING,
7055 name: name,
7056 key: key,
7057 modifier: holder.keypath,
7058 hooks: directives[DIRECTIVE_BINDING],
7059 hint: hint
7060 });
7061 return holder.value;
7062 },
7063 renderModelVnode = function (holder) {
7064 setPair($vnode, KEY_DIRECTIVES, DIRECTIVE_MODEL, {
7065 ns: DIRECTIVE_MODEL,
7066 name: EMPTY_STRING,
7067 key: DIRECTIVE_MODEL,
7068 value: holder.value,
7069 modifier: holder.keypath,
7070 hooks: directives[DIRECTIVE_MODEL]
7071 });
7072 },
7073 renderEventMethodVnode = function (name, key, modifier, value, method, args) {
7074 setPair($vnode, KEY_DIRECTIVES, key, {
7075 ns: DIRECTIVE_EVENT,
7076 name: name,
7077 key: key,
7078 value: value,
7079 modifier: modifier,
7080 hooks: directives[DIRECTIVE_EVENT],
7081 handler: createMethodListener(method, args, $stack)
7082 });
7083 },
7084 renderEventNameVnode = function (name, key, modifier, value, event) {
7085 setPair($vnode, KEY_DIRECTIVES, key, {
7086 ns: DIRECTIVE_EVENT,
7087 name: name,
7088 key: key,
7089 value: value,
7090 modifier: modifier,
7091 hooks: directives[DIRECTIVE_EVENT],
7092 handler: createEventListener(event)
7093 });
7094 },
7095 renderDirectiveVnode = function (name, key, modifier, value, method, args, getter) {
7096 var hooks = directives[name];
7097 {
7098 if (!hooks) {
7099 fatal("The directive " + name + " can't be found.");
7100 }
7101 }
7102 setPair($vnode, KEY_DIRECTIVES, key, {
7103 ns: DIRECTIVE_CUSTOM,
7104 name: name,
7105 key: key,
7106 value: value,
7107 hooks: hooks,
7108 modifier: modifier,
7109 getter: getter ? createGetter(getter, $stack) : UNDEFINED,
7110 handler: method ? createMethodListener(method, args, $stack) : UNDEFINED
7111 });
7112 },
7113 renderSpreadVnode = function (holder) {
7114 var value = holder.value,
7115 keypath = holder.keypath;
7116
7117 if (object(value)) {
7118 // 数组也算一种对象
7119 // 延展操作符不支持数组
7120 {
7121 if (array(value)) {
7122 fatal("The spread operator can't be used by an array.");
7123 }
7124 }
7125
7126 for (var key in value) {
7127 setPair($vnode, 'props', key, value[key]);
7128 }
7129
7130 if (keypath) {
7131 var key = join$1(DIRECTIVE_BINDING, keypath);
7132 setPair($vnode, KEY_DIRECTIVES, key, {
7133 ns: DIRECTIVE_BINDING,
7134 name: EMPTY_STRING,
7135 key: key,
7136 modifier: join$1(keypath, RAW_WILDCARD),
7137 hooks: directives[DIRECTIVE_BINDING]
7138 });
7139 }
7140 }
7141 },
7142 appendVnode = function (vnode) {
7143 var vnodeList = last(vnodeStack);
7144
7145 if (vnodeList) {
7146 push(vnodeList, vnode);
7147 }
7148
7149 return vnode;
7150 },
7151 renderCommentVnode = function () {
7152 // 注释节点和文本节点需要有个区分
7153 // 如果两者都没有 tag,则 patchVnode 时,会认为两者是 patchable 的
7154 return appendVnode({
7155 tag: '!',
7156 isComment: TRUE,
7157 text: EMPTY_STRING,
7158 keypath: $scope.$keypath,
7159 context: context
7160 });
7161 },
7162 renderElementVnode = function (tag, attrs, childs, text, isStatic, isOption, isStyle, isSvg, html, ref, key) {
7163 var vnode = {
7164 tag: tag,
7165 text: text,
7166 html: html,
7167 isStatic: isStatic,
7168 isOption: isOption,
7169 isStyle: isStyle,
7170 isSvg: isSvg,
7171 ref: ref,
7172 key: key,
7173 context: context,
7174 keypath: $scope.$keypath
7175 };
7176
7177 if (attrs) {
7178 $vnode = vnode;
7179 attrs();
7180 $vnode = UNDEFINED;
7181 }
7182
7183 if (childs) {
7184 vnodeStack.push(vnode.children = []);
7185 childs();
7186 pop(vnodeStack);
7187 }
7188
7189 return appendVnode(vnode);
7190 },
7191 renderComponentVnode = function (staticTag, attrs, slots, ref, key, dynamicTag) {
7192 var tag; // 组件支持动态名称
7193
7194 if (dynamicTag) {
7195 var componentName = observer.get(dynamicTag);
7196 {
7197 if (!componentName) {
7198 warn("The dynamic component \"" + dynamicTag + "\" can't be found.");
7199 }
7200 }
7201 tag = componentName;
7202 } else {
7203 tag = staticTag;
7204 }
7205
7206 var vnode = {
7207 tag: tag,
7208 ref: ref,
7209 key: key,
7210 context: context,
7211 keypath: $scope.$keypath,
7212 isComponent: TRUE
7213 };
7214
7215 if (attrs) {
7216 $vnode = vnode;
7217 attrs();
7218 $vnode = UNDEFINED;
7219 }
7220
7221 if (slots) {
7222 var vnodeSlots = {};
7223
7224 for (var name in slots) {
7225 vnodeStack.push([]);
7226 slots[name]();
7227 var vnodes = pop(vnodeStack);
7228 vnodeSlots[name] = vnodes.length ? vnodes : UNDEFINED;
7229 }
7230
7231 vnode.slots = vnodeSlots;
7232 }
7233
7234 return appendVnode(vnode);
7235 },
7236 renderExpressionIdentifier = function (name, lookup, offset, holder, depIgnore, stack) {
7237 var myStack = stack || $stack,
7238 index = myStack.length - 1;
7239
7240 if (offset) {
7241 index -= offset;
7242 }
7243
7244 var result = findValue(myStack, index, name, lookup, depIgnore);
7245 return holder ? result : result.value;
7246 },
7247 renderExpressionMemberKeypath = function (identifier, runtimeKeypath) {
7248 unshift(runtimeKeypath, identifier);
7249 return join(runtimeKeypath, RAW_DOT);
7250 },
7251 renderExpressionMemberLiteral = function (value, staticKeypath, runtimeKeypath, holder$1) {
7252 if (runtimeKeypath !== UNDEFINED) {
7253 staticKeypath = join(runtimeKeypath, RAW_DOT);
7254 }
7255
7256 var match = get(value, staticKeypath);
7257 holder.keypath = UNDEFINED;
7258 holder.value = match ? match.value : UNDEFINED;
7259 return holder$1 ? holder : holder.value;
7260 },
7261 renderExpressionCall = function (fn, args, holder$1) {
7262 holder.keypath = UNDEFINED; // 当 holder 为 true, args 为空时,args 会传入 false
7263
7264 holder.value = execute(fn, context, args || UNDEFINED);
7265 return holder$1 ? holder : holder.value;
7266 },
7267 // <slot name="xx"/>
7268 renderSlot = function (name, defaultRender) {
7269 var vnodeList = last(vnodeStack),
7270 vnodes = context.get(name);
7271
7272 if (vnodeList) {
7273 if (vnodes) {
7274 for (var i = 0, length = vnodes.length; i < length; i++) {
7275 push(vnodeList, vnodes[i]);
7276 vnodes[i].slot = name;
7277 vnodes[i].parent = context;
7278 }
7279 } else if (defaultRender) {
7280 defaultRender();
7281 }
7282 } // 不能重复输出相同名称的 slot
7283
7284
7285 {
7286 if (renderedSlots[name]) {
7287 fatal("The slot \"" + slice(name, SLOT_DATA_PREFIX.length) + "\" can't render more than one time.");
7288 }
7289
7290 renderedSlots[name] = TRUE;
7291 }
7292 },
7293 // {{#partial name}}
7294 // xx
7295 // {{/partial}}
7296 renderPartial = function (name, render) {
7297 localPartials[name] = render;
7298 },
7299 // {{> name}}
7300 renderImport = function (name) {
7301 if (localPartials[name]) {
7302 localPartials[name]();
7303 } else {
7304 var partial = partials[name];
7305
7306 if (partial) {
7307 partial(renderExpressionIdentifier, renderExpressionMemberKeypath, renderExpressionMemberLiteral, renderExpressionCall, renderTextVnode, renderAttributeVnode, renderPropertyVnode, renderLazyVnode, renderTransitionVnode, renderBindingVnode, renderModelVnode, renderEventMethodVnode, renderEventNameVnode, renderDirectiveVnode, renderSpreadVnode, renderCommentVnode, renderElementVnode, renderComponentVnode, renderSlot, renderPartial, renderImport, renderEach, renderRange, renderEqualRange, toString);
7308 } else {
7309 fatal("The partial \"" + name + "\" can't be found.");
7310 }
7311 }
7312 },
7313 eachHandler = function (generate, item, key, keypath, index, length) {
7314 var lastScope = $scope,
7315 lastStack = $stack; // each 会改变 keypath
7316
7317 $scope = {
7318 $keypath: keypath
7319 };
7320 $stack = lastStack.concat($scope); // 避免模板里频繁读取 list.length
7321
7322 if (length !== UNDEFINED) {
7323 $scope.$length = length;
7324 } // 业务层是否写了 expr:index
7325
7326
7327 if (index) {
7328 $scope[index] = key;
7329 } // 无法通过 context.get($keypath + key) 读取到数据的场景
7330 // 必须把 item 写到 scope
7331
7332
7333 if (!keypath) {
7334 $scope.$item = item;
7335 }
7336
7337 generate();
7338 $scope = lastScope;
7339 $stack = lastStack;
7340 },
7341 renderEach = function (generate, holder, index) {
7342 var keypath = holder.keypath,
7343 value = holder.value;
7344
7345 if (array(value)) {
7346 for (var i = 0, length = value.length; i < length; i++) {
7347 eachHandler(generate, value[i], i, keypath ? join$1(keypath, EMPTY_STRING + i) : EMPTY_STRING, index, length);
7348 }
7349 } else if (object(value)) {
7350 for (var key in value) {
7351 eachHandler(generate, value[key], key, keypath ? join$1(keypath, key) : EMPTY_STRING, index);
7352 }
7353 }
7354 },
7355 renderRange = function (generate, from, to, index) {
7356 var count = 0;
7357
7358 if (from < to) {
7359 for (var i = from; i < to; i++) {
7360 eachHandler(generate, i, count++, EMPTY_STRING, index);
7361 }
7362 } else {
7363 for (var i = from; i > to; i--) {
7364 eachHandler(generate, i, count++, EMPTY_STRING, index);
7365 }
7366 }
7367 },
7368 renderEqualRange = function (generate, from, to, index) {
7369 var count = 0;
7370
7371 if (from < to) {
7372 for (var i = from; i <= to; i++) {
7373 eachHandler(generate, i, count++, EMPTY_STRING, index);
7374 }
7375 } else {
7376 for (var i = from; i >= to; i--) {
7377 eachHandler(generate, i, count++, EMPTY_STRING, index);
7378 }
7379 }
7380 };
7381
7382 return template(renderExpressionIdentifier, renderExpressionMemberKeypath, renderExpressionMemberLiteral, renderExpressionCall, renderTextVnode, renderAttributeVnode, renderPropertyVnode, renderLazyVnode, renderTransitionVnode, renderBindingVnode, renderModelVnode, renderEventMethodVnode, renderEventNameVnode, renderDirectiveVnode, renderSpreadVnode, renderCommentVnode, renderElementVnode, renderComponentVnode, renderSlot, renderPartial, renderImport, renderEach, renderRange, renderEqualRange, toString);
7383 }
7384
7385 var guid$1 = 0,
7386 // 这里先写 IE9 支持的接口
7387 innerText = 'textContent',
7388 innerHTML = 'innerHTML',
7389 createEvent = function (event, node) {
7390 return event;
7391 },
7392 findElement = function (selector) {
7393 var node = DOCUMENT.querySelector(selector);
7394
7395 if (node) {
7396 return node;
7397 }
7398 },
7399 addEventListener = function (node, type, listener) {
7400 node.addEventListener(type, listener, FALSE);
7401 },
7402 removeEventListener = function (node, type, listener) {
7403 node.removeEventListener(type, listener, FALSE);
7404 },
7405 // IE9 不支持 classList
7406 addElementClass = function (node, className) {
7407 node.classList.add(className);
7408 },
7409 removeElementClass = function (node, className) {
7410 node.classList.remove(className);
7411 };
7412
7413 {
7414 if (DOCUMENT) {
7415 // 此时 document.body 不一定有值,比如 script 放在 head 里
7416 if (!DOCUMENT.documentElement.classList) {
7417 addElementClass = function (node, className) {
7418 var classes = node.className.split(CHAR_WHITESPACE);
7419
7420 if (!has(classes, className)) {
7421 push(classes, className);
7422 node.className = join(classes, CHAR_WHITESPACE);
7423 }
7424 };
7425
7426 removeElementClass = function (node, className) {
7427 var classes = node.className.split(CHAR_WHITESPACE);
7428
7429 if (remove(classes, className)) {
7430 node.className = join(classes, CHAR_WHITESPACE);
7431 }
7432 };
7433 }
7434 }
7435 }
7436 var CHAR_WHITESPACE = ' ',
7437
7438 /**
7439 * 绑定在 HTML 元素上的事件发射器
7440 */
7441 EMITTER = '$emitter',
7442
7443 /**
7444 * 跟输入事件配套使用的事件
7445 */
7446 COMPOSITION_START = 'compositionstart',
7447
7448 /**
7449 * 跟输入事件配套使用的事件
7450 */
7451 COMPOSITION_END = 'compositionend',
7452 domain = 'http://www.w3.org/',
7453 namespaces = {
7454 svg: domain + '2000/svg'
7455 },
7456 emitterHolders = {},
7457 specialEvents = {};
7458 specialEvents[EVENT_MODEL] = {
7459 on: function on(node, listener) {
7460 var locked = FALSE;
7461
7462 _on(node, COMPOSITION_START, listener[COMPOSITION_START] = function () {
7463 locked = TRUE;
7464 });
7465
7466 _on(node, COMPOSITION_END, listener[COMPOSITION_END] = function (event) {
7467 locked = FALSE;
7468 listener(event);
7469 });
7470
7471 addEventListener(node, EVENT_INPUT, listener[EVENT_INPUT] = function (event) {
7472 if (!locked) {
7473 listener(event);
7474 }
7475 });
7476 },
7477 off: function off(node, listener) {
7478 _off(node, COMPOSITION_START, listener[COMPOSITION_START]);
7479
7480 _off(node, COMPOSITION_END, listener[COMPOSITION_END]);
7481
7482 removeEventListener(node, EVENT_INPUT, listener[EVENT_INPUT]);
7483 listener[COMPOSITION_START] = listener[COMPOSITION_END] = listener[EVENT_INPUT] = UNDEFINED;
7484 }
7485 };
7486
7487 function createElement$2(tag, isSvg) {
7488 return isSvg ? DOCUMENT.createElementNS(namespaces.svg, tag) : DOCUMENT.createElement(tag);
7489 }
7490
7491 function createText$1(text) {
7492 return DOCUMENT.createTextNode(text);
7493 }
7494
7495 function createComment(text) {
7496 return DOCUMENT.createComment(text);
7497 }
7498
7499 function prop(node, name, value) {
7500 if (value !== UNDEFINED) {
7501 set(node, name, value, FALSE);
7502 } else {
7503 var holder = get(node, name);
7504
7505 if (holder) {
7506 return holder.value;
7507 }
7508 }
7509 }
7510
7511 function removeProp(node, name) {
7512 set(node, name, UNDEFINED);
7513 }
7514
7515 function attr(node, name, value) {
7516 if (value !== UNDEFINED) {
7517 node.setAttribute(name, value);
7518 } else {
7519 // value 还可能是 null
7520 var value_1 = node.getAttribute(name);
7521
7522 if (value_1 != NULL) {
7523 return value_1;
7524 }
7525 }
7526 }
7527
7528 function removeAttr(node, name) {
7529 node.removeAttribute(name);
7530 }
7531
7532 function before(parentNode, node, beforeNode) {
7533 parentNode.insertBefore(node, beforeNode);
7534 }
7535
7536 function append(parentNode, node) {
7537 parentNode.appendChild(node);
7538 }
7539
7540 function replace(parentNode, node, oldNode) {
7541 parentNode.replaceChild(node, oldNode);
7542 }
7543
7544 function remove$2(parentNode, node) {
7545 parentNode.removeChild(node);
7546 }
7547
7548 function parent(node) {
7549 var parentNode = node.parentNode;
7550
7551 if (parentNode) {
7552 return parentNode;
7553 }
7554 }
7555
7556 function next(node) {
7557 var nextSibling = node.nextSibling;
7558
7559 if (nextSibling) {
7560 return nextSibling;
7561 }
7562 }
7563
7564 var find = findElement;
7565
7566 function tag(node) {
7567 if (node.nodeType === 1) {
7568 return lower(node.tagName);
7569 }
7570 }
7571
7572 function text(node, text, isStyle, isOption) {
7573 if (text !== UNDEFINED) {
7574 {
7575 node[innerText] = text;
7576 }
7577 } else {
7578 return node[innerText];
7579 }
7580 }
7581
7582 function html(node, html, isStyle, isOption) {
7583 if (html !== UNDEFINED) {
7584 {
7585 node[innerHTML] = html;
7586 }
7587 } else {
7588 return node[innerHTML];
7589 }
7590 }
7591
7592 var addClass = addElementClass;
7593 var removeClass = removeElementClass;
7594
7595 function _on(node, type, listener, context) {
7596 var emitterKey = node[EMITTER] || (node[EMITTER] = ++guid$1),
7597 emitter = emitterHolders[emitterKey] || (emitterHolders[emitterKey] = new Emitter()),
7598 nativeListeners = emitter.nativeListeners || (emitter.nativeListeners = {}); // 一个元素,相同的事件,只注册一个 native listener
7599
7600 if (!nativeListeners[type]) {
7601 // 特殊事件
7602 var special = specialEvents[type],
7603 // 唯一的原生监听器
7604 nativeListener = function (event) {
7605 var customEvent = event instanceof CustomEvent ? event : new CustomEvent(event.type, createEvent(event, node));
7606
7607 if (customEvent.type !== type) {
7608 customEvent.type = type;
7609 }
7610
7611 emitter.fire(type, [customEvent]);
7612 };
7613
7614 nativeListeners[type] = nativeListener;
7615
7616 if (special) {
7617 special.on(node, nativeListener);
7618 } else {
7619 addEventListener(node, type, nativeListener);
7620 }
7621 }
7622
7623 emitter.on(type, {
7624 fn: listener,
7625 ctx: context
7626 });
7627 }
7628
7629 function _off(node, type, listener) {
7630 var emitterKey = node[EMITTER],
7631 emitter = emitterHolders[emitterKey],
7632 listeners = emitter.listeners,
7633 nativeListeners = emitter.nativeListeners; // emitter 会根据 type 和 listener 参数进行适当的删除
7634
7635 emitter.off(type, listener); // 如果注册的 type 事件都解绑了,则去掉原生监听器
7636
7637 if (nativeListeners && !emitter.has(type)) {
7638 var special = specialEvents[type],
7639 nativeListener = nativeListeners[type];
7640
7641 if (special) {
7642 special.off(node, nativeListener);
7643 } else {
7644 removeEventListener(node, type, nativeListener);
7645 }
7646
7647 delete nativeListeners[type];
7648 }
7649
7650 if (emitterHolders[emitterKey] && falsy$2(listeners)) {
7651 node[EMITTER] = UNDEFINED;
7652 delete emitterHolders[emitterKey];
7653 }
7654 }
7655
7656 function addSpecialEvent(type, hooks) {
7657 {
7658 if (specialEvents[type]) {
7659 fatal("The special event \"" + type + "\" already exists.");
7660 }
7661
7662 info("The special event \"" + type + "\" is added successfully.");
7663 }
7664 specialEvents[type] = hooks;
7665 }
7666
7667 var domApi =
7668 /*#__PURE__*/
7669 {
7670 createElement: createElement$2,
7671 createText: createText$1,
7672 createComment: createComment,
7673 prop: prop,
7674 removeProp: removeProp,
7675 attr: attr,
7676 removeAttr: removeAttr,
7677 before: before,
7678 append: append,
7679 replace: replace,
7680 remove: remove$2,
7681 parent: parent,
7682 next: next,
7683 find: find,
7684 tag: tag,
7685 text: text,
7686 html: html,
7687 addClass: addClass,
7688 removeClass: removeClass,
7689 on: _on,
7690 off: _off,
7691 addSpecialEvent: addSpecialEvent
7692 };
7693 /**
7694 * 计算属性
7695 *
7696 * 可配置 cache、deps、get、set 等
7697 */
7698
7699 var Computed =
7700 /** @class */
7701 function () {
7702 function Computed(keypath, sync, cache, deps, observer, getter, setter) {
7703 var instance = this;
7704 instance.keypath = keypath;
7705 instance.cache = cache;
7706 instance.deps = deps;
7707 instance.context = observer.context;
7708 instance.observer = observer;
7709 instance.getter = getter;
7710 instance.setter = setter;
7711 instance.unique = {};
7712
7713 instance.watcher = function ($0, $1, $2) {
7714 // 计算属性的依赖变了会走进这里
7715 var oldValue = instance.value,
7716 newValue = instance.get(TRUE);
7717
7718 if (newValue !== oldValue) {
7719 observer.diff(keypath, newValue, oldValue);
7720 }
7721 };
7722
7723 instance.watcherOptions = {
7724 sync: sync,
7725 watcher: instance.watcher
7726 };
7727
7728 if (instance.fixed = !falsy(deps)) {
7729 each(deps, function (dep) {
7730 observer.watch(dep, instance.watcherOptions);
7731 });
7732 }
7733 }
7734 /**
7735 * 读取计算属性的值
7736 *
7737 * @param force 是否强制刷新缓存
7738 */
7739
7740
7741 Computed.prototype.get = function (force) {
7742 var instance = this,
7743 getter = instance.getter,
7744 context = instance.context; // 禁用缓存
7745
7746 if (!instance.cache) {
7747 instance.value = execute(getter, context);
7748 } // 减少取值频率,尤其是处理复杂的计算规则
7749 else if (force || !has$2(instance, RAW_VALUE)) {
7750 // 如果写死了依赖,则不需要收集依赖
7751 if (instance.fixed) {
7752 instance.value = execute(getter, context);
7753 } else {
7754 // 清空上次收集的依赖
7755 instance.unbind(); // 开始收集新的依赖
7756
7757 var lastComputed = Computed.current;
7758 Computed.current = instance;
7759 instance.value = execute(getter, context); // 绑定新的依赖
7760
7761 instance.bind();
7762 Computed.current = lastComputed;
7763 }
7764 }
7765
7766 return instance.value;
7767 };
7768
7769 Computed.prototype.set = function (value) {
7770 var _a = this,
7771 setter = _a.setter,
7772 context = _a.context;
7773
7774 if (setter) {
7775 setter.call(context, value);
7776 }
7777 };
7778 /**
7779 * 添加依赖
7780 *
7781 * 这里只是为了保证依赖唯一,最后由 bind() 实现绑定
7782 *
7783 * @param dep
7784 */
7785
7786
7787 Computed.prototype.add = function (dep) {
7788 this.unique[dep] = TRUE;
7789 };
7790 /**
7791 * 绑定依赖
7792 */
7793
7794
7795 Computed.prototype.bind = function () {
7796 var _a = this,
7797 unique = _a.unique,
7798 deps = _a.deps,
7799 observer = _a.observer,
7800 watcherOptions = _a.watcherOptions;
7801
7802 each$2(unique, function (_, dep) {
7803 push(deps, dep);
7804 observer.watch(dep, watcherOptions);
7805 }); // 用完重置
7806 // 方便下次收集依赖
7807
7808 this.unique = {};
7809 };
7810 /**
7811 * 解绑依赖
7812 */
7813
7814
7815 Computed.prototype.unbind = function () {
7816 var _a = this,
7817 deps = _a.deps,
7818 observer = _a.observer,
7819 watcher = _a.watcher;
7820
7821 each(deps, function (dep) {
7822 observer.unwatch(dep, watcher);
7823 }, TRUE);
7824 deps.length = 0;
7825 };
7826
7827 return Computed;
7828 }();
7829
7830 function readValue(source, keypath) {
7831 if (source == NULL || keypath === EMPTY_STRING) {
7832 return source;
7833 }
7834
7835 var result = get(source, keypath);
7836
7837 if (result) {
7838 return result.value;
7839 }
7840 }
7841 /**
7842 * 对比新旧数组
7843 *
7844 * @param newValue
7845 * @param oldValue
7846 * @param callback
7847 */
7848
7849
7850 function diffString(newValue, oldValue, callback) {
7851 var newIsString = string(newValue),
7852 oldIsString = string(oldValue);
7853
7854 if (newIsString || oldIsString) {
7855 callback(RAW_LENGTH, newIsString ? newValue.length : UNDEFINED, oldIsString ? oldValue.length : UNDEFINED);
7856 return TRUE;
7857 }
7858 }
7859 /**
7860 * 对比新旧数组
7861 *
7862 * @param newValue
7863 * @param oldValue
7864 * @param callback
7865 */
7866
7867
7868 function diffArray(newValue, oldValue, callback) {
7869 var newIsArray = array(newValue),
7870 oldIsArray = array(oldValue);
7871
7872 if (newIsArray || oldIsArray) {
7873 var newLength = newIsArray ? newValue.length : UNDEFINED,
7874 oldLength = oldIsArray ? oldValue.length : UNDEFINED;
7875 callback(RAW_LENGTH, newLength, oldLength);
7876
7877 for (var i = 0, length = Math.max(newLength || 0, oldLength || 0); i < length; i++) {
7878 callback('' + i, newValue ? newValue[i] : UNDEFINED, oldValue ? oldValue[i] : UNDEFINED);
7879 }
7880
7881 return TRUE;
7882 }
7883 }
7884 /**
7885 * 对比新旧对象
7886 *
7887 * @param newValue
7888 * @param oldValue
7889 * @param callback
7890 */
7891
7892
7893 function diffObject(newValue, oldValue, callback) {
7894 var newIsObject = object(newValue),
7895 oldIsObject = object(oldValue);
7896
7897 if (newIsObject || oldIsObject) {
7898 newValue = newIsObject ? newValue : EMPTY_OBJECT;
7899 oldValue = oldIsObject ? oldValue : EMPTY_OBJECT;
7900
7901 if (newIsObject) {
7902 each$2(newValue, function (value, key) {
7903 if (value !== oldValue[key]) {
7904 callback(key, value, oldValue[key]);
7905 }
7906 });
7907 }
7908
7909 if (oldIsObject) {
7910 each$2(oldValue, function (value, key) {
7911 if (value !== newValue[key]) {
7912 callback(key, newValue[key], value);
7913 }
7914 });
7915 }
7916 }
7917 }
7918
7919 function diffRecursion(keypath, newValue, oldValue, watchFuzzyKeypaths, callback) {
7920 var diff = function (subKeypath, subNewValue, subOldValue) {
7921 if (subNewValue !== subOldValue) {
7922 var newKeypath_1 = join$1(keypath, subKeypath);
7923 each(watchFuzzyKeypaths, function (fuzzyKeypath) {
7924 if (matchFuzzy(newKeypath_1, fuzzyKeypath) !== UNDEFINED) {
7925 callback(fuzzyKeypath, newKeypath_1, subNewValue, subOldValue);
7926 }
7927 });
7928 diffRecursion(newKeypath_1, subNewValue, subOldValue, watchFuzzyKeypaths, callback);
7929 }
7930 };
7931
7932 diffString(newValue, oldValue, diff) || diffArray(newValue, oldValue, diff) || diffObject(newValue, oldValue, diff);
7933 }
7934
7935 function diffWatcher(keypath, newValue, oldValue, watcher, isRecursive, callback) {
7936 var fuzzyKeypaths; // 遍历监听的 keypath,如果未被监听,则无需触发任何事件
7937
7938 each$2(watcher, function (_, watchKeypath) {
7939 // 模糊监听,如 users.*.name
7940 if (isFuzzy(watchKeypath)) {
7941 // 如果当前修改的是 users.0 整个对象
7942 // users.0 和 users.*.name 无法匹配
7943 // 此时要知道设置 users.0 到底会不会改变 users.*.name 需要靠递归了
7944 // 如果匹配,则无需递归
7945 if (matchFuzzy(keypath, watchKeypath) !== UNDEFINED) {
7946 callback(watchKeypath, keypath, newValue, oldValue);
7947 } else if (isRecursive) {
7948 if (fuzzyKeypaths) {
7949 push(fuzzyKeypaths, watchKeypath);
7950 } else {
7951 fuzzyKeypaths = [watchKeypath];
7952 }
7953 }
7954
7955 return;
7956 } // 不是模糊匹配,直接靠前缀匹配
7957 // 比如监听的是 users.0.name,此时修改 users.0,则直接读出子属性值,判断是否相等
7958
7959
7960 var length = match(watchKeypath, keypath);
7961
7962 if (length >= 0) {
7963 var subKeypath = slice(watchKeypath, length),
7964 subNewValue = readValue(newValue, subKeypath),
7965 subOldValue = readValue(oldValue, subKeypath);
7966
7967 if (subNewValue !== subOldValue) {
7968 callback(watchKeypath, watchKeypath, subNewValue, subOldValue);
7969 }
7970 }
7971 }); // 存在模糊匹配的需求
7972 // 必须对数据进行递归
7973 // 性能确实会慢一些,但是很好用啊,几乎可以监听所有的数据
7974
7975 if (fuzzyKeypaths) {
7976 diffRecursion(keypath, newValue, oldValue, fuzzyKeypaths, callback);
7977 }
7978 }
7979 /**
7980 * 触发异步变化时,用此函数过滤下,哪些 listener 应该执行
7981 *
7982 * @param item
7983 * @param data
7984 */
7985
7986
7987 function filterWatcher(_, args, options) {
7988 if (options.count && args) {
7989 // 采用计数器的原因是,同一个 options 可能执行多次
7990 // 比如监听 user.*,如果同批次修改了 user.name 和 user.age
7991 // 这个监听器会调用多次,如果第一次执行就把 count 干掉了,第二次就无法执行了
7992 options.count--; // 新旧值不相等
7993
7994 return args[0] !== args[1];
7995 }
7996 } // 避免频繁创建对象
7997
7998
7999 var optionsHolder = {
8000 watcher: EMPTY_FUNCTION
8001 };
8002 /**
8003 * 格式化 watch options
8004 *
8005 * @param options
8006 */
8007
8008 function formatWatcherOptions(options, immediate) {
8009 if (func(options)) {
8010 optionsHolder.watcher = options;
8011 optionsHolder.immediate = immediate === TRUE;
8012 return optionsHolder;
8013 }
8014
8015 if (options && options.watcher) {
8016 return options;
8017 }
8018
8019 {
8020 fatal("watcher should be a function or object.");
8021 }
8022 }
8023 /**
8024 * 观察者有两种观察模式:
8025 *
8026 * 1. 同步监听
8027 * 2. 异步监听
8028 *
8029 * 对于`计算属性`这种需要实时变化的对象,即它的依赖变了,它需要立即跟着变,否则会出现不一致的问题
8030 * 这种属于同步监听
8031 *
8032 * 对于外部调用 observer.watch('keypath', listener),属于异步监听,它只关心是否变了,而不关心是否是立即触发的
8033 */
8034
8035
8036 var Observer =
8037 /** @class */
8038 function () {
8039 function Observer(data, context) {
8040 var instance = this;
8041 instance.data = data || {};
8042 instance.context = context || instance;
8043 instance.nextTask = new NextTask();
8044 instance.syncEmitter = new Emitter();
8045 instance.asyncEmitter = new Emitter();
8046 instance.asyncChanges = {};
8047 }
8048 /**
8049 * 获取数据
8050 *
8051 * @param keypath
8052 * @param defaultValue
8053 * @param depIgnore
8054 * @return
8055 */
8056
8057
8058 Observer.prototype.get = function (keypath, defaultValue, depIgnore) {
8059 var instance = this,
8060 currentComputed = Computed.current,
8061 data = instance.data,
8062 computed = instance.computed; // 传入 '' 获取整个 data
8063
8064 if (keypath === EMPTY_STRING) {
8065 return data;
8066 } // 调用 get 时,外面想要获取依赖必须设置是谁在收集依赖
8067 // 如果没设置,则跳过依赖收集
8068
8069
8070 if (currentComputed && !depIgnore) {
8071 currentComputed.add(keypath);
8072 }
8073
8074 var result;
8075
8076 if (computed) {
8077 result = get(computed, keypath);
8078 }
8079
8080 if (!result) {
8081 result = get(data, keypath);
8082 }
8083
8084 return result ? result.value : defaultValue;
8085 };
8086 /**
8087 * 更新数据
8088 *
8089 * @param keypath
8090 * @param value
8091 */
8092
8093
8094 Observer.prototype.set = function (keypath, value) {
8095 var instance = this,
8096 data = instance.data,
8097 computed = instance.computed,
8098 setValue = function (newValue, keypath) {
8099 var oldValue = instance.get(keypath);
8100
8101 if (newValue === oldValue) {
8102 return;
8103 }
8104
8105 var next;
8106 each$1(keypath, function (key, index, lastIndex) {
8107 if (index === 0) {
8108 if (computed && computed[key]) {
8109 if (lastIndex === 0) {
8110 computed[key].set(newValue);
8111 } else {
8112 // 这里 next 可能为空
8113 next = computed[key].get();
8114 }
8115 } else {
8116 if (lastIndex === 0) {
8117 data[key] = newValue;
8118 } else {
8119 next = data[key] || (data[key] = {});
8120 }
8121 }
8122
8123 return;
8124 }
8125
8126 if (next) {
8127 if (index === lastIndex) {
8128 next[key] = newValue;
8129 } else {
8130 next = next[key] || (next[key] = {});
8131 }
8132 }
8133 });
8134 instance.diff(keypath, newValue, oldValue);
8135 };
8136
8137 if (string(keypath)) {
8138 setValue(value, keypath);
8139 } else if (object(keypath)) {
8140 each$2(keypath, setValue);
8141 }
8142 };
8143 /**
8144 * 同步调用的 diff,用于触发 syncEmitter,以及唤醒 asyncEmitter
8145 *
8146 * @param keypath
8147 * @param newValue
8148 * @param oldValue
8149 */
8150
8151
8152 Observer.prototype.diff = function (keypath, newValue, oldValue) {
8153 var instance = this,
8154 syncEmitter = instance.syncEmitter,
8155 asyncEmitter = instance.asyncEmitter,
8156 asyncChanges = instance.asyncChanges,
8157
8158 /**
8159 * 我们认为 $ 开头的变量是不可递归的
8160 * 比如浏览器中常见的 $0 表示当前选中元素
8161 * DOM 元素是不能递归的
8162 */
8163 isRecursive = codeAt(keypath) !== 36;
8164 diffWatcher(keypath, newValue, oldValue, syncEmitter.listeners, isRecursive, function (watchKeypath, keypath, newValue, oldValue) {
8165 syncEmitter.fire(watchKeypath, [newValue, oldValue, keypath]);
8166 });
8167 /**
8168 * 此处有坑,举个例子
8169 *
8170 * observer.watch('a', function () {})
8171 *
8172 * observer.set('a', 1)
8173 *
8174 * observer.watch('a', function () {})
8175 *
8176 * 这里,第一个 watcher 应该触发,但第二个不应该,因为它绑定监听时,值已经是最新的了
8177 */
8178
8179 diffWatcher(keypath, newValue, oldValue, asyncEmitter.listeners, isRecursive, function (watchKeypath, keypath, newValue, oldValue) {
8180 each(asyncEmitter.listeners[watchKeypath], function (item) {
8181 item.count++;
8182 });
8183 var keypaths = (asyncChanges[keypath] || (asyncChanges[keypath] = {
8184 value: oldValue,
8185 keypaths: []
8186 })).keypaths;
8187
8188 if (!has(keypaths, watchKeypath)) {
8189 push(keypaths, watchKeypath);
8190 }
8191
8192 if (!instance.pending) {
8193 instance.pending = TRUE;
8194 instance.nextTask.append(function () {
8195 if (instance.pending) {
8196 instance.pending = UNDEFINED;
8197 instance.diffAsync();
8198 }
8199 });
8200 }
8201 });
8202 };
8203 /**
8204 * 异步触发的 diff
8205 */
8206
8207
8208 Observer.prototype.diffAsync = function () {
8209 var instance = this,
8210 asyncEmitter = instance.asyncEmitter,
8211 asyncChanges = instance.asyncChanges;
8212 instance.asyncChanges = {};
8213 each$2(asyncChanges, function (change, keypath) {
8214 var args = [instance.get(keypath), change.value, keypath]; // 不能在这判断新旧值是否相同,相同就不 fire
8215 // 因为前面标记了 count,在这中断会导致 count 无法清除
8216
8217 each(change.keypaths, function (watchKeypath) {
8218 asyncEmitter.fire(watchKeypath, args, filterWatcher);
8219 });
8220 });
8221 };
8222 /**
8223 * 添加计算属性
8224 *
8225 * @param keypath
8226 * @param computed
8227 */
8228
8229
8230 Observer.prototype.addComputed = function (keypath, options) {
8231 var cache = TRUE,
8232 sync = TRUE,
8233 deps = [],
8234 getter,
8235 setter;
8236
8237 if (func(options)) {
8238 getter = options;
8239 } else if (object(options)) {
8240 var computedOptions = options;
8241
8242 if (boolean(computedOptions.cache)) {
8243 cache = computedOptions.cache;
8244 }
8245
8246 if (boolean(computedOptions.sync)) {
8247 sync = computedOptions.sync;
8248 } // 因为可能会修改 deps,所以这里创建一个新的 deps,避免影响外部传入的 deps
8249
8250
8251 if (array(computedOptions.deps)) {
8252 deps = copy(computedOptions.deps);
8253 }
8254
8255 if (func(computedOptions.get)) {
8256 getter = computedOptions.get;
8257 }
8258
8259 if (func(computedOptions.set)) {
8260 setter = computedOptions.set;
8261 }
8262 }
8263
8264 if (getter) {
8265 var instance = this,
8266 computed = new Computed(keypath, sync, cache, deps, instance, getter, setter);
8267
8268 if (!instance.computed) {
8269 instance.computed = {};
8270 }
8271
8272 instance.computed[keypath] = computed;
8273 return computed;
8274 }
8275 };
8276 /**
8277 * 移除计算属性
8278 *
8279 * @param keypath
8280 */
8281
8282
8283 Observer.prototype.removeComputed = function (keypath) {
8284 var instance = this,
8285 computed = instance.computed;
8286
8287 if (computed && has$2(computed, keypath)) {
8288 delete computed[keypath];
8289 }
8290 };
8291 /**
8292 * 监听数据变化
8293 *
8294 * @param keypath
8295 * @param watcher
8296 * @param immediate
8297 */
8298
8299
8300 Observer.prototype.watch = function (keypath, watcher, immediate) {
8301 var instance = this,
8302 context = instance.context,
8303 syncEmitter = instance.syncEmitter,
8304 asyncEmitter = instance.asyncEmitter,
8305 bind = function (keypath, options) {
8306 var emitter = options.sync ? syncEmitter : asyncEmitter,
8307 // formatWatcherOptions 保证了 options.watcher 一定存在
8308 listener = {
8309 fn: options.watcher,
8310 ctx: context,
8311 count: 0
8312 };
8313
8314 if (options.once) {
8315 listener.max = 1;
8316 }
8317
8318 emitter.on(keypath, listener);
8319
8320 if (options.immediate) {
8321 execute(options.watcher, context, [instance.get(keypath), UNDEFINED, keypath]);
8322 }
8323 };
8324
8325 if (string(keypath)) {
8326 bind(keypath, formatWatcherOptions(watcher, immediate));
8327 return;
8328 }
8329
8330 each$2(keypath, function (options, keypath) {
8331 bind(keypath, formatWatcherOptions(options));
8332 });
8333 };
8334 /**
8335 * 取消监听数据变化
8336 *
8337 * @param keypath
8338 * @param watcher
8339 */
8340
8341
8342 Observer.prototype.unwatch = function (keypath, watcher) {
8343 this.syncEmitter.off(keypath, watcher);
8344 this.asyncEmitter.off(keypath, watcher);
8345 };
8346 /**
8347 * 取反 keypath 对应的数据
8348 *
8349 * 不管 keypath 对应的数据是什么类型,操作后都是布尔型
8350 *
8351 * @param keypath
8352 * @return 取反后的布尔值
8353 */
8354
8355
8356 Observer.prototype.toggle = function (keypath) {
8357 var value = !this.get(keypath);
8358 this.set(keypath, value);
8359 return value;
8360 };
8361 /**
8362 * 递增 keypath 对应的数据
8363 *
8364 * 注意,最好是整型的加法,如果涉及浮点型,不保证计算正确
8365 *
8366 * @param keypath 值必须能转型成数字,如果不能,则默认从 0 开始递增
8367 * @param step 步进值,默认是 1
8368 * @param max 可以递增到的最大值,默认不限制
8369 */
8370
8371
8372 Observer.prototype.increase = function (keypath, step, max) {
8373 var value = toNumber(this.get(keypath), 0) + (step || 1);
8374
8375 if (!number(max) || value <= max) {
8376 this.set(keypath, value);
8377 return value;
8378 }
8379 };
8380 /**
8381 * 递减 keypath 对应的数据
8382 *
8383 * 注意,最好是整型的减法,如果涉及浮点型,不保证计算正确
8384 *
8385 * @param keypath 值必须能转型成数字,如果不能,则默认从 0 开始递减
8386 * @param step 步进值,默认是 1
8387 * @param min 可以递减到的最小值,默认不限制
8388 */
8389
8390
8391 Observer.prototype.decrease = function (keypath, step, min) {
8392 var value = toNumber(this.get(keypath), 0) - (step || 1);
8393
8394 if (!number(min) || value >= min) {
8395 this.set(keypath, value);
8396 return value;
8397 }
8398 };
8399 /**
8400 * 在数组指定位置插入元素
8401 *
8402 * @param keypath
8403 * @param item
8404 * @param index
8405 */
8406
8407
8408 Observer.prototype.insert = function (keypath, item, index) {
8409 var list = this.get(keypath);
8410 list = !array(list) ? [] : copy(list);
8411 var length = list.length;
8412
8413 if (index === TRUE || index === length) {
8414 list.push(item);
8415 } else if (index === FALSE || index === 0) {
8416 list.unshift(item);
8417 } else if (index > 0 && index < length) {
8418 list.splice(index, 0, item);
8419 } else {
8420 return;
8421 }
8422
8423 this.set(keypath, list);
8424 return TRUE;
8425 };
8426 /**
8427 * 在数组尾部添加元素
8428 *
8429 * @param keypath
8430 * @param item
8431 */
8432
8433
8434 Observer.prototype.append = function (keypath, item) {
8435 return this.insert(keypath, item, TRUE);
8436 };
8437 /**
8438 * 在数组首部添加元素
8439 *
8440 * @param keypath
8441 * @param item
8442 */
8443
8444
8445 Observer.prototype.prepend = function (keypath, item) {
8446 return this.insert(keypath, item, FALSE);
8447 };
8448 /**
8449 * 通过索引移除数组中的元素
8450 *
8451 * @param keypath
8452 * @param index
8453 */
8454
8455
8456 Observer.prototype.removeAt = function (keypath, index) {
8457 var list = this.get(keypath);
8458
8459 if (array(list) && index >= 0 && index < list.length) {
8460 list = copy(list);
8461 list.splice(index, 1);
8462 this.set(keypath, list);
8463 return TRUE;
8464 }
8465 };
8466 /**
8467 * 直接移除数组中的元素
8468 *
8469 * @param keypath
8470 * @param item
8471 */
8472
8473
8474 Observer.prototype.remove = function (keypath, item) {
8475 var list = this.get(keypath);
8476
8477 if (array(list)) {
8478 list = copy(list);
8479
8480 if (remove(list, item)) {
8481 this.set(keypath, list);
8482 return TRUE;
8483 }
8484 }
8485 };
8486 /**
8487 * 拷贝任意数据,支持深拷贝
8488 *
8489 * @param data
8490 * @param deep
8491 */
8492
8493
8494 Observer.prototype.copy = function (data, deep) {
8495 return copy(data, deep);
8496 };
8497 /**
8498 * 销毁
8499 */
8500
8501
8502 Observer.prototype.destroy = function () {
8503 var instance = this;
8504 instance.syncEmitter.off();
8505 instance.asyncEmitter.off();
8506 instance.nextTask.clear();
8507 clear(instance);
8508 };
8509
8510 return Observer;
8511 }();
8512 /**
8513 * 节流调用
8514 *
8515 * @param fn 需要节制调用的函数
8516 * @param delay 调用的时间间隔,单位毫秒
8517 * @param immediate 是否立即触发
8518 * @return 节流函数
8519 */
8520
8521
8522 function debounce(fn, delay, immediate) {
8523 var timer;
8524 return function () {
8525 if (!timer) {
8526 var args_1 = toArray(arguments);
8527
8528 if (immediate) {
8529 execute(fn, UNDEFINED, args_1);
8530 }
8531
8532 timer = setTimeout(function () {
8533 timer = UNDEFINED;
8534
8535 if (!immediate) {
8536 execute(fn, UNDEFINED, args_1);
8537 }
8538 }, delay);
8539 }
8540 };
8541 }
8542
8543 function bind(node, directive, vnode) {
8544 var key = directive.key,
8545 name = directive.name,
8546 modifier = directive.modifier,
8547 handler = directive.handler,
8548 lazy = vnode.lazy;
8549
8550 if (!handler) {
8551 return;
8552 }
8553
8554 if (lazy) {
8555 var value = lazy[name] || lazy[EMPTY_STRING];
8556
8557 if (value === TRUE) {
8558 name = EVENT_CHANGE;
8559 } else if (value > 0) {
8560 handler = debounce(handler, value, // 避免连续多次点击,主要用于提交表单场景
8561 // 移动端的 tap 事件可自行在业务层打补丁实现
8562 name === EVENT_CLICK || name === EVENT_TAP);
8563 }
8564 }
8565
8566 var element;
8567
8568 if (vnode.isComponent) {
8569 var component_1 = node;
8570
8571 if (modifier === MODIFER_NATIVE) {
8572 element = component_1.$el;
8573
8574 _on(element, name, handler);
8575
8576 vnode.data[key] = function () {
8577 _off(element, name, handler);
8578 };
8579 } else {
8580 // 还原命名空间
8581 if (modifier) {
8582 name += RAW_DOT + modifier;
8583 }
8584
8585 component_1.on(name, handler);
8586
8587 vnode.data[key] = function () {
8588 component_1.off(name, handler);
8589 };
8590 }
8591 } else {
8592 element = node;
8593
8594 _on(element, name, handler);
8595
8596 vnode.data[key] = function () {
8597 _off(element, name, handler);
8598 };
8599 }
8600 }
8601
8602 function unbind(node, directive, vnode) {
8603 execute(vnode.data[directive.key]);
8604 }
8605
8606 var event =
8607 /*#__PURE__*/
8608 {
8609 bind: bind,
8610 unbind: unbind
8611 };
8612
8613 function debounceIfNeeded(fn, lazy) {
8614 // 应用 lazy
8615 return lazy && lazy !== TRUE ? debounce(fn, lazy) : fn;
8616 }
8617
8618 var inputControl = {
8619 set: function set(node, value) {
8620 node.value = toString(value);
8621 },
8622 sync: function sync(node, keypath, context) {
8623 context.set(keypath, node.value);
8624 },
8625 name: RAW_VALUE
8626 },
8627 radioControl = {
8628 set: function set(node, value) {
8629 node.checked = node.value === toString(value);
8630 },
8631 sync: function sync(node, keypath, context) {
8632 if (node.checked) {
8633 context.set(keypath, node.value);
8634 }
8635 },
8636 name: 'checked'
8637 },
8638 checkboxControl = {
8639 set: function set(node, value) {
8640 node.checked = array(value) ? has(value, node.value, FALSE) : !!value;
8641 },
8642 sync: function sync(node, keypath, context) {
8643 var value = context.get(keypath);
8644
8645 if (array(value)) {
8646 if (node.checked) {
8647 context.append(keypath, node.value);
8648 } else {
8649 context.removeAt(keypath, indexOf(value, node.value, FALSE));
8650 }
8651 } else {
8652 context.set(keypath, node.checked);
8653 }
8654 },
8655 name: 'checked'
8656 },
8657 selectControl = {
8658 set: function set(node, value) {
8659 each(toArray(node.options), node.multiple ? function (option) {
8660 option.selected = has(value, option.value, FALSE);
8661 } : function (option, index) {
8662 if (option.value == value) {
8663 node.selectedIndex = index;
8664 return FALSE;
8665 }
8666 });
8667 },
8668 sync: function sync(node, keypath, context) {
8669 var options = node.options;
8670
8671 if (node.multiple) {
8672 var values_1 = [];
8673 each(toArray(options), function (option) {
8674 if (option.selected) {
8675 push(values_1, option.value);
8676 }
8677 });
8678 context.set(keypath, values_1);
8679 } else {
8680 context.set(keypath, options[node.selectedIndex].value);
8681 }
8682 },
8683 name: RAW_VALUE
8684 };
8685 var once = TRUE;
8686
8687 function bind$1(node, directive, vnode) {
8688 var context = vnode.context,
8689 lazy = vnode.lazy,
8690 isComponent = vnode.isComponent,
8691 dataBinding = directive.modifier,
8692 lazyValue = lazy && (lazy[DIRECTIVE_MODEL] || lazy[EMPTY_STRING]),
8693 _set2,
8694 unbind;
8695
8696 if (isComponent) {
8697 var component_1 = node,
8698 viewBinding_1 = component_1.$model,
8699 viewSyncing_1 = debounceIfNeeded(function (newValue) {
8700 context.set(dataBinding, newValue);
8701 }, lazyValue);
8702
8703 _set2 = function set(newValue) {
8704 if (_set2) {
8705 component_1.set(viewBinding_1, newValue);
8706 }
8707 };
8708
8709 unbind = function () {
8710 component_1.unwatch(viewBinding_1, viewSyncing_1);
8711 };
8712
8713 component_1.watch(viewBinding_1, viewSyncing_1);
8714 } else {
8715 var element_1 = node,
8716 control_1 = vnode.tag === 'select' ? selectControl : inputControl,
8717 // checkbox,radio,select 监听的是 change 事件
8718 eventName_1 = EVENT_CHANGE;
8719
8720 if (control_1 === inputControl) {
8721 var type = node.type;
8722
8723 if (type === 'radio') {
8724 control_1 = radioControl;
8725 } else if (type === 'checkbox') {
8726 control_1 = checkboxControl;
8727 } // 如果是输入框,则切换成 model 事件
8728 // model 事件是个 yox-dom 实现的特殊事件
8729 // 不会在输入法组合文字过程中得到触发事件
8730 else if (lazyValue !== TRUE) {
8731 eventName_1 = EVENT_MODEL;
8732 }
8733 }
8734
8735 _set2 = function _set(newValue) {
8736 if (_set2) {
8737 control_1.set(element_1, newValue);
8738 }
8739 };
8740
8741 var sync_1 = debounceIfNeeded(function () {
8742 control_1.sync(element_1, dataBinding, context);
8743 }, lazyValue);
8744
8745 unbind = function () {
8746 _off(element_1, eventName_1, sync_1);
8747 };
8748
8749 _on(element_1, eventName_1, sync_1);
8750
8751 control_1.set(element_1, directive.value);
8752 } // 监听数据,修改界面
8753
8754
8755 context.watch(dataBinding, _set2);
8756
8757 vnode.data[directive.key] = function () {
8758 context.unwatch(dataBinding, _set2);
8759 _set2 = UNDEFINED;
8760 unbind();
8761 };
8762 }
8763
8764 function unbind$1(node, directive, vnode) {
8765 execute(vnode.data[directive.key]);
8766 }
8767
8768 var model =
8769 /*#__PURE__*/
8770 {
8771 once: once,
8772 bind: bind$1,
8773 unbind: unbind$1
8774 };
8775 var once$1 = TRUE;
8776
8777 function bind$2(node, directive, vnode) {
8778 // binding 可能是模糊匹配
8779 // 比如延展属性 {{...obj}},这里 binding 会是 `obj.*`
8780 var binding = directive.modifier,
8781 // 提前判断好是否是模糊匹配,避免 watcher 频繁执行判断逻辑
8782 isFuzzy$1 = isFuzzy(binding),
8783 _watcher = function watcher(newValue, _, keypath) {
8784 if (_watcher) {
8785 var name = isFuzzy$1 ? matchFuzzy(keypath, binding) : directive.name;
8786
8787 if (vnode.isComponent) {
8788 var component = node;
8789 component.checkProp(name, newValue);
8790 component.set(name, newValue);
8791 } else {
8792 var element = node;
8793
8794 if (directive.hint !== UNDEFINED) {
8795 prop(element, name, newValue);
8796 } else {
8797 attr(element, name, newValue);
8798 }
8799 }
8800 }
8801 };
8802
8803 vnode.context.watch(binding, _watcher);
8804
8805 vnode.data[directive.key] = function () {
8806 vnode.context.unwatch(binding, _watcher);
8807 _watcher = UNDEFINED;
8808 };
8809 }
8810
8811 function unbind$2(node, directive, vnode) {
8812 execute(vnode.data[directive.key]);
8813 }
8814
8815 var binding =
8816 /*#__PURE__*/
8817 {
8818 once: once$1,
8819 bind: bind$2,
8820 unbind: unbind$2
8821 };
8822 var globalDirectives = {},
8823 globalTransitions = {},
8824 globalComponents = {},
8825 globalPartials = {},
8826 globalFilters = {},
8827 compileCache = {},
8828 TEMPLATE_COMPUTED = '$$',
8829 selectorPattern = /^[#.][-\w+]+$/;
8830
8831 var Yox =
8832 /** @class */
8833 function () {
8834 function Yox(options) {
8835 var instance = this,
8836 $options = options || EMPTY_OBJECT; // 为了冒泡 HOOK_BEFORE_CREATE 事件,必须第一时间创建 emitter
8837 // 监听各种事件
8838 // 支持命名空间
8839
8840 instance.$emitter = new Emitter(TRUE);
8841
8842 if ($options.events) {
8843 instance.on($options.events);
8844 }
8845
8846 {
8847 // 当前组件的直接父组件
8848 if ($options.parent) {
8849 instance.$parent = $options.parent;
8850 } // 建立好父子连接后,立即触发钩子
8851
8852
8853 execute($options[HOOK_BEFORE_CREATE], instance, $options); // 冒泡 before create 事件
8854
8855 instance.fire(HOOK_BEFORE_CREATE + NAMESPACE_HOOK, $options);
8856 }
8857 var data = $options.data,
8858 props = $options.props,
8859 vnode = $options.vnode,
8860 propTypes = $options.propTypes,
8861 computed = $options.computed,
8862 methods = $options.methods,
8863 watchers = $options.watchers,
8864 extensions = $options.extensions;
8865 instance.$options = $options;
8866
8867 if (extensions) {
8868 extend(instance, extensions);
8869 } // 数据源,默认值仅在创建组件时启用
8870
8871
8872 var source = props ? copy(props) : {};
8873 {
8874 if (propTypes) {
8875 each$2(propTypes, function (rule, key) {
8876 var value = source[key];
8877 {
8878 checkProp($options.name, key, value, rule);
8879 }
8880
8881 if (value === UNDEFINED) {
8882 value = rule.value;
8883
8884 if (value !== UNDEFINED) {
8885 source[key] = rule.type === RAW_FUNCTION ? value : func(value) ? value() : value;
8886 }
8887 }
8888 });
8889 }
8890 } // 先放 props
8891 // 当 data 是函数时,可以通过 this.get() 获取到外部数据
8892
8893 var observer = instance.$observer = new Observer(source, instance);
8894
8895 if (computed) {
8896 each$2(computed, function (options, keypath) {
8897 observer.addComputed(keypath, options);
8898 });
8899 } // 后放 data
8900
8901
8902 {
8903 if (vnode && object(data)) {
8904 warn("The \"data\" option of child component should be a function which return an object.");
8905 }
8906 }
8907 var extend$1 = func(data) ? execute(data, instance, options) : data;
8908
8909 if (object(extend$1)) {
8910 each$2(extend$1, function (value, key) {
8911 {
8912 if (has$2(source, key)) {
8913 warn("The data \"" + key + "\" is already used as a prop.");
8914 }
8915 }
8916 source[key] = value;
8917 });
8918 }
8919
8920 if (methods) {
8921 each$2(methods, function (method, name) {
8922 {
8923 if (instance[name]) {
8924 fatal("The method \"" + name + "\" is conflicted with built-in methods.");
8925 }
8926 }
8927 instance[name] = method;
8928 });
8929 }
8930
8931 {
8932 var placeholder = UNDEFINED,
8933 el = $options.el,
8934 root = $options.root,
8935 model_1 = $options.model,
8936 context = $options.context,
8937 replace = $options.replace,
8938 template = $options.template,
8939 transitions = $options.transitions,
8940 components = $options.components,
8941 directives = $options.directives,
8942 partials = $options.partials,
8943 filters = $options.filters,
8944 slots = $options.slots;
8945
8946 if (model_1) {
8947 instance.$model = model_1;
8948 } // 把 slots 放进数据里,方便 get
8949
8950
8951 if (slots) {
8952 extend(source, slots);
8953 } // 检查 template
8954
8955
8956 if (string(template)) {
8957 // 传了选择器,则取对应元素的 html
8958 if (selectorPattern.test(template)) {
8959 placeholder = find(template);
8960
8961 if (placeholder) {
8962 template = html(placeholder);
8963 placeholder = UNDEFINED;
8964 } else {
8965 fatal("The selector \"" + template + "\" can't match an element.");
8966 }
8967 }
8968 } // 检查 el
8969
8970
8971 if (el) {
8972 if (string(el)) {
8973 var selector = el;
8974
8975 if (selectorPattern.test(selector)) {
8976 placeholder = find(selector);
8977 {
8978 if (!placeholder) {
8979 fatal("The selector \"" + selector + "\" can't match an element.");
8980 }
8981 }
8982 } else {
8983 fatal("The \"el\" option should be a selector.");
8984 }
8985 } else {
8986 placeholder = el;
8987 }
8988
8989 if (!replace) {
8990 append(placeholder, placeholder = createComment(EMPTY_STRING));
8991 }
8992 } // 根组件
8993
8994
8995 if (root) {
8996 instance.$root = root;
8997 } // 当前组件是被哪个组件渲染出来的
8998 // 因为有 slot 机制,$context 不一定等于 $parent
8999
9000
9001 if (context) {
9002 instance.$context = context;
9003 }
9004
9005 setFlexibleOptions(instance, RAW_TRANSITION, transitions);
9006 setFlexibleOptions(instance, RAW_COMPONENT, components);
9007 setFlexibleOptions(instance, RAW_DIRECTIVE, directives);
9008 setFlexibleOptions(instance, RAW_PARTIAL, partials);
9009 setFlexibleOptions(instance, RAW_FILTER, filters); // 当存在模板和计算属性时
9010 // 因为这里把模板当做一种特殊的计算属性
9011 // 因此模板这个计算属性的优先级应该最高
9012
9013 if (template) {
9014 // 拷贝一份,避免影响外部定义的 watchers
9015 var newWatchers = watchers ? copy(watchers) : {};
9016 newWatchers[TEMPLATE_COMPUTED] = {
9017 // 模板一旦变化,立即刷新
9018 sync: TRUE,
9019 watcher: function watcher(vnode) {
9020 instance.update(vnode, instance.$vnode);
9021 }
9022 }; // 当模板的依赖变了,则重新创建 virtual dom
9023
9024 observer.addComputed(TEMPLATE_COMPUTED, {
9025 // 当模板依赖变化时,异步通知模板更新
9026 sync: FALSE,
9027 get: function get() {
9028 return instance.render();
9029 }
9030 });
9031 instance.watch(newWatchers);
9032 {
9033 execute(instance.$options[HOOK_AFTER_CREATE], instance);
9034 instance.fire(HOOK_AFTER_CREATE + NAMESPACE_HOOK);
9035 } // 编译模板
9036 // 在开发阶段,template 是原始的 html 模板
9037 // 在产品阶段,template 是编译后的渲染函数
9038 // 当然,具体是什么需要外部自己控制
9039
9040 instance.$template = string(template) ? Yox.compile(template) : template;
9041
9042 if (!vnode) {
9043 {
9044 if (!placeholder) {
9045 fatal('The "el" option is required for root component.');
9046 }
9047 }
9048 vnode = create(domApi, placeholder, instance, EMPTY_STRING);
9049 }
9050
9051 instance.update(instance.get(TEMPLATE_COMPUTED), vnode);
9052 return;
9053 } else {
9054 if (placeholder || vnode) {
9055 fatal('The "template" option is required.');
9056 }
9057 }
9058 }
9059
9060 if (watchers) {
9061 instance.watch(watchers);
9062 }
9063
9064 {
9065 execute(instance.$options[HOOK_AFTER_CREATE], instance);
9066 instance.fire(HOOK_AFTER_CREATE + NAMESPACE_HOOK);
9067 }
9068 }
9069 /**
9070 * 定义组件对象
9071 */
9072
9073
9074 Yox.define = function (options) {
9075 return options;
9076 };
9077 /**
9078 * 安装插件
9079 *
9080 * 插件必须暴露 install 方法
9081 */
9082
9083
9084 Yox.use = function (plugin) {
9085 plugin.install(Yox);
9086 };
9087 /**
9088 * 因为组件采用的是异步更新机制,为了在更新之后进行一些操作,可使用 nextTick
9089 */
9090
9091
9092 Yox.nextTick = function (task, context) {
9093 NextTask.shared().append(task, context);
9094 };
9095 /**
9096 * 编译模板,暴露出来是为了打包阶段的模板预编译
9097 */
9098
9099
9100 Yox.compile = function (template, stringify) {
9101 {
9102 // 需要编译的都是模板源文件,一旦经过预编译,就成了 render 函数
9103 if (func(template)) {
9104 return template;
9105 }
9106
9107 if (!compileCache[template]) {
9108 var nodes = compile$1(template);
9109 {
9110 if (nodes.length !== 1) {
9111 fatal("The \"template\" option should have just one root element.");
9112 }
9113 }
9114 compileCache[template] = generate$1(nodes[0]);
9115 }
9116
9117 template = compileCache[template];
9118 return stringify ? template : new Function("return " + template)();
9119 }
9120 };
9121 /**
9122 * 注册全局指令
9123 */
9124
9125
9126 Yox.directive = function (name, directive) {
9127 {
9128 if (string(name) && !directive) {
9129 return getResource(globalDirectives, name);
9130 }
9131
9132 setResource(globalDirectives, name, directive);
9133 }
9134 };
9135 /**
9136 * 注册全局过渡动画
9137 */
9138
9139
9140 Yox.transition = function (name, transition) {
9141 {
9142 if (string(name) && !transition) {
9143 return getResource(globalTransitions, name);
9144 }
9145
9146 setResource(globalTransitions, name, transition);
9147 }
9148 };
9149 /**
9150 * 注册全局组件
9151 */
9152
9153
9154 Yox.component = function (name, component) {
9155 {
9156 if (string(name) && !component) {
9157 return getResource(globalComponents, name);
9158 }
9159
9160 setResource(globalComponents, name, component);
9161 }
9162 };
9163 /**
9164 * 注册全局子模板
9165 */
9166
9167
9168 Yox.partial = function (name, partial) {
9169 {
9170 if (string(name) && !partial) {
9171 return getResource(globalPartials, name);
9172 }
9173
9174 setResource(globalPartials, name, partial, Yox.compile);
9175 }
9176 };
9177 /**
9178 * 注册全局过滤器
9179 */
9180
9181
9182
9183
9184 Yox.filters = globalFilters;
9185
9186 Yox.filter = function (name, filter) {
9187
9188
9189 {
9190 if (string(name) && !filter) {
9191 return getResource(globalFilters, name);
9192 }
9193
9194 setResource(globalFilters, name, filter);
9195 }
9196 };
9197 /**
9198 * 取值
9199 */
9200
9201
9202 Yox.prototype.get = function (keypath, defaultValue) {
9203 return this.$observer.get(keypath, defaultValue);
9204 };
9205 /**
9206 * 设值
9207 */
9208
9209
9210 Yox.prototype.set = function (keypath, value) {
9211 // 组件经常有各种异步改值,为了避免组件销毁后依然调用 set
9212 // 这里判断一下,至于其他方法的异步调用就算了,业务自己控制吧
9213 var $observer = this.$observer;
9214
9215 if ($observer) {
9216 $observer.set(keypath, value);
9217 }
9218 };
9219 /**
9220 * 监听事件,支持链式调用
9221 */
9222
9223
9224 Yox.prototype.on = function (type, listener) {
9225 addEvents(this, type, listener);
9226 return this;
9227 };
9228 /**
9229 * 监听一次事件,支持链式调用
9230 */
9231
9232
9233 Yox.prototype.once = function (type, listener) {
9234 addEvents(this, type, listener, TRUE);
9235 return this;
9236 };
9237 /**
9238 * 取消监听事件,支持链式调用
9239 */
9240
9241
9242 Yox.prototype.off = function (type, listener) {
9243 this.$emitter.off(type, listener);
9244 return this;
9245 };
9246 /**
9247 * 发射事件
9248 */
9249
9250
9251 Yox.prototype.fire = function (type, data, downward) {
9252 // 外部为了使用方便,fire(type) 或 fire(type, data) 就行了
9253 // 内部为了保持格式统一
9254 // 需要转成 Event,这样还能知道 target 是哪个组件
9255 var instance = this,
9256 $emitter = instance.$emitter,
9257 $parent = instance.$parent,
9258 $children = instance.$children,
9259 event = type instanceof CustomEvent ? type : new CustomEvent(type),
9260 args = [event],
9261 isComplete; // 创建完 CustomEvent,如果没有人为操作
9262 // 它的 ns 为 undefined
9263 // 这里先解析出命名空间,避免每次 fire 都要解析
9264
9265 if (event.ns === UNDEFINED) {
9266 var namespace = $emitter.parse(event.type);
9267 event.type = namespace.type;
9268 event.ns = namespace.ns;
9269 } // 告诉外部是谁发出的事件
9270
9271
9272 if (!event.target) {
9273 event.target = instance;
9274 } // 比如 fire('name', true) 直接向下发事件
9275
9276
9277 if (object(data)) {
9278 push(args, data);
9279 } else if (data === TRUE) {
9280 downward = TRUE;
9281 } // 如果手动 fire 带上了事件命名空间
9282 // 则命名空间不能是 native,因为 native 有特殊用处
9283
9284
9285 {
9286 if (event.ns === MODIFER_NATIVE) {
9287 error("The namespace \"" + MODIFER_NATIVE + "\" is not permitted.");
9288 }
9289 } // 向上发事件会经过自己
9290 // 如果向下发事件再经过自己,就产生了一次重叠
9291 // 这是没有必要的,而且会导致向下发事件时,外部能接收到该事件,但我们的本意只是想让子组件接收到事件
9292
9293 isComplete = downward && event.target === instance ? TRUE : $emitter.fire(event, args);
9294
9295 if (isComplete) {
9296 if (downward) {
9297 if ($children) {
9298 event.phase = CustomEvent.PHASE_DOWNWARD;
9299 each($children, function (child) {
9300 return isComplete = child.fire(event, data, TRUE);
9301 });
9302 }
9303 } else if ($parent) {
9304 event.phase = CustomEvent.PHASE_UPWARD;
9305 isComplete = $parent.fire(event, data);
9306 }
9307 }
9308
9309 return isComplete;
9310 };
9311 /**
9312 * 监听数据变化,支持链式调用
9313 */
9314
9315
9316 Yox.prototype.watch = function (keypath, watcher, immediate) {
9317 this.$observer.watch(keypath, watcher, immediate);
9318 return this;
9319 };
9320 /**
9321 * 取消监听数据变化,支持链式调用
9322 */
9323
9324
9325 Yox.prototype.unwatch = function (keypath, watcher) {
9326 this.$observer.unwatch(keypath, watcher);
9327 return this;
9328 };
9329 /**
9330 * 加载组件,组件可以是同步或异步,最后会调用 callback
9331 *
9332 * @param name 组件名称
9333 * @param callback 组件加载成功后的回调
9334 */
9335
9336
9337 Yox.prototype.loadComponent = function (name, callback) {
9338 {
9339 if (!loadComponent(this.$components, name, callback)) {
9340 {
9341 if (!loadComponent(globalComponents, name, callback)) {
9342 error("The component \"" + name + "\" is not found.");
9343 }
9344 }
9345 }
9346 }
9347 };
9348 /**
9349 * 创建子组件
9350 *
9351 * @param options 组件配置
9352 * @param vnode 虚拟节点
9353 */
9354
9355
9356 Yox.prototype.createComponent = function (options, vnode) {
9357 {
9358 var instance = this;
9359 options = copy(options);
9360 options.root = instance.$root || instance;
9361 options.parent = instance;
9362 options.context = vnode.context;
9363 options.vnode = vnode;
9364 options.replace = TRUE;
9365 var props = vnode.props,
9366 slots = vnode.slots,
9367 directives = vnode.directives,
9368 model_2 = directives && directives[DIRECTIVE_MODEL];
9369
9370 if (model_2) {
9371 if (!props) {
9372 props = {};
9373 }
9374
9375 var key = options.model || MODEL_PROP_DEFAULT;
9376 props[key] = model_2.value;
9377 options.model = key;
9378 }
9379
9380 if (props) {
9381 options.props = props;
9382 }
9383
9384 if (slots) {
9385 options.slots = slots;
9386 }
9387
9388 var child = new Yox(options);
9389 push(instance.$children || (instance.$children = []), child);
9390 var node = child.$el;
9391
9392 if (node) {
9393 vnode.node = node;
9394 } else {
9395 fatal("The root element of component \"" + vnode.tag + "\" is not found.");
9396 }
9397
9398 return child;
9399 }
9400 };
9401 /**
9402 * 注册当前组件级别的指令
9403 */
9404
9405
9406 Yox.prototype.directive = function (name, directive) {
9407 {
9408 var instance = this,
9409 $directives = instance.$directives;
9410
9411 if (string(name) && !directive) {
9412 return getResource($directives, name, Yox.directive);
9413 }
9414
9415 setResource($directives || (instance.$directives = {}), name, directive);
9416 }
9417 };
9418 /**
9419 * 注册当前组件级别的过渡动画
9420 */
9421
9422
9423 Yox.prototype.transition = function (name, transition) {
9424 {
9425 var instance = this,
9426 $transitions = instance.$transitions;
9427
9428 if (string(name) && !transition) {
9429 return getResource($transitions, name, Yox.transition);
9430 }
9431
9432 setResource($transitions || (instance.$transitions = {}), name, transition);
9433 }
9434 };
9435 /**
9436 * 注册当前组件级别的组件
9437 */
9438
9439
9440 Yox.prototype.component = function (name, component) {
9441 {
9442 var instance = this,
9443 $components = instance.$components;
9444
9445 if (string(name) && !component) {
9446 return getResource($components, name, Yox.component);
9447 }
9448
9449 setResource($components || (instance.$components = {}), name, component);
9450 }
9451 };
9452 /**
9453 * 注册当前组件级别的子模板
9454 */
9455
9456
9457 Yox.prototype.partial = function (name, partial) {
9458 {
9459 var instance = this,
9460 $partials = instance.$partials;
9461
9462 if (string(name) && !partial) {
9463 return getResource($partials, name, Yox.partial);
9464 }
9465
9466 setResource($partials || (instance.$partials = {}), name, partial, Yox.compile);
9467 }
9468 };
9469 /**
9470 * 注册当前组件级别的过滤器
9471 */
9472
9473
9474 Yox.prototype.filter = function (name, filter) {
9475 {
9476 var instance = this,
9477 $filters = instance.$filters;
9478
9479 if (string(name) && !filter) {
9480 return getResource($filters, name, Yox.filter);
9481 }
9482
9483 setResource($filters || (instance.$filters = {}), name, filter);
9484 }
9485 };
9486 /**
9487 * 对于某些特殊场景,修改了数据,但是模板的依赖中并没有这一项
9488 * 而你非常确定需要更新模板,强制刷新正是你需要的
9489 */
9490
9491
9492 Yox.prototype.forceUpdate = function (props) {
9493 {
9494 var instance = this,
9495 $options = instance.$options,
9496 $vnode = instance.$vnode,
9497 $observer = instance.$observer,
9498 computed = $observer.computed;
9499
9500 if ($vnode && computed) {
9501 var template = computed[TEMPLATE_COMPUTED],
9502 oldValue = template.get();
9503
9504 if (props) {
9505 execute($options[HOOK_BEFORE_PROPS_UPDATE], instance, props);
9506 instance.set(props);
9507 } // 当前可能正在进行下一轮更新
9508
9509
9510 $observer.nextTask.run(); // 没有更新模板,强制刷新
9511
9512 if (!props && oldValue === template.get()) {
9513 instance.update(template.get(TRUE), $vnode);
9514 }
9515 }
9516 }
9517 };
9518 /**
9519 * 把模板抽象语法树渲染成 virtual dom
9520 */
9521
9522
9523 Yox.prototype.render = function () {
9524 {
9525 var instance = this;
9526 return render(instance, instance.$observer, instance.$template, merge(instance.$filters, globalFilters), merge(instance.$partials, globalPartials), merge(instance.$directives, globalDirectives), merge(instance.$transitions, globalTransitions));
9527 }
9528 };
9529 /**
9530 * 更新 virtual dom
9531 *
9532 * @param vnode
9533 * @param oldVnode
9534 */
9535
9536
9537 Yox.prototype.update = function (vnode, oldVnode) {
9538 {
9539 var instance_1 = this,
9540 $vnode = instance_1.$vnode,
9541 $options_1 = instance_1.$options,
9542 afterHook_1; // 每次渲染重置 refs
9543 // 在渲染过程中收集最新的 ref
9544 // 这样可避免更新时,新的 ref,在前面创建,老的 ref 却在后面删除的情况
9545
9546 instance_1.$refs = {};
9547
9548 if ($vnode) {
9549 execute($options_1[HOOK_BEFORE_UPDATE], instance_1);
9550 instance_1.fire(HOOK_BEFORE_UPDATE + NAMESPACE_HOOK);
9551 patch(domApi, vnode, oldVnode);
9552 afterHook_1 = HOOK_AFTER_UPDATE;
9553 } else {
9554 execute($options_1[HOOK_BEFORE_MOUNT], instance_1);
9555 instance_1.fire(HOOK_BEFORE_MOUNT + NAMESPACE_HOOK);
9556 patch(domApi, vnode, oldVnode);
9557 instance_1.$el = vnode.node;
9558 afterHook_1 = HOOK_AFTER_MOUNT;
9559 }
9560
9561 instance_1.$vnode = vnode; // 跟 nextTask 保持一个节奏
9562 // 这样可以预留一些优化的余地
9563
9564 Yox.nextTick(function () {
9565 if (instance_1.$vnode) {
9566 execute($options_1[afterHook_1], instance_1);
9567 instance_1.fire(afterHook_1 + NAMESPACE_HOOK);
9568 }
9569 });
9570 }
9571 };
9572 /**
9573 * 校验组件参数
9574 *
9575 * @param props
9576 */
9577
9578
9579 Yox.prototype.checkProp = function (key, value) {
9580 {
9581 var _a = this.$options,
9582 name = _a.name,
9583 propTypes = _a.propTypes;
9584
9585 if (propTypes) {
9586 var rule = propTypes[key];
9587
9588 if (rule) {
9589 checkProp(name, key, value, rule);
9590 }
9591 }
9592 }
9593 };
9594 /**
9595 * 销毁组件
9596 */
9597
9598
9599 Yox.prototype.destroy = function () {
9600 var instance = this,
9601 $parent = instance.$parent,
9602 $options = instance.$options,
9603 $emitter = instance.$emitter,
9604 $observer = instance.$observer;
9605 {
9606 execute($options[HOOK_BEFORE_DESTROY], instance);
9607 instance.fire(HOOK_BEFORE_DESTROY + NAMESPACE_HOOK);
9608 var $vnode = instance.$vnode;
9609
9610 if ($parent && $parent.$children) {
9611 remove($parent.$children, instance);
9612 }
9613
9614 if ($vnode) {
9615 // virtual dom 通过判断 parent.$vnode 知道宿主组件是否正在销毁
9616 instance.$vnode = UNDEFINED;
9617 destroy(domApi, $vnode, !$parent);
9618 }
9619 }
9620 $observer.destroy();
9621 {
9622 execute($options[HOOK_AFTER_DESTROY], instance);
9623 instance.fire(HOOK_AFTER_DESTROY + NAMESPACE_HOOK);
9624 } // 发完 after destroy 事件再解绑所有事件
9625
9626 $emitter.off();
9627 clear(instance);
9628 };
9629 /**
9630 * 因为组件采用的是异步更新机制,为了在更新之后进行一些操作,可使用 nextTick
9631 */
9632
9633
9634 Yox.prototype.nextTick = function (task) {
9635 this.$observer.nextTask.append(task, this);
9636 };
9637 /**
9638 * 取反 keypath 对应的数据
9639 *
9640 * 不管 keypath 对应的数据是什么类型,操作后都是布尔型
9641 */
9642
9643
9644 Yox.prototype.toggle = function (keypath) {
9645 return this.$observer.toggle(keypath);
9646 };
9647 /**
9648 * 递增 keypath 对应的数据
9649 *
9650 * 注意,最好是整型的加法,如果涉及浮点型,不保证计算正确
9651 *
9652 * @param keypath 值必须能转型成数字,如果不能,则默认从 0 开始递增
9653 * @param step 步进值,默认是 1
9654 * @param max 可以递增到的最大值,默认不限制
9655 */
9656
9657
9658 Yox.prototype.increase = function (keypath, step, max) {
9659 return this.$observer.increase(keypath, step, max);
9660 };
9661 /**
9662 * 递减 keypath 对应的数据
9663 *
9664 * 注意,最好是整型的减法,如果涉及浮点型,不保证计算正确
9665 *
9666 * @param keypath 值必须能转型成数字,如果不能,则默认从 0 开始递减
9667 * @param step 步进值,默认是 1
9668 * @param min 可以递减到的最小值,默认不限制
9669 */
9670
9671
9672 Yox.prototype.decrease = function (keypath, step, min) {
9673 return this.$observer.decrease(keypath, step, min);
9674 };
9675 /**
9676 * 在数组指定位置插入元素
9677 *
9678 * @param keypath
9679 * @param item
9680 * @param index
9681 */
9682
9683
9684 Yox.prototype.insert = function (keypath, item, index) {
9685 return this.$observer.insert(keypath, item, index);
9686 };
9687 /**
9688 * 在数组尾部添加元素
9689 *
9690 * @param keypath
9691 * @param item
9692 */
9693
9694
9695 Yox.prototype.append = function (keypath, item) {
9696 return this.$observer.append(keypath, item);
9697 };
9698 /**
9699 * 在数组首部添加元素
9700 *
9701 * @param keypath
9702 * @param item
9703 */
9704
9705
9706 Yox.prototype.prepend = function (keypath, item) {
9707 return this.$observer.prepend(keypath, item);
9708 };
9709 /**
9710 * 通过索引移除数组中的元素
9711 *
9712 * @param keypath
9713 * @param index
9714 */
9715
9716
9717 Yox.prototype.removeAt = function (keypath, index) {
9718 return this.$observer.removeAt(keypath, index);
9719 };
9720 /**
9721 * 直接移除数组中的元素
9722 *
9723 * @param keypath
9724 * @param item
9725 */
9726
9727
9728 Yox.prototype.remove = function (keypath, item) {
9729 return this.$observer.remove(keypath, item);
9730 };
9731 /**
9732 * 拷贝任意数据,支持深拷贝
9733 *
9734 * @param data
9735 * @param deep
9736 */
9737
9738
9739 Yox.prototype.copy = function (data, deep) {
9740 return this.$observer.copy(data, deep);
9741 };
9742 /**
9743 * core 版本
9744 */
9745
9746
9747 Yox.version = "1.0.0-alpha.118";
9748 /**
9749 * 方便外部共用的通用逻辑,特别是写插件,减少重复代码
9750 */
9751
9752 Yox.is = is;
9753 Yox.dom = domApi;
9754 Yox.array = array$1;
9755 Yox.object = object$1;
9756 Yox.string = string$1;
9757 Yox.logger = logger;
9758 Yox.Event = CustomEvent;
9759 Yox.Emitter = Emitter;
9760 return Yox;
9761 }();
9762
9763 var toString$2 = Object.prototype.toString;
9764
9765 function matchType(value, type) {
9766 return type === 'numeric' ? numeric(value) : lower(toString$2.call(value)) === "[object " + type + "]";
9767 }
9768
9769 function checkProp(componentName, key, value, rule) {
9770 // 传了数据
9771 if (value !== UNDEFINED) {
9772 var type = rule.type; // 如果不写 type 或 type 不是 字符串 或 数组
9773 // 就当做此规则无效,和没写一样
9774
9775 if (type) {
9776 // 自定义函数判断是否匹配类型
9777 // 自己打印警告信息吧
9778 if (func(type)) {
9779 type(key, value, componentName);
9780 } else {
9781 var matched_1 = FALSE; // type: 'string'
9782
9783 if (!falsy$1(type)) {
9784 matched_1 = matchType(value, type);
9785 } // type: ['string', 'number']
9786 else if (!falsy(type)) {
9787 each(type, function (item) {
9788 if (matchType(value, item)) {
9789 matched_1 = TRUE;
9790 return FALSE;
9791 }
9792 });
9793 }
9794
9795 if (!matched_1) {
9796 warn("The type of prop \"" + key + "\" expected to be \"" + type + "\", but is \"" + value + "\".", componentName);
9797 }
9798 }
9799 } else {
9800 warn("The prop \"" + key + "\" in propTypes has no type.", componentName);
9801 }
9802 } // 没传值但此项是必传项
9803 else if (rule.required) {
9804 warn("The prop \"" + key + "\" is marked as required, but its value is undefined.", componentName);
9805 }
9806 }
9807
9808 function setFlexibleOptions(instance, key, value) {
9809 if (func(value)) {
9810 instance[key](execute(value, instance));
9811 } else if (object(value)) {
9812 instance[key](value);
9813 }
9814 }
9815
9816 function addEvent(instance, type, listener, once) {
9817 var options = {
9818 fn: listener,
9819 ctx: instance
9820 };
9821
9822 if (once) {
9823 options.max = 1;
9824 } // YoxInterface 没有声明 $emitter,因为不想让外部访问,
9825 // 但是这里要用一次,所以加了 as any
9826
9827
9828 instance.$emitter.on(type, options);
9829 }
9830
9831 function addEvents(instance, type, listener, once) {
9832 if (string(type)) {
9833 addEvent(instance, type, listener, once);
9834 } else {
9835 each$2(type, function (value, key) {
9836 addEvent(instance, key, value, once);
9837 });
9838 }
9839 }
9840
9841 function loadComponent(registry, name, callback) {
9842 if (registry && registry[name]) {
9843 var component = registry[name]; // 注册的是异步加载函数
9844
9845 if (func(component)) {
9846 registry[name] = [callback];
9847
9848 var componentCallback = function (result) {
9849 var queue = registry[name],
9850 options = result['default'] || result;
9851 registry[name] = options;
9852 each(queue, function (callback) {
9853 callback(options);
9854 });
9855 },
9856 promise = component(componentCallback);
9857
9858 if (promise) {
9859 promise.then(componentCallback);
9860 }
9861 } // 正在加载中
9862 else if (array(component)) {
9863 push(component, callback);
9864 } // 不是异步加载函数,直接同步返回
9865 else {
9866 callback(component);
9867 }
9868
9869 return TRUE;
9870 }
9871 }
9872
9873 function getResource(registry, name, lookup) {
9874 if (registry && registry[name]) {
9875 return registry[name];
9876 } else if (lookup) {
9877 return lookup(name);
9878 }
9879 }
9880
9881 function setResource(registry, name, value, formatValue) {
9882 if (string(name)) {
9883 registry[name] = formatValue ? formatValue(value) : value;
9884 } else {
9885 each$2(name, function (value, key) {
9886 registry[key] = formatValue ? formatValue(value) : value;
9887 });
9888 }
9889 }
9890
9891 {
9892 // 全局注册内置指令
9893 Yox.directive({
9894 event: event,
9895 model: model,
9896 binding: binding
9897 }); // 全局注册内置过滤器
9898
9899 Yox.filter({
9900 hasSlot: function hasSlot(name) {
9901 // 不鼓励在过滤器使用 this
9902 // 因此过滤器没有 this 的类型声明
9903 // 这个内置过滤器是不得不用 this
9904 return this.get(SLOT_DATA_PREFIX + name) !== UNDEFINED;
9905 }
9906 });
9907 }
9908 return Yox;
9909 });
9910 });
9911
9912 var jquery = createCommonjsModule(function (module) {
9913 /*!
9914 * jQuery JavaScript Library v1.12.4
9915 * http://jquery.com/
9916 *
9917 * Includes Sizzle.js
9918 * http://sizzlejs.com/
9919 *
9920 * Copyright jQuery Foundation and other contributors
9921 * Released under the MIT license
9922 * http://jquery.org/license
9923 *
9924 * Date: 2016-05-20T17:17Z
9925 */
9926
9927 (function( global, factory ) {
9928
9929 {
9930 // For CommonJS and CommonJS-like environments where a proper `window`
9931 // is present, execute the factory and get jQuery.
9932 // For environments that do not have a `window` with a `document`
9933 // (such as Node.js), expose a factory as module.exports.
9934 // This accentuates the need for the creation of a real `window`.
9935 // e.g. var jQuery = require("jquery")(window);
9936 // See ticket #14549 for more info.
9937 module.exports = global.document ?
9938 factory( global, true ) :
9939 function( w ) {
9940 if ( !w.document ) {
9941 throw new Error( "jQuery requires a window with a document" );
9942 }
9943 return factory( w );
9944 };
9945 }
9946
9947 // Pass this if window is not defined yet
9948 }(typeof window !== "undefined" ? window : commonjsGlobal, function( window, noGlobal ) {
9949
9950 // Support: Firefox 18+
9951 // Can't be in strict mode, several libs including ASP.NET trace
9952 // the stack via arguments.caller.callee and Firefox dies if
9953 // you try to trace through "use strict" call chains. (#13335)
9954 //"use strict";
9955 var deletedIds = [];
9956
9957 var document = window.document;
9958
9959 var slice = deletedIds.slice;
9960
9961 var concat = deletedIds.concat;
9962
9963 var push = deletedIds.push;
9964
9965 var indexOf = deletedIds.indexOf;
9966
9967 var class2type = {};
9968
9969 var toString = class2type.toString;
9970
9971 var hasOwn = class2type.hasOwnProperty;
9972
9973 var support = {};
9974
9975
9976
9977 var
9978 version = "1.12.4",
9979
9980 // Define a local copy of jQuery
9981 jQuery = function( selector, context ) {
9982
9983 // The jQuery object is actually just the init constructor 'enhanced'
9984 // Need init if jQuery is called (just allow error to be thrown if not included)
9985 return new jQuery.fn.init( selector, context );
9986 },
9987
9988 // Support: Android<4.1, IE<9
9989 // Make sure we trim BOM and NBSP
9990 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
9991
9992 // Matches dashed string for camelizing
9993 rmsPrefix = /^-ms-/,
9994 rdashAlpha = /-([\da-z])/gi,
9995
9996 // Used by jQuery.camelCase as callback to replace()
9997 fcamelCase = function( all, letter ) {
9998 return letter.toUpperCase();
9999 };
10000
10001 jQuery.fn = jQuery.prototype = {
10002
10003 // The current version of jQuery being used
10004 jquery: version,
10005
10006 constructor: jQuery,
10007
10008 // Start with an empty selector
10009 selector: "",
10010
10011 // The default length of a jQuery object is 0
10012 length: 0,
10013
10014 toArray: function() {
10015 return slice.call( this );
10016 },
10017
10018 // Get the Nth element in the matched element set OR
10019 // Get the whole matched element set as a clean array
10020 get: function( num ) {
10021 return num != null ?
10022
10023 // Return just the one element from the set
10024 ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
10025
10026 // Return all the elements in a clean array
10027 slice.call( this );
10028 },
10029
10030 // Take an array of elements and push it onto the stack
10031 // (returning the new matched element set)
10032 pushStack: function( elems ) {
10033
10034 // Build a new jQuery matched element set
10035 var ret = jQuery.merge( this.constructor(), elems );
10036
10037 // Add the old object onto the stack (as a reference)
10038 ret.prevObject = this;
10039 ret.context = this.context;
10040
10041 // Return the newly-formed element set
10042 return ret;
10043 },
10044
10045 // Execute a callback for every element in the matched set.
10046 each: function( callback ) {
10047 return jQuery.each( this, callback );
10048 },
10049
10050 map: function( callback ) {
10051 return this.pushStack( jQuery.map( this, function( elem, i ) {
10052 return callback.call( elem, i, elem );
10053 } ) );
10054 },
10055
10056 slice: function() {
10057 return this.pushStack( slice.apply( this, arguments ) );
10058 },
10059
10060 first: function() {
10061 return this.eq( 0 );
10062 },
10063
10064 last: function() {
10065 return this.eq( -1 );
10066 },
10067
10068 eq: function( i ) {
10069 var len = this.length,
10070 j = +i + ( i < 0 ? len : 0 );
10071 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
10072 },
10073
10074 end: function() {
10075 return this.prevObject || this.constructor();
10076 },
10077
10078 // For internal use only.
10079 // Behaves like an Array's method, not like a jQuery method.
10080 push: push,
10081 sort: deletedIds.sort,
10082 splice: deletedIds.splice
10083 };
10084
10085 jQuery.extend = jQuery.fn.extend = function() {
10086 var src, copyIsArray, copy, name, options, clone,
10087 target = arguments[ 0 ] || {},
10088 i = 1,
10089 length = arguments.length,
10090 deep = false;
10091
10092 // Handle a deep copy situation
10093 if ( typeof target === "boolean" ) {
10094 deep = target;
10095
10096 // skip the boolean and the target
10097 target = arguments[ i ] || {};
10098 i++;
10099 }
10100
10101 // Handle case when target is a string or something (possible in deep copy)
10102 if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
10103 target = {};
10104 }
10105
10106 // extend jQuery itself if only one argument is passed
10107 if ( i === length ) {
10108 target = this;
10109 i--;
10110 }
10111
10112 for ( ; i < length; i++ ) {
10113
10114 // Only deal with non-null/undefined values
10115 if ( ( options = arguments[ i ] ) != null ) {
10116
10117 // Extend the base object
10118 for ( name in options ) {
10119 src = target[ name ];
10120 copy = options[ name ];
10121
10122 // Prevent never-ending loop
10123 if ( target === copy ) {
10124 continue;
10125 }
10126
10127 // Recurse if we're merging plain objects or arrays
10128 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
10129 ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
10130
10131 if ( copyIsArray ) {
10132 copyIsArray = false;
10133 clone = src && jQuery.isArray( src ) ? src : [];
10134
10135 } else {
10136 clone = src && jQuery.isPlainObject( src ) ? src : {};
10137 }
10138
10139 // Never move original objects, clone them
10140 target[ name ] = jQuery.extend( deep, clone, copy );
10141
10142 // Don't bring in undefined values
10143 } else if ( copy !== undefined ) {
10144 target[ name ] = copy;
10145 }
10146 }
10147 }
10148 }
10149
10150 // Return the modified object
10151 return target;
10152 };
10153
10154 jQuery.extend( {
10155
10156 // Unique for each copy of jQuery on the page
10157 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
10158
10159 // Assume jQuery is ready without the ready module
10160 isReady: true,
10161
10162 error: function( msg ) {
10163 throw new Error( msg );
10164 },
10165
10166 noop: function() {},
10167
10168 // See test/unit/core.js for details concerning isFunction.
10169 // Since version 1.3, DOM methods and functions like alert
10170 // aren't supported. They return false on IE (#2968).
10171 isFunction: function( obj ) {
10172 return jQuery.type( obj ) === "function";
10173 },
10174
10175 isArray: Array.isArray || function( obj ) {
10176 return jQuery.type( obj ) === "array";
10177 },
10178
10179 isWindow: function( obj ) {
10180 /* jshint eqeqeq: false */
10181 return obj != null && obj == obj.window;
10182 },
10183
10184 isNumeric: function( obj ) {
10185
10186 // parseFloat NaNs numeric-cast false positives (null|true|false|"")
10187 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10188 // subtraction forces infinities to NaN
10189 // adding 1 corrects loss of precision from parseFloat (#15100)
10190 var realStringObj = obj && obj.toString();
10191 return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
10192 },
10193
10194 isEmptyObject: function( obj ) {
10195 var name;
10196 for ( name in obj ) {
10197 return false;
10198 }
10199 return true;
10200 },
10201
10202 isPlainObject: function( obj ) {
10203 var key;
10204
10205 // Must be an Object.
10206 // Because of IE, we also have to check the presence of the constructor property.
10207 // Make sure that DOM nodes and window objects don't pass through, as well
10208 if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
10209 return false;
10210 }
10211
10212 try {
10213
10214 // Not own constructor property must be Object
10215 if ( obj.constructor &&
10216 !hasOwn.call( obj, "constructor" ) &&
10217 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
10218 return false;
10219 }
10220 } catch ( e ) {
10221
10222 // IE8,9 Will throw exceptions on certain host objects #9897
10223 return false;
10224 }
10225
10226 // Support: IE<9
10227 // Handle iteration over inherited properties before own properties.
10228 if ( !support.ownFirst ) {
10229 for ( key in obj ) {
10230 return hasOwn.call( obj, key );
10231 }
10232 }
10233
10234 // Own properties are enumerated firstly, so to speed up,
10235 // if last one is own, then all properties are own.
10236 for ( key in obj ) {}
10237
10238 return key === undefined || hasOwn.call( obj, key );
10239 },
10240
10241 type: function( obj ) {
10242 if ( obj == null ) {
10243 return obj + "";
10244 }
10245 return typeof obj === "object" || typeof obj === "function" ?
10246 class2type[ toString.call( obj ) ] || "object" :
10247 typeof obj;
10248 },
10249
10250 // Workarounds based on findings by Jim Driscoll
10251 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
10252 globalEval: function( data ) {
10253 if ( data && jQuery.trim( data ) ) {
10254
10255 // We use execScript on Internet Explorer
10256 // We use an anonymous function so that context is window
10257 // rather than jQuery in Firefox
10258 ( window.execScript || function( data ) {
10259 window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
10260 } )( data );
10261 }
10262 },
10263
10264 // Convert dashed to camelCase; used by the css and data modules
10265 // Microsoft forgot to hump their vendor prefix (#9572)
10266 camelCase: function( string ) {
10267 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
10268 },
10269
10270 nodeName: function( elem, name ) {
10271 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
10272 },
10273
10274 each: function( obj, callback ) {
10275 var length, i = 0;
10276
10277 if ( isArrayLike( obj ) ) {
10278 length = obj.length;
10279 for ( ; i < length; i++ ) {
10280 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
10281 break;
10282 }
10283 }
10284 } else {
10285 for ( i in obj ) {
10286 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
10287 break;
10288 }
10289 }
10290 }
10291
10292 return obj;
10293 },
10294
10295 // Support: Android<4.1, IE<9
10296 trim: function( text ) {
10297 return text == null ?
10298 "" :
10299 ( text + "" ).replace( rtrim, "" );
10300 },
10301
10302 // results is for internal usage only
10303 makeArray: function( arr, results ) {
10304 var ret = results || [];
10305
10306 if ( arr != null ) {
10307 if ( isArrayLike( Object( arr ) ) ) {
10308 jQuery.merge( ret,
10309 typeof arr === "string" ?
10310 [ arr ] : arr
10311 );
10312 } else {
10313 push.call( ret, arr );
10314 }
10315 }
10316
10317 return ret;
10318 },
10319
10320 inArray: function( elem, arr, i ) {
10321 var len;
10322
10323 if ( arr ) {
10324 if ( indexOf ) {
10325 return indexOf.call( arr, elem, i );
10326 }
10327
10328 len = arr.length;
10329 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
10330
10331 for ( ; i < len; i++ ) {
10332
10333 // Skip accessing in sparse arrays
10334 if ( i in arr && arr[ i ] === elem ) {
10335 return i;
10336 }
10337 }
10338 }
10339
10340 return -1;
10341 },
10342
10343 merge: function( first, second ) {
10344 var len = +second.length,
10345 j = 0,
10346 i = first.length;
10347
10348 while ( j < len ) {
10349 first[ i++ ] = second[ j++ ];
10350 }
10351
10352 // Support: IE<9
10353 // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
10354 if ( len !== len ) {
10355 while ( second[ j ] !== undefined ) {
10356 first[ i++ ] = second[ j++ ];
10357 }
10358 }
10359
10360 first.length = i;
10361
10362 return first;
10363 },
10364
10365 grep: function( elems, callback, invert ) {
10366 var callbackInverse,
10367 matches = [],
10368 i = 0,
10369 length = elems.length,
10370 callbackExpect = !invert;
10371
10372 // Go through the array, only saving the items
10373 // that pass the validator function
10374 for ( ; i < length; i++ ) {
10375 callbackInverse = !callback( elems[ i ], i );
10376 if ( callbackInverse !== callbackExpect ) {
10377 matches.push( elems[ i ] );
10378 }
10379 }
10380
10381 return matches;
10382 },
10383
10384 // arg is for internal usage only
10385 map: function( elems, callback, arg ) {
10386 var length, value,
10387 i = 0,
10388 ret = [];
10389
10390 // Go through the array, translating each of the items to their new values
10391 if ( isArrayLike( elems ) ) {
10392 length = elems.length;
10393 for ( ; i < length; i++ ) {
10394 value = callback( elems[ i ], i, arg );
10395
10396 if ( value != null ) {
10397 ret.push( value );
10398 }
10399 }
10400
10401 // Go through every key on the object,
10402 } else {
10403 for ( i in elems ) {
10404 value = callback( elems[ i ], i, arg );
10405
10406 if ( value != null ) {
10407 ret.push( value );
10408 }
10409 }
10410 }
10411
10412 // Flatten any nested arrays
10413 return concat.apply( [], ret );
10414 },
10415
10416 // A global GUID counter for objects
10417 guid: 1,
10418
10419 // Bind a function to a context, optionally partially applying any
10420 // arguments.
10421 proxy: function( fn, context ) {
10422 var args, proxy, tmp;
10423
10424 if ( typeof context === "string" ) {
10425 tmp = fn[ context ];
10426 context = fn;
10427 fn = tmp;
10428 }
10429
10430 // Quick check to determine if target is callable, in the spec
10431 // this throws a TypeError, but we will just return undefined.
10432 if ( !jQuery.isFunction( fn ) ) {
10433 return undefined;
10434 }
10435
10436 // Simulated bind
10437 args = slice.call( arguments, 2 );
10438 proxy = function() {
10439 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
10440 };
10441
10442 // Set the guid of unique handler to the same of original handler, so it can be removed
10443 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10444
10445 return proxy;
10446 },
10447
10448 now: function() {
10449 return +( new Date() );
10450 },
10451
10452 // jQuery.support is not used in Core but other projects attach their
10453 // properties to it so it needs to exist.
10454 support: support
10455 } );
10456
10457 // JSHint would error on this code due to the Symbol not being defined in ES5.
10458 // Defining this global in .jshintrc would create a danger of using the global
10459 // unguarded in another place, it seems safer to just disable JSHint for these
10460 // three lines.
10461 /* jshint ignore: start */
10462 if ( typeof Symbol === "function" ) {
10463 jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
10464 }
10465 /* jshint ignore: end */
10466
10467 // Populate the class2type map
10468 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
10469 function( i, name ) {
10470 class2type[ "[object " + name + "]" ] = name.toLowerCase();
10471 } );
10472
10473 function isArrayLike( obj ) {
10474
10475 // Support: iOS 8.2 (not reproducible in simulator)
10476 // `in` check used to prevent JIT error (gh-2145)
10477 // hasOwn isn't used here due to false negatives
10478 // regarding Nodelist length in IE
10479 var length = !!obj && "length" in obj && obj.length,
10480 type = jQuery.type( obj );
10481
10482 if ( type === "function" || jQuery.isWindow( obj ) ) {
10483 return false;
10484 }
10485
10486 return type === "array" || length === 0 ||
10487 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
10488 }
10489 var Sizzle =
10490 /*!
10491 * Sizzle CSS Selector Engine v2.2.1
10492 * http://sizzlejs.com/
10493 *
10494 * Copyright jQuery Foundation and other contributors
10495 * Released under the MIT license
10496 * http://jquery.org/license
10497 *
10498 * Date: 2015-10-17
10499 */
10500 (function( window ) {
10501
10502 var i,
10503 support,
10504 Expr,
10505 getText,
10506 isXML,
10507 tokenize,
10508 compile,
10509 select,
10510 outermostContext,
10511 sortInput,
10512 hasDuplicate,
10513
10514 // Local document vars
10515 setDocument,
10516 document,
10517 docElem,
10518 documentIsHTML,
10519 rbuggyQSA,
10520 rbuggyMatches,
10521 matches,
10522 contains,
10523
10524 // Instance-specific data
10525 expando = "sizzle" + 1 * new Date(),
10526 preferredDoc = window.document,
10527 dirruns = 0,
10528 done = 0,
10529 classCache = createCache(),
10530 tokenCache = createCache(),
10531 compilerCache = createCache(),
10532 sortOrder = function( a, b ) {
10533 if ( a === b ) {
10534 hasDuplicate = true;
10535 }
10536 return 0;
10537 },
10538
10539 // General-purpose constants
10540 MAX_NEGATIVE = 1 << 31,
10541
10542 // Instance methods
10543 hasOwn = ({}).hasOwnProperty,
10544 arr = [],
10545 pop = arr.pop,
10546 push_native = arr.push,
10547 push = arr.push,
10548 slice = arr.slice,
10549 // Use a stripped-down indexOf as it's faster than native
10550 // http://jsperf.com/thor-indexof-vs-for/5
10551 indexOf = function( list, elem ) {
10552 var i = 0,
10553 len = list.length;
10554 for ( ; i < len; i++ ) {
10555 if ( list[i] === elem ) {
10556 return i;
10557 }
10558 }
10559 return -1;
10560 },
10561
10562 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
10563
10564 // Regular expressions
10565
10566 // http://www.w3.org/TR/css3-selectors/#whitespace
10567 whitespace = "[\\x20\\t\\r\\n\\f]",
10568
10569 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
10570 identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
10571
10572 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
10573 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
10574 // Operator (capture 2)
10575 "*([*^$|!~]?=)" + whitespace +
10576 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
10577 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
10578 "*\\]",
10579
10580 pseudos = ":(" + identifier + ")(?:\\((" +
10581 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
10582 // 1. quoted (capture 3; capture 4 or capture 5)
10583 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
10584 // 2. simple (capture 6)
10585 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
10586 // 3. anything else (capture 2)
10587 ".*" +
10588 ")\\)|)",
10589
10590 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
10591 rwhitespace = new RegExp( whitespace + "+", "g" ),
10592 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
10593
10594 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
10595 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
10596
10597 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
10598
10599 rpseudo = new RegExp( pseudos ),
10600 ridentifier = new RegExp( "^" + identifier + "$" ),
10601
10602 matchExpr = {
10603 "ID": new RegExp( "^#(" + identifier + ")" ),
10604 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
10605 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
10606 "ATTR": new RegExp( "^" + attributes ),
10607 "PSEUDO": new RegExp( "^" + pseudos ),
10608 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
10609 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
10610 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
10611 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
10612 // For use in libraries implementing .is()
10613 // We use this for POS matching in `select`
10614 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
10615 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
10616 },
10617
10618 rinputs = /^(?:input|select|textarea|button)$/i,
10619 rheader = /^h\d$/i,
10620
10621 rnative = /^[^{]+\{\s*\[native \w/,
10622
10623 // Easily-parseable/retrievable ID or TAG or CLASS selectors
10624 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
10625
10626 rsibling = /[+~]/,
10627 rescape = /'|\\/g,
10628
10629 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
10630 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
10631 funescape = function( _, escaped, escapedWhitespace ) {
10632 var high = "0x" + escaped - 0x10000;
10633 // NaN means non-codepoint
10634 // Support: Firefox<24
10635 // Workaround erroneous numeric interpretation of +"0x"
10636 return high !== high || escapedWhitespace ?
10637 escaped :
10638 high < 0 ?
10639 // BMP codepoint
10640 String.fromCharCode( high + 0x10000 ) :
10641 // Supplemental Plane codepoint (surrogate pair)
10642 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
10643 },
10644
10645 // Used for iframes
10646 // See setDocument()
10647 // Removing the function wrapper causes a "Permission Denied"
10648 // error in IE
10649 unloadHandler = function() {
10650 setDocument();
10651 };
10652
10653 // Optimize for push.apply( _, NodeList )
10654 try {
10655 push.apply(
10656 (arr = slice.call( preferredDoc.childNodes )),
10657 preferredDoc.childNodes
10658 );
10659 // Support: Android<4.0
10660 // Detect silently failing push.apply
10661 arr[ preferredDoc.childNodes.length ].nodeType;
10662 } catch ( e ) {
10663 push = { apply: arr.length ?
10664
10665 // Leverage slice if possible
10666 function( target, els ) {
10667 push_native.apply( target, slice.call(els) );
10668 } :
10669
10670 // Support: IE<9
10671 // Otherwise append directly
10672 function( target, els ) {
10673 var j = target.length,
10674 i = 0;
10675 // Can't trust NodeList.length
10676 while ( (target[j++] = els[i++]) ) {}
10677 target.length = j - 1;
10678 }
10679 };
10680 }
10681
10682 function Sizzle( selector, context, results, seed ) {
10683 var m, i, elem, nid, nidselect, match, groups, newSelector,
10684 newContext = context && context.ownerDocument,
10685
10686 // nodeType defaults to 9, since context defaults to document
10687 nodeType = context ? context.nodeType : 9;
10688
10689 results = results || [];
10690
10691 // Return early from calls with invalid selector or context
10692 if ( typeof selector !== "string" || !selector ||
10693 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
10694
10695 return results;
10696 }
10697
10698 // Try to shortcut find operations (as opposed to filters) in HTML documents
10699 if ( !seed ) {
10700
10701 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
10702 setDocument( context );
10703 }
10704 context = context || document;
10705
10706 if ( documentIsHTML ) {
10707
10708 // If the selector is sufficiently simple, try using a "get*By*" DOM method
10709 // (excepting DocumentFragment context, where the methods don't exist)
10710 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
10711
10712 // ID selector
10713 if ( (m = match[1]) ) {
10714
10715 // Document context
10716 if ( nodeType === 9 ) {
10717 if ( (elem = context.getElementById( m )) ) {
10718
10719 // Support: IE, Opera, Webkit
10720 // TODO: identify versions
10721 // getElementById can match elements by name instead of ID
10722 if ( elem.id === m ) {
10723 results.push( elem );
10724 return results;
10725 }
10726 } else {
10727 return results;
10728 }
10729
10730 // Element context
10731 } else {
10732
10733 // Support: IE, Opera, Webkit
10734 // TODO: identify versions
10735 // getElementById can match elements by name instead of ID
10736 if ( newContext && (elem = newContext.getElementById( m )) &&
10737 contains( context, elem ) &&
10738 elem.id === m ) {
10739
10740 results.push( elem );
10741 return results;
10742 }
10743 }
10744
10745 // Type selector
10746 } else if ( match[2] ) {
10747 push.apply( results, context.getElementsByTagName( selector ) );
10748 return results;
10749
10750 // Class selector
10751 } else if ( (m = match[3]) && support.getElementsByClassName &&
10752 context.getElementsByClassName ) {
10753
10754 push.apply( results, context.getElementsByClassName( m ) );
10755 return results;
10756 }
10757 }
10758
10759 // Take advantage of querySelectorAll
10760 if ( support.qsa &&
10761 !compilerCache[ selector + " " ] &&
10762 (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
10763
10764 if ( nodeType !== 1 ) {
10765 newContext = context;
10766 newSelector = selector;
10767
10768 // qSA looks outside Element context, which is not what we want
10769 // Thanks to Andrew Dupont for this workaround technique
10770 // Support: IE <=8
10771 // Exclude object elements
10772 } else if ( context.nodeName.toLowerCase() !== "object" ) {
10773
10774 // Capture the context ID, setting it first if necessary
10775 if ( (nid = context.getAttribute( "id" )) ) {
10776 nid = nid.replace( rescape, "\\$&" );
10777 } else {
10778 context.setAttribute( "id", (nid = expando) );
10779 }
10780
10781 // Prefix every selector in the list
10782 groups = tokenize( selector );
10783 i = groups.length;
10784 nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
10785 while ( i-- ) {
10786 groups[i] = nidselect + " " + toSelector( groups[i] );
10787 }
10788 newSelector = groups.join( "," );
10789
10790 // Expand context for sibling selectors
10791 newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
10792 context;
10793 }
10794
10795 if ( newSelector ) {
10796 try {
10797 push.apply( results,
10798 newContext.querySelectorAll( newSelector )
10799 );
10800 return results;
10801 } catch ( qsaError ) {
10802 } finally {
10803 if ( nid === expando ) {
10804 context.removeAttribute( "id" );
10805 }
10806 }
10807 }
10808 }
10809 }
10810 }
10811
10812 // All others
10813 return select( selector.replace( rtrim, "$1" ), context, results, seed );
10814 }
10815
10816 /**
10817 * Create key-value caches of limited size
10818 * @returns {function(string, object)} Returns the Object data after storing it on itself with
10819 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
10820 * deleting the oldest entry
10821 */
10822 function createCache() {
10823 var keys = [];
10824
10825 function cache( key, value ) {
10826 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
10827 if ( keys.push( key + " " ) > Expr.cacheLength ) {
10828 // Only keep the most recent entries
10829 delete cache[ keys.shift() ];
10830 }
10831 return (cache[ key + " " ] = value);
10832 }
10833 return cache;
10834 }
10835
10836 /**
10837 * Mark a function for special use by Sizzle
10838 * @param {Function} fn The function to mark
10839 */
10840 function markFunction( fn ) {
10841 fn[ expando ] = true;
10842 return fn;
10843 }
10844
10845 /**
10846 * Support testing using an element
10847 * @param {Function} fn Passed the created div and expects a boolean result
10848 */
10849 function assert( fn ) {
10850 var div = document.createElement("div");
10851
10852 try {
10853 return !!fn( div );
10854 } catch (e) {
10855 return false;
10856 } finally {
10857 // Remove from its parent by default
10858 if ( div.parentNode ) {
10859 div.parentNode.removeChild( div );
10860 }
10861 // release memory in IE
10862 div = null;
10863 }
10864 }
10865
10866 /**
10867 * Adds the same handler for all of the specified attrs
10868 * @param {String} attrs Pipe-separated list of attributes
10869 * @param {Function} handler The method that will be applied
10870 */
10871 function addHandle( attrs, handler ) {
10872 var arr = attrs.split("|"),
10873 i = arr.length;
10874
10875 while ( i-- ) {
10876 Expr.attrHandle[ arr[i] ] = handler;
10877 }
10878 }
10879
10880 /**
10881 * Checks document order of two siblings
10882 * @param {Element} a
10883 * @param {Element} b
10884 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
10885 */
10886 function siblingCheck( a, b ) {
10887 var cur = b && a,
10888 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
10889 ( ~b.sourceIndex || MAX_NEGATIVE ) -
10890 ( ~a.sourceIndex || MAX_NEGATIVE );
10891
10892 // Use IE sourceIndex if available on both nodes
10893 if ( diff ) {
10894 return diff;
10895 }
10896
10897 // Check if b follows a
10898 if ( cur ) {
10899 while ( (cur = cur.nextSibling) ) {
10900 if ( cur === b ) {
10901 return -1;
10902 }
10903 }
10904 }
10905
10906 return a ? 1 : -1;
10907 }
10908
10909 /**
10910 * Returns a function to use in pseudos for input types
10911 * @param {String} type
10912 */
10913 function createInputPseudo( type ) {
10914 return function( elem ) {
10915 var name = elem.nodeName.toLowerCase();
10916 return name === "input" && elem.type === type;
10917 };
10918 }
10919
10920 /**
10921 * Returns a function to use in pseudos for buttons
10922 * @param {String} type
10923 */
10924 function createButtonPseudo( type ) {
10925 return function( elem ) {
10926 var name = elem.nodeName.toLowerCase();
10927 return (name === "input" || name === "button") && elem.type === type;
10928 };
10929 }
10930
10931 /**
10932 * Returns a function to use in pseudos for positionals
10933 * @param {Function} fn
10934 */
10935 function createPositionalPseudo( fn ) {
10936 return markFunction(function( argument ) {
10937 argument = +argument;
10938 return markFunction(function( seed, matches ) {
10939 var j,
10940 matchIndexes = fn( [], seed.length, argument ),
10941 i = matchIndexes.length;
10942
10943 // Match elements found at the specified indexes
10944 while ( i-- ) {
10945 if ( seed[ (j = matchIndexes[i]) ] ) {
10946 seed[j] = !(matches[j] = seed[j]);
10947 }
10948 }
10949 });
10950 });
10951 }
10952
10953 /**
10954 * Checks a node for validity as a Sizzle context
10955 * @param {Element|Object=} context
10956 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
10957 */
10958 function testContext( context ) {
10959 return context && typeof context.getElementsByTagName !== "undefined" && context;
10960 }
10961
10962 // Expose support vars for convenience
10963 support = Sizzle.support = {};
10964
10965 /**
10966 * Detects XML nodes
10967 * @param {Element|Object} elem An element or a document
10968 * @returns {Boolean} True iff elem is a non-HTML XML node
10969 */
10970 isXML = Sizzle.isXML = function( elem ) {
10971 // documentElement is verified for cases where it doesn't yet exist
10972 // (such as loading iframes in IE - #4833)
10973 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
10974 return documentElement ? documentElement.nodeName !== "HTML" : false;
10975 };
10976
10977 /**
10978 * Sets document-related variables once based on the current document
10979 * @param {Element|Object} [doc] An element or document object to use to set the document
10980 * @returns {Object} Returns the current document
10981 */
10982 setDocument = Sizzle.setDocument = function( node ) {
10983 var hasCompare, parent,
10984 doc = node ? node.ownerDocument || node : preferredDoc;
10985
10986 // Return early if doc is invalid or already selected
10987 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
10988 return document;
10989 }
10990
10991 // Update global variables
10992 document = doc;
10993 docElem = document.documentElement;
10994 documentIsHTML = !isXML( document );
10995
10996 // Support: IE 9-11, Edge
10997 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
10998 if ( (parent = document.defaultView) && parent.top !== parent ) {
10999 // Support: IE 11
11000 if ( parent.addEventListener ) {
11001 parent.addEventListener( "unload", unloadHandler, false );
11002
11003 // Support: IE 9 - 10 only
11004 } else if ( parent.attachEvent ) {
11005 parent.attachEvent( "onunload", unloadHandler );
11006 }
11007 }
11008
11009 /* Attributes
11010 ---------------------------------------------------------------------- */
11011
11012 // Support: IE<8
11013 // Verify that getAttribute really returns attributes and not properties
11014 // (excepting IE8 booleans)
11015 support.attributes = assert(function( div ) {
11016 div.className = "i";
11017 return !div.getAttribute("className");
11018 });
11019
11020 /* getElement(s)By*
11021 ---------------------------------------------------------------------- */
11022
11023 // Check if getElementsByTagName("*") returns only elements
11024 support.getElementsByTagName = assert(function( div ) {
11025 div.appendChild( document.createComment("") );
11026 return !div.getElementsByTagName("*").length;
11027 });
11028
11029 // Support: IE<9
11030 support.getElementsByClassName = rnative.test( document.getElementsByClassName );
11031
11032 // Support: IE<10
11033 // Check if getElementById returns elements by name
11034 // The broken getElementById methods don't pick up programatically-set names,
11035 // so use a roundabout getElementsByName test
11036 support.getById = assert(function( div ) {
11037 docElem.appendChild( div ).id = expando;
11038 return !document.getElementsByName || !document.getElementsByName( expando ).length;
11039 });
11040
11041 // ID find and filter
11042 if ( support.getById ) {
11043 Expr.find["ID"] = function( id, context ) {
11044 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
11045 var m = context.getElementById( id );
11046 return m ? [ m ] : [];
11047 }
11048 };
11049 Expr.filter["ID"] = function( id ) {
11050 var attrId = id.replace( runescape, funescape );
11051 return function( elem ) {
11052 return elem.getAttribute("id") === attrId;
11053 };
11054 };
11055 } else {
11056 // Support: IE6/7
11057 // getElementById is not reliable as a find shortcut
11058 delete Expr.find["ID"];
11059
11060 Expr.filter["ID"] = function( id ) {
11061 var attrId = id.replace( runescape, funescape );
11062 return function( elem ) {
11063 var node = typeof elem.getAttributeNode !== "undefined" &&
11064 elem.getAttributeNode("id");
11065 return node && node.value === attrId;
11066 };
11067 };
11068 }
11069
11070 // Tag
11071 Expr.find["TAG"] = support.getElementsByTagName ?
11072 function( tag, context ) {
11073 if ( typeof context.getElementsByTagName !== "undefined" ) {
11074 return context.getElementsByTagName( tag );
11075
11076 // DocumentFragment nodes don't have gEBTN
11077 } else if ( support.qsa ) {
11078 return context.querySelectorAll( tag );
11079 }
11080 } :
11081
11082 function( tag, context ) {
11083 var elem,
11084 tmp = [],
11085 i = 0,
11086 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
11087 results = context.getElementsByTagName( tag );
11088
11089 // Filter out possible comments
11090 if ( tag === "*" ) {
11091 while ( (elem = results[i++]) ) {
11092 if ( elem.nodeType === 1 ) {
11093 tmp.push( elem );
11094 }
11095 }
11096
11097 return tmp;
11098 }
11099 return results;
11100 };
11101
11102 // Class
11103 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
11104 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
11105 return context.getElementsByClassName( className );
11106 }
11107 };
11108
11109 /* QSA/matchesSelector
11110 ---------------------------------------------------------------------- */
11111
11112 // QSA and matchesSelector support
11113
11114 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
11115 rbuggyMatches = [];
11116
11117 // qSa(:focus) reports false when true (Chrome 21)
11118 // We allow this because of a bug in IE8/9 that throws an error
11119 // whenever `document.activeElement` is accessed on an iframe
11120 // So, we allow :focus to pass through QSA all the time to avoid the IE error
11121 // See http://bugs.jquery.com/ticket/13378
11122 rbuggyQSA = [];
11123
11124 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
11125 // Build QSA regex
11126 // Regex strategy adopted from Diego Perini
11127 assert(function( div ) {
11128 // Select is set to empty string on purpose
11129 // This is to test IE's treatment of not explicitly
11130 // setting a boolean content attribute,
11131 // since its presence should be enough
11132 // http://bugs.jquery.com/ticket/12359
11133 docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
11134 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
11135 "<option selected=''></option></select>";
11136
11137 // Support: IE8, Opera 11-12.16
11138 // Nothing should be selected when empty strings follow ^= or $= or *=
11139 // The test attribute must be unknown in Opera but "safe" for WinRT
11140 // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
11141 if ( div.querySelectorAll("[msallowcapture^='']").length ) {
11142 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
11143 }
11144
11145 // Support: IE8
11146 // Boolean attributes and "value" are not treated correctly
11147 if ( !div.querySelectorAll("[selected]").length ) {
11148 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
11149 }
11150
11151 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
11152 if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
11153 rbuggyQSA.push("~=");
11154 }
11155
11156 // Webkit/Opera - :checked should return selected option elements
11157 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
11158 // IE8 throws error here and will not see later tests
11159 if ( !div.querySelectorAll(":checked").length ) {
11160 rbuggyQSA.push(":checked");
11161 }
11162
11163 // Support: Safari 8+, iOS 8+
11164 // https://bugs.webkit.org/show_bug.cgi?id=136851
11165 // In-page `selector#id sibing-combinator selector` fails
11166 if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
11167 rbuggyQSA.push(".#.+[+~]");
11168 }
11169 });
11170
11171 assert(function( div ) {
11172 // Support: Windows 8 Native Apps
11173 // The type and name attributes are restricted during .innerHTML assignment
11174 var input = document.createElement("input");
11175 input.setAttribute( "type", "hidden" );
11176 div.appendChild( input ).setAttribute( "name", "D" );
11177
11178 // Support: IE8
11179 // Enforce case-sensitivity of name attribute
11180 if ( div.querySelectorAll("[name=d]").length ) {
11181 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
11182 }
11183
11184 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
11185 // IE8 throws error here and will not see later tests
11186 if ( !div.querySelectorAll(":enabled").length ) {
11187 rbuggyQSA.push( ":enabled", ":disabled" );
11188 }
11189
11190 // Opera 10-11 does not throw on post-comma invalid pseudos
11191 div.querySelectorAll("*,:x");
11192 rbuggyQSA.push(",.*:");
11193 });
11194 }
11195
11196 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
11197 docElem.webkitMatchesSelector ||
11198 docElem.mozMatchesSelector ||
11199 docElem.oMatchesSelector ||
11200 docElem.msMatchesSelector) )) ) {
11201
11202 assert(function( div ) {
11203 // Check to see if it's possible to do matchesSelector
11204 // on a disconnected node (IE 9)
11205 support.disconnectedMatch = matches.call( div, "div" );
11206
11207 // This should fail with an exception
11208 // Gecko does not error, returns false instead
11209 matches.call( div, "[s!='']:x" );
11210 rbuggyMatches.push( "!=", pseudos );
11211 });
11212 }
11213
11214 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
11215 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
11216
11217 /* Contains
11218 ---------------------------------------------------------------------- */
11219 hasCompare = rnative.test( docElem.compareDocumentPosition );
11220
11221 // Element contains another
11222 // Purposefully self-exclusive
11223 // As in, an element does not contain itself
11224 contains = hasCompare || rnative.test( docElem.contains ) ?
11225 function( a, b ) {
11226 var adown = a.nodeType === 9 ? a.documentElement : a,
11227 bup = b && b.parentNode;
11228 return a === bup || !!( bup && bup.nodeType === 1 && (
11229 adown.contains ?
11230 adown.contains( bup ) :
11231 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
11232 ));
11233 } :
11234 function( a, b ) {
11235 if ( b ) {
11236 while ( (b = b.parentNode) ) {
11237 if ( b === a ) {
11238 return true;
11239 }
11240 }
11241 }
11242 return false;
11243 };
11244
11245 /* Sorting
11246 ---------------------------------------------------------------------- */
11247
11248 // Document order sorting
11249 sortOrder = hasCompare ?
11250 function( a, b ) {
11251
11252 // Flag for duplicate removal
11253 if ( a === b ) {
11254 hasDuplicate = true;
11255 return 0;
11256 }
11257
11258 // Sort on method existence if only one input has compareDocumentPosition
11259 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
11260 if ( compare ) {
11261 return compare;
11262 }
11263
11264 // Calculate position if both inputs belong to the same document
11265 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
11266 a.compareDocumentPosition( b ) :
11267
11268 // Otherwise we know they are disconnected
11269 1;
11270
11271 // Disconnected nodes
11272 if ( compare & 1 ||
11273 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
11274
11275 // Choose the first element that is related to our preferred document
11276 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
11277 return -1;
11278 }
11279 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
11280 return 1;
11281 }
11282
11283 // Maintain original order
11284 return sortInput ?
11285 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
11286 0;
11287 }
11288
11289 return compare & 4 ? -1 : 1;
11290 } :
11291 function( a, b ) {
11292 // Exit early if the nodes are identical
11293 if ( a === b ) {
11294 hasDuplicate = true;
11295 return 0;
11296 }
11297
11298 var cur,
11299 i = 0,
11300 aup = a.parentNode,
11301 bup = b.parentNode,
11302 ap = [ a ],
11303 bp = [ b ];
11304
11305 // Parentless nodes are either documents or disconnected
11306 if ( !aup || !bup ) {
11307 return a === document ? -1 :
11308 b === document ? 1 :
11309 aup ? -1 :
11310 bup ? 1 :
11311 sortInput ?
11312 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
11313 0;
11314
11315 // If the nodes are siblings, we can do a quick check
11316 } else if ( aup === bup ) {
11317 return siblingCheck( a, b );
11318 }
11319
11320 // Otherwise we need full lists of their ancestors for comparison
11321 cur = a;
11322 while ( (cur = cur.parentNode) ) {
11323 ap.unshift( cur );
11324 }
11325 cur = b;
11326 while ( (cur = cur.parentNode) ) {
11327 bp.unshift( cur );
11328 }
11329
11330 // Walk down the tree looking for a discrepancy
11331 while ( ap[i] === bp[i] ) {
11332 i++;
11333 }
11334
11335 return i ?
11336 // Do a sibling check if the nodes have a common ancestor
11337 siblingCheck( ap[i], bp[i] ) :
11338
11339 // Otherwise nodes in our document sort first
11340 ap[i] === preferredDoc ? -1 :
11341 bp[i] === preferredDoc ? 1 :
11342 0;
11343 };
11344
11345 return document;
11346 };
11347
11348 Sizzle.matches = function( expr, elements ) {
11349 return Sizzle( expr, null, null, elements );
11350 };
11351
11352 Sizzle.matchesSelector = function( elem, expr ) {
11353 // Set document vars if needed
11354 if ( ( elem.ownerDocument || elem ) !== document ) {
11355 setDocument( elem );
11356 }
11357
11358 // Make sure that attribute selectors are quoted
11359 expr = expr.replace( rattributeQuotes, "='$1']" );
11360
11361 if ( support.matchesSelector && documentIsHTML &&
11362 !compilerCache[ expr + " " ] &&
11363 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
11364 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
11365
11366 try {
11367 var ret = matches.call( elem, expr );
11368
11369 // IE 9's matchesSelector returns false on disconnected nodes
11370 if ( ret || support.disconnectedMatch ||
11371 // As well, disconnected nodes are said to be in a document
11372 // fragment in IE 9
11373 elem.document && elem.document.nodeType !== 11 ) {
11374 return ret;
11375 }
11376 } catch (e) {}
11377 }
11378
11379 return Sizzle( expr, document, null, [ elem ] ).length > 0;
11380 };
11381
11382 Sizzle.contains = function( context, elem ) {
11383 // Set document vars if needed
11384 if ( ( context.ownerDocument || context ) !== document ) {
11385 setDocument( context );
11386 }
11387 return contains( context, elem );
11388 };
11389
11390 Sizzle.attr = function( elem, name ) {
11391 // Set document vars if needed
11392 if ( ( elem.ownerDocument || elem ) !== document ) {
11393 setDocument( elem );
11394 }
11395
11396 var fn = Expr.attrHandle[ name.toLowerCase() ],
11397 // Don't get fooled by Object.prototype properties (jQuery #13807)
11398 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
11399 fn( elem, name, !documentIsHTML ) :
11400 undefined;
11401
11402 return val !== undefined ?
11403 val :
11404 support.attributes || !documentIsHTML ?
11405 elem.getAttribute( name ) :
11406 (val = elem.getAttributeNode(name)) && val.specified ?
11407 val.value :
11408 null;
11409 };
11410
11411 Sizzle.error = function( msg ) {
11412 throw new Error( "Syntax error, unrecognized expression: " + msg );
11413 };
11414
11415 /**
11416 * Document sorting and removing duplicates
11417 * @param {ArrayLike} results
11418 */
11419 Sizzle.uniqueSort = function( results ) {
11420 var elem,
11421 duplicates = [],
11422 j = 0,
11423 i = 0;
11424
11425 // Unless we *know* we can detect duplicates, assume their presence
11426 hasDuplicate = !support.detectDuplicates;
11427 sortInput = !support.sortStable && results.slice( 0 );
11428 results.sort( sortOrder );
11429
11430 if ( hasDuplicate ) {
11431 while ( (elem = results[i++]) ) {
11432 if ( elem === results[ i ] ) {
11433 j = duplicates.push( i );
11434 }
11435 }
11436 while ( j-- ) {
11437 results.splice( duplicates[ j ], 1 );
11438 }
11439 }
11440
11441 // Clear input after sorting to release objects
11442 // See https://github.com/jquery/sizzle/pull/225
11443 sortInput = null;
11444
11445 return results;
11446 };
11447
11448 /**
11449 * Utility function for retrieving the text value of an array of DOM nodes
11450 * @param {Array|Element} elem
11451 */
11452 getText = Sizzle.getText = function( elem ) {
11453 var node,
11454 ret = "",
11455 i = 0,
11456 nodeType = elem.nodeType;
11457
11458 if ( !nodeType ) {
11459 // If no nodeType, this is expected to be an array
11460 while ( (node = elem[i++]) ) {
11461 // Do not traverse comment nodes
11462 ret += getText( node );
11463 }
11464 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
11465 // Use textContent for elements
11466 // innerText usage removed for consistency of new lines (jQuery #11153)
11467 if ( typeof elem.textContent === "string" ) {
11468 return elem.textContent;
11469 } else {
11470 // Traverse its children
11471 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
11472 ret += getText( elem );
11473 }
11474 }
11475 } else if ( nodeType === 3 || nodeType === 4 ) {
11476 return elem.nodeValue;
11477 }
11478 // Do not include comment or processing instruction nodes
11479
11480 return ret;
11481 };
11482
11483 Expr = Sizzle.selectors = {
11484
11485 // Can be adjusted by the user
11486 cacheLength: 50,
11487
11488 createPseudo: markFunction,
11489
11490 match: matchExpr,
11491
11492 attrHandle: {},
11493
11494 find: {},
11495
11496 relative: {
11497 ">": { dir: "parentNode", first: true },
11498 " ": { dir: "parentNode" },
11499 "+": { dir: "previousSibling", first: true },
11500 "~": { dir: "previousSibling" }
11501 },
11502
11503 preFilter: {
11504 "ATTR": function( match ) {
11505 match[1] = match[1].replace( runescape, funescape );
11506
11507 // Move the given value to match[3] whether quoted or unquoted
11508 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
11509
11510 if ( match[2] === "~=" ) {
11511 match[3] = " " + match[3] + " ";
11512 }
11513
11514 return match.slice( 0, 4 );
11515 },
11516
11517 "CHILD": function( match ) {
11518 /* matches from matchExpr["CHILD"]
11519 1 type (only|nth|...)
11520 2 what (child|of-type)
11521 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
11522 4 xn-component of xn+y argument ([+-]?\d*n|)
11523 5 sign of xn-component
11524 6 x of xn-component
11525 7 sign of y-component
11526 8 y of y-component
11527 */
11528 match[1] = match[1].toLowerCase();
11529
11530 if ( match[1].slice( 0, 3 ) === "nth" ) {
11531 // nth-* requires argument
11532 if ( !match[3] ) {
11533 Sizzle.error( match[0] );
11534 }
11535
11536 // numeric x and y parameters for Expr.filter.CHILD
11537 // remember that false/true cast respectively to 0/1
11538 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
11539 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
11540
11541 // other types prohibit arguments
11542 } else if ( match[3] ) {
11543 Sizzle.error( match[0] );
11544 }
11545
11546 return match;
11547 },
11548
11549 "PSEUDO": function( match ) {
11550 var excess,
11551 unquoted = !match[6] && match[2];
11552
11553 if ( matchExpr["CHILD"].test( match[0] ) ) {
11554 return null;
11555 }
11556
11557 // Accept quoted arguments as-is
11558 if ( match[3] ) {
11559 match[2] = match[4] || match[5] || "";
11560
11561 // Strip excess characters from unquoted arguments
11562 } else if ( unquoted && rpseudo.test( unquoted ) &&
11563 // Get excess from tokenize (recursively)
11564 (excess = tokenize( unquoted, true )) &&
11565 // advance to the next closing parenthesis
11566 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
11567
11568 // excess is a negative index
11569 match[0] = match[0].slice( 0, excess );
11570 match[2] = unquoted.slice( 0, excess );
11571 }
11572
11573 // Return only captures needed by the pseudo filter method (type and argument)
11574 return match.slice( 0, 3 );
11575 }
11576 },
11577
11578 filter: {
11579
11580 "TAG": function( nodeNameSelector ) {
11581 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
11582 return nodeNameSelector === "*" ?
11583 function() { return true; } :
11584 function( elem ) {
11585 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
11586 };
11587 },
11588
11589 "CLASS": function( className ) {
11590 var pattern = classCache[ className + " " ];
11591
11592 return pattern ||
11593 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
11594 classCache( className, function( elem ) {
11595 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
11596 });
11597 },
11598
11599 "ATTR": function( name, operator, check ) {
11600 return function( elem ) {
11601 var result = Sizzle.attr( elem, name );
11602
11603 if ( result == null ) {
11604 return operator === "!=";
11605 }
11606 if ( !operator ) {
11607 return true;
11608 }
11609
11610 result += "";
11611
11612 return operator === "=" ? result === check :
11613 operator === "!=" ? result !== check :
11614 operator === "^=" ? check && result.indexOf( check ) === 0 :
11615 operator === "*=" ? check && result.indexOf( check ) > -1 :
11616 operator === "$=" ? check && result.slice( -check.length ) === check :
11617 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
11618 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
11619 false;
11620 };
11621 },
11622
11623 "CHILD": function( type, what, argument, first, last ) {
11624 var simple = type.slice( 0, 3 ) !== "nth",
11625 forward = type.slice( -4 ) !== "last",
11626 ofType = what === "of-type";
11627
11628 return first === 1 && last === 0 ?
11629
11630 // Shortcut for :nth-*(n)
11631 function( elem ) {
11632 return !!elem.parentNode;
11633 } :
11634
11635 function( elem, context, xml ) {
11636 var cache, uniqueCache, outerCache, node, nodeIndex, start,
11637 dir = simple !== forward ? "nextSibling" : "previousSibling",
11638 parent = elem.parentNode,
11639 name = ofType && elem.nodeName.toLowerCase(),
11640 useCache = !xml && !ofType,
11641 diff = false;
11642
11643 if ( parent ) {
11644
11645 // :(first|last|only)-(child|of-type)
11646 if ( simple ) {
11647 while ( dir ) {
11648 node = elem;
11649 while ( (node = node[ dir ]) ) {
11650 if ( ofType ?
11651 node.nodeName.toLowerCase() === name :
11652 node.nodeType === 1 ) {
11653
11654 return false;
11655 }
11656 }
11657 // Reverse direction for :only-* (if we haven't yet done so)
11658 start = dir = type === "only" && !start && "nextSibling";
11659 }
11660 return true;
11661 }
11662
11663 start = [ forward ? parent.firstChild : parent.lastChild ];
11664
11665 // non-xml :nth-child(...) stores cache data on `parent`
11666 if ( forward && useCache ) {
11667
11668 // Seek `elem` from a previously-cached index
11669
11670 // ...in a gzip-friendly way
11671 node = parent;
11672 outerCache = node[ expando ] || (node[ expando ] = {});
11673
11674 // Support: IE <9 only
11675 // Defend against cloned attroperties (jQuery gh-1709)
11676 uniqueCache = outerCache[ node.uniqueID ] ||
11677 (outerCache[ node.uniqueID ] = {});
11678
11679 cache = uniqueCache[ type ] || [];
11680 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
11681 diff = nodeIndex && cache[ 2 ];
11682 node = nodeIndex && parent.childNodes[ nodeIndex ];
11683
11684 while ( (node = ++nodeIndex && node && node[ dir ] ||
11685
11686 // Fallback to seeking `elem` from the start
11687 (diff = nodeIndex = 0) || start.pop()) ) {
11688
11689 // When found, cache indexes on `parent` and break
11690 if ( node.nodeType === 1 && ++diff && node === elem ) {
11691 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
11692 break;
11693 }
11694 }
11695
11696 } else {
11697 // Use previously-cached element index if available
11698 if ( useCache ) {
11699 // ...in a gzip-friendly way
11700 node = elem;
11701 outerCache = node[ expando ] || (node[ expando ] = {});
11702
11703 // Support: IE <9 only
11704 // Defend against cloned attroperties (jQuery gh-1709)
11705 uniqueCache = outerCache[ node.uniqueID ] ||
11706 (outerCache[ node.uniqueID ] = {});
11707
11708 cache = uniqueCache[ type ] || [];
11709 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
11710 diff = nodeIndex;
11711 }
11712
11713 // xml :nth-child(...)
11714 // or :nth-last-child(...) or :nth(-last)?-of-type(...)
11715 if ( diff === false ) {
11716 // Use the same loop as above to seek `elem` from the start
11717 while ( (node = ++nodeIndex && node && node[ dir ] ||
11718 (diff = nodeIndex = 0) || start.pop()) ) {
11719
11720 if ( ( ofType ?
11721 node.nodeName.toLowerCase() === name :
11722 node.nodeType === 1 ) &&
11723 ++diff ) {
11724
11725 // Cache the index of each encountered element
11726 if ( useCache ) {
11727 outerCache = node[ expando ] || (node[ expando ] = {});
11728
11729 // Support: IE <9 only
11730 // Defend against cloned attroperties (jQuery gh-1709)
11731 uniqueCache = outerCache[ node.uniqueID ] ||
11732 (outerCache[ node.uniqueID ] = {});
11733
11734 uniqueCache[ type ] = [ dirruns, diff ];
11735 }
11736
11737 if ( node === elem ) {
11738 break;
11739 }
11740 }
11741 }
11742 }
11743 }
11744
11745 // Incorporate the offset, then check against cycle size
11746 diff -= last;
11747 return diff === first || ( diff % first === 0 && diff / first >= 0 );
11748 }
11749 };
11750 },
11751
11752 "PSEUDO": function( pseudo, argument ) {
11753 // pseudo-class names are case-insensitive
11754 // http://www.w3.org/TR/selectors/#pseudo-classes
11755 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
11756 // Remember that setFilters inherits from pseudos
11757 var args,
11758 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
11759 Sizzle.error( "unsupported pseudo: " + pseudo );
11760
11761 // The user may use createPseudo to indicate that
11762 // arguments are needed to create the filter function
11763 // just as Sizzle does
11764 if ( fn[ expando ] ) {
11765 return fn( argument );
11766 }
11767
11768 // But maintain support for old signatures
11769 if ( fn.length > 1 ) {
11770 args = [ pseudo, pseudo, "", argument ];
11771 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
11772 markFunction(function( seed, matches ) {
11773 var idx,
11774 matched = fn( seed, argument ),
11775 i = matched.length;
11776 while ( i-- ) {
11777 idx = indexOf( seed, matched[i] );
11778 seed[ idx ] = !( matches[ idx ] = matched[i] );
11779 }
11780 }) :
11781 function( elem ) {
11782 return fn( elem, 0, args );
11783 };
11784 }
11785
11786 return fn;
11787 }
11788 },
11789
11790 pseudos: {
11791 // Potentially complex pseudos
11792 "not": markFunction(function( selector ) {
11793 // Trim the selector passed to compile
11794 // to avoid treating leading and trailing
11795 // spaces as combinators
11796 var input = [],
11797 results = [],
11798 matcher = compile( selector.replace( rtrim, "$1" ) );
11799
11800 return matcher[ expando ] ?
11801 markFunction(function( seed, matches, context, xml ) {
11802 var elem,
11803 unmatched = matcher( seed, null, xml, [] ),
11804 i = seed.length;
11805
11806 // Match elements unmatched by `matcher`
11807 while ( i-- ) {
11808 if ( (elem = unmatched[i]) ) {
11809 seed[i] = !(matches[i] = elem);
11810 }
11811 }
11812 }) :
11813 function( elem, context, xml ) {
11814 input[0] = elem;
11815 matcher( input, null, xml, results );
11816 // Don't keep the element (issue #299)
11817 input[0] = null;
11818 return !results.pop();
11819 };
11820 }),
11821
11822 "has": markFunction(function( selector ) {
11823 return function( elem ) {
11824 return Sizzle( selector, elem ).length > 0;
11825 };
11826 }),
11827
11828 "contains": markFunction(function( text ) {
11829 text = text.replace( runescape, funescape );
11830 return function( elem ) {
11831 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
11832 };
11833 }),
11834
11835 // "Whether an element is represented by a :lang() selector
11836 // is based solely on the element's language value
11837 // being equal to the identifier C,
11838 // or beginning with the identifier C immediately followed by "-".
11839 // The matching of C against the element's language value is performed case-insensitively.
11840 // The identifier C does not have to be a valid language name."
11841 // http://www.w3.org/TR/selectors/#lang-pseudo
11842 "lang": markFunction( function( lang ) {
11843 // lang value must be a valid identifier
11844 if ( !ridentifier.test(lang || "") ) {
11845 Sizzle.error( "unsupported lang: " + lang );
11846 }
11847 lang = lang.replace( runescape, funescape ).toLowerCase();
11848 return function( elem ) {
11849 var elemLang;
11850 do {
11851 if ( (elemLang = documentIsHTML ?
11852 elem.lang :
11853 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
11854
11855 elemLang = elemLang.toLowerCase();
11856 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
11857 }
11858 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
11859 return false;
11860 };
11861 }),
11862
11863 // Miscellaneous
11864 "target": function( elem ) {
11865 var hash = window.location && window.location.hash;
11866 return hash && hash.slice( 1 ) === elem.id;
11867 },
11868
11869 "root": function( elem ) {
11870 return elem === docElem;
11871 },
11872
11873 "focus": function( elem ) {
11874 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
11875 },
11876
11877 // Boolean properties
11878 "enabled": function( elem ) {
11879 return elem.disabled === false;
11880 },
11881
11882 "disabled": function( elem ) {
11883 return elem.disabled === true;
11884 },
11885
11886 "checked": function( elem ) {
11887 // In CSS3, :checked should return both checked and selected elements
11888 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
11889 var nodeName = elem.nodeName.toLowerCase();
11890 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
11891 },
11892
11893 "selected": function( elem ) {
11894 // Accessing this property makes selected-by-default
11895 // options in Safari work properly
11896 if ( elem.parentNode ) {
11897 elem.parentNode.selectedIndex;
11898 }
11899
11900 return elem.selected === true;
11901 },
11902
11903 // Contents
11904 "empty": function( elem ) {
11905 // http://www.w3.org/TR/selectors/#empty-pseudo
11906 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
11907 // but not by others (comment: 8; processing instruction: 7; etc.)
11908 // nodeType < 6 works because attributes (2) do not appear as children
11909 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
11910 if ( elem.nodeType < 6 ) {
11911 return false;
11912 }
11913 }
11914 return true;
11915 },
11916
11917 "parent": function( elem ) {
11918 return !Expr.pseudos["empty"]( elem );
11919 },
11920
11921 // Element/input types
11922 "header": function( elem ) {
11923 return rheader.test( elem.nodeName );
11924 },
11925
11926 "input": function( elem ) {
11927 return rinputs.test( elem.nodeName );
11928 },
11929
11930 "button": function( elem ) {
11931 var name = elem.nodeName.toLowerCase();
11932 return name === "input" && elem.type === "button" || name === "button";
11933 },
11934
11935 "text": function( elem ) {
11936 var attr;
11937 return elem.nodeName.toLowerCase() === "input" &&
11938 elem.type === "text" &&
11939
11940 // Support: IE<8
11941 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
11942 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
11943 },
11944
11945 // Position-in-collection
11946 "first": createPositionalPseudo(function() {
11947 return [ 0 ];
11948 }),
11949
11950 "last": createPositionalPseudo(function( matchIndexes, length ) {
11951 return [ length - 1 ];
11952 }),
11953
11954 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
11955 return [ argument < 0 ? argument + length : argument ];
11956 }),
11957
11958 "even": createPositionalPseudo(function( matchIndexes, length ) {
11959 var i = 0;
11960 for ( ; i < length; i += 2 ) {
11961 matchIndexes.push( i );
11962 }
11963 return matchIndexes;
11964 }),
11965
11966 "odd": createPositionalPseudo(function( matchIndexes, length ) {
11967 var i = 1;
11968 for ( ; i < length; i += 2 ) {
11969 matchIndexes.push( i );
11970 }
11971 return matchIndexes;
11972 }),
11973
11974 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
11975 var i = argument < 0 ? argument + length : argument;
11976 for ( ; --i >= 0; ) {
11977 matchIndexes.push( i );
11978 }
11979 return matchIndexes;
11980 }),
11981
11982 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
11983 var i = argument < 0 ? argument + length : argument;
11984 for ( ; ++i < length; ) {
11985 matchIndexes.push( i );
11986 }
11987 return matchIndexes;
11988 })
11989 }
11990 };
11991
11992 Expr.pseudos["nth"] = Expr.pseudos["eq"];
11993
11994 // Add button/input type pseudos
11995 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
11996 Expr.pseudos[ i ] = createInputPseudo( i );
11997 }
11998 for ( i in { submit: true, reset: true } ) {
11999 Expr.pseudos[ i ] = createButtonPseudo( i );
12000 }
12001
12002 // Easy API for creating new setFilters
12003 function setFilters() {}
12004 setFilters.prototype = Expr.filters = Expr.pseudos;
12005 Expr.setFilters = new setFilters();
12006
12007 tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
12008 var matched, match, tokens, type,
12009 soFar, groups, preFilters,
12010 cached = tokenCache[ selector + " " ];
12011
12012 if ( cached ) {
12013 return parseOnly ? 0 : cached.slice( 0 );
12014 }
12015
12016 soFar = selector;
12017 groups = [];
12018 preFilters = Expr.preFilter;
12019
12020 while ( soFar ) {
12021
12022 // Comma and first run
12023 if ( !matched || (match = rcomma.exec( soFar )) ) {
12024 if ( match ) {
12025 // Don't consume trailing commas as valid
12026 soFar = soFar.slice( match[0].length ) || soFar;
12027 }
12028 groups.push( (tokens = []) );
12029 }
12030
12031 matched = false;
12032
12033 // Combinators
12034 if ( (match = rcombinators.exec( soFar )) ) {
12035 matched = match.shift();
12036 tokens.push({
12037 value: matched,
12038 // Cast descendant combinators to space
12039 type: match[0].replace( rtrim, " " )
12040 });
12041 soFar = soFar.slice( matched.length );
12042 }
12043
12044 // Filters
12045 for ( type in Expr.filter ) {
12046 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
12047 (match = preFilters[ type ]( match ))) ) {
12048 matched = match.shift();
12049 tokens.push({
12050 value: matched,
12051 type: type,
12052 matches: match
12053 });
12054 soFar = soFar.slice( matched.length );
12055 }
12056 }
12057
12058 if ( !matched ) {
12059 break;
12060 }
12061 }
12062
12063 // Return the length of the invalid excess
12064 // if we're just parsing
12065 // Otherwise, throw an error or return tokens
12066 return parseOnly ?
12067 soFar.length :
12068 soFar ?
12069 Sizzle.error( selector ) :
12070 // Cache the tokens
12071 tokenCache( selector, groups ).slice( 0 );
12072 };
12073
12074 function toSelector( tokens ) {
12075 var i = 0,
12076 len = tokens.length,
12077 selector = "";
12078 for ( ; i < len; i++ ) {
12079 selector += tokens[i].value;
12080 }
12081 return selector;
12082 }
12083
12084 function addCombinator( matcher, combinator, base ) {
12085 var dir = combinator.dir,
12086 checkNonElements = base && dir === "parentNode",
12087 doneName = done++;
12088
12089 return combinator.first ?
12090 // Check against closest ancestor/preceding element
12091 function( elem, context, xml ) {
12092 while ( (elem = elem[ dir ]) ) {
12093 if ( elem.nodeType === 1 || checkNonElements ) {
12094 return matcher( elem, context, xml );
12095 }
12096 }
12097 } :
12098
12099 // Check against all ancestor/preceding elements
12100 function( elem, context, xml ) {
12101 var oldCache, uniqueCache, outerCache,
12102 newCache = [ dirruns, doneName ];
12103
12104 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
12105 if ( xml ) {
12106 while ( (elem = elem[ dir ]) ) {
12107 if ( elem.nodeType === 1 || checkNonElements ) {
12108 if ( matcher( elem, context, xml ) ) {
12109 return true;
12110 }
12111 }
12112 }
12113 } else {
12114 while ( (elem = elem[ dir ]) ) {
12115 if ( elem.nodeType === 1 || checkNonElements ) {
12116 outerCache = elem[ expando ] || (elem[ expando ] = {});
12117
12118 // Support: IE <9 only
12119 // Defend against cloned attroperties (jQuery gh-1709)
12120 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
12121
12122 if ( (oldCache = uniqueCache[ dir ]) &&
12123 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
12124
12125 // Assign to newCache so results back-propagate to previous elements
12126 return (newCache[ 2 ] = oldCache[ 2 ]);
12127 } else {
12128 // Reuse newcache so results back-propagate to previous elements
12129 uniqueCache[ dir ] = newCache;
12130
12131 // A match means we're done; a fail means we have to keep checking
12132 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
12133 return true;
12134 }
12135 }
12136 }
12137 }
12138 }
12139 };
12140 }
12141
12142 function elementMatcher( matchers ) {
12143 return matchers.length > 1 ?
12144 function( elem, context, xml ) {
12145 var i = matchers.length;
12146 while ( i-- ) {
12147 if ( !matchers[i]( elem, context, xml ) ) {
12148 return false;
12149 }
12150 }
12151 return true;
12152 } :
12153 matchers[0];
12154 }
12155
12156 function multipleContexts( selector, contexts, results ) {
12157 var i = 0,
12158 len = contexts.length;
12159 for ( ; i < len; i++ ) {
12160 Sizzle( selector, contexts[i], results );
12161 }
12162 return results;
12163 }
12164
12165 function condense( unmatched, map, filter, context, xml ) {
12166 var elem,
12167 newUnmatched = [],
12168 i = 0,
12169 len = unmatched.length,
12170 mapped = map != null;
12171
12172 for ( ; i < len; i++ ) {
12173 if ( (elem = unmatched[i]) ) {
12174 if ( !filter || filter( elem, context, xml ) ) {
12175 newUnmatched.push( elem );
12176 if ( mapped ) {
12177 map.push( i );
12178 }
12179 }
12180 }
12181 }
12182
12183 return newUnmatched;
12184 }
12185
12186 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
12187 if ( postFilter && !postFilter[ expando ] ) {
12188 postFilter = setMatcher( postFilter );
12189 }
12190 if ( postFinder && !postFinder[ expando ] ) {
12191 postFinder = setMatcher( postFinder, postSelector );
12192 }
12193 return markFunction(function( seed, results, context, xml ) {
12194 var temp, i, elem,
12195 preMap = [],
12196 postMap = [],
12197 preexisting = results.length,
12198
12199 // Get initial elements from seed or context
12200 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
12201
12202 // Prefilter to get matcher input, preserving a map for seed-results synchronization
12203 matcherIn = preFilter && ( seed || !selector ) ?
12204 condense( elems, preMap, preFilter, context, xml ) :
12205 elems,
12206
12207 matcherOut = matcher ?
12208 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
12209 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
12210
12211 // ...intermediate processing is necessary
12212 [] :
12213
12214 // ...otherwise use results directly
12215 results :
12216 matcherIn;
12217
12218 // Find primary matches
12219 if ( matcher ) {
12220 matcher( matcherIn, matcherOut, context, xml );
12221 }
12222
12223 // Apply postFilter
12224 if ( postFilter ) {
12225 temp = condense( matcherOut, postMap );
12226 postFilter( temp, [], context, xml );
12227
12228 // Un-match failing elements by moving them back to matcherIn
12229 i = temp.length;
12230 while ( i-- ) {
12231 if ( (elem = temp[i]) ) {
12232 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
12233 }
12234 }
12235 }
12236
12237 if ( seed ) {
12238 if ( postFinder || preFilter ) {
12239 if ( postFinder ) {
12240 // Get the final matcherOut by condensing this intermediate into postFinder contexts
12241 temp = [];
12242 i = matcherOut.length;
12243 while ( i-- ) {
12244 if ( (elem = matcherOut[i]) ) {
12245 // Restore matcherIn since elem is not yet a final match
12246 temp.push( (matcherIn[i] = elem) );
12247 }
12248 }
12249 postFinder( null, (matcherOut = []), temp, xml );
12250 }
12251
12252 // Move matched elements from seed to results to keep them synchronized
12253 i = matcherOut.length;
12254 while ( i-- ) {
12255 if ( (elem = matcherOut[i]) &&
12256 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
12257
12258 seed[temp] = !(results[temp] = elem);
12259 }
12260 }
12261 }
12262
12263 // Add elements to results, through postFinder if defined
12264 } else {
12265 matcherOut = condense(
12266 matcherOut === results ?
12267 matcherOut.splice( preexisting, matcherOut.length ) :
12268 matcherOut
12269 );
12270 if ( postFinder ) {
12271 postFinder( null, results, matcherOut, xml );
12272 } else {
12273 push.apply( results, matcherOut );
12274 }
12275 }
12276 });
12277 }
12278
12279 function matcherFromTokens( tokens ) {
12280 var checkContext, matcher, j,
12281 len = tokens.length,
12282 leadingRelative = Expr.relative[ tokens[0].type ],
12283 implicitRelative = leadingRelative || Expr.relative[" "],
12284 i = leadingRelative ? 1 : 0,
12285
12286 // The foundational matcher ensures that elements are reachable from top-level context(s)
12287 matchContext = addCombinator( function( elem ) {
12288 return elem === checkContext;
12289 }, implicitRelative, true ),
12290 matchAnyContext = addCombinator( function( elem ) {
12291 return indexOf( checkContext, elem ) > -1;
12292 }, implicitRelative, true ),
12293 matchers = [ function( elem, context, xml ) {
12294 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
12295 (checkContext = context).nodeType ?
12296 matchContext( elem, context, xml ) :
12297 matchAnyContext( elem, context, xml ) );
12298 // Avoid hanging onto element (issue #299)
12299 checkContext = null;
12300 return ret;
12301 } ];
12302
12303 for ( ; i < len; i++ ) {
12304 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
12305 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
12306 } else {
12307 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
12308
12309 // Return special upon seeing a positional matcher
12310 if ( matcher[ expando ] ) {
12311 // Find the next relative operator (if any) for proper handling
12312 j = ++i;
12313 for ( ; j < len; j++ ) {
12314 if ( Expr.relative[ tokens[j].type ] ) {
12315 break;
12316 }
12317 }
12318 return setMatcher(
12319 i > 1 && elementMatcher( matchers ),
12320 i > 1 && toSelector(
12321 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
12322 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
12323 ).replace( rtrim, "$1" ),
12324 matcher,
12325 i < j && matcherFromTokens( tokens.slice( i, j ) ),
12326 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
12327 j < len && toSelector( tokens )
12328 );
12329 }
12330 matchers.push( matcher );
12331 }
12332 }
12333
12334 return elementMatcher( matchers );
12335 }
12336
12337 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
12338 var bySet = setMatchers.length > 0,
12339 byElement = elementMatchers.length > 0,
12340 superMatcher = function( seed, context, xml, results, outermost ) {
12341 var elem, j, matcher,
12342 matchedCount = 0,
12343 i = "0",
12344 unmatched = seed && [],
12345 setMatched = [],
12346 contextBackup = outermostContext,
12347 // We must always have either seed elements or outermost context
12348 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
12349 // Use integer dirruns iff this is the outermost matcher
12350 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
12351 len = elems.length;
12352
12353 if ( outermost ) {
12354 outermostContext = context === document || context || outermost;
12355 }
12356
12357 // Add elements passing elementMatchers directly to results
12358 // Support: IE<9, Safari
12359 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
12360 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
12361 if ( byElement && elem ) {
12362 j = 0;
12363 if ( !context && elem.ownerDocument !== document ) {
12364 setDocument( elem );
12365 xml = !documentIsHTML;
12366 }
12367 while ( (matcher = elementMatchers[j++]) ) {
12368 if ( matcher( elem, context || document, xml) ) {
12369 results.push( elem );
12370 break;
12371 }
12372 }
12373 if ( outermost ) {
12374 dirruns = dirrunsUnique;
12375 }
12376 }
12377
12378 // Track unmatched elements for set filters
12379 if ( bySet ) {
12380 // They will have gone through all possible matchers
12381 if ( (elem = !matcher && elem) ) {
12382 matchedCount--;
12383 }
12384
12385 // Lengthen the array for every element, matched or not
12386 if ( seed ) {
12387 unmatched.push( elem );
12388 }
12389 }
12390 }
12391
12392 // `i` is now the count of elements visited above, and adding it to `matchedCount`
12393 // makes the latter nonnegative.
12394 matchedCount += i;
12395
12396 // Apply set filters to unmatched elements
12397 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
12398 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
12399 // no element matchers and no seed.
12400 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
12401 // case, which will result in a "00" `matchedCount` that differs from `i` but is also
12402 // numerically zero.
12403 if ( bySet && i !== matchedCount ) {
12404 j = 0;
12405 while ( (matcher = setMatchers[j++]) ) {
12406 matcher( unmatched, setMatched, context, xml );
12407 }
12408
12409 if ( seed ) {
12410 // Reintegrate element matches to eliminate the need for sorting
12411 if ( matchedCount > 0 ) {
12412 while ( i-- ) {
12413 if ( !(unmatched[i] || setMatched[i]) ) {
12414 setMatched[i] = pop.call( results );
12415 }
12416 }
12417 }
12418
12419 // Discard index placeholder values to get only actual matches
12420 setMatched = condense( setMatched );
12421 }
12422
12423 // Add matches to results
12424 push.apply( results, setMatched );
12425
12426 // Seedless set matches succeeding multiple successful matchers stipulate sorting
12427 if ( outermost && !seed && setMatched.length > 0 &&
12428 ( matchedCount + setMatchers.length ) > 1 ) {
12429
12430 Sizzle.uniqueSort( results );
12431 }
12432 }
12433
12434 // Override manipulation of globals by nested matchers
12435 if ( outermost ) {
12436 dirruns = dirrunsUnique;
12437 outermostContext = contextBackup;
12438 }
12439
12440 return unmatched;
12441 };
12442
12443 return bySet ?
12444 markFunction( superMatcher ) :
12445 superMatcher;
12446 }
12447
12448 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
12449 var i,
12450 setMatchers = [],
12451 elementMatchers = [],
12452 cached = compilerCache[ selector + " " ];
12453
12454 if ( !cached ) {
12455 // Generate a function of recursive functions that can be used to check each element
12456 if ( !match ) {
12457 match = tokenize( selector );
12458 }
12459 i = match.length;
12460 while ( i-- ) {
12461 cached = matcherFromTokens( match[i] );
12462 if ( cached[ expando ] ) {
12463 setMatchers.push( cached );
12464 } else {
12465 elementMatchers.push( cached );
12466 }
12467 }
12468
12469 // Cache the compiled function
12470 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
12471
12472 // Save selector and tokenization
12473 cached.selector = selector;
12474 }
12475 return cached;
12476 };
12477
12478 /**
12479 * A low-level selection function that works with Sizzle's compiled
12480 * selector functions
12481 * @param {String|Function} selector A selector or a pre-compiled
12482 * selector function built with Sizzle.compile
12483 * @param {Element} context
12484 * @param {Array} [results]
12485 * @param {Array} [seed] A set of elements to match against
12486 */
12487 select = Sizzle.select = function( selector, context, results, seed ) {
12488 var i, tokens, token, type, find,
12489 compiled = typeof selector === "function" && selector,
12490 match = !seed && tokenize( (selector = compiled.selector || selector) );
12491
12492 results = results || [];
12493
12494 // Try to minimize operations if there is only one selector in the list and no seed
12495 // (the latter of which guarantees us context)
12496 if ( match.length === 1 ) {
12497
12498 // Reduce context if the leading compound selector is an ID
12499 tokens = match[0] = match[0].slice( 0 );
12500 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
12501 support.getById && context.nodeType === 9 && documentIsHTML &&
12502 Expr.relative[ tokens[1].type ] ) {
12503
12504 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
12505 if ( !context ) {
12506 return results;
12507
12508 // Precompiled matchers will still verify ancestry, so step up a level
12509 } else if ( compiled ) {
12510 context = context.parentNode;
12511 }
12512
12513 selector = selector.slice( tokens.shift().value.length );
12514 }
12515
12516 // Fetch a seed set for right-to-left matching
12517 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
12518 while ( i-- ) {
12519 token = tokens[i];
12520
12521 // Abort if we hit a combinator
12522 if ( Expr.relative[ (type = token.type) ] ) {
12523 break;
12524 }
12525 if ( (find = Expr.find[ type ]) ) {
12526 // Search, expanding context for leading sibling combinators
12527 if ( (seed = find(
12528 token.matches[0].replace( runescape, funescape ),
12529 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
12530 )) ) {
12531
12532 // If seed is empty or no tokens remain, we can return early
12533 tokens.splice( i, 1 );
12534 selector = seed.length && toSelector( tokens );
12535 if ( !selector ) {
12536 push.apply( results, seed );
12537 return results;
12538 }
12539
12540 break;
12541 }
12542 }
12543 }
12544 }
12545
12546 // Compile and execute a filtering function if one is not provided
12547 // Provide `match` to avoid retokenization if we modified the selector above
12548 ( compiled || compile( selector, match ) )(
12549 seed,
12550 context,
12551 !documentIsHTML,
12552 results,
12553 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
12554 );
12555 return results;
12556 };
12557
12558 // One-time assignments
12559
12560 // Sort stability
12561 support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
12562
12563 // Support: Chrome 14-35+
12564 // Always assume duplicates if they aren't passed to the comparison function
12565 support.detectDuplicates = !!hasDuplicate;
12566
12567 // Initialize against the default document
12568 setDocument();
12569
12570 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
12571 // Detached nodes confoundingly follow *each other*
12572 support.sortDetached = assert(function( div1 ) {
12573 // Should return 1, but returns 4 (following)
12574 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
12575 });
12576
12577 // Support: IE<8
12578 // Prevent attribute/property "interpolation"
12579 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
12580 if ( !assert(function( div ) {
12581 div.innerHTML = "<a href='#'></a>";
12582 return div.firstChild.getAttribute("href") === "#" ;
12583 }) ) {
12584 addHandle( "type|href|height|width", function( elem, name, isXML ) {
12585 if ( !isXML ) {
12586 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
12587 }
12588 });
12589 }
12590
12591 // Support: IE<9
12592 // Use defaultValue in place of getAttribute("value")
12593 if ( !support.attributes || !assert(function( div ) {
12594 div.innerHTML = "<input/>";
12595 div.firstChild.setAttribute( "value", "" );
12596 return div.firstChild.getAttribute( "value" ) === "";
12597 }) ) {
12598 addHandle( "value", function( elem, name, isXML ) {
12599 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
12600 return elem.defaultValue;
12601 }
12602 });
12603 }
12604
12605 // Support: IE<9
12606 // Use getAttributeNode to fetch booleans when getAttribute lies
12607 if ( !assert(function( div ) {
12608 return div.getAttribute("disabled") == null;
12609 }) ) {
12610 addHandle( booleans, function( elem, name, isXML ) {
12611 var val;
12612 if ( !isXML ) {
12613 return elem[ name ] === true ? name.toLowerCase() :
12614 (val = elem.getAttributeNode( name )) && val.specified ?
12615 val.value :
12616 null;
12617 }
12618 });
12619 }
12620
12621 return Sizzle;
12622
12623 })( window );
12624
12625
12626
12627 jQuery.find = Sizzle;
12628 jQuery.expr = Sizzle.selectors;
12629 jQuery.expr[ ":" ] = jQuery.expr.pseudos;
12630 jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
12631 jQuery.text = Sizzle.getText;
12632 jQuery.isXMLDoc = Sizzle.isXML;
12633 jQuery.contains = Sizzle.contains;
12634
12635
12636
12637 var dir = function( elem, dir, until ) {
12638 var matched = [],
12639 truncate = until !== undefined;
12640
12641 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
12642 if ( elem.nodeType === 1 ) {
12643 if ( truncate && jQuery( elem ).is( until ) ) {
12644 break;
12645 }
12646 matched.push( elem );
12647 }
12648 }
12649 return matched;
12650 };
12651
12652
12653 var siblings = function( n, elem ) {
12654 var matched = [];
12655
12656 for ( ; n; n = n.nextSibling ) {
12657 if ( n.nodeType === 1 && n !== elem ) {
12658 matched.push( n );
12659 }
12660 }
12661
12662 return matched;
12663 };
12664
12665
12666 var rneedsContext = jQuery.expr.match.needsContext;
12667
12668 var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
12669
12670
12671
12672 var risSimple = /^.[^:#\[\.,]*$/;
12673
12674 // Implement the identical functionality for filter and not
12675 function winnow( elements, qualifier, not ) {
12676 if ( jQuery.isFunction( qualifier ) ) {
12677 return jQuery.grep( elements, function( elem, i ) {
12678 /* jshint -W018 */
12679 return !!qualifier.call( elem, i, elem ) !== not;
12680 } );
12681
12682 }
12683
12684 if ( qualifier.nodeType ) {
12685 return jQuery.grep( elements, function( elem ) {
12686 return ( elem === qualifier ) !== not;
12687 } );
12688
12689 }
12690
12691 if ( typeof qualifier === "string" ) {
12692 if ( risSimple.test( qualifier ) ) {
12693 return jQuery.filter( qualifier, elements, not );
12694 }
12695
12696 qualifier = jQuery.filter( qualifier, elements );
12697 }
12698
12699 return jQuery.grep( elements, function( elem ) {
12700 return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
12701 } );
12702 }
12703
12704 jQuery.filter = function( expr, elems, not ) {
12705 var elem = elems[ 0 ];
12706
12707 if ( not ) {
12708 expr = ":not(" + expr + ")";
12709 }
12710
12711 return elems.length === 1 && elem.nodeType === 1 ?
12712 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
12713 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
12714 return elem.nodeType === 1;
12715 } ) );
12716 };
12717
12718 jQuery.fn.extend( {
12719 find: function( selector ) {
12720 var i,
12721 ret = [],
12722 self = this,
12723 len = self.length;
12724
12725 if ( typeof selector !== "string" ) {
12726 return this.pushStack( jQuery( selector ).filter( function() {
12727 for ( i = 0; i < len; i++ ) {
12728 if ( jQuery.contains( self[ i ], this ) ) {
12729 return true;
12730 }
12731 }
12732 } ) );
12733 }
12734
12735 for ( i = 0; i < len; i++ ) {
12736 jQuery.find( selector, self[ i ], ret );
12737 }
12738
12739 // Needed because $( selector, context ) becomes $( context ).find( selector )
12740 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
12741 ret.selector = this.selector ? this.selector + " " + selector : selector;
12742 return ret;
12743 },
12744 filter: function( selector ) {
12745 return this.pushStack( winnow( this, selector || [], false ) );
12746 },
12747 not: function( selector ) {
12748 return this.pushStack( winnow( this, selector || [], true ) );
12749 },
12750 is: function( selector ) {
12751 return !!winnow(
12752 this,
12753
12754 // If this is a positional/relative selector, check membership in the returned set
12755 // so $("p:first").is("p:last") won't return true for a doc with two "p".
12756 typeof selector === "string" && rneedsContext.test( selector ) ?
12757 jQuery( selector ) :
12758 selector || [],
12759 false
12760 ).length;
12761 }
12762 } );
12763
12764
12765 // Initialize a jQuery object
12766
12767
12768 // A central reference to the root jQuery(document)
12769 var rootjQuery,
12770
12771 // A simple way to check for HTML strings
12772 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
12773 // Strict HTML recognition (#11290: must start with <)
12774 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
12775
12776 init = jQuery.fn.init = function( selector, context, root ) {
12777 var match, elem;
12778
12779 // HANDLE: $(""), $(null), $(undefined), $(false)
12780 if ( !selector ) {
12781 return this;
12782 }
12783
12784 // init accepts an alternate rootjQuery
12785 // so migrate can support jQuery.sub (gh-2101)
12786 root = root || rootjQuery;
12787
12788 // Handle HTML strings
12789 if ( typeof selector === "string" ) {
12790 if ( selector.charAt( 0 ) === "<" &&
12791 selector.charAt( selector.length - 1 ) === ">" &&
12792 selector.length >= 3 ) {
12793
12794 // Assume that strings that start and end with <> are HTML and skip the regex check
12795 match = [ null, selector, null ];
12796
12797 } else {
12798 match = rquickExpr.exec( selector );
12799 }
12800
12801 // Match html or make sure no context is specified for #id
12802 if ( match && ( match[ 1 ] || !context ) ) {
12803
12804 // HANDLE: $(html) -> $(array)
12805 if ( match[ 1 ] ) {
12806 context = context instanceof jQuery ? context[ 0 ] : context;
12807
12808 // scripts is true for back-compat
12809 // Intentionally let the error be thrown if parseHTML is not present
12810 jQuery.merge( this, jQuery.parseHTML(
12811 match[ 1 ],
12812 context && context.nodeType ? context.ownerDocument || context : document,
12813 true
12814 ) );
12815
12816 // HANDLE: $(html, props)
12817 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
12818 for ( match in context ) {
12819
12820 // Properties of context are called as methods if possible
12821 if ( jQuery.isFunction( this[ match ] ) ) {
12822 this[ match ]( context[ match ] );
12823
12824 // ...and otherwise set as attributes
12825 } else {
12826 this.attr( match, context[ match ] );
12827 }
12828 }
12829 }
12830
12831 return this;
12832
12833 // HANDLE: $(#id)
12834 } else {
12835 elem = document.getElementById( match[ 2 ] );
12836
12837 // Check parentNode to catch when Blackberry 4.6 returns
12838 // nodes that are no longer in the document #6963
12839 if ( elem && elem.parentNode ) {
12840
12841 // Handle the case where IE and Opera return items
12842 // by name instead of ID
12843 if ( elem.id !== match[ 2 ] ) {
12844 return rootjQuery.find( selector );
12845 }
12846
12847 // Otherwise, we inject the element directly into the jQuery object
12848 this.length = 1;
12849 this[ 0 ] = elem;
12850 }
12851
12852 this.context = document;
12853 this.selector = selector;
12854 return this;
12855 }
12856
12857 // HANDLE: $(expr, $(...))
12858 } else if ( !context || context.jquery ) {
12859 return ( context || root ).find( selector );
12860
12861 // HANDLE: $(expr, context)
12862 // (which is just equivalent to: $(context).find(expr)
12863 } else {
12864 return this.constructor( context ).find( selector );
12865 }
12866
12867 // HANDLE: $(DOMElement)
12868 } else if ( selector.nodeType ) {
12869 this.context = this[ 0 ] = selector;
12870 this.length = 1;
12871 return this;
12872
12873 // HANDLE: $(function)
12874 // Shortcut for document ready
12875 } else if ( jQuery.isFunction( selector ) ) {
12876 return typeof root.ready !== "undefined" ?
12877 root.ready( selector ) :
12878
12879 // Execute immediately if ready is not present
12880 selector( jQuery );
12881 }
12882
12883 if ( selector.selector !== undefined ) {
12884 this.selector = selector.selector;
12885 this.context = selector.context;
12886 }
12887
12888 return jQuery.makeArray( selector, this );
12889 };
12890
12891 // Give the init function the jQuery prototype for later instantiation
12892 init.prototype = jQuery.fn;
12893
12894 // Initialize central reference
12895 rootjQuery = jQuery( document );
12896
12897
12898 var rparentsprev = /^(?:parents|prev(?:Until|All))/,
12899
12900 // methods guaranteed to produce a unique set when starting from a unique set
12901 guaranteedUnique = {
12902 children: true,
12903 contents: true,
12904 next: true,
12905 prev: true
12906 };
12907
12908 jQuery.fn.extend( {
12909 has: function( target ) {
12910 var i,
12911 targets = jQuery( target, this ),
12912 len = targets.length;
12913
12914 return this.filter( function() {
12915 for ( i = 0; i < len; i++ ) {
12916 if ( jQuery.contains( this, targets[ i ] ) ) {
12917 return true;
12918 }
12919 }
12920 } );
12921 },
12922
12923 closest: function( selectors, context ) {
12924 var cur,
12925 i = 0,
12926 l = this.length,
12927 matched = [],
12928 pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
12929 jQuery( selectors, context || this.context ) :
12930 0;
12931
12932 for ( ; i < l; i++ ) {
12933 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
12934
12935 // Always skip document fragments
12936 if ( cur.nodeType < 11 && ( pos ?
12937 pos.index( cur ) > -1 :
12938
12939 // Don't pass non-elements to Sizzle
12940 cur.nodeType === 1 &&
12941 jQuery.find.matchesSelector( cur, selectors ) ) ) {
12942
12943 matched.push( cur );
12944 break;
12945 }
12946 }
12947 }
12948
12949 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
12950 },
12951
12952 // Determine the position of an element within
12953 // the matched set of elements
12954 index: function( elem ) {
12955
12956 // No argument, return index in parent
12957 if ( !elem ) {
12958 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
12959 }
12960
12961 // index in selector
12962 if ( typeof elem === "string" ) {
12963 return jQuery.inArray( this[ 0 ], jQuery( elem ) );
12964 }
12965
12966 // Locate the position of the desired element
12967 return jQuery.inArray(
12968
12969 // If it receives a jQuery object, the first element is used
12970 elem.jquery ? elem[ 0 ] : elem, this );
12971 },
12972
12973 add: function( selector, context ) {
12974 return this.pushStack(
12975 jQuery.uniqueSort(
12976 jQuery.merge( this.get(), jQuery( selector, context ) )
12977 )
12978 );
12979 },
12980
12981 addBack: function( selector ) {
12982 return this.add( selector == null ?
12983 this.prevObject : this.prevObject.filter( selector )
12984 );
12985 }
12986 } );
12987
12988 function sibling( cur, dir ) {
12989 do {
12990 cur = cur[ dir ];
12991 } while ( cur && cur.nodeType !== 1 );
12992
12993 return cur;
12994 }
12995
12996 jQuery.each( {
12997 parent: function( elem ) {
12998 var parent = elem.parentNode;
12999 return parent && parent.nodeType !== 11 ? parent : null;
13000 },
13001 parents: function( elem ) {
13002 return dir( elem, "parentNode" );
13003 },
13004 parentsUntil: function( elem, i, until ) {
13005 return dir( elem, "parentNode", until );
13006 },
13007 next: function( elem ) {
13008 return sibling( elem, "nextSibling" );
13009 },
13010 prev: function( elem ) {
13011 return sibling( elem, "previousSibling" );
13012 },
13013 nextAll: function( elem ) {
13014 return dir( elem, "nextSibling" );
13015 },
13016 prevAll: function( elem ) {
13017 return dir( elem, "previousSibling" );
13018 },
13019 nextUntil: function( elem, i, until ) {
13020 return dir( elem, "nextSibling", until );
13021 },
13022 prevUntil: function( elem, i, until ) {
13023 return dir( elem, "previousSibling", until );
13024 },
13025 siblings: function( elem ) {
13026 return siblings( ( elem.parentNode || {} ).firstChild, elem );
13027 },
13028 children: function( elem ) {
13029 return siblings( elem.firstChild );
13030 },
13031 contents: function( elem ) {
13032 return jQuery.nodeName( elem, "iframe" ) ?
13033 elem.contentDocument || elem.contentWindow.document :
13034 jQuery.merge( [], elem.childNodes );
13035 }
13036 }, function( name, fn ) {
13037 jQuery.fn[ name ] = function( until, selector ) {
13038 var ret = jQuery.map( this, fn, until );
13039
13040 if ( name.slice( -5 ) !== "Until" ) {
13041 selector = until;
13042 }
13043
13044 if ( selector && typeof selector === "string" ) {
13045 ret = jQuery.filter( selector, ret );
13046 }
13047
13048 if ( this.length > 1 ) {
13049
13050 // Remove duplicates
13051 if ( !guaranteedUnique[ name ] ) {
13052 ret = jQuery.uniqueSort( ret );
13053 }
13054
13055 // Reverse order for parents* and prev-derivatives
13056 if ( rparentsprev.test( name ) ) {
13057 ret = ret.reverse();
13058 }
13059 }
13060
13061 return this.pushStack( ret );
13062 };
13063 } );
13064 var rnotwhite = ( /\S+/g );
13065
13066
13067
13068 // Convert String-formatted options into Object-formatted ones
13069 function createOptions( options ) {
13070 var object = {};
13071 jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
13072 object[ flag ] = true;
13073 } );
13074 return object;
13075 }
13076
13077 /*
13078 * Create a callback list using the following parameters:
13079 *
13080 * options: an optional list of space-separated options that will change how
13081 * the callback list behaves or a more traditional option object
13082 *
13083 * By default a callback list will act like an event callback list and can be
13084 * "fired" multiple times.
13085 *
13086 * Possible options:
13087 *
13088 * once: will ensure the callback list can only be fired once (like a Deferred)
13089 *
13090 * memory: will keep track of previous values and will call any callback added
13091 * after the list has been fired right away with the latest "memorized"
13092 * values (like a Deferred)
13093 *
13094 * unique: will ensure a callback can only be added once (no duplicate in the list)
13095 *
13096 * stopOnFalse: interrupt callings when a callback returns false
13097 *
13098 */
13099 jQuery.Callbacks = function( options ) {
13100
13101 // Convert options from String-formatted to Object-formatted if needed
13102 // (we check in cache first)
13103 options = typeof options === "string" ?
13104 createOptions( options ) :
13105 jQuery.extend( {}, options );
13106
13107 var // Flag to know if list is currently firing
13108 firing,
13109
13110 // Last fire value for non-forgettable lists
13111 memory,
13112
13113 // Flag to know if list was already fired
13114 fired,
13115
13116 // Flag to prevent firing
13117 locked,
13118
13119 // Actual callback list
13120 list = [],
13121
13122 // Queue of execution data for repeatable lists
13123 queue = [],
13124
13125 // Index of currently firing callback (modified by add/remove as needed)
13126 firingIndex = -1,
13127
13128 // Fire callbacks
13129 fire = function() {
13130
13131 // Enforce single-firing
13132 locked = options.once;
13133
13134 // Execute callbacks for all pending executions,
13135 // respecting firingIndex overrides and runtime changes
13136 fired = firing = true;
13137 for ( ; queue.length; firingIndex = -1 ) {
13138 memory = queue.shift();
13139 while ( ++firingIndex < list.length ) {
13140
13141 // Run callback and check for early termination
13142 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
13143 options.stopOnFalse ) {
13144
13145 // Jump to end and forget the data so .add doesn't re-fire
13146 firingIndex = list.length;
13147 memory = false;
13148 }
13149 }
13150 }
13151
13152 // Forget the data if we're done with it
13153 if ( !options.memory ) {
13154 memory = false;
13155 }
13156
13157 firing = false;
13158
13159 // Clean up if we're done firing for good
13160 if ( locked ) {
13161
13162 // Keep an empty list if we have data for future add calls
13163 if ( memory ) {
13164 list = [];
13165
13166 // Otherwise, this object is spent
13167 } else {
13168 list = "";
13169 }
13170 }
13171 },
13172
13173 // Actual Callbacks object
13174 self = {
13175
13176 // Add a callback or a collection of callbacks to the list
13177 add: function() {
13178 if ( list ) {
13179
13180 // If we have memory from a past run, we should fire after adding
13181 if ( memory && !firing ) {
13182 firingIndex = list.length - 1;
13183 queue.push( memory );
13184 }
13185
13186 ( function add( args ) {
13187 jQuery.each( args, function( _, arg ) {
13188 if ( jQuery.isFunction( arg ) ) {
13189 if ( !options.unique || !self.has( arg ) ) {
13190 list.push( arg );
13191 }
13192 } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
13193
13194 // Inspect recursively
13195 add( arg );
13196 }
13197 } );
13198 } )( arguments );
13199
13200 if ( memory && !firing ) {
13201 fire();
13202 }
13203 }
13204 return this;
13205 },
13206
13207 // Remove a callback from the list
13208 remove: function() {
13209 jQuery.each( arguments, function( _, arg ) {
13210 var index;
13211 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
13212 list.splice( index, 1 );
13213
13214 // Handle firing indexes
13215 if ( index <= firingIndex ) {
13216 firingIndex--;
13217 }
13218 }
13219 } );
13220 return this;
13221 },
13222
13223 // Check if a given callback is in the list.
13224 // If no argument is given, return whether or not list has callbacks attached.
13225 has: function( fn ) {
13226 return fn ?
13227 jQuery.inArray( fn, list ) > -1 :
13228 list.length > 0;
13229 },
13230
13231 // Remove all callbacks from the list
13232 empty: function() {
13233 if ( list ) {
13234 list = [];
13235 }
13236 return this;
13237 },
13238
13239 // Disable .fire and .add
13240 // Abort any current/pending executions
13241 // Clear all callbacks and values
13242 disable: function() {
13243 locked = queue = [];
13244 list = memory = "";
13245 return this;
13246 },
13247 disabled: function() {
13248 return !list;
13249 },
13250
13251 // Disable .fire
13252 // Also disable .add unless we have memory (since it would have no effect)
13253 // Abort any pending executions
13254 lock: function() {
13255 locked = true;
13256 if ( !memory ) {
13257 self.disable();
13258 }
13259 return this;
13260 },
13261 locked: function() {
13262 return !!locked;
13263 },
13264
13265 // Call all callbacks with the given context and arguments
13266 fireWith: function( context, args ) {
13267 if ( !locked ) {
13268 args = args || [];
13269 args = [ context, args.slice ? args.slice() : args ];
13270 queue.push( args );
13271 if ( !firing ) {
13272 fire();
13273 }
13274 }
13275 return this;
13276 },
13277
13278 // Call all the callbacks with the given arguments
13279 fire: function() {
13280 self.fireWith( this, arguments );
13281 return this;
13282 },
13283
13284 // To know if the callbacks have already been called at least once
13285 fired: function() {
13286 return !!fired;
13287 }
13288 };
13289
13290 return self;
13291 };
13292
13293
13294 jQuery.extend( {
13295
13296 Deferred: function( func ) {
13297 var tuples = [
13298
13299 // action, add listener, listener list, final state
13300 [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
13301 [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
13302 [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
13303 ],
13304 state = "pending",
13305 promise = {
13306 state: function() {
13307 return state;
13308 },
13309 always: function() {
13310 deferred.done( arguments ).fail( arguments );
13311 return this;
13312 },
13313 then: function( /* fnDone, fnFail, fnProgress */ ) {
13314 var fns = arguments;
13315 return jQuery.Deferred( function( newDefer ) {
13316 jQuery.each( tuples, function( i, tuple ) {
13317 var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
13318
13319 // deferred[ done | fail | progress ] for forwarding actions to newDefer
13320 deferred[ tuple[ 1 ] ]( function() {
13321 var returned = fn && fn.apply( this, arguments );
13322 if ( returned && jQuery.isFunction( returned.promise ) ) {
13323 returned.promise()
13324 .progress( newDefer.notify )
13325 .done( newDefer.resolve )
13326 .fail( newDefer.reject );
13327 } else {
13328 newDefer[ tuple[ 0 ] + "With" ](
13329 this === promise ? newDefer.promise() : this,
13330 fn ? [ returned ] : arguments
13331 );
13332 }
13333 } );
13334 } );
13335 fns = null;
13336 } ).promise();
13337 },
13338
13339 // Get a promise for this deferred
13340 // If obj is provided, the promise aspect is added to the object
13341 promise: function( obj ) {
13342 return obj != null ? jQuery.extend( obj, promise ) : promise;
13343 }
13344 },
13345 deferred = {};
13346
13347 // Keep pipe for back-compat
13348 promise.pipe = promise.then;
13349
13350 // Add list-specific methods
13351 jQuery.each( tuples, function( i, tuple ) {
13352 var list = tuple[ 2 ],
13353 stateString = tuple[ 3 ];
13354
13355 // promise[ done | fail | progress ] = list.add
13356 promise[ tuple[ 1 ] ] = list.add;
13357
13358 // Handle state
13359 if ( stateString ) {
13360 list.add( function() {
13361
13362 // state = [ resolved | rejected ]
13363 state = stateString;
13364
13365 // [ reject_list | resolve_list ].disable; progress_list.lock
13366 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
13367 }
13368
13369 // deferred[ resolve | reject | notify ]
13370 deferred[ tuple[ 0 ] ] = function() {
13371 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
13372 return this;
13373 };
13374 deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
13375 } );
13376
13377 // Make the deferred a promise
13378 promise.promise( deferred );
13379
13380 // Call given func if any
13381 if ( func ) {
13382 func.call( deferred, deferred );
13383 }
13384
13385 // All done!
13386 return deferred;
13387 },
13388
13389 // Deferred helper
13390 when: function( subordinate /* , ..., subordinateN */ ) {
13391 var i = 0,
13392 resolveValues = slice.call( arguments ),
13393 length = resolveValues.length,
13394
13395 // the count of uncompleted subordinates
13396 remaining = length !== 1 ||
13397 ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
13398
13399 // the master Deferred.
13400 // If resolveValues consist of only a single Deferred, just use that.
13401 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
13402
13403 // Update function for both resolve and progress values
13404 updateFunc = function( i, contexts, values ) {
13405 return function( value ) {
13406 contexts[ i ] = this;
13407 values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
13408 if ( values === progressValues ) {
13409 deferred.notifyWith( contexts, values );
13410
13411 } else if ( !( --remaining ) ) {
13412 deferred.resolveWith( contexts, values );
13413 }
13414 };
13415 },
13416
13417 progressValues, progressContexts, resolveContexts;
13418
13419 // add listeners to Deferred subordinates; treat others as resolved
13420 if ( length > 1 ) {
13421 progressValues = new Array( length );
13422 progressContexts = new Array( length );
13423 resolveContexts = new Array( length );
13424 for ( ; i < length; i++ ) {
13425 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
13426 resolveValues[ i ].promise()
13427 .progress( updateFunc( i, progressContexts, progressValues ) )
13428 .done( updateFunc( i, resolveContexts, resolveValues ) )
13429 .fail( deferred.reject );
13430 } else {
13431 --remaining;
13432 }
13433 }
13434 }
13435
13436 // if we're not waiting on anything, resolve the master
13437 if ( !remaining ) {
13438 deferred.resolveWith( resolveContexts, resolveValues );
13439 }
13440
13441 return deferred.promise();
13442 }
13443 } );
13444
13445
13446 // The deferred used on DOM ready
13447 var readyList;
13448
13449 jQuery.fn.ready = function( fn ) {
13450
13451 // Add the callback
13452 jQuery.ready.promise().done( fn );
13453
13454 return this;
13455 };
13456
13457 jQuery.extend( {
13458
13459 // Is the DOM ready to be used? Set to true once it occurs.
13460 isReady: false,
13461
13462 // A counter to track how many items to wait for before
13463 // the ready event fires. See #6781
13464 readyWait: 1,
13465
13466 // Hold (or release) the ready event
13467 holdReady: function( hold ) {
13468 if ( hold ) {
13469 jQuery.readyWait++;
13470 } else {
13471 jQuery.ready( true );
13472 }
13473 },
13474
13475 // Handle when the DOM is ready
13476 ready: function( wait ) {
13477
13478 // Abort if there are pending holds or we're already ready
13479 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
13480 return;
13481 }
13482
13483 // Remember that the DOM is ready
13484 jQuery.isReady = true;
13485
13486 // If a normal DOM Ready event fired, decrement, and wait if need be
13487 if ( wait !== true && --jQuery.readyWait > 0 ) {
13488 return;
13489 }
13490
13491 // If there are functions bound, to execute
13492 readyList.resolveWith( document, [ jQuery ] );
13493
13494 // Trigger any bound ready events
13495 if ( jQuery.fn.triggerHandler ) {
13496 jQuery( document ).triggerHandler( "ready" );
13497 jQuery( document ).off( "ready" );
13498 }
13499 }
13500 } );
13501
13502 /**
13503 * Clean-up method for dom ready events
13504 */
13505 function detach() {
13506 if ( document.addEventListener ) {
13507 document.removeEventListener( "DOMContentLoaded", completed );
13508 window.removeEventListener( "load", completed );
13509
13510 } else {
13511 document.detachEvent( "onreadystatechange", completed );
13512 window.detachEvent( "onload", completed );
13513 }
13514 }
13515
13516 /**
13517 * The ready event handler and self cleanup method
13518 */
13519 function completed() {
13520
13521 // readyState === "complete" is good enough for us to call the dom ready in oldIE
13522 if ( document.addEventListener ||
13523 window.event.type === "load" ||
13524 document.readyState === "complete" ) {
13525
13526 detach();
13527 jQuery.ready();
13528 }
13529 }
13530
13531 jQuery.ready.promise = function( obj ) {
13532 if ( !readyList ) {
13533
13534 readyList = jQuery.Deferred();
13535
13536 // Catch cases where $(document).ready() is called
13537 // after the browser event has already occurred.
13538 // Support: IE6-10
13539 // Older IE sometimes signals "interactive" too soon
13540 if ( document.readyState === "complete" ||
13541 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
13542
13543 // Handle it asynchronously to allow scripts the opportunity to delay ready
13544 window.setTimeout( jQuery.ready );
13545
13546 // Standards-based browsers support DOMContentLoaded
13547 } else if ( document.addEventListener ) {
13548
13549 // Use the handy event callback
13550 document.addEventListener( "DOMContentLoaded", completed );
13551
13552 // A fallback to window.onload, that will always work
13553 window.addEventListener( "load", completed );
13554
13555 // If IE event model is used
13556 } else {
13557
13558 // Ensure firing before onload, maybe late but safe also for iframes
13559 document.attachEvent( "onreadystatechange", completed );
13560
13561 // A fallback to window.onload, that will always work
13562 window.attachEvent( "onload", completed );
13563
13564 // If IE and not a frame
13565 // continually check to see if the document is ready
13566 var top = false;
13567
13568 try {
13569 top = window.frameElement == null && document.documentElement;
13570 } catch ( e ) {}
13571
13572 if ( top && top.doScroll ) {
13573 ( function doScrollCheck() {
13574 if ( !jQuery.isReady ) {
13575
13576 try {
13577
13578 // Use the trick by Diego Perini
13579 // http://javascript.nwbox.com/IEContentLoaded/
13580 top.doScroll( "left" );
13581 } catch ( e ) {
13582 return window.setTimeout( doScrollCheck, 50 );
13583 }
13584
13585 // detach all dom ready events
13586 detach();
13587
13588 // and execute any waiting functions
13589 jQuery.ready();
13590 }
13591 } )();
13592 }
13593 }
13594 }
13595 return readyList.promise( obj );
13596 };
13597
13598 // Kick off the DOM ready check even if the user does not
13599 jQuery.ready.promise();
13600
13601
13602
13603
13604 // Support: IE<9
13605 // Iteration over object's inherited properties before its own
13606 var i;
13607 for ( i in jQuery( support ) ) {
13608 break;
13609 }
13610 support.ownFirst = i === "0";
13611
13612 // Note: most support tests are defined in their respective modules.
13613 // false until the test is run
13614 support.inlineBlockNeedsLayout = false;
13615
13616 // Execute ASAP in case we need to set body.style.zoom
13617 jQuery( function() {
13618
13619 // Minified: var a,b,c,d
13620 var val, div, body, container;
13621
13622 body = document.getElementsByTagName( "body" )[ 0 ];
13623 if ( !body || !body.style ) {
13624
13625 // Return for frameset docs that don't have a body
13626 return;
13627 }
13628
13629 // Setup
13630 div = document.createElement( "div" );
13631 container = document.createElement( "div" );
13632 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
13633 body.appendChild( container ).appendChild( div );
13634
13635 if ( typeof div.style.zoom !== "undefined" ) {
13636
13637 // Support: IE<8
13638 // Check if natively block-level elements act like inline-block
13639 // elements when setting their display to 'inline' and giving
13640 // them layout
13641 div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
13642
13643 support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
13644 if ( val ) {
13645
13646 // Prevent IE 6 from affecting layout for positioned elements #11048
13647 // Prevent IE from shrinking the body in IE 7 mode #12869
13648 // Support: IE<8
13649 body.style.zoom = 1;
13650 }
13651 }
13652
13653 body.removeChild( container );
13654 } );
13655
13656
13657 ( function() {
13658 var div = document.createElement( "div" );
13659
13660 // Support: IE<9
13661 support.deleteExpando = true;
13662 try {
13663 delete div.test;
13664 } catch ( e ) {
13665 support.deleteExpando = false;
13666 }
13667
13668 // Null elements to avoid leaks in IE.
13669 div = null;
13670 } )();
13671 var acceptData = function( elem ) {
13672 var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
13673 nodeType = +elem.nodeType || 1;
13674
13675 // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
13676 return nodeType !== 1 && nodeType !== 9 ?
13677 false :
13678
13679 // Nodes accept data unless otherwise specified; rejection can be conditional
13680 !noData || noData !== true && elem.getAttribute( "classid" ) === noData;
13681 };
13682
13683
13684
13685
13686 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
13687 rmultiDash = /([A-Z])/g;
13688
13689 function dataAttr( elem, key, data ) {
13690
13691 // If nothing was found internally, try to fetch any
13692 // data from the HTML5 data-* attribute
13693 if ( data === undefined && elem.nodeType === 1 ) {
13694
13695 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
13696
13697 data = elem.getAttribute( name );
13698
13699 if ( typeof data === "string" ) {
13700 try {
13701 data = data === "true" ? true :
13702 data === "false" ? false :
13703 data === "null" ? null :
13704
13705 // Only convert to a number if it doesn't change the string
13706 +data + "" === data ? +data :
13707 rbrace.test( data ) ? jQuery.parseJSON( data ) :
13708 data;
13709 } catch ( e ) {}
13710
13711 // Make sure we set the data so it isn't changed later
13712 jQuery.data( elem, key, data );
13713
13714 } else {
13715 data = undefined;
13716 }
13717 }
13718
13719 return data;
13720 }
13721
13722 // checks a cache object for emptiness
13723 function isEmptyDataObject( obj ) {
13724 var name;
13725 for ( name in obj ) {
13726
13727 // if the public data object is empty, the private is still empty
13728 if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
13729 continue;
13730 }
13731 if ( name !== "toJSON" ) {
13732 return false;
13733 }
13734 }
13735
13736 return true;
13737 }
13738
13739 function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
13740 if ( !acceptData( elem ) ) {
13741 return;
13742 }
13743
13744 var ret, thisCache,
13745 internalKey = jQuery.expando,
13746
13747 // We have to handle DOM nodes and JS objects differently because IE6-7
13748 // can't GC object references properly across the DOM-JS boundary
13749 isNode = elem.nodeType,
13750
13751 // Only DOM nodes need the global jQuery cache; JS object data is
13752 // attached directly to the object so GC can occur automatically
13753 cache = isNode ? jQuery.cache : elem,
13754
13755 // Only defining an ID for JS objects if its cache already exists allows
13756 // the code to shortcut on the same path as a DOM node with no cache
13757 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
13758
13759 // Avoid doing any more work than we need to when trying to get data on an
13760 // object that has no data at all
13761 if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
13762 data === undefined && typeof name === "string" ) {
13763 return;
13764 }
13765
13766 if ( !id ) {
13767
13768 // Only DOM nodes need a new unique ID for each element since their data
13769 // ends up in the global cache
13770 if ( isNode ) {
13771 id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
13772 } else {
13773 id = internalKey;
13774 }
13775 }
13776
13777 if ( !cache[ id ] ) {
13778
13779 // Avoid exposing jQuery metadata on plain JS objects when the object
13780 // is serialized using JSON.stringify
13781 cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
13782 }
13783
13784 // An object can be passed to jQuery.data instead of a key/value pair; this gets
13785 // shallow copied over onto the existing cache
13786 if ( typeof name === "object" || typeof name === "function" ) {
13787 if ( pvt ) {
13788 cache[ id ] = jQuery.extend( cache[ id ], name );
13789 } else {
13790 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
13791 }
13792 }
13793
13794 thisCache = cache[ id ];
13795
13796 // jQuery data() is stored in a separate object inside the object's internal data
13797 // cache in order to avoid key collisions between internal data and user-defined
13798 // data.
13799 if ( !pvt ) {
13800 if ( !thisCache.data ) {
13801 thisCache.data = {};
13802 }
13803
13804 thisCache = thisCache.data;
13805 }
13806
13807 if ( data !== undefined ) {
13808 thisCache[ jQuery.camelCase( name ) ] = data;
13809 }
13810
13811 // Check for both converted-to-camel and non-converted data property names
13812 // If a data property was specified
13813 if ( typeof name === "string" ) {
13814
13815 // First Try to find as-is property data
13816 ret = thisCache[ name ];
13817
13818 // Test for null|undefined property data
13819 if ( ret == null ) {
13820
13821 // Try to find the camelCased property
13822 ret = thisCache[ jQuery.camelCase( name ) ];
13823 }
13824 } else {
13825 ret = thisCache;
13826 }
13827
13828 return ret;
13829 }
13830
13831 function internalRemoveData( elem, name, pvt ) {
13832 if ( !acceptData( elem ) ) {
13833 return;
13834 }
13835
13836 var thisCache, i,
13837 isNode = elem.nodeType,
13838
13839 // See jQuery.data for more information
13840 cache = isNode ? jQuery.cache : elem,
13841 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
13842
13843 // If there is already no cache entry for this object, there is no
13844 // purpose in continuing
13845 if ( !cache[ id ] ) {
13846 return;
13847 }
13848
13849 if ( name ) {
13850
13851 thisCache = pvt ? cache[ id ] : cache[ id ].data;
13852
13853 if ( thisCache ) {
13854
13855 // Support array or space separated string names for data keys
13856 if ( !jQuery.isArray( name ) ) {
13857
13858 // try the string as a key before any manipulation
13859 if ( name in thisCache ) {
13860 name = [ name ];
13861 } else {
13862
13863 // split the camel cased version by spaces unless a key with the spaces exists
13864 name = jQuery.camelCase( name );
13865 if ( name in thisCache ) {
13866 name = [ name ];
13867 } else {
13868 name = name.split( " " );
13869 }
13870 }
13871 } else {
13872
13873 // If "name" is an array of keys...
13874 // When data is initially created, via ("key", "val") signature,
13875 // keys will be converted to camelCase.
13876 // Since there is no way to tell _how_ a key was added, remove
13877 // both plain key and camelCase key. #12786
13878 // This will only penalize the array argument path.
13879 name = name.concat( jQuery.map( name, jQuery.camelCase ) );
13880 }
13881
13882 i = name.length;
13883 while ( i-- ) {
13884 delete thisCache[ name[ i ] ];
13885 }
13886
13887 // If there is no data left in the cache, we want to continue
13888 // and let the cache object itself get destroyed
13889 if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
13890 return;
13891 }
13892 }
13893 }
13894
13895 // See jQuery.data for more information
13896 if ( !pvt ) {
13897 delete cache[ id ].data;
13898
13899 // Don't destroy the parent cache unless the internal data object
13900 // had been the only thing left in it
13901 if ( !isEmptyDataObject( cache[ id ] ) ) {
13902 return;
13903 }
13904 }
13905
13906 // Destroy the cache
13907 if ( isNode ) {
13908 jQuery.cleanData( [ elem ], true );
13909
13910 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
13911 /* jshint eqeqeq: false */
13912 } else if ( support.deleteExpando || cache != cache.window ) {
13913 /* jshint eqeqeq: true */
13914 delete cache[ id ];
13915
13916 // When all else fails, undefined
13917 } else {
13918 cache[ id ] = undefined;
13919 }
13920 }
13921
13922 jQuery.extend( {
13923 cache: {},
13924
13925 // The following elements (space-suffixed to avoid Object.prototype collisions)
13926 // throw uncatchable exceptions if you attempt to set expando properties
13927 noData: {
13928 "applet ": true,
13929 "embed ": true,
13930
13931 // ...but Flash objects (which have this classid) *can* handle expandos
13932 "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
13933 },
13934
13935 hasData: function( elem ) {
13936 elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
13937 return !!elem && !isEmptyDataObject( elem );
13938 },
13939
13940 data: function( elem, name, data ) {
13941 return internalData( elem, name, data );
13942 },
13943
13944 removeData: function( elem, name ) {
13945 return internalRemoveData( elem, name );
13946 },
13947
13948 // For internal use only.
13949 _data: function( elem, name, data ) {
13950 return internalData( elem, name, data, true );
13951 },
13952
13953 _removeData: function( elem, name ) {
13954 return internalRemoveData( elem, name, true );
13955 }
13956 } );
13957
13958 jQuery.fn.extend( {
13959 data: function( key, value ) {
13960 var i, name, data,
13961 elem = this[ 0 ],
13962 attrs = elem && elem.attributes;
13963
13964 // Special expections of .data basically thwart jQuery.access,
13965 // so implement the relevant behavior ourselves
13966
13967 // Gets all values
13968 if ( key === undefined ) {
13969 if ( this.length ) {
13970 data = jQuery.data( elem );
13971
13972 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
13973 i = attrs.length;
13974 while ( i-- ) {
13975
13976 // Support: IE11+
13977 // The attrs elements can be null (#14894)
13978 if ( attrs[ i ] ) {
13979 name = attrs[ i ].name;
13980 if ( name.indexOf( "data-" ) === 0 ) {
13981 name = jQuery.camelCase( name.slice( 5 ) );
13982 dataAttr( elem, name, data[ name ] );
13983 }
13984 }
13985 }
13986 jQuery._data( elem, "parsedAttrs", true );
13987 }
13988 }
13989
13990 return data;
13991 }
13992
13993 // Sets multiple values
13994 if ( typeof key === "object" ) {
13995 return this.each( function() {
13996 jQuery.data( this, key );
13997 } );
13998 }
13999
14000 return arguments.length > 1 ?
14001
14002 // Sets one value
14003 this.each( function() {
14004 jQuery.data( this, key, value );
14005 } ) :
14006
14007 // Gets one value
14008 // Try to fetch any internally stored data first
14009 elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
14010 },
14011
14012 removeData: function( key ) {
14013 return this.each( function() {
14014 jQuery.removeData( this, key );
14015 } );
14016 }
14017 } );
14018
14019
14020 jQuery.extend( {
14021 queue: function( elem, type, data ) {
14022 var queue;
14023
14024 if ( elem ) {
14025 type = ( type || "fx" ) + "queue";
14026 queue = jQuery._data( elem, type );
14027
14028 // Speed up dequeue by getting out quickly if this is just a lookup
14029 if ( data ) {
14030 if ( !queue || jQuery.isArray( data ) ) {
14031 queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
14032 } else {
14033 queue.push( data );
14034 }
14035 }
14036 return queue || [];
14037 }
14038 },
14039
14040 dequeue: function( elem, type ) {
14041 type = type || "fx";
14042
14043 var queue = jQuery.queue( elem, type ),
14044 startLength = queue.length,
14045 fn = queue.shift(),
14046 hooks = jQuery._queueHooks( elem, type ),
14047 next = function() {
14048 jQuery.dequeue( elem, type );
14049 };
14050
14051 // If the fx queue is dequeued, always remove the progress sentinel
14052 if ( fn === "inprogress" ) {
14053 fn = queue.shift();
14054 startLength--;
14055 }
14056
14057 if ( fn ) {
14058
14059 // Add a progress sentinel to prevent the fx queue from being
14060 // automatically dequeued
14061 if ( type === "fx" ) {
14062 queue.unshift( "inprogress" );
14063 }
14064
14065 // clear up the last queue stop function
14066 delete hooks.stop;
14067 fn.call( elem, next, hooks );
14068 }
14069
14070 if ( !startLength && hooks ) {
14071 hooks.empty.fire();
14072 }
14073 },
14074
14075 // not intended for public consumption - generates a queueHooks object,
14076 // or returns the current one
14077 _queueHooks: function( elem, type ) {
14078 var key = type + "queueHooks";
14079 return jQuery._data( elem, key ) || jQuery._data( elem, key, {
14080 empty: jQuery.Callbacks( "once memory" ).add( function() {
14081 jQuery._removeData( elem, type + "queue" );
14082 jQuery._removeData( elem, key );
14083 } )
14084 } );
14085 }
14086 } );
14087
14088 jQuery.fn.extend( {
14089 queue: function( type, data ) {
14090 var setter = 2;
14091
14092 if ( typeof type !== "string" ) {
14093 data = type;
14094 type = "fx";
14095 setter--;
14096 }
14097
14098 if ( arguments.length < setter ) {
14099 return jQuery.queue( this[ 0 ], type );
14100 }
14101
14102 return data === undefined ?
14103 this :
14104 this.each( function() {
14105 var queue = jQuery.queue( this, type, data );
14106
14107 // ensure a hooks for this queue
14108 jQuery._queueHooks( this, type );
14109
14110 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
14111 jQuery.dequeue( this, type );
14112 }
14113 } );
14114 },
14115 dequeue: function( type ) {
14116 return this.each( function() {
14117 jQuery.dequeue( this, type );
14118 } );
14119 },
14120 clearQueue: function( type ) {
14121 return this.queue( type || "fx", [] );
14122 },
14123
14124 // Get a promise resolved when queues of a certain type
14125 // are emptied (fx is the type by default)
14126 promise: function( type, obj ) {
14127 var tmp,
14128 count = 1,
14129 defer = jQuery.Deferred(),
14130 elements = this,
14131 i = this.length,
14132 resolve = function() {
14133 if ( !( --count ) ) {
14134 defer.resolveWith( elements, [ elements ] );
14135 }
14136 };
14137
14138 if ( typeof type !== "string" ) {
14139 obj = type;
14140 type = undefined;
14141 }
14142 type = type || "fx";
14143
14144 while ( i-- ) {
14145 tmp = jQuery._data( elements[ i ], type + "queueHooks" );
14146 if ( tmp && tmp.empty ) {
14147 count++;
14148 tmp.empty.add( resolve );
14149 }
14150 }
14151 resolve();
14152 return defer.promise( obj );
14153 }
14154 } );
14155
14156
14157 ( function() {
14158 var shrinkWrapBlocksVal;
14159
14160 support.shrinkWrapBlocks = function() {
14161 if ( shrinkWrapBlocksVal != null ) {
14162 return shrinkWrapBlocksVal;
14163 }
14164
14165 // Will be changed later if needed.
14166 shrinkWrapBlocksVal = false;
14167
14168 // Minified: var b,c,d
14169 var div, body, container;
14170
14171 body = document.getElementsByTagName( "body" )[ 0 ];
14172 if ( !body || !body.style ) {
14173
14174 // Test fired too early or in an unsupported environment, exit.
14175 return;
14176 }
14177
14178 // Setup
14179 div = document.createElement( "div" );
14180 container = document.createElement( "div" );
14181 container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
14182 body.appendChild( container ).appendChild( div );
14183
14184 // Support: IE6
14185 // Check if elements with layout shrink-wrap their children
14186 if ( typeof div.style.zoom !== "undefined" ) {
14187
14188 // Reset CSS: box-sizing; display; margin; border
14189 div.style.cssText =
14190
14191 // Support: Firefox<29, Android 2.3
14192 // Vendor-prefix box-sizing
14193 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
14194 "box-sizing:content-box;display:block;margin:0;border:0;" +
14195 "padding:1px;width:1px;zoom:1";
14196 div.appendChild( document.createElement( "div" ) ).style.width = "5px";
14197 shrinkWrapBlocksVal = div.offsetWidth !== 3;
14198 }
14199
14200 body.removeChild( container );
14201
14202 return shrinkWrapBlocksVal;
14203 };
14204
14205 } )();
14206 var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
14207
14208 var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
14209
14210
14211 var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
14212
14213 var isHidden = function( elem, el ) {
14214
14215 // isHidden might be called from jQuery#filter function;
14216 // in that case, element will be second argument
14217 elem = el || elem;
14218 return jQuery.css( elem, "display" ) === "none" ||
14219 !jQuery.contains( elem.ownerDocument, elem );
14220 };
14221
14222
14223
14224 function adjustCSS( elem, prop, valueParts, tween ) {
14225 var adjusted,
14226 scale = 1,
14227 maxIterations = 20,
14228 currentValue = tween ?
14229 function() { return tween.cur(); } :
14230 function() { return jQuery.css( elem, prop, "" ); },
14231 initial = currentValue(),
14232 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
14233
14234 // Starting value computation is required for potential unit mismatches
14235 initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
14236 rcssNum.exec( jQuery.css( elem, prop ) );
14237
14238 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
14239
14240 // Trust units reported by jQuery.css
14241 unit = unit || initialInUnit[ 3 ];
14242
14243 // Make sure we update the tween properties later on
14244 valueParts = valueParts || [];
14245
14246 // Iteratively approximate from a nonzero starting point
14247 initialInUnit = +initial || 1;
14248
14249 do {
14250
14251 // If previous iteration zeroed out, double until we get *something*.
14252 // Use string for doubling so we don't accidentally see scale as unchanged below
14253 scale = scale || ".5";
14254
14255 // Adjust and apply
14256 initialInUnit = initialInUnit / scale;
14257 jQuery.style( elem, prop, initialInUnit + unit );
14258
14259 // Update scale, tolerating zero or NaN from tween.cur()
14260 // Break the loop if scale is unchanged or perfect, or if we've just had enough.
14261 } while (
14262 scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
14263 );
14264 }
14265
14266 if ( valueParts ) {
14267 initialInUnit = +initialInUnit || +initial || 0;
14268
14269 // Apply relative offset (+=/-=) if specified
14270 adjusted = valueParts[ 1 ] ?
14271 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
14272 +valueParts[ 2 ];
14273 if ( tween ) {
14274 tween.unit = unit;
14275 tween.start = initialInUnit;
14276 tween.end = adjusted;
14277 }
14278 }
14279 return adjusted;
14280 }
14281
14282
14283 // Multifunctional method to get and set values of a collection
14284 // The value/s can optionally be executed if it's a function
14285 var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
14286 var i = 0,
14287 length = elems.length,
14288 bulk = key == null;
14289
14290 // Sets many values
14291 if ( jQuery.type( key ) === "object" ) {
14292 chainable = true;
14293 for ( i in key ) {
14294 access( elems, fn, i, key[ i ], true, emptyGet, raw );
14295 }
14296
14297 // Sets one value
14298 } else if ( value !== undefined ) {
14299 chainable = true;
14300
14301 if ( !jQuery.isFunction( value ) ) {
14302 raw = true;
14303 }
14304
14305 if ( bulk ) {
14306
14307 // Bulk operations run against the entire set
14308 if ( raw ) {
14309 fn.call( elems, value );
14310 fn = null;
14311
14312 // ...except when executing function values
14313 } else {
14314 bulk = fn;
14315 fn = function( elem, key, value ) {
14316 return bulk.call( jQuery( elem ), value );
14317 };
14318 }
14319 }
14320
14321 if ( fn ) {
14322 for ( ; i < length; i++ ) {
14323 fn(
14324 elems[ i ],
14325 key,
14326 raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
14327 );
14328 }
14329 }
14330 }
14331
14332 return chainable ?
14333 elems :
14334
14335 // Gets
14336 bulk ?
14337 fn.call( elems ) :
14338 length ? fn( elems[ 0 ], key ) : emptyGet;
14339 };
14340 var rcheckableType = ( /^(?:checkbox|radio)$/i );
14341
14342 var rtagName = ( /<([\w:-]+)/ );
14343
14344 var rscriptType = ( /^$|\/(?:java|ecma)script/i );
14345
14346 var rleadingWhitespace = ( /^\s+/ );
14347
14348 var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
14349 "details|dialog|figcaption|figure|footer|header|hgroup|main|" +
14350 "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
14351
14352
14353
14354 function createSafeFragment( document ) {
14355 var list = nodeNames.split( "|" ),
14356 safeFrag = document.createDocumentFragment();
14357
14358 if ( safeFrag.createElement ) {
14359 while ( list.length ) {
14360 safeFrag.createElement(
14361 list.pop()
14362 );
14363 }
14364 }
14365 return safeFrag;
14366 }
14367
14368
14369 ( function() {
14370 var div = document.createElement( "div" ),
14371 fragment = document.createDocumentFragment(),
14372 input = document.createElement( "input" );
14373
14374 // Setup
14375 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
14376
14377 // IE strips leading whitespace when .innerHTML is used
14378 support.leadingWhitespace = div.firstChild.nodeType === 3;
14379
14380 // Make sure that tbody elements aren't automatically inserted
14381 // IE will insert them into empty tables
14382 support.tbody = !div.getElementsByTagName( "tbody" ).length;
14383
14384 // Make sure that link elements get serialized correctly by innerHTML
14385 // This requires a wrapper element in IE
14386 support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
14387
14388 // Makes sure cloning an html5 element does not cause problems
14389 // Where outerHTML is undefined, this still works
14390 support.html5Clone =
14391 document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
14392
14393 // Check if a disconnected checkbox will retain its checked
14394 // value of true after appended to the DOM (IE6/7)
14395 input.type = "checkbox";
14396 input.checked = true;
14397 fragment.appendChild( input );
14398 support.appendChecked = input.checked;
14399
14400 // Make sure textarea (and checkbox) defaultValue is properly cloned
14401 // Support: IE6-IE11+
14402 div.innerHTML = "<textarea>x</textarea>";
14403 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
14404
14405 // #11217 - WebKit loses check when the name is after the checked attribute
14406 fragment.appendChild( div );
14407
14408 // Support: Windows Web Apps (WWA)
14409 // `name` and `type` must use .setAttribute for WWA (#14901)
14410 input = document.createElement( "input" );
14411 input.setAttribute( "type", "radio" );
14412 input.setAttribute( "checked", "checked" );
14413 input.setAttribute( "name", "t" );
14414
14415 div.appendChild( input );
14416
14417 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
14418 // old WebKit doesn't clone checked state correctly in fragments
14419 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
14420
14421 // Support: IE<9
14422 // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
14423 support.noCloneEvent = !!div.addEventListener;
14424
14425 // Support: IE<9
14426 // Since attributes and properties are the same in IE,
14427 // cleanData must set properties to undefined rather than use removeAttribute
14428 div[ jQuery.expando ] = 1;
14429 support.attributes = !div.getAttribute( jQuery.expando );
14430 } )();
14431
14432
14433 // We have to close these tags to support XHTML (#13200)
14434 var wrapMap = {
14435 option: [ 1, "<select multiple='multiple'>", "</select>" ],
14436 legend: [ 1, "<fieldset>", "</fieldset>" ],
14437 area: [ 1, "<map>", "</map>" ],
14438
14439 // Support: IE8
14440 param: [ 1, "<object>", "</object>" ],
14441 thead: [ 1, "<table>", "</table>" ],
14442 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
14443 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
14444 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
14445
14446 // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
14447 // unless wrapped in a div with non-breaking characters in front of it.
14448 _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
14449 };
14450
14451 // Support: IE8-IE9
14452 wrapMap.optgroup = wrapMap.option;
14453
14454 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
14455 wrapMap.th = wrapMap.td;
14456
14457
14458 function getAll( context, tag ) {
14459 var elems, elem,
14460 i = 0,
14461 found = typeof context.getElementsByTagName !== "undefined" ?
14462 context.getElementsByTagName( tag || "*" ) :
14463 typeof context.querySelectorAll !== "undefined" ?
14464 context.querySelectorAll( tag || "*" ) :
14465 undefined;
14466
14467 if ( !found ) {
14468 for ( found = [], elems = context.childNodes || context;
14469 ( elem = elems[ i ] ) != null;
14470 i++
14471 ) {
14472 if ( !tag || jQuery.nodeName( elem, tag ) ) {
14473 found.push( elem );
14474 } else {
14475 jQuery.merge( found, getAll( elem, tag ) );
14476 }
14477 }
14478 }
14479
14480 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
14481 jQuery.merge( [ context ], found ) :
14482 found;
14483 }
14484
14485
14486 // Mark scripts as having already been evaluated
14487 function setGlobalEval( elems, refElements ) {
14488 var elem,
14489 i = 0;
14490 for ( ; ( elem = elems[ i ] ) != null; i++ ) {
14491 jQuery._data(
14492 elem,
14493 "globalEval",
14494 !refElements || jQuery._data( refElements[ i ], "globalEval" )
14495 );
14496 }
14497 }
14498
14499
14500 var rhtml = /<|&#?\w+;/,
14501 rtbody = /<tbody/i;
14502
14503 function fixDefaultChecked( elem ) {
14504 if ( rcheckableType.test( elem.type ) ) {
14505 elem.defaultChecked = elem.checked;
14506 }
14507 }
14508
14509 function buildFragment( elems, context, scripts, selection, ignored ) {
14510 var j, elem, contains,
14511 tmp, tag, tbody, wrap,
14512 l = elems.length,
14513
14514 // Ensure a safe fragment
14515 safe = createSafeFragment( context ),
14516
14517 nodes = [],
14518 i = 0;
14519
14520 for ( ; i < l; i++ ) {
14521 elem = elems[ i ];
14522
14523 if ( elem || elem === 0 ) {
14524
14525 // Add nodes directly
14526 if ( jQuery.type( elem ) === "object" ) {
14527 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
14528
14529 // Convert non-html into a text node
14530 } else if ( !rhtml.test( elem ) ) {
14531 nodes.push( context.createTextNode( elem ) );
14532
14533 // Convert html into DOM nodes
14534 } else {
14535 tmp = tmp || safe.appendChild( context.createElement( "div" ) );
14536
14537 // Deserialize a standard representation
14538 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
14539 wrap = wrapMap[ tag ] || wrapMap._default;
14540
14541 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
14542
14543 // Descend through wrappers to the right content
14544 j = wrap[ 0 ];
14545 while ( j-- ) {
14546 tmp = tmp.lastChild;
14547 }
14548
14549 // Manually add leading whitespace removed by IE
14550 if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
14551 nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
14552 }
14553
14554 // Remove IE's autoinserted <tbody> from table fragments
14555 if ( !support.tbody ) {
14556
14557 // String was a <table>, *may* have spurious <tbody>
14558 elem = tag === "table" && !rtbody.test( elem ) ?
14559 tmp.firstChild :
14560
14561 // String was a bare <thead> or <tfoot>
14562 wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
14563 tmp :
14564 0;
14565
14566 j = elem && elem.childNodes.length;
14567 while ( j-- ) {
14568 if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
14569 !tbody.childNodes.length ) {
14570
14571 elem.removeChild( tbody );
14572 }
14573 }
14574 }
14575
14576 jQuery.merge( nodes, tmp.childNodes );
14577
14578 // Fix #12392 for WebKit and IE > 9
14579 tmp.textContent = "";
14580
14581 // Fix #12392 for oldIE
14582 while ( tmp.firstChild ) {
14583 tmp.removeChild( tmp.firstChild );
14584 }
14585
14586 // Remember the top-level container for proper cleanup
14587 tmp = safe.lastChild;
14588 }
14589 }
14590 }
14591
14592 // Fix #11356: Clear elements from fragment
14593 if ( tmp ) {
14594 safe.removeChild( tmp );
14595 }
14596
14597 // Reset defaultChecked for any radios and checkboxes
14598 // about to be appended to the DOM in IE 6/7 (#8060)
14599 if ( !support.appendChecked ) {
14600 jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
14601 }
14602
14603 i = 0;
14604 while ( ( elem = nodes[ i++ ] ) ) {
14605
14606 // Skip elements already in the context collection (trac-4087)
14607 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
14608 if ( ignored ) {
14609 ignored.push( elem );
14610 }
14611
14612 continue;
14613 }
14614
14615 contains = jQuery.contains( elem.ownerDocument, elem );
14616
14617 // Append to fragment
14618 tmp = getAll( safe.appendChild( elem ), "script" );
14619
14620 // Preserve script evaluation history
14621 if ( contains ) {
14622 setGlobalEval( tmp );
14623 }
14624
14625 // Capture executables
14626 if ( scripts ) {
14627 j = 0;
14628 while ( ( elem = tmp[ j++ ] ) ) {
14629 if ( rscriptType.test( elem.type || "" ) ) {
14630 scripts.push( elem );
14631 }
14632 }
14633 }
14634 }
14635
14636 tmp = null;
14637
14638 return safe;
14639 }
14640
14641
14642 ( function() {
14643 var i, eventName,
14644 div = document.createElement( "div" );
14645
14646 // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
14647 for ( i in { submit: true, change: true, focusin: true } ) {
14648 eventName = "on" + i;
14649
14650 if ( !( support[ i ] = eventName in window ) ) {
14651
14652 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
14653 div.setAttribute( eventName, "t" );
14654 support[ i ] = div.attributes[ eventName ].expando === false;
14655 }
14656 }
14657
14658 // Null elements to avoid leaks in IE.
14659 div = null;
14660 } )();
14661
14662
14663 var rformElems = /^(?:input|select|textarea)$/i,
14664 rkeyEvent = /^key/,
14665 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
14666 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
14667 rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
14668
14669 function returnTrue() {
14670 return true;
14671 }
14672
14673 function returnFalse() {
14674 return false;
14675 }
14676
14677 // Support: IE9
14678 // See #13393 for more info
14679 function safeActiveElement() {
14680 try {
14681 return document.activeElement;
14682 } catch ( err ) { }
14683 }
14684
14685 function on( elem, types, selector, data, fn, one ) {
14686 var origFn, type;
14687
14688 // Types can be a map of types/handlers
14689 if ( typeof types === "object" ) {
14690
14691 // ( types-Object, selector, data )
14692 if ( typeof selector !== "string" ) {
14693
14694 // ( types-Object, data )
14695 data = data || selector;
14696 selector = undefined;
14697 }
14698 for ( type in types ) {
14699 on( elem, type, selector, data, types[ type ], one );
14700 }
14701 return elem;
14702 }
14703
14704 if ( data == null && fn == null ) {
14705
14706 // ( types, fn )
14707 fn = selector;
14708 data = selector = undefined;
14709 } else if ( fn == null ) {
14710 if ( typeof selector === "string" ) {
14711
14712 // ( types, selector, fn )
14713 fn = data;
14714 data = undefined;
14715 } else {
14716
14717 // ( types, data, fn )
14718 fn = data;
14719 data = selector;
14720 selector = undefined;
14721 }
14722 }
14723 if ( fn === false ) {
14724 fn = returnFalse;
14725 } else if ( !fn ) {
14726 return elem;
14727 }
14728
14729 if ( one === 1 ) {
14730 origFn = fn;
14731 fn = function( event ) {
14732
14733 // Can use an empty set, since event contains the info
14734 jQuery().off( event );
14735 return origFn.apply( this, arguments );
14736 };
14737
14738 // Use same guid so caller can remove using origFn
14739 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
14740 }
14741 return elem.each( function() {
14742 jQuery.event.add( this, types, fn, data, selector );
14743 } );
14744 }
14745
14746 /*
14747 * Helper functions for managing events -- not part of the public interface.
14748 * Props to Dean Edwards' addEvent library for many of the ideas.
14749 */
14750 jQuery.event = {
14751
14752 global: {},
14753
14754 add: function( elem, types, handler, data, selector ) {
14755 var tmp, events, t, handleObjIn,
14756 special, eventHandle, handleObj,
14757 handlers, type, namespaces, origType,
14758 elemData = jQuery._data( elem );
14759
14760 // Don't attach events to noData or text/comment nodes (but allow plain objects)
14761 if ( !elemData ) {
14762 return;
14763 }
14764
14765 // Caller can pass in an object of custom data in lieu of the handler
14766 if ( handler.handler ) {
14767 handleObjIn = handler;
14768 handler = handleObjIn.handler;
14769 selector = handleObjIn.selector;
14770 }
14771
14772 // Make sure that the handler has a unique ID, used to find/remove it later
14773 if ( !handler.guid ) {
14774 handler.guid = jQuery.guid++;
14775 }
14776
14777 // Init the element's event structure and main handler, if this is the first
14778 if ( !( events = elemData.events ) ) {
14779 events = elemData.events = {};
14780 }
14781 if ( !( eventHandle = elemData.handle ) ) {
14782 eventHandle = elemData.handle = function( e ) {
14783
14784 // Discard the second event of a jQuery.event.trigger() and
14785 // when an event is called after a page has unloaded
14786 return typeof jQuery !== "undefined" &&
14787 ( !e || jQuery.event.triggered !== e.type ) ?
14788 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
14789 undefined;
14790 };
14791
14792 // Add elem as a property of the handle fn to prevent a memory leak
14793 // with IE non-native events
14794 eventHandle.elem = elem;
14795 }
14796
14797 // Handle multiple events separated by a space
14798 types = ( types || "" ).match( rnotwhite ) || [ "" ];
14799 t = types.length;
14800 while ( t-- ) {
14801 tmp = rtypenamespace.exec( types[ t ] ) || [];
14802 type = origType = tmp[ 1 ];
14803 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
14804
14805 // There *must* be a type, no attaching namespace-only handlers
14806 if ( !type ) {
14807 continue;
14808 }
14809
14810 // If event changes its type, use the special event handlers for the changed type
14811 special = jQuery.event.special[ type ] || {};
14812
14813 // If selector defined, determine special event api type, otherwise given type
14814 type = ( selector ? special.delegateType : special.bindType ) || type;
14815
14816 // Update special based on newly reset type
14817 special = jQuery.event.special[ type ] || {};
14818
14819 // handleObj is passed to all event handlers
14820 handleObj = jQuery.extend( {
14821 type: type,
14822 origType: origType,
14823 data: data,
14824 handler: handler,
14825 guid: handler.guid,
14826 selector: selector,
14827 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
14828 namespace: namespaces.join( "." )
14829 }, handleObjIn );
14830
14831 // Init the event handler queue if we're the first
14832 if ( !( handlers = events[ type ] ) ) {
14833 handlers = events[ type ] = [];
14834 handlers.delegateCount = 0;
14835
14836 // Only use addEventListener/attachEvent if the special events handler returns false
14837 if ( !special.setup ||
14838 special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
14839
14840 // Bind the global event handler to the element
14841 if ( elem.addEventListener ) {
14842 elem.addEventListener( type, eventHandle, false );
14843
14844 } else if ( elem.attachEvent ) {
14845 elem.attachEvent( "on" + type, eventHandle );
14846 }
14847 }
14848 }
14849
14850 if ( special.add ) {
14851 special.add.call( elem, handleObj );
14852
14853 if ( !handleObj.handler.guid ) {
14854 handleObj.handler.guid = handler.guid;
14855 }
14856 }
14857
14858 // Add to the element's handler list, delegates in front
14859 if ( selector ) {
14860 handlers.splice( handlers.delegateCount++, 0, handleObj );
14861 } else {
14862 handlers.push( handleObj );
14863 }
14864
14865 // Keep track of which events have ever been used, for event optimization
14866 jQuery.event.global[ type ] = true;
14867 }
14868
14869 // Nullify elem to prevent memory leaks in IE
14870 elem = null;
14871 },
14872
14873 // Detach an event or set of events from an element
14874 remove: function( elem, types, handler, selector, mappedTypes ) {
14875 var j, handleObj, tmp,
14876 origCount, t, events,
14877 special, handlers, type,
14878 namespaces, origType,
14879 elemData = jQuery.hasData( elem ) && jQuery._data( elem );
14880
14881 if ( !elemData || !( events = elemData.events ) ) {
14882 return;
14883 }
14884
14885 // Once for each type.namespace in types; type may be omitted
14886 types = ( types || "" ).match( rnotwhite ) || [ "" ];
14887 t = types.length;
14888 while ( t-- ) {
14889 tmp = rtypenamespace.exec( types[ t ] ) || [];
14890 type = origType = tmp[ 1 ];
14891 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
14892
14893 // Unbind all events (on this namespace, if provided) for the element
14894 if ( !type ) {
14895 for ( type in events ) {
14896 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
14897 }
14898 continue;
14899 }
14900
14901 special = jQuery.event.special[ type ] || {};
14902 type = ( selector ? special.delegateType : special.bindType ) || type;
14903 handlers = events[ type ] || [];
14904 tmp = tmp[ 2 ] &&
14905 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
14906
14907 // Remove matching events
14908 origCount = j = handlers.length;
14909 while ( j-- ) {
14910 handleObj = handlers[ j ];
14911
14912 if ( ( mappedTypes || origType === handleObj.origType ) &&
14913 ( !handler || handler.guid === handleObj.guid ) &&
14914 ( !tmp || tmp.test( handleObj.namespace ) ) &&
14915 ( !selector || selector === handleObj.selector ||
14916 selector === "**" && handleObj.selector ) ) {
14917 handlers.splice( j, 1 );
14918
14919 if ( handleObj.selector ) {
14920 handlers.delegateCount--;
14921 }
14922 if ( special.remove ) {
14923 special.remove.call( elem, handleObj );
14924 }
14925 }
14926 }
14927
14928 // Remove generic event handler if we removed something and no more handlers exist
14929 // (avoids potential for endless recursion during removal of special event handlers)
14930 if ( origCount && !handlers.length ) {
14931 if ( !special.teardown ||
14932 special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
14933
14934 jQuery.removeEvent( elem, type, elemData.handle );
14935 }
14936
14937 delete events[ type ];
14938 }
14939 }
14940
14941 // Remove the expando if it's no longer used
14942 if ( jQuery.isEmptyObject( events ) ) {
14943 delete elemData.handle;
14944
14945 // removeData also checks for emptiness and clears the expando if empty
14946 // so use it instead of delete
14947 jQuery._removeData( elem, "events" );
14948 }
14949 },
14950
14951 trigger: function( event, data, elem, onlyHandlers ) {
14952 var handle, ontype, cur,
14953 bubbleType, special, tmp, i,
14954 eventPath = [ elem || document ],
14955 type = hasOwn.call( event, "type" ) ? event.type : event,
14956 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
14957
14958 cur = tmp = elem = elem || document;
14959
14960 // Don't do events on text and comment nodes
14961 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
14962 return;
14963 }
14964
14965 // focus/blur morphs to focusin/out; ensure we're not firing them right now
14966 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
14967 return;
14968 }
14969
14970 if ( type.indexOf( "." ) > -1 ) {
14971
14972 // Namespaced trigger; create a regexp to match event type in handle()
14973 namespaces = type.split( "." );
14974 type = namespaces.shift();
14975 namespaces.sort();
14976 }
14977 ontype = type.indexOf( ":" ) < 0 && "on" + type;
14978
14979 // Caller can pass in a jQuery.Event object, Object, or just an event type string
14980 event = event[ jQuery.expando ] ?
14981 event :
14982 new jQuery.Event( type, typeof event === "object" && event );
14983
14984 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
14985 event.isTrigger = onlyHandlers ? 2 : 3;
14986 event.namespace = namespaces.join( "." );
14987 event.rnamespace = event.namespace ?
14988 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
14989 null;
14990
14991 // Clean up the event in case it is being reused
14992 event.result = undefined;
14993 if ( !event.target ) {
14994 event.target = elem;
14995 }
14996
14997 // Clone any incoming data and prepend the event, creating the handler arg list
14998 data = data == null ?
14999 [ event ] :
15000 jQuery.makeArray( data, [ event ] );
15001
15002 // Allow special events to draw outside the lines
15003 special = jQuery.event.special[ type ] || {};
15004 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
15005 return;
15006 }
15007
15008 // Determine event propagation path in advance, per W3C events spec (#9951)
15009 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
15010 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
15011
15012 bubbleType = special.delegateType || type;
15013 if ( !rfocusMorph.test( bubbleType + type ) ) {
15014 cur = cur.parentNode;
15015 }
15016 for ( ; cur; cur = cur.parentNode ) {
15017 eventPath.push( cur );
15018 tmp = cur;
15019 }
15020
15021 // Only add window if we got to document (e.g., not plain obj or detached DOM)
15022 if ( tmp === ( elem.ownerDocument || document ) ) {
15023 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
15024 }
15025 }
15026
15027 // Fire handlers on the event path
15028 i = 0;
15029 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
15030
15031 event.type = i > 1 ?
15032 bubbleType :
15033 special.bindType || type;
15034
15035 // jQuery handler
15036 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
15037 jQuery._data( cur, "handle" );
15038
15039 if ( handle ) {
15040 handle.apply( cur, data );
15041 }
15042
15043 // Native handler
15044 handle = ontype && cur[ ontype ];
15045 if ( handle && handle.apply && acceptData( cur ) ) {
15046 event.result = handle.apply( cur, data );
15047 if ( event.result === false ) {
15048 event.preventDefault();
15049 }
15050 }
15051 }
15052 event.type = type;
15053
15054 // If nobody prevented the default action, do it now
15055 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
15056
15057 if (
15058 ( !special._default ||
15059 special._default.apply( eventPath.pop(), data ) === false
15060 ) && acceptData( elem )
15061 ) {
15062
15063 // Call a native DOM method on the target with the same name name as the event.
15064 // Can't use an .isFunction() check here because IE6/7 fails that test.
15065 // Don't do default actions on window, that's where global variables be (#6170)
15066 if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
15067
15068 // Don't re-trigger an onFOO event when we call its FOO() method
15069 tmp = elem[ ontype ];
15070
15071 if ( tmp ) {
15072 elem[ ontype ] = null;
15073 }
15074
15075 // Prevent re-triggering of the same event, since we already bubbled it above
15076 jQuery.event.triggered = type;
15077 try {
15078 elem[ type ]();
15079 } catch ( e ) {
15080
15081 // IE<9 dies on focus/blur to hidden element (#1486,#12518)
15082 // only reproducible on winXP IE8 native, not IE9 in IE8 mode
15083 }
15084 jQuery.event.triggered = undefined;
15085
15086 if ( tmp ) {
15087 elem[ ontype ] = tmp;
15088 }
15089 }
15090 }
15091 }
15092
15093 return event.result;
15094 },
15095
15096 dispatch: function( event ) {
15097
15098 // Make a writable jQuery.Event from the native event object
15099 event = jQuery.event.fix( event );
15100
15101 var i, j, ret, matched, handleObj,
15102 handlerQueue = [],
15103 args = slice.call( arguments ),
15104 handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
15105 special = jQuery.event.special[ event.type ] || {};
15106
15107 // Use the fix-ed jQuery.Event rather than the (read-only) native event
15108 args[ 0 ] = event;
15109 event.delegateTarget = this;
15110
15111 // Call the preDispatch hook for the mapped type, and let it bail if desired
15112 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
15113 return;
15114 }
15115
15116 // Determine handlers
15117 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
15118
15119 // Run delegates first; they may want to stop propagation beneath us
15120 i = 0;
15121 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
15122 event.currentTarget = matched.elem;
15123
15124 j = 0;
15125 while ( ( handleObj = matched.handlers[ j++ ] ) &&
15126 !event.isImmediatePropagationStopped() ) {
15127
15128 // Triggered event must either 1) have no namespace, or 2) have namespace(s)
15129 // a subset or equal to those in the bound event (both can have no namespace).
15130 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
15131
15132 event.handleObj = handleObj;
15133 event.data = handleObj.data;
15134
15135 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
15136 handleObj.handler ).apply( matched.elem, args );
15137
15138 if ( ret !== undefined ) {
15139 if ( ( event.result = ret ) === false ) {
15140 event.preventDefault();
15141 event.stopPropagation();
15142 }
15143 }
15144 }
15145 }
15146 }
15147
15148 // Call the postDispatch hook for the mapped type
15149 if ( special.postDispatch ) {
15150 special.postDispatch.call( this, event );
15151 }
15152
15153 return event.result;
15154 },
15155
15156 handlers: function( event, handlers ) {
15157 var i, matches, sel, handleObj,
15158 handlerQueue = [],
15159 delegateCount = handlers.delegateCount,
15160 cur = event.target;
15161
15162 // Support (at least): Chrome, IE9
15163 // Find delegate handlers
15164 // Black-hole SVG <use> instance trees (#13180)
15165 //
15166 // Support: Firefox<=42+
15167 // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
15168 if ( delegateCount && cur.nodeType &&
15169 ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
15170
15171 /* jshint eqeqeq: false */
15172 for ( ; cur != this; cur = cur.parentNode || this ) {
15173 /* jshint eqeqeq: true */
15174
15175 // Don't check non-elements (#13208)
15176 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
15177 if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
15178 matches = [];
15179 for ( i = 0; i < delegateCount; i++ ) {
15180 handleObj = handlers[ i ];
15181
15182 // Don't conflict with Object.prototype properties (#13203)
15183 sel = handleObj.selector + " ";
15184
15185 if ( matches[ sel ] === undefined ) {
15186 matches[ sel ] = handleObj.needsContext ?
15187 jQuery( sel, this ).index( cur ) > -1 :
15188 jQuery.find( sel, this, null, [ cur ] ).length;
15189 }
15190 if ( matches[ sel ] ) {
15191 matches.push( handleObj );
15192 }
15193 }
15194 if ( matches.length ) {
15195 handlerQueue.push( { elem: cur, handlers: matches } );
15196 }
15197 }
15198 }
15199 }
15200
15201 // Add the remaining (directly-bound) handlers
15202 if ( delegateCount < handlers.length ) {
15203 handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
15204 }
15205
15206 return handlerQueue;
15207 },
15208
15209 fix: function( event ) {
15210 if ( event[ jQuery.expando ] ) {
15211 return event;
15212 }
15213
15214 // Create a writable copy of the event object and normalize some properties
15215 var i, prop, copy,
15216 type = event.type,
15217 originalEvent = event,
15218 fixHook = this.fixHooks[ type ];
15219
15220 if ( !fixHook ) {
15221 this.fixHooks[ type ] = fixHook =
15222 rmouseEvent.test( type ) ? this.mouseHooks :
15223 rkeyEvent.test( type ) ? this.keyHooks :
15224 {};
15225 }
15226 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
15227
15228 event = new jQuery.Event( originalEvent );
15229
15230 i = copy.length;
15231 while ( i-- ) {
15232 prop = copy[ i ];
15233 event[ prop ] = originalEvent[ prop ];
15234 }
15235
15236 // Support: IE<9
15237 // Fix target property (#1925)
15238 if ( !event.target ) {
15239 event.target = originalEvent.srcElement || document;
15240 }
15241
15242 // Support: Safari 6-8+
15243 // Target should not be a text node (#504, #13143)
15244 if ( event.target.nodeType === 3 ) {
15245 event.target = event.target.parentNode;
15246 }
15247
15248 // Support: IE<9
15249 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
15250 event.metaKey = !!event.metaKey;
15251
15252 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
15253 },
15254
15255 // Includes some event props shared by KeyEvent and MouseEvent
15256 props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
15257 "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
15258
15259 fixHooks: {},
15260
15261 keyHooks: {
15262 props: "char charCode key keyCode".split( " " ),
15263 filter: function( event, original ) {
15264
15265 // Add which for key events
15266 if ( event.which == null ) {
15267 event.which = original.charCode != null ? original.charCode : original.keyCode;
15268 }
15269
15270 return event;
15271 }
15272 },
15273
15274 mouseHooks: {
15275 props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
15276 "pageX pageY screenX screenY toElement" ).split( " " ),
15277 filter: function( event, original ) {
15278 var body, eventDoc, doc,
15279 button = original.button,
15280 fromElement = original.fromElement;
15281
15282 // Calculate pageX/Y if missing and clientX/Y available
15283 if ( event.pageX == null && original.clientX != null ) {
15284 eventDoc = event.target.ownerDocument || document;
15285 doc = eventDoc.documentElement;
15286 body = eventDoc.body;
15287
15288 event.pageX = original.clientX +
15289 ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
15290 ( doc && doc.clientLeft || body && body.clientLeft || 0 );
15291 event.pageY = original.clientY +
15292 ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
15293 ( doc && doc.clientTop || body && body.clientTop || 0 );
15294 }
15295
15296 // Add relatedTarget, if necessary
15297 if ( !event.relatedTarget && fromElement ) {
15298 event.relatedTarget = fromElement === event.target ?
15299 original.toElement :
15300 fromElement;
15301 }
15302
15303 // Add which for click: 1 === left; 2 === middle; 3 === right
15304 // Note: button is not normalized, so don't use it
15305 if ( !event.which && button !== undefined ) {
15306 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
15307 }
15308
15309 return event;
15310 }
15311 },
15312
15313 special: {
15314 load: {
15315
15316 // Prevent triggered image.load events from bubbling to window.load
15317 noBubble: true
15318 },
15319 focus: {
15320
15321 // Fire native event if possible so blur/focus sequence is correct
15322 trigger: function() {
15323 if ( this !== safeActiveElement() && this.focus ) {
15324 try {
15325 this.focus();
15326 return false;
15327 } catch ( e ) {
15328
15329 // Support: IE<9
15330 // If we error on focus to hidden element (#1486, #12518),
15331 // let .trigger() run the handlers
15332 }
15333 }
15334 },
15335 delegateType: "focusin"
15336 },
15337 blur: {
15338 trigger: function() {
15339 if ( this === safeActiveElement() && this.blur ) {
15340 this.blur();
15341 return false;
15342 }
15343 },
15344 delegateType: "focusout"
15345 },
15346 click: {
15347
15348 // For checkbox, fire native event so checked state will be right
15349 trigger: function() {
15350 if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
15351 this.click();
15352 return false;
15353 }
15354 },
15355
15356 // For cross-browser consistency, don't fire native .click() on links
15357 _default: function( event ) {
15358 return jQuery.nodeName( event.target, "a" );
15359 }
15360 },
15361
15362 beforeunload: {
15363 postDispatch: function( event ) {
15364
15365 // Support: Firefox 20+
15366 // Firefox doesn't alert if the returnValue field is not set.
15367 if ( event.result !== undefined && event.originalEvent ) {
15368 event.originalEvent.returnValue = event.result;
15369 }
15370 }
15371 }
15372 },
15373
15374 // Piggyback on a donor event to simulate a different one
15375 simulate: function( type, elem, event ) {
15376 var e = jQuery.extend(
15377 new jQuery.Event(),
15378 event,
15379 {
15380 type: type,
15381 isSimulated: true
15382
15383 // Previously, `originalEvent: {}` was set here, so stopPropagation call
15384 // would not be triggered on donor event, since in our own
15385 // jQuery.event.stopPropagation function we had a check for existence of
15386 // originalEvent.stopPropagation method, so, consequently it would be a noop.
15387 //
15388 // Guard for simulated events was moved to jQuery.event.stopPropagation function
15389 // since `originalEvent` should point to the original event for the
15390 // constancy with other events and for more focused logic
15391 }
15392 );
15393
15394 jQuery.event.trigger( e, null, elem );
15395
15396 if ( e.isDefaultPrevented() ) {
15397 event.preventDefault();
15398 }
15399 }
15400 };
15401
15402 jQuery.removeEvent = document.removeEventListener ?
15403 function( elem, type, handle ) {
15404
15405 // This "if" is needed for plain objects
15406 if ( elem.removeEventListener ) {
15407 elem.removeEventListener( type, handle );
15408 }
15409 } :
15410 function( elem, type, handle ) {
15411 var name = "on" + type;
15412
15413 if ( elem.detachEvent ) {
15414
15415 // #8545, #7054, preventing memory leaks for custom events in IE6-8
15416 // detachEvent needed property on element, by name of that event,
15417 // to properly expose it to GC
15418 if ( typeof elem[ name ] === "undefined" ) {
15419 elem[ name ] = null;
15420 }
15421
15422 elem.detachEvent( name, handle );
15423 }
15424 };
15425
15426 jQuery.Event = function( src, props ) {
15427
15428 // Allow instantiation without the 'new' keyword
15429 if ( !( this instanceof jQuery.Event ) ) {
15430 return new jQuery.Event( src, props );
15431 }
15432
15433 // Event object
15434 if ( src && src.type ) {
15435 this.originalEvent = src;
15436 this.type = src.type;
15437
15438 // Events bubbling up the document may have been marked as prevented
15439 // by a handler lower down the tree; reflect the correct value.
15440 this.isDefaultPrevented = src.defaultPrevented ||
15441 src.defaultPrevented === undefined &&
15442
15443 // Support: IE < 9, Android < 4.0
15444 src.returnValue === false ?
15445 returnTrue :
15446 returnFalse;
15447
15448 // Event type
15449 } else {
15450 this.type = src;
15451 }
15452
15453 // Put explicitly provided properties onto the event object
15454 if ( props ) {
15455 jQuery.extend( this, props );
15456 }
15457
15458 // Create a timestamp if incoming event doesn't have one
15459 this.timeStamp = src && src.timeStamp || jQuery.now();
15460
15461 // Mark it as fixed
15462 this[ jQuery.expando ] = true;
15463 };
15464
15465 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
15466 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
15467 jQuery.Event.prototype = {
15468 constructor: jQuery.Event,
15469 isDefaultPrevented: returnFalse,
15470 isPropagationStopped: returnFalse,
15471 isImmediatePropagationStopped: returnFalse,
15472
15473 preventDefault: function() {
15474 var e = this.originalEvent;
15475
15476 this.isDefaultPrevented = returnTrue;
15477 if ( !e ) {
15478 return;
15479 }
15480
15481 // If preventDefault exists, run it on the original event
15482 if ( e.preventDefault ) {
15483 e.preventDefault();
15484
15485 // Support: IE
15486 // Otherwise set the returnValue property of the original event to false
15487 } else {
15488 e.returnValue = false;
15489 }
15490 },
15491 stopPropagation: function() {
15492 var e = this.originalEvent;
15493
15494 this.isPropagationStopped = returnTrue;
15495
15496 if ( !e || this.isSimulated ) {
15497 return;
15498 }
15499
15500 // If stopPropagation exists, run it on the original event
15501 if ( e.stopPropagation ) {
15502 e.stopPropagation();
15503 }
15504
15505 // Support: IE
15506 // Set the cancelBubble property of the original event to true
15507 e.cancelBubble = true;
15508 },
15509 stopImmediatePropagation: function() {
15510 var e = this.originalEvent;
15511
15512 this.isImmediatePropagationStopped = returnTrue;
15513
15514 if ( e && e.stopImmediatePropagation ) {
15515 e.stopImmediatePropagation();
15516 }
15517
15518 this.stopPropagation();
15519 }
15520 };
15521
15522 // Create mouseenter/leave events using mouseover/out and event-time checks
15523 // so that event delegation works in jQuery.
15524 // Do the same for pointerenter/pointerleave and pointerover/pointerout
15525 //
15526 // Support: Safari 7 only
15527 // Safari sends mouseenter too often; see:
15528 // https://code.google.com/p/chromium/issues/detail?id=470258
15529 // for the description of the bug (it existed in older Chrome versions as well).
15530 jQuery.each( {
15531 mouseenter: "mouseover",
15532 mouseleave: "mouseout",
15533 pointerenter: "pointerover",
15534 pointerleave: "pointerout"
15535 }, function( orig, fix ) {
15536 jQuery.event.special[ orig ] = {
15537 delegateType: fix,
15538 bindType: fix,
15539
15540 handle: function( event ) {
15541 var ret,
15542 target = this,
15543 related = event.relatedTarget,
15544 handleObj = event.handleObj;
15545
15546 // For mouseenter/leave call the handler if related is outside the target.
15547 // NB: No relatedTarget if the mouse left/entered the browser window
15548 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
15549 event.type = handleObj.origType;
15550 ret = handleObj.handler.apply( this, arguments );
15551 event.type = fix;
15552 }
15553 return ret;
15554 }
15555 };
15556 } );
15557
15558 // IE submit delegation
15559 if ( !support.submit ) {
15560
15561 jQuery.event.special.submit = {
15562 setup: function() {
15563
15564 // Only need this for delegated form submit events
15565 if ( jQuery.nodeName( this, "form" ) ) {
15566 return false;
15567 }
15568
15569 // Lazy-add a submit handler when a descendant form may potentially be submitted
15570 jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
15571
15572 // Node name check avoids a VML-related crash in IE (#9807)
15573 var elem = e.target,
15574 form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
15575
15576 // Support: IE <=8
15577 // We use jQuery.prop instead of elem.form
15578 // to allow fixing the IE8 delegated submit issue (gh-2332)
15579 // by 3rd party polyfills/workarounds.
15580 jQuery.prop( elem, "form" ) :
15581 undefined;
15582
15583 if ( form && !jQuery._data( form, "submit" ) ) {
15584 jQuery.event.add( form, "submit._submit", function( event ) {
15585 event._submitBubble = true;
15586 } );
15587 jQuery._data( form, "submit", true );
15588 }
15589 } );
15590
15591 // return undefined since we don't need an event listener
15592 },
15593
15594 postDispatch: function( event ) {
15595
15596 // If form was submitted by the user, bubble the event up the tree
15597 if ( event._submitBubble ) {
15598 delete event._submitBubble;
15599 if ( this.parentNode && !event.isTrigger ) {
15600 jQuery.event.simulate( "submit", this.parentNode, event );
15601 }
15602 }
15603 },
15604
15605 teardown: function() {
15606
15607 // Only need this for delegated form submit events
15608 if ( jQuery.nodeName( this, "form" ) ) {
15609 return false;
15610 }
15611
15612 // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
15613 jQuery.event.remove( this, "._submit" );
15614 }
15615 };
15616 }
15617
15618 // IE change delegation and checkbox/radio fix
15619 if ( !support.change ) {
15620
15621 jQuery.event.special.change = {
15622
15623 setup: function() {
15624
15625 if ( rformElems.test( this.nodeName ) ) {
15626
15627 // IE doesn't fire change on a check/radio until blur; trigger it on click
15628 // after a propertychange. Eat the blur-change in special.change.handle.
15629 // This still fires onchange a second time for check/radio after blur.
15630 if ( this.type === "checkbox" || this.type === "radio" ) {
15631 jQuery.event.add( this, "propertychange._change", function( event ) {
15632 if ( event.originalEvent.propertyName === "checked" ) {
15633 this._justChanged = true;
15634 }
15635 } );
15636 jQuery.event.add( this, "click._change", function( event ) {
15637 if ( this._justChanged && !event.isTrigger ) {
15638 this._justChanged = false;
15639 }
15640
15641 // Allow triggered, simulated change events (#11500)
15642 jQuery.event.simulate( "change", this, event );
15643 } );
15644 }
15645 return false;
15646 }
15647
15648 // Delegated event; lazy-add a change handler on descendant inputs
15649 jQuery.event.add( this, "beforeactivate._change", function( e ) {
15650 var elem = e.target;
15651
15652 if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
15653 jQuery.event.add( elem, "change._change", function( event ) {
15654 if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
15655 jQuery.event.simulate( "change", this.parentNode, event );
15656 }
15657 } );
15658 jQuery._data( elem, "change", true );
15659 }
15660 } );
15661 },
15662
15663 handle: function( event ) {
15664 var elem = event.target;
15665
15666 // Swallow native change events from checkbox/radio, we already triggered them above
15667 if ( this !== elem || event.isSimulated || event.isTrigger ||
15668 ( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
15669
15670 return event.handleObj.handler.apply( this, arguments );
15671 }
15672 },
15673
15674 teardown: function() {
15675 jQuery.event.remove( this, "._change" );
15676
15677 return !rformElems.test( this.nodeName );
15678 }
15679 };
15680 }
15681
15682 // Support: Firefox
15683 // Firefox doesn't have focus(in | out) events
15684 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
15685 //
15686 // Support: Chrome, Safari
15687 // focus(in | out) events fire after focus & blur events,
15688 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
15689 // Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
15690 if ( !support.focusin ) {
15691 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
15692
15693 // Attach a single capturing handler on the document while someone wants focusin/focusout
15694 var handler = function( event ) {
15695 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
15696 };
15697
15698 jQuery.event.special[ fix ] = {
15699 setup: function() {
15700 var doc = this.ownerDocument || this,
15701 attaches = jQuery._data( doc, fix );
15702
15703 if ( !attaches ) {
15704 doc.addEventListener( orig, handler, true );
15705 }
15706 jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
15707 },
15708 teardown: function() {
15709 var doc = this.ownerDocument || this,
15710 attaches = jQuery._data( doc, fix ) - 1;
15711
15712 if ( !attaches ) {
15713 doc.removeEventListener( orig, handler, true );
15714 jQuery._removeData( doc, fix );
15715 } else {
15716 jQuery._data( doc, fix, attaches );
15717 }
15718 }
15719 };
15720 } );
15721 }
15722
15723 jQuery.fn.extend( {
15724
15725 on: function( types, selector, data, fn ) {
15726 return on( this, types, selector, data, fn );
15727 },
15728 one: function( types, selector, data, fn ) {
15729 return on( this, types, selector, data, fn, 1 );
15730 },
15731 off: function( types, selector, fn ) {
15732 var handleObj, type;
15733 if ( types && types.preventDefault && types.handleObj ) {
15734
15735 // ( event ) dispatched jQuery.Event
15736 handleObj = types.handleObj;
15737 jQuery( types.delegateTarget ).off(
15738 handleObj.namespace ?
15739 handleObj.origType + "." + handleObj.namespace :
15740 handleObj.origType,
15741 handleObj.selector,
15742 handleObj.handler
15743 );
15744 return this;
15745 }
15746 if ( typeof types === "object" ) {
15747
15748 // ( types-object [, selector] )
15749 for ( type in types ) {
15750 this.off( type, selector, types[ type ] );
15751 }
15752 return this;
15753 }
15754 if ( selector === false || typeof selector === "function" ) {
15755
15756 // ( types [, fn] )
15757 fn = selector;
15758 selector = undefined;
15759 }
15760 if ( fn === false ) {
15761 fn = returnFalse;
15762 }
15763 return this.each( function() {
15764 jQuery.event.remove( this, types, fn, selector );
15765 } );
15766 },
15767
15768 trigger: function( type, data ) {
15769 return this.each( function() {
15770 jQuery.event.trigger( type, data, this );
15771 } );
15772 },
15773 triggerHandler: function( type, data ) {
15774 var elem = this[ 0 ];
15775 if ( elem ) {
15776 return jQuery.event.trigger( type, data, elem, true );
15777 }
15778 }
15779 } );
15780
15781
15782 var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
15783 rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
15784 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
15785
15786 // Support: IE 10-11, Edge 10240+
15787 // In IE/Edge using regex groups here causes severe slowdowns.
15788 // See https://connect.microsoft.com/IE/feedback/details/1736512/
15789 rnoInnerhtml = /<script|<style|<link/i,
15790
15791 // checked="checked" or checked
15792 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
15793 rscriptTypeMasked = /^true\/(.*)/,
15794 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
15795 safeFragment = createSafeFragment( document ),
15796 fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
15797
15798 // Support: IE<8
15799 // Manipulating tables requires a tbody
15800 function manipulationTarget( elem, content ) {
15801 return jQuery.nodeName( elem, "table" ) &&
15802 jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
15803
15804 elem.getElementsByTagName( "tbody" )[ 0 ] ||
15805 elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
15806 elem;
15807 }
15808
15809 // Replace/restore the type attribute of script elements for safe DOM manipulation
15810 function disableScript( elem ) {
15811 elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
15812 return elem;
15813 }
15814 function restoreScript( elem ) {
15815 var match = rscriptTypeMasked.exec( elem.type );
15816 if ( match ) {
15817 elem.type = match[ 1 ];
15818 } else {
15819 elem.removeAttribute( "type" );
15820 }
15821 return elem;
15822 }
15823
15824 function cloneCopyEvent( src, dest ) {
15825 if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
15826 return;
15827 }
15828
15829 var type, i, l,
15830 oldData = jQuery._data( src ),
15831 curData = jQuery._data( dest, oldData ),
15832 events = oldData.events;
15833
15834 if ( events ) {
15835 delete curData.handle;
15836 curData.events = {};
15837
15838 for ( type in events ) {
15839 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
15840 jQuery.event.add( dest, type, events[ type ][ i ] );
15841 }
15842 }
15843 }
15844
15845 // make the cloned public data object a copy from the original
15846 if ( curData.data ) {
15847 curData.data = jQuery.extend( {}, curData.data );
15848 }
15849 }
15850
15851 function fixCloneNodeIssues( src, dest ) {
15852 var nodeName, e, data;
15853
15854 // We do not need to do anything for non-Elements
15855 if ( dest.nodeType !== 1 ) {
15856 return;
15857 }
15858
15859 nodeName = dest.nodeName.toLowerCase();
15860
15861 // IE6-8 copies events bound via attachEvent when using cloneNode.
15862 if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
15863 data = jQuery._data( dest );
15864
15865 for ( e in data.events ) {
15866 jQuery.removeEvent( dest, e, data.handle );
15867 }
15868
15869 // Event data gets referenced instead of copied if the expando gets copied too
15870 dest.removeAttribute( jQuery.expando );
15871 }
15872
15873 // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
15874 if ( nodeName === "script" && dest.text !== src.text ) {
15875 disableScript( dest ).text = src.text;
15876 restoreScript( dest );
15877
15878 // IE6-10 improperly clones children of object elements using classid.
15879 // IE10 throws NoModificationAllowedError if parent is null, #12132.
15880 } else if ( nodeName === "object" ) {
15881 if ( dest.parentNode ) {
15882 dest.outerHTML = src.outerHTML;
15883 }
15884
15885 // This path appears unavoidable for IE9. When cloning an object
15886 // element in IE9, the outerHTML strategy above is not sufficient.
15887 // If the src has innerHTML and the destination does not,
15888 // copy the src.innerHTML into the dest.innerHTML. #10324
15889 if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
15890 dest.innerHTML = src.innerHTML;
15891 }
15892
15893 } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
15894
15895 // IE6-8 fails to persist the checked state of a cloned checkbox
15896 // or radio button. Worse, IE6-7 fail to give the cloned element
15897 // a checked appearance if the defaultChecked value isn't also set
15898
15899 dest.defaultChecked = dest.checked = src.checked;
15900
15901 // IE6-7 get confused and end up setting the value of a cloned
15902 // checkbox/radio button to an empty string instead of "on"
15903 if ( dest.value !== src.value ) {
15904 dest.value = src.value;
15905 }
15906
15907 // IE6-8 fails to return the selected option to the default selected
15908 // state when cloning options
15909 } else if ( nodeName === "option" ) {
15910 dest.defaultSelected = dest.selected = src.defaultSelected;
15911
15912 // IE6-8 fails to set the defaultValue to the correct value when
15913 // cloning other types of input fields
15914 } else if ( nodeName === "input" || nodeName === "textarea" ) {
15915 dest.defaultValue = src.defaultValue;
15916 }
15917 }
15918
15919 function domManip( collection, args, callback, ignored ) {
15920
15921 // Flatten any nested arrays
15922 args = concat.apply( [], args );
15923
15924 var first, node, hasScripts,
15925 scripts, doc, fragment,
15926 i = 0,
15927 l = collection.length,
15928 iNoClone = l - 1,
15929 value = args[ 0 ],
15930 isFunction = jQuery.isFunction( value );
15931
15932 // We can't cloneNode fragments that contain checked, in WebKit
15933 if ( isFunction ||
15934 ( l > 1 && typeof value === "string" &&
15935 !support.checkClone && rchecked.test( value ) ) ) {
15936 return collection.each( function( index ) {
15937 var self = collection.eq( index );
15938 if ( isFunction ) {
15939 args[ 0 ] = value.call( this, index, self.html() );
15940 }
15941 domManip( self, args, callback, ignored );
15942 } );
15943 }
15944
15945 if ( l ) {
15946 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
15947 first = fragment.firstChild;
15948
15949 if ( fragment.childNodes.length === 1 ) {
15950 fragment = first;
15951 }
15952
15953 // Require either new content or an interest in ignored elements to invoke the callback
15954 if ( first || ignored ) {
15955 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
15956 hasScripts = scripts.length;
15957
15958 // Use the original fragment for the last item
15959 // instead of the first because it can end up
15960 // being emptied incorrectly in certain situations (#8070).
15961 for ( ; i < l; i++ ) {
15962 node = fragment;
15963
15964 if ( i !== iNoClone ) {
15965 node = jQuery.clone( node, true, true );
15966
15967 // Keep references to cloned scripts for later restoration
15968 if ( hasScripts ) {
15969
15970 // Support: Android<4.1, PhantomJS<2
15971 // push.apply(_, arraylike) throws on ancient WebKit
15972 jQuery.merge( scripts, getAll( node, "script" ) );
15973 }
15974 }
15975
15976 callback.call( collection[ i ], node, i );
15977 }
15978
15979 if ( hasScripts ) {
15980 doc = scripts[ scripts.length - 1 ].ownerDocument;
15981
15982 // Reenable scripts
15983 jQuery.map( scripts, restoreScript );
15984
15985 // Evaluate executable scripts on first document insertion
15986 for ( i = 0; i < hasScripts; i++ ) {
15987 node = scripts[ i ];
15988 if ( rscriptType.test( node.type || "" ) &&
15989 !jQuery._data( node, "globalEval" ) &&
15990 jQuery.contains( doc, node ) ) {
15991
15992 if ( node.src ) {
15993
15994 // Optional AJAX dependency, but won't run scripts if not present
15995 if ( jQuery._evalUrl ) {
15996 jQuery._evalUrl( node.src );
15997 }
15998 } else {
15999 jQuery.globalEval(
16000 ( node.text || node.textContent || node.innerHTML || "" )
16001 .replace( rcleanScript, "" )
16002 );
16003 }
16004 }
16005 }
16006 }
16007
16008 // Fix #11809: Avoid leaking memory
16009 fragment = first = null;
16010 }
16011 }
16012
16013 return collection;
16014 }
16015
16016 function remove( elem, selector, keepData ) {
16017 var node,
16018 elems = selector ? jQuery.filter( selector, elem ) : elem,
16019 i = 0;
16020
16021 for ( ; ( node = elems[ i ] ) != null; i++ ) {
16022
16023 if ( !keepData && node.nodeType === 1 ) {
16024 jQuery.cleanData( getAll( node ) );
16025 }
16026
16027 if ( node.parentNode ) {
16028 if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
16029 setGlobalEval( getAll( node, "script" ) );
16030 }
16031 node.parentNode.removeChild( node );
16032 }
16033 }
16034
16035 return elem;
16036 }
16037
16038 jQuery.extend( {
16039 htmlPrefilter: function( html ) {
16040 return html.replace( rxhtmlTag, "<$1></$2>" );
16041 },
16042
16043 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
16044 var destElements, node, clone, i, srcElements,
16045 inPage = jQuery.contains( elem.ownerDocument, elem );
16046
16047 if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
16048 !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
16049
16050 clone = elem.cloneNode( true );
16051
16052 // IE<=8 does not properly clone detached, unknown element nodes
16053 } else {
16054 fragmentDiv.innerHTML = elem.outerHTML;
16055 fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
16056 }
16057
16058 if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
16059 ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
16060
16061 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
16062 destElements = getAll( clone );
16063 srcElements = getAll( elem );
16064
16065 // Fix all IE cloning issues
16066 for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
16067
16068 // Ensure that the destination node is not null; Fixes #9587
16069 if ( destElements[ i ] ) {
16070 fixCloneNodeIssues( node, destElements[ i ] );
16071 }
16072 }
16073 }
16074
16075 // Copy the events from the original to the clone
16076 if ( dataAndEvents ) {
16077 if ( deepDataAndEvents ) {
16078 srcElements = srcElements || getAll( elem );
16079 destElements = destElements || getAll( clone );
16080
16081 for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
16082 cloneCopyEvent( node, destElements[ i ] );
16083 }
16084 } else {
16085 cloneCopyEvent( elem, clone );
16086 }
16087 }
16088
16089 // Preserve script evaluation history
16090 destElements = getAll( clone, "script" );
16091 if ( destElements.length > 0 ) {
16092 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
16093 }
16094
16095 destElements = srcElements = node = null;
16096
16097 // Return the cloned set
16098 return clone;
16099 },
16100
16101 cleanData: function( elems, /* internal */ forceAcceptData ) {
16102 var elem, type, id, data,
16103 i = 0,
16104 internalKey = jQuery.expando,
16105 cache = jQuery.cache,
16106 attributes = support.attributes,
16107 special = jQuery.event.special;
16108
16109 for ( ; ( elem = elems[ i ] ) != null; i++ ) {
16110 if ( forceAcceptData || acceptData( elem ) ) {
16111
16112 id = elem[ internalKey ];
16113 data = id && cache[ id ];
16114
16115 if ( data ) {
16116 if ( data.events ) {
16117 for ( type in data.events ) {
16118 if ( special[ type ] ) {
16119 jQuery.event.remove( elem, type );
16120
16121 // This is a shortcut to avoid jQuery.event.remove's overhead
16122 } else {
16123 jQuery.removeEvent( elem, type, data.handle );
16124 }
16125 }
16126 }
16127
16128 // Remove cache only if it was not already removed by jQuery.event.remove
16129 if ( cache[ id ] ) {
16130
16131 delete cache[ id ];
16132
16133 // Support: IE<9
16134 // IE does not allow us to delete expando properties from nodes
16135 // IE creates expando attributes along with the property
16136 // IE does not have a removeAttribute function on Document nodes
16137 if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
16138 elem.removeAttribute( internalKey );
16139
16140 // Webkit & Blink performance suffers when deleting properties
16141 // from DOM nodes, so set to undefined instead
16142 // https://code.google.com/p/chromium/issues/detail?id=378607
16143 } else {
16144 elem[ internalKey ] = undefined;
16145 }
16146
16147 deletedIds.push( id );
16148 }
16149 }
16150 }
16151 }
16152 }
16153 } );
16154
16155 jQuery.fn.extend( {
16156
16157 // Keep domManip exposed until 3.0 (gh-2225)
16158 domManip: domManip,
16159
16160 detach: function( selector ) {
16161 return remove( this, selector, true );
16162 },
16163
16164 remove: function( selector ) {
16165 return remove( this, selector );
16166 },
16167
16168 text: function( value ) {
16169 return access( this, function( value ) {
16170 return value === undefined ?
16171 jQuery.text( this ) :
16172 this.empty().append(
16173 ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
16174 );
16175 }, null, value, arguments.length );
16176 },
16177
16178 append: function() {
16179 return domManip( this, arguments, function( elem ) {
16180 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
16181 var target = manipulationTarget( this, elem );
16182 target.appendChild( elem );
16183 }
16184 } );
16185 },
16186
16187 prepend: function() {
16188 return domManip( this, arguments, function( elem ) {
16189 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
16190 var target = manipulationTarget( this, elem );
16191 target.insertBefore( elem, target.firstChild );
16192 }
16193 } );
16194 },
16195
16196 before: function() {
16197 return domManip( this, arguments, function( elem ) {
16198 if ( this.parentNode ) {
16199 this.parentNode.insertBefore( elem, this );
16200 }
16201 } );
16202 },
16203
16204 after: function() {
16205 return domManip( this, arguments, function( elem ) {
16206 if ( this.parentNode ) {
16207 this.parentNode.insertBefore( elem, this.nextSibling );
16208 }
16209 } );
16210 },
16211
16212 empty: function() {
16213 var elem,
16214 i = 0;
16215
16216 for ( ; ( elem = this[ i ] ) != null; i++ ) {
16217
16218 // Remove element nodes and prevent memory leaks
16219 if ( elem.nodeType === 1 ) {
16220 jQuery.cleanData( getAll( elem, false ) );
16221 }
16222
16223 // Remove any remaining nodes
16224 while ( elem.firstChild ) {
16225 elem.removeChild( elem.firstChild );
16226 }
16227
16228 // If this is a select, ensure that it displays empty (#12336)
16229 // Support: IE<9
16230 if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
16231 elem.options.length = 0;
16232 }
16233 }
16234
16235 return this;
16236 },
16237
16238 clone: function( dataAndEvents, deepDataAndEvents ) {
16239 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
16240 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
16241
16242 return this.map( function() {
16243 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
16244 } );
16245 },
16246
16247 html: function( value ) {
16248 return access( this, function( value ) {
16249 var elem = this[ 0 ] || {},
16250 i = 0,
16251 l = this.length;
16252
16253 if ( value === undefined ) {
16254 return elem.nodeType === 1 ?
16255 elem.innerHTML.replace( rinlinejQuery, "" ) :
16256 undefined;
16257 }
16258
16259 // See if we can take a shortcut and just use innerHTML
16260 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
16261 ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
16262 ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
16263 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
16264
16265 value = jQuery.htmlPrefilter( value );
16266
16267 try {
16268 for ( ; i < l; i++ ) {
16269
16270 // Remove element nodes and prevent memory leaks
16271 elem = this[ i ] || {};
16272 if ( elem.nodeType === 1 ) {
16273 jQuery.cleanData( getAll( elem, false ) );
16274 elem.innerHTML = value;
16275 }
16276 }
16277
16278 elem = 0;
16279
16280 // If using innerHTML throws an exception, use the fallback method
16281 } catch ( e ) {}
16282 }
16283
16284 if ( elem ) {
16285 this.empty().append( value );
16286 }
16287 }, null, value, arguments.length );
16288 },
16289
16290 replaceWith: function() {
16291 var ignored = [];
16292
16293 // Make the changes, replacing each non-ignored context element with the new content
16294 return domManip( this, arguments, function( elem ) {
16295 var parent = this.parentNode;
16296
16297 if ( jQuery.inArray( this, ignored ) < 0 ) {
16298 jQuery.cleanData( getAll( this ) );
16299 if ( parent ) {
16300 parent.replaceChild( elem, this );
16301 }
16302 }
16303
16304 // Force callback invocation
16305 }, ignored );
16306 }
16307 } );
16308
16309 jQuery.each( {
16310 appendTo: "append",
16311 prependTo: "prepend",
16312 insertBefore: "before",
16313 insertAfter: "after",
16314 replaceAll: "replaceWith"
16315 }, function( name, original ) {
16316 jQuery.fn[ name ] = function( selector ) {
16317 var elems,
16318 i = 0,
16319 ret = [],
16320 insert = jQuery( selector ),
16321 last = insert.length - 1;
16322
16323 for ( ; i <= last; i++ ) {
16324 elems = i === last ? this : this.clone( true );
16325 jQuery( insert[ i ] )[ original ]( elems );
16326
16327 // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
16328 push.apply( ret, elems.get() );
16329 }
16330
16331 return this.pushStack( ret );
16332 };
16333 } );
16334
16335
16336 var iframe,
16337 elemdisplay = {
16338
16339 // Support: Firefox
16340 // We have to pre-define these values for FF (#10227)
16341 HTML: "block",
16342 BODY: "block"
16343 };
16344
16345 /**
16346 * Retrieve the actual display of a element
16347 * @param {String} name nodeName of the element
16348 * @param {Object} doc Document object
16349 */
16350
16351 // Called only from within defaultDisplay
16352 function actualDisplay( name, doc ) {
16353 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
16354
16355 display = jQuery.css( elem[ 0 ], "display" );
16356
16357 // We don't have any data stored on the element,
16358 // so use "detach" method as fast way to get rid of the element
16359 elem.detach();
16360
16361 return display;
16362 }
16363
16364 /**
16365 * Try to determine the default display value of an element
16366 * @param {String} nodeName
16367 */
16368 function defaultDisplay( nodeName ) {
16369 var doc = document,
16370 display = elemdisplay[ nodeName ];
16371
16372 if ( !display ) {
16373 display = actualDisplay( nodeName, doc );
16374
16375 // If the simple way fails, read from inside an iframe
16376 if ( display === "none" || !display ) {
16377
16378 // Use the already-created iframe if possible
16379 iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
16380 .appendTo( doc.documentElement );
16381
16382 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
16383 doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
16384
16385 // Support: IE
16386 doc.write();
16387 doc.close();
16388
16389 display = actualDisplay( nodeName, doc );
16390 iframe.detach();
16391 }
16392
16393 // Store the correct default display
16394 elemdisplay[ nodeName ] = display;
16395 }
16396
16397 return display;
16398 }
16399 var rmargin = ( /^margin/ );
16400
16401 var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
16402
16403 var swap = function( elem, options, callback, args ) {
16404 var ret, name,
16405 old = {};
16406
16407 // Remember the old values, and insert the new ones
16408 for ( name in options ) {
16409 old[ name ] = elem.style[ name ];
16410 elem.style[ name ] = options[ name ];
16411 }
16412
16413 ret = callback.apply( elem, args || [] );
16414
16415 // Revert the old values
16416 for ( name in options ) {
16417 elem.style[ name ] = old[ name ];
16418 }
16419
16420 return ret;
16421 };
16422
16423
16424 var documentElement = document.documentElement;
16425
16426
16427
16428 ( function() {
16429 var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
16430 reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
16431 container = document.createElement( "div" ),
16432 div = document.createElement( "div" );
16433
16434 // Finish early in limited (non-browser) environments
16435 if ( !div.style ) {
16436 return;
16437 }
16438
16439 div.style.cssText = "float:left;opacity:.5";
16440
16441 // Support: IE<9
16442 // Make sure that element opacity exists (as opposed to filter)
16443 support.opacity = div.style.opacity === "0.5";
16444
16445 // Verify style float existence
16446 // (IE uses styleFloat instead of cssFloat)
16447 support.cssFloat = !!div.style.cssFloat;
16448
16449 div.style.backgroundClip = "content-box";
16450 div.cloneNode( true ).style.backgroundClip = "";
16451 support.clearCloneStyle = div.style.backgroundClip === "content-box";
16452
16453 container = document.createElement( "div" );
16454 container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
16455 "padding:0;margin-top:1px;position:absolute";
16456 div.innerHTML = "";
16457 container.appendChild( div );
16458
16459 // Support: Firefox<29, Android 2.3
16460 // Vendor-prefix box-sizing
16461 support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
16462 div.style.WebkitBoxSizing === "";
16463
16464 jQuery.extend( support, {
16465 reliableHiddenOffsets: function() {
16466 if ( pixelPositionVal == null ) {
16467 computeStyleTests();
16468 }
16469 return reliableHiddenOffsetsVal;
16470 },
16471
16472 boxSizingReliable: function() {
16473
16474 // We're checking for pixelPositionVal here instead of boxSizingReliableVal
16475 // since that compresses better and they're computed together anyway.
16476 if ( pixelPositionVal == null ) {
16477 computeStyleTests();
16478 }
16479 return boxSizingReliableVal;
16480 },
16481
16482 pixelMarginRight: function() {
16483
16484 // Support: Android 4.0-4.3
16485 if ( pixelPositionVal == null ) {
16486 computeStyleTests();
16487 }
16488 return pixelMarginRightVal;
16489 },
16490
16491 pixelPosition: function() {
16492 if ( pixelPositionVal == null ) {
16493 computeStyleTests();
16494 }
16495 return pixelPositionVal;
16496 },
16497
16498 reliableMarginRight: function() {
16499
16500 // Support: Android 2.3
16501 if ( pixelPositionVal == null ) {
16502 computeStyleTests();
16503 }
16504 return reliableMarginRightVal;
16505 },
16506
16507 reliableMarginLeft: function() {
16508
16509 // Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
16510 if ( pixelPositionVal == null ) {
16511 computeStyleTests();
16512 }
16513 return reliableMarginLeftVal;
16514 }
16515 } );
16516
16517 function computeStyleTests() {
16518 var contents, divStyle,
16519 documentElement = document.documentElement;
16520
16521 // Setup
16522 documentElement.appendChild( container );
16523
16524 div.style.cssText =
16525
16526 // Support: Android 2.3
16527 // Vendor-prefix box-sizing
16528 "-webkit-box-sizing:border-box;box-sizing:border-box;" +
16529 "position:relative;display:block;" +
16530 "margin:auto;border:1px;padding:1px;" +
16531 "top:1%;width:50%";
16532
16533 // Support: IE<9
16534 // Assume reasonable values in the absence of getComputedStyle
16535 pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
16536 pixelMarginRightVal = reliableMarginRightVal = true;
16537
16538 // Check for getComputedStyle so that this code is not run in IE<9.
16539 if ( window.getComputedStyle ) {
16540 divStyle = window.getComputedStyle( div );
16541 pixelPositionVal = ( divStyle || {} ).top !== "1%";
16542 reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
16543 boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
16544
16545 // Support: Android 4.0 - 4.3 only
16546 // Some styles come back with percentage values, even though they shouldn't
16547 div.style.marginRight = "50%";
16548 pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
16549
16550 // Support: Android 2.3 only
16551 // Div with explicit width and no margin-right incorrectly
16552 // gets computed margin-right based on width of container (#3333)
16553 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
16554 contents = div.appendChild( document.createElement( "div" ) );
16555
16556 // Reset CSS: box-sizing; display; margin; border; padding
16557 contents.style.cssText = div.style.cssText =
16558
16559 // Support: Android 2.3
16560 // Vendor-prefix box-sizing
16561 "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
16562 "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
16563 contents.style.marginRight = contents.style.width = "0";
16564 div.style.width = "1px";
16565
16566 reliableMarginRightVal =
16567 !parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
16568
16569 div.removeChild( contents );
16570 }
16571
16572 // Support: IE6-8
16573 // First check that getClientRects works as expected
16574 // Check if table cells still have offsetWidth/Height when they are set
16575 // to display:none and there are still other visible table cells in a
16576 // table row; if so, offsetWidth/Height are not reliable for use when
16577 // determining if an element has been hidden directly using
16578 // display:none (it is still safe to use offsets if a parent element is
16579 // hidden; don safety goggles and see bug #4512 for more information).
16580 div.style.display = "none";
16581 reliableHiddenOffsetsVal = div.getClientRects().length === 0;
16582 if ( reliableHiddenOffsetsVal ) {
16583 div.style.display = "";
16584 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
16585 div.childNodes[ 0 ].style.borderCollapse = "separate";
16586 contents = div.getElementsByTagName( "td" );
16587 contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
16588 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
16589 if ( reliableHiddenOffsetsVal ) {
16590 contents[ 0 ].style.display = "";
16591 contents[ 1 ].style.display = "none";
16592 reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
16593 }
16594 }
16595
16596 // Teardown
16597 documentElement.removeChild( container );
16598 }
16599
16600 } )();
16601
16602
16603 var getStyles, curCSS,
16604 rposition = /^(top|right|bottom|left)$/;
16605
16606 if ( window.getComputedStyle ) {
16607 getStyles = function( elem ) {
16608
16609 // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
16610 // IE throws on elements created in popups
16611 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
16612 var view = elem.ownerDocument.defaultView;
16613
16614 if ( !view || !view.opener ) {
16615 view = window;
16616 }
16617
16618 return view.getComputedStyle( elem );
16619 };
16620
16621 curCSS = function( elem, name, computed ) {
16622 var width, minWidth, maxWidth, ret,
16623 style = elem.style;
16624
16625 computed = computed || getStyles( elem );
16626
16627 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
16628 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
16629
16630 // Support: Opera 12.1x only
16631 // Fall back to style even without computed
16632 // computed is undefined for elems on document fragments
16633 if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
16634 ret = jQuery.style( elem, name );
16635 }
16636
16637 if ( computed ) {
16638
16639 // A tribute to the "awesome hack by Dean Edwards"
16640 // Chrome < 17 and Safari 5.0 uses "computed value"
16641 // instead of "used value" for margin-right
16642 // Safari 5.1.7 (at least) returns percentage for a larger set of values,
16643 // but width seems to be reliably pixels
16644 // this is against the CSSOM draft spec:
16645 // http://dev.w3.org/csswg/cssom/#resolved-values
16646 if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
16647
16648 // Remember the original values
16649 width = style.width;
16650 minWidth = style.minWidth;
16651 maxWidth = style.maxWidth;
16652
16653 // Put in the new values to get a computed value out
16654 style.minWidth = style.maxWidth = style.width = ret;
16655 ret = computed.width;
16656
16657 // Revert the changed values
16658 style.width = width;
16659 style.minWidth = minWidth;
16660 style.maxWidth = maxWidth;
16661 }
16662 }
16663
16664 // Support: IE
16665 // IE returns zIndex value as an integer.
16666 return ret === undefined ?
16667 ret :
16668 ret + "";
16669 };
16670 } else if ( documentElement.currentStyle ) {
16671 getStyles = function( elem ) {
16672 return elem.currentStyle;
16673 };
16674
16675 curCSS = function( elem, name, computed ) {
16676 var left, rs, rsLeft, ret,
16677 style = elem.style;
16678
16679 computed = computed || getStyles( elem );
16680 ret = computed ? computed[ name ] : undefined;
16681
16682 // Avoid setting ret to empty string here
16683 // so we don't default to auto
16684 if ( ret == null && style && style[ name ] ) {
16685 ret = style[ name ];
16686 }
16687
16688 // From the awesome hack by Dean Edwards
16689 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
16690
16691 // If we're not dealing with a regular pixel number
16692 // but a number that has a weird ending, we need to convert it to pixels
16693 // but not position css attributes, as those are
16694 // proportional to the parent element instead
16695 // and we can't measure the parent instead because it
16696 // might trigger a "stacking dolls" problem
16697 if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
16698
16699 // Remember the original values
16700 left = style.left;
16701 rs = elem.runtimeStyle;
16702 rsLeft = rs && rs.left;
16703
16704 // Put in the new values to get a computed value out
16705 if ( rsLeft ) {
16706 rs.left = elem.currentStyle.left;
16707 }
16708 style.left = name === "fontSize" ? "1em" : ret;
16709 ret = style.pixelLeft + "px";
16710
16711 // Revert the changed values
16712 style.left = left;
16713 if ( rsLeft ) {
16714 rs.left = rsLeft;
16715 }
16716 }
16717
16718 // Support: IE
16719 // IE returns zIndex value as an integer.
16720 return ret === undefined ?
16721 ret :
16722 ret + "" || "auto";
16723 };
16724 }
16725
16726
16727
16728
16729 function addGetHookIf( conditionFn, hookFn ) {
16730
16731 // Define the hook, we'll check on the first run if it's really needed.
16732 return {
16733 get: function() {
16734 if ( conditionFn() ) {
16735
16736 // Hook not needed (or it's not possible to use it due
16737 // to missing dependency), remove it.
16738 delete this.get;
16739 return;
16740 }
16741
16742 // Hook needed; redefine it so that the support test is not executed again.
16743 return ( this.get = hookFn ).apply( this, arguments );
16744 }
16745 };
16746 }
16747
16748
16749 var
16750
16751 ralpha = /alpha\([^)]*\)/i,
16752 ropacity = /opacity\s*=\s*([^)]*)/i,
16753
16754 // swappable if display is none or starts with table except
16755 // "table", "table-cell", or "table-caption"
16756 // see here for display values:
16757 // https://developer.mozilla.org/en-US/docs/CSS/display
16758 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
16759 rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
16760
16761 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
16762 cssNormalTransform = {
16763 letterSpacing: "0",
16764 fontWeight: "400"
16765 },
16766
16767 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
16768 emptyStyle = document.createElement( "div" ).style;
16769
16770
16771 // return a css property mapped to a potentially vendor prefixed property
16772 function vendorPropName( name ) {
16773
16774 // shortcut for names that are not vendor prefixed
16775 if ( name in emptyStyle ) {
16776 return name;
16777 }
16778
16779 // check for vendor prefixed names
16780 var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
16781 i = cssPrefixes.length;
16782
16783 while ( i-- ) {
16784 name = cssPrefixes[ i ] + capName;
16785 if ( name in emptyStyle ) {
16786 return name;
16787 }
16788 }
16789 }
16790
16791 function showHide( elements, show ) {
16792 var display, elem, hidden,
16793 values = [],
16794 index = 0,
16795 length = elements.length;
16796
16797 for ( ; index < length; index++ ) {
16798 elem = elements[ index ];
16799 if ( !elem.style ) {
16800 continue;
16801 }
16802
16803 values[ index ] = jQuery._data( elem, "olddisplay" );
16804 display = elem.style.display;
16805 if ( show ) {
16806
16807 // Reset the inline display of this element to learn if it is
16808 // being hidden by cascaded rules or not
16809 if ( !values[ index ] && display === "none" ) {
16810 elem.style.display = "";
16811 }
16812
16813 // Set elements which have been overridden with display: none
16814 // in a stylesheet to whatever the default browser style is
16815 // for such an element
16816 if ( elem.style.display === "" && isHidden( elem ) ) {
16817 values[ index ] =
16818 jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
16819 }
16820 } else {
16821 hidden = isHidden( elem );
16822
16823 if ( display && display !== "none" || !hidden ) {
16824 jQuery._data(
16825 elem,
16826 "olddisplay",
16827 hidden ? display : jQuery.css( elem, "display" )
16828 );
16829 }
16830 }
16831 }
16832
16833 // Set the display of most of the elements in a second loop
16834 // to avoid the constant reflow
16835 for ( index = 0; index < length; index++ ) {
16836 elem = elements[ index ];
16837 if ( !elem.style ) {
16838 continue;
16839 }
16840 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
16841 elem.style.display = show ? values[ index ] || "" : "none";
16842 }
16843 }
16844
16845 return elements;
16846 }
16847
16848 function setPositiveNumber( elem, value, subtract ) {
16849 var matches = rnumsplit.exec( value );
16850 return matches ?
16851
16852 // Guard against undefined "subtract", e.g., when used as in cssHooks
16853 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
16854 value;
16855 }
16856
16857 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
16858 var i = extra === ( isBorderBox ? "border" : "content" ) ?
16859
16860 // If we already have the right measurement, avoid augmentation
16861 4 :
16862
16863 // Otherwise initialize for horizontal or vertical properties
16864 name === "width" ? 1 : 0,
16865
16866 val = 0;
16867
16868 for ( ; i < 4; i += 2 ) {
16869
16870 // both box models exclude margin, so add it if we want it
16871 if ( extra === "margin" ) {
16872 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
16873 }
16874
16875 if ( isBorderBox ) {
16876
16877 // border-box includes padding, so remove it if we want content
16878 if ( extra === "content" ) {
16879 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
16880 }
16881
16882 // at this point, extra isn't border nor margin, so remove border
16883 if ( extra !== "margin" ) {
16884 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
16885 }
16886 } else {
16887
16888 // at this point, extra isn't content, so add padding
16889 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
16890
16891 // at this point, extra isn't content nor padding, so add border
16892 if ( extra !== "padding" ) {
16893 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
16894 }
16895 }
16896 }
16897
16898 return val;
16899 }
16900
16901 function getWidthOrHeight( elem, name, extra ) {
16902
16903 // Start with offset property, which is equivalent to the border-box value
16904 var valueIsBorderBox = true,
16905 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
16906 styles = getStyles( elem ),
16907 isBorderBox = support.boxSizing &&
16908 jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
16909
16910 // some non-html elements return undefined for offsetWidth, so check for null/undefined
16911 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
16912 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
16913 if ( val <= 0 || val == null ) {
16914
16915 // Fall back to computed then uncomputed css if necessary
16916 val = curCSS( elem, name, styles );
16917 if ( val < 0 || val == null ) {
16918 val = elem.style[ name ];
16919 }
16920
16921 // Computed unit is not pixels. Stop here and return.
16922 if ( rnumnonpx.test( val ) ) {
16923 return val;
16924 }
16925
16926 // we need the check for style in case a browser which returns unreliable values
16927 // for getComputedStyle silently falls back to the reliable elem.style
16928 valueIsBorderBox = isBorderBox &&
16929 ( support.boxSizingReliable() || val === elem.style[ name ] );
16930
16931 // Normalize "", auto, and prepare for extra
16932 val = parseFloat( val ) || 0;
16933 }
16934
16935 // use the active box-sizing model to add/subtract irrelevant styles
16936 return ( val +
16937 augmentWidthOrHeight(
16938 elem,
16939 name,
16940 extra || ( isBorderBox ? "border" : "content" ),
16941 valueIsBorderBox,
16942 styles
16943 )
16944 ) + "px";
16945 }
16946
16947 jQuery.extend( {
16948
16949 // Add in style property hooks for overriding the default
16950 // behavior of getting and setting a style property
16951 cssHooks: {
16952 opacity: {
16953 get: function( elem, computed ) {
16954 if ( computed ) {
16955
16956 // We should always get a number back from opacity
16957 var ret = curCSS( elem, "opacity" );
16958 return ret === "" ? "1" : ret;
16959 }
16960 }
16961 }
16962 },
16963
16964 // Don't automatically add "px" to these possibly-unitless properties
16965 cssNumber: {
16966 "animationIterationCount": true,
16967 "columnCount": true,
16968 "fillOpacity": true,
16969 "flexGrow": true,
16970 "flexShrink": true,
16971 "fontWeight": true,
16972 "lineHeight": true,
16973 "opacity": true,
16974 "order": true,
16975 "orphans": true,
16976 "widows": true,
16977 "zIndex": true,
16978 "zoom": true
16979 },
16980
16981 // Add in properties whose names you wish to fix before
16982 // setting or getting the value
16983 cssProps: {
16984
16985 // normalize float css property
16986 "float": support.cssFloat ? "cssFloat" : "styleFloat"
16987 },
16988
16989 // Get and set the style property on a DOM Node
16990 style: function( elem, name, value, extra ) {
16991
16992 // Don't set styles on text and comment nodes
16993 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
16994 return;
16995 }
16996
16997 // Make sure that we're working with the right name
16998 var ret, type, hooks,
16999 origName = jQuery.camelCase( name ),
17000 style = elem.style;
17001
17002 name = jQuery.cssProps[ origName ] ||
17003 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
17004
17005 // gets hook for the prefixed version
17006 // followed by the unprefixed version
17007 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
17008
17009 // Check if we're setting a value
17010 if ( value !== undefined ) {
17011 type = typeof value;
17012
17013 // Convert "+=" or "-=" to relative numbers (#7345)
17014 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
17015 value = adjustCSS( elem, name, ret );
17016
17017 // Fixes bug #9237
17018 type = "number";
17019 }
17020
17021 // Make sure that null and NaN values aren't set. See: #7116
17022 if ( value == null || value !== value ) {
17023 return;
17024 }
17025
17026 // If a number was passed in, add the unit (except for certain CSS properties)
17027 if ( type === "number" ) {
17028 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
17029 }
17030
17031 // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
17032 // but it would mean to define eight
17033 // (for every problematic property) identical functions
17034 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
17035 style[ name ] = "inherit";
17036 }
17037
17038 // If a hook was provided, use that value, otherwise just set the specified value
17039 if ( !hooks || !( "set" in hooks ) ||
17040 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
17041
17042 // Support: IE
17043 // Swallow errors from 'invalid' CSS values (#5509)
17044 try {
17045 style[ name ] = value;
17046 } catch ( e ) {}
17047 }
17048
17049 } else {
17050
17051 // If a hook was provided get the non-computed value from there
17052 if ( hooks && "get" in hooks &&
17053 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
17054
17055 return ret;
17056 }
17057
17058 // Otherwise just get the value from the style object
17059 return style[ name ];
17060 }
17061 },
17062
17063 css: function( elem, name, extra, styles ) {
17064 var num, val, hooks,
17065 origName = jQuery.camelCase( name );
17066
17067 // Make sure that we're working with the right name
17068 name = jQuery.cssProps[ origName ] ||
17069 ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
17070
17071 // gets hook for the prefixed version
17072 // followed by the unprefixed version
17073 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
17074
17075 // If a hook was provided get the computed value from there
17076 if ( hooks && "get" in hooks ) {
17077 val = hooks.get( elem, true, extra );
17078 }
17079
17080 // Otherwise, if a way to get the computed value exists, use that
17081 if ( val === undefined ) {
17082 val = curCSS( elem, name, styles );
17083 }
17084
17085 //convert "normal" to computed value
17086 if ( val === "normal" && name in cssNormalTransform ) {
17087 val = cssNormalTransform[ name ];
17088 }
17089
17090 // Return, converting to number if forced or a qualifier was provided and val looks numeric
17091 if ( extra === "" || extra ) {
17092 num = parseFloat( val );
17093 return extra === true || isFinite( num ) ? num || 0 : val;
17094 }
17095 return val;
17096 }
17097 } );
17098
17099 jQuery.each( [ "height", "width" ], function( i, name ) {
17100 jQuery.cssHooks[ name ] = {
17101 get: function( elem, computed, extra ) {
17102 if ( computed ) {
17103
17104 // certain elements can have dimension info if we invisibly show them
17105 // however, it must have a current display style that would benefit from this
17106 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
17107 elem.offsetWidth === 0 ?
17108 swap( elem, cssShow, function() {
17109 return getWidthOrHeight( elem, name, extra );
17110 } ) :
17111 getWidthOrHeight( elem, name, extra );
17112 }
17113 },
17114
17115 set: function( elem, value, extra ) {
17116 var styles = extra && getStyles( elem );
17117 return setPositiveNumber( elem, value, extra ?
17118 augmentWidthOrHeight(
17119 elem,
17120 name,
17121 extra,
17122 support.boxSizing &&
17123 jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
17124 styles
17125 ) : 0
17126 );
17127 }
17128 };
17129 } );
17130
17131 if ( !support.opacity ) {
17132 jQuery.cssHooks.opacity = {
17133 get: function( elem, computed ) {
17134
17135 // IE uses filters for opacity
17136 return ropacity.test( ( computed && elem.currentStyle ?
17137 elem.currentStyle.filter :
17138 elem.style.filter ) || "" ) ?
17139 ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
17140 computed ? "1" : "";
17141 },
17142
17143 set: function( elem, value ) {
17144 var style = elem.style,
17145 currentStyle = elem.currentStyle,
17146 opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
17147 filter = currentStyle && currentStyle.filter || style.filter || "";
17148
17149 // IE has trouble with opacity if it does not have layout
17150 // Force it by setting the zoom level
17151 style.zoom = 1;
17152
17153 // if setting opacity to 1, and no other filters exist -
17154 // attempt to remove filter attribute #6652
17155 // if value === "", then remove inline opacity #12685
17156 if ( ( value >= 1 || value === "" ) &&
17157 jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
17158 style.removeAttribute ) {
17159
17160 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
17161 // if "filter:" is present at all, clearType is disabled, we want to avoid this
17162 // style.removeAttribute is IE Only, but so apparently is this code path...
17163 style.removeAttribute( "filter" );
17164
17165 // if there is no filter style applied in a css rule
17166 // or unset inline opacity, we are done
17167 if ( value === "" || currentStyle && !currentStyle.filter ) {
17168 return;
17169 }
17170 }
17171
17172 // otherwise, set new filter values
17173 style.filter = ralpha.test( filter ) ?
17174 filter.replace( ralpha, opacity ) :
17175 filter + " " + opacity;
17176 }
17177 };
17178 }
17179
17180 jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
17181 function( elem, computed ) {
17182 if ( computed ) {
17183 return swap( elem, { "display": "inline-block" },
17184 curCSS, [ elem, "marginRight" ] );
17185 }
17186 }
17187 );
17188
17189 jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
17190 function( elem, computed ) {
17191 if ( computed ) {
17192 return (
17193 parseFloat( curCSS( elem, "marginLeft" ) ) ||
17194
17195 // Support: IE<=11+
17196 // Running getBoundingClientRect on a disconnected node in IE throws an error
17197 // Support: IE8 only
17198 // getClientRects() errors on disconnected elems
17199 ( jQuery.contains( elem.ownerDocument, elem ) ?
17200 elem.getBoundingClientRect().left -
17201 swap( elem, { marginLeft: 0 }, function() {
17202 return elem.getBoundingClientRect().left;
17203 } ) :
17204 0
17205 )
17206 ) + "px";
17207 }
17208 }
17209 );
17210
17211 // These hooks are used by animate to expand properties
17212 jQuery.each( {
17213 margin: "",
17214 padding: "",
17215 border: "Width"
17216 }, function( prefix, suffix ) {
17217 jQuery.cssHooks[ prefix + suffix ] = {
17218 expand: function( value ) {
17219 var i = 0,
17220 expanded = {},
17221
17222 // assumes a single number if not a string
17223 parts = typeof value === "string" ? value.split( " " ) : [ value ];
17224
17225 for ( ; i < 4; i++ ) {
17226 expanded[ prefix + cssExpand[ i ] + suffix ] =
17227 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
17228 }
17229
17230 return expanded;
17231 }
17232 };
17233
17234 if ( !rmargin.test( prefix ) ) {
17235 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
17236 }
17237 } );
17238
17239 jQuery.fn.extend( {
17240 css: function( name, value ) {
17241 return access( this, function( elem, name, value ) {
17242 var styles, len,
17243 map = {},
17244 i = 0;
17245
17246 if ( jQuery.isArray( name ) ) {
17247 styles = getStyles( elem );
17248 len = name.length;
17249
17250 for ( ; i < len; i++ ) {
17251 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
17252 }
17253
17254 return map;
17255 }
17256
17257 return value !== undefined ?
17258 jQuery.style( elem, name, value ) :
17259 jQuery.css( elem, name );
17260 }, name, value, arguments.length > 1 );
17261 },
17262 show: function() {
17263 return showHide( this, true );
17264 },
17265 hide: function() {
17266 return showHide( this );
17267 },
17268 toggle: function( state ) {
17269 if ( typeof state === "boolean" ) {
17270 return state ? this.show() : this.hide();
17271 }
17272
17273 return this.each( function() {
17274 if ( isHidden( this ) ) {
17275 jQuery( this ).show();
17276 } else {
17277 jQuery( this ).hide();
17278 }
17279 } );
17280 }
17281 } );
17282
17283
17284 function Tween( elem, options, prop, end, easing ) {
17285 return new Tween.prototype.init( elem, options, prop, end, easing );
17286 }
17287 jQuery.Tween = Tween;
17288
17289 Tween.prototype = {
17290 constructor: Tween,
17291 init: function( elem, options, prop, end, easing, unit ) {
17292 this.elem = elem;
17293 this.prop = prop;
17294 this.easing = easing || jQuery.easing._default;
17295 this.options = options;
17296 this.start = this.now = this.cur();
17297 this.end = end;
17298 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
17299 },
17300 cur: function() {
17301 var hooks = Tween.propHooks[ this.prop ];
17302
17303 return hooks && hooks.get ?
17304 hooks.get( this ) :
17305 Tween.propHooks._default.get( this );
17306 },
17307 run: function( percent ) {
17308 var eased,
17309 hooks = Tween.propHooks[ this.prop ];
17310
17311 if ( this.options.duration ) {
17312 this.pos = eased = jQuery.easing[ this.easing ](
17313 percent, this.options.duration * percent, 0, 1, this.options.duration
17314 );
17315 } else {
17316 this.pos = eased = percent;
17317 }
17318 this.now = ( this.end - this.start ) * eased + this.start;
17319
17320 if ( this.options.step ) {
17321 this.options.step.call( this.elem, this.now, this );
17322 }
17323
17324 if ( hooks && hooks.set ) {
17325 hooks.set( this );
17326 } else {
17327 Tween.propHooks._default.set( this );
17328 }
17329 return this;
17330 }
17331 };
17332
17333 Tween.prototype.init.prototype = Tween.prototype;
17334
17335 Tween.propHooks = {
17336 _default: {
17337 get: function( tween ) {
17338 var result;
17339
17340 // Use a property on the element directly when it is not a DOM element,
17341 // or when there is no matching style property that exists.
17342 if ( tween.elem.nodeType !== 1 ||
17343 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
17344 return tween.elem[ tween.prop ];
17345 }
17346
17347 // passing an empty string as a 3rd parameter to .css will automatically
17348 // attempt a parseFloat and fallback to a string if the parse fails
17349 // so, simple values such as "10px" are parsed to Float.
17350 // complex values such as "rotate(1rad)" are returned as is.
17351 result = jQuery.css( tween.elem, tween.prop, "" );
17352
17353 // Empty strings, null, undefined and "auto" are converted to 0.
17354 return !result || result === "auto" ? 0 : result;
17355 },
17356 set: function( tween ) {
17357
17358 // use step hook for back compat - use cssHook if its there - use .style if its
17359 // available and use plain properties where available
17360 if ( jQuery.fx.step[ tween.prop ] ) {
17361 jQuery.fx.step[ tween.prop ]( tween );
17362 } else if ( tween.elem.nodeType === 1 &&
17363 ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
17364 jQuery.cssHooks[ tween.prop ] ) ) {
17365 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
17366 } else {
17367 tween.elem[ tween.prop ] = tween.now;
17368 }
17369 }
17370 }
17371 };
17372
17373 // Support: IE <=9
17374 // Panic based approach to setting things on disconnected nodes
17375
17376 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
17377 set: function( tween ) {
17378 if ( tween.elem.nodeType && tween.elem.parentNode ) {
17379 tween.elem[ tween.prop ] = tween.now;
17380 }
17381 }
17382 };
17383
17384 jQuery.easing = {
17385 linear: function( p ) {
17386 return p;
17387 },
17388 swing: function( p ) {
17389 return 0.5 - Math.cos( p * Math.PI ) / 2;
17390 },
17391 _default: "swing"
17392 };
17393
17394 jQuery.fx = Tween.prototype.init;
17395
17396 // Back Compat <1.8 extension point
17397 jQuery.fx.step = {};
17398
17399
17400
17401
17402 var
17403 fxNow, timerId,
17404 rfxtypes = /^(?:toggle|show|hide)$/,
17405 rrun = /queueHooks$/;
17406
17407 // Animations created synchronously will run synchronously
17408 function createFxNow() {
17409 window.setTimeout( function() {
17410 fxNow = undefined;
17411 } );
17412 return ( fxNow = jQuery.now() );
17413 }
17414
17415 // Generate parameters to create a standard animation
17416 function genFx( type, includeWidth ) {
17417 var which,
17418 attrs = { height: type },
17419 i = 0;
17420
17421 // if we include width, step value is 1 to do all cssExpand values,
17422 // if we don't include width, step value is 2 to skip over Left and Right
17423 includeWidth = includeWidth ? 1 : 0;
17424 for ( ; i < 4 ; i += 2 - includeWidth ) {
17425 which = cssExpand[ i ];
17426 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
17427 }
17428
17429 if ( includeWidth ) {
17430 attrs.opacity = attrs.width = type;
17431 }
17432
17433 return attrs;
17434 }
17435
17436 function createTween( value, prop, animation ) {
17437 var tween,
17438 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
17439 index = 0,
17440 length = collection.length;
17441 for ( ; index < length; index++ ) {
17442 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
17443
17444 // we're done with this property
17445 return tween;
17446 }
17447 }
17448 }
17449
17450 function defaultPrefilter( elem, props, opts ) {
17451 /* jshint validthis: true */
17452 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
17453 anim = this,
17454 orig = {},
17455 style = elem.style,
17456 hidden = elem.nodeType && isHidden( elem ),
17457 dataShow = jQuery._data( elem, "fxshow" );
17458
17459 // handle queue: false promises
17460 if ( !opts.queue ) {
17461 hooks = jQuery._queueHooks( elem, "fx" );
17462 if ( hooks.unqueued == null ) {
17463 hooks.unqueued = 0;
17464 oldfire = hooks.empty.fire;
17465 hooks.empty.fire = function() {
17466 if ( !hooks.unqueued ) {
17467 oldfire();
17468 }
17469 };
17470 }
17471 hooks.unqueued++;
17472
17473 anim.always( function() {
17474
17475 // doing this makes sure that the complete handler will be called
17476 // before this completes
17477 anim.always( function() {
17478 hooks.unqueued--;
17479 if ( !jQuery.queue( elem, "fx" ).length ) {
17480 hooks.empty.fire();
17481 }
17482 } );
17483 } );
17484 }
17485
17486 // height/width overflow pass
17487 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
17488
17489 // Make sure that nothing sneaks out
17490 // Record all 3 overflow attributes because IE does not
17491 // change the overflow attribute when overflowX and
17492 // overflowY are set to the same value
17493 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
17494
17495 // Set display property to inline-block for height/width
17496 // animations on inline elements that are having width/height animated
17497 display = jQuery.css( elem, "display" );
17498
17499 // Test default display if display is currently "none"
17500 checkDisplay = display === "none" ?
17501 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
17502
17503 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
17504
17505 // inline-level elements accept inline-block;
17506 // block-level elements need to be inline with layout
17507 if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
17508 style.display = "inline-block";
17509 } else {
17510 style.zoom = 1;
17511 }
17512 }
17513 }
17514
17515 if ( opts.overflow ) {
17516 style.overflow = "hidden";
17517 if ( !support.shrinkWrapBlocks() ) {
17518 anim.always( function() {
17519 style.overflow = opts.overflow[ 0 ];
17520 style.overflowX = opts.overflow[ 1 ];
17521 style.overflowY = opts.overflow[ 2 ];
17522 } );
17523 }
17524 }
17525
17526 // show/hide pass
17527 for ( prop in props ) {
17528 value = props[ prop ];
17529 if ( rfxtypes.exec( value ) ) {
17530 delete props[ prop ];
17531 toggle = toggle || value === "toggle";
17532 if ( value === ( hidden ? "hide" : "show" ) ) {
17533
17534 // If there is dataShow left over from a stopped hide or show
17535 // and we are going to proceed with show, we should pretend to be hidden
17536 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
17537 hidden = true;
17538 } else {
17539 continue;
17540 }
17541 }
17542 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
17543
17544 // Any non-fx value stops us from restoring the original display value
17545 } else {
17546 display = undefined;
17547 }
17548 }
17549
17550 if ( !jQuery.isEmptyObject( orig ) ) {
17551 if ( dataShow ) {
17552 if ( "hidden" in dataShow ) {
17553 hidden = dataShow.hidden;
17554 }
17555 } else {
17556 dataShow = jQuery._data( elem, "fxshow", {} );
17557 }
17558
17559 // store state if its toggle - enables .stop().toggle() to "reverse"
17560 if ( toggle ) {
17561 dataShow.hidden = !hidden;
17562 }
17563 if ( hidden ) {
17564 jQuery( elem ).show();
17565 } else {
17566 anim.done( function() {
17567 jQuery( elem ).hide();
17568 } );
17569 }
17570 anim.done( function() {
17571 var prop;
17572 jQuery._removeData( elem, "fxshow" );
17573 for ( prop in orig ) {
17574 jQuery.style( elem, prop, orig[ prop ] );
17575 }
17576 } );
17577 for ( prop in orig ) {
17578 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
17579
17580 if ( !( prop in dataShow ) ) {
17581 dataShow[ prop ] = tween.start;
17582 if ( hidden ) {
17583 tween.end = tween.start;
17584 tween.start = prop === "width" || prop === "height" ? 1 : 0;
17585 }
17586 }
17587 }
17588
17589 // If this is a noop like .hide().hide(), restore an overwritten display value
17590 } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
17591 style.display = display;
17592 }
17593 }
17594
17595 function propFilter( props, specialEasing ) {
17596 var index, name, easing, value, hooks;
17597
17598 // camelCase, specialEasing and expand cssHook pass
17599 for ( index in props ) {
17600 name = jQuery.camelCase( index );
17601 easing = specialEasing[ name ];
17602 value = props[ index ];
17603 if ( jQuery.isArray( value ) ) {
17604 easing = value[ 1 ];
17605 value = props[ index ] = value[ 0 ];
17606 }
17607
17608 if ( index !== name ) {
17609 props[ name ] = value;
17610 delete props[ index ];
17611 }
17612
17613 hooks = jQuery.cssHooks[ name ];
17614 if ( hooks && "expand" in hooks ) {
17615 value = hooks.expand( value );
17616 delete props[ name ];
17617
17618 // not quite $.extend, this wont overwrite keys already present.
17619 // also - reusing 'index' from above because we have the correct "name"
17620 for ( index in value ) {
17621 if ( !( index in props ) ) {
17622 props[ index ] = value[ index ];
17623 specialEasing[ index ] = easing;
17624 }
17625 }
17626 } else {
17627 specialEasing[ name ] = easing;
17628 }
17629 }
17630 }
17631
17632 function Animation( elem, properties, options ) {
17633 var result,
17634 stopped,
17635 index = 0,
17636 length = Animation.prefilters.length,
17637 deferred = jQuery.Deferred().always( function() {
17638
17639 // don't match elem in the :animated selector
17640 delete tick.elem;
17641 } ),
17642 tick = function() {
17643 if ( stopped ) {
17644 return false;
17645 }
17646 var currentTime = fxNow || createFxNow(),
17647 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
17648
17649 // Support: Android 2.3
17650 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
17651 temp = remaining / animation.duration || 0,
17652 percent = 1 - temp,
17653 index = 0,
17654 length = animation.tweens.length;
17655
17656 for ( ; index < length ; index++ ) {
17657 animation.tweens[ index ].run( percent );
17658 }
17659
17660 deferred.notifyWith( elem, [ animation, percent, remaining ] );
17661
17662 if ( percent < 1 && length ) {
17663 return remaining;
17664 } else {
17665 deferred.resolveWith( elem, [ animation ] );
17666 return false;
17667 }
17668 },
17669 animation = deferred.promise( {
17670 elem: elem,
17671 props: jQuery.extend( {}, properties ),
17672 opts: jQuery.extend( true, {
17673 specialEasing: {},
17674 easing: jQuery.easing._default
17675 }, options ),
17676 originalProperties: properties,
17677 originalOptions: options,
17678 startTime: fxNow || createFxNow(),
17679 duration: options.duration,
17680 tweens: [],
17681 createTween: function( prop, end ) {
17682 var tween = jQuery.Tween( elem, animation.opts, prop, end,
17683 animation.opts.specialEasing[ prop ] || animation.opts.easing );
17684 animation.tweens.push( tween );
17685 return tween;
17686 },
17687 stop: function( gotoEnd ) {
17688 var index = 0,
17689
17690 // if we are going to the end, we want to run all the tweens
17691 // otherwise we skip this part
17692 length = gotoEnd ? animation.tweens.length : 0;
17693 if ( stopped ) {
17694 return this;
17695 }
17696 stopped = true;
17697 for ( ; index < length ; index++ ) {
17698 animation.tweens[ index ].run( 1 );
17699 }
17700
17701 // resolve when we played the last frame
17702 // otherwise, reject
17703 if ( gotoEnd ) {
17704 deferred.notifyWith( elem, [ animation, 1, 0 ] );
17705 deferred.resolveWith( elem, [ animation, gotoEnd ] );
17706 } else {
17707 deferred.rejectWith( elem, [ animation, gotoEnd ] );
17708 }
17709 return this;
17710 }
17711 } ),
17712 props = animation.props;
17713
17714 propFilter( props, animation.opts.specialEasing );
17715
17716 for ( ; index < length ; index++ ) {
17717 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
17718 if ( result ) {
17719 if ( jQuery.isFunction( result.stop ) ) {
17720 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
17721 jQuery.proxy( result.stop, result );
17722 }
17723 return result;
17724 }
17725 }
17726
17727 jQuery.map( props, createTween, animation );
17728
17729 if ( jQuery.isFunction( animation.opts.start ) ) {
17730 animation.opts.start.call( elem, animation );
17731 }
17732
17733 jQuery.fx.timer(
17734 jQuery.extend( tick, {
17735 elem: elem,
17736 anim: animation,
17737 queue: animation.opts.queue
17738 } )
17739 );
17740
17741 // attach callbacks from options
17742 return animation.progress( animation.opts.progress )
17743 .done( animation.opts.done, animation.opts.complete )
17744 .fail( animation.opts.fail )
17745 .always( animation.opts.always );
17746 }
17747
17748 jQuery.Animation = jQuery.extend( Animation, {
17749
17750 tweeners: {
17751 "*": [ function( prop, value ) {
17752 var tween = this.createTween( prop, value );
17753 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
17754 return tween;
17755 } ]
17756 },
17757
17758 tweener: function( props, callback ) {
17759 if ( jQuery.isFunction( props ) ) {
17760 callback = props;
17761 props = [ "*" ];
17762 } else {
17763 props = props.match( rnotwhite );
17764 }
17765
17766 var prop,
17767 index = 0,
17768 length = props.length;
17769
17770 for ( ; index < length ; index++ ) {
17771 prop = props[ index ];
17772 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
17773 Animation.tweeners[ prop ].unshift( callback );
17774 }
17775 },
17776
17777 prefilters: [ defaultPrefilter ],
17778
17779 prefilter: function( callback, prepend ) {
17780 if ( prepend ) {
17781 Animation.prefilters.unshift( callback );
17782 } else {
17783 Animation.prefilters.push( callback );
17784 }
17785 }
17786 } );
17787
17788 jQuery.speed = function( speed, easing, fn ) {
17789 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
17790 complete: fn || !fn && easing ||
17791 jQuery.isFunction( speed ) && speed,
17792 duration: speed,
17793 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
17794 };
17795
17796 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
17797 opt.duration in jQuery.fx.speeds ?
17798 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
17799
17800 // normalize opt.queue - true/undefined/null -> "fx"
17801 if ( opt.queue == null || opt.queue === true ) {
17802 opt.queue = "fx";
17803 }
17804
17805 // Queueing
17806 opt.old = opt.complete;
17807
17808 opt.complete = function() {
17809 if ( jQuery.isFunction( opt.old ) ) {
17810 opt.old.call( this );
17811 }
17812
17813 if ( opt.queue ) {
17814 jQuery.dequeue( this, opt.queue );
17815 }
17816 };
17817
17818 return opt;
17819 };
17820
17821 jQuery.fn.extend( {
17822 fadeTo: function( speed, to, easing, callback ) {
17823
17824 // show any hidden elements after setting opacity to 0
17825 return this.filter( isHidden ).css( "opacity", 0 ).show()
17826
17827 // animate to the value specified
17828 .end().animate( { opacity: to }, speed, easing, callback );
17829 },
17830 animate: function( prop, speed, easing, callback ) {
17831 var empty = jQuery.isEmptyObject( prop ),
17832 optall = jQuery.speed( speed, easing, callback ),
17833 doAnimation = function() {
17834
17835 // Operate on a copy of prop so per-property easing won't be lost
17836 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
17837
17838 // Empty animations, or finishing resolves immediately
17839 if ( empty || jQuery._data( this, "finish" ) ) {
17840 anim.stop( true );
17841 }
17842 };
17843 doAnimation.finish = doAnimation;
17844
17845 return empty || optall.queue === false ?
17846 this.each( doAnimation ) :
17847 this.queue( optall.queue, doAnimation );
17848 },
17849 stop: function( type, clearQueue, gotoEnd ) {
17850 var stopQueue = function( hooks ) {
17851 var stop = hooks.stop;
17852 delete hooks.stop;
17853 stop( gotoEnd );
17854 };
17855
17856 if ( typeof type !== "string" ) {
17857 gotoEnd = clearQueue;
17858 clearQueue = type;
17859 type = undefined;
17860 }
17861 if ( clearQueue && type !== false ) {
17862 this.queue( type || "fx", [] );
17863 }
17864
17865 return this.each( function() {
17866 var dequeue = true,
17867 index = type != null && type + "queueHooks",
17868 timers = jQuery.timers,
17869 data = jQuery._data( this );
17870
17871 if ( index ) {
17872 if ( data[ index ] && data[ index ].stop ) {
17873 stopQueue( data[ index ] );
17874 }
17875 } else {
17876 for ( index in data ) {
17877 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
17878 stopQueue( data[ index ] );
17879 }
17880 }
17881 }
17882
17883 for ( index = timers.length; index--; ) {
17884 if ( timers[ index ].elem === this &&
17885 ( type == null || timers[ index ].queue === type ) ) {
17886
17887 timers[ index ].anim.stop( gotoEnd );
17888 dequeue = false;
17889 timers.splice( index, 1 );
17890 }
17891 }
17892
17893 // start the next in the queue if the last step wasn't forced
17894 // timers currently will call their complete callbacks, which will dequeue
17895 // but only if they were gotoEnd
17896 if ( dequeue || !gotoEnd ) {
17897 jQuery.dequeue( this, type );
17898 }
17899 } );
17900 },
17901 finish: function( type ) {
17902 if ( type !== false ) {
17903 type = type || "fx";
17904 }
17905 return this.each( function() {
17906 var index,
17907 data = jQuery._data( this ),
17908 queue = data[ type + "queue" ],
17909 hooks = data[ type + "queueHooks" ],
17910 timers = jQuery.timers,
17911 length = queue ? queue.length : 0;
17912
17913 // enable finishing flag on private data
17914 data.finish = true;
17915
17916 // empty the queue first
17917 jQuery.queue( this, type, [] );
17918
17919 if ( hooks && hooks.stop ) {
17920 hooks.stop.call( this, true );
17921 }
17922
17923 // look for any active animations, and finish them
17924 for ( index = timers.length; index--; ) {
17925 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
17926 timers[ index ].anim.stop( true );
17927 timers.splice( index, 1 );
17928 }
17929 }
17930
17931 // look for any animations in the old queue and finish them
17932 for ( index = 0; index < length; index++ ) {
17933 if ( queue[ index ] && queue[ index ].finish ) {
17934 queue[ index ].finish.call( this );
17935 }
17936 }
17937
17938 // turn off finishing flag
17939 delete data.finish;
17940 } );
17941 }
17942 } );
17943
17944 jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
17945 var cssFn = jQuery.fn[ name ];
17946 jQuery.fn[ name ] = function( speed, easing, callback ) {
17947 return speed == null || typeof speed === "boolean" ?
17948 cssFn.apply( this, arguments ) :
17949 this.animate( genFx( name, true ), speed, easing, callback );
17950 };
17951 } );
17952
17953 // Generate shortcuts for custom animations
17954 jQuery.each( {
17955 slideDown: genFx( "show" ),
17956 slideUp: genFx( "hide" ),
17957 slideToggle: genFx( "toggle" ),
17958 fadeIn: { opacity: "show" },
17959 fadeOut: { opacity: "hide" },
17960 fadeToggle: { opacity: "toggle" }
17961 }, function( name, props ) {
17962 jQuery.fn[ name ] = function( speed, easing, callback ) {
17963 return this.animate( props, speed, easing, callback );
17964 };
17965 } );
17966
17967 jQuery.timers = [];
17968 jQuery.fx.tick = function() {
17969 var timer,
17970 timers = jQuery.timers,
17971 i = 0;
17972
17973 fxNow = jQuery.now();
17974
17975 for ( ; i < timers.length; i++ ) {
17976 timer = timers[ i ];
17977
17978 // Checks the timer has not already been removed
17979 if ( !timer() && timers[ i ] === timer ) {
17980 timers.splice( i--, 1 );
17981 }
17982 }
17983
17984 if ( !timers.length ) {
17985 jQuery.fx.stop();
17986 }
17987 fxNow = undefined;
17988 };
17989
17990 jQuery.fx.timer = function( timer ) {
17991 jQuery.timers.push( timer );
17992 if ( timer() ) {
17993 jQuery.fx.start();
17994 } else {
17995 jQuery.timers.pop();
17996 }
17997 };
17998
17999 jQuery.fx.interval = 13;
18000
18001 jQuery.fx.start = function() {
18002 if ( !timerId ) {
18003 timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
18004 }
18005 };
18006
18007 jQuery.fx.stop = function() {
18008 window.clearInterval( timerId );
18009 timerId = null;
18010 };
18011
18012 jQuery.fx.speeds = {
18013 slow: 600,
18014 fast: 200,
18015
18016 // Default speed
18017 _default: 400
18018 };
18019
18020
18021 // Based off of the plugin by Clint Helfers, with permission.
18022 // http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
18023 jQuery.fn.delay = function( time, type ) {
18024 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
18025 type = type || "fx";
18026
18027 return this.queue( type, function( next, hooks ) {
18028 var timeout = window.setTimeout( next, time );
18029 hooks.stop = function() {
18030 window.clearTimeout( timeout );
18031 };
18032 } );
18033 };
18034
18035
18036 ( function() {
18037 var a,
18038 input = document.createElement( "input" ),
18039 div = document.createElement( "div" ),
18040 select = document.createElement( "select" ),
18041 opt = select.appendChild( document.createElement( "option" ) );
18042
18043 // Setup
18044 div = document.createElement( "div" );
18045 div.setAttribute( "className", "t" );
18046 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
18047 a = div.getElementsByTagName( "a" )[ 0 ];
18048
18049 // Support: Windows Web Apps (WWA)
18050 // `type` must use .setAttribute for WWA (#14901)
18051 input.setAttribute( "type", "checkbox" );
18052 div.appendChild( input );
18053
18054 a = div.getElementsByTagName( "a" )[ 0 ];
18055
18056 // First batch of tests.
18057 a.style.cssText = "top:1px";
18058
18059 // Test setAttribute on camelCase class.
18060 // If it works, we need attrFixes when doing get/setAttribute (ie6/7)
18061 support.getSetAttribute = div.className !== "t";
18062
18063 // Get the style information from getAttribute
18064 // (IE uses .cssText instead)
18065 support.style = /top/.test( a.getAttribute( "style" ) );
18066
18067 // Make sure that URLs aren't manipulated
18068 // (IE normalizes it by default)
18069 support.hrefNormalized = a.getAttribute( "href" ) === "/a";
18070
18071 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
18072 support.checkOn = !!input.value;
18073
18074 // Make sure that a selected-by-default option has a working selected property.
18075 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
18076 support.optSelected = opt.selected;
18077
18078 // Tests for enctype support on a form (#6743)
18079 support.enctype = !!document.createElement( "form" ).enctype;
18080
18081 // Make sure that the options inside disabled selects aren't marked as disabled
18082 // (WebKit marks them as disabled)
18083 select.disabled = true;
18084 support.optDisabled = !opt.disabled;
18085
18086 // Support: IE8 only
18087 // Check if we can trust getAttribute("value")
18088 input = document.createElement( "input" );
18089 input.setAttribute( "value", "" );
18090 support.input = input.getAttribute( "value" ) === "";
18091
18092 // Check if an input maintains its value after becoming a radio
18093 input.value = "t";
18094 input.setAttribute( "type", "radio" );
18095 support.radioValue = input.value === "t";
18096 } )();
18097
18098
18099 var rreturn = /\r/g,
18100 rspaces = /[\x20\t\r\n\f]+/g;
18101
18102 jQuery.fn.extend( {
18103 val: function( value ) {
18104 var hooks, ret, isFunction,
18105 elem = this[ 0 ];
18106
18107 if ( !arguments.length ) {
18108 if ( elem ) {
18109 hooks = jQuery.valHooks[ elem.type ] ||
18110 jQuery.valHooks[ elem.nodeName.toLowerCase() ];
18111
18112 if (
18113 hooks &&
18114 "get" in hooks &&
18115 ( ret = hooks.get( elem, "value" ) ) !== undefined
18116 ) {
18117 return ret;
18118 }
18119
18120 ret = elem.value;
18121
18122 return typeof ret === "string" ?
18123
18124 // handle most common string cases
18125 ret.replace( rreturn, "" ) :
18126
18127 // handle cases where value is null/undef or number
18128 ret == null ? "" : ret;
18129 }
18130
18131 return;
18132 }
18133
18134 isFunction = jQuery.isFunction( value );
18135
18136 return this.each( function( i ) {
18137 var val;
18138
18139 if ( this.nodeType !== 1 ) {
18140 return;
18141 }
18142
18143 if ( isFunction ) {
18144 val = value.call( this, i, jQuery( this ).val() );
18145 } else {
18146 val = value;
18147 }
18148
18149 // Treat null/undefined as ""; convert numbers to string
18150 if ( val == null ) {
18151 val = "";
18152 } else if ( typeof val === "number" ) {
18153 val += "";
18154 } else if ( jQuery.isArray( val ) ) {
18155 val = jQuery.map( val, function( value ) {
18156 return value == null ? "" : value + "";
18157 } );
18158 }
18159
18160 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
18161
18162 // If set returns undefined, fall back to normal setting
18163 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
18164 this.value = val;
18165 }
18166 } );
18167 }
18168 } );
18169
18170 jQuery.extend( {
18171 valHooks: {
18172 option: {
18173 get: function( elem ) {
18174 var val = jQuery.find.attr( elem, "value" );
18175 return val != null ?
18176 val :
18177
18178 // Support: IE10-11+
18179 // option.text throws exceptions (#14686, #14858)
18180 // Strip and collapse whitespace
18181 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
18182 jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
18183 }
18184 },
18185 select: {
18186 get: function( elem ) {
18187 var value, option,
18188 options = elem.options,
18189 index = elem.selectedIndex,
18190 one = elem.type === "select-one" || index < 0,
18191 values = one ? null : [],
18192 max = one ? index + 1 : options.length,
18193 i = index < 0 ?
18194 max :
18195 one ? index : 0;
18196
18197 // Loop through all the selected options
18198 for ( ; i < max; i++ ) {
18199 option = options[ i ];
18200
18201 // oldIE doesn't update selected after form reset (#2551)
18202 if ( ( option.selected || i === index ) &&
18203
18204 // Don't return options that are disabled or in a disabled optgroup
18205 ( support.optDisabled ?
18206 !option.disabled :
18207 option.getAttribute( "disabled" ) === null ) &&
18208 ( !option.parentNode.disabled ||
18209 !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
18210
18211 // Get the specific value for the option
18212 value = jQuery( option ).val();
18213
18214 // We don't need an array for one selects
18215 if ( one ) {
18216 return value;
18217 }
18218
18219 // Multi-Selects return an array
18220 values.push( value );
18221 }
18222 }
18223
18224 return values;
18225 },
18226
18227 set: function( elem, value ) {
18228 var optionSet, option,
18229 options = elem.options,
18230 values = jQuery.makeArray( value ),
18231 i = options.length;
18232
18233 while ( i-- ) {
18234 option = options[ i ];
18235
18236 if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
18237
18238 // Support: IE6
18239 // When new option element is added to select box we need to
18240 // force reflow of newly added node in order to workaround delay
18241 // of initialization properties
18242 try {
18243 option.selected = optionSet = true;
18244
18245 } catch ( _ ) {
18246
18247 // Will be executed only in IE6
18248 option.scrollHeight;
18249 }
18250
18251 } else {
18252 option.selected = false;
18253 }
18254 }
18255
18256 // Force browsers to behave consistently when non-matching value is set
18257 if ( !optionSet ) {
18258 elem.selectedIndex = -1;
18259 }
18260
18261 return options;
18262 }
18263 }
18264 }
18265 } );
18266
18267 // Radios and checkboxes getter/setter
18268 jQuery.each( [ "radio", "checkbox" ], function() {
18269 jQuery.valHooks[ this ] = {
18270 set: function( elem, value ) {
18271 if ( jQuery.isArray( value ) ) {
18272 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
18273 }
18274 }
18275 };
18276 if ( !support.checkOn ) {
18277 jQuery.valHooks[ this ].get = function( elem ) {
18278 return elem.getAttribute( "value" ) === null ? "on" : elem.value;
18279 };
18280 }
18281 } );
18282
18283
18284
18285
18286 var nodeHook, boolHook,
18287 attrHandle = jQuery.expr.attrHandle,
18288 ruseDefault = /^(?:checked|selected)$/i,
18289 getSetAttribute = support.getSetAttribute,
18290 getSetInput = support.input;
18291
18292 jQuery.fn.extend( {
18293 attr: function( name, value ) {
18294 return access( this, jQuery.attr, name, value, arguments.length > 1 );
18295 },
18296
18297 removeAttr: function( name ) {
18298 return this.each( function() {
18299 jQuery.removeAttr( this, name );
18300 } );
18301 }
18302 } );
18303
18304 jQuery.extend( {
18305 attr: function( elem, name, value ) {
18306 var ret, hooks,
18307 nType = elem.nodeType;
18308
18309 // Don't get/set attributes on text, comment and attribute nodes
18310 if ( nType === 3 || nType === 8 || nType === 2 ) {
18311 return;
18312 }
18313
18314 // Fallback to prop when attributes are not supported
18315 if ( typeof elem.getAttribute === "undefined" ) {
18316 return jQuery.prop( elem, name, value );
18317 }
18318
18319 // All attributes are lowercase
18320 // Grab necessary hook if one is defined
18321 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
18322 name = name.toLowerCase();
18323 hooks = jQuery.attrHooks[ name ] ||
18324 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
18325 }
18326
18327 if ( value !== undefined ) {
18328 if ( value === null ) {
18329 jQuery.removeAttr( elem, name );
18330 return;
18331 }
18332
18333 if ( hooks && "set" in hooks &&
18334 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
18335 return ret;
18336 }
18337
18338 elem.setAttribute( name, value + "" );
18339 return value;
18340 }
18341
18342 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
18343 return ret;
18344 }
18345
18346 ret = jQuery.find.attr( elem, name );
18347
18348 // Non-existent attributes return null, we normalize to undefined
18349 return ret == null ? undefined : ret;
18350 },
18351
18352 attrHooks: {
18353 type: {
18354 set: function( elem, value ) {
18355 if ( !support.radioValue && value === "radio" &&
18356 jQuery.nodeName( elem, "input" ) ) {
18357
18358 // Setting the type on a radio button after the value resets the value in IE8-9
18359 // Reset value to default in case type is set after value during creation
18360 var val = elem.value;
18361 elem.setAttribute( "type", value );
18362 if ( val ) {
18363 elem.value = val;
18364 }
18365 return value;
18366 }
18367 }
18368 }
18369 },
18370
18371 removeAttr: function( elem, value ) {
18372 var name, propName,
18373 i = 0,
18374 attrNames = value && value.match( rnotwhite );
18375
18376 if ( attrNames && elem.nodeType === 1 ) {
18377 while ( ( name = attrNames[ i++ ] ) ) {
18378 propName = jQuery.propFix[ name ] || name;
18379
18380 // Boolean attributes get special treatment (#10870)
18381 if ( jQuery.expr.match.bool.test( name ) ) {
18382
18383 // Set corresponding property to false
18384 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
18385 elem[ propName ] = false;
18386
18387 // Support: IE<9
18388 // Also clear defaultChecked/defaultSelected (if appropriate)
18389 } else {
18390 elem[ jQuery.camelCase( "default-" + name ) ] =
18391 elem[ propName ] = false;
18392 }
18393
18394 // See #9699 for explanation of this approach (setting first, then removal)
18395 } else {
18396 jQuery.attr( elem, name, "" );
18397 }
18398
18399 elem.removeAttribute( getSetAttribute ? name : propName );
18400 }
18401 }
18402 }
18403 } );
18404
18405 // Hooks for boolean attributes
18406 boolHook = {
18407 set: function( elem, value, name ) {
18408 if ( value === false ) {
18409
18410 // Remove boolean attributes when set to false
18411 jQuery.removeAttr( elem, name );
18412 } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
18413
18414 // IE<8 needs the *property* name
18415 elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
18416
18417 } else {
18418
18419 // Support: IE<9
18420 // Use defaultChecked and defaultSelected for oldIE
18421 elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
18422 }
18423 return name;
18424 }
18425 };
18426
18427 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
18428 var getter = attrHandle[ name ] || jQuery.find.attr;
18429
18430 if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
18431 attrHandle[ name ] = function( elem, name, isXML ) {
18432 var ret, handle;
18433 if ( !isXML ) {
18434
18435 // Avoid an infinite loop by temporarily removing this function from the getter
18436 handle = attrHandle[ name ];
18437 attrHandle[ name ] = ret;
18438 ret = getter( elem, name, isXML ) != null ?
18439 name.toLowerCase() :
18440 null;
18441 attrHandle[ name ] = handle;
18442 }
18443 return ret;
18444 };
18445 } else {
18446 attrHandle[ name ] = function( elem, name, isXML ) {
18447 if ( !isXML ) {
18448 return elem[ jQuery.camelCase( "default-" + name ) ] ?
18449 name.toLowerCase() :
18450 null;
18451 }
18452 };
18453 }
18454 } );
18455
18456 // fix oldIE attroperties
18457 if ( !getSetInput || !getSetAttribute ) {
18458 jQuery.attrHooks.value = {
18459 set: function( elem, value, name ) {
18460 if ( jQuery.nodeName( elem, "input" ) ) {
18461
18462 // Does not return so that setAttribute is also used
18463 elem.defaultValue = value;
18464 } else {
18465
18466 // Use nodeHook if defined (#1954); otherwise setAttribute is fine
18467 return nodeHook && nodeHook.set( elem, value, name );
18468 }
18469 }
18470 };
18471 }
18472
18473 // IE6/7 do not support getting/setting some attributes with get/setAttribute
18474 if ( !getSetAttribute ) {
18475
18476 // Use this for any attribute in IE6/7
18477 // This fixes almost every IE6/7 issue
18478 nodeHook = {
18479 set: function( elem, value, name ) {
18480
18481 // Set the existing or create a new attribute node
18482 var ret = elem.getAttributeNode( name );
18483 if ( !ret ) {
18484 elem.setAttributeNode(
18485 ( ret = elem.ownerDocument.createAttribute( name ) )
18486 );
18487 }
18488
18489 ret.value = value += "";
18490
18491 // Break association with cloned elements by also using setAttribute (#9646)
18492 if ( name === "value" || value === elem.getAttribute( name ) ) {
18493 return value;
18494 }
18495 }
18496 };
18497
18498 // Some attributes are constructed with empty-string values when not defined
18499 attrHandle.id = attrHandle.name = attrHandle.coords =
18500 function( elem, name, isXML ) {
18501 var ret;
18502 if ( !isXML ) {
18503 return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
18504 ret.value :
18505 null;
18506 }
18507 };
18508
18509 // Fixing value retrieval on a button requires this module
18510 jQuery.valHooks.button = {
18511 get: function( elem, name ) {
18512 var ret = elem.getAttributeNode( name );
18513 if ( ret && ret.specified ) {
18514 return ret.value;
18515 }
18516 },
18517 set: nodeHook.set
18518 };
18519
18520 // Set contenteditable to false on removals(#10429)
18521 // Setting to empty string throws an error as an invalid value
18522 jQuery.attrHooks.contenteditable = {
18523 set: function( elem, value, name ) {
18524 nodeHook.set( elem, value === "" ? false : value, name );
18525 }
18526 };
18527
18528 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
18529 // This is for removals
18530 jQuery.each( [ "width", "height" ], function( i, name ) {
18531 jQuery.attrHooks[ name ] = {
18532 set: function( elem, value ) {
18533 if ( value === "" ) {
18534 elem.setAttribute( name, "auto" );
18535 return value;
18536 }
18537 }
18538 };
18539 } );
18540 }
18541
18542 if ( !support.style ) {
18543 jQuery.attrHooks.style = {
18544 get: function( elem ) {
18545
18546 // Return undefined in the case of empty string
18547 // Note: IE uppercases css property names, but if we were to .toLowerCase()
18548 // .cssText, that would destroy case sensitivity in URL's, like in "background"
18549 return elem.style.cssText || undefined;
18550 },
18551 set: function( elem, value ) {
18552 return ( elem.style.cssText = value + "" );
18553 }
18554 };
18555 }
18556
18557
18558
18559
18560 var rfocusable = /^(?:input|select|textarea|button|object)$/i,
18561 rclickable = /^(?:a|area)$/i;
18562
18563 jQuery.fn.extend( {
18564 prop: function( name, value ) {
18565 return access( this, jQuery.prop, name, value, arguments.length > 1 );
18566 },
18567
18568 removeProp: function( name ) {
18569 name = jQuery.propFix[ name ] || name;
18570 return this.each( function() {
18571
18572 // try/catch handles cases where IE balks (such as removing a property on window)
18573 try {
18574 this[ name ] = undefined;
18575 delete this[ name ];
18576 } catch ( e ) {}
18577 } );
18578 }
18579 } );
18580
18581 jQuery.extend( {
18582 prop: function( elem, name, value ) {
18583 var ret, hooks,
18584 nType = elem.nodeType;
18585
18586 // Don't get/set properties on text, comment and attribute nodes
18587 if ( nType === 3 || nType === 8 || nType === 2 ) {
18588 return;
18589 }
18590
18591 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
18592
18593 // Fix name and attach hooks
18594 name = jQuery.propFix[ name ] || name;
18595 hooks = jQuery.propHooks[ name ];
18596 }
18597
18598 if ( value !== undefined ) {
18599 if ( hooks && "set" in hooks &&
18600 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
18601 return ret;
18602 }
18603
18604 return ( elem[ name ] = value );
18605 }
18606
18607 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
18608 return ret;
18609 }
18610
18611 return elem[ name ];
18612 },
18613
18614 propHooks: {
18615 tabIndex: {
18616 get: function( elem ) {
18617
18618 // elem.tabIndex doesn't always return the
18619 // correct value when it hasn't been explicitly set
18620 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
18621 // Use proper attribute retrieval(#12072)
18622 var tabindex = jQuery.find.attr( elem, "tabindex" );
18623
18624 return tabindex ?
18625 parseInt( tabindex, 10 ) :
18626 rfocusable.test( elem.nodeName ) ||
18627 rclickable.test( elem.nodeName ) && elem.href ?
18628 0 :
18629 -1;
18630 }
18631 }
18632 },
18633
18634 propFix: {
18635 "for": "htmlFor",
18636 "class": "className"
18637 }
18638 } );
18639
18640 // Some attributes require a special call on IE
18641 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
18642 if ( !support.hrefNormalized ) {
18643
18644 // href/src property should get the full normalized URL (#10299/#12915)
18645 jQuery.each( [ "href", "src" ], function( i, name ) {
18646 jQuery.propHooks[ name ] = {
18647 get: function( elem ) {
18648 return elem.getAttribute( name, 4 );
18649 }
18650 };
18651 } );
18652 }
18653
18654 // Support: Safari, IE9+
18655 // Accessing the selectedIndex property
18656 // forces the browser to respect setting selected
18657 // on the option
18658 // The getter ensures a default option is selected
18659 // when in an optgroup
18660 if ( !support.optSelected ) {
18661 jQuery.propHooks.selected = {
18662 get: function( elem ) {
18663 var parent = elem.parentNode;
18664
18665 if ( parent ) {
18666 parent.selectedIndex;
18667
18668 // Make sure that it also works with optgroups, see #5701
18669 if ( parent.parentNode ) {
18670 parent.parentNode.selectedIndex;
18671 }
18672 }
18673 return null;
18674 },
18675 set: function( elem ) {
18676 var parent = elem.parentNode;
18677 if ( parent ) {
18678 parent.selectedIndex;
18679
18680 if ( parent.parentNode ) {
18681 parent.parentNode.selectedIndex;
18682 }
18683 }
18684 }
18685 };
18686 }
18687
18688 jQuery.each( [
18689 "tabIndex",
18690 "readOnly",
18691 "maxLength",
18692 "cellSpacing",
18693 "cellPadding",
18694 "rowSpan",
18695 "colSpan",
18696 "useMap",
18697 "frameBorder",
18698 "contentEditable"
18699 ], function() {
18700 jQuery.propFix[ this.toLowerCase() ] = this;
18701 } );
18702
18703 // IE6/7 call enctype encoding
18704 if ( !support.enctype ) {
18705 jQuery.propFix.enctype = "encoding";
18706 }
18707
18708
18709
18710
18711 var rclass = /[\t\r\n\f]/g;
18712
18713 function getClass( elem ) {
18714 return jQuery.attr( elem, "class" ) || "";
18715 }
18716
18717 jQuery.fn.extend( {
18718 addClass: function( value ) {
18719 var classes, elem, cur, curValue, clazz, j, finalValue,
18720 i = 0;
18721
18722 if ( jQuery.isFunction( value ) ) {
18723 return this.each( function( j ) {
18724 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
18725 } );
18726 }
18727
18728 if ( typeof value === "string" && value ) {
18729 classes = value.match( rnotwhite ) || [];
18730
18731 while ( ( elem = this[ i++ ] ) ) {
18732 curValue = getClass( elem );
18733 cur = elem.nodeType === 1 &&
18734 ( " " + curValue + " " ).replace( rclass, " " );
18735
18736 if ( cur ) {
18737 j = 0;
18738 while ( ( clazz = classes[ j++ ] ) ) {
18739 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
18740 cur += clazz + " ";
18741 }
18742 }
18743
18744 // only assign if different to avoid unneeded rendering.
18745 finalValue = jQuery.trim( cur );
18746 if ( curValue !== finalValue ) {
18747 jQuery.attr( elem, "class", finalValue );
18748 }
18749 }
18750 }
18751 }
18752
18753 return this;
18754 },
18755
18756 removeClass: function( value ) {
18757 var classes, elem, cur, curValue, clazz, j, finalValue,
18758 i = 0;
18759
18760 if ( jQuery.isFunction( value ) ) {
18761 return this.each( function( j ) {
18762 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
18763 } );
18764 }
18765
18766 if ( !arguments.length ) {
18767 return this.attr( "class", "" );
18768 }
18769
18770 if ( typeof value === "string" && value ) {
18771 classes = value.match( rnotwhite ) || [];
18772
18773 while ( ( elem = this[ i++ ] ) ) {
18774 curValue = getClass( elem );
18775
18776 // This expression is here for better compressibility (see addClass)
18777 cur = elem.nodeType === 1 &&
18778 ( " " + curValue + " " ).replace( rclass, " " );
18779
18780 if ( cur ) {
18781 j = 0;
18782 while ( ( clazz = classes[ j++ ] ) ) {
18783
18784 // Remove *all* instances
18785 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
18786 cur = cur.replace( " " + clazz + " ", " " );
18787 }
18788 }
18789
18790 // Only assign if different to avoid unneeded rendering.
18791 finalValue = jQuery.trim( cur );
18792 if ( curValue !== finalValue ) {
18793 jQuery.attr( elem, "class", finalValue );
18794 }
18795 }
18796 }
18797 }
18798
18799 return this;
18800 },
18801
18802 toggleClass: function( value, stateVal ) {
18803 var type = typeof value;
18804
18805 if ( typeof stateVal === "boolean" && type === "string" ) {
18806 return stateVal ? this.addClass( value ) : this.removeClass( value );
18807 }
18808
18809 if ( jQuery.isFunction( value ) ) {
18810 return this.each( function( i ) {
18811 jQuery( this ).toggleClass(
18812 value.call( this, i, getClass( this ), stateVal ),
18813 stateVal
18814 );
18815 } );
18816 }
18817
18818 return this.each( function() {
18819 var className, i, self, classNames;
18820
18821 if ( type === "string" ) {
18822
18823 // Toggle individual class names
18824 i = 0;
18825 self = jQuery( this );
18826 classNames = value.match( rnotwhite ) || [];
18827
18828 while ( ( className = classNames[ i++ ] ) ) {
18829
18830 // Check each className given, space separated list
18831 if ( self.hasClass( className ) ) {
18832 self.removeClass( className );
18833 } else {
18834 self.addClass( className );
18835 }
18836 }
18837
18838 // Toggle whole class name
18839 } else if ( value === undefined || type === "boolean" ) {
18840 className = getClass( this );
18841 if ( className ) {
18842
18843 // store className if set
18844 jQuery._data( this, "__className__", className );
18845 }
18846
18847 // If the element has a class name or if we're passed "false",
18848 // then remove the whole classname (if there was one, the above saved it).
18849 // Otherwise bring back whatever was previously saved (if anything),
18850 // falling back to the empty string if nothing was stored.
18851 jQuery.attr( this, "class",
18852 className || value === false ?
18853 "" :
18854 jQuery._data( this, "__className__" ) || ""
18855 );
18856 }
18857 } );
18858 },
18859
18860 hasClass: function( selector ) {
18861 var className, elem,
18862 i = 0;
18863
18864 className = " " + selector + " ";
18865 while ( ( elem = this[ i++ ] ) ) {
18866 if ( elem.nodeType === 1 &&
18867 ( " " + getClass( elem ) + " " ).replace( rclass, " " )
18868 .indexOf( className ) > -1
18869 ) {
18870 return true;
18871 }
18872 }
18873
18874 return false;
18875 }
18876 } );
18877
18878
18879
18880
18881 // Return jQuery for attributes-only inclusion
18882
18883
18884 jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
18885 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
18886 "change select submit keydown keypress keyup error contextmenu" ).split( " " ),
18887 function( i, name ) {
18888
18889 // Handle event binding
18890 jQuery.fn[ name ] = function( data, fn ) {
18891 return arguments.length > 0 ?
18892 this.on( name, null, data, fn ) :
18893 this.trigger( name );
18894 };
18895 } );
18896
18897 jQuery.fn.extend( {
18898 hover: function( fnOver, fnOut ) {
18899 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
18900 }
18901 } );
18902
18903
18904 var location = window.location;
18905
18906 var nonce = jQuery.now();
18907
18908 var rquery = ( /\?/ );
18909
18910
18911
18912 var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
18913
18914 jQuery.parseJSON = function( data ) {
18915
18916 // Attempt to parse using the native JSON parser first
18917 if ( window.JSON && window.JSON.parse ) {
18918
18919 // Support: Android 2.3
18920 // Workaround failure to string-cast null input
18921 return window.JSON.parse( data + "" );
18922 }
18923
18924 var requireNonComma,
18925 depth = null,
18926 str = jQuery.trim( data + "" );
18927
18928 // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
18929 // after removing valid tokens
18930 return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
18931
18932 // Force termination if we see a misplaced comma
18933 if ( requireNonComma && comma ) {
18934 depth = 0;
18935 }
18936
18937 // Perform no more replacements after returning to outermost depth
18938 if ( depth === 0 ) {
18939 return token;
18940 }
18941
18942 // Commas must not follow "[", "{", or ","
18943 requireNonComma = open || comma;
18944
18945 // Determine new depth
18946 // array/object open ("[" or "{"): depth += true - false (increment)
18947 // array/object close ("]" or "}"): depth += false - true (decrement)
18948 // other cases ("," or primitive): depth += true - true (numeric cast)
18949 depth += !close - !open;
18950
18951 // Remove this token
18952 return "";
18953 } ) ) ?
18954 ( Function( "return " + str ) )() :
18955 jQuery.error( "Invalid JSON: " + data );
18956 };
18957
18958
18959 // Cross-browser xml parsing
18960 jQuery.parseXML = function( data ) {
18961 var xml, tmp;
18962 if ( !data || typeof data !== "string" ) {
18963 return null;
18964 }
18965 try {
18966 if ( window.DOMParser ) { // Standard
18967 tmp = new window.DOMParser();
18968 xml = tmp.parseFromString( data, "text/xml" );
18969 } else { // IE
18970 xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
18971 xml.async = "false";
18972 xml.loadXML( data );
18973 }
18974 } catch ( e ) {
18975 xml = undefined;
18976 }
18977 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
18978 jQuery.error( "Invalid XML: " + data );
18979 }
18980 return xml;
18981 };
18982
18983
18984 var
18985 rhash = /#.*$/,
18986 rts = /([?&])_=[^&]*/,
18987
18988 // IE leaves an \r character at EOL
18989 rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
18990
18991 // #7653, #8125, #8152: local protocol detection
18992 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
18993 rnoContent = /^(?:GET|HEAD)$/,
18994 rprotocol = /^\/\//,
18995 rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
18996
18997 /* Prefilters
18998 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
18999 * 2) These are called:
19000 * - BEFORE asking for a transport
19001 * - AFTER param serialization (s.data is a string if s.processData is true)
19002 * 3) key is the dataType
19003 * 4) the catchall symbol "*" can be used
19004 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
19005 */
19006 prefilters = {},
19007
19008 /* Transports bindings
19009 * 1) key is the dataType
19010 * 2) the catchall symbol "*" can be used
19011 * 3) selection will start with transport dataType and THEN go to "*" if needed
19012 */
19013 transports = {},
19014
19015 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
19016 allTypes = "*/".concat( "*" ),
19017
19018 // Document location
19019 ajaxLocation = location.href,
19020
19021 // Segment location into parts
19022 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
19023
19024 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
19025 function addToPrefiltersOrTransports( structure ) {
19026
19027 // dataTypeExpression is optional and defaults to "*"
19028 return function( dataTypeExpression, func ) {
19029
19030 if ( typeof dataTypeExpression !== "string" ) {
19031 func = dataTypeExpression;
19032 dataTypeExpression = "*";
19033 }
19034
19035 var dataType,
19036 i = 0,
19037 dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
19038
19039 if ( jQuery.isFunction( func ) ) {
19040
19041 // For each dataType in the dataTypeExpression
19042 while ( ( dataType = dataTypes[ i++ ] ) ) {
19043
19044 // Prepend if requested
19045 if ( dataType.charAt( 0 ) === "+" ) {
19046 dataType = dataType.slice( 1 ) || "*";
19047 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
19048
19049 // Otherwise append
19050 } else {
19051 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
19052 }
19053 }
19054 }
19055 };
19056 }
19057
19058 // Base inspection function for prefilters and transports
19059 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
19060
19061 var inspected = {},
19062 seekingTransport = ( structure === transports );
19063
19064 function inspect( dataType ) {
19065 var selected;
19066 inspected[ dataType ] = true;
19067 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
19068 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
19069 if ( typeof dataTypeOrTransport === "string" &&
19070 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
19071
19072 options.dataTypes.unshift( dataTypeOrTransport );
19073 inspect( dataTypeOrTransport );
19074 return false;
19075 } else if ( seekingTransport ) {
19076 return !( selected = dataTypeOrTransport );
19077 }
19078 } );
19079 return selected;
19080 }
19081
19082 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
19083 }
19084
19085 // A special extend for ajax options
19086 // that takes "flat" options (not to be deep extended)
19087 // Fixes #9887
19088 function ajaxExtend( target, src ) {
19089 var deep, key,
19090 flatOptions = jQuery.ajaxSettings.flatOptions || {};
19091
19092 for ( key in src ) {
19093 if ( src[ key ] !== undefined ) {
19094 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
19095 }
19096 }
19097 if ( deep ) {
19098 jQuery.extend( true, target, deep );
19099 }
19100
19101 return target;
19102 }
19103
19104 /* Handles responses to an ajax request:
19105 * - finds the right dataType (mediates between content-type and expected dataType)
19106 * - returns the corresponding response
19107 */
19108 function ajaxHandleResponses( s, jqXHR, responses ) {
19109 var firstDataType, ct, finalDataType, type,
19110 contents = s.contents,
19111 dataTypes = s.dataTypes;
19112
19113 // Remove auto dataType and get content-type in the process
19114 while ( dataTypes[ 0 ] === "*" ) {
19115 dataTypes.shift();
19116 if ( ct === undefined ) {
19117 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
19118 }
19119 }
19120
19121 // Check if we're dealing with a known content-type
19122 if ( ct ) {
19123 for ( type in contents ) {
19124 if ( contents[ type ] && contents[ type ].test( ct ) ) {
19125 dataTypes.unshift( type );
19126 break;
19127 }
19128 }
19129 }
19130
19131 // Check to see if we have a response for the expected dataType
19132 if ( dataTypes[ 0 ] in responses ) {
19133 finalDataType = dataTypes[ 0 ];
19134 } else {
19135
19136 // Try convertible dataTypes
19137 for ( type in responses ) {
19138 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
19139 finalDataType = type;
19140 break;
19141 }
19142 if ( !firstDataType ) {
19143 firstDataType = type;
19144 }
19145 }
19146
19147 // Or just use first one
19148 finalDataType = finalDataType || firstDataType;
19149 }
19150
19151 // If we found a dataType
19152 // We add the dataType to the list if needed
19153 // and return the corresponding response
19154 if ( finalDataType ) {
19155 if ( finalDataType !== dataTypes[ 0 ] ) {
19156 dataTypes.unshift( finalDataType );
19157 }
19158 return responses[ finalDataType ];
19159 }
19160 }
19161
19162 /* Chain conversions given the request and the original response
19163 * Also sets the responseXXX fields on the jqXHR instance
19164 */
19165 function ajaxConvert( s, response, jqXHR, isSuccess ) {
19166 var conv2, current, conv, tmp, prev,
19167 converters = {},
19168
19169 // Work with a copy of dataTypes in case we need to modify it for conversion
19170 dataTypes = s.dataTypes.slice();
19171
19172 // Create converters map with lowercased keys
19173 if ( dataTypes[ 1 ] ) {
19174 for ( conv in s.converters ) {
19175 converters[ conv.toLowerCase() ] = s.converters[ conv ];
19176 }
19177 }
19178
19179 current = dataTypes.shift();
19180
19181 // Convert to each sequential dataType
19182 while ( current ) {
19183
19184 if ( s.responseFields[ current ] ) {
19185 jqXHR[ s.responseFields[ current ] ] = response;
19186 }
19187
19188 // Apply the dataFilter if provided
19189 if ( !prev && isSuccess && s.dataFilter ) {
19190 response = s.dataFilter( response, s.dataType );
19191 }
19192
19193 prev = current;
19194 current = dataTypes.shift();
19195
19196 if ( current ) {
19197
19198 // There's only work to do if current dataType is non-auto
19199 if ( current === "*" ) {
19200
19201 current = prev;
19202
19203 // Convert response if prev dataType is non-auto and differs from current
19204 } else if ( prev !== "*" && prev !== current ) {
19205
19206 // Seek a direct converter
19207 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
19208
19209 // If none found, seek a pair
19210 if ( !conv ) {
19211 for ( conv2 in converters ) {
19212
19213 // If conv2 outputs current
19214 tmp = conv2.split( " " );
19215 if ( tmp[ 1 ] === current ) {
19216
19217 // If prev can be converted to accepted input
19218 conv = converters[ prev + " " + tmp[ 0 ] ] ||
19219 converters[ "* " + tmp[ 0 ] ];
19220 if ( conv ) {
19221
19222 // Condense equivalence converters
19223 if ( conv === true ) {
19224 conv = converters[ conv2 ];
19225
19226 // Otherwise, insert the intermediate dataType
19227 } else if ( converters[ conv2 ] !== true ) {
19228 current = tmp[ 0 ];
19229 dataTypes.unshift( tmp[ 1 ] );
19230 }
19231 break;
19232 }
19233 }
19234 }
19235 }
19236
19237 // Apply converter (if not an equivalence)
19238 if ( conv !== true ) {
19239
19240 // Unless errors are allowed to bubble, catch and return them
19241 if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
19242 response = conv( response );
19243 } else {
19244 try {
19245 response = conv( response );
19246 } catch ( e ) {
19247 return {
19248 state: "parsererror",
19249 error: conv ? e : "No conversion from " + prev + " to " + current
19250 };
19251 }
19252 }
19253 }
19254 }
19255 }
19256 }
19257
19258 return { state: "success", data: response };
19259 }
19260
19261 jQuery.extend( {
19262
19263 // Counter for holding the number of active queries
19264 active: 0,
19265
19266 // Last-Modified header cache for next request
19267 lastModified: {},
19268 etag: {},
19269
19270 ajaxSettings: {
19271 url: ajaxLocation,
19272 type: "GET",
19273 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
19274 global: true,
19275 processData: true,
19276 async: true,
19277 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
19278 /*
19279 timeout: 0,
19280 data: null,
19281 dataType: null,
19282 username: null,
19283 password: null,
19284 cache: null,
19285 throws: false,
19286 traditional: false,
19287 headers: {},
19288 */
19289
19290 accepts: {
19291 "*": allTypes,
19292 text: "text/plain",
19293 html: "text/html",
19294 xml: "application/xml, text/xml",
19295 json: "application/json, text/javascript"
19296 },
19297
19298 contents: {
19299 xml: /\bxml\b/,
19300 html: /\bhtml/,
19301 json: /\bjson\b/
19302 },
19303
19304 responseFields: {
19305 xml: "responseXML",
19306 text: "responseText",
19307 json: "responseJSON"
19308 },
19309
19310 // Data converters
19311 // Keys separate source (or catchall "*") and destination types with a single space
19312 converters: {
19313
19314 // Convert anything to text
19315 "* text": String,
19316
19317 // Text to html (true = no transformation)
19318 "text html": true,
19319
19320 // Evaluate text as a json expression
19321 "text json": jQuery.parseJSON,
19322
19323 // Parse text as xml
19324 "text xml": jQuery.parseXML
19325 },
19326
19327 // For options that shouldn't be deep extended:
19328 // you can add your own custom options here if
19329 // and when you create one that shouldn't be
19330 // deep extended (see ajaxExtend)
19331 flatOptions: {
19332 url: true,
19333 context: true
19334 }
19335 },
19336
19337 // Creates a full fledged settings object into target
19338 // with both ajaxSettings and settings fields.
19339 // If target is omitted, writes into ajaxSettings.
19340 ajaxSetup: function( target, settings ) {
19341 return settings ?
19342
19343 // Building a settings object
19344 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
19345
19346 // Extending ajaxSettings
19347 ajaxExtend( jQuery.ajaxSettings, target );
19348 },
19349
19350 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
19351 ajaxTransport: addToPrefiltersOrTransports( transports ),
19352
19353 // Main method
19354 ajax: function( url, options ) {
19355
19356 // If url is an object, simulate pre-1.5 signature
19357 if ( typeof url === "object" ) {
19358 options = url;
19359 url = undefined;
19360 }
19361
19362 // Force options to be an object
19363 options = options || {};
19364
19365 var
19366
19367 // Cross-domain detection vars
19368 parts,
19369
19370 // Loop variable
19371 i,
19372
19373 // URL without anti-cache param
19374 cacheURL,
19375
19376 // Response headers as string
19377 responseHeadersString,
19378
19379 // timeout handle
19380 timeoutTimer,
19381
19382 // To know if global events are to be dispatched
19383 fireGlobals,
19384
19385 transport,
19386
19387 // Response headers
19388 responseHeaders,
19389
19390 // Create the final options object
19391 s = jQuery.ajaxSetup( {}, options ),
19392
19393 // Callbacks context
19394 callbackContext = s.context || s,
19395
19396 // Context for global events is callbackContext if it is a DOM node or jQuery collection
19397 globalEventContext = s.context &&
19398 ( callbackContext.nodeType || callbackContext.jquery ) ?
19399 jQuery( callbackContext ) :
19400 jQuery.event,
19401
19402 // Deferreds
19403 deferred = jQuery.Deferred(),
19404 completeDeferred = jQuery.Callbacks( "once memory" ),
19405
19406 // Status-dependent callbacks
19407 statusCode = s.statusCode || {},
19408
19409 // Headers (they are sent all at once)
19410 requestHeaders = {},
19411 requestHeadersNames = {},
19412
19413 // The jqXHR state
19414 state = 0,
19415
19416 // Default abort message
19417 strAbort = "canceled",
19418
19419 // Fake xhr
19420 jqXHR = {
19421 readyState: 0,
19422
19423 // Builds headers hashtable if needed
19424 getResponseHeader: function( key ) {
19425 var match;
19426 if ( state === 2 ) {
19427 if ( !responseHeaders ) {
19428 responseHeaders = {};
19429 while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
19430 responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
19431 }
19432 }
19433 match = responseHeaders[ key.toLowerCase() ];
19434 }
19435 return match == null ? null : match;
19436 },
19437
19438 // Raw string
19439 getAllResponseHeaders: function() {
19440 return state === 2 ? responseHeadersString : null;
19441 },
19442
19443 // Caches the header
19444 setRequestHeader: function( name, value ) {
19445 var lname = name.toLowerCase();
19446 if ( !state ) {
19447 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
19448 requestHeaders[ name ] = value;
19449 }
19450 return this;
19451 },
19452
19453 // Overrides response content-type header
19454 overrideMimeType: function( type ) {
19455 if ( !state ) {
19456 s.mimeType = type;
19457 }
19458 return this;
19459 },
19460
19461 // Status-dependent callbacks
19462 statusCode: function( map ) {
19463 var code;
19464 if ( map ) {
19465 if ( state < 2 ) {
19466 for ( code in map ) {
19467
19468 // Lazy-add the new callback in a way that preserves old ones
19469 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
19470 }
19471 } else {
19472
19473 // Execute the appropriate callbacks
19474 jqXHR.always( map[ jqXHR.status ] );
19475 }
19476 }
19477 return this;
19478 },
19479
19480 // Cancel the request
19481 abort: function( statusText ) {
19482 var finalText = statusText || strAbort;
19483 if ( transport ) {
19484 transport.abort( finalText );
19485 }
19486 done( 0, finalText );
19487 return this;
19488 }
19489 };
19490
19491 // Attach deferreds
19492 deferred.promise( jqXHR ).complete = completeDeferred.add;
19493 jqXHR.success = jqXHR.done;
19494 jqXHR.error = jqXHR.fail;
19495
19496 // Remove hash character (#7531: and string promotion)
19497 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
19498 // Handle falsy url in the settings object (#10093: consistency with old signature)
19499 // We also use the url parameter if available
19500 s.url = ( ( url || s.url || ajaxLocation ) + "" )
19501 .replace( rhash, "" )
19502 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
19503
19504 // Alias method option to type as per ticket #12004
19505 s.type = options.method || options.type || s.method || s.type;
19506
19507 // Extract dataTypes list
19508 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
19509
19510 // A cross-domain request is in order when we have a protocol:host:port mismatch
19511 if ( s.crossDomain == null ) {
19512 parts = rurl.exec( s.url.toLowerCase() );
19513 s.crossDomain = !!( parts &&
19514 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
19515 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
19516 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
19517 );
19518 }
19519
19520 // Convert data if not already a string
19521 if ( s.data && s.processData && typeof s.data !== "string" ) {
19522 s.data = jQuery.param( s.data, s.traditional );
19523 }
19524
19525 // Apply prefilters
19526 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
19527
19528 // If request was aborted inside a prefilter, stop there
19529 if ( state === 2 ) {
19530 return jqXHR;
19531 }
19532
19533 // We can fire global events as of now if asked to
19534 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
19535 fireGlobals = jQuery.event && s.global;
19536
19537 // Watch for a new set of requests
19538 if ( fireGlobals && jQuery.active++ === 0 ) {
19539 jQuery.event.trigger( "ajaxStart" );
19540 }
19541
19542 // Uppercase the type
19543 s.type = s.type.toUpperCase();
19544
19545 // Determine if request has content
19546 s.hasContent = !rnoContent.test( s.type );
19547
19548 // Save the URL in case we're toying with the If-Modified-Since
19549 // and/or If-None-Match header later on
19550 cacheURL = s.url;
19551
19552 // More options handling for requests with no content
19553 if ( !s.hasContent ) {
19554
19555 // If data is available, append data to url
19556 if ( s.data ) {
19557 cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
19558
19559 // #9682: remove data so that it's not used in an eventual retry
19560 delete s.data;
19561 }
19562
19563 // Add anti-cache in url if needed
19564 if ( s.cache === false ) {
19565 s.url = rts.test( cacheURL ) ?
19566
19567 // If there is already a '_' parameter, set its value
19568 cacheURL.replace( rts, "$1_=" + nonce++ ) :
19569
19570 // Otherwise add one to the end
19571 cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
19572 }
19573 }
19574
19575 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
19576 if ( s.ifModified ) {
19577 if ( jQuery.lastModified[ cacheURL ] ) {
19578 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
19579 }
19580 if ( jQuery.etag[ cacheURL ] ) {
19581 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
19582 }
19583 }
19584
19585 // Set the correct header, if data is being sent
19586 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
19587 jqXHR.setRequestHeader( "Content-Type", s.contentType );
19588 }
19589
19590 // Set the Accepts header for the server, depending on the dataType
19591 jqXHR.setRequestHeader(
19592 "Accept",
19593 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
19594 s.accepts[ s.dataTypes[ 0 ] ] +
19595 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
19596 s.accepts[ "*" ]
19597 );
19598
19599 // Check for headers option
19600 for ( i in s.headers ) {
19601 jqXHR.setRequestHeader( i, s.headers[ i ] );
19602 }
19603
19604 // Allow custom headers/mimetypes and early abort
19605 if ( s.beforeSend &&
19606 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
19607
19608 // Abort if not done already and return
19609 return jqXHR.abort();
19610 }
19611
19612 // aborting is no longer a cancellation
19613 strAbort = "abort";
19614
19615 // Install callbacks on deferreds
19616 for ( i in { success: 1, error: 1, complete: 1 } ) {
19617 jqXHR[ i ]( s[ i ] );
19618 }
19619
19620 // Get transport
19621 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
19622
19623 // If no transport, we auto-abort
19624 if ( !transport ) {
19625 done( -1, "No Transport" );
19626 } else {
19627 jqXHR.readyState = 1;
19628
19629 // Send global event
19630 if ( fireGlobals ) {
19631 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
19632 }
19633
19634 // If request was aborted inside ajaxSend, stop there
19635 if ( state === 2 ) {
19636 return jqXHR;
19637 }
19638
19639 // Timeout
19640 if ( s.async && s.timeout > 0 ) {
19641 timeoutTimer = window.setTimeout( function() {
19642 jqXHR.abort( "timeout" );
19643 }, s.timeout );
19644 }
19645
19646 try {
19647 state = 1;
19648 transport.send( requestHeaders, done );
19649 } catch ( e ) {
19650
19651 // Propagate exception as error if not done
19652 if ( state < 2 ) {
19653 done( -1, e );
19654
19655 // Simply rethrow otherwise
19656 } else {
19657 throw e;
19658 }
19659 }
19660 }
19661
19662 // Callback for when everything is done
19663 function done( status, nativeStatusText, responses, headers ) {
19664 var isSuccess, success, error, response, modified,
19665 statusText = nativeStatusText;
19666
19667 // Called once
19668 if ( state === 2 ) {
19669 return;
19670 }
19671
19672 // State is "done" now
19673 state = 2;
19674
19675 // Clear timeout if it exists
19676 if ( timeoutTimer ) {
19677 window.clearTimeout( timeoutTimer );
19678 }
19679
19680 // Dereference transport for early garbage collection
19681 // (no matter how long the jqXHR object will be used)
19682 transport = undefined;
19683
19684 // Cache response headers
19685 responseHeadersString = headers || "";
19686
19687 // Set readyState
19688 jqXHR.readyState = status > 0 ? 4 : 0;
19689
19690 // Determine if successful
19691 isSuccess = status >= 200 && status < 300 || status === 304;
19692
19693 // Get response data
19694 if ( responses ) {
19695 response = ajaxHandleResponses( s, jqXHR, responses );
19696 }
19697
19698 // Convert no matter what (that way responseXXX fields are always set)
19699 response = ajaxConvert( s, response, jqXHR, isSuccess );
19700
19701 // If successful, handle type chaining
19702 if ( isSuccess ) {
19703
19704 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
19705 if ( s.ifModified ) {
19706 modified = jqXHR.getResponseHeader( "Last-Modified" );
19707 if ( modified ) {
19708 jQuery.lastModified[ cacheURL ] = modified;
19709 }
19710 modified = jqXHR.getResponseHeader( "etag" );
19711 if ( modified ) {
19712 jQuery.etag[ cacheURL ] = modified;
19713 }
19714 }
19715
19716 // if no content
19717 if ( status === 204 || s.type === "HEAD" ) {
19718 statusText = "nocontent";
19719
19720 // if not modified
19721 } else if ( status === 304 ) {
19722 statusText = "notmodified";
19723
19724 // If we have data, let's convert it
19725 } else {
19726 statusText = response.state;
19727 success = response.data;
19728 error = response.error;
19729 isSuccess = !error;
19730 }
19731 } else {
19732
19733 // We extract error from statusText
19734 // then normalize statusText and status for non-aborts
19735 error = statusText;
19736 if ( status || !statusText ) {
19737 statusText = "error";
19738 if ( status < 0 ) {
19739 status = 0;
19740 }
19741 }
19742 }
19743
19744 // Set data for the fake xhr object
19745 jqXHR.status = status;
19746 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
19747
19748 // Success/Error
19749 if ( isSuccess ) {
19750 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
19751 } else {
19752 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
19753 }
19754
19755 // Status-dependent callbacks
19756 jqXHR.statusCode( statusCode );
19757 statusCode = undefined;
19758
19759 if ( fireGlobals ) {
19760 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
19761 [ jqXHR, s, isSuccess ? success : error ] );
19762 }
19763
19764 // Complete
19765 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
19766
19767 if ( fireGlobals ) {
19768 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
19769
19770 // Handle the global AJAX counter
19771 if ( !( --jQuery.active ) ) {
19772 jQuery.event.trigger( "ajaxStop" );
19773 }
19774 }
19775 }
19776
19777 return jqXHR;
19778 },
19779
19780 getJSON: function( url, data, callback ) {
19781 return jQuery.get( url, data, callback, "json" );
19782 },
19783
19784 getScript: function( url, callback ) {
19785 return jQuery.get( url, undefined, callback, "script" );
19786 }
19787 } );
19788
19789 jQuery.each( [ "get", "post" ], function( i, method ) {
19790 jQuery[ method ] = function( url, data, callback, type ) {
19791
19792 // shift arguments if data argument was omitted
19793 if ( jQuery.isFunction( data ) ) {
19794 type = type || callback;
19795 callback = data;
19796 data = undefined;
19797 }
19798
19799 // The url can be an options object (which then must have .url)
19800 return jQuery.ajax( jQuery.extend( {
19801 url: url,
19802 type: method,
19803 dataType: type,
19804 data: data,
19805 success: callback
19806 }, jQuery.isPlainObject( url ) && url ) );
19807 };
19808 } );
19809
19810
19811 jQuery._evalUrl = function( url ) {
19812 return jQuery.ajax( {
19813 url: url,
19814
19815 // Make this explicit, since user can override this through ajaxSetup (#11264)
19816 type: "GET",
19817 dataType: "script",
19818 cache: true,
19819 async: false,
19820 global: false,
19821 "throws": true
19822 } );
19823 };
19824
19825
19826 jQuery.fn.extend( {
19827 wrapAll: function( html ) {
19828 if ( jQuery.isFunction( html ) ) {
19829 return this.each( function( i ) {
19830 jQuery( this ).wrapAll( html.call( this, i ) );
19831 } );
19832 }
19833
19834 if ( this[ 0 ] ) {
19835
19836 // The elements to wrap the target around
19837 var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
19838
19839 if ( this[ 0 ].parentNode ) {
19840 wrap.insertBefore( this[ 0 ] );
19841 }
19842
19843 wrap.map( function() {
19844 var elem = this;
19845
19846 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
19847 elem = elem.firstChild;
19848 }
19849
19850 return elem;
19851 } ).append( this );
19852 }
19853
19854 return this;
19855 },
19856
19857 wrapInner: function( html ) {
19858 if ( jQuery.isFunction( html ) ) {
19859 return this.each( function( i ) {
19860 jQuery( this ).wrapInner( html.call( this, i ) );
19861 } );
19862 }
19863
19864 return this.each( function() {
19865 var self = jQuery( this ),
19866 contents = self.contents();
19867
19868 if ( contents.length ) {
19869 contents.wrapAll( html );
19870
19871 } else {
19872 self.append( html );
19873 }
19874 } );
19875 },
19876
19877 wrap: function( html ) {
19878 var isFunction = jQuery.isFunction( html );
19879
19880 return this.each( function( i ) {
19881 jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
19882 } );
19883 },
19884
19885 unwrap: function() {
19886 return this.parent().each( function() {
19887 if ( !jQuery.nodeName( this, "body" ) ) {
19888 jQuery( this ).replaceWith( this.childNodes );
19889 }
19890 } ).end();
19891 }
19892 } );
19893
19894
19895 function getDisplay( elem ) {
19896 return elem.style && elem.style.display || jQuery.css( elem, "display" );
19897 }
19898
19899 function filterHidden( elem ) {
19900
19901 // Disconnected elements are considered hidden
19902 if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
19903 return true;
19904 }
19905 while ( elem && elem.nodeType === 1 ) {
19906 if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
19907 return true;
19908 }
19909 elem = elem.parentNode;
19910 }
19911 return false;
19912 }
19913
19914 jQuery.expr.filters.hidden = function( elem ) {
19915
19916 // Support: Opera <= 12.12
19917 // Opera reports offsetWidths and offsetHeights less than zero on some elements
19918 return support.reliableHiddenOffsets() ?
19919 ( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
19920 !elem.getClientRects().length ) :
19921 filterHidden( elem );
19922 };
19923
19924 jQuery.expr.filters.visible = function( elem ) {
19925 return !jQuery.expr.filters.hidden( elem );
19926 };
19927
19928
19929
19930
19931 var r20 = /%20/g,
19932 rbracket = /\[\]$/,
19933 rCRLF = /\r?\n/g,
19934 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
19935 rsubmittable = /^(?:input|select|textarea|keygen)/i;
19936
19937 function buildParams( prefix, obj, traditional, add ) {
19938 var name;
19939
19940 if ( jQuery.isArray( obj ) ) {
19941
19942 // Serialize array item.
19943 jQuery.each( obj, function( i, v ) {
19944 if ( traditional || rbracket.test( prefix ) ) {
19945
19946 // Treat each array item as a scalar.
19947 add( prefix, v );
19948
19949 } else {
19950
19951 // Item is non-scalar (array or object), encode its numeric index.
19952 buildParams(
19953 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
19954 v,
19955 traditional,
19956 add
19957 );
19958 }
19959 } );
19960
19961 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
19962
19963 // Serialize object item.
19964 for ( name in obj ) {
19965 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
19966 }
19967
19968 } else {
19969
19970 // Serialize scalar item.
19971 add( prefix, obj );
19972 }
19973 }
19974
19975 // Serialize an array of form elements or a set of
19976 // key/values into a query string
19977 jQuery.param = function( a, traditional ) {
19978 var prefix,
19979 s = [],
19980 add = function( key, value ) {
19981
19982 // If value is a function, invoke it and return its value
19983 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
19984 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
19985 };
19986
19987 // Set traditional to true for jQuery <= 1.3.2 behavior.
19988 if ( traditional === undefined ) {
19989 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
19990 }
19991
19992 // If an array was passed in, assume that it is an array of form elements.
19993 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
19994
19995 // Serialize the form elements
19996 jQuery.each( a, function() {
19997 add( this.name, this.value );
19998 } );
19999
20000 } else {
20001
20002 // If traditional, encode the "old" way (the way 1.3.2 or older
20003 // did it), otherwise encode params recursively.
20004 for ( prefix in a ) {
20005 buildParams( prefix, a[ prefix ], traditional, add );
20006 }
20007 }
20008
20009 // Return the resulting serialization
20010 return s.join( "&" ).replace( r20, "+" );
20011 };
20012
20013 jQuery.fn.extend( {
20014 serialize: function() {
20015 return jQuery.param( this.serializeArray() );
20016 },
20017 serializeArray: function() {
20018 return this.map( function() {
20019
20020 // Can add propHook for "elements" to filter or add form elements
20021 var elements = jQuery.prop( this, "elements" );
20022 return elements ? jQuery.makeArray( elements ) : this;
20023 } )
20024 .filter( function() {
20025 var type = this.type;
20026
20027 // Use .is(":disabled") so that fieldset[disabled] works
20028 return this.name && !jQuery( this ).is( ":disabled" ) &&
20029 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
20030 ( this.checked || !rcheckableType.test( type ) );
20031 } )
20032 .map( function( i, elem ) {
20033 var val = jQuery( this ).val();
20034
20035 return val == null ?
20036 null :
20037 jQuery.isArray( val ) ?
20038 jQuery.map( val, function( val ) {
20039 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
20040 } ) :
20041 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
20042 } ).get();
20043 }
20044 } );
20045
20046
20047 // Create the request object
20048 // (This is still attached to ajaxSettings for backward compatibility)
20049 jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
20050
20051 // Support: IE6-IE8
20052 function() {
20053
20054 // XHR cannot access local files, always use ActiveX for that case
20055 if ( this.isLocal ) {
20056 return createActiveXHR();
20057 }
20058
20059 // Support: IE 9-11
20060 // IE seems to error on cross-domain PATCH requests when ActiveX XHR
20061 // is used. In IE 9+ always use the native XHR.
20062 // Note: this condition won't catch Edge as it doesn't define
20063 // document.documentMode but it also doesn't support ActiveX so it won't
20064 // reach this code.
20065 if ( document.documentMode > 8 ) {
20066 return createStandardXHR();
20067 }
20068
20069 // Support: IE<9
20070 // oldIE XHR does not support non-RFC2616 methods (#13240)
20071 // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
20072 // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
20073 // Although this check for six methods instead of eight
20074 // since IE also does not support "trace" and "connect"
20075 return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
20076 createStandardXHR() || createActiveXHR();
20077 } :
20078
20079 // For all other browsers, use the standard XMLHttpRequest object
20080 createStandardXHR;
20081
20082 var xhrId = 0,
20083 xhrCallbacks = {},
20084 xhrSupported = jQuery.ajaxSettings.xhr();
20085
20086 // Support: IE<10
20087 // Open requests must be manually aborted on unload (#5280)
20088 // See https://support.microsoft.com/kb/2856746 for more info
20089 if ( window.attachEvent ) {
20090 window.attachEvent( "onunload", function() {
20091 for ( var key in xhrCallbacks ) {
20092 xhrCallbacks[ key ]( undefined, true );
20093 }
20094 } );
20095 }
20096
20097 // Determine support properties
20098 support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
20099 xhrSupported = support.ajax = !!xhrSupported;
20100
20101 // Create transport if the browser can provide an xhr
20102 if ( xhrSupported ) {
20103
20104 jQuery.ajaxTransport( function( options ) {
20105
20106 // Cross domain only allowed if supported through XMLHttpRequest
20107 if ( !options.crossDomain || support.cors ) {
20108
20109 var callback;
20110
20111 return {
20112 send: function( headers, complete ) {
20113 var i,
20114 xhr = options.xhr(),
20115 id = ++xhrId;
20116
20117 // Open the socket
20118 xhr.open(
20119 options.type,
20120 options.url,
20121 options.async,
20122 options.username,
20123 options.password
20124 );
20125
20126 // Apply custom fields if provided
20127 if ( options.xhrFields ) {
20128 for ( i in options.xhrFields ) {
20129 xhr[ i ] = options.xhrFields[ i ];
20130 }
20131 }
20132
20133 // Override mime type if needed
20134 if ( options.mimeType && xhr.overrideMimeType ) {
20135 xhr.overrideMimeType( options.mimeType );
20136 }
20137
20138 // X-Requested-With header
20139 // For cross-domain requests, seeing as conditions for a preflight are
20140 // akin to a jigsaw puzzle, we simply never set it to be sure.
20141 // (it can always be set on a per-request basis or even using ajaxSetup)
20142 // For same-domain requests, won't change header if already provided.
20143 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
20144 headers[ "X-Requested-With" ] = "XMLHttpRequest";
20145 }
20146
20147 // Set headers
20148 for ( i in headers ) {
20149
20150 // Support: IE<9
20151 // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
20152 // request header to a null-value.
20153 //
20154 // To keep consistent with other XHR implementations, cast the value
20155 // to string and ignore `undefined`.
20156 if ( headers[ i ] !== undefined ) {
20157 xhr.setRequestHeader( i, headers[ i ] + "" );
20158 }
20159 }
20160
20161 // Do send the request
20162 // This may raise an exception which is actually
20163 // handled in jQuery.ajax (so no try/catch here)
20164 xhr.send( ( options.hasContent && options.data ) || null );
20165
20166 // Listener
20167 callback = function( _, isAbort ) {
20168 var status, statusText, responses;
20169
20170 // Was never called and is aborted or complete
20171 if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
20172
20173 // Clean up
20174 delete xhrCallbacks[ id ];
20175 callback = undefined;
20176 xhr.onreadystatechange = jQuery.noop;
20177
20178 // Abort manually if needed
20179 if ( isAbort ) {
20180 if ( xhr.readyState !== 4 ) {
20181 xhr.abort();
20182 }
20183 } else {
20184 responses = {};
20185 status = xhr.status;
20186
20187 // Support: IE<10
20188 // Accessing binary-data responseText throws an exception
20189 // (#11426)
20190 if ( typeof xhr.responseText === "string" ) {
20191 responses.text = xhr.responseText;
20192 }
20193
20194 // Firefox throws an exception when accessing
20195 // statusText for faulty cross-domain requests
20196 try {
20197 statusText = xhr.statusText;
20198 } catch ( e ) {
20199
20200 // We normalize with Webkit giving an empty statusText
20201 statusText = "";
20202 }
20203
20204 // Filter status for non standard behaviors
20205
20206 // If the request is local and we have data: assume a success
20207 // (success with no data won't get notified, that's the best we
20208 // can do given current implementations)
20209 if ( !status && options.isLocal && !options.crossDomain ) {
20210 status = responses.text ? 200 : 404;
20211
20212 // IE - #1450: sometimes returns 1223 when it should be 204
20213 } else if ( status === 1223 ) {
20214 status = 204;
20215 }
20216 }
20217 }
20218
20219 // Call complete if needed
20220 if ( responses ) {
20221 complete( status, statusText, responses, xhr.getAllResponseHeaders() );
20222 }
20223 };
20224
20225 // Do send the request
20226 // `xhr.send` may raise an exception, but it will be
20227 // handled in jQuery.ajax (so no try/catch here)
20228 if ( !options.async ) {
20229
20230 // If we're in sync mode we fire the callback
20231 callback();
20232 } else if ( xhr.readyState === 4 ) {
20233
20234 // (IE6 & IE7) if it's in cache and has been
20235 // retrieved directly we need to fire the callback
20236 window.setTimeout( callback );
20237 } else {
20238
20239 // Register the callback, but delay it in case `xhr.send` throws
20240 // Add to the list of active xhr callbacks
20241 xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
20242 }
20243 },
20244
20245 abort: function() {
20246 if ( callback ) {
20247 callback( undefined, true );
20248 }
20249 }
20250 };
20251 }
20252 } );
20253 }
20254
20255 // Functions to create xhrs
20256 function createStandardXHR() {
20257 try {
20258 return new window.XMLHttpRequest();
20259 } catch ( e ) {}
20260 }
20261
20262 function createActiveXHR() {
20263 try {
20264 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
20265 } catch ( e ) {}
20266 }
20267
20268
20269
20270
20271 // Install script dataType
20272 jQuery.ajaxSetup( {
20273 accepts: {
20274 script: "text/javascript, application/javascript, " +
20275 "application/ecmascript, application/x-ecmascript"
20276 },
20277 contents: {
20278 script: /\b(?:java|ecma)script\b/
20279 },
20280 converters: {
20281 "text script": function( text ) {
20282 jQuery.globalEval( text );
20283 return text;
20284 }
20285 }
20286 } );
20287
20288 // Handle cache's special case and global
20289 jQuery.ajaxPrefilter( "script", function( s ) {
20290 if ( s.cache === undefined ) {
20291 s.cache = false;
20292 }
20293 if ( s.crossDomain ) {
20294 s.type = "GET";
20295 s.global = false;
20296 }
20297 } );
20298
20299 // Bind script tag hack transport
20300 jQuery.ajaxTransport( "script", function( s ) {
20301
20302 // This transport only deals with cross domain requests
20303 if ( s.crossDomain ) {
20304
20305 var script,
20306 head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
20307
20308 return {
20309
20310 send: function( _, callback ) {
20311
20312 script = document.createElement( "script" );
20313
20314 script.async = true;
20315
20316 if ( s.scriptCharset ) {
20317 script.charset = s.scriptCharset;
20318 }
20319
20320 script.src = s.url;
20321
20322 // Attach handlers for all browsers
20323 script.onload = script.onreadystatechange = function( _, isAbort ) {
20324
20325 if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
20326
20327 // Handle memory leak in IE
20328 script.onload = script.onreadystatechange = null;
20329
20330 // Remove the script
20331 if ( script.parentNode ) {
20332 script.parentNode.removeChild( script );
20333 }
20334
20335 // Dereference the script
20336 script = null;
20337
20338 // Callback if not abort
20339 if ( !isAbort ) {
20340 callback( 200, "success" );
20341 }
20342 }
20343 };
20344
20345 // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
20346 // Use native DOM manipulation to avoid our domManip AJAX trickery
20347 head.insertBefore( script, head.firstChild );
20348 },
20349
20350 abort: function() {
20351 if ( script ) {
20352 script.onload( undefined, true );
20353 }
20354 }
20355 };
20356 }
20357 } );
20358
20359
20360
20361
20362 var oldCallbacks = [],
20363 rjsonp = /(=)\?(?=&|$)|\?\?/;
20364
20365 // Default jsonp settings
20366 jQuery.ajaxSetup( {
20367 jsonp: "callback",
20368 jsonpCallback: function() {
20369 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
20370 this[ callback ] = true;
20371 return callback;
20372 }
20373 } );
20374
20375 // Detect, normalize options and install callbacks for jsonp requests
20376 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
20377
20378 var callbackName, overwritten, responseContainer,
20379 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
20380 "url" :
20381 typeof s.data === "string" &&
20382 ( s.contentType || "" )
20383 .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
20384 rjsonp.test( s.data ) && "data"
20385 );
20386
20387 // Handle iff the expected data type is "jsonp" or we have a parameter to set
20388 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
20389
20390 // Get callback name, remembering preexisting value associated with it
20391 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
20392 s.jsonpCallback() :
20393 s.jsonpCallback;
20394
20395 // Insert callback into url or form data
20396 if ( jsonProp ) {
20397 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
20398 } else if ( s.jsonp !== false ) {
20399 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
20400 }
20401
20402 // Use data converter to retrieve json after script execution
20403 s.converters[ "script json" ] = function() {
20404 if ( !responseContainer ) {
20405 jQuery.error( callbackName + " was not called" );
20406 }
20407 return responseContainer[ 0 ];
20408 };
20409
20410 // force json dataType
20411 s.dataTypes[ 0 ] = "json";
20412
20413 // Install callback
20414 overwritten = window[ callbackName ];
20415 window[ callbackName ] = function() {
20416 responseContainer = arguments;
20417 };
20418
20419 // Clean-up function (fires after converters)
20420 jqXHR.always( function() {
20421
20422 // If previous value didn't exist - remove it
20423 if ( overwritten === undefined ) {
20424 jQuery( window ).removeProp( callbackName );
20425
20426 // Otherwise restore preexisting value
20427 } else {
20428 window[ callbackName ] = overwritten;
20429 }
20430
20431 // Save back as free
20432 if ( s[ callbackName ] ) {
20433
20434 // make sure that re-using the options doesn't screw things around
20435 s.jsonpCallback = originalSettings.jsonpCallback;
20436
20437 // save the callback name for future use
20438 oldCallbacks.push( callbackName );
20439 }
20440
20441 // Call if it was a function and we have a response
20442 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
20443 overwritten( responseContainer[ 0 ] );
20444 }
20445
20446 responseContainer = overwritten = undefined;
20447 } );
20448
20449 // Delegate to script
20450 return "script";
20451 }
20452 } );
20453
20454
20455
20456
20457 // data: string of html
20458 // context (optional): If specified, the fragment will be created in this context,
20459 // defaults to document
20460 // keepScripts (optional): If true, will include scripts passed in the html string
20461 jQuery.parseHTML = function( data, context, keepScripts ) {
20462 if ( !data || typeof data !== "string" ) {
20463 return null;
20464 }
20465 if ( typeof context === "boolean" ) {
20466 keepScripts = context;
20467 context = false;
20468 }
20469 context = context || document;
20470
20471 var parsed = rsingleTag.exec( data ),
20472 scripts = !keepScripts && [];
20473
20474 // Single tag
20475 if ( parsed ) {
20476 return [ context.createElement( parsed[ 1 ] ) ];
20477 }
20478
20479 parsed = buildFragment( [ data ], context, scripts );
20480
20481 if ( scripts && scripts.length ) {
20482 jQuery( scripts ).remove();
20483 }
20484
20485 return jQuery.merge( [], parsed.childNodes );
20486 };
20487
20488
20489 // Keep a copy of the old load method
20490 var _load = jQuery.fn.load;
20491
20492 /**
20493 * Load a url into a page
20494 */
20495 jQuery.fn.load = function( url, params, callback ) {
20496 if ( typeof url !== "string" && _load ) {
20497 return _load.apply( this, arguments );
20498 }
20499
20500 var selector, type, response,
20501 self = this,
20502 off = url.indexOf( " " );
20503
20504 if ( off > -1 ) {
20505 selector = jQuery.trim( url.slice( off, url.length ) );
20506 url = url.slice( 0, off );
20507 }
20508
20509 // If it's a function
20510 if ( jQuery.isFunction( params ) ) {
20511
20512 // We assume that it's the callback
20513 callback = params;
20514 params = undefined;
20515
20516 // Otherwise, build a param string
20517 } else if ( params && typeof params === "object" ) {
20518 type = "POST";
20519 }
20520
20521 // If we have elements to modify, make the request
20522 if ( self.length > 0 ) {
20523 jQuery.ajax( {
20524 url: url,
20525
20526 // If "type" variable is undefined, then "GET" method will be used.
20527 // Make value of this field explicit since
20528 // user can override it through ajaxSetup method
20529 type: type || "GET",
20530 dataType: "html",
20531 data: params
20532 } ).done( function( responseText ) {
20533
20534 // Save response for use in complete callback
20535 response = arguments;
20536
20537 self.html( selector ?
20538
20539 // If a selector was specified, locate the right elements in a dummy div
20540 // Exclude scripts to avoid IE 'Permission Denied' errors
20541 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
20542
20543 // Otherwise use the full result
20544 responseText );
20545
20546 // If the request succeeds, this function gets "data", "status", "jqXHR"
20547 // but they are ignored because response was set above.
20548 // If it fails, this function gets "jqXHR", "status", "error"
20549 } ).always( callback && function( jqXHR, status ) {
20550 self.each( function() {
20551 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
20552 } );
20553 } );
20554 }
20555
20556 return this;
20557 };
20558
20559
20560
20561
20562 // Attach a bunch of functions for handling common AJAX events
20563 jQuery.each( [
20564 "ajaxStart",
20565 "ajaxStop",
20566 "ajaxComplete",
20567 "ajaxError",
20568 "ajaxSuccess",
20569 "ajaxSend"
20570 ], function( i, type ) {
20571 jQuery.fn[ type ] = function( fn ) {
20572 return this.on( type, fn );
20573 };
20574 } );
20575
20576
20577
20578
20579 jQuery.expr.filters.animated = function( elem ) {
20580 return jQuery.grep( jQuery.timers, function( fn ) {
20581 return elem === fn.elem;
20582 } ).length;
20583 };
20584
20585
20586
20587
20588
20589 /**
20590 * Gets a window from an element
20591 */
20592 function getWindow( elem ) {
20593 return jQuery.isWindow( elem ) ?
20594 elem :
20595 elem.nodeType === 9 ?
20596 elem.defaultView || elem.parentWindow :
20597 false;
20598 }
20599
20600 jQuery.offset = {
20601 setOffset: function( elem, options, i ) {
20602 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
20603 position = jQuery.css( elem, "position" ),
20604 curElem = jQuery( elem ),
20605 props = {};
20606
20607 // set position first, in-case top/left are set even on static elem
20608 if ( position === "static" ) {
20609 elem.style.position = "relative";
20610 }
20611
20612 curOffset = curElem.offset();
20613 curCSSTop = jQuery.css( elem, "top" );
20614 curCSSLeft = jQuery.css( elem, "left" );
20615 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
20616 jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
20617
20618 // need to be able to calculate position if either top or left
20619 // is auto and position is either absolute or fixed
20620 if ( calculatePosition ) {
20621 curPosition = curElem.position();
20622 curTop = curPosition.top;
20623 curLeft = curPosition.left;
20624 } else {
20625 curTop = parseFloat( curCSSTop ) || 0;
20626 curLeft = parseFloat( curCSSLeft ) || 0;
20627 }
20628
20629 if ( jQuery.isFunction( options ) ) {
20630
20631 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
20632 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
20633 }
20634
20635 if ( options.top != null ) {
20636 props.top = ( options.top - curOffset.top ) + curTop;
20637 }
20638 if ( options.left != null ) {
20639 props.left = ( options.left - curOffset.left ) + curLeft;
20640 }
20641
20642 if ( "using" in options ) {
20643 options.using.call( elem, props );
20644 } else {
20645 curElem.css( props );
20646 }
20647 }
20648 };
20649
20650 jQuery.fn.extend( {
20651 offset: function( options ) {
20652 if ( arguments.length ) {
20653 return options === undefined ?
20654 this :
20655 this.each( function( i ) {
20656 jQuery.offset.setOffset( this, options, i );
20657 } );
20658 }
20659
20660 var docElem, win,
20661 box = { top: 0, left: 0 },
20662 elem = this[ 0 ],
20663 doc = elem && elem.ownerDocument;
20664
20665 if ( !doc ) {
20666 return;
20667 }
20668
20669 docElem = doc.documentElement;
20670
20671 // Make sure it's not a disconnected DOM node
20672 if ( !jQuery.contains( docElem, elem ) ) {
20673 return box;
20674 }
20675
20676 // If we don't have gBCR, just use 0,0 rather than error
20677 // BlackBerry 5, iOS 3 (original iPhone)
20678 if ( typeof elem.getBoundingClientRect !== "undefined" ) {
20679 box = elem.getBoundingClientRect();
20680 }
20681 win = getWindow( doc );
20682 return {
20683 top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
20684 left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
20685 };
20686 },
20687
20688 position: function() {
20689 if ( !this[ 0 ] ) {
20690 return;
20691 }
20692
20693 var offsetParent, offset,
20694 parentOffset = { top: 0, left: 0 },
20695 elem = this[ 0 ];
20696
20697 // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
20698 // because it is its only offset parent
20699 if ( jQuery.css( elem, "position" ) === "fixed" ) {
20700
20701 // we assume that getBoundingClientRect is available when computed position is fixed
20702 offset = elem.getBoundingClientRect();
20703 } else {
20704
20705 // Get *real* offsetParent
20706 offsetParent = this.offsetParent();
20707
20708 // Get correct offsets
20709 offset = this.offset();
20710 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
20711 parentOffset = offsetParent.offset();
20712 }
20713
20714 // Add offsetParent borders
20715 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
20716 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
20717 }
20718
20719 // Subtract parent offsets and element margins
20720 // note: when an element has margin: auto the offsetLeft and marginLeft
20721 // are the same in Safari causing offset.left to incorrectly be 0
20722 return {
20723 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
20724 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
20725 };
20726 },
20727
20728 offsetParent: function() {
20729 return this.map( function() {
20730 var offsetParent = this.offsetParent;
20731
20732 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
20733 jQuery.css( offsetParent, "position" ) === "static" ) ) {
20734 offsetParent = offsetParent.offsetParent;
20735 }
20736 return offsetParent || documentElement;
20737 } );
20738 }
20739 } );
20740
20741 // Create scrollLeft and scrollTop methods
20742 jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
20743 var top = /Y/.test( prop );
20744
20745 jQuery.fn[ method ] = function( val ) {
20746 return access( this, function( elem, method, val ) {
20747 var win = getWindow( elem );
20748
20749 if ( val === undefined ) {
20750 return win ? ( prop in win ) ? win[ prop ] :
20751 win.document.documentElement[ method ] :
20752 elem[ method ];
20753 }
20754
20755 if ( win ) {
20756 win.scrollTo(
20757 !top ? val : jQuery( win ).scrollLeft(),
20758 top ? val : jQuery( win ).scrollTop()
20759 );
20760
20761 } else {
20762 elem[ method ] = val;
20763 }
20764 }, method, val, arguments.length, null );
20765 };
20766 } );
20767
20768 // Support: Safari<7-8+, Chrome<37-44+
20769 // Add the top/left cssHooks using jQuery.fn.position
20770 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
20771 // getComputedStyle returns percent when specified for top/left/bottom/right
20772 // rather than make the css module depend on the offset module, we just check for it here
20773 jQuery.each( [ "top", "left" ], function( i, prop ) {
20774 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
20775 function( elem, computed ) {
20776 if ( computed ) {
20777 computed = curCSS( elem, prop );
20778
20779 // if curCSS returns percentage, fallback to offset
20780 return rnumnonpx.test( computed ) ?
20781 jQuery( elem ).position()[ prop ] + "px" :
20782 computed;
20783 }
20784 }
20785 );
20786 } );
20787
20788
20789 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
20790 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
20791 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
20792 function( defaultExtra, funcName ) {
20793
20794 // margin is only for outerHeight, outerWidth
20795 jQuery.fn[ funcName ] = function( margin, value ) {
20796 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
20797 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
20798
20799 return access( this, function( elem, type, value ) {
20800 var doc;
20801
20802 if ( jQuery.isWindow( elem ) ) {
20803
20804 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
20805 // isn't a whole lot we can do. See pull request at this URL for discussion:
20806 // https://github.com/jquery/jquery/pull/764
20807 return elem.document.documentElement[ "client" + name ];
20808 }
20809
20810 // Get document width or height
20811 if ( elem.nodeType === 9 ) {
20812 doc = elem.documentElement;
20813
20814 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
20815 // whichever is greatest
20816 // unfortunately, this causes bug #3838 in IE6/8 only,
20817 // but there is currently no good, small way to fix it.
20818 return Math.max(
20819 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
20820 elem.body[ "offset" + name ], doc[ "offset" + name ],
20821 doc[ "client" + name ]
20822 );
20823 }
20824
20825 return value === undefined ?
20826
20827 // Get width or height on the element, requesting but not forcing parseFloat
20828 jQuery.css( elem, type, extra ) :
20829
20830 // Set width or height on the element
20831 jQuery.style( elem, type, value, extra );
20832 }, type, chainable ? margin : undefined, chainable, null );
20833 };
20834 } );
20835 } );
20836
20837
20838 jQuery.fn.extend( {
20839
20840 bind: function( types, data, fn ) {
20841 return this.on( types, null, data, fn );
20842 },
20843 unbind: function( types, fn ) {
20844 return this.off( types, null, fn );
20845 },
20846
20847 delegate: function( selector, types, data, fn ) {
20848 return this.on( types, selector, data, fn );
20849 },
20850 undelegate: function( selector, types, fn ) {
20851
20852 // ( namespace ) or ( selector, types [, fn] )
20853 return arguments.length === 1 ?
20854 this.off( selector, "**" ) :
20855 this.off( types, selector || "**", fn );
20856 }
20857 } );
20858
20859 // The number of elements contained in the matched element set
20860 jQuery.fn.size = function() {
20861 return this.length;
20862 };
20863
20864 jQuery.fn.andSelf = jQuery.fn.addBack;
20865
20866
20867
20868 var
20869
20870 // Map over jQuery in case of overwrite
20871 _jQuery = window.jQuery,
20872
20873 // Map over the $ in case of overwrite
20874 _$ = window.$;
20875
20876 jQuery.noConflict = function( deep ) {
20877 if ( window.$ === jQuery ) {
20878 window.$ = _$;
20879 }
20880
20881 if ( deep && window.jQuery === jQuery ) {
20882 window.jQuery = _jQuery;
20883 }
20884
20885 return jQuery;
20886 };
20887
20888 // Expose jQuery and $ identifiers, even in
20889 // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
20890 // and CommonJS for browser emulators (#13566)
20891 if ( !noGlobal ) {
20892 window.jQuery = window.$ = jQuery;
20893 }
20894
20895 return jQuery;
20896 }));
20897 });
20898
20899 var lodash = createCommonjsModule(function (module, exports) {
20900 (function() {
20901
20902 /** Used as a safe reference for `undefined` in pre-ES5 environments. */
20903 var undefined$1;
20904
20905 /** Used as the semantic version number. */
20906 var VERSION = '4.17.15';
20907
20908 /** Used as the size to enable large array optimizations. */
20909 var LARGE_ARRAY_SIZE = 200;
20910
20911 /** Error message constants. */
20912 var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
20913 FUNC_ERROR_TEXT = 'Expected a function';
20914
20915 /** Used to stand-in for `undefined` hash values. */
20916 var HASH_UNDEFINED = '__lodash_hash_undefined__';
20917
20918 /** Used as the maximum memoize cache size. */
20919 var MAX_MEMOIZE_SIZE = 500;
20920
20921 /** Used as the internal argument placeholder. */
20922 var PLACEHOLDER = '__lodash_placeholder__';
20923
20924 /** Used to compose bitmasks for cloning. */
20925 var CLONE_DEEP_FLAG = 1,
20926 CLONE_FLAT_FLAG = 2,
20927 CLONE_SYMBOLS_FLAG = 4;
20928
20929 /** Used to compose bitmasks for value comparisons. */
20930 var COMPARE_PARTIAL_FLAG = 1,
20931 COMPARE_UNORDERED_FLAG = 2;
20932
20933 /** Used to compose bitmasks for function metadata. */
20934 var WRAP_BIND_FLAG = 1,
20935 WRAP_BIND_KEY_FLAG = 2,
20936 WRAP_CURRY_BOUND_FLAG = 4,
20937 WRAP_CURRY_FLAG = 8,
20938 WRAP_CURRY_RIGHT_FLAG = 16,
20939 WRAP_PARTIAL_FLAG = 32,
20940 WRAP_PARTIAL_RIGHT_FLAG = 64,
20941 WRAP_ARY_FLAG = 128,
20942 WRAP_REARG_FLAG = 256,
20943 WRAP_FLIP_FLAG = 512;
20944
20945 /** Used as default options for `_.truncate`. */
20946 var DEFAULT_TRUNC_LENGTH = 30,
20947 DEFAULT_TRUNC_OMISSION = '...';
20948
20949 /** Used to detect hot functions by number of calls within a span of milliseconds. */
20950 var HOT_COUNT = 800,
20951 HOT_SPAN = 16;
20952
20953 /** Used to indicate the type of lazy iteratees. */
20954 var LAZY_FILTER_FLAG = 1,
20955 LAZY_MAP_FLAG = 2,
20956 LAZY_WHILE_FLAG = 3;
20957
20958 /** Used as references for various `Number` constants. */
20959 var INFINITY = 1 / 0,
20960 MAX_SAFE_INTEGER = 9007199254740991,
20961 MAX_INTEGER = 1.7976931348623157e+308,
20962 NAN = 0 / 0;
20963
20964 /** Used as references for the maximum length and index of an array. */
20965 var MAX_ARRAY_LENGTH = 4294967295,
20966 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
20967 HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
20968
20969 /** Used to associate wrap methods with their bit flags. */
20970 var wrapFlags = [
20971 ['ary', WRAP_ARY_FLAG],
20972 ['bind', WRAP_BIND_FLAG],
20973 ['bindKey', WRAP_BIND_KEY_FLAG],
20974 ['curry', WRAP_CURRY_FLAG],
20975 ['curryRight', WRAP_CURRY_RIGHT_FLAG],
20976 ['flip', WRAP_FLIP_FLAG],
20977 ['partial', WRAP_PARTIAL_FLAG],
20978 ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
20979 ['rearg', WRAP_REARG_FLAG]
20980 ];
20981
20982 /** `Object#toString` result references. */
20983 var argsTag = '[object Arguments]',
20984 arrayTag = '[object Array]',
20985 asyncTag = '[object AsyncFunction]',
20986 boolTag = '[object Boolean]',
20987 dateTag = '[object Date]',
20988 domExcTag = '[object DOMException]',
20989 errorTag = '[object Error]',
20990 funcTag = '[object Function]',
20991 genTag = '[object GeneratorFunction]',
20992 mapTag = '[object Map]',
20993 numberTag = '[object Number]',
20994 nullTag = '[object Null]',
20995 objectTag = '[object Object]',
20996 promiseTag = '[object Promise]',
20997 proxyTag = '[object Proxy]',
20998 regexpTag = '[object RegExp]',
20999 setTag = '[object Set]',
21000 stringTag = '[object String]',
21001 symbolTag = '[object Symbol]',
21002 undefinedTag = '[object Undefined]',
21003 weakMapTag = '[object WeakMap]',
21004 weakSetTag = '[object WeakSet]';
21005
21006 var arrayBufferTag = '[object ArrayBuffer]',
21007 dataViewTag = '[object DataView]',
21008 float32Tag = '[object Float32Array]',
21009 float64Tag = '[object Float64Array]',
21010 int8Tag = '[object Int8Array]',
21011 int16Tag = '[object Int16Array]',
21012 int32Tag = '[object Int32Array]',
21013 uint8Tag = '[object Uint8Array]',
21014 uint8ClampedTag = '[object Uint8ClampedArray]',
21015 uint16Tag = '[object Uint16Array]',
21016 uint32Tag = '[object Uint32Array]';
21017
21018 /** Used to match empty string literals in compiled template source. */
21019 var reEmptyStringLeading = /\b__p \+= '';/g,
21020 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
21021 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
21022
21023 /** Used to match HTML entities and HTML characters. */
21024 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
21025 reUnescapedHtml = /[&<>"']/g,
21026 reHasEscapedHtml = RegExp(reEscapedHtml.source),
21027 reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
21028
21029 /** Used to match template delimiters. */
21030 var reEscape = /<%-([\s\S]+?)%>/g,
21031 reEvaluate = /<%([\s\S]+?)%>/g,
21032 reInterpolate = /<%=([\s\S]+?)%>/g;
21033
21034 /** Used to match property names within property paths. */
21035 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
21036 reIsPlainProp = /^\w*$/,
21037 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
21038
21039 /**
21040 * Used to match `RegExp`
21041 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
21042 */
21043 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
21044 reHasRegExpChar = RegExp(reRegExpChar.source);
21045
21046 /** Used to match leading and trailing whitespace. */
21047 var reTrim = /^\s+|\s+$/g,
21048 reTrimStart = /^\s+/,
21049 reTrimEnd = /\s+$/;
21050
21051 /** Used to match wrap detail comments. */
21052 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
21053 reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
21054 reSplitDetails = /,? & /;
21055
21056 /** Used to match words composed of alphanumeric characters. */
21057 var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
21058
21059 /** Used to match backslashes in property paths. */
21060 var reEscapeChar = /\\(\\)?/g;
21061
21062 /**
21063 * Used to match
21064 * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
21065 */
21066 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
21067
21068 /** Used to match `RegExp` flags from their coerced string values. */
21069 var reFlags = /\w*$/;
21070
21071 /** Used to detect bad signed hexadecimal string values. */
21072 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
21073
21074 /** Used to detect binary string values. */
21075 var reIsBinary = /^0b[01]+$/i;
21076
21077 /** Used to detect host constructors (Safari). */
21078 var reIsHostCtor = /^\[object .+?Constructor\]$/;
21079
21080 /** Used to detect octal string values. */
21081 var reIsOctal = /^0o[0-7]+$/i;
21082
21083 /** Used to detect unsigned integer values. */
21084 var reIsUint = /^(?:0|[1-9]\d*)$/;
21085
21086 /** Used to match Latin Unicode letters (excluding mathematical operators). */
21087 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
21088
21089 /** Used to ensure capturing order of template delimiters. */
21090 var reNoMatch = /($^)/;
21091
21092 /** Used to match unescaped characters in compiled string literals. */
21093 var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
21094
21095 /** Used to compose unicode character classes. */
21096 var rsAstralRange = '\\ud800-\\udfff',
21097 rsComboMarksRange = '\\u0300-\\u036f',
21098 reComboHalfMarksRange = '\\ufe20-\\ufe2f',
21099 rsComboSymbolsRange = '\\u20d0-\\u20ff',
21100 rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
21101 rsDingbatRange = '\\u2700-\\u27bf',
21102 rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
21103 rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
21104 rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
21105 rsPunctuationRange = '\\u2000-\\u206f',
21106 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',
21107 rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
21108 rsVarRange = '\\ufe0e\\ufe0f',
21109 rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
21110
21111 /** Used to compose unicode capture groups. */
21112 var rsApos = "['\u2019]",
21113 rsAstral = '[' + rsAstralRange + ']',
21114 rsBreak = '[' + rsBreakRange + ']',
21115 rsCombo = '[' + rsComboRange + ']',
21116 rsDigits = '\\d+',
21117 rsDingbat = '[' + rsDingbatRange + ']',
21118 rsLower = '[' + rsLowerRange + ']',
21119 rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
21120 rsFitz = '\\ud83c[\\udffb-\\udfff]',
21121 rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
21122 rsNonAstral = '[^' + rsAstralRange + ']',
21123 rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
21124 rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
21125 rsUpper = '[' + rsUpperRange + ']',
21126 rsZWJ = '\\u200d';
21127
21128 /** Used to compose unicode regexes. */
21129 var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
21130 rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
21131 rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
21132 rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
21133 reOptMod = rsModifier + '?',
21134 rsOptVar = '[' + rsVarRange + ']?',
21135 rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
21136 rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
21137 rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
21138 rsSeq = rsOptVar + reOptMod + rsOptJoin,
21139 rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
21140 rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
21141
21142 /** Used to match apostrophes. */
21143 var reApos = RegExp(rsApos, 'g');
21144
21145 /**
21146 * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
21147 * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
21148 */
21149 var reComboMark = RegExp(rsCombo, 'g');
21150
21151 /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
21152 var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
21153
21154 /** Used to match complex or compound words. */
21155 var reUnicodeWord = RegExp([
21156 rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
21157 rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
21158 rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
21159 rsUpper + '+' + rsOptContrUpper,
21160 rsOrdUpper,
21161 rsOrdLower,
21162 rsDigits,
21163 rsEmoji
21164 ].join('|'), 'g');
21165
21166 /** 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/). */
21167 var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
21168
21169 /** Used to detect strings that need a more robust regexp to match words. */
21170 var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
21171
21172 /** Used to assign default `context` object properties. */
21173 var contextProps = [
21174 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
21175 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
21176 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
21177 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
21178 '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
21179 ];
21180
21181 /** Used to make template sourceURLs easier to identify. */
21182 var templateCounter = -1;
21183
21184 /** Used to identify `toStringTag` values of typed arrays. */
21185 var typedArrayTags = {};
21186 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
21187 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
21188 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
21189 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
21190 typedArrayTags[uint32Tag] = true;
21191 typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
21192 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
21193 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
21194 typedArrayTags[errorTag] = typedArrayTags[funcTag] =
21195 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
21196 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
21197 typedArrayTags[setTag] = typedArrayTags[stringTag] =
21198 typedArrayTags[weakMapTag] = false;
21199
21200 /** Used to identify `toStringTag` values supported by `_.clone`. */
21201 var cloneableTags = {};
21202 cloneableTags[argsTag] = cloneableTags[arrayTag] =
21203 cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
21204 cloneableTags[boolTag] = cloneableTags[dateTag] =
21205 cloneableTags[float32Tag] = cloneableTags[float64Tag] =
21206 cloneableTags[int8Tag] = cloneableTags[int16Tag] =
21207 cloneableTags[int32Tag] = cloneableTags[mapTag] =
21208 cloneableTags[numberTag] = cloneableTags[objectTag] =
21209 cloneableTags[regexpTag] = cloneableTags[setTag] =
21210 cloneableTags[stringTag] = cloneableTags[symbolTag] =
21211 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
21212 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
21213 cloneableTags[errorTag] = cloneableTags[funcTag] =
21214 cloneableTags[weakMapTag] = false;
21215
21216 /** Used to map Latin Unicode letters to basic Latin letters. */
21217 var deburredLetters = {
21218 // Latin-1 Supplement block.
21219 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
21220 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
21221 '\xc7': 'C', '\xe7': 'c',
21222 '\xd0': 'D', '\xf0': 'd',
21223 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
21224 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
21225 '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
21226 '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
21227 '\xd1': 'N', '\xf1': 'n',
21228 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
21229 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
21230 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
21231 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
21232 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
21233 '\xc6': 'Ae', '\xe6': 'ae',
21234 '\xde': 'Th', '\xfe': 'th',
21235 '\xdf': 'ss',
21236 // Latin Extended-A block.
21237 '\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
21238 '\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
21239 '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
21240 '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
21241 '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
21242 '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
21243 '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
21244 '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
21245 '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
21246 '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
21247 '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
21248 '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
21249 '\u0134': 'J', '\u0135': 'j',
21250 '\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
21251 '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
21252 '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
21253 '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
21254 '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
21255 '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
21256 '\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
21257 '\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
21258 '\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
21259 '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
21260 '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
21261 '\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
21262 '\u0163': 't', '\u0165': 't', '\u0167': 't',
21263 '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
21264 '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
21265 '\u0174': 'W', '\u0175': 'w',
21266 '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
21267 '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
21268 '\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
21269 '\u0132': 'IJ', '\u0133': 'ij',
21270 '\u0152': 'Oe', '\u0153': 'oe',
21271 '\u0149': "'n", '\u017f': 's'
21272 };
21273
21274 /** Used to map characters to HTML entities. */
21275 var htmlEscapes = {
21276 '&': '&amp;',
21277 '<': '&lt;',
21278 '>': '&gt;',
21279 '"': '&quot;',
21280 "'": '&#39;'
21281 };
21282
21283 /** Used to map HTML entities to characters. */
21284 var htmlUnescapes = {
21285 '&amp;': '&',
21286 '&lt;': '<',
21287 '&gt;': '>',
21288 '&quot;': '"',
21289 '&#39;': "'"
21290 };
21291
21292 /** Used to escape characters for inclusion in compiled string literals. */
21293 var stringEscapes = {
21294 '\\': '\\',
21295 "'": "'",
21296 '\n': 'n',
21297 '\r': 'r',
21298 '\u2028': 'u2028',
21299 '\u2029': 'u2029'
21300 };
21301
21302 /** Built-in method references without a dependency on `root`. */
21303 var freeParseFloat = parseFloat,
21304 freeParseInt = parseInt;
21305
21306 /** Detect free variable `global` from Node.js. */
21307 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
21308
21309 /** Detect free variable `self`. */
21310 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
21311
21312 /** Used as a reference to the global object. */
21313 var root = freeGlobal || freeSelf || Function('return this')();
21314
21315 /** Detect free variable `exports`. */
21316 var freeExports = exports && !exports.nodeType && exports;
21317
21318 /** Detect free variable `module`. */
21319 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
21320
21321 /** Detect the popular CommonJS extension `module.exports`. */
21322 var moduleExports = freeModule && freeModule.exports === freeExports;
21323
21324 /** Detect free variable `process` from Node.js. */
21325 var freeProcess = moduleExports && freeGlobal.process;
21326
21327 /** Used to access faster Node.js helpers. */
21328 var nodeUtil = (function() {
21329 try {
21330 // Use `util.types` for Node.js 10+.
21331 var types = freeModule && freeModule.require && freeModule.require('util').types;
21332
21333 if (types) {
21334 return types;
21335 }
21336
21337 // Legacy `process.binding('util')` for Node.js < 10.
21338 return freeProcess && freeProcess.binding && freeProcess.binding('util');
21339 } catch (e) {}
21340 }());
21341
21342 /* Node.js helper references. */
21343 var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
21344 nodeIsDate = nodeUtil && nodeUtil.isDate,
21345 nodeIsMap = nodeUtil && nodeUtil.isMap,
21346 nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
21347 nodeIsSet = nodeUtil && nodeUtil.isSet,
21348 nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
21349
21350 /*--------------------------------------------------------------------------*/
21351
21352 /**
21353 * A faster alternative to `Function#apply`, this function invokes `func`
21354 * with the `this` binding of `thisArg` and the arguments of `args`.
21355 *
21356 * @private
21357 * @param {Function} func The function to invoke.
21358 * @param {*} thisArg The `this` binding of `func`.
21359 * @param {Array} args The arguments to invoke `func` with.
21360 * @returns {*} Returns the result of `func`.
21361 */
21362 function apply(func, thisArg, args) {
21363 switch (args.length) {
21364 case 0: return func.call(thisArg);
21365 case 1: return func.call(thisArg, args[0]);
21366 case 2: return func.call(thisArg, args[0], args[1]);
21367 case 3: return func.call(thisArg, args[0], args[1], args[2]);
21368 }
21369 return func.apply(thisArg, args);
21370 }
21371
21372 /**
21373 * A specialized version of `baseAggregator` for arrays.
21374 *
21375 * @private
21376 * @param {Array} [array] The array to iterate over.
21377 * @param {Function} setter The function to set `accumulator` values.
21378 * @param {Function} iteratee The iteratee to transform keys.
21379 * @param {Object} accumulator The initial aggregated object.
21380 * @returns {Function} Returns `accumulator`.
21381 */
21382 function arrayAggregator(array, setter, iteratee, accumulator) {
21383 var index = -1,
21384 length = array == null ? 0 : array.length;
21385
21386 while (++index < length) {
21387 var value = array[index];
21388 setter(accumulator, value, iteratee(value), array);
21389 }
21390 return accumulator;
21391 }
21392
21393 /**
21394 * A specialized version of `_.forEach` for arrays without support for
21395 * iteratee shorthands.
21396 *
21397 * @private
21398 * @param {Array} [array] The array to iterate over.
21399 * @param {Function} iteratee The function invoked per iteration.
21400 * @returns {Array} Returns `array`.
21401 */
21402 function arrayEach(array, iteratee) {
21403 var index = -1,
21404 length = array == null ? 0 : array.length;
21405
21406 while (++index < length) {
21407 if (iteratee(array[index], index, array) === false) {
21408 break;
21409 }
21410 }
21411 return array;
21412 }
21413
21414 /**
21415 * A specialized version of `_.forEachRight` for arrays without support for
21416 * iteratee shorthands.
21417 *
21418 * @private
21419 * @param {Array} [array] The array to iterate over.
21420 * @param {Function} iteratee The function invoked per iteration.
21421 * @returns {Array} Returns `array`.
21422 */
21423 function arrayEachRight(array, iteratee) {
21424 var length = array == null ? 0 : array.length;
21425
21426 while (length--) {
21427 if (iteratee(array[length], length, array) === false) {
21428 break;
21429 }
21430 }
21431 return array;
21432 }
21433
21434 /**
21435 * A specialized version of `_.every` for arrays without support for
21436 * iteratee shorthands.
21437 *
21438 * @private
21439 * @param {Array} [array] The array to iterate over.
21440 * @param {Function} predicate The function invoked per iteration.
21441 * @returns {boolean} Returns `true` if all elements pass the predicate check,
21442 * else `false`.
21443 */
21444 function arrayEvery(array, predicate) {
21445 var index = -1,
21446 length = array == null ? 0 : array.length;
21447
21448 while (++index < length) {
21449 if (!predicate(array[index], index, array)) {
21450 return false;
21451 }
21452 }
21453 return true;
21454 }
21455
21456 /**
21457 * A specialized version of `_.filter` for arrays without support for
21458 * iteratee shorthands.
21459 *
21460 * @private
21461 * @param {Array} [array] The array to iterate over.
21462 * @param {Function} predicate The function invoked per iteration.
21463 * @returns {Array} Returns the new filtered array.
21464 */
21465 function arrayFilter(array, predicate) {
21466 var index = -1,
21467 length = array == null ? 0 : array.length,
21468 resIndex = 0,
21469 result = [];
21470
21471 while (++index < length) {
21472 var value = array[index];
21473 if (predicate(value, index, array)) {
21474 result[resIndex++] = value;
21475 }
21476 }
21477 return result;
21478 }
21479
21480 /**
21481 * A specialized version of `_.includes` for arrays without support for
21482 * specifying an index to search from.
21483 *
21484 * @private
21485 * @param {Array} [array] The array to inspect.
21486 * @param {*} target The value to search for.
21487 * @returns {boolean} Returns `true` if `target` is found, else `false`.
21488 */
21489 function arrayIncludes(array, value) {
21490 var length = array == null ? 0 : array.length;
21491 return !!length && baseIndexOf(array, value, 0) > -1;
21492 }
21493
21494 /**
21495 * This function is like `arrayIncludes` except that it accepts a comparator.
21496 *
21497 * @private
21498 * @param {Array} [array] The array to inspect.
21499 * @param {*} target The value to search for.
21500 * @param {Function} comparator The comparator invoked per element.
21501 * @returns {boolean} Returns `true` if `target` is found, else `false`.
21502 */
21503 function arrayIncludesWith(array, value, comparator) {
21504 var index = -1,
21505 length = array == null ? 0 : array.length;
21506
21507 while (++index < length) {
21508 if (comparator(value, array[index])) {
21509 return true;
21510 }
21511 }
21512 return false;
21513 }
21514
21515 /**
21516 * A specialized version of `_.map` for arrays without support for iteratee
21517 * shorthands.
21518 *
21519 * @private
21520 * @param {Array} [array] The array to iterate over.
21521 * @param {Function} iteratee The function invoked per iteration.
21522 * @returns {Array} Returns the new mapped array.
21523 */
21524 function arrayMap(array, iteratee) {
21525 var index = -1,
21526 length = array == null ? 0 : array.length,
21527 result = Array(length);
21528
21529 while (++index < length) {
21530 result[index] = iteratee(array[index], index, array);
21531 }
21532 return result;
21533 }
21534
21535 /**
21536 * Appends the elements of `values` to `array`.
21537 *
21538 * @private
21539 * @param {Array} array The array to modify.
21540 * @param {Array} values The values to append.
21541 * @returns {Array} Returns `array`.
21542 */
21543 function arrayPush(array, values) {
21544 var index = -1,
21545 length = values.length,
21546 offset = array.length;
21547
21548 while (++index < length) {
21549 array[offset + index] = values[index];
21550 }
21551 return array;
21552 }
21553
21554 /**
21555 * A specialized version of `_.reduce` for arrays without support for
21556 * iteratee shorthands.
21557 *
21558 * @private
21559 * @param {Array} [array] The array to iterate over.
21560 * @param {Function} iteratee The function invoked per iteration.
21561 * @param {*} [accumulator] The initial value.
21562 * @param {boolean} [initAccum] Specify using the first element of `array` as
21563 * the initial value.
21564 * @returns {*} Returns the accumulated value.
21565 */
21566 function arrayReduce(array, iteratee, accumulator, initAccum) {
21567 var index = -1,
21568 length = array == null ? 0 : array.length;
21569
21570 if (initAccum && length) {
21571 accumulator = array[++index];
21572 }
21573 while (++index < length) {
21574 accumulator = iteratee(accumulator, array[index], index, array);
21575 }
21576 return accumulator;
21577 }
21578
21579 /**
21580 * A specialized version of `_.reduceRight` for arrays without support for
21581 * iteratee shorthands.
21582 *
21583 * @private
21584 * @param {Array} [array] The array to iterate over.
21585 * @param {Function} iteratee The function invoked per iteration.
21586 * @param {*} [accumulator] The initial value.
21587 * @param {boolean} [initAccum] Specify using the last element of `array` as
21588 * the initial value.
21589 * @returns {*} Returns the accumulated value.
21590 */
21591 function arrayReduceRight(array, iteratee, accumulator, initAccum) {
21592 var length = array == null ? 0 : array.length;
21593 if (initAccum && length) {
21594 accumulator = array[--length];
21595 }
21596 while (length--) {
21597 accumulator = iteratee(accumulator, array[length], length, array);
21598 }
21599 return accumulator;
21600 }
21601
21602 /**
21603 * A specialized version of `_.some` for arrays without support for iteratee
21604 * shorthands.
21605 *
21606 * @private
21607 * @param {Array} [array] The array to iterate over.
21608 * @param {Function} predicate The function invoked per iteration.
21609 * @returns {boolean} Returns `true` if any element passes the predicate check,
21610 * else `false`.
21611 */
21612 function arraySome(array, predicate) {
21613 var index = -1,
21614 length = array == null ? 0 : array.length;
21615
21616 while (++index < length) {
21617 if (predicate(array[index], index, array)) {
21618 return true;
21619 }
21620 }
21621 return false;
21622 }
21623
21624 /**
21625 * Gets the size of an ASCII `string`.
21626 *
21627 * @private
21628 * @param {string} string The string inspect.
21629 * @returns {number} Returns the string size.
21630 */
21631 var asciiSize = baseProperty('length');
21632
21633 /**
21634 * Converts an ASCII `string` to an array.
21635 *
21636 * @private
21637 * @param {string} string The string to convert.
21638 * @returns {Array} Returns the converted array.
21639 */
21640 function asciiToArray(string) {
21641 return string.split('');
21642 }
21643
21644 /**
21645 * Splits an ASCII `string` into an array of its words.
21646 *
21647 * @private
21648 * @param {string} The string to inspect.
21649 * @returns {Array} Returns the words of `string`.
21650 */
21651 function asciiWords(string) {
21652 return string.match(reAsciiWord) || [];
21653 }
21654
21655 /**
21656 * The base implementation of methods like `_.findKey` and `_.findLastKey`,
21657 * without support for iteratee shorthands, which iterates over `collection`
21658 * using `eachFunc`.
21659 *
21660 * @private
21661 * @param {Array|Object} collection The collection to inspect.
21662 * @param {Function} predicate The function invoked per iteration.
21663 * @param {Function} eachFunc The function to iterate over `collection`.
21664 * @returns {*} Returns the found element or its key, else `undefined`.
21665 */
21666 function baseFindKey(collection, predicate, eachFunc) {
21667 var result;
21668 eachFunc(collection, function(value, key, collection) {
21669 if (predicate(value, key, collection)) {
21670 result = key;
21671 return false;
21672 }
21673 });
21674 return result;
21675 }
21676
21677 /**
21678 * The base implementation of `_.findIndex` and `_.findLastIndex` without
21679 * support for iteratee shorthands.
21680 *
21681 * @private
21682 * @param {Array} array The array to inspect.
21683 * @param {Function} predicate The function invoked per iteration.
21684 * @param {number} fromIndex The index to search from.
21685 * @param {boolean} [fromRight] Specify iterating from right to left.
21686 * @returns {number} Returns the index of the matched value, else `-1`.
21687 */
21688 function baseFindIndex(array, predicate, fromIndex, fromRight) {
21689 var length = array.length,
21690 index = fromIndex + (fromRight ? 1 : -1);
21691
21692 while ((fromRight ? index-- : ++index < length)) {
21693 if (predicate(array[index], index, array)) {
21694 return index;
21695 }
21696 }
21697 return -1;
21698 }
21699
21700 /**
21701 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
21702 *
21703 * @private
21704 * @param {Array} array The array to inspect.
21705 * @param {*} value The value to search for.
21706 * @param {number} fromIndex The index to search from.
21707 * @returns {number} Returns the index of the matched value, else `-1`.
21708 */
21709 function baseIndexOf(array, value, fromIndex) {
21710 return value === value
21711 ? strictIndexOf(array, value, fromIndex)
21712 : baseFindIndex(array, baseIsNaN, fromIndex);
21713 }
21714
21715 /**
21716 * This function is like `baseIndexOf` except that it accepts a comparator.
21717 *
21718 * @private
21719 * @param {Array} array The array to inspect.
21720 * @param {*} value The value to search for.
21721 * @param {number} fromIndex The index to search from.
21722 * @param {Function} comparator The comparator invoked per element.
21723 * @returns {number} Returns the index of the matched value, else `-1`.
21724 */
21725 function baseIndexOfWith(array, value, fromIndex, comparator) {
21726 var index = fromIndex - 1,
21727 length = array.length;
21728
21729 while (++index < length) {
21730 if (comparator(array[index], value)) {
21731 return index;
21732 }
21733 }
21734 return -1;
21735 }
21736
21737 /**
21738 * The base implementation of `_.isNaN` without support for number objects.
21739 *
21740 * @private
21741 * @param {*} value The value to check.
21742 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
21743 */
21744 function baseIsNaN(value) {
21745 return value !== value;
21746 }
21747
21748 /**
21749 * The base implementation of `_.mean` and `_.meanBy` without support for
21750 * iteratee shorthands.
21751 *
21752 * @private
21753 * @param {Array} array The array to iterate over.
21754 * @param {Function} iteratee The function invoked per iteration.
21755 * @returns {number} Returns the mean.
21756 */
21757 function baseMean(array, iteratee) {
21758 var length = array == null ? 0 : array.length;
21759 return length ? (baseSum(array, iteratee) / length) : NAN;
21760 }
21761
21762 /**
21763 * The base implementation of `_.property` without support for deep paths.
21764 *
21765 * @private
21766 * @param {string} key The key of the property to get.
21767 * @returns {Function} Returns the new accessor function.
21768 */
21769 function baseProperty(key) {
21770 return function(object) {
21771 return object == null ? undefined$1 : object[key];
21772 };
21773 }
21774
21775 /**
21776 * The base implementation of `_.propertyOf` without support for deep paths.
21777 *
21778 * @private
21779 * @param {Object} object The object to query.
21780 * @returns {Function} Returns the new accessor function.
21781 */
21782 function basePropertyOf(object) {
21783 return function(key) {
21784 return object == null ? undefined$1 : object[key];
21785 };
21786 }
21787
21788 /**
21789 * The base implementation of `_.reduce` and `_.reduceRight`, without support
21790 * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
21791 *
21792 * @private
21793 * @param {Array|Object} collection The collection to iterate over.
21794 * @param {Function} iteratee The function invoked per iteration.
21795 * @param {*} accumulator The initial value.
21796 * @param {boolean} initAccum Specify using the first or last element of
21797 * `collection` as the initial value.
21798 * @param {Function} eachFunc The function to iterate over `collection`.
21799 * @returns {*} Returns the accumulated value.
21800 */
21801 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
21802 eachFunc(collection, function(value, index, collection) {
21803 accumulator = initAccum
21804 ? (initAccum = false, value)
21805 : iteratee(accumulator, value, index, collection);
21806 });
21807 return accumulator;
21808 }
21809
21810 /**
21811 * The base implementation of `_.sortBy` which uses `comparer` to define the
21812 * sort order of `array` and replaces criteria objects with their corresponding
21813 * values.
21814 *
21815 * @private
21816 * @param {Array} array The array to sort.
21817 * @param {Function} comparer The function to define sort order.
21818 * @returns {Array} Returns `array`.
21819 */
21820 function baseSortBy(array, comparer) {
21821 var length = array.length;
21822
21823 array.sort(comparer);
21824 while (length--) {
21825 array[length] = array[length].value;
21826 }
21827 return array;
21828 }
21829
21830 /**
21831 * The base implementation of `_.sum` and `_.sumBy` without support for
21832 * iteratee shorthands.
21833 *
21834 * @private
21835 * @param {Array} array The array to iterate over.
21836 * @param {Function} iteratee The function invoked per iteration.
21837 * @returns {number} Returns the sum.
21838 */
21839 function baseSum(array, iteratee) {
21840 var result,
21841 index = -1,
21842 length = array.length;
21843
21844 while (++index < length) {
21845 var current = iteratee(array[index]);
21846 if (current !== undefined$1) {
21847 result = result === undefined$1 ? current : (result + current);
21848 }
21849 }
21850 return result;
21851 }
21852
21853 /**
21854 * The base implementation of `_.times` without support for iteratee shorthands
21855 * or max array length checks.
21856 *
21857 * @private
21858 * @param {number} n The number of times to invoke `iteratee`.
21859 * @param {Function} iteratee The function invoked per iteration.
21860 * @returns {Array} Returns the array of results.
21861 */
21862 function baseTimes(n, iteratee) {
21863 var index = -1,
21864 result = Array(n);
21865
21866 while (++index < n) {
21867 result[index] = iteratee(index);
21868 }
21869 return result;
21870 }
21871
21872 /**
21873 * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
21874 * of key-value pairs for `object` corresponding to the property names of `props`.
21875 *
21876 * @private
21877 * @param {Object} object The object to query.
21878 * @param {Array} props The property names to get values for.
21879 * @returns {Object} Returns the key-value pairs.
21880 */
21881 function baseToPairs(object, props) {
21882 return arrayMap(props, function(key) {
21883 return [key, object[key]];
21884 });
21885 }
21886
21887 /**
21888 * The base implementation of `_.unary` without support for storing metadata.
21889 *
21890 * @private
21891 * @param {Function} func The function to cap arguments for.
21892 * @returns {Function} Returns the new capped function.
21893 */
21894 function baseUnary(func) {
21895 return function(value) {
21896 return func(value);
21897 };
21898 }
21899
21900 /**
21901 * The base implementation of `_.values` and `_.valuesIn` which creates an
21902 * array of `object` property values corresponding to the property names
21903 * of `props`.
21904 *
21905 * @private
21906 * @param {Object} object The object to query.
21907 * @param {Array} props The property names to get values for.
21908 * @returns {Object} Returns the array of property values.
21909 */
21910 function baseValues(object, props) {
21911 return arrayMap(props, function(key) {
21912 return object[key];
21913 });
21914 }
21915
21916 /**
21917 * Checks if a `cache` value for `key` exists.
21918 *
21919 * @private
21920 * @param {Object} cache The cache to query.
21921 * @param {string} key The key of the entry to check.
21922 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
21923 */
21924 function cacheHas(cache, key) {
21925 return cache.has(key);
21926 }
21927
21928 /**
21929 * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
21930 * that is not found in the character symbols.
21931 *
21932 * @private
21933 * @param {Array} strSymbols The string symbols to inspect.
21934 * @param {Array} chrSymbols The character symbols to find.
21935 * @returns {number} Returns the index of the first unmatched string symbol.
21936 */
21937 function charsStartIndex(strSymbols, chrSymbols) {
21938 var index = -1,
21939 length = strSymbols.length;
21940
21941 while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
21942 return index;
21943 }
21944
21945 /**
21946 * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
21947 * that is not found in the character symbols.
21948 *
21949 * @private
21950 * @param {Array} strSymbols The string symbols to inspect.
21951 * @param {Array} chrSymbols The character symbols to find.
21952 * @returns {number} Returns the index of the last unmatched string symbol.
21953 */
21954 function charsEndIndex(strSymbols, chrSymbols) {
21955 var index = strSymbols.length;
21956
21957 while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
21958 return index;
21959 }
21960
21961 /**
21962 * Gets the number of `placeholder` occurrences in `array`.
21963 *
21964 * @private
21965 * @param {Array} array The array to inspect.
21966 * @param {*} placeholder The placeholder to search for.
21967 * @returns {number} Returns the placeholder count.
21968 */
21969 function countHolders(array, placeholder) {
21970 var length = array.length,
21971 result = 0;
21972
21973 while (length--) {
21974 if (array[length] === placeholder) {
21975 ++result;
21976 }
21977 }
21978 return result;
21979 }
21980
21981 /**
21982 * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
21983 * letters to basic Latin letters.
21984 *
21985 * @private
21986 * @param {string} letter The matched letter to deburr.
21987 * @returns {string} Returns the deburred letter.
21988 */
21989 var deburrLetter = basePropertyOf(deburredLetters);
21990
21991 /**
21992 * Used by `_.escape` to convert characters to HTML entities.
21993 *
21994 * @private
21995 * @param {string} chr The matched character to escape.
21996 * @returns {string} Returns the escaped character.
21997 */
21998 var escapeHtmlChar = basePropertyOf(htmlEscapes);
21999
22000 /**
22001 * Used by `_.template` to escape characters for inclusion in compiled string literals.
22002 *
22003 * @private
22004 * @param {string} chr The matched character to escape.
22005 * @returns {string} Returns the escaped character.
22006 */
22007 function escapeStringChar(chr) {
22008 return '\\' + stringEscapes[chr];
22009 }
22010
22011 /**
22012 * Gets the value at `key` of `object`.
22013 *
22014 * @private
22015 * @param {Object} [object] The object to query.
22016 * @param {string} key The key of the property to get.
22017 * @returns {*} Returns the property value.
22018 */
22019 function getValue(object, key) {
22020 return object == null ? undefined$1 : object[key];
22021 }
22022
22023 /**
22024 * Checks if `string` contains Unicode symbols.
22025 *
22026 * @private
22027 * @param {string} string The string to inspect.
22028 * @returns {boolean} Returns `true` if a symbol is found, else `false`.
22029 */
22030 function hasUnicode(string) {
22031 return reHasUnicode.test(string);
22032 }
22033
22034 /**
22035 * Checks if `string` contains a word composed of Unicode symbols.
22036 *
22037 * @private
22038 * @param {string} string The string to inspect.
22039 * @returns {boolean} Returns `true` if a word is found, else `false`.
22040 */
22041 function hasUnicodeWord(string) {
22042 return reHasUnicodeWord.test(string);
22043 }
22044
22045 /**
22046 * Converts `iterator` to an array.
22047 *
22048 * @private
22049 * @param {Object} iterator The iterator to convert.
22050 * @returns {Array} Returns the converted array.
22051 */
22052 function iteratorToArray(iterator) {
22053 var data,
22054 result = [];
22055
22056 while (!(data = iterator.next()).done) {
22057 result.push(data.value);
22058 }
22059 return result;
22060 }
22061
22062 /**
22063 * Converts `map` to its key-value pairs.
22064 *
22065 * @private
22066 * @param {Object} map The map to convert.
22067 * @returns {Array} Returns the key-value pairs.
22068 */
22069 function mapToArray(map) {
22070 var index = -1,
22071 result = Array(map.size);
22072
22073 map.forEach(function(value, key) {
22074 result[++index] = [key, value];
22075 });
22076 return result;
22077 }
22078
22079 /**
22080 * Creates a unary function that invokes `func` with its argument transformed.
22081 *
22082 * @private
22083 * @param {Function} func The function to wrap.
22084 * @param {Function} transform The argument transform.
22085 * @returns {Function} Returns the new function.
22086 */
22087 function overArg(func, transform) {
22088 return function(arg) {
22089 return func(transform(arg));
22090 };
22091 }
22092
22093 /**
22094 * Replaces all `placeholder` elements in `array` with an internal placeholder
22095 * and returns an array of their indexes.
22096 *
22097 * @private
22098 * @param {Array} array The array to modify.
22099 * @param {*} placeholder The placeholder to replace.
22100 * @returns {Array} Returns the new array of placeholder indexes.
22101 */
22102 function replaceHolders(array, placeholder) {
22103 var index = -1,
22104 length = array.length,
22105 resIndex = 0,
22106 result = [];
22107
22108 while (++index < length) {
22109 var value = array[index];
22110 if (value === placeholder || value === PLACEHOLDER) {
22111 array[index] = PLACEHOLDER;
22112 result[resIndex++] = index;
22113 }
22114 }
22115 return result;
22116 }
22117
22118 /**
22119 * Converts `set` to an array of its values.
22120 *
22121 * @private
22122 * @param {Object} set The set to convert.
22123 * @returns {Array} Returns the values.
22124 */
22125 function setToArray(set) {
22126 var index = -1,
22127 result = Array(set.size);
22128
22129 set.forEach(function(value) {
22130 result[++index] = value;
22131 });
22132 return result;
22133 }
22134
22135 /**
22136 * Converts `set` to its value-value pairs.
22137 *
22138 * @private
22139 * @param {Object} set The set to convert.
22140 * @returns {Array} Returns the value-value pairs.
22141 */
22142 function setToPairs(set) {
22143 var index = -1,
22144 result = Array(set.size);
22145
22146 set.forEach(function(value) {
22147 result[++index] = [value, value];
22148 });
22149 return result;
22150 }
22151
22152 /**
22153 * A specialized version of `_.indexOf` which performs strict equality
22154 * comparisons of values, i.e. `===`.
22155 *
22156 * @private
22157 * @param {Array} array The array to inspect.
22158 * @param {*} value The value to search for.
22159 * @param {number} fromIndex The index to search from.
22160 * @returns {number} Returns the index of the matched value, else `-1`.
22161 */
22162 function strictIndexOf(array, value, fromIndex) {
22163 var index = fromIndex - 1,
22164 length = array.length;
22165
22166 while (++index < length) {
22167 if (array[index] === value) {
22168 return index;
22169 }
22170 }
22171 return -1;
22172 }
22173
22174 /**
22175 * A specialized version of `_.lastIndexOf` which performs strict equality
22176 * comparisons of values, i.e. `===`.
22177 *
22178 * @private
22179 * @param {Array} array The array to inspect.
22180 * @param {*} value The value to search for.
22181 * @param {number} fromIndex The index to search from.
22182 * @returns {number} Returns the index of the matched value, else `-1`.
22183 */
22184 function strictLastIndexOf(array, value, fromIndex) {
22185 var index = fromIndex + 1;
22186 while (index--) {
22187 if (array[index] === value) {
22188 return index;
22189 }
22190 }
22191 return index;
22192 }
22193
22194 /**
22195 * Gets the number of symbols in `string`.
22196 *
22197 * @private
22198 * @param {string} string The string to inspect.
22199 * @returns {number} Returns the string size.
22200 */
22201 function stringSize(string) {
22202 return hasUnicode(string)
22203 ? unicodeSize(string)
22204 : asciiSize(string);
22205 }
22206
22207 /**
22208 * Converts `string` to an array.
22209 *
22210 * @private
22211 * @param {string} string The string to convert.
22212 * @returns {Array} Returns the converted array.
22213 */
22214 function stringToArray(string) {
22215 return hasUnicode(string)
22216 ? unicodeToArray(string)
22217 : asciiToArray(string);
22218 }
22219
22220 /**
22221 * Used by `_.unescape` to convert HTML entities to characters.
22222 *
22223 * @private
22224 * @param {string} chr The matched character to unescape.
22225 * @returns {string} Returns the unescaped character.
22226 */
22227 var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
22228
22229 /**
22230 * Gets the size of a Unicode `string`.
22231 *
22232 * @private
22233 * @param {string} string The string inspect.
22234 * @returns {number} Returns the string size.
22235 */
22236 function unicodeSize(string) {
22237 var result = reUnicode.lastIndex = 0;
22238 while (reUnicode.test(string)) {
22239 ++result;
22240 }
22241 return result;
22242 }
22243
22244 /**
22245 * Converts a Unicode `string` to an array.
22246 *
22247 * @private
22248 * @param {string} string The string to convert.
22249 * @returns {Array} Returns the converted array.
22250 */
22251 function unicodeToArray(string) {
22252 return string.match(reUnicode) || [];
22253 }
22254
22255 /**
22256 * Splits a Unicode `string` into an array of its words.
22257 *
22258 * @private
22259 * @param {string} The string to inspect.
22260 * @returns {Array} Returns the words of `string`.
22261 */
22262 function unicodeWords(string) {
22263 return string.match(reUnicodeWord) || [];
22264 }
22265
22266 /*--------------------------------------------------------------------------*/
22267
22268 /**
22269 * Create a new pristine `lodash` function using the `context` object.
22270 *
22271 * @static
22272 * @memberOf _
22273 * @since 1.1.0
22274 * @category Util
22275 * @param {Object} [context=root] The context object.
22276 * @returns {Function} Returns a new `lodash` function.
22277 * @example
22278 *
22279 * _.mixin({ 'foo': _.constant('foo') });
22280 *
22281 * var lodash = _.runInContext();
22282 * lodash.mixin({ 'bar': lodash.constant('bar') });
22283 *
22284 * _.isFunction(_.foo);
22285 * // => true
22286 * _.isFunction(_.bar);
22287 * // => false
22288 *
22289 * lodash.isFunction(lodash.foo);
22290 * // => false
22291 * lodash.isFunction(lodash.bar);
22292 * // => true
22293 *
22294 * // Create a suped-up `defer` in Node.js.
22295 * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
22296 */
22297 var runInContext = (function runInContext(context) {
22298 context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
22299
22300 /** Built-in constructor references. */
22301 var Array = context.Array,
22302 Date = context.Date,
22303 Error = context.Error,
22304 Function = context.Function,
22305 Math = context.Math,
22306 Object = context.Object,
22307 RegExp = context.RegExp,
22308 String = context.String,
22309 TypeError = context.TypeError;
22310
22311 /** Used for built-in method references. */
22312 var arrayProto = Array.prototype,
22313 funcProto = Function.prototype,
22314 objectProto = Object.prototype;
22315
22316 /** Used to detect overreaching core-js shims. */
22317 var coreJsData = context['__core-js_shared__'];
22318
22319 /** Used to resolve the decompiled source of functions. */
22320 var funcToString = funcProto.toString;
22321
22322 /** Used to check objects for own properties. */
22323 var hasOwnProperty = objectProto.hasOwnProperty;
22324
22325 /** Used to generate unique IDs. */
22326 var idCounter = 0;
22327
22328 /** Used to detect methods masquerading as native. */
22329 var maskSrcKey = (function() {
22330 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
22331 return uid ? ('Symbol(src)_1.' + uid) : '';
22332 }());
22333
22334 /**
22335 * Used to resolve the
22336 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
22337 * of values.
22338 */
22339 var nativeObjectToString = objectProto.toString;
22340
22341 /** Used to infer the `Object` constructor. */
22342 var objectCtorString = funcToString.call(Object);
22343
22344 /** Used to restore the original `_` reference in `_.noConflict`. */
22345 var oldDash = root._;
22346
22347 /** Used to detect if a method is native. */
22348 var reIsNative = RegExp('^' +
22349 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
22350 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
22351 );
22352
22353 /** Built-in value references. */
22354 var Buffer = moduleExports ? context.Buffer : undefined$1,
22355 Symbol = context.Symbol,
22356 Uint8Array = context.Uint8Array,
22357 allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined$1,
22358 getPrototype = overArg(Object.getPrototypeOf, Object),
22359 objectCreate = Object.create,
22360 propertyIsEnumerable = objectProto.propertyIsEnumerable,
22361 splice = arrayProto.splice,
22362 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined$1,
22363 symIterator = Symbol ? Symbol.iterator : undefined$1,
22364 symToStringTag = Symbol ? Symbol.toStringTag : undefined$1;
22365
22366 var defineProperty = (function() {
22367 try {
22368 var func = getNative(Object, 'defineProperty');
22369 func({}, '', {});
22370 return func;
22371 } catch (e) {}
22372 }());
22373
22374 /** Mocked built-ins. */
22375 var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
22376 ctxNow = Date && Date.now !== root.Date.now && Date.now,
22377 ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
22378
22379 /* Built-in method references for those with the same name as other `lodash` methods. */
22380 var nativeCeil = Math.ceil,
22381 nativeFloor = Math.floor,
22382 nativeGetSymbols = Object.getOwnPropertySymbols,
22383 nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined$1,
22384 nativeIsFinite = context.isFinite,
22385 nativeJoin = arrayProto.join,
22386 nativeKeys = overArg(Object.keys, Object),
22387 nativeMax = Math.max,
22388 nativeMin = Math.min,
22389 nativeNow = Date.now,
22390 nativeParseInt = context.parseInt,
22391 nativeRandom = Math.random,
22392 nativeReverse = arrayProto.reverse;
22393
22394 /* Built-in method references that are verified to be native. */
22395 var DataView = getNative(context, 'DataView'),
22396 Map = getNative(context, 'Map'),
22397 Promise = getNative(context, 'Promise'),
22398 Set = getNative(context, 'Set'),
22399 WeakMap = getNative(context, 'WeakMap'),
22400 nativeCreate = getNative(Object, 'create');
22401
22402 /** Used to store function metadata. */
22403 var metaMap = WeakMap && new WeakMap;
22404
22405 /** Used to lookup unminified function names. */
22406 var realNames = {};
22407
22408 /** Used to detect maps, sets, and weakmaps. */
22409 var dataViewCtorString = toSource(DataView),
22410 mapCtorString = toSource(Map),
22411 promiseCtorString = toSource(Promise),
22412 setCtorString = toSource(Set),
22413 weakMapCtorString = toSource(WeakMap);
22414
22415 /** Used to convert symbols to primitives and strings. */
22416 var symbolProto = Symbol ? Symbol.prototype : undefined$1,
22417 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined$1,
22418 symbolToString = symbolProto ? symbolProto.toString : undefined$1;
22419
22420 /*------------------------------------------------------------------------*/
22421
22422 /**
22423 * Creates a `lodash` object which wraps `value` to enable implicit method
22424 * chain sequences. Methods that operate on and return arrays, collections,
22425 * and functions can be chained together. Methods that retrieve a single value
22426 * or may return a primitive value will automatically end the chain sequence
22427 * and return the unwrapped value. Otherwise, the value must be unwrapped
22428 * with `_#value`.
22429 *
22430 * Explicit chain sequences, which must be unwrapped with `_#value`, may be
22431 * enabled using `_.chain`.
22432 *
22433 * The execution of chained methods is lazy, that is, it's deferred until
22434 * `_#value` is implicitly or explicitly called.
22435 *
22436 * Lazy evaluation allows several methods to support shortcut fusion.
22437 * Shortcut fusion is an optimization to merge iteratee calls; this avoids
22438 * the creation of intermediate arrays and can greatly reduce the number of
22439 * iteratee executions. Sections of a chain sequence qualify for shortcut
22440 * fusion if the section is applied to an array and iteratees accept only
22441 * one argument. The heuristic for whether a section qualifies for shortcut
22442 * fusion is subject to change.
22443 *
22444 * Chaining is supported in custom builds as long as the `_#value` method is
22445 * directly or indirectly included in the build.
22446 *
22447 * In addition to lodash methods, wrappers have `Array` and `String` methods.
22448 *
22449 * The wrapper `Array` methods are:
22450 * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
22451 *
22452 * The wrapper `String` methods are:
22453 * `replace` and `split`
22454 *
22455 * The wrapper methods that support shortcut fusion are:
22456 * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
22457 * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
22458 * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
22459 *
22460 * The chainable wrapper methods are:
22461 * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
22462 * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
22463 * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
22464 * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
22465 * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
22466 * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
22467 * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
22468 * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
22469 * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
22470 * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
22471 * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
22472 * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
22473 * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
22474 * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
22475 * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
22476 * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
22477 * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
22478 * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
22479 * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
22480 * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
22481 * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
22482 * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
22483 * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
22484 * `zipObject`, `zipObjectDeep`, and `zipWith`
22485 *
22486 * The wrapper methods that are **not** chainable by default are:
22487 * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
22488 * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
22489 * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
22490 * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
22491 * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
22492 * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
22493 * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
22494 * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
22495 * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
22496 * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
22497 * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
22498 * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
22499 * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
22500 * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
22501 * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
22502 * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
22503 * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
22504 * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
22505 * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
22506 * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
22507 * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
22508 * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
22509 * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
22510 * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
22511 * `upperFirst`, `value`, and `words`
22512 *
22513 * @name _
22514 * @constructor
22515 * @category Seq
22516 * @param {*} value The value to wrap in a `lodash` instance.
22517 * @returns {Object} Returns the new `lodash` wrapper instance.
22518 * @example
22519 *
22520 * function square(n) {
22521 * return n * n;
22522 * }
22523 *
22524 * var wrapped = _([1, 2, 3]);
22525 *
22526 * // Returns an unwrapped value.
22527 * wrapped.reduce(_.add);
22528 * // => 6
22529 *
22530 * // Returns a wrapped value.
22531 * var squares = wrapped.map(square);
22532 *
22533 * _.isArray(squares);
22534 * // => false
22535 *
22536 * _.isArray(squares.value());
22537 * // => true
22538 */
22539 function lodash(value) {
22540 if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
22541 if (value instanceof LodashWrapper) {
22542 return value;
22543 }
22544 if (hasOwnProperty.call(value, '__wrapped__')) {
22545 return wrapperClone(value);
22546 }
22547 }
22548 return new LodashWrapper(value);
22549 }
22550
22551 /**
22552 * The base implementation of `_.create` without support for assigning
22553 * properties to the created object.
22554 *
22555 * @private
22556 * @param {Object} proto The object to inherit from.
22557 * @returns {Object} Returns the new object.
22558 */
22559 var baseCreate = (function() {
22560 function object() {}
22561 return function(proto) {
22562 if (!isObject(proto)) {
22563 return {};
22564 }
22565 if (objectCreate) {
22566 return objectCreate(proto);
22567 }
22568 object.prototype = proto;
22569 var result = new object;
22570 object.prototype = undefined$1;
22571 return result;
22572 };
22573 }());
22574
22575 /**
22576 * The function whose prototype chain sequence wrappers inherit from.
22577 *
22578 * @private
22579 */
22580 function baseLodash() {
22581 // No operation performed.
22582 }
22583
22584 /**
22585 * The base constructor for creating `lodash` wrapper objects.
22586 *
22587 * @private
22588 * @param {*} value The value to wrap.
22589 * @param {boolean} [chainAll] Enable explicit method chain sequences.
22590 */
22591 function LodashWrapper(value, chainAll) {
22592 this.__wrapped__ = value;
22593 this.__actions__ = [];
22594 this.__chain__ = !!chainAll;
22595 this.__index__ = 0;
22596 this.__values__ = undefined$1;
22597 }
22598
22599 /**
22600 * By default, the template delimiters used by lodash are like those in
22601 * embedded Ruby (ERB) as well as ES2015 template strings. Change the
22602 * following template settings to use alternative delimiters.
22603 *
22604 * @static
22605 * @memberOf _
22606 * @type {Object}
22607 */
22608 lodash.templateSettings = {
22609
22610 /**
22611 * Used to detect `data` property values to be HTML-escaped.
22612 *
22613 * @memberOf _.templateSettings
22614 * @type {RegExp}
22615 */
22616 'escape': reEscape,
22617
22618 /**
22619 * Used to detect code to be evaluated.
22620 *
22621 * @memberOf _.templateSettings
22622 * @type {RegExp}
22623 */
22624 'evaluate': reEvaluate,
22625
22626 /**
22627 * Used to detect `data` property values to inject.
22628 *
22629 * @memberOf _.templateSettings
22630 * @type {RegExp}
22631 */
22632 'interpolate': reInterpolate,
22633
22634 /**
22635 * Used to reference the data object in the template text.
22636 *
22637 * @memberOf _.templateSettings
22638 * @type {string}
22639 */
22640 'variable': '',
22641
22642 /**
22643 * Used to import variables into the compiled template.
22644 *
22645 * @memberOf _.templateSettings
22646 * @type {Object}
22647 */
22648 'imports': {
22649
22650 /**
22651 * A reference to the `lodash` function.
22652 *
22653 * @memberOf _.templateSettings.imports
22654 * @type {Function}
22655 */
22656 '_': lodash
22657 }
22658 };
22659
22660 // Ensure wrappers are instances of `baseLodash`.
22661 lodash.prototype = baseLodash.prototype;
22662 lodash.prototype.constructor = lodash;
22663
22664 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
22665 LodashWrapper.prototype.constructor = LodashWrapper;
22666
22667 /*------------------------------------------------------------------------*/
22668
22669 /**
22670 * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
22671 *
22672 * @private
22673 * @constructor
22674 * @param {*} value The value to wrap.
22675 */
22676 function LazyWrapper(value) {
22677 this.__wrapped__ = value;
22678 this.__actions__ = [];
22679 this.__dir__ = 1;
22680 this.__filtered__ = false;
22681 this.__iteratees__ = [];
22682 this.__takeCount__ = MAX_ARRAY_LENGTH;
22683 this.__views__ = [];
22684 }
22685
22686 /**
22687 * Creates a clone of the lazy wrapper object.
22688 *
22689 * @private
22690 * @name clone
22691 * @memberOf LazyWrapper
22692 * @returns {Object} Returns the cloned `LazyWrapper` object.
22693 */
22694 function lazyClone() {
22695 var result = new LazyWrapper(this.__wrapped__);
22696 result.__actions__ = copyArray(this.__actions__);
22697 result.__dir__ = this.__dir__;
22698 result.__filtered__ = this.__filtered__;
22699 result.__iteratees__ = copyArray(this.__iteratees__);
22700 result.__takeCount__ = this.__takeCount__;
22701 result.__views__ = copyArray(this.__views__);
22702 return result;
22703 }
22704
22705 /**
22706 * Reverses the direction of lazy iteration.
22707 *
22708 * @private
22709 * @name reverse
22710 * @memberOf LazyWrapper
22711 * @returns {Object} Returns the new reversed `LazyWrapper` object.
22712 */
22713 function lazyReverse() {
22714 if (this.__filtered__) {
22715 var result = new LazyWrapper(this);
22716 result.__dir__ = -1;
22717 result.__filtered__ = true;
22718 } else {
22719 result = this.clone();
22720 result.__dir__ *= -1;
22721 }
22722 return result;
22723 }
22724
22725 /**
22726 * Extracts the unwrapped value from its lazy wrapper.
22727 *
22728 * @private
22729 * @name value
22730 * @memberOf LazyWrapper
22731 * @returns {*} Returns the unwrapped value.
22732 */
22733 function lazyValue() {
22734 var array = this.__wrapped__.value(),
22735 dir = this.__dir__,
22736 isArr = isArray(array),
22737 isRight = dir < 0,
22738 arrLength = isArr ? array.length : 0,
22739 view = getView(0, arrLength, this.__views__),
22740 start = view.start,
22741 end = view.end,
22742 length = end - start,
22743 index = isRight ? end : (start - 1),
22744 iteratees = this.__iteratees__,
22745 iterLength = iteratees.length,
22746 resIndex = 0,
22747 takeCount = nativeMin(length, this.__takeCount__);
22748
22749 if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
22750 return baseWrapperValue(array, this.__actions__);
22751 }
22752 var result = [];
22753
22754 outer:
22755 while (length-- && resIndex < takeCount) {
22756 index += dir;
22757
22758 var iterIndex = -1,
22759 value = array[index];
22760
22761 while (++iterIndex < iterLength) {
22762 var data = iteratees[iterIndex],
22763 iteratee = data.iteratee,
22764 type = data.type,
22765 computed = iteratee(value);
22766
22767 if (type == LAZY_MAP_FLAG) {
22768 value = computed;
22769 } else if (!computed) {
22770 if (type == LAZY_FILTER_FLAG) {
22771 continue outer;
22772 } else {
22773 break outer;
22774 }
22775 }
22776 }
22777 result[resIndex++] = value;
22778 }
22779 return result;
22780 }
22781
22782 // Ensure `LazyWrapper` is an instance of `baseLodash`.
22783 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
22784 LazyWrapper.prototype.constructor = LazyWrapper;
22785
22786 /*------------------------------------------------------------------------*/
22787
22788 /**
22789 * Creates a hash object.
22790 *
22791 * @private
22792 * @constructor
22793 * @param {Array} [entries] The key-value pairs to cache.
22794 */
22795 function Hash(entries) {
22796 var index = -1,
22797 length = entries == null ? 0 : entries.length;
22798
22799 this.clear();
22800 while (++index < length) {
22801 var entry = entries[index];
22802 this.set(entry[0], entry[1]);
22803 }
22804 }
22805
22806 /**
22807 * Removes all key-value entries from the hash.
22808 *
22809 * @private
22810 * @name clear
22811 * @memberOf Hash
22812 */
22813 function hashClear() {
22814 this.__data__ = nativeCreate ? nativeCreate(null) : {};
22815 this.size = 0;
22816 }
22817
22818 /**
22819 * Removes `key` and its value from the hash.
22820 *
22821 * @private
22822 * @name delete
22823 * @memberOf Hash
22824 * @param {Object} hash The hash to modify.
22825 * @param {string} key The key of the value to remove.
22826 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
22827 */
22828 function hashDelete(key) {
22829 var result = this.has(key) && delete this.__data__[key];
22830 this.size -= result ? 1 : 0;
22831 return result;
22832 }
22833
22834 /**
22835 * Gets the hash value for `key`.
22836 *
22837 * @private
22838 * @name get
22839 * @memberOf Hash
22840 * @param {string} key The key of the value to get.
22841 * @returns {*} Returns the entry value.
22842 */
22843 function hashGet(key) {
22844 var data = this.__data__;
22845 if (nativeCreate) {
22846 var result = data[key];
22847 return result === HASH_UNDEFINED ? undefined$1 : result;
22848 }
22849 return hasOwnProperty.call(data, key) ? data[key] : undefined$1;
22850 }
22851
22852 /**
22853 * Checks if a hash value for `key` exists.
22854 *
22855 * @private
22856 * @name has
22857 * @memberOf Hash
22858 * @param {string} key The key of the entry to check.
22859 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
22860 */
22861 function hashHas(key) {
22862 var data = this.__data__;
22863 return nativeCreate ? (data[key] !== undefined$1) : hasOwnProperty.call(data, key);
22864 }
22865
22866 /**
22867 * Sets the hash `key` to `value`.
22868 *
22869 * @private
22870 * @name set
22871 * @memberOf Hash
22872 * @param {string} key The key of the value to set.
22873 * @param {*} value The value to set.
22874 * @returns {Object} Returns the hash instance.
22875 */
22876 function hashSet(key, value) {
22877 var data = this.__data__;
22878 this.size += this.has(key) ? 0 : 1;
22879 data[key] = (nativeCreate && value === undefined$1) ? HASH_UNDEFINED : value;
22880 return this;
22881 }
22882
22883 // Add methods to `Hash`.
22884 Hash.prototype.clear = hashClear;
22885 Hash.prototype['delete'] = hashDelete;
22886 Hash.prototype.get = hashGet;
22887 Hash.prototype.has = hashHas;
22888 Hash.prototype.set = hashSet;
22889
22890 /*------------------------------------------------------------------------*/
22891
22892 /**
22893 * Creates an list cache object.
22894 *
22895 * @private
22896 * @constructor
22897 * @param {Array} [entries] The key-value pairs to cache.
22898 */
22899 function ListCache(entries) {
22900 var index = -1,
22901 length = entries == null ? 0 : entries.length;
22902
22903 this.clear();
22904 while (++index < length) {
22905 var entry = entries[index];
22906 this.set(entry[0], entry[1]);
22907 }
22908 }
22909
22910 /**
22911 * Removes all key-value entries from the list cache.
22912 *
22913 * @private
22914 * @name clear
22915 * @memberOf ListCache
22916 */
22917 function listCacheClear() {
22918 this.__data__ = [];
22919 this.size = 0;
22920 }
22921
22922 /**
22923 * Removes `key` and its value from the list cache.
22924 *
22925 * @private
22926 * @name delete
22927 * @memberOf ListCache
22928 * @param {string} key The key of the value to remove.
22929 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
22930 */
22931 function listCacheDelete(key) {
22932 var data = this.__data__,
22933 index = assocIndexOf(data, key);
22934
22935 if (index < 0) {
22936 return false;
22937 }
22938 var lastIndex = data.length - 1;
22939 if (index == lastIndex) {
22940 data.pop();
22941 } else {
22942 splice.call(data, index, 1);
22943 }
22944 --this.size;
22945 return true;
22946 }
22947
22948 /**
22949 * Gets the list cache value for `key`.
22950 *
22951 * @private
22952 * @name get
22953 * @memberOf ListCache
22954 * @param {string} key The key of the value to get.
22955 * @returns {*} Returns the entry value.
22956 */
22957 function listCacheGet(key) {
22958 var data = this.__data__,
22959 index = assocIndexOf(data, key);
22960
22961 return index < 0 ? undefined$1 : data[index][1];
22962 }
22963
22964 /**
22965 * Checks if a list cache value for `key` exists.
22966 *
22967 * @private
22968 * @name has
22969 * @memberOf ListCache
22970 * @param {string} key The key of the entry to check.
22971 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
22972 */
22973 function listCacheHas(key) {
22974 return assocIndexOf(this.__data__, key) > -1;
22975 }
22976
22977 /**
22978 * Sets the list cache `key` to `value`.
22979 *
22980 * @private
22981 * @name set
22982 * @memberOf ListCache
22983 * @param {string} key The key of the value to set.
22984 * @param {*} value The value to set.
22985 * @returns {Object} Returns the list cache instance.
22986 */
22987 function listCacheSet(key, value) {
22988 var data = this.__data__,
22989 index = assocIndexOf(data, key);
22990
22991 if (index < 0) {
22992 ++this.size;
22993 data.push([key, value]);
22994 } else {
22995 data[index][1] = value;
22996 }
22997 return this;
22998 }
22999
23000 // Add methods to `ListCache`.
23001 ListCache.prototype.clear = listCacheClear;
23002 ListCache.prototype['delete'] = listCacheDelete;
23003 ListCache.prototype.get = listCacheGet;
23004 ListCache.prototype.has = listCacheHas;
23005 ListCache.prototype.set = listCacheSet;
23006
23007 /*------------------------------------------------------------------------*/
23008
23009 /**
23010 * Creates a map cache object to store key-value pairs.
23011 *
23012 * @private
23013 * @constructor
23014 * @param {Array} [entries] The key-value pairs to cache.
23015 */
23016 function MapCache(entries) {
23017 var index = -1,
23018 length = entries == null ? 0 : entries.length;
23019
23020 this.clear();
23021 while (++index < length) {
23022 var entry = entries[index];
23023 this.set(entry[0], entry[1]);
23024 }
23025 }
23026
23027 /**
23028 * Removes all key-value entries from the map.
23029 *
23030 * @private
23031 * @name clear
23032 * @memberOf MapCache
23033 */
23034 function mapCacheClear() {
23035 this.size = 0;
23036 this.__data__ = {
23037 'hash': new Hash,
23038 'map': new (Map || ListCache),
23039 'string': new Hash
23040 };
23041 }
23042
23043 /**
23044 * Removes `key` and its value from the map.
23045 *
23046 * @private
23047 * @name delete
23048 * @memberOf MapCache
23049 * @param {string} key The key of the value to remove.
23050 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
23051 */
23052 function mapCacheDelete(key) {
23053 var result = getMapData(this, key)['delete'](key);
23054 this.size -= result ? 1 : 0;
23055 return result;
23056 }
23057
23058 /**
23059 * Gets the map value for `key`.
23060 *
23061 * @private
23062 * @name get
23063 * @memberOf MapCache
23064 * @param {string} key The key of the value to get.
23065 * @returns {*} Returns the entry value.
23066 */
23067 function mapCacheGet(key) {
23068 return getMapData(this, key).get(key);
23069 }
23070
23071 /**
23072 * Checks if a map value for `key` exists.
23073 *
23074 * @private
23075 * @name has
23076 * @memberOf MapCache
23077 * @param {string} key The key of the entry to check.
23078 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
23079 */
23080 function mapCacheHas(key) {
23081 return getMapData(this, key).has(key);
23082 }
23083
23084 /**
23085 * Sets the map `key` to `value`.
23086 *
23087 * @private
23088 * @name set
23089 * @memberOf MapCache
23090 * @param {string} key The key of the value to set.
23091 * @param {*} value The value to set.
23092 * @returns {Object} Returns the map cache instance.
23093 */
23094 function mapCacheSet(key, value) {
23095 var data = getMapData(this, key),
23096 size = data.size;
23097
23098 data.set(key, value);
23099 this.size += data.size == size ? 0 : 1;
23100 return this;
23101 }
23102
23103 // Add methods to `MapCache`.
23104 MapCache.prototype.clear = mapCacheClear;
23105 MapCache.prototype['delete'] = mapCacheDelete;
23106 MapCache.prototype.get = mapCacheGet;
23107 MapCache.prototype.has = mapCacheHas;
23108 MapCache.prototype.set = mapCacheSet;
23109
23110 /*------------------------------------------------------------------------*/
23111
23112 /**
23113 *
23114 * Creates an array cache object to store unique values.
23115 *
23116 * @private
23117 * @constructor
23118 * @param {Array} [values] The values to cache.
23119 */
23120 function SetCache(values) {
23121 var index = -1,
23122 length = values == null ? 0 : values.length;
23123
23124 this.__data__ = new MapCache;
23125 while (++index < length) {
23126 this.add(values[index]);
23127 }
23128 }
23129
23130 /**
23131 * Adds `value` to the array cache.
23132 *
23133 * @private
23134 * @name add
23135 * @memberOf SetCache
23136 * @alias push
23137 * @param {*} value The value to cache.
23138 * @returns {Object} Returns the cache instance.
23139 */
23140 function setCacheAdd(value) {
23141 this.__data__.set(value, HASH_UNDEFINED);
23142 return this;
23143 }
23144
23145 /**
23146 * Checks if `value` is in the array cache.
23147 *
23148 * @private
23149 * @name has
23150 * @memberOf SetCache
23151 * @param {*} value The value to search for.
23152 * @returns {number} Returns `true` if `value` is found, else `false`.
23153 */
23154 function setCacheHas(value) {
23155 return this.__data__.has(value);
23156 }
23157
23158 // Add methods to `SetCache`.
23159 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
23160 SetCache.prototype.has = setCacheHas;
23161
23162 /*------------------------------------------------------------------------*/
23163
23164 /**
23165 * Creates a stack cache object to store key-value pairs.
23166 *
23167 * @private
23168 * @constructor
23169 * @param {Array} [entries] The key-value pairs to cache.
23170 */
23171 function Stack(entries) {
23172 var data = this.__data__ = new ListCache(entries);
23173 this.size = data.size;
23174 }
23175
23176 /**
23177 * Removes all key-value entries from the stack.
23178 *
23179 * @private
23180 * @name clear
23181 * @memberOf Stack
23182 */
23183 function stackClear() {
23184 this.__data__ = new ListCache;
23185 this.size = 0;
23186 }
23187
23188 /**
23189 * Removes `key` and its value from the stack.
23190 *
23191 * @private
23192 * @name delete
23193 * @memberOf Stack
23194 * @param {string} key The key of the value to remove.
23195 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
23196 */
23197 function stackDelete(key) {
23198 var data = this.__data__,
23199 result = data['delete'](key);
23200
23201 this.size = data.size;
23202 return result;
23203 }
23204
23205 /**
23206 * Gets the stack value for `key`.
23207 *
23208 * @private
23209 * @name get
23210 * @memberOf Stack
23211 * @param {string} key The key of the value to get.
23212 * @returns {*} Returns the entry value.
23213 */
23214 function stackGet(key) {
23215 return this.__data__.get(key);
23216 }
23217
23218 /**
23219 * Checks if a stack value for `key` exists.
23220 *
23221 * @private
23222 * @name has
23223 * @memberOf Stack
23224 * @param {string} key The key of the entry to check.
23225 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
23226 */
23227 function stackHas(key) {
23228 return this.__data__.has(key);
23229 }
23230
23231 /**
23232 * Sets the stack `key` to `value`.
23233 *
23234 * @private
23235 * @name set
23236 * @memberOf Stack
23237 * @param {string} key The key of the value to set.
23238 * @param {*} value The value to set.
23239 * @returns {Object} Returns the stack cache instance.
23240 */
23241 function stackSet(key, value) {
23242 var data = this.__data__;
23243 if (data instanceof ListCache) {
23244 var pairs = data.__data__;
23245 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
23246 pairs.push([key, value]);
23247 this.size = ++data.size;
23248 return this;
23249 }
23250 data = this.__data__ = new MapCache(pairs);
23251 }
23252 data.set(key, value);
23253 this.size = data.size;
23254 return this;
23255 }
23256
23257 // Add methods to `Stack`.
23258 Stack.prototype.clear = stackClear;
23259 Stack.prototype['delete'] = stackDelete;
23260 Stack.prototype.get = stackGet;
23261 Stack.prototype.has = stackHas;
23262 Stack.prototype.set = stackSet;
23263
23264 /*------------------------------------------------------------------------*/
23265
23266 /**
23267 * Creates an array of the enumerable property names of the array-like `value`.
23268 *
23269 * @private
23270 * @param {*} value The value to query.
23271 * @param {boolean} inherited Specify returning inherited property names.
23272 * @returns {Array} Returns the array of property names.
23273 */
23274 function arrayLikeKeys(value, inherited) {
23275 var isArr = isArray(value),
23276 isArg = !isArr && isArguments(value),
23277 isBuff = !isArr && !isArg && isBuffer(value),
23278 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
23279 skipIndexes = isArr || isArg || isBuff || isType,
23280 result = skipIndexes ? baseTimes(value.length, String) : [],
23281 length = result.length;
23282
23283 for (var key in value) {
23284 if ((inherited || hasOwnProperty.call(value, key)) &&
23285 !(skipIndexes && (
23286 // Safari 9 has enumerable `arguments.length` in strict mode.
23287 key == 'length' ||
23288 // Node.js 0.10 has enumerable non-index properties on buffers.
23289 (isBuff && (key == 'offset' || key == 'parent')) ||
23290 // PhantomJS 2 has enumerable non-index properties on typed arrays.
23291 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
23292 // Skip index properties.
23293 isIndex(key, length)
23294 ))) {
23295 result.push(key);
23296 }
23297 }
23298 return result;
23299 }
23300
23301 /**
23302 * A specialized version of `_.sample` for arrays.
23303 *
23304 * @private
23305 * @param {Array} array The array to sample.
23306 * @returns {*} Returns the random element.
23307 */
23308 function arraySample(array) {
23309 var length = array.length;
23310 return length ? array[baseRandom(0, length - 1)] : undefined$1;
23311 }
23312
23313 /**
23314 * A specialized version of `_.sampleSize` for arrays.
23315 *
23316 * @private
23317 * @param {Array} array The array to sample.
23318 * @param {number} n The number of elements to sample.
23319 * @returns {Array} Returns the random elements.
23320 */
23321 function arraySampleSize(array, n) {
23322 return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
23323 }
23324
23325 /**
23326 * A specialized version of `_.shuffle` for arrays.
23327 *
23328 * @private
23329 * @param {Array} array The array to shuffle.
23330 * @returns {Array} Returns the new shuffled array.
23331 */
23332 function arrayShuffle(array) {
23333 return shuffleSelf(copyArray(array));
23334 }
23335
23336 /**
23337 * This function is like `assignValue` except that it doesn't assign
23338 * `undefined` values.
23339 *
23340 * @private
23341 * @param {Object} object The object to modify.
23342 * @param {string} key The key of the property to assign.
23343 * @param {*} value The value to assign.
23344 */
23345 function assignMergeValue(object, key, value) {
23346 if ((value !== undefined$1 && !eq(object[key], value)) ||
23347 (value === undefined$1 && !(key in object))) {
23348 baseAssignValue(object, key, value);
23349 }
23350 }
23351
23352 /**
23353 * Assigns `value` to `key` of `object` if the existing value is not equivalent
23354 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
23355 * for equality comparisons.
23356 *
23357 * @private
23358 * @param {Object} object The object to modify.
23359 * @param {string} key The key of the property to assign.
23360 * @param {*} value The value to assign.
23361 */
23362 function assignValue(object, key, value) {
23363 var objValue = object[key];
23364 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
23365 (value === undefined$1 && !(key in object))) {
23366 baseAssignValue(object, key, value);
23367 }
23368 }
23369
23370 /**
23371 * Gets the index at which the `key` is found in `array` of key-value pairs.
23372 *
23373 * @private
23374 * @param {Array} array The array to inspect.
23375 * @param {*} key The key to search for.
23376 * @returns {number} Returns the index of the matched value, else `-1`.
23377 */
23378 function assocIndexOf(array, key) {
23379 var length = array.length;
23380 while (length--) {
23381 if (eq(array[length][0], key)) {
23382 return length;
23383 }
23384 }
23385 return -1;
23386 }
23387
23388 /**
23389 * Aggregates elements of `collection` on `accumulator` with keys transformed
23390 * by `iteratee` and values set by `setter`.
23391 *
23392 * @private
23393 * @param {Array|Object} collection The collection to iterate over.
23394 * @param {Function} setter The function to set `accumulator` values.
23395 * @param {Function} iteratee The iteratee to transform keys.
23396 * @param {Object} accumulator The initial aggregated object.
23397 * @returns {Function} Returns `accumulator`.
23398 */
23399 function baseAggregator(collection, setter, iteratee, accumulator) {
23400 baseEach(collection, function(value, key, collection) {
23401 setter(accumulator, value, iteratee(value), collection);
23402 });
23403 return accumulator;
23404 }
23405
23406 /**
23407 * The base implementation of `_.assign` without support for multiple sources
23408 * or `customizer` functions.
23409 *
23410 * @private
23411 * @param {Object} object The destination object.
23412 * @param {Object} source The source object.
23413 * @returns {Object} Returns `object`.
23414 */
23415 function baseAssign(object, source) {
23416 return object && copyObject(source, keys(source), object);
23417 }
23418
23419 /**
23420 * The base implementation of `_.assignIn` without support for multiple sources
23421 * or `customizer` functions.
23422 *
23423 * @private
23424 * @param {Object} object The destination object.
23425 * @param {Object} source The source object.
23426 * @returns {Object} Returns `object`.
23427 */
23428 function baseAssignIn(object, source) {
23429 return object && copyObject(source, keysIn(source), object);
23430 }
23431
23432 /**
23433 * The base implementation of `assignValue` and `assignMergeValue` without
23434 * value checks.
23435 *
23436 * @private
23437 * @param {Object} object The object to modify.
23438 * @param {string} key The key of the property to assign.
23439 * @param {*} value The value to assign.
23440 */
23441 function baseAssignValue(object, key, value) {
23442 if (key == '__proto__' && defineProperty) {
23443 defineProperty(object, key, {
23444 'configurable': true,
23445 'enumerable': true,
23446 'value': value,
23447 'writable': true
23448 });
23449 } else {
23450 object[key] = value;
23451 }
23452 }
23453
23454 /**
23455 * The base implementation of `_.at` without support for individual paths.
23456 *
23457 * @private
23458 * @param {Object} object The object to iterate over.
23459 * @param {string[]} paths The property paths to pick.
23460 * @returns {Array} Returns the picked elements.
23461 */
23462 function baseAt(object, paths) {
23463 var index = -1,
23464 length = paths.length,
23465 result = Array(length),
23466 skip = object == null;
23467
23468 while (++index < length) {
23469 result[index] = skip ? undefined$1 : get(object, paths[index]);
23470 }
23471 return result;
23472 }
23473
23474 /**
23475 * The base implementation of `_.clamp` which doesn't coerce arguments.
23476 *
23477 * @private
23478 * @param {number} number The number to clamp.
23479 * @param {number} [lower] The lower bound.
23480 * @param {number} upper The upper bound.
23481 * @returns {number} Returns the clamped number.
23482 */
23483 function baseClamp(number, lower, upper) {
23484 if (number === number) {
23485 if (upper !== undefined$1) {
23486 number = number <= upper ? number : upper;
23487 }
23488 if (lower !== undefined$1) {
23489 number = number >= lower ? number : lower;
23490 }
23491 }
23492 return number;
23493 }
23494
23495 /**
23496 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
23497 * traversed objects.
23498 *
23499 * @private
23500 * @param {*} value The value to clone.
23501 * @param {boolean} bitmask The bitmask flags.
23502 * 1 - Deep clone
23503 * 2 - Flatten inherited properties
23504 * 4 - Clone symbols
23505 * @param {Function} [customizer] The function to customize cloning.
23506 * @param {string} [key] The key of `value`.
23507 * @param {Object} [object] The parent object of `value`.
23508 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
23509 * @returns {*} Returns the cloned value.
23510 */
23511 function baseClone(value, bitmask, customizer, key, object, stack) {
23512 var result,
23513 isDeep = bitmask & CLONE_DEEP_FLAG,
23514 isFlat = bitmask & CLONE_FLAT_FLAG,
23515 isFull = bitmask & CLONE_SYMBOLS_FLAG;
23516
23517 if (customizer) {
23518 result = object ? customizer(value, key, object, stack) : customizer(value);
23519 }
23520 if (result !== undefined$1) {
23521 return result;
23522 }
23523 if (!isObject(value)) {
23524 return value;
23525 }
23526 var isArr = isArray(value);
23527 if (isArr) {
23528 result = initCloneArray(value);
23529 if (!isDeep) {
23530 return copyArray(value, result);
23531 }
23532 } else {
23533 var tag = getTag(value),
23534 isFunc = tag == funcTag || tag == genTag;
23535
23536 if (isBuffer(value)) {
23537 return cloneBuffer(value, isDeep);
23538 }
23539 if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
23540 result = (isFlat || isFunc) ? {} : initCloneObject(value);
23541 if (!isDeep) {
23542 return isFlat
23543 ? copySymbolsIn(value, baseAssignIn(result, value))
23544 : copySymbols(value, baseAssign(result, value));
23545 }
23546 } else {
23547 if (!cloneableTags[tag]) {
23548 return object ? value : {};
23549 }
23550 result = initCloneByTag(value, tag, isDeep);
23551 }
23552 }
23553 // Check for circular references and return its corresponding clone.
23554 stack || (stack = new Stack);
23555 var stacked = stack.get(value);
23556 if (stacked) {
23557 return stacked;
23558 }
23559 stack.set(value, result);
23560
23561 if (isSet(value)) {
23562 value.forEach(function(subValue) {
23563 result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
23564 });
23565 } else if (isMap(value)) {
23566 value.forEach(function(subValue, key) {
23567 result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
23568 });
23569 }
23570
23571 var keysFunc = isFull
23572 ? (isFlat ? getAllKeysIn : getAllKeys)
23573 : (isFlat ? keysIn : keys);
23574
23575 var props = isArr ? undefined$1 : keysFunc(value);
23576 arrayEach(props || value, function(subValue, key) {
23577 if (props) {
23578 key = subValue;
23579 subValue = value[key];
23580 }
23581 // Recursively populate clone (susceptible to call stack limits).
23582 assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
23583 });
23584 return result;
23585 }
23586
23587 /**
23588 * The base implementation of `_.conforms` which doesn't clone `source`.
23589 *
23590 * @private
23591 * @param {Object} source The object of property predicates to conform to.
23592 * @returns {Function} Returns the new spec function.
23593 */
23594 function baseConforms(source) {
23595 var props = keys(source);
23596 return function(object) {
23597 return baseConformsTo(object, source, props);
23598 };
23599 }
23600
23601 /**
23602 * The base implementation of `_.conformsTo` which accepts `props` to check.
23603 *
23604 * @private
23605 * @param {Object} object The object to inspect.
23606 * @param {Object} source The object of property predicates to conform to.
23607 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
23608 */
23609 function baseConformsTo(object, source, props) {
23610 var length = props.length;
23611 if (object == null) {
23612 return !length;
23613 }
23614 object = Object(object);
23615 while (length--) {
23616 var key = props[length],
23617 predicate = source[key],
23618 value = object[key];
23619
23620 if ((value === undefined$1 && !(key in object)) || !predicate(value)) {
23621 return false;
23622 }
23623 }
23624 return true;
23625 }
23626
23627 /**
23628 * The base implementation of `_.delay` and `_.defer` which accepts `args`
23629 * to provide to `func`.
23630 *
23631 * @private
23632 * @param {Function} func The function to delay.
23633 * @param {number} wait The number of milliseconds to delay invocation.
23634 * @param {Array} args The arguments to provide to `func`.
23635 * @returns {number|Object} Returns the timer id or timeout object.
23636 */
23637 function baseDelay(func, wait, args) {
23638 if (typeof func != 'function') {
23639 throw new Error(FUNC_ERROR_TEXT);
23640 }
23641 return setTimeout(function() { func.apply(undefined$1, args); }, wait);
23642 }
23643
23644 /**
23645 * The base implementation of methods like `_.difference` without support
23646 * for excluding multiple arrays or iteratee shorthands.
23647 *
23648 * @private
23649 * @param {Array} array The array to inspect.
23650 * @param {Array} values The values to exclude.
23651 * @param {Function} [iteratee] The iteratee invoked per element.
23652 * @param {Function} [comparator] The comparator invoked per element.
23653 * @returns {Array} Returns the new array of filtered values.
23654 */
23655 function baseDifference(array, values, iteratee, comparator) {
23656 var index = -1,
23657 includes = arrayIncludes,
23658 isCommon = true,
23659 length = array.length,
23660 result = [],
23661 valuesLength = values.length;
23662
23663 if (!length) {
23664 return result;
23665 }
23666 if (iteratee) {
23667 values = arrayMap(values, baseUnary(iteratee));
23668 }
23669 if (comparator) {
23670 includes = arrayIncludesWith;
23671 isCommon = false;
23672 }
23673 else if (values.length >= LARGE_ARRAY_SIZE) {
23674 includes = cacheHas;
23675 isCommon = false;
23676 values = new SetCache(values);
23677 }
23678 outer:
23679 while (++index < length) {
23680 var value = array[index],
23681 computed = iteratee == null ? value : iteratee(value);
23682
23683 value = (comparator || value !== 0) ? value : 0;
23684 if (isCommon && computed === computed) {
23685 var valuesIndex = valuesLength;
23686 while (valuesIndex--) {
23687 if (values[valuesIndex] === computed) {
23688 continue outer;
23689 }
23690 }
23691 result.push(value);
23692 }
23693 else if (!includes(values, computed, comparator)) {
23694 result.push(value);
23695 }
23696 }
23697 return result;
23698 }
23699
23700 /**
23701 * The base implementation of `_.forEach` without support for iteratee shorthands.
23702 *
23703 * @private
23704 * @param {Array|Object} collection The collection to iterate over.
23705 * @param {Function} iteratee The function invoked per iteration.
23706 * @returns {Array|Object} Returns `collection`.
23707 */
23708 var baseEach = createBaseEach(baseForOwn);
23709
23710 /**
23711 * The base implementation of `_.forEachRight` without support for iteratee shorthands.
23712 *
23713 * @private
23714 * @param {Array|Object} collection The collection to iterate over.
23715 * @param {Function} iteratee The function invoked per iteration.
23716 * @returns {Array|Object} Returns `collection`.
23717 */
23718 var baseEachRight = createBaseEach(baseForOwnRight, true);
23719
23720 /**
23721 * The base implementation of `_.every` without support for iteratee shorthands.
23722 *
23723 * @private
23724 * @param {Array|Object} collection The collection to iterate over.
23725 * @param {Function} predicate The function invoked per iteration.
23726 * @returns {boolean} Returns `true` if all elements pass the predicate check,
23727 * else `false`
23728 */
23729 function baseEvery(collection, predicate) {
23730 var result = true;
23731 baseEach(collection, function(value, index, collection) {
23732 result = !!predicate(value, index, collection);
23733 return result;
23734 });
23735 return result;
23736 }
23737
23738 /**
23739 * The base implementation of methods like `_.max` and `_.min` which accepts a
23740 * `comparator` to determine the extremum value.
23741 *
23742 * @private
23743 * @param {Array} array The array to iterate over.
23744 * @param {Function} iteratee The iteratee invoked per iteration.
23745 * @param {Function} comparator The comparator used to compare values.
23746 * @returns {*} Returns the extremum value.
23747 */
23748 function baseExtremum(array, iteratee, comparator) {
23749 var index = -1,
23750 length = array.length;
23751
23752 while (++index < length) {
23753 var value = array[index],
23754 current = iteratee(value);
23755
23756 if (current != null && (computed === undefined$1
23757 ? (current === current && !isSymbol(current))
23758 : comparator(current, computed)
23759 )) {
23760 var computed = current,
23761 result = value;
23762 }
23763 }
23764 return result;
23765 }
23766
23767 /**
23768 * The base implementation of `_.fill` without an iteratee call guard.
23769 *
23770 * @private
23771 * @param {Array} array The array to fill.
23772 * @param {*} value The value to fill `array` with.
23773 * @param {number} [start=0] The start position.
23774 * @param {number} [end=array.length] The end position.
23775 * @returns {Array} Returns `array`.
23776 */
23777 function baseFill(array, value, start, end) {
23778 var length = array.length;
23779
23780 start = toInteger(start);
23781 if (start < 0) {
23782 start = -start > length ? 0 : (length + start);
23783 }
23784 end = (end === undefined$1 || end > length) ? length : toInteger(end);
23785 if (end < 0) {
23786 end += length;
23787 }
23788 end = start > end ? 0 : toLength(end);
23789 while (start < end) {
23790 array[start++] = value;
23791 }
23792 return array;
23793 }
23794
23795 /**
23796 * The base implementation of `_.filter` without support for iteratee shorthands.
23797 *
23798 * @private
23799 * @param {Array|Object} collection The collection to iterate over.
23800 * @param {Function} predicate The function invoked per iteration.
23801 * @returns {Array} Returns the new filtered array.
23802 */
23803 function baseFilter(collection, predicate) {
23804 var result = [];
23805 baseEach(collection, function(value, index, collection) {
23806 if (predicate(value, index, collection)) {
23807 result.push(value);
23808 }
23809 });
23810 return result;
23811 }
23812
23813 /**
23814 * The base implementation of `_.flatten` with support for restricting flattening.
23815 *
23816 * @private
23817 * @param {Array} array The array to flatten.
23818 * @param {number} depth The maximum recursion depth.
23819 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
23820 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
23821 * @param {Array} [result=[]] The initial result value.
23822 * @returns {Array} Returns the new flattened array.
23823 */
23824 function baseFlatten(array, depth, predicate, isStrict, result) {
23825 var index = -1,
23826 length = array.length;
23827
23828 predicate || (predicate = isFlattenable);
23829 result || (result = []);
23830
23831 while (++index < length) {
23832 var value = array[index];
23833 if (depth > 0 && predicate(value)) {
23834 if (depth > 1) {
23835 // Recursively flatten arrays (susceptible to call stack limits).
23836 baseFlatten(value, depth - 1, predicate, isStrict, result);
23837 } else {
23838 arrayPush(result, value);
23839 }
23840 } else if (!isStrict) {
23841 result[result.length] = value;
23842 }
23843 }
23844 return result;
23845 }
23846
23847 /**
23848 * The base implementation of `baseForOwn` which iterates over `object`
23849 * properties returned by `keysFunc` and invokes `iteratee` for each property.
23850 * Iteratee functions may exit iteration early by explicitly returning `false`.
23851 *
23852 * @private
23853 * @param {Object} object The object to iterate over.
23854 * @param {Function} iteratee The function invoked per iteration.
23855 * @param {Function} keysFunc The function to get the keys of `object`.
23856 * @returns {Object} Returns `object`.
23857 */
23858 var baseFor = createBaseFor();
23859
23860 /**
23861 * This function is like `baseFor` except that it iterates over properties
23862 * in the opposite order.
23863 *
23864 * @private
23865 * @param {Object} object The object to iterate over.
23866 * @param {Function} iteratee The function invoked per iteration.
23867 * @param {Function} keysFunc The function to get the keys of `object`.
23868 * @returns {Object} Returns `object`.
23869 */
23870 var baseForRight = createBaseFor(true);
23871
23872 /**
23873 * The base implementation of `_.forOwn` without support for iteratee shorthands.
23874 *
23875 * @private
23876 * @param {Object} object The object to iterate over.
23877 * @param {Function} iteratee The function invoked per iteration.
23878 * @returns {Object} Returns `object`.
23879 */
23880 function baseForOwn(object, iteratee) {
23881 return object && baseFor(object, iteratee, keys);
23882 }
23883
23884 /**
23885 * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
23886 *
23887 * @private
23888 * @param {Object} object The object to iterate over.
23889 * @param {Function} iteratee The function invoked per iteration.
23890 * @returns {Object} Returns `object`.
23891 */
23892 function baseForOwnRight(object, iteratee) {
23893 return object && baseForRight(object, iteratee, keys);
23894 }
23895
23896 /**
23897 * The base implementation of `_.functions` which creates an array of
23898 * `object` function property names filtered from `props`.
23899 *
23900 * @private
23901 * @param {Object} object The object to inspect.
23902 * @param {Array} props The property names to filter.
23903 * @returns {Array} Returns the function names.
23904 */
23905 function baseFunctions(object, props) {
23906 return arrayFilter(props, function(key) {
23907 return isFunction(object[key]);
23908 });
23909 }
23910
23911 /**
23912 * The base implementation of `_.get` without support for default values.
23913 *
23914 * @private
23915 * @param {Object} object The object to query.
23916 * @param {Array|string} path The path of the property to get.
23917 * @returns {*} Returns the resolved value.
23918 */
23919 function baseGet(object, path) {
23920 path = castPath(path, object);
23921
23922 var index = 0,
23923 length = path.length;
23924
23925 while (object != null && index < length) {
23926 object = object[toKey(path[index++])];
23927 }
23928 return (index && index == length) ? object : undefined$1;
23929 }
23930
23931 /**
23932 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
23933 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
23934 * symbols of `object`.
23935 *
23936 * @private
23937 * @param {Object} object The object to query.
23938 * @param {Function} keysFunc The function to get the keys of `object`.
23939 * @param {Function} symbolsFunc The function to get the symbols of `object`.
23940 * @returns {Array} Returns the array of property names and symbols.
23941 */
23942 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
23943 var result = keysFunc(object);
23944 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
23945 }
23946
23947 /**
23948 * The base implementation of `getTag` without fallbacks for buggy environments.
23949 *
23950 * @private
23951 * @param {*} value The value to query.
23952 * @returns {string} Returns the `toStringTag`.
23953 */
23954 function baseGetTag(value) {
23955 if (value == null) {
23956 return value === undefined$1 ? undefinedTag : nullTag;
23957 }
23958 return (symToStringTag && symToStringTag in Object(value))
23959 ? getRawTag(value)
23960 : objectToString(value);
23961 }
23962
23963 /**
23964 * The base implementation of `_.gt` which doesn't coerce arguments.
23965 *
23966 * @private
23967 * @param {*} value The value to compare.
23968 * @param {*} other The other value to compare.
23969 * @returns {boolean} Returns `true` if `value` is greater than `other`,
23970 * else `false`.
23971 */
23972 function baseGt(value, other) {
23973 return value > other;
23974 }
23975
23976 /**
23977 * The base implementation of `_.has` without support for deep paths.
23978 *
23979 * @private
23980 * @param {Object} [object] The object to query.
23981 * @param {Array|string} key The key to check.
23982 * @returns {boolean} Returns `true` if `key` exists, else `false`.
23983 */
23984 function baseHas(object, key) {
23985 return object != null && hasOwnProperty.call(object, key);
23986 }
23987
23988 /**
23989 * The base implementation of `_.hasIn` without support for deep paths.
23990 *
23991 * @private
23992 * @param {Object} [object] The object to query.
23993 * @param {Array|string} key The key to check.
23994 * @returns {boolean} Returns `true` if `key` exists, else `false`.
23995 */
23996 function baseHasIn(object, key) {
23997 return object != null && key in Object(object);
23998 }
23999
24000 /**
24001 * The base implementation of `_.inRange` which doesn't coerce arguments.
24002 *
24003 * @private
24004 * @param {number} number The number to check.
24005 * @param {number} start The start of the range.
24006 * @param {number} end The end of the range.
24007 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
24008 */
24009 function baseInRange(number, start, end) {
24010 return number >= nativeMin(start, end) && number < nativeMax(start, end);
24011 }
24012
24013 /**
24014 * The base implementation of methods like `_.intersection`, without support
24015 * for iteratee shorthands, that accepts an array of arrays to inspect.
24016 *
24017 * @private
24018 * @param {Array} arrays The arrays to inspect.
24019 * @param {Function} [iteratee] The iteratee invoked per element.
24020 * @param {Function} [comparator] The comparator invoked per element.
24021 * @returns {Array} Returns the new array of shared values.
24022 */
24023 function baseIntersection(arrays, iteratee, comparator) {
24024 var includes = comparator ? arrayIncludesWith : arrayIncludes,
24025 length = arrays[0].length,
24026 othLength = arrays.length,
24027 othIndex = othLength,
24028 caches = Array(othLength),
24029 maxLength = Infinity,
24030 result = [];
24031
24032 while (othIndex--) {
24033 var array = arrays[othIndex];
24034 if (othIndex && iteratee) {
24035 array = arrayMap(array, baseUnary(iteratee));
24036 }
24037 maxLength = nativeMin(array.length, maxLength);
24038 caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
24039 ? new SetCache(othIndex && array)
24040 : undefined$1;
24041 }
24042 array = arrays[0];
24043
24044 var index = -1,
24045 seen = caches[0];
24046
24047 outer:
24048 while (++index < length && result.length < maxLength) {
24049 var value = array[index],
24050 computed = iteratee ? iteratee(value) : value;
24051
24052 value = (comparator || value !== 0) ? value : 0;
24053 if (!(seen
24054 ? cacheHas(seen, computed)
24055 : includes(result, computed, comparator)
24056 )) {
24057 othIndex = othLength;
24058 while (--othIndex) {
24059 var cache = caches[othIndex];
24060 if (!(cache
24061 ? cacheHas(cache, computed)
24062 : includes(arrays[othIndex], computed, comparator))
24063 ) {
24064 continue outer;
24065 }
24066 }
24067 if (seen) {
24068 seen.push(computed);
24069 }
24070 result.push(value);
24071 }
24072 }
24073 return result;
24074 }
24075
24076 /**
24077 * The base implementation of `_.invert` and `_.invertBy` which inverts
24078 * `object` with values transformed by `iteratee` and set by `setter`.
24079 *
24080 * @private
24081 * @param {Object} object The object to iterate over.
24082 * @param {Function} setter The function to set `accumulator` values.
24083 * @param {Function} iteratee The iteratee to transform values.
24084 * @param {Object} accumulator The initial inverted object.
24085 * @returns {Function} Returns `accumulator`.
24086 */
24087 function baseInverter(object, setter, iteratee, accumulator) {
24088 baseForOwn(object, function(value, key, object) {
24089 setter(accumulator, iteratee(value), key, object);
24090 });
24091 return accumulator;
24092 }
24093
24094 /**
24095 * The base implementation of `_.invoke` without support for individual
24096 * method arguments.
24097 *
24098 * @private
24099 * @param {Object} object The object to query.
24100 * @param {Array|string} path The path of the method to invoke.
24101 * @param {Array} args The arguments to invoke the method with.
24102 * @returns {*} Returns the result of the invoked method.
24103 */
24104 function baseInvoke(object, path, args) {
24105 path = castPath(path, object);
24106 object = parent(object, path);
24107 var func = object == null ? object : object[toKey(last(path))];
24108 return func == null ? undefined$1 : apply(func, object, args);
24109 }
24110
24111 /**
24112 * The base implementation of `_.isArguments`.
24113 *
24114 * @private
24115 * @param {*} value The value to check.
24116 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
24117 */
24118 function baseIsArguments(value) {
24119 return isObjectLike(value) && baseGetTag(value) == argsTag;
24120 }
24121
24122 /**
24123 * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
24124 *
24125 * @private
24126 * @param {*} value The value to check.
24127 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
24128 */
24129 function baseIsArrayBuffer(value) {
24130 return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
24131 }
24132
24133 /**
24134 * The base implementation of `_.isDate` without Node.js optimizations.
24135 *
24136 * @private
24137 * @param {*} value The value to check.
24138 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
24139 */
24140 function baseIsDate(value) {
24141 return isObjectLike(value) && baseGetTag(value) == dateTag;
24142 }
24143
24144 /**
24145 * The base implementation of `_.isEqual` which supports partial comparisons
24146 * and tracks traversed objects.
24147 *
24148 * @private
24149 * @param {*} value The value to compare.
24150 * @param {*} other The other value to compare.
24151 * @param {boolean} bitmask The bitmask flags.
24152 * 1 - Unordered comparison
24153 * 2 - Partial comparison
24154 * @param {Function} [customizer] The function to customize comparisons.
24155 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
24156 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
24157 */
24158 function baseIsEqual(value, other, bitmask, customizer, stack) {
24159 if (value === other) {
24160 return true;
24161 }
24162 if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
24163 return value !== value && other !== other;
24164 }
24165 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
24166 }
24167
24168 /**
24169 * A specialized version of `baseIsEqual` for arrays and objects which performs
24170 * deep comparisons and tracks traversed objects enabling objects with circular
24171 * references to be compared.
24172 *
24173 * @private
24174 * @param {Object} object The object to compare.
24175 * @param {Object} other The other object to compare.
24176 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
24177 * @param {Function} customizer The function to customize comparisons.
24178 * @param {Function} equalFunc The function to determine equivalents of values.
24179 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
24180 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
24181 */
24182 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
24183 var objIsArr = isArray(object),
24184 othIsArr = isArray(other),
24185 objTag = objIsArr ? arrayTag : getTag(object),
24186 othTag = othIsArr ? arrayTag : getTag(other);
24187
24188 objTag = objTag == argsTag ? objectTag : objTag;
24189 othTag = othTag == argsTag ? objectTag : othTag;
24190
24191 var objIsObj = objTag == objectTag,
24192 othIsObj = othTag == objectTag,
24193 isSameTag = objTag == othTag;
24194
24195 if (isSameTag && isBuffer(object)) {
24196 if (!isBuffer(other)) {
24197 return false;
24198 }
24199 objIsArr = true;
24200 objIsObj = false;
24201 }
24202 if (isSameTag && !objIsObj) {
24203 stack || (stack = new Stack);
24204 return (objIsArr || isTypedArray(object))
24205 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
24206 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
24207 }
24208 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
24209 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
24210 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
24211
24212 if (objIsWrapped || othIsWrapped) {
24213 var objUnwrapped = objIsWrapped ? object.value() : object,
24214 othUnwrapped = othIsWrapped ? other.value() : other;
24215
24216 stack || (stack = new Stack);
24217 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
24218 }
24219 }
24220 if (!isSameTag) {
24221 return false;
24222 }
24223 stack || (stack = new Stack);
24224 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
24225 }
24226
24227 /**
24228 * The base implementation of `_.isMap` without Node.js optimizations.
24229 *
24230 * @private
24231 * @param {*} value The value to check.
24232 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
24233 */
24234 function baseIsMap(value) {
24235 return isObjectLike(value) && getTag(value) == mapTag;
24236 }
24237
24238 /**
24239 * The base implementation of `_.isMatch` without support for iteratee shorthands.
24240 *
24241 * @private
24242 * @param {Object} object The object to inspect.
24243 * @param {Object} source The object of property values to match.
24244 * @param {Array} matchData The property names, values, and compare flags to match.
24245 * @param {Function} [customizer] The function to customize comparisons.
24246 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
24247 */
24248 function baseIsMatch(object, source, matchData, customizer) {
24249 var index = matchData.length,
24250 length = index,
24251 noCustomizer = !customizer;
24252
24253 if (object == null) {
24254 return !length;
24255 }
24256 object = Object(object);
24257 while (index--) {
24258 var data = matchData[index];
24259 if ((noCustomizer && data[2])
24260 ? data[1] !== object[data[0]]
24261 : !(data[0] in object)
24262 ) {
24263 return false;
24264 }
24265 }
24266 while (++index < length) {
24267 data = matchData[index];
24268 var key = data[0],
24269 objValue = object[key],
24270 srcValue = data[1];
24271
24272 if (noCustomizer && data[2]) {
24273 if (objValue === undefined$1 && !(key in object)) {
24274 return false;
24275 }
24276 } else {
24277 var stack = new Stack;
24278 if (customizer) {
24279 var result = customizer(objValue, srcValue, key, object, source, stack);
24280 }
24281 if (!(result === undefined$1
24282 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
24283 : result
24284 )) {
24285 return false;
24286 }
24287 }
24288 }
24289 return true;
24290 }
24291
24292 /**
24293 * The base implementation of `_.isNative` without bad shim checks.
24294 *
24295 * @private
24296 * @param {*} value The value to check.
24297 * @returns {boolean} Returns `true` if `value` is a native function,
24298 * else `false`.
24299 */
24300 function baseIsNative(value) {
24301 if (!isObject(value) || isMasked(value)) {
24302 return false;
24303 }
24304 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
24305 return pattern.test(toSource(value));
24306 }
24307
24308 /**
24309 * The base implementation of `_.isRegExp` without Node.js optimizations.
24310 *
24311 * @private
24312 * @param {*} value The value to check.
24313 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
24314 */
24315 function baseIsRegExp(value) {
24316 return isObjectLike(value) && baseGetTag(value) == regexpTag;
24317 }
24318
24319 /**
24320 * The base implementation of `_.isSet` without Node.js optimizations.
24321 *
24322 * @private
24323 * @param {*} value The value to check.
24324 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
24325 */
24326 function baseIsSet(value) {
24327 return isObjectLike(value) && getTag(value) == setTag;
24328 }
24329
24330 /**
24331 * The base implementation of `_.isTypedArray` without Node.js optimizations.
24332 *
24333 * @private
24334 * @param {*} value The value to check.
24335 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
24336 */
24337 function baseIsTypedArray(value) {
24338 return isObjectLike(value) &&
24339 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
24340 }
24341
24342 /**
24343 * The base implementation of `_.iteratee`.
24344 *
24345 * @private
24346 * @param {*} [value=_.identity] The value to convert to an iteratee.
24347 * @returns {Function} Returns the iteratee.
24348 */
24349 function baseIteratee(value) {
24350 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
24351 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
24352 if (typeof value == 'function') {
24353 return value;
24354 }
24355 if (value == null) {
24356 return identity;
24357 }
24358 if (typeof value == 'object') {
24359 return isArray(value)
24360 ? baseMatchesProperty(value[0], value[1])
24361 : baseMatches(value);
24362 }
24363 return property(value);
24364 }
24365
24366 /**
24367 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
24368 *
24369 * @private
24370 * @param {Object} object The object to query.
24371 * @returns {Array} Returns the array of property names.
24372 */
24373 function baseKeys(object) {
24374 if (!isPrototype(object)) {
24375 return nativeKeys(object);
24376 }
24377 var result = [];
24378 for (var key in Object(object)) {
24379 if (hasOwnProperty.call(object, key) && key != 'constructor') {
24380 result.push(key);
24381 }
24382 }
24383 return result;
24384 }
24385
24386 /**
24387 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
24388 *
24389 * @private
24390 * @param {Object} object The object to query.
24391 * @returns {Array} Returns the array of property names.
24392 */
24393 function baseKeysIn(object) {
24394 if (!isObject(object)) {
24395 return nativeKeysIn(object);
24396 }
24397 var isProto = isPrototype(object),
24398 result = [];
24399
24400 for (var key in object) {
24401 if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
24402 result.push(key);
24403 }
24404 }
24405 return result;
24406 }
24407
24408 /**
24409 * The base implementation of `_.lt` which doesn't coerce arguments.
24410 *
24411 * @private
24412 * @param {*} value The value to compare.
24413 * @param {*} other The other value to compare.
24414 * @returns {boolean} Returns `true` if `value` is less than `other`,
24415 * else `false`.
24416 */
24417 function baseLt(value, other) {
24418 return value < other;
24419 }
24420
24421 /**
24422 * The base implementation of `_.map` without support for iteratee shorthands.
24423 *
24424 * @private
24425 * @param {Array|Object} collection The collection to iterate over.
24426 * @param {Function} iteratee The function invoked per iteration.
24427 * @returns {Array} Returns the new mapped array.
24428 */
24429 function baseMap(collection, iteratee) {
24430 var index = -1,
24431 result = isArrayLike(collection) ? Array(collection.length) : [];
24432
24433 baseEach(collection, function(value, key, collection) {
24434 result[++index] = iteratee(value, key, collection);
24435 });
24436 return result;
24437 }
24438
24439 /**
24440 * The base implementation of `_.matches` which doesn't clone `source`.
24441 *
24442 * @private
24443 * @param {Object} source The object of property values to match.
24444 * @returns {Function} Returns the new spec function.
24445 */
24446 function baseMatches(source) {
24447 var matchData = getMatchData(source);
24448 if (matchData.length == 1 && matchData[0][2]) {
24449 return matchesStrictComparable(matchData[0][0], matchData[0][1]);
24450 }
24451 return function(object) {
24452 return object === source || baseIsMatch(object, source, matchData);
24453 };
24454 }
24455
24456 /**
24457 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
24458 *
24459 * @private
24460 * @param {string} path The path of the property to get.
24461 * @param {*} srcValue The value to match.
24462 * @returns {Function} Returns the new spec function.
24463 */
24464 function baseMatchesProperty(path, srcValue) {
24465 if (isKey(path) && isStrictComparable(srcValue)) {
24466 return matchesStrictComparable(toKey(path), srcValue);
24467 }
24468 return function(object) {
24469 var objValue = get(object, path);
24470 return (objValue === undefined$1 && objValue === srcValue)
24471 ? hasIn(object, path)
24472 : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
24473 };
24474 }
24475
24476 /**
24477 * The base implementation of `_.merge` without support for multiple sources.
24478 *
24479 * @private
24480 * @param {Object} object The destination object.
24481 * @param {Object} source The source object.
24482 * @param {number} srcIndex The index of `source`.
24483 * @param {Function} [customizer] The function to customize merged values.
24484 * @param {Object} [stack] Tracks traversed source values and their merged
24485 * counterparts.
24486 */
24487 function baseMerge(object, source, srcIndex, customizer, stack) {
24488 if (object === source) {
24489 return;
24490 }
24491 baseFor(source, function(srcValue, key) {
24492 stack || (stack = new Stack);
24493 if (isObject(srcValue)) {
24494 baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
24495 }
24496 else {
24497 var newValue = customizer
24498 ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
24499 : undefined$1;
24500
24501 if (newValue === undefined$1) {
24502 newValue = srcValue;
24503 }
24504 assignMergeValue(object, key, newValue);
24505 }
24506 }, keysIn);
24507 }
24508
24509 /**
24510 * A specialized version of `baseMerge` for arrays and objects which performs
24511 * deep merges and tracks traversed objects enabling objects with circular
24512 * references to be merged.
24513 *
24514 * @private
24515 * @param {Object} object The destination object.
24516 * @param {Object} source The source object.
24517 * @param {string} key The key of the value to merge.
24518 * @param {number} srcIndex The index of `source`.
24519 * @param {Function} mergeFunc The function to merge values.
24520 * @param {Function} [customizer] The function to customize assigned values.
24521 * @param {Object} [stack] Tracks traversed source values and their merged
24522 * counterparts.
24523 */
24524 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
24525 var objValue = safeGet(object, key),
24526 srcValue = safeGet(source, key),
24527 stacked = stack.get(srcValue);
24528
24529 if (stacked) {
24530 assignMergeValue(object, key, stacked);
24531 return;
24532 }
24533 var newValue = customizer
24534 ? customizer(objValue, srcValue, (key + ''), object, source, stack)
24535 : undefined$1;
24536
24537 var isCommon = newValue === undefined$1;
24538
24539 if (isCommon) {
24540 var isArr = isArray(srcValue),
24541 isBuff = !isArr && isBuffer(srcValue),
24542 isTyped = !isArr && !isBuff && isTypedArray(srcValue);
24543
24544 newValue = srcValue;
24545 if (isArr || isBuff || isTyped) {
24546 if (isArray(objValue)) {
24547 newValue = objValue;
24548 }
24549 else if (isArrayLikeObject(objValue)) {
24550 newValue = copyArray(objValue);
24551 }
24552 else if (isBuff) {
24553 isCommon = false;
24554 newValue = cloneBuffer(srcValue, true);
24555 }
24556 else if (isTyped) {
24557 isCommon = false;
24558 newValue = cloneTypedArray(srcValue, true);
24559 }
24560 else {
24561 newValue = [];
24562 }
24563 }
24564 else if (isPlainObject(srcValue) || isArguments(srcValue)) {
24565 newValue = objValue;
24566 if (isArguments(objValue)) {
24567 newValue = toPlainObject(objValue);
24568 }
24569 else if (!isObject(objValue) || isFunction(objValue)) {
24570 newValue = initCloneObject(srcValue);
24571 }
24572 }
24573 else {
24574 isCommon = false;
24575 }
24576 }
24577 if (isCommon) {
24578 // Recursively merge objects and arrays (susceptible to call stack limits).
24579 stack.set(srcValue, newValue);
24580 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
24581 stack['delete'](srcValue);
24582 }
24583 assignMergeValue(object, key, newValue);
24584 }
24585
24586 /**
24587 * The base implementation of `_.nth` which doesn't coerce arguments.
24588 *
24589 * @private
24590 * @param {Array} array The array to query.
24591 * @param {number} n The index of the element to return.
24592 * @returns {*} Returns the nth element of `array`.
24593 */
24594 function baseNth(array, n) {
24595 var length = array.length;
24596 if (!length) {
24597 return;
24598 }
24599 n += n < 0 ? length : 0;
24600 return isIndex(n, length) ? array[n] : undefined$1;
24601 }
24602
24603 /**
24604 * The base implementation of `_.orderBy` without param guards.
24605 *
24606 * @private
24607 * @param {Array|Object} collection The collection to iterate over.
24608 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
24609 * @param {string[]} orders The sort orders of `iteratees`.
24610 * @returns {Array} Returns the new sorted array.
24611 */
24612 function baseOrderBy(collection, iteratees, orders) {
24613 var index = -1;
24614 iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
24615
24616 var result = baseMap(collection, function(value, key, collection) {
24617 var criteria = arrayMap(iteratees, function(iteratee) {
24618 return iteratee(value);
24619 });
24620 return { 'criteria': criteria, 'index': ++index, 'value': value };
24621 });
24622
24623 return baseSortBy(result, function(object, other) {
24624 return compareMultiple(object, other, orders);
24625 });
24626 }
24627
24628 /**
24629 * The base implementation of `_.pick` without support for individual
24630 * property identifiers.
24631 *
24632 * @private
24633 * @param {Object} object The source object.
24634 * @param {string[]} paths The property paths to pick.
24635 * @returns {Object} Returns the new object.
24636 */
24637 function basePick(object, paths) {
24638 return basePickBy(object, paths, function(value, path) {
24639 return hasIn(object, path);
24640 });
24641 }
24642
24643 /**
24644 * The base implementation of `_.pickBy` without support for iteratee shorthands.
24645 *
24646 * @private
24647 * @param {Object} object The source object.
24648 * @param {string[]} paths The property paths to pick.
24649 * @param {Function} predicate The function invoked per property.
24650 * @returns {Object} Returns the new object.
24651 */
24652 function basePickBy(object, paths, predicate) {
24653 var index = -1,
24654 length = paths.length,
24655 result = {};
24656
24657 while (++index < length) {
24658 var path = paths[index],
24659 value = baseGet(object, path);
24660
24661 if (predicate(value, path)) {
24662 baseSet(result, castPath(path, object), value);
24663 }
24664 }
24665 return result;
24666 }
24667
24668 /**
24669 * A specialized version of `baseProperty` which supports deep paths.
24670 *
24671 * @private
24672 * @param {Array|string} path The path of the property to get.
24673 * @returns {Function} Returns the new accessor function.
24674 */
24675 function basePropertyDeep(path) {
24676 return function(object) {
24677 return baseGet(object, path);
24678 };
24679 }
24680
24681 /**
24682 * The base implementation of `_.pullAllBy` without support for iteratee
24683 * shorthands.
24684 *
24685 * @private
24686 * @param {Array} array The array to modify.
24687 * @param {Array} values The values to remove.
24688 * @param {Function} [iteratee] The iteratee invoked per element.
24689 * @param {Function} [comparator] The comparator invoked per element.
24690 * @returns {Array} Returns `array`.
24691 */
24692 function basePullAll(array, values, iteratee, comparator) {
24693 var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
24694 index = -1,
24695 length = values.length,
24696 seen = array;
24697
24698 if (array === values) {
24699 values = copyArray(values);
24700 }
24701 if (iteratee) {
24702 seen = arrayMap(array, baseUnary(iteratee));
24703 }
24704 while (++index < length) {
24705 var fromIndex = 0,
24706 value = values[index],
24707 computed = iteratee ? iteratee(value) : value;
24708
24709 while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
24710 if (seen !== array) {
24711 splice.call(seen, fromIndex, 1);
24712 }
24713 splice.call(array, fromIndex, 1);
24714 }
24715 }
24716 return array;
24717 }
24718
24719 /**
24720 * The base implementation of `_.pullAt` without support for individual
24721 * indexes or capturing the removed elements.
24722 *
24723 * @private
24724 * @param {Array} array The array to modify.
24725 * @param {number[]} indexes The indexes of elements to remove.
24726 * @returns {Array} Returns `array`.
24727 */
24728 function basePullAt(array, indexes) {
24729 var length = array ? indexes.length : 0,
24730 lastIndex = length - 1;
24731
24732 while (length--) {
24733 var index = indexes[length];
24734 if (length == lastIndex || index !== previous) {
24735 var previous = index;
24736 if (isIndex(index)) {
24737 splice.call(array, index, 1);
24738 } else {
24739 baseUnset(array, index);
24740 }
24741 }
24742 }
24743 return array;
24744 }
24745
24746 /**
24747 * The base implementation of `_.random` without support for returning
24748 * floating-point numbers.
24749 *
24750 * @private
24751 * @param {number} lower The lower bound.
24752 * @param {number} upper The upper bound.
24753 * @returns {number} Returns the random number.
24754 */
24755 function baseRandom(lower, upper) {
24756 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
24757 }
24758
24759 /**
24760 * The base implementation of `_.range` and `_.rangeRight` which doesn't
24761 * coerce arguments.
24762 *
24763 * @private
24764 * @param {number} start The start of the range.
24765 * @param {number} end The end of the range.
24766 * @param {number} step The value to increment or decrement by.
24767 * @param {boolean} [fromRight] Specify iterating from right to left.
24768 * @returns {Array} Returns the range of numbers.
24769 */
24770 function baseRange(start, end, step, fromRight) {
24771 var index = -1,
24772 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
24773 result = Array(length);
24774
24775 while (length--) {
24776 result[fromRight ? length : ++index] = start;
24777 start += step;
24778 }
24779 return result;
24780 }
24781
24782 /**
24783 * The base implementation of `_.repeat` which doesn't coerce arguments.
24784 *
24785 * @private
24786 * @param {string} string The string to repeat.
24787 * @param {number} n The number of times to repeat the string.
24788 * @returns {string} Returns the repeated string.
24789 */
24790 function baseRepeat(string, n) {
24791 var result = '';
24792 if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
24793 return result;
24794 }
24795 // Leverage the exponentiation by squaring algorithm for a faster repeat.
24796 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
24797 do {
24798 if (n % 2) {
24799 result += string;
24800 }
24801 n = nativeFloor(n / 2);
24802 if (n) {
24803 string += string;
24804 }
24805 } while (n);
24806
24807 return result;
24808 }
24809
24810 /**
24811 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
24812 *
24813 * @private
24814 * @param {Function} func The function to apply a rest parameter to.
24815 * @param {number} [start=func.length-1] The start position of the rest parameter.
24816 * @returns {Function} Returns the new function.
24817 */
24818 function baseRest(func, start) {
24819 return setToString(overRest(func, start, identity), func + '');
24820 }
24821
24822 /**
24823 * The base implementation of `_.sample`.
24824 *
24825 * @private
24826 * @param {Array|Object} collection The collection to sample.
24827 * @returns {*} Returns the random element.
24828 */
24829 function baseSample(collection) {
24830 return arraySample(values(collection));
24831 }
24832
24833 /**
24834 * The base implementation of `_.sampleSize` without param guards.
24835 *
24836 * @private
24837 * @param {Array|Object} collection The collection to sample.
24838 * @param {number} n The number of elements to sample.
24839 * @returns {Array} Returns the random elements.
24840 */
24841 function baseSampleSize(collection, n) {
24842 var array = values(collection);
24843 return shuffleSelf(array, baseClamp(n, 0, array.length));
24844 }
24845
24846 /**
24847 * The base implementation of `_.set`.
24848 *
24849 * @private
24850 * @param {Object} object The object to modify.
24851 * @param {Array|string} path The path of the property to set.
24852 * @param {*} value The value to set.
24853 * @param {Function} [customizer] The function to customize path creation.
24854 * @returns {Object} Returns `object`.
24855 */
24856 function baseSet(object, path, value, customizer) {
24857 if (!isObject(object)) {
24858 return object;
24859 }
24860 path = castPath(path, object);
24861
24862 var index = -1,
24863 length = path.length,
24864 lastIndex = length - 1,
24865 nested = object;
24866
24867 while (nested != null && ++index < length) {
24868 var key = toKey(path[index]),
24869 newValue = value;
24870
24871 if (index != lastIndex) {
24872 var objValue = nested[key];
24873 newValue = customizer ? customizer(objValue, key, nested) : undefined$1;
24874 if (newValue === undefined$1) {
24875 newValue = isObject(objValue)
24876 ? objValue
24877 : (isIndex(path[index + 1]) ? [] : {});
24878 }
24879 }
24880 assignValue(nested, key, newValue);
24881 nested = nested[key];
24882 }
24883 return object;
24884 }
24885
24886 /**
24887 * The base implementation of `setData` without support for hot loop shorting.
24888 *
24889 * @private
24890 * @param {Function} func The function to associate metadata with.
24891 * @param {*} data The metadata.
24892 * @returns {Function} Returns `func`.
24893 */
24894 var baseSetData = !metaMap ? identity : function(func, data) {
24895 metaMap.set(func, data);
24896 return func;
24897 };
24898
24899 /**
24900 * The base implementation of `setToString` without support for hot loop shorting.
24901 *
24902 * @private
24903 * @param {Function} func The function to modify.
24904 * @param {Function} string The `toString` result.
24905 * @returns {Function} Returns `func`.
24906 */
24907 var baseSetToString = !defineProperty ? identity : function(func, string) {
24908 return defineProperty(func, 'toString', {
24909 'configurable': true,
24910 'enumerable': false,
24911 'value': constant(string),
24912 'writable': true
24913 });
24914 };
24915
24916 /**
24917 * The base implementation of `_.shuffle`.
24918 *
24919 * @private
24920 * @param {Array|Object} collection The collection to shuffle.
24921 * @returns {Array} Returns the new shuffled array.
24922 */
24923 function baseShuffle(collection) {
24924 return shuffleSelf(values(collection));
24925 }
24926
24927 /**
24928 * The base implementation of `_.slice` without an iteratee call guard.
24929 *
24930 * @private
24931 * @param {Array} array The array to slice.
24932 * @param {number} [start=0] The start position.
24933 * @param {number} [end=array.length] The end position.
24934 * @returns {Array} Returns the slice of `array`.
24935 */
24936 function baseSlice(array, start, end) {
24937 var index = -1,
24938 length = array.length;
24939
24940 if (start < 0) {
24941 start = -start > length ? 0 : (length + start);
24942 }
24943 end = end > length ? length : end;
24944 if (end < 0) {
24945 end += length;
24946 }
24947 length = start > end ? 0 : ((end - start) >>> 0);
24948 start >>>= 0;
24949
24950 var result = Array(length);
24951 while (++index < length) {
24952 result[index] = array[index + start];
24953 }
24954 return result;
24955 }
24956
24957 /**
24958 * The base implementation of `_.some` without support for iteratee shorthands.
24959 *
24960 * @private
24961 * @param {Array|Object} collection The collection to iterate over.
24962 * @param {Function} predicate The function invoked per iteration.
24963 * @returns {boolean} Returns `true` if any element passes the predicate check,
24964 * else `false`.
24965 */
24966 function baseSome(collection, predicate) {
24967 var result;
24968
24969 baseEach(collection, function(value, index, collection) {
24970 result = predicate(value, index, collection);
24971 return !result;
24972 });
24973 return !!result;
24974 }
24975
24976 /**
24977 * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
24978 * performs a binary search of `array` to determine the index at which `value`
24979 * should be inserted into `array` in order to maintain its sort order.
24980 *
24981 * @private
24982 * @param {Array} array The sorted array to inspect.
24983 * @param {*} value The value to evaluate.
24984 * @param {boolean} [retHighest] Specify returning the highest qualified index.
24985 * @returns {number} Returns the index at which `value` should be inserted
24986 * into `array`.
24987 */
24988 function baseSortedIndex(array, value, retHighest) {
24989 var low = 0,
24990 high = array == null ? low : array.length;
24991
24992 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
24993 while (low < high) {
24994 var mid = (low + high) >>> 1,
24995 computed = array[mid];
24996
24997 if (computed !== null && !isSymbol(computed) &&
24998 (retHighest ? (computed <= value) : (computed < value))) {
24999 low = mid + 1;
25000 } else {
25001 high = mid;
25002 }
25003 }
25004 return high;
25005 }
25006 return baseSortedIndexBy(array, value, identity, retHighest);
25007 }
25008
25009 /**
25010 * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
25011 * which invokes `iteratee` for `value` and each element of `array` to compute
25012 * their sort ranking. The iteratee is invoked with one argument; (value).
25013 *
25014 * @private
25015 * @param {Array} array The sorted array to inspect.
25016 * @param {*} value The value to evaluate.
25017 * @param {Function} iteratee The iteratee invoked per element.
25018 * @param {boolean} [retHighest] Specify returning the highest qualified index.
25019 * @returns {number} Returns the index at which `value` should be inserted
25020 * into `array`.
25021 */
25022 function baseSortedIndexBy(array, value, iteratee, retHighest) {
25023 value = iteratee(value);
25024
25025 var low = 0,
25026 high = array == null ? 0 : array.length,
25027 valIsNaN = value !== value,
25028 valIsNull = value === null,
25029 valIsSymbol = isSymbol(value),
25030 valIsUndefined = value === undefined$1;
25031
25032 while (low < high) {
25033 var mid = nativeFloor((low + high) / 2),
25034 computed = iteratee(array[mid]),
25035 othIsDefined = computed !== undefined$1,
25036 othIsNull = computed === null,
25037 othIsReflexive = computed === computed,
25038 othIsSymbol = isSymbol(computed);
25039
25040 if (valIsNaN) {
25041 var setLow = retHighest || othIsReflexive;
25042 } else if (valIsUndefined) {
25043 setLow = othIsReflexive && (retHighest || othIsDefined);
25044 } else if (valIsNull) {
25045 setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
25046 } else if (valIsSymbol) {
25047 setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
25048 } else if (othIsNull || othIsSymbol) {
25049 setLow = false;
25050 } else {
25051 setLow = retHighest ? (computed <= value) : (computed < value);
25052 }
25053 if (setLow) {
25054 low = mid + 1;
25055 } else {
25056 high = mid;
25057 }
25058 }
25059 return nativeMin(high, MAX_ARRAY_INDEX);
25060 }
25061
25062 /**
25063 * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
25064 * support for iteratee shorthands.
25065 *
25066 * @private
25067 * @param {Array} array The array to inspect.
25068 * @param {Function} [iteratee] The iteratee invoked per element.
25069 * @returns {Array} Returns the new duplicate free array.
25070 */
25071 function baseSortedUniq(array, iteratee) {
25072 var index = -1,
25073 length = array.length,
25074 resIndex = 0,
25075 result = [];
25076
25077 while (++index < length) {
25078 var value = array[index],
25079 computed = iteratee ? iteratee(value) : value;
25080
25081 if (!index || !eq(computed, seen)) {
25082 var seen = computed;
25083 result[resIndex++] = value === 0 ? 0 : value;
25084 }
25085 }
25086 return result;
25087 }
25088
25089 /**
25090 * The base implementation of `_.toNumber` which doesn't ensure correct
25091 * conversions of binary, hexadecimal, or octal string values.
25092 *
25093 * @private
25094 * @param {*} value The value to process.
25095 * @returns {number} Returns the number.
25096 */
25097 function baseToNumber(value) {
25098 if (typeof value == 'number') {
25099 return value;
25100 }
25101 if (isSymbol(value)) {
25102 return NAN;
25103 }
25104 return +value;
25105 }
25106
25107 /**
25108 * The base implementation of `_.toString` which doesn't convert nullish
25109 * values to empty strings.
25110 *
25111 * @private
25112 * @param {*} value The value to process.
25113 * @returns {string} Returns the string.
25114 */
25115 function baseToString(value) {
25116 // Exit early for strings to avoid a performance hit in some environments.
25117 if (typeof value == 'string') {
25118 return value;
25119 }
25120 if (isArray(value)) {
25121 // Recursively convert values (susceptible to call stack limits).
25122 return arrayMap(value, baseToString) + '';
25123 }
25124 if (isSymbol(value)) {
25125 return symbolToString ? symbolToString.call(value) : '';
25126 }
25127 var result = (value + '');
25128 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
25129 }
25130
25131 /**
25132 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
25133 *
25134 * @private
25135 * @param {Array} array The array to inspect.
25136 * @param {Function} [iteratee] The iteratee invoked per element.
25137 * @param {Function} [comparator] The comparator invoked per element.
25138 * @returns {Array} Returns the new duplicate free array.
25139 */
25140 function baseUniq(array, iteratee, comparator) {
25141 var index = -1,
25142 includes = arrayIncludes,
25143 length = array.length,
25144 isCommon = true,
25145 result = [],
25146 seen = result;
25147
25148 if (comparator) {
25149 isCommon = false;
25150 includes = arrayIncludesWith;
25151 }
25152 else if (length >= LARGE_ARRAY_SIZE) {
25153 var set = iteratee ? null : createSet(array);
25154 if (set) {
25155 return setToArray(set);
25156 }
25157 isCommon = false;
25158 includes = cacheHas;
25159 seen = new SetCache;
25160 }
25161 else {
25162 seen = iteratee ? [] : result;
25163 }
25164 outer:
25165 while (++index < length) {
25166 var value = array[index],
25167 computed = iteratee ? iteratee(value) : value;
25168
25169 value = (comparator || value !== 0) ? value : 0;
25170 if (isCommon && computed === computed) {
25171 var seenIndex = seen.length;
25172 while (seenIndex--) {
25173 if (seen[seenIndex] === computed) {
25174 continue outer;
25175 }
25176 }
25177 if (iteratee) {
25178 seen.push(computed);
25179 }
25180 result.push(value);
25181 }
25182 else if (!includes(seen, computed, comparator)) {
25183 if (seen !== result) {
25184 seen.push(computed);
25185 }
25186 result.push(value);
25187 }
25188 }
25189 return result;
25190 }
25191
25192 /**
25193 * The base implementation of `_.unset`.
25194 *
25195 * @private
25196 * @param {Object} object The object to modify.
25197 * @param {Array|string} path The property path to unset.
25198 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
25199 */
25200 function baseUnset(object, path) {
25201 path = castPath(path, object);
25202 object = parent(object, path);
25203 return object == null || delete object[toKey(last(path))];
25204 }
25205
25206 /**
25207 * The base implementation of `_.update`.
25208 *
25209 * @private
25210 * @param {Object} object The object to modify.
25211 * @param {Array|string} path The path of the property to update.
25212 * @param {Function} updater The function to produce the updated value.
25213 * @param {Function} [customizer] The function to customize path creation.
25214 * @returns {Object} Returns `object`.
25215 */
25216 function baseUpdate(object, path, updater, customizer) {
25217 return baseSet(object, path, updater(baseGet(object, path)), customizer);
25218 }
25219
25220 /**
25221 * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
25222 * without support for iteratee shorthands.
25223 *
25224 * @private
25225 * @param {Array} array The array to query.
25226 * @param {Function} predicate The function invoked per iteration.
25227 * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
25228 * @param {boolean} [fromRight] Specify iterating from right to left.
25229 * @returns {Array} Returns the slice of `array`.
25230 */
25231 function baseWhile(array, predicate, isDrop, fromRight) {
25232 var length = array.length,
25233 index = fromRight ? length : -1;
25234
25235 while ((fromRight ? index-- : ++index < length) &&
25236 predicate(array[index], index, array)) {}
25237
25238 return isDrop
25239 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
25240 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
25241 }
25242
25243 /**
25244 * The base implementation of `wrapperValue` which returns the result of
25245 * performing a sequence of actions on the unwrapped `value`, where each
25246 * successive action is supplied the return value of the previous.
25247 *
25248 * @private
25249 * @param {*} value The unwrapped value.
25250 * @param {Array} actions Actions to perform to resolve the unwrapped value.
25251 * @returns {*} Returns the resolved value.
25252 */
25253 function baseWrapperValue(value, actions) {
25254 var result = value;
25255 if (result instanceof LazyWrapper) {
25256 result = result.value();
25257 }
25258 return arrayReduce(actions, function(result, action) {
25259 return action.func.apply(action.thisArg, arrayPush([result], action.args));
25260 }, result);
25261 }
25262
25263 /**
25264 * The base implementation of methods like `_.xor`, without support for
25265 * iteratee shorthands, that accepts an array of arrays to inspect.
25266 *
25267 * @private
25268 * @param {Array} arrays The arrays to inspect.
25269 * @param {Function} [iteratee] The iteratee invoked per element.
25270 * @param {Function} [comparator] The comparator invoked per element.
25271 * @returns {Array} Returns the new array of values.
25272 */
25273 function baseXor(arrays, iteratee, comparator) {
25274 var length = arrays.length;
25275 if (length < 2) {
25276 return length ? baseUniq(arrays[0]) : [];
25277 }
25278 var index = -1,
25279 result = Array(length);
25280
25281 while (++index < length) {
25282 var array = arrays[index],
25283 othIndex = -1;
25284
25285 while (++othIndex < length) {
25286 if (othIndex != index) {
25287 result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
25288 }
25289 }
25290 }
25291 return baseUniq(baseFlatten(result, 1), iteratee, comparator);
25292 }
25293
25294 /**
25295 * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
25296 *
25297 * @private
25298 * @param {Array} props The property identifiers.
25299 * @param {Array} values The property values.
25300 * @param {Function} assignFunc The function to assign values.
25301 * @returns {Object} Returns the new object.
25302 */
25303 function baseZipObject(props, values, assignFunc) {
25304 var index = -1,
25305 length = props.length,
25306 valsLength = values.length,
25307 result = {};
25308
25309 while (++index < length) {
25310 var value = index < valsLength ? values[index] : undefined$1;
25311 assignFunc(result, props[index], value);
25312 }
25313 return result;
25314 }
25315
25316 /**
25317 * Casts `value` to an empty array if it's not an array like object.
25318 *
25319 * @private
25320 * @param {*} value The value to inspect.
25321 * @returns {Array|Object} Returns the cast array-like object.
25322 */
25323 function castArrayLikeObject(value) {
25324 return isArrayLikeObject(value) ? value : [];
25325 }
25326
25327 /**
25328 * Casts `value` to `identity` if it's not a function.
25329 *
25330 * @private
25331 * @param {*} value The value to inspect.
25332 * @returns {Function} Returns cast function.
25333 */
25334 function castFunction(value) {
25335 return typeof value == 'function' ? value : identity;
25336 }
25337
25338 /**
25339 * Casts `value` to a path array if it's not one.
25340 *
25341 * @private
25342 * @param {*} value The value to inspect.
25343 * @param {Object} [object] The object to query keys on.
25344 * @returns {Array} Returns the cast property path array.
25345 */
25346 function castPath(value, object) {
25347 if (isArray(value)) {
25348 return value;
25349 }
25350 return isKey(value, object) ? [value] : stringToPath(toString(value));
25351 }
25352
25353 /**
25354 * A `baseRest` alias which can be replaced with `identity` by module
25355 * replacement plugins.
25356 *
25357 * @private
25358 * @type {Function}
25359 * @param {Function} func The function to apply a rest parameter to.
25360 * @returns {Function} Returns the new function.
25361 */
25362 var castRest = baseRest;
25363
25364 /**
25365 * Casts `array` to a slice if it's needed.
25366 *
25367 * @private
25368 * @param {Array} array The array to inspect.
25369 * @param {number} start The start position.
25370 * @param {number} [end=array.length] The end position.
25371 * @returns {Array} Returns the cast slice.
25372 */
25373 function castSlice(array, start, end) {
25374 var length = array.length;
25375 end = end === undefined$1 ? length : end;
25376 return (!start && end >= length) ? array : baseSlice(array, start, end);
25377 }
25378
25379 /**
25380 * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
25381 *
25382 * @private
25383 * @param {number|Object} id The timer id or timeout object of the timer to clear.
25384 */
25385 var clearTimeout = ctxClearTimeout || function(id) {
25386 return root.clearTimeout(id);
25387 };
25388
25389 /**
25390 * Creates a clone of `buffer`.
25391 *
25392 * @private
25393 * @param {Buffer} buffer The buffer to clone.
25394 * @param {boolean} [isDeep] Specify a deep clone.
25395 * @returns {Buffer} Returns the cloned buffer.
25396 */
25397 function cloneBuffer(buffer, isDeep) {
25398 if (isDeep) {
25399 return buffer.slice();
25400 }
25401 var length = buffer.length,
25402 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
25403
25404 buffer.copy(result);
25405 return result;
25406 }
25407
25408 /**
25409 * Creates a clone of `arrayBuffer`.
25410 *
25411 * @private
25412 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
25413 * @returns {ArrayBuffer} Returns the cloned array buffer.
25414 */
25415 function cloneArrayBuffer(arrayBuffer) {
25416 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
25417 new Uint8Array(result).set(new Uint8Array(arrayBuffer));
25418 return result;
25419 }
25420
25421 /**
25422 * Creates a clone of `dataView`.
25423 *
25424 * @private
25425 * @param {Object} dataView The data view to clone.
25426 * @param {boolean} [isDeep] Specify a deep clone.
25427 * @returns {Object} Returns the cloned data view.
25428 */
25429 function cloneDataView(dataView, isDeep) {
25430 var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
25431 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
25432 }
25433
25434 /**
25435 * Creates a clone of `regexp`.
25436 *
25437 * @private
25438 * @param {Object} regexp The regexp to clone.
25439 * @returns {Object} Returns the cloned regexp.
25440 */
25441 function cloneRegExp(regexp) {
25442 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
25443 result.lastIndex = regexp.lastIndex;
25444 return result;
25445 }
25446
25447 /**
25448 * Creates a clone of the `symbol` object.
25449 *
25450 * @private
25451 * @param {Object} symbol The symbol object to clone.
25452 * @returns {Object} Returns the cloned symbol object.
25453 */
25454 function cloneSymbol(symbol) {
25455 return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
25456 }
25457
25458 /**
25459 * Creates a clone of `typedArray`.
25460 *
25461 * @private
25462 * @param {Object} typedArray The typed array to clone.
25463 * @param {boolean} [isDeep] Specify a deep clone.
25464 * @returns {Object} Returns the cloned typed array.
25465 */
25466 function cloneTypedArray(typedArray, isDeep) {
25467 var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
25468 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
25469 }
25470
25471 /**
25472 * Compares values to sort them in ascending order.
25473 *
25474 * @private
25475 * @param {*} value The value to compare.
25476 * @param {*} other The other value to compare.
25477 * @returns {number} Returns the sort order indicator for `value`.
25478 */
25479 function compareAscending(value, other) {
25480 if (value !== other) {
25481 var valIsDefined = value !== undefined$1,
25482 valIsNull = value === null,
25483 valIsReflexive = value === value,
25484 valIsSymbol = isSymbol(value);
25485
25486 var othIsDefined = other !== undefined$1,
25487 othIsNull = other === null,
25488 othIsReflexive = other === other,
25489 othIsSymbol = isSymbol(other);
25490
25491 if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
25492 (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
25493 (valIsNull && othIsDefined && othIsReflexive) ||
25494 (!valIsDefined && othIsReflexive) ||
25495 !valIsReflexive) {
25496 return 1;
25497 }
25498 if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
25499 (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
25500 (othIsNull && valIsDefined && valIsReflexive) ||
25501 (!othIsDefined && valIsReflexive) ||
25502 !othIsReflexive) {
25503 return -1;
25504 }
25505 }
25506 return 0;
25507 }
25508
25509 /**
25510 * Used by `_.orderBy` to compare multiple properties of a value to another
25511 * and stable sort them.
25512 *
25513 * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
25514 * specify an order of "desc" for descending or "asc" for ascending sort order
25515 * of corresponding values.
25516 *
25517 * @private
25518 * @param {Object} object The object to compare.
25519 * @param {Object} other The other object to compare.
25520 * @param {boolean[]|string[]} orders The order to sort by for each property.
25521 * @returns {number} Returns the sort order indicator for `object`.
25522 */
25523 function compareMultiple(object, other, orders) {
25524 var index = -1,
25525 objCriteria = object.criteria,
25526 othCriteria = other.criteria,
25527 length = objCriteria.length,
25528 ordersLength = orders.length;
25529
25530 while (++index < length) {
25531 var result = compareAscending(objCriteria[index], othCriteria[index]);
25532 if (result) {
25533 if (index >= ordersLength) {
25534 return result;
25535 }
25536 var order = orders[index];
25537 return result * (order == 'desc' ? -1 : 1);
25538 }
25539 }
25540 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
25541 // that causes it, under certain circumstances, to provide the same value for
25542 // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
25543 // for more details.
25544 //
25545 // This also ensures a stable sort in V8 and other engines.
25546 // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
25547 return object.index - other.index;
25548 }
25549
25550 /**
25551 * Creates an array that is the composition of partially applied arguments,
25552 * placeholders, and provided arguments into a single array of arguments.
25553 *
25554 * @private
25555 * @param {Array} args The provided arguments.
25556 * @param {Array} partials The arguments to prepend to those provided.
25557 * @param {Array} holders The `partials` placeholder indexes.
25558 * @params {boolean} [isCurried] Specify composing for a curried function.
25559 * @returns {Array} Returns the new array of composed arguments.
25560 */
25561 function composeArgs(args, partials, holders, isCurried) {
25562 var argsIndex = -1,
25563 argsLength = args.length,
25564 holdersLength = holders.length,
25565 leftIndex = -1,
25566 leftLength = partials.length,
25567 rangeLength = nativeMax(argsLength - holdersLength, 0),
25568 result = Array(leftLength + rangeLength),
25569 isUncurried = !isCurried;
25570
25571 while (++leftIndex < leftLength) {
25572 result[leftIndex] = partials[leftIndex];
25573 }
25574 while (++argsIndex < holdersLength) {
25575 if (isUncurried || argsIndex < argsLength) {
25576 result[holders[argsIndex]] = args[argsIndex];
25577 }
25578 }
25579 while (rangeLength--) {
25580 result[leftIndex++] = args[argsIndex++];
25581 }
25582 return result;
25583 }
25584
25585 /**
25586 * This function is like `composeArgs` except that the arguments composition
25587 * is tailored for `_.partialRight`.
25588 *
25589 * @private
25590 * @param {Array} args The provided arguments.
25591 * @param {Array} partials The arguments to append to those provided.
25592 * @param {Array} holders The `partials` placeholder indexes.
25593 * @params {boolean} [isCurried] Specify composing for a curried function.
25594 * @returns {Array} Returns the new array of composed arguments.
25595 */
25596 function composeArgsRight(args, partials, holders, isCurried) {
25597 var argsIndex = -1,
25598 argsLength = args.length,
25599 holdersIndex = -1,
25600 holdersLength = holders.length,
25601 rightIndex = -1,
25602 rightLength = partials.length,
25603 rangeLength = nativeMax(argsLength - holdersLength, 0),
25604 result = Array(rangeLength + rightLength),
25605 isUncurried = !isCurried;
25606
25607 while (++argsIndex < rangeLength) {
25608 result[argsIndex] = args[argsIndex];
25609 }
25610 var offset = argsIndex;
25611 while (++rightIndex < rightLength) {
25612 result[offset + rightIndex] = partials[rightIndex];
25613 }
25614 while (++holdersIndex < holdersLength) {
25615 if (isUncurried || argsIndex < argsLength) {
25616 result[offset + holders[holdersIndex]] = args[argsIndex++];
25617 }
25618 }
25619 return result;
25620 }
25621
25622 /**
25623 * Copies the values of `source` to `array`.
25624 *
25625 * @private
25626 * @param {Array} source The array to copy values from.
25627 * @param {Array} [array=[]] The array to copy values to.
25628 * @returns {Array} Returns `array`.
25629 */
25630 function copyArray(source, array) {
25631 var index = -1,
25632 length = source.length;
25633
25634 array || (array = Array(length));
25635 while (++index < length) {
25636 array[index] = source[index];
25637 }
25638 return array;
25639 }
25640
25641 /**
25642 * Copies properties of `source` to `object`.
25643 *
25644 * @private
25645 * @param {Object} source The object to copy properties from.
25646 * @param {Array} props The property identifiers to copy.
25647 * @param {Object} [object={}] The object to copy properties to.
25648 * @param {Function} [customizer] The function to customize copied values.
25649 * @returns {Object} Returns `object`.
25650 */
25651 function copyObject(source, props, object, customizer) {
25652 var isNew = !object;
25653 object || (object = {});
25654
25655 var index = -1,
25656 length = props.length;
25657
25658 while (++index < length) {
25659 var key = props[index];
25660
25661 var newValue = customizer
25662 ? customizer(object[key], source[key], key, object, source)
25663 : undefined$1;
25664
25665 if (newValue === undefined$1) {
25666 newValue = source[key];
25667 }
25668 if (isNew) {
25669 baseAssignValue(object, key, newValue);
25670 } else {
25671 assignValue(object, key, newValue);
25672 }
25673 }
25674 return object;
25675 }
25676
25677 /**
25678 * Copies own symbols of `source` to `object`.
25679 *
25680 * @private
25681 * @param {Object} source The object to copy symbols from.
25682 * @param {Object} [object={}] The object to copy symbols to.
25683 * @returns {Object} Returns `object`.
25684 */
25685 function copySymbols(source, object) {
25686 return copyObject(source, getSymbols(source), object);
25687 }
25688
25689 /**
25690 * Copies own and inherited symbols of `source` to `object`.
25691 *
25692 * @private
25693 * @param {Object} source The object to copy symbols from.
25694 * @param {Object} [object={}] The object to copy symbols to.
25695 * @returns {Object} Returns `object`.
25696 */
25697 function copySymbolsIn(source, object) {
25698 return copyObject(source, getSymbolsIn(source), object);
25699 }
25700
25701 /**
25702 * Creates a function like `_.groupBy`.
25703 *
25704 * @private
25705 * @param {Function} setter The function to set accumulator values.
25706 * @param {Function} [initializer] The accumulator object initializer.
25707 * @returns {Function} Returns the new aggregator function.
25708 */
25709 function createAggregator(setter, initializer) {
25710 return function(collection, iteratee) {
25711 var func = isArray(collection) ? arrayAggregator : baseAggregator,
25712 accumulator = initializer ? initializer() : {};
25713
25714 return func(collection, setter, getIteratee(iteratee, 2), accumulator);
25715 };
25716 }
25717
25718 /**
25719 * Creates a function like `_.assign`.
25720 *
25721 * @private
25722 * @param {Function} assigner The function to assign values.
25723 * @returns {Function} Returns the new assigner function.
25724 */
25725 function createAssigner(assigner) {
25726 return baseRest(function(object, sources) {
25727 var index = -1,
25728 length = sources.length,
25729 customizer = length > 1 ? sources[length - 1] : undefined$1,
25730 guard = length > 2 ? sources[2] : undefined$1;
25731
25732 customizer = (assigner.length > 3 && typeof customizer == 'function')
25733 ? (length--, customizer)
25734 : undefined$1;
25735
25736 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
25737 customizer = length < 3 ? undefined$1 : customizer;
25738 length = 1;
25739 }
25740 object = Object(object);
25741 while (++index < length) {
25742 var source = sources[index];
25743 if (source) {
25744 assigner(object, source, index, customizer);
25745 }
25746 }
25747 return object;
25748 });
25749 }
25750
25751 /**
25752 * Creates a `baseEach` or `baseEachRight` function.
25753 *
25754 * @private
25755 * @param {Function} eachFunc The function to iterate over a collection.
25756 * @param {boolean} [fromRight] Specify iterating from right to left.
25757 * @returns {Function} Returns the new base function.
25758 */
25759 function createBaseEach(eachFunc, fromRight) {
25760 return function(collection, iteratee) {
25761 if (collection == null) {
25762 return collection;
25763 }
25764 if (!isArrayLike(collection)) {
25765 return eachFunc(collection, iteratee);
25766 }
25767 var length = collection.length,
25768 index = fromRight ? length : -1,
25769 iterable = Object(collection);
25770
25771 while ((fromRight ? index-- : ++index < length)) {
25772 if (iteratee(iterable[index], index, iterable) === false) {
25773 break;
25774 }
25775 }
25776 return collection;
25777 };
25778 }
25779
25780 /**
25781 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
25782 *
25783 * @private
25784 * @param {boolean} [fromRight] Specify iterating from right to left.
25785 * @returns {Function} Returns the new base function.
25786 */
25787 function createBaseFor(fromRight) {
25788 return function(object, iteratee, keysFunc) {
25789 var index = -1,
25790 iterable = Object(object),
25791 props = keysFunc(object),
25792 length = props.length;
25793
25794 while (length--) {
25795 var key = props[fromRight ? length : ++index];
25796 if (iteratee(iterable[key], key, iterable) === false) {
25797 break;
25798 }
25799 }
25800 return object;
25801 };
25802 }
25803
25804 /**
25805 * Creates a function that wraps `func` to invoke it with the optional `this`
25806 * binding of `thisArg`.
25807 *
25808 * @private
25809 * @param {Function} func The function to wrap.
25810 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
25811 * @param {*} [thisArg] The `this` binding of `func`.
25812 * @returns {Function} Returns the new wrapped function.
25813 */
25814 function createBind(func, bitmask, thisArg) {
25815 var isBind = bitmask & WRAP_BIND_FLAG,
25816 Ctor = createCtor(func);
25817
25818 function wrapper() {
25819 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
25820 return fn.apply(isBind ? thisArg : this, arguments);
25821 }
25822 return wrapper;
25823 }
25824
25825 /**
25826 * Creates a function like `_.lowerFirst`.
25827 *
25828 * @private
25829 * @param {string} methodName The name of the `String` case method to use.
25830 * @returns {Function} Returns the new case function.
25831 */
25832 function createCaseFirst(methodName) {
25833 return function(string) {
25834 string = toString(string);
25835
25836 var strSymbols = hasUnicode(string)
25837 ? stringToArray(string)
25838 : undefined$1;
25839
25840 var chr = strSymbols
25841 ? strSymbols[0]
25842 : string.charAt(0);
25843
25844 var trailing = strSymbols
25845 ? castSlice(strSymbols, 1).join('')
25846 : string.slice(1);
25847
25848 return chr[methodName]() + trailing;
25849 };
25850 }
25851
25852 /**
25853 * Creates a function like `_.camelCase`.
25854 *
25855 * @private
25856 * @param {Function} callback The function to combine each word.
25857 * @returns {Function} Returns the new compounder function.
25858 */
25859 function createCompounder(callback) {
25860 return function(string) {
25861 return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
25862 };
25863 }
25864
25865 /**
25866 * Creates a function that produces an instance of `Ctor` regardless of
25867 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
25868 *
25869 * @private
25870 * @param {Function} Ctor The constructor to wrap.
25871 * @returns {Function} Returns the new wrapped function.
25872 */
25873 function createCtor(Ctor) {
25874 return function() {
25875 // Use a `switch` statement to work with class constructors. See
25876 // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
25877 // for more details.
25878 var args = arguments;
25879 switch (args.length) {
25880 case 0: return new Ctor;
25881 case 1: return new Ctor(args[0]);
25882 case 2: return new Ctor(args[0], args[1]);
25883 case 3: return new Ctor(args[0], args[1], args[2]);
25884 case 4: return new Ctor(args[0], args[1], args[2], args[3]);
25885 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
25886 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
25887 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
25888 }
25889 var thisBinding = baseCreate(Ctor.prototype),
25890 result = Ctor.apply(thisBinding, args);
25891
25892 // Mimic the constructor's `return` behavior.
25893 // See https://es5.github.io/#x13.2.2 for more details.
25894 return isObject(result) ? result : thisBinding;
25895 };
25896 }
25897
25898 /**
25899 * Creates a function that wraps `func` to enable currying.
25900 *
25901 * @private
25902 * @param {Function} func The function to wrap.
25903 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
25904 * @param {number} arity The arity of `func`.
25905 * @returns {Function} Returns the new wrapped function.
25906 */
25907 function createCurry(func, bitmask, arity) {
25908 var Ctor = createCtor(func);
25909
25910 function wrapper() {
25911 var length = arguments.length,
25912 args = Array(length),
25913 index = length,
25914 placeholder = getHolder(wrapper);
25915
25916 while (index--) {
25917 args[index] = arguments[index];
25918 }
25919 var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
25920 ? []
25921 : replaceHolders(args, placeholder);
25922
25923 length -= holders.length;
25924 if (length < arity) {
25925 return createRecurry(
25926 func, bitmask, createHybrid, wrapper.placeholder, undefined$1,
25927 args, holders, undefined$1, undefined$1, arity - length);
25928 }
25929 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
25930 return apply(fn, this, args);
25931 }
25932 return wrapper;
25933 }
25934
25935 /**
25936 * Creates a `_.find` or `_.findLast` function.
25937 *
25938 * @private
25939 * @param {Function} findIndexFunc The function to find the collection index.
25940 * @returns {Function} Returns the new find function.
25941 */
25942 function createFind(findIndexFunc) {
25943 return function(collection, predicate, fromIndex) {
25944 var iterable = Object(collection);
25945 if (!isArrayLike(collection)) {
25946 var iteratee = getIteratee(predicate, 3);
25947 collection = keys(collection);
25948 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
25949 }
25950 var index = findIndexFunc(collection, predicate, fromIndex);
25951 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined$1;
25952 };
25953 }
25954
25955 /**
25956 * Creates a `_.flow` or `_.flowRight` function.
25957 *
25958 * @private
25959 * @param {boolean} [fromRight] Specify iterating from right to left.
25960 * @returns {Function} Returns the new flow function.
25961 */
25962 function createFlow(fromRight) {
25963 return flatRest(function(funcs) {
25964 var length = funcs.length,
25965 index = length,
25966 prereq = LodashWrapper.prototype.thru;
25967
25968 if (fromRight) {
25969 funcs.reverse();
25970 }
25971 while (index--) {
25972 var func = funcs[index];
25973 if (typeof func != 'function') {
25974 throw new Error(FUNC_ERROR_TEXT);
25975 }
25976 if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
25977 var wrapper = new LodashWrapper([], true);
25978 }
25979 }
25980 index = wrapper ? index : length;
25981 while (++index < length) {
25982 func = funcs[index];
25983
25984 var funcName = getFuncName(func),
25985 data = funcName == 'wrapper' ? getData(func) : undefined$1;
25986
25987 if (data && isLaziable(data[0]) &&
25988 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
25989 !data[4].length && data[9] == 1
25990 ) {
25991 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
25992 } else {
25993 wrapper = (func.length == 1 && isLaziable(func))
25994 ? wrapper[funcName]()
25995 : wrapper.thru(func);
25996 }
25997 }
25998 return function() {
25999 var args = arguments,
26000 value = args[0];
26001
26002 if (wrapper && args.length == 1 && isArray(value)) {
26003 return wrapper.plant(value).value();
26004 }
26005 var index = 0,
26006 result = length ? funcs[index].apply(this, args) : value;
26007
26008 while (++index < length) {
26009 result = funcs[index].call(this, result);
26010 }
26011 return result;
26012 };
26013 });
26014 }
26015
26016 /**
26017 * Creates a function that wraps `func` to invoke it with optional `this`
26018 * binding of `thisArg`, partial application, and currying.
26019 *
26020 * @private
26021 * @param {Function|string} func The function or method name to wrap.
26022 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
26023 * @param {*} [thisArg] The `this` binding of `func`.
26024 * @param {Array} [partials] The arguments to prepend to those provided to
26025 * the new function.
26026 * @param {Array} [holders] The `partials` placeholder indexes.
26027 * @param {Array} [partialsRight] The arguments to append to those provided
26028 * to the new function.
26029 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
26030 * @param {Array} [argPos] The argument positions of the new function.
26031 * @param {number} [ary] The arity cap of `func`.
26032 * @param {number} [arity] The arity of `func`.
26033 * @returns {Function} Returns the new wrapped function.
26034 */
26035 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
26036 var isAry = bitmask & WRAP_ARY_FLAG,
26037 isBind = bitmask & WRAP_BIND_FLAG,
26038 isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
26039 isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
26040 isFlip = bitmask & WRAP_FLIP_FLAG,
26041 Ctor = isBindKey ? undefined$1 : createCtor(func);
26042
26043 function wrapper() {
26044 var length = arguments.length,
26045 args = Array(length),
26046 index = length;
26047
26048 while (index--) {
26049 args[index] = arguments[index];
26050 }
26051 if (isCurried) {
26052 var placeholder = getHolder(wrapper),
26053 holdersCount = countHolders(args, placeholder);
26054 }
26055 if (partials) {
26056 args = composeArgs(args, partials, holders, isCurried);
26057 }
26058 if (partialsRight) {
26059 args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
26060 }
26061 length -= holdersCount;
26062 if (isCurried && length < arity) {
26063 var newHolders = replaceHolders(args, placeholder);
26064 return createRecurry(
26065 func, bitmask, createHybrid, wrapper.placeholder, thisArg,
26066 args, newHolders, argPos, ary, arity - length
26067 );
26068 }
26069 var thisBinding = isBind ? thisArg : this,
26070 fn = isBindKey ? thisBinding[func] : func;
26071
26072 length = args.length;
26073 if (argPos) {
26074 args = reorder(args, argPos);
26075 } else if (isFlip && length > 1) {
26076 args.reverse();
26077 }
26078 if (isAry && ary < length) {
26079 args.length = ary;
26080 }
26081 if (this && this !== root && this instanceof wrapper) {
26082 fn = Ctor || createCtor(fn);
26083 }
26084 return fn.apply(thisBinding, args);
26085 }
26086 return wrapper;
26087 }
26088
26089 /**
26090 * Creates a function like `_.invertBy`.
26091 *
26092 * @private
26093 * @param {Function} setter The function to set accumulator values.
26094 * @param {Function} toIteratee The function to resolve iteratees.
26095 * @returns {Function} Returns the new inverter function.
26096 */
26097 function createInverter(setter, toIteratee) {
26098 return function(object, iteratee) {
26099 return baseInverter(object, setter, toIteratee(iteratee), {});
26100 };
26101 }
26102
26103 /**
26104 * Creates a function that performs a mathematical operation on two values.
26105 *
26106 * @private
26107 * @param {Function} operator The function to perform the operation.
26108 * @param {number} [defaultValue] The value used for `undefined` arguments.
26109 * @returns {Function} Returns the new mathematical operation function.
26110 */
26111 function createMathOperation(operator, defaultValue) {
26112 return function(value, other) {
26113 var result;
26114 if (value === undefined$1 && other === undefined$1) {
26115 return defaultValue;
26116 }
26117 if (value !== undefined$1) {
26118 result = value;
26119 }
26120 if (other !== undefined$1) {
26121 if (result === undefined$1) {
26122 return other;
26123 }
26124 if (typeof value == 'string' || typeof other == 'string') {
26125 value = baseToString(value);
26126 other = baseToString(other);
26127 } else {
26128 value = baseToNumber(value);
26129 other = baseToNumber(other);
26130 }
26131 result = operator(value, other);
26132 }
26133 return result;
26134 };
26135 }
26136
26137 /**
26138 * Creates a function like `_.over`.
26139 *
26140 * @private
26141 * @param {Function} arrayFunc The function to iterate over iteratees.
26142 * @returns {Function} Returns the new over function.
26143 */
26144 function createOver(arrayFunc) {
26145 return flatRest(function(iteratees) {
26146 iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
26147 return baseRest(function(args) {
26148 var thisArg = this;
26149 return arrayFunc(iteratees, function(iteratee) {
26150 return apply(iteratee, thisArg, args);
26151 });
26152 });
26153 });
26154 }
26155
26156 /**
26157 * Creates the padding for `string` based on `length`. The `chars` string
26158 * is truncated if the number of characters exceeds `length`.
26159 *
26160 * @private
26161 * @param {number} length The padding length.
26162 * @param {string} [chars=' '] The string used as padding.
26163 * @returns {string} Returns the padding for `string`.
26164 */
26165 function createPadding(length, chars) {
26166 chars = chars === undefined$1 ? ' ' : baseToString(chars);
26167
26168 var charsLength = chars.length;
26169 if (charsLength < 2) {
26170 return charsLength ? baseRepeat(chars, length) : chars;
26171 }
26172 var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
26173 return hasUnicode(chars)
26174 ? castSlice(stringToArray(result), 0, length).join('')
26175 : result.slice(0, length);
26176 }
26177
26178 /**
26179 * Creates a function that wraps `func` to invoke it with the `this` binding
26180 * of `thisArg` and `partials` prepended to the arguments it receives.
26181 *
26182 * @private
26183 * @param {Function} func The function to wrap.
26184 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
26185 * @param {*} thisArg The `this` binding of `func`.
26186 * @param {Array} partials The arguments to prepend to those provided to
26187 * the new function.
26188 * @returns {Function} Returns the new wrapped function.
26189 */
26190 function createPartial(func, bitmask, thisArg, partials) {
26191 var isBind = bitmask & WRAP_BIND_FLAG,
26192 Ctor = createCtor(func);
26193
26194 function wrapper() {
26195 var argsIndex = -1,
26196 argsLength = arguments.length,
26197 leftIndex = -1,
26198 leftLength = partials.length,
26199 args = Array(leftLength + argsLength),
26200 fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
26201
26202 while (++leftIndex < leftLength) {
26203 args[leftIndex] = partials[leftIndex];
26204 }
26205 while (argsLength--) {
26206 args[leftIndex++] = arguments[++argsIndex];
26207 }
26208 return apply(fn, isBind ? thisArg : this, args);
26209 }
26210 return wrapper;
26211 }
26212
26213 /**
26214 * Creates a `_.range` or `_.rangeRight` function.
26215 *
26216 * @private
26217 * @param {boolean} [fromRight] Specify iterating from right to left.
26218 * @returns {Function} Returns the new range function.
26219 */
26220 function createRange(fromRight) {
26221 return function(start, end, step) {
26222 if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
26223 end = step = undefined$1;
26224 }
26225 // Ensure the sign of `-0` is preserved.
26226 start = toFinite(start);
26227 if (end === undefined$1) {
26228 end = start;
26229 start = 0;
26230 } else {
26231 end = toFinite(end);
26232 }
26233 step = step === undefined$1 ? (start < end ? 1 : -1) : toFinite(step);
26234 return baseRange(start, end, step, fromRight);
26235 };
26236 }
26237
26238 /**
26239 * Creates a function that performs a relational operation on two values.
26240 *
26241 * @private
26242 * @param {Function} operator The function to perform the operation.
26243 * @returns {Function} Returns the new relational operation function.
26244 */
26245 function createRelationalOperation(operator) {
26246 return function(value, other) {
26247 if (!(typeof value == 'string' && typeof other == 'string')) {
26248 value = toNumber(value);
26249 other = toNumber(other);
26250 }
26251 return operator(value, other);
26252 };
26253 }
26254
26255 /**
26256 * Creates a function that wraps `func` to continue currying.
26257 *
26258 * @private
26259 * @param {Function} func The function to wrap.
26260 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
26261 * @param {Function} wrapFunc The function to create the `func` wrapper.
26262 * @param {*} placeholder The placeholder value.
26263 * @param {*} [thisArg] The `this` binding of `func`.
26264 * @param {Array} [partials] The arguments to prepend to those provided to
26265 * the new function.
26266 * @param {Array} [holders] The `partials` placeholder indexes.
26267 * @param {Array} [argPos] The argument positions of the new function.
26268 * @param {number} [ary] The arity cap of `func`.
26269 * @param {number} [arity] The arity of `func`.
26270 * @returns {Function} Returns the new wrapped function.
26271 */
26272 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
26273 var isCurry = bitmask & WRAP_CURRY_FLAG,
26274 newHolders = isCurry ? holders : undefined$1,
26275 newHoldersRight = isCurry ? undefined$1 : holders,
26276 newPartials = isCurry ? partials : undefined$1,
26277 newPartialsRight = isCurry ? undefined$1 : partials;
26278
26279 bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
26280 bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
26281
26282 if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
26283 bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
26284 }
26285 var newData = [
26286 func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
26287 newHoldersRight, argPos, ary, arity
26288 ];
26289
26290 var result = wrapFunc.apply(undefined$1, newData);
26291 if (isLaziable(func)) {
26292 setData(result, newData);
26293 }
26294 result.placeholder = placeholder;
26295 return setWrapToString(result, func, bitmask);
26296 }
26297
26298 /**
26299 * Creates a function like `_.round`.
26300 *
26301 * @private
26302 * @param {string} methodName The name of the `Math` method to use when rounding.
26303 * @returns {Function} Returns the new round function.
26304 */
26305 function createRound(methodName) {
26306 var func = Math[methodName];
26307 return function(number, precision) {
26308 number = toNumber(number);
26309 precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
26310 if (precision && nativeIsFinite(number)) {
26311 // Shift with exponential notation to avoid floating-point issues.
26312 // See [MDN](https://mdn.io/round#Examples) for more details.
26313 var pair = (toString(number) + 'e').split('e'),
26314 value = func(pair[0] + 'e' + (+pair[1] + precision));
26315
26316 pair = (toString(value) + 'e').split('e');
26317 return +(pair[0] + 'e' + (+pair[1] - precision));
26318 }
26319 return func(number);
26320 };
26321 }
26322
26323 /**
26324 * Creates a set object of `values`.
26325 *
26326 * @private
26327 * @param {Array} values The values to add to the set.
26328 * @returns {Object} Returns the new set.
26329 */
26330 var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
26331 return new Set(values);
26332 };
26333
26334 /**
26335 * Creates a `_.toPairs` or `_.toPairsIn` function.
26336 *
26337 * @private
26338 * @param {Function} keysFunc The function to get the keys of a given object.
26339 * @returns {Function} Returns the new pairs function.
26340 */
26341 function createToPairs(keysFunc) {
26342 return function(object) {
26343 var tag = getTag(object);
26344 if (tag == mapTag) {
26345 return mapToArray(object);
26346 }
26347 if (tag == setTag) {
26348 return setToPairs(object);
26349 }
26350 return baseToPairs(object, keysFunc(object));
26351 };
26352 }
26353
26354 /**
26355 * Creates a function that either curries or invokes `func` with optional
26356 * `this` binding and partially applied arguments.
26357 *
26358 * @private
26359 * @param {Function|string} func The function or method name to wrap.
26360 * @param {number} bitmask The bitmask flags.
26361 * 1 - `_.bind`
26362 * 2 - `_.bindKey`
26363 * 4 - `_.curry` or `_.curryRight` of a bound function
26364 * 8 - `_.curry`
26365 * 16 - `_.curryRight`
26366 * 32 - `_.partial`
26367 * 64 - `_.partialRight`
26368 * 128 - `_.rearg`
26369 * 256 - `_.ary`
26370 * 512 - `_.flip`
26371 * @param {*} [thisArg] The `this` binding of `func`.
26372 * @param {Array} [partials] The arguments to be partially applied.
26373 * @param {Array} [holders] The `partials` placeholder indexes.
26374 * @param {Array} [argPos] The argument positions of the new function.
26375 * @param {number} [ary] The arity cap of `func`.
26376 * @param {number} [arity] The arity of `func`.
26377 * @returns {Function} Returns the new wrapped function.
26378 */
26379 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
26380 var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
26381 if (!isBindKey && typeof func != 'function') {
26382 throw new Error(FUNC_ERROR_TEXT);
26383 }
26384 var length = partials ? partials.length : 0;
26385 if (!length) {
26386 bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
26387 partials = holders = undefined$1;
26388 }
26389 ary = ary === undefined$1 ? ary : nativeMax(toInteger(ary), 0);
26390 arity = arity === undefined$1 ? arity : toInteger(arity);
26391 length -= holders ? holders.length : 0;
26392
26393 if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
26394 var partialsRight = partials,
26395 holdersRight = holders;
26396
26397 partials = holders = undefined$1;
26398 }
26399 var data = isBindKey ? undefined$1 : getData(func);
26400
26401 var newData = [
26402 func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
26403 argPos, ary, arity
26404 ];
26405
26406 if (data) {
26407 mergeData(newData, data);
26408 }
26409 func = newData[0];
26410 bitmask = newData[1];
26411 thisArg = newData[2];
26412 partials = newData[3];
26413 holders = newData[4];
26414 arity = newData[9] = newData[9] === undefined$1
26415 ? (isBindKey ? 0 : func.length)
26416 : nativeMax(newData[9] - length, 0);
26417
26418 if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
26419 bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
26420 }
26421 if (!bitmask || bitmask == WRAP_BIND_FLAG) {
26422 var result = createBind(func, bitmask, thisArg);
26423 } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
26424 result = createCurry(func, bitmask, arity);
26425 } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
26426 result = createPartial(func, bitmask, thisArg, partials);
26427 } else {
26428 result = createHybrid.apply(undefined$1, newData);
26429 }
26430 var setter = data ? baseSetData : setData;
26431 return setWrapToString(setter(result, newData), func, bitmask);
26432 }
26433
26434 /**
26435 * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
26436 * of source objects to the destination object for all destination properties
26437 * that resolve to `undefined`.
26438 *
26439 * @private
26440 * @param {*} objValue The destination value.
26441 * @param {*} srcValue The source value.
26442 * @param {string} key The key of the property to assign.
26443 * @param {Object} object The parent object of `objValue`.
26444 * @returns {*} Returns the value to assign.
26445 */
26446 function customDefaultsAssignIn(objValue, srcValue, key, object) {
26447 if (objValue === undefined$1 ||
26448 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
26449 return srcValue;
26450 }
26451 return objValue;
26452 }
26453
26454 /**
26455 * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
26456 * objects into destination objects that are passed thru.
26457 *
26458 * @private
26459 * @param {*} objValue The destination value.
26460 * @param {*} srcValue The source value.
26461 * @param {string} key The key of the property to merge.
26462 * @param {Object} object The parent object of `objValue`.
26463 * @param {Object} source The parent object of `srcValue`.
26464 * @param {Object} [stack] Tracks traversed source values and their merged
26465 * counterparts.
26466 * @returns {*} Returns the value to assign.
26467 */
26468 function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
26469 if (isObject(objValue) && isObject(srcValue)) {
26470 // Recursively merge objects and arrays (susceptible to call stack limits).
26471 stack.set(srcValue, objValue);
26472 baseMerge(objValue, srcValue, undefined$1, customDefaultsMerge, stack);
26473 stack['delete'](srcValue);
26474 }
26475 return objValue;
26476 }
26477
26478 /**
26479 * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
26480 * objects.
26481 *
26482 * @private
26483 * @param {*} value The value to inspect.
26484 * @param {string} key The key of the property to inspect.
26485 * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
26486 */
26487 function customOmitClone(value) {
26488 return isPlainObject(value) ? undefined$1 : value;
26489 }
26490
26491 /**
26492 * A specialized version of `baseIsEqualDeep` for arrays with support for
26493 * partial deep comparisons.
26494 *
26495 * @private
26496 * @param {Array} array The array to compare.
26497 * @param {Array} other The other array to compare.
26498 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
26499 * @param {Function} customizer The function to customize comparisons.
26500 * @param {Function} equalFunc The function to determine equivalents of values.
26501 * @param {Object} stack Tracks traversed `array` and `other` objects.
26502 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
26503 */
26504 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
26505 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
26506 arrLength = array.length,
26507 othLength = other.length;
26508
26509 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
26510 return false;
26511 }
26512 // Assume cyclic values are equal.
26513 var stacked = stack.get(array);
26514 if (stacked && stack.get(other)) {
26515 return stacked == other;
26516 }
26517 var index = -1,
26518 result = true,
26519 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined$1;
26520
26521 stack.set(array, other);
26522 stack.set(other, array);
26523
26524 // Ignore non-index properties.
26525 while (++index < arrLength) {
26526 var arrValue = array[index],
26527 othValue = other[index];
26528
26529 if (customizer) {
26530 var compared = isPartial
26531 ? customizer(othValue, arrValue, index, other, array, stack)
26532 : customizer(arrValue, othValue, index, array, other, stack);
26533 }
26534 if (compared !== undefined$1) {
26535 if (compared) {
26536 continue;
26537 }
26538 result = false;
26539 break;
26540 }
26541 // Recursively compare arrays (susceptible to call stack limits).
26542 if (seen) {
26543 if (!arraySome(other, function(othValue, othIndex) {
26544 if (!cacheHas(seen, othIndex) &&
26545 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
26546 return seen.push(othIndex);
26547 }
26548 })) {
26549 result = false;
26550 break;
26551 }
26552 } else if (!(
26553 arrValue === othValue ||
26554 equalFunc(arrValue, othValue, bitmask, customizer, stack)
26555 )) {
26556 result = false;
26557 break;
26558 }
26559 }
26560 stack['delete'](array);
26561 stack['delete'](other);
26562 return result;
26563 }
26564
26565 /**
26566 * A specialized version of `baseIsEqualDeep` for comparing objects of
26567 * the same `toStringTag`.
26568 *
26569 * **Note:** This function only supports comparing values with tags of
26570 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
26571 *
26572 * @private
26573 * @param {Object} object The object to compare.
26574 * @param {Object} other The other object to compare.
26575 * @param {string} tag The `toStringTag` of the objects to compare.
26576 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
26577 * @param {Function} customizer The function to customize comparisons.
26578 * @param {Function} equalFunc The function to determine equivalents of values.
26579 * @param {Object} stack Tracks traversed `object` and `other` objects.
26580 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
26581 */
26582 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
26583 switch (tag) {
26584 case dataViewTag:
26585 if ((object.byteLength != other.byteLength) ||
26586 (object.byteOffset != other.byteOffset)) {
26587 return false;
26588 }
26589 object = object.buffer;
26590 other = other.buffer;
26591
26592 case arrayBufferTag:
26593 if ((object.byteLength != other.byteLength) ||
26594 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
26595 return false;
26596 }
26597 return true;
26598
26599 case boolTag:
26600 case dateTag:
26601 case numberTag:
26602 // Coerce booleans to `1` or `0` and dates to milliseconds.
26603 // Invalid dates are coerced to `NaN`.
26604 return eq(+object, +other);
26605
26606 case errorTag:
26607 return object.name == other.name && object.message == other.message;
26608
26609 case regexpTag:
26610 case stringTag:
26611 // Coerce regexes to strings and treat strings, primitives and objects,
26612 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
26613 // for more details.
26614 return object == (other + '');
26615
26616 case mapTag:
26617 var convert = mapToArray;
26618
26619 case setTag:
26620 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
26621 convert || (convert = setToArray);
26622
26623 if (object.size != other.size && !isPartial) {
26624 return false;
26625 }
26626 // Assume cyclic values are equal.
26627 var stacked = stack.get(object);
26628 if (stacked) {
26629 return stacked == other;
26630 }
26631 bitmask |= COMPARE_UNORDERED_FLAG;
26632
26633 // Recursively compare objects (susceptible to call stack limits).
26634 stack.set(object, other);
26635 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
26636 stack['delete'](object);
26637 return result;
26638
26639 case symbolTag:
26640 if (symbolValueOf) {
26641 return symbolValueOf.call(object) == symbolValueOf.call(other);
26642 }
26643 }
26644 return false;
26645 }
26646
26647 /**
26648 * A specialized version of `baseIsEqualDeep` for objects with support for
26649 * partial deep comparisons.
26650 *
26651 * @private
26652 * @param {Object} object The object to compare.
26653 * @param {Object} other The other object to compare.
26654 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
26655 * @param {Function} customizer The function to customize comparisons.
26656 * @param {Function} equalFunc The function to determine equivalents of values.
26657 * @param {Object} stack Tracks traversed `object` and `other` objects.
26658 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
26659 */
26660 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
26661 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
26662 objProps = getAllKeys(object),
26663 objLength = objProps.length,
26664 othProps = getAllKeys(other),
26665 othLength = othProps.length;
26666
26667 if (objLength != othLength && !isPartial) {
26668 return false;
26669 }
26670 var index = objLength;
26671 while (index--) {
26672 var key = objProps[index];
26673 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
26674 return false;
26675 }
26676 }
26677 // Assume cyclic values are equal.
26678 var stacked = stack.get(object);
26679 if (stacked && stack.get(other)) {
26680 return stacked == other;
26681 }
26682 var result = true;
26683 stack.set(object, other);
26684 stack.set(other, object);
26685
26686 var skipCtor = isPartial;
26687 while (++index < objLength) {
26688 key = objProps[index];
26689 var objValue = object[key],
26690 othValue = other[key];
26691
26692 if (customizer) {
26693 var compared = isPartial
26694 ? customizer(othValue, objValue, key, other, object, stack)
26695 : customizer(objValue, othValue, key, object, other, stack);
26696 }
26697 // Recursively compare objects (susceptible to call stack limits).
26698 if (!(compared === undefined$1
26699 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
26700 : compared
26701 )) {
26702 result = false;
26703 break;
26704 }
26705 skipCtor || (skipCtor = key == 'constructor');
26706 }
26707 if (result && !skipCtor) {
26708 var objCtor = object.constructor,
26709 othCtor = other.constructor;
26710
26711 // Non `Object` object instances with different constructors are not equal.
26712 if (objCtor != othCtor &&
26713 ('constructor' in object && 'constructor' in other) &&
26714 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
26715 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
26716 result = false;
26717 }
26718 }
26719 stack['delete'](object);
26720 stack['delete'](other);
26721 return result;
26722 }
26723
26724 /**
26725 * A specialized version of `baseRest` which flattens the rest array.
26726 *
26727 * @private
26728 * @param {Function} func The function to apply a rest parameter to.
26729 * @returns {Function} Returns the new function.
26730 */
26731 function flatRest(func) {
26732 return setToString(overRest(func, undefined$1, flatten), func + '');
26733 }
26734
26735 /**
26736 * Creates an array of own enumerable property names and symbols of `object`.
26737 *
26738 * @private
26739 * @param {Object} object The object to query.
26740 * @returns {Array} Returns the array of property names and symbols.
26741 */
26742 function getAllKeys(object) {
26743 return baseGetAllKeys(object, keys, getSymbols);
26744 }
26745
26746 /**
26747 * Creates an array of own and inherited enumerable property names and
26748 * symbols of `object`.
26749 *
26750 * @private
26751 * @param {Object} object The object to query.
26752 * @returns {Array} Returns the array of property names and symbols.
26753 */
26754 function getAllKeysIn(object) {
26755 return baseGetAllKeys(object, keysIn, getSymbolsIn);
26756 }
26757
26758 /**
26759 * Gets metadata for `func`.
26760 *
26761 * @private
26762 * @param {Function} func The function to query.
26763 * @returns {*} Returns the metadata for `func`.
26764 */
26765 var getData = !metaMap ? noop : function(func) {
26766 return metaMap.get(func);
26767 };
26768
26769 /**
26770 * Gets the name of `func`.
26771 *
26772 * @private
26773 * @param {Function} func The function to query.
26774 * @returns {string} Returns the function name.
26775 */
26776 function getFuncName(func) {
26777 var result = (func.name + ''),
26778 array = realNames[result],
26779 length = hasOwnProperty.call(realNames, result) ? array.length : 0;
26780
26781 while (length--) {
26782 var data = array[length],
26783 otherFunc = data.func;
26784 if (otherFunc == null || otherFunc == func) {
26785 return data.name;
26786 }
26787 }
26788 return result;
26789 }
26790
26791 /**
26792 * Gets the argument placeholder value for `func`.
26793 *
26794 * @private
26795 * @param {Function} func The function to inspect.
26796 * @returns {*} Returns the placeholder value.
26797 */
26798 function getHolder(func) {
26799 var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
26800 return object.placeholder;
26801 }
26802
26803 /**
26804 * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
26805 * this function returns the custom method, otherwise it returns `baseIteratee`.
26806 * If arguments are provided, the chosen function is invoked with them and
26807 * its result is returned.
26808 *
26809 * @private
26810 * @param {*} [value] The value to convert to an iteratee.
26811 * @param {number} [arity] The arity of the created iteratee.
26812 * @returns {Function} Returns the chosen function or its result.
26813 */
26814 function getIteratee() {
26815 var result = lodash.iteratee || iteratee;
26816 result = result === iteratee ? baseIteratee : result;
26817 return arguments.length ? result(arguments[0], arguments[1]) : result;
26818 }
26819
26820 /**
26821 * Gets the data for `map`.
26822 *
26823 * @private
26824 * @param {Object} map The map to query.
26825 * @param {string} key The reference key.
26826 * @returns {*} Returns the map data.
26827 */
26828 function getMapData(map, key) {
26829 var data = map.__data__;
26830 return isKeyable(key)
26831 ? data[typeof key == 'string' ? 'string' : 'hash']
26832 : data.map;
26833 }
26834
26835 /**
26836 * Gets the property names, values, and compare flags of `object`.
26837 *
26838 * @private
26839 * @param {Object} object The object to query.
26840 * @returns {Array} Returns the match data of `object`.
26841 */
26842 function getMatchData(object) {
26843 var result = keys(object),
26844 length = result.length;
26845
26846 while (length--) {
26847 var key = result[length],
26848 value = object[key];
26849
26850 result[length] = [key, value, isStrictComparable(value)];
26851 }
26852 return result;
26853 }
26854
26855 /**
26856 * Gets the native function at `key` of `object`.
26857 *
26858 * @private
26859 * @param {Object} object The object to query.
26860 * @param {string} key The key of the method to get.
26861 * @returns {*} Returns the function if it's native, else `undefined`.
26862 */
26863 function getNative(object, key) {
26864 var value = getValue(object, key);
26865 return baseIsNative(value) ? value : undefined$1;
26866 }
26867
26868 /**
26869 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
26870 *
26871 * @private
26872 * @param {*} value The value to query.
26873 * @returns {string} Returns the raw `toStringTag`.
26874 */
26875 function getRawTag(value) {
26876 var isOwn = hasOwnProperty.call(value, symToStringTag),
26877 tag = value[symToStringTag];
26878
26879 try {
26880 value[symToStringTag] = undefined$1;
26881 var unmasked = true;
26882 } catch (e) {}
26883
26884 var result = nativeObjectToString.call(value);
26885 if (unmasked) {
26886 if (isOwn) {
26887 value[symToStringTag] = tag;
26888 } else {
26889 delete value[symToStringTag];
26890 }
26891 }
26892 return result;
26893 }
26894
26895 /**
26896 * Creates an array of the own enumerable symbols of `object`.
26897 *
26898 * @private
26899 * @param {Object} object The object to query.
26900 * @returns {Array} Returns the array of symbols.
26901 */
26902 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
26903 if (object == null) {
26904 return [];
26905 }
26906 object = Object(object);
26907 return arrayFilter(nativeGetSymbols(object), function(symbol) {
26908 return propertyIsEnumerable.call(object, symbol);
26909 });
26910 };
26911
26912 /**
26913 * Creates an array of the own and inherited enumerable symbols of `object`.
26914 *
26915 * @private
26916 * @param {Object} object The object to query.
26917 * @returns {Array} Returns the array of symbols.
26918 */
26919 var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
26920 var result = [];
26921 while (object) {
26922 arrayPush(result, getSymbols(object));
26923 object = getPrototype(object);
26924 }
26925 return result;
26926 };
26927
26928 /**
26929 * Gets the `toStringTag` of `value`.
26930 *
26931 * @private
26932 * @param {*} value The value to query.
26933 * @returns {string} Returns the `toStringTag`.
26934 */
26935 var getTag = baseGetTag;
26936
26937 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
26938 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
26939 (Map && getTag(new Map) != mapTag) ||
26940 (Promise && getTag(Promise.resolve()) != promiseTag) ||
26941 (Set && getTag(new Set) != setTag) ||
26942 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
26943 getTag = function(value) {
26944 var result = baseGetTag(value),
26945 Ctor = result == objectTag ? value.constructor : undefined$1,
26946 ctorString = Ctor ? toSource(Ctor) : '';
26947
26948 if (ctorString) {
26949 switch (ctorString) {
26950 case dataViewCtorString: return dataViewTag;
26951 case mapCtorString: return mapTag;
26952 case promiseCtorString: return promiseTag;
26953 case setCtorString: return setTag;
26954 case weakMapCtorString: return weakMapTag;
26955 }
26956 }
26957 return result;
26958 };
26959 }
26960
26961 /**
26962 * Gets the view, applying any `transforms` to the `start` and `end` positions.
26963 *
26964 * @private
26965 * @param {number} start The start of the view.
26966 * @param {number} end The end of the view.
26967 * @param {Array} transforms The transformations to apply to the view.
26968 * @returns {Object} Returns an object containing the `start` and `end`
26969 * positions of the view.
26970 */
26971 function getView(start, end, transforms) {
26972 var index = -1,
26973 length = transforms.length;
26974
26975 while (++index < length) {
26976 var data = transforms[index],
26977 size = data.size;
26978
26979 switch (data.type) {
26980 case 'drop': start += size; break;
26981 case 'dropRight': end -= size; break;
26982 case 'take': end = nativeMin(end, start + size); break;
26983 case 'takeRight': start = nativeMax(start, end - size); break;
26984 }
26985 }
26986 return { 'start': start, 'end': end };
26987 }
26988
26989 /**
26990 * Extracts wrapper details from the `source` body comment.
26991 *
26992 * @private
26993 * @param {string} source The source to inspect.
26994 * @returns {Array} Returns the wrapper details.
26995 */
26996 function getWrapDetails(source) {
26997 var match = source.match(reWrapDetails);
26998 return match ? match[1].split(reSplitDetails) : [];
26999 }
27000
27001 /**
27002 * Checks if `path` exists on `object`.
27003 *
27004 * @private
27005 * @param {Object} object The object to query.
27006 * @param {Array|string} path The path to check.
27007 * @param {Function} hasFunc The function to check properties.
27008 * @returns {boolean} Returns `true` if `path` exists, else `false`.
27009 */
27010 function hasPath(object, path, hasFunc) {
27011 path = castPath(path, object);
27012
27013 var index = -1,
27014 length = path.length,
27015 result = false;
27016
27017 while (++index < length) {
27018 var key = toKey(path[index]);
27019 if (!(result = object != null && hasFunc(object, key))) {
27020 break;
27021 }
27022 object = object[key];
27023 }
27024 if (result || ++index != length) {
27025 return result;
27026 }
27027 length = object == null ? 0 : object.length;
27028 return !!length && isLength(length) && isIndex(key, length) &&
27029 (isArray(object) || isArguments(object));
27030 }
27031
27032 /**
27033 * Initializes an array clone.
27034 *
27035 * @private
27036 * @param {Array} array The array to clone.
27037 * @returns {Array} Returns the initialized clone.
27038 */
27039 function initCloneArray(array) {
27040 var length = array.length,
27041 result = new array.constructor(length);
27042
27043 // Add properties assigned by `RegExp#exec`.
27044 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
27045 result.index = array.index;
27046 result.input = array.input;
27047 }
27048 return result;
27049 }
27050
27051 /**
27052 * Initializes an object clone.
27053 *
27054 * @private
27055 * @param {Object} object The object to clone.
27056 * @returns {Object} Returns the initialized clone.
27057 */
27058 function initCloneObject(object) {
27059 return (typeof object.constructor == 'function' && !isPrototype(object))
27060 ? baseCreate(getPrototype(object))
27061 : {};
27062 }
27063
27064 /**
27065 * Initializes an object clone based on its `toStringTag`.
27066 *
27067 * **Note:** This function only supports cloning values with tags of
27068 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
27069 *
27070 * @private
27071 * @param {Object} object The object to clone.
27072 * @param {string} tag The `toStringTag` of the object to clone.
27073 * @param {boolean} [isDeep] Specify a deep clone.
27074 * @returns {Object} Returns the initialized clone.
27075 */
27076 function initCloneByTag(object, tag, isDeep) {
27077 var Ctor = object.constructor;
27078 switch (tag) {
27079 case arrayBufferTag:
27080 return cloneArrayBuffer(object);
27081
27082 case boolTag:
27083 case dateTag:
27084 return new Ctor(+object);
27085
27086 case dataViewTag:
27087 return cloneDataView(object, isDeep);
27088
27089 case float32Tag: case float64Tag:
27090 case int8Tag: case int16Tag: case int32Tag:
27091 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
27092 return cloneTypedArray(object, isDeep);
27093
27094 case mapTag:
27095 return new Ctor;
27096
27097 case numberTag:
27098 case stringTag:
27099 return new Ctor(object);
27100
27101 case regexpTag:
27102 return cloneRegExp(object);
27103
27104 case setTag:
27105 return new Ctor;
27106
27107 case symbolTag:
27108 return cloneSymbol(object);
27109 }
27110 }
27111
27112 /**
27113 * Inserts wrapper `details` in a comment at the top of the `source` body.
27114 *
27115 * @private
27116 * @param {string} source The source to modify.
27117 * @returns {Array} details The details to insert.
27118 * @returns {string} Returns the modified source.
27119 */
27120 function insertWrapDetails(source, details) {
27121 var length = details.length;
27122 if (!length) {
27123 return source;
27124 }
27125 var lastIndex = length - 1;
27126 details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
27127 details = details.join(length > 2 ? ', ' : ' ');
27128 return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
27129 }
27130
27131 /**
27132 * Checks if `value` is a flattenable `arguments` object or array.
27133 *
27134 * @private
27135 * @param {*} value The value to check.
27136 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
27137 */
27138 function isFlattenable(value) {
27139 return isArray(value) || isArguments(value) ||
27140 !!(spreadableSymbol && value && value[spreadableSymbol]);
27141 }
27142
27143 /**
27144 * Checks if `value` is a valid array-like index.
27145 *
27146 * @private
27147 * @param {*} value The value to check.
27148 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
27149 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
27150 */
27151 function isIndex(value, length) {
27152 var type = typeof value;
27153 length = length == null ? MAX_SAFE_INTEGER : length;
27154
27155 return !!length &&
27156 (type == 'number' ||
27157 (type != 'symbol' && reIsUint.test(value))) &&
27158 (value > -1 && value % 1 == 0 && value < length);
27159 }
27160
27161 /**
27162 * Checks if the given arguments are from an iteratee call.
27163 *
27164 * @private
27165 * @param {*} value The potential iteratee value argument.
27166 * @param {*} index The potential iteratee index or key argument.
27167 * @param {*} object The potential iteratee object argument.
27168 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
27169 * else `false`.
27170 */
27171 function isIterateeCall(value, index, object) {
27172 if (!isObject(object)) {
27173 return false;
27174 }
27175 var type = typeof index;
27176 if (type == 'number'
27177 ? (isArrayLike(object) && isIndex(index, object.length))
27178 : (type == 'string' && index in object)
27179 ) {
27180 return eq(object[index], value);
27181 }
27182 return false;
27183 }
27184
27185 /**
27186 * Checks if `value` is a property name and not a property path.
27187 *
27188 * @private
27189 * @param {*} value The value to check.
27190 * @param {Object} [object] The object to query keys on.
27191 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
27192 */
27193 function isKey(value, object) {
27194 if (isArray(value)) {
27195 return false;
27196 }
27197 var type = typeof value;
27198 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
27199 value == null || isSymbol(value)) {
27200 return true;
27201 }
27202 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
27203 (object != null && value in Object(object));
27204 }
27205
27206 /**
27207 * Checks if `value` is suitable for use as unique object key.
27208 *
27209 * @private
27210 * @param {*} value The value to check.
27211 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
27212 */
27213 function isKeyable(value) {
27214 var type = typeof value;
27215 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
27216 ? (value !== '__proto__')
27217 : (value === null);
27218 }
27219
27220 /**
27221 * Checks if `func` has a lazy counterpart.
27222 *
27223 * @private
27224 * @param {Function} func The function to check.
27225 * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
27226 * else `false`.
27227 */
27228 function isLaziable(func) {
27229 var funcName = getFuncName(func),
27230 other = lodash[funcName];
27231
27232 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
27233 return false;
27234 }
27235 if (func === other) {
27236 return true;
27237 }
27238 var data = getData(other);
27239 return !!data && func === data[0];
27240 }
27241
27242 /**
27243 * Checks if `func` has its source masked.
27244 *
27245 * @private
27246 * @param {Function} func The function to check.
27247 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
27248 */
27249 function isMasked(func) {
27250 return !!maskSrcKey && (maskSrcKey in func);
27251 }
27252
27253 /**
27254 * Checks if `func` is capable of being masked.
27255 *
27256 * @private
27257 * @param {*} value The value to check.
27258 * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
27259 */
27260 var isMaskable = coreJsData ? isFunction : stubFalse;
27261
27262 /**
27263 * Checks if `value` is likely a prototype object.
27264 *
27265 * @private
27266 * @param {*} value The value to check.
27267 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
27268 */
27269 function isPrototype(value) {
27270 var Ctor = value && value.constructor,
27271 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
27272
27273 return value === proto;
27274 }
27275
27276 /**
27277 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
27278 *
27279 * @private
27280 * @param {*} value The value to check.
27281 * @returns {boolean} Returns `true` if `value` if suitable for strict
27282 * equality comparisons, else `false`.
27283 */
27284 function isStrictComparable(value) {
27285 return value === value && !isObject(value);
27286 }
27287
27288 /**
27289 * A specialized version of `matchesProperty` for source values suitable
27290 * for strict equality comparisons, i.e. `===`.
27291 *
27292 * @private
27293 * @param {string} key The key of the property to get.
27294 * @param {*} srcValue The value to match.
27295 * @returns {Function} Returns the new spec function.
27296 */
27297 function matchesStrictComparable(key, srcValue) {
27298 return function(object) {
27299 if (object == null) {
27300 return false;
27301 }
27302 return object[key] === srcValue &&
27303 (srcValue !== undefined$1 || (key in Object(object)));
27304 };
27305 }
27306
27307 /**
27308 * A specialized version of `_.memoize` which clears the memoized function's
27309 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
27310 *
27311 * @private
27312 * @param {Function} func The function to have its output memoized.
27313 * @returns {Function} Returns the new memoized function.
27314 */
27315 function memoizeCapped(func) {
27316 var result = memoize(func, function(key) {
27317 if (cache.size === MAX_MEMOIZE_SIZE) {
27318 cache.clear();
27319 }
27320 return key;
27321 });
27322
27323 var cache = result.cache;
27324 return result;
27325 }
27326
27327 /**
27328 * Merges the function metadata of `source` into `data`.
27329 *
27330 * Merging metadata reduces the number of wrappers used to invoke a function.
27331 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
27332 * may be applied regardless of execution order. Methods like `_.ary` and
27333 * `_.rearg` modify function arguments, making the order in which they are
27334 * executed important, preventing the merging of metadata. However, we make
27335 * an exception for a safe combined case where curried functions have `_.ary`
27336 * and or `_.rearg` applied.
27337 *
27338 * @private
27339 * @param {Array} data The destination metadata.
27340 * @param {Array} source The source metadata.
27341 * @returns {Array} Returns `data`.
27342 */
27343 function mergeData(data, source) {
27344 var bitmask = data[1],
27345 srcBitmask = source[1],
27346 newBitmask = bitmask | srcBitmask,
27347 isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
27348
27349 var isCombo =
27350 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
27351 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
27352 ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
27353
27354 // Exit early if metadata can't be merged.
27355 if (!(isCommon || isCombo)) {
27356 return data;
27357 }
27358 // Use source `thisArg` if available.
27359 if (srcBitmask & WRAP_BIND_FLAG) {
27360 data[2] = source[2];
27361 // Set when currying a bound function.
27362 newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
27363 }
27364 // Compose partial arguments.
27365 var value = source[3];
27366 if (value) {
27367 var partials = data[3];
27368 data[3] = partials ? composeArgs(partials, value, source[4]) : value;
27369 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
27370 }
27371 // Compose partial right arguments.
27372 value = source[5];
27373 if (value) {
27374 partials = data[5];
27375 data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
27376 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
27377 }
27378 // Use source `argPos` if available.
27379 value = source[7];
27380 if (value) {
27381 data[7] = value;
27382 }
27383 // Use source `ary` if it's smaller.
27384 if (srcBitmask & WRAP_ARY_FLAG) {
27385 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
27386 }
27387 // Use source `arity` if one is not provided.
27388 if (data[9] == null) {
27389 data[9] = source[9];
27390 }
27391 // Use source `func` and merge bitmasks.
27392 data[0] = source[0];
27393 data[1] = newBitmask;
27394
27395 return data;
27396 }
27397
27398 /**
27399 * This function is like
27400 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
27401 * except that it includes inherited enumerable properties.
27402 *
27403 * @private
27404 * @param {Object} object The object to query.
27405 * @returns {Array} Returns the array of property names.
27406 */
27407 function nativeKeysIn(object) {
27408 var result = [];
27409 if (object != null) {
27410 for (var key in Object(object)) {
27411 result.push(key);
27412 }
27413 }
27414 return result;
27415 }
27416
27417 /**
27418 * Converts `value` to a string using `Object.prototype.toString`.
27419 *
27420 * @private
27421 * @param {*} value The value to convert.
27422 * @returns {string} Returns the converted string.
27423 */
27424 function objectToString(value) {
27425 return nativeObjectToString.call(value);
27426 }
27427
27428 /**
27429 * A specialized version of `baseRest` which transforms the rest array.
27430 *
27431 * @private
27432 * @param {Function} func The function to apply a rest parameter to.
27433 * @param {number} [start=func.length-1] The start position of the rest parameter.
27434 * @param {Function} transform The rest array transform.
27435 * @returns {Function} Returns the new function.
27436 */
27437 function overRest(func, start, transform) {
27438 start = nativeMax(start === undefined$1 ? (func.length - 1) : start, 0);
27439 return function() {
27440 var args = arguments,
27441 index = -1,
27442 length = nativeMax(args.length - start, 0),
27443 array = Array(length);
27444
27445 while (++index < length) {
27446 array[index] = args[start + index];
27447 }
27448 index = -1;
27449 var otherArgs = Array(start + 1);
27450 while (++index < start) {
27451 otherArgs[index] = args[index];
27452 }
27453 otherArgs[start] = transform(array);
27454 return apply(func, this, otherArgs);
27455 };
27456 }
27457
27458 /**
27459 * Gets the parent value at `path` of `object`.
27460 *
27461 * @private
27462 * @param {Object} object The object to query.
27463 * @param {Array} path The path to get the parent value of.
27464 * @returns {*} Returns the parent value.
27465 */
27466 function parent(object, path) {
27467 return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
27468 }
27469
27470 /**
27471 * Reorder `array` according to the specified indexes where the element at
27472 * the first index is assigned as the first element, the element at
27473 * the second index is assigned as the second element, and so on.
27474 *
27475 * @private
27476 * @param {Array} array The array to reorder.
27477 * @param {Array} indexes The arranged array indexes.
27478 * @returns {Array} Returns `array`.
27479 */
27480 function reorder(array, indexes) {
27481 var arrLength = array.length,
27482 length = nativeMin(indexes.length, arrLength),
27483 oldArray = copyArray(array);
27484
27485 while (length--) {
27486 var index = indexes[length];
27487 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined$1;
27488 }
27489 return array;
27490 }
27491
27492 /**
27493 * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
27494 *
27495 * @private
27496 * @param {Object} object The object to query.
27497 * @param {string} key The key of the property to get.
27498 * @returns {*} Returns the property value.
27499 */
27500 function safeGet(object, key) {
27501 if (key === 'constructor' && typeof object[key] === 'function') {
27502 return;
27503 }
27504
27505 if (key == '__proto__') {
27506 return;
27507 }
27508
27509 return object[key];
27510 }
27511
27512 /**
27513 * Sets metadata for `func`.
27514 *
27515 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
27516 * period of time, it will trip its breaker and transition to an identity
27517 * function to avoid garbage collection pauses in V8. See
27518 * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
27519 * for more details.
27520 *
27521 * @private
27522 * @param {Function} func The function to associate metadata with.
27523 * @param {*} data The metadata.
27524 * @returns {Function} Returns `func`.
27525 */
27526 var setData = shortOut(baseSetData);
27527
27528 /**
27529 * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
27530 *
27531 * @private
27532 * @param {Function} func The function to delay.
27533 * @param {number} wait The number of milliseconds to delay invocation.
27534 * @returns {number|Object} Returns the timer id or timeout object.
27535 */
27536 var setTimeout = ctxSetTimeout || function(func, wait) {
27537 return root.setTimeout(func, wait);
27538 };
27539
27540 /**
27541 * Sets the `toString` method of `func` to return `string`.
27542 *
27543 * @private
27544 * @param {Function} func The function to modify.
27545 * @param {Function} string The `toString` result.
27546 * @returns {Function} Returns `func`.
27547 */
27548 var setToString = shortOut(baseSetToString);
27549
27550 /**
27551 * Sets the `toString` method of `wrapper` to mimic the source of `reference`
27552 * with wrapper details in a comment at the top of the source body.
27553 *
27554 * @private
27555 * @param {Function} wrapper The function to modify.
27556 * @param {Function} reference The reference function.
27557 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27558 * @returns {Function} Returns `wrapper`.
27559 */
27560 function setWrapToString(wrapper, reference, bitmask) {
27561 var source = (reference + '');
27562 return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
27563 }
27564
27565 /**
27566 * Creates a function that'll short out and invoke `identity` instead
27567 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
27568 * milliseconds.
27569 *
27570 * @private
27571 * @param {Function} func The function to restrict.
27572 * @returns {Function} Returns the new shortable function.
27573 */
27574 function shortOut(func) {
27575 var count = 0,
27576 lastCalled = 0;
27577
27578 return function() {
27579 var stamp = nativeNow(),
27580 remaining = HOT_SPAN - (stamp - lastCalled);
27581
27582 lastCalled = stamp;
27583 if (remaining > 0) {
27584 if (++count >= HOT_COUNT) {
27585 return arguments[0];
27586 }
27587 } else {
27588 count = 0;
27589 }
27590 return func.apply(undefined$1, arguments);
27591 };
27592 }
27593
27594 /**
27595 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
27596 *
27597 * @private
27598 * @param {Array} array The array to shuffle.
27599 * @param {number} [size=array.length] The size of `array`.
27600 * @returns {Array} Returns `array`.
27601 */
27602 function shuffleSelf(array, size) {
27603 var index = -1,
27604 length = array.length,
27605 lastIndex = length - 1;
27606
27607 size = size === undefined$1 ? length : size;
27608 while (++index < size) {
27609 var rand = baseRandom(index, lastIndex),
27610 value = array[rand];
27611
27612 array[rand] = array[index];
27613 array[index] = value;
27614 }
27615 array.length = size;
27616 return array;
27617 }
27618
27619 /**
27620 * Converts `string` to a property path array.
27621 *
27622 * @private
27623 * @param {string} string The string to convert.
27624 * @returns {Array} Returns the property path array.
27625 */
27626 var stringToPath = memoizeCapped(function(string) {
27627 var result = [];
27628 if (string.charCodeAt(0) === 46 /* . */) {
27629 result.push('');
27630 }
27631 string.replace(rePropName, function(match, number, quote, subString) {
27632 result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
27633 });
27634 return result;
27635 });
27636
27637 /**
27638 * Converts `value` to a string key if it's not a string or symbol.
27639 *
27640 * @private
27641 * @param {*} value The value to inspect.
27642 * @returns {string|symbol} Returns the key.
27643 */
27644 function toKey(value) {
27645 if (typeof value == 'string' || isSymbol(value)) {
27646 return value;
27647 }
27648 var result = (value + '');
27649 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
27650 }
27651
27652 /**
27653 * Converts `func` to its source code.
27654 *
27655 * @private
27656 * @param {Function} func The function to convert.
27657 * @returns {string} Returns the source code.
27658 */
27659 function toSource(func) {
27660 if (func != null) {
27661 try {
27662 return funcToString.call(func);
27663 } catch (e) {}
27664 try {
27665 return (func + '');
27666 } catch (e) {}
27667 }
27668 return '';
27669 }
27670
27671 /**
27672 * Updates wrapper `details` based on `bitmask` flags.
27673 *
27674 * @private
27675 * @returns {Array} details The details to modify.
27676 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27677 * @returns {Array} Returns `details`.
27678 */
27679 function updateWrapDetails(details, bitmask) {
27680 arrayEach(wrapFlags, function(pair) {
27681 var value = '_.' + pair[0];
27682 if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
27683 details.push(value);
27684 }
27685 });
27686 return details.sort();
27687 }
27688
27689 /**
27690 * Creates a clone of `wrapper`.
27691 *
27692 * @private
27693 * @param {Object} wrapper The wrapper to clone.
27694 * @returns {Object} Returns the cloned wrapper.
27695 */
27696 function wrapperClone(wrapper) {
27697 if (wrapper instanceof LazyWrapper) {
27698 return wrapper.clone();
27699 }
27700 var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
27701 result.__actions__ = copyArray(wrapper.__actions__);
27702 result.__index__ = wrapper.__index__;
27703 result.__values__ = wrapper.__values__;
27704 return result;
27705 }
27706
27707 /*------------------------------------------------------------------------*/
27708
27709 /**
27710 * Creates an array of elements split into groups the length of `size`.
27711 * If `array` can't be split evenly, the final chunk will be the remaining
27712 * elements.
27713 *
27714 * @static
27715 * @memberOf _
27716 * @since 3.0.0
27717 * @category Array
27718 * @param {Array} array The array to process.
27719 * @param {number} [size=1] The length of each chunk
27720 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
27721 * @returns {Array} Returns the new array of chunks.
27722 * @example
27723 *
27724 * _.chunk(['a', 'b', 'c', 'd'], 2);
27725 * // => [['a', 'b'], ['c', 'd']]
27726 *
27727 * _.chunk(['a', 'b', 'c', 'd'], 3);
27728 * // => [['a', 'b', 'c'], ['d']]
27729 */
27730 function chunk(array, size, guard) {
27731 if ((guard ? isIterateeCall(array, size, guard) : size === undefined$1)) {
27732 size = 1;
27733 } else {
27734 size = nativeMax(toInteger(size), 0);
27735 }
27736 var length = array == null ? 0 : array.length;
27737 if (!length || size < 1) {
27738 return [];
27739 }
27740 var index = 0,
27741 resIndex = 0,
27742 result = Array(nativeCeil(length / size));
27743
27744 while (index < length) {
27745 result[resIndex++] = baseSlice(array, index, (index += size));
27746 }
27747 return result;
27748 }
27749
27750 /**
27751 * Creates an array with all falsey values removed. The values `false`, `null`,
27752 * `0`, `""`, `undefined`, and `NaN` are falsey.
27753 *
27754 * @static
27755 * @memberOf _
27756 * @since 0.1.0
27757 * @category Array
27758 * @param {Array} array The array to compact.
27759 * @returns {Array} Returns the new array of filtered values.
27760 * @example
27761 *
27762 * _.compact([0, 1, false, 2, '', 3]);
27763 * // => [1, 2, 3]
27764 */
27765 function compact(array) {
27766 var index = -1,
27767 length = array == null ? 0 : array.length,
27768 resIndex = 0,
27769 result = [];
27770
27771 while (++index < length) {
27772 var value = array[index];
27773 if (value) {
27774 result[resIndex++] = value;
27775 }
27776 }
27777 return result;
27778 }
27779
27780 /**
27781 * Creates a new array concatenating `array` with any additional arrays
27782 * and/or values.
27783 *
27784 * @static
27785 * @memberOf _
27786 * @since 4.0.0
27787 * @category Array
27788 * @param {Array} array The array to concatenate.
27789 * @param {...*} [values] The values to concatenate.
27790 * @returns {Array} Returns the new concatenated array.
27791 * @example
27792 *
27793 * var array = [1];
27794 * var other = _.concat(array, 2, [3], [[4]]);
27795 *
27796 * console.log(other);
27797 * // => [1, 2, 3, [4]]
27798 *
27799 * console.log(array);
27800 * // => [1]
27801 */
27802 function concat() {
27803 var length = arguments.length;
27804 if (!length) {
27805 return [];
27806 }
27807 var args = Array(length - 1),
27808 array = arguments[0],
27809 index = length;
27810
27811 while (index--) {
27812 args[index - 1] = arguments[index];
27813 }
27814 return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
27815 }
27816
27817 /**
27818 * Creates an array of `array` values not included in the other given arrays
27819 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
27820 * for equality comparisons. The order and references of result values are
27821 * determined by the first array.
27822 *
27823 * **Note:** Unlike `_.pullAll`, this method returns a new array.
27824 *
27825 * @static
27826 * @memberOf _
27827 * @since 0.1.0
27828 * @category Array
27829 * @param {Array} array The array to inspect.
27830 * @param {...Array} [values] The values to exclude.
27831 * @returns {Array} Returns the new array of filtered values.
27832 * @see _.without, _.xor
27833 * @example
27834 *
27835 * _.difference([2, 1], [2, 3]);
27836 * // => [1]
27837 */
27838 var difference = baseRest(function(array, values) {
27839 return isArrayLikeObject(array)
27840 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
27841 : [];
27842 });
27843
27844 /**
27845 * This method is like `_.difference` except that it accepts `iteratee` which
27846 * is invoked for each element of `array` and `values` to generate the criterion
27847 * by which they're compared. The order and references of result values are
27848 * determined by the first array. The iteratee is invoked with one argument:
27849 * (value).
27850 *
27851 * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
27852 *
27853 * @static
27854 * @memberOf _
27855 * @since 4.0.0
27856 * @category Array
27857 * @param {Array} array The array to inspect.
27858 * @param {...Array} [values] The values to exclude.
27859 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
27860 * @returns {Array} Returns the new array of filtered values.
27861 * @example
27862 *
27863 * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
27864 * // => [1.2]
27865 *
27866 * // The `_.property` iteratee shorthand.
27867 * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
27868 * // => [{ 'x': 2 }]
27869 */
27870 var differenceBy = baseRest(function(array, values) {
27871 var iteratee = last(values);
27872 if (isArrayLikeObject(iteratee)) {
27873 iteratee = undefined$1;
27874 }
27875 return isArrayLikeObject(array)
27876 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
27877 : [];
27878 });
27879
27880 /**
27881 * This method is like `_.difference` except that it accepts `comparator`
27882 * which is invoked to compare elements of `array` to `values`. The order and
27883 * references of result values are determined by the first array. The comparator
27884 * is invoked with two arguments: (arrVal, othVal).
27885 *
27886 * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
27887 *
27888 * @static
27889 * @memberOf _
27890 * @since 4.0.0
27891 * @category Array
27892 * @param {Array} array The array to inspect.
27893 * @param {...Array} [values] The values to exclude.
27894 * @param {Function} [comparator] The comparator invoked per element.
27895 * @returns {Array} Returns the new array of filtered values.
27896 * @example
27897 *
27898 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
27899 *
27900 * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
27901 * // => [{ 'x': 2, 'y': 1 }]
27902 */
27903 var differenceWith = baseRest(function(array, values) {
27904 var comparator = last(values);
27905 if (isArrayLikeObject(comparator)) {
27906 comparator = undefined$1;
27907 }
27908 return isArrayLikeObject(array)
27909 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined$1, comparator)
27910 : [];
27911 });
27912
27913 /**
27914 * Creates a slice of `array` with `n` elements dropped from the beginning.
27915 *
27916 * @static
27917 * @memberOf _
27918 * @since 0.5.0
27919 * @category Array
27920 * @param {Array} array The array to query.
27921 * @param {number} [n=1] The number of elements to drop.
27922 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
27923 * @returns {Array} Returns the slice of `array`.
27924 * @example
27925 *
27926 * _.drop([1, 2, 3]);
27927 * // => [2, 3]
27928 *
27929 * _.drop([1, 2, 3], 2);
27930 * // => [3]
27931 *
27932 * _.drop([1, 2, 3], 5);
27933 * // => []
27934 *
27935 * _.drop([1, 2, 3], 0);
27936 * // => [1, 2, 3]
27937 */
27938 function drop(array, n, guard) {
27939 var length = array == null ? 0 : array.length;
27940 if (!length) {
27941 return [];
27942 }
27943 n = (guard || n === undefined$1) ? 1 : toInteger(n);
27944 return baseSlice(array, n < 0 ? 0 : n, length);
27945 }
27946
27947 /**
27948 * Creates a slice of `array` with `n` elements dropped from the end.
27949 *
27950 * @static
27951 * @memberOf _
27952 * @since 3.0.0
27953 * @category Array
27954 * @param {Array} array The array to query.
27955 * @param {number} [n=1] The number of elements to drop.
27956 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
27957 * @returns {Array} Returns the slice of `array`.
27958 * @example
27959 *
27960 * _.dropRight([1, 2, 3]);
27961 * // => [1, 2]
27962 *
27963 * _.dropRight([1, 2, 3], 2);
27964 * // => [1]
27965 *
27966 * _.dropRight([1, 2, 3], 5);
27967 * // => []
27968 *
27969 * _.dropRight([1, 2, 3], 0);
27970 * // => [1, 2, 3]
27971 */
27972 function dropRight(array, n, guard) {
27973 var length = array == null ? 0 : array.length;
27974 if (!length) {
27975 return [];
27976 }
27977 n = (guard || n === undefined$1) ? 1 : toInteger(n);
27978 n = length - n;
27979 return baseSlice(array, 0, n < 0 ? 0 : n);
27980 }
27981
27982 /**
27983 * Creates a slice of `array` excluding elements dropped from the end.
27984 * Elements are dropped until `predicate` returns falsey. The predicate is
27985 * invoked with three arguments: (value, index, array).
27986 *
27987 * @static
27988 * @memberOf _
27989 * @since 3.0.0
27990 * @category Array
27991 * @param {Array} array The array to query.
27992 * @param {Function} [predicate=_.identity] The function invoked per iteration.
27993 * @returns {Array} Returns the slice of `array`.
27994 * @example
27995 *
27996 * var users = [
27997 * { 'user': 'barney', 'active': true },
27998 * { 'user': 'fred', 'active': false },
27999 * { 'user': 'pebbles', 'active': false }
28000 * ];
28001 *
28002 * _.dropRightWhile(users, function(o) { return !o.active; });
28003 * // => objects for ['barney']
28004 *
28005 * // The `_.matches` iteratee shorthand.
28006 * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
28007 * // => objects for ['barney', 'fred']
28008 *
28009 * // The `_.matchesProperty` iteratee shorthand.
28010 * _.dropRightWhile(users, ['active', false]);
28011 * // => objects for ['barney']
28012 *
28013 * // The `_.property` iteratee shorthand.
28014 * _.dropRightWhile(users, 'active');
28015 * // => objects for ['barney', 'fred', 'pebbles']
28016 */
28017 function dropRightWhile(array, predicate) {
28018 return (array && array.length)
28019 ? baseWhile(array, getIteratee(predicate, 3), true, true)
28020 : [];
28021 }
28022
28023 /**
28024 * Creates a slice of `array` excluding elements dropped from the beginning.
28025 * Elements are dropped until `predicate` returns falsey. The predicate is
28026 * invoked with three arguments: (value, index, array).
28027 *
28028 * @static
28029 * @memberOf _
28030 * @since 3.0.0
28031 * @category Array
28032 * @param {Array} array The array to query.
28033 * @param {Function} [predicate=_.identity] The function invoked per iteration.
28034 * @returns {Array} Returns the slice of `array`.
28035 * @example
28036 *
28037 * var users = [
28038 * { 'user': 'barney', 'active': false },
28039 * { 'user': 'fred', 'active': false },
28040 * { 'user': 'pebbles', 'active': true }
28041 * ];
28042 *
28043 * _.dropWhile(users, function(o) { return !o.active; });
28044 * // => objects for ['pebbles']
28045 *
28046 * // The `_.matches` iteratee shorthand.
28047 * _.dropWhile(users, { 'user': 'barney', 'active': false });
28048 * // => objects for ['fred', 'pebbles']
28049 *
28050 * // The `_.matchesProperty` iteratee shorthand.
28051 * _.dropWhile(users, ['active', false]);
28052 * // => objects for ['pebbles']
28053 *
28054 * // The `_.property` iteratee shorthand.
28055 * _.dropWhile(users, 'active');
28056 * // => objects for ['barney', 'fred', 'pebbles']
28057 */
28058 function dropWhile(array, predicate) {
28059 return (array && array.length)
28060 ? baseWhile(array, getIteratee(predicate, 3), true)
28061 : [];
28062 }
28063
28064 /**
28065 * Fills elements of `array` with `value` from `start` up to, but not
28066 * including, `end`.
28067 *
28068 * **Note:** This method mutates `array`.
28069 *
28070 * @static
28071 * @memberOf _
28072 * @since 3.2.0
28073 * @category Array
28074 * @param {Array} array The array to fill.
28075 * @param {*} value The value to fill `array` with.
28076 * @param {number} [start=0] The start position.
28077 * @param {number} [end=array.length] The end position.
28078 * @returns {Array} Returns `array`.
28079 * @example
28080 *
28081 * var array = [1, 2, 3];
28082 *
28083 * _.fill(array, 'a');
28084 * console.log(array);
28085 * // => ['a', 'a', 'a']
28086 *
28087 * _.fill(Array(3), 2);
28088 * // => [2, 2, 2]
28089 *
28090 * _.fill([4, 6, 8, 10], '*', 1, 3);
28091 * // => [4, '*', '*', 10]
28092 */
28093 function fill(array, value, start, end) {
28094 var length = array == null ? 0 : array.length;
28095 if (!length) {
28096 return [];
28097 }
28098 if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
28099 start = 0;
28100 end = length;
28101 }
28102 return baseFill(array, value, start, end);
28103 }
28104
28105 /**
28106 * This method is like `_.find` except that it returns the index of the first
28107 * element `predicate` returns truthy for instead of the element itself.
28108 *
28109 * @static
28110 * @memberOf _
28111 * @since 1.1.0
28112 * @category Array
28113 * @param {Array} array The array to inspect.
28114 * @param {Function} [predicate=_.identity] The function invoked per iteration.
28115 * @param {number} [fromIndex=0] The index to search from.
28116 * @returns {number} Returns the index of the found element, else `-1`.
28117 * @example
28118 *
28119 * var users = [
28120 * { 'user': 'barney', 'active': false },
28121 * { 'user': 'fred', 'active': false },
28122 * { 'user': 'pebbles', 'active': true }
28123 * ];
28124 *
28125 * _.findIndex(users, function(o) { return o.user == 'barney'; });
28126 * // => 0
28127 *
28128 * // The `_.matches` iteratee shorthand.
28129 * _.findIndex(users, { 'user': 'fred', 'active': false });
28130 * // => 1
28131 *
28132 * // The `_.matchesProperty` iteratee shorthand.
28133 * _.findIndex(users, ['active', false]);
28134 * // => 0
28135 *
28136 * // The `_.property` iteratee shorthand.
28137 * _.findIndex(users, 'active');
28138 * // => 2
28139 */
28140 function findIndex(array, predicate, fromIndex) {
28141 var length = array == null ? 0 : array.length;
28142 if (!length) {
28143 return -1;
28144 }
28145 var index = fromIndex == null ? 0 : toInteger(fromIndex);
28146 if (index < 0) {
28147 index = nativeMax(length + index, 0);
28148 }
28149 return baseFindIndex(array, getIteratee(predicate, 3), index);
28150 }
28151
28152 /**
28153 * This method is like `_.findIndex` except that it iterates over elements
28154 * of `collection` from right to left.
28155 *
28156 * @static
28157 * @memberOf _
28158 * @since 2.0.0
28159 * @category Array
28160 * @param {Array} array The array to inspect.
28161 * @param {Function} [predicate=_.identity] The function invoked per iteration.
28162 * @param {number} [fromIndex=array.length-1] The index to search from.
28163 * @returns {number} Returns the index of the found element, else `-1`.
28164 * @example
28165 *
28166 * var users = [
28167 * { 'user': 'barney', 'active': true },
28168 * { 'user': 'fred', 'active': false },
28169 * { 'user': 'pebbles', 'active': false }
28170 * ];
28171 *
28172 * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
28173 * // => 2
28174 *
28175 * // The `_.matches` iteratee shorthand.
28176 * _.findLastIndex(users, { 'user': 'barney', 'active': true });
28177 * // => 0
28178 *
28179 * // The `_.matchesProperty` iteratee shorthand.
28180 * _.findLastIndex(users, ['active', false]);
28181 * // => 2
28182 *
28183 * // The `_.property` iteratee shorthand.
28184 * _.findLastIndex(users, 'active');
28185 * // => 0
28186 */
28187 function findLastIndex(array, predicate, fromIndex) {
28188 var length = array == null ? 0 : array.length;
28189 if (!length) {
28190 return -1;
28191 }
28192 var index = length - 1;
28193 if (fromIndex !== undefined$1) {
28194 index = toInteger(fromIndex);
28195 index = fromIndex < 0
28196 ? nativeMax(length + index, 0)
28197 : nativeMin(index, length - 1);
28198 }
28199 return baseFindIndex(array, getIteratee(predicate, 3), index, true);
28200 }
28201
28202 /**
28203 * Flattens `array` a single level deep.
28204 *
28205 * @static
28206 * @memberOf _
28207 * @since 0.1.0
28208 * @category Array
28209 * @param {Array} array The array to flatten.
28210 * @returns {Array} Returns the new flattened array.
28211 * @example
28212 *
28213 * _.flatten([1, [2, [3, [4]], 5]]);
28214 * // => [1, 2, [3, [4]], 5]
28215 */
28216 function flatten(array) {
28217 var length = array == null ? 0 : array.length;
28218 return length ? baseFlatten(array, 1) : [];
28219 }
28220
28221 /**
28222 * Recursively flattens `array`.
28223 *
28224 * @static
28225 * @memberOf _
28226 * @since 3.0.0
28227 * @category Array
28228 * @param {Array} array The array to flatten.
28229 * @returns {Array} Returns the new flattened array.
28230 * @example
28231 *
28232 * _.flattenDeep([1, [2, [3, [4]], 5]]);
28233 * // => [1, 2, 3, 4, 5]
28234 */
28235 function flattenDeep(array) {
28236 var length = array == null ? 0 : array.length;
28237 return length ? baseFlatten(array, INFINITY) : [];
28238 }
28239
28240 /**
28241 * Recursively flatten `array` up to `depth` times.
28242 *
28243 * @static
28244 * @memberOf _
28245 * @since 4.4.0
28246 * @category Array
28247 * @param {Array} array The array to flatten.
28248 * @param {number} [depth=1] The maximum recursion depth.
28249 * @returns {Array} Returns the new flattened array.
28250 * @example
28251 *
28252 * var array = [1, [2, [3, [4]], 5]];
28253 *
28254 * _.flattenDepth(array, 1);
28255 * // => [1, 2, [3, [4]], 5]
28256 *
28257 * _.flattenDepth(array, 2);
28258 * // => [1, 2, 3, [4], 5]
28259 */
28260 function flattenDepth(array, depth) {
28261 var length = array == null ? 0 : array.length;
28262 if (!length) {
28263 return [];
28264 }
28265 depth = depth === undefined$1 ? 1 : toInteger(depth);
28266 return baseFlatten(array, depth);
28267 }
28268
28269 /**
28270 * The inverse of `_.toPairs`; this method returns an object composed
28271 * from key-value `pairs`.
28272 *
28273 * @static
28274 * @memberOf _
28275 * @since 4.0.0
28276 * @category Array
28277 * @param {Array} pairs The key-value pairs.
28278 * @returns {Object} Returns the new object.
28279 * @example
28280 *
28281 * _.fromPairs([['a', 1], ['b', 2]]);
28282 * // => { 'a': 1, 'b': 2 }
28283 */
28284 function fromPairs(pairs) {
28285 var index = -1,
28286 length = pairs == null ? 0 : pairs.length,
28287 result = {};
28288
28289 while (++index < length) {
28290 var pair = pairs[index];
28291 result[pair[0]] = pair[1];
28292 }
28293 return result;
28294 }
28295
28296 /**
28297 * Gets the first element of `array`.
28298 *
28299 * @static
28300 * @memberOf _
28301 * @since 0.1.0
28302 * @alias first
28303 * @category Array
28304 * @param {Array} array The array to query.
28305 * @returns {*} Returns the first element of `array`.
28306 * @example
28307 *
28308 * _.head([1, 2, 3]);
28309 * // => 1
28310 *
28311 * _.head([]);
28312 * // => undefined
28313 */
28314 function head(array) {
28315 return (array && array.length) ? array[0] : undefined$1;
28316 }
28317
28318 /**
28319 * Gets the index at which the first occurrence of `value` is found in `array`
28320 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
28321 * for equality comparisons. If `fromIndex` is negative, it's used as the
28322 * offset from the end of `array`.
28323 *
28324 * @static
28325 * @memberOf _
28326 * @since 0.1.0
28327 * @category Array
28328 * @param {Array} array The array to inspect.
28329 * @param {*} value The value to search for.
28330 * @param {number} [fromIndex=0] The index to search from.
28331 * @returns {number} Returns the index of the matched value, else `-1`.
28332 * @example
28333 *
28334 * _.indexOf([1, 2, 1, 2], 2);
28335 * // => 1
28336 *
28337 * // Search from the `fromIndex`.
28338 * _.indexOf([1, 2, 1, 2], 2, 2);
28339 * // => 3
28340 */
28341 function indexOf(array, value, fromIndex) {
28342 var length = array == null ? 0 : array.length;
28343 if (!length) {
28344 return -1;
28345 }
28346 var index = fromIndex == null ? 0 : toInteger(fromIndex);
28347 if (index < 0) {
28348 index = nativeMax(length + index, 0);
28349 }
28350 return baseIndexOf(array, value, index);
28351 }
28352
28353 /**
28354 * Gets all but the last element of `array`.
28355 *
28356 * @static
28357 * @memberOf _
28358 * @since 0.1.0
28359 * @category Array
28360 * @param {Array} array The array to query.
28361 * @returns {Array} Returns the slice of `array`.
28362 * @example
28363 *
28364 * _.initial([1, 2, 3]);
28365 * // => [1, 2]
28366 */
28367 function initial(array) {
28368 var length = array == null ? 0 : array.length;
28369 return length ? baseSlice(array, 0, -1) : [];
28370 }
28371
28372 /**
28373 * Creates an array of unique values that are included in all given arrays
28374 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
28375 * for equality comparisons. The order and references of result values are
28376 * determined by the first array.
28377 *
28378 * @static
28379 * @memberOf _
28380 * @since 0.1.0
28381 * @category Array
28382 * @param {...Array} [arrays] The arrays to inspect.
28383 * @returns {Array} Returns the new array of intersecting values.
28384 * @example
28385 *
28386 * _.intersection([2, 1], [2, 3]);
28387 * // => [2]
28388 */
28389 var intersection = baseRest(function(arrays) {
28390 var mapped = arrayMap(arrays, castArrayLikeObject);
28391 return (mapped.length && mapped[0] === arrays[0])
28392 ? baseIntersection(mapped)
28393 : [];
28394 });
28395
28396 /**
28397 * This method is like `_.intersection` except that it accepts `iteratee`
28398 * which is invoked for each element of each `arrays` to generate the criterion
28399 * by which they're compared. The order and references of result values are
28400 * determined by the first array. The iteratee is invoked with one argument:
28401 * (value).
28402 *
28403 * @static
28404 * @memberOf _
28405 * @since 4.0.0
28406 * @category Array
28407 * @param {...Array} [arrays] The arrays to inspect.
28408 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
28409 * @returns {Array} Returns the new array of intersecting values.
28410 * @example
28411 *
28412 * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
28413 * // => [2.1]
28414 *
28415 * // The `_.property` iteratee shorthand.
28416 * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
28417 * // => [{ 'x': 1 }]
28418 */
28419 var intersectionBy = baseRest(function(arrays) {
28420 var iteratee = last(arrays),
28421 mapped = arrayMap(arrays, castArrayLikeObject);
28422
28423 if (iteratee === last(mapped)) {
28424 iteratee = undefined$1;
28425 } else {
28426 mapped.pop();
28427 }
28428 return (mapped.length && mapped[0] === arrays[0])
28429 ? baseIntersection(mapped, getIteratee(iteratee, 2))
28430 : [];
28431 });
28432
28433 /**
28434 * This method is like `_.intersection` except that it accepts `comparator`
28435 * which is invoked to compare elements of `arrays`. The order and references
28436 * of result values are determined by the first array. The comparator is
28437 * invoked with two arguments: (arrVal, othVal).
28438 *
28439 * @static
28440 * @memberOf _
28441 * @since 4.0.0
28442 * @category Array
28443 * @param {...Array} [arrays] The arrays to inspect.
28444 * @param {Function} [comparator] The comparator invoked per element.
28445 * @returns {Array} Returns the new array of intersecting values.
28446 * @example
28447 *
28448 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
28449 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
28450 *
28451 * _.intersectionWith(objects, others, _.isEqual);
28452 * // => [{ 'x': 1, 'y': 2 }]
28453 */
28454 var intersectionWith = baseRest(function(arrays) {
28455 var comparator = last(arrays),
28456 mapped = arrayMap(arrays, castArrayLikeObject);
28457
28458 comparator = typeof comparator == 'function' ? comparator : undefined$1;
28459 if (comparator) {
28460 mapped.pop();
28461 }
28462 return (mapped.length && mapped[0] === arrays[0])
28463 ? baseIntersection(mapped, undefined$1, comparator)
28464 : [];
28465 });
28466
28467 /**
28468 * Converts all elements in `array` into a string separated by `separator`.
28469 *
28470 * @static
28471 * @memberOf _
28472 * @since 4.0.0
28473 * @category Array
28474 * @param {Array} array The array to convert.
28475 * @param {string} [separator=','] The element separator.
28476 * @returns {string} Returns the joined string.
28477 * @example
28478 *
28479 * _.join(['a', 'b', 'c'], '~');
28480 * // => 'a~b~c'
28481 */
28482 function join(array, separator) {
28483 return array == null ? '' : nativeJoin.call(array, separator);
28484 }
28485
28486 /**
28487 * Gets the last element of `array`.
28488 *
28489 * @static
28490 * @memberOf _
28491 * @since 0.1.0
28492 * @category Array
28493 * @param {Array} array The array to query.
28494 * @returns {*} Returns the last element of `array`.
28495 * @example
28496 *
28497 * _.last([1, 2, 3]);
28498 * // => 3
28499 */
28500 function last(array) {
28501 var length = array == null ? 0 : array.length;
28502 return length ? array[length - 1] : undefined$1;
28503 }
28504
28505 /**
28506 * This method is like `_.indexOf` except that it iterates over elements of
28507 * `array` from right to left.
28508 *
28509 * @static
28510 * @memberOf _
28511 * @since 0.1.0
28512 * @category Array
28513 * @param {Array} array The array to inspect.
28514 * @param {*} value The value to search for.
28515 * @param {number} [fromIndex=array.length-1] The index to search from.
28516 * @returns {number} Returns the index of the matched value, else `-1`.
28517 * @example
28518 *
28519 * _.lastIndexOf([1, 2, 1, 2], 2);
28520 * // => 3
28521 *
28522 * // Search from the `fromIndex`.
28523 * _.lastIndexOf([1, 2, 1, 2], 2, 2);
28524 * // => 1
28525 */
28526 function lastIndexOf(array, value, fromIndex) {
28527 var length = array == null ? 0 : array.length;
28528 if (!length) {
28529 return -1;
28530 }
28531 var index = length;
28532 if (fromIndex !== undefined$1) {
28533 index = toInteger(fromIndex);
28534 index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
28535 }
28536 return value === value
28537 ? strictLastIndexOf(array, value, index)
28538 : baseFindIndex(array, baseIsNaN, index, true);
28539 }
28540
28541 /**
28542 * Gets the element at index `n` of `array`. If `n` is negative, the nth
28543 * element from the end is returned.
28544 *
28545 * @static
28546 * @memberOf _
28547 * @since 4.11.0
28548 * @category Array
28549 * @param {Array} array The array to query.
28550 * @param {number} [n=0] The index of the element to return.
28551 * @returns {*} Returns the nth element of `array`.
28552 * @example
28553 *
28554 * var array = ['a', 'b', 'c', 'd'];
28555 *
28556 * _.nth(array, 1);
28557 * // => 'b'
28558 *
28559 * _.nth(array, -2);
28560 * // => 'c';
28561 */
28562 function nth(array, n) {
28563 return (array && array.length) ? baseNth(array, toInteger(n)) : undefined$1;
28564 }
28565
28566 /**
28567 * Removes all given values from `array` using
28568 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
28569 * for equality comparisons.
28570 *
28571 * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
28572 * to remove elements from an array by predicate.
28573 *
28574 * @static
28575 * @memberOf _
28576 * @since 2.0.0
28577 * @category Array
28578 * @param {Array} array The array to modify.
28579 * @param {...*} [values] The values to remove.
28580 * @returns {Array} Returns `array`.
28581 * @example
28582 *
28583 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
28584 *
28585 * _.pull(array, 'a', 'c');
28586 * console.log(array);
28587 * // => ['b', 'b']
28588 */
28589 var pull = baseRest(pullAll);
28590
28591 /**
28592 * This method is like `_.pull` except that it accepts an array of values to remove.
28593 *
28594 * **Note:** Unlike `_.difference`, this method mutates `array`.
28595 *
28596 * @static
28597 * @memberOf _
28598 * @since 4.0.0
28599 * @category Array
28600 * @param {Array} array The array to modify.
28601 * @param {Array} values The values to remove.
28602 * @returns {Array} Returns `array`.
28603 * @example
28604 *
28605 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
28606 *
28607 * _.pullAll(array, ['a', 'c']);
28608 * console.log(array);
28609 * // => ['b', 'b']
28610 */
28611 function pullAll(array, values) {
28612 return (array && array.length && values && values.length)
28613 ? basePullAll(array, values)
28614 : array;
28615 }
28616
28617 /**
28618 * This method is like `_.pullAll` except that it accepts `iteratee` which is
28619 * invoked for each element of `array` and `values` to generate the criterion
28620 * by which they're compared. The iteratee is invoked with one argument: (value).
28621 *
28622 * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
28623 *
28624 * @static
28625 * @memberOf _
28626 * @since 4.0.0
28627 * @category Array
28628 * @param {Array} array The array to modify.
28629 * @param {Array} values The values to remove.
28630 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
28631 * @returns {Array} Returns `array`.
28632 * @example
28633 *
28634 * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
28635 *
28636 * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
28637 * console.log(array);
28638 * // => [{ 'x': 2 }]
28639 */
28640 function pullAllBy(array, values, iteratee) {
28641 return (array && array.length && values && values.length)
28642 ? basePullAll(array, values, getIteratee(iteratee, 2))
28643 : array;
28644 }
28645
28646 /**
28647 * This method is like `_.pullAll` except that it accepts `comparator` which
28648 * is invoked to compare elements of `array` to `values`. The comparator is
28649 * invoked with two arguments: (arrVal, othVal).
28650 *
28651 * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
28652 *
28653 * @static
28654 * @memberOf _
28655 * @since 4.6.0
28656 * @category Array
28657 * @param {Array} array The array to modify.
28658 * @param {Array} values The values to remove.
28659 * @param {Function} [comparator] The comparator invoked per element.
28660 * @returns {Array} Returns `array`.
28661 * @example
28662 *
28663 * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
28664 *
28665 * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
28666 * console.log(array);
28667 * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
28668 */
28669 function pullAllWith(array, values, comparator) {
28670 return (array && array.length && values && values.length)
28671 ? basePullAll(array, values, undefined$1, comparator)
28672 : array;
28673 }
28674
28675 /**
28676 * Removes elements from `array` corresponding to `indexes` and returns an
28677 * array of removed elements.
28678 *
28679 * **Note:** Unlike `_.at`, this method mutates `array`.
28680 *
28681 * @static
28682 * @memberOf _
28683 * @since 3.0.0
28684 * @category Array
28685 * @param {Array} array The array to modify.
28686 * @param {...(number|number[])} [indexes] The indexes of elements to remove.
28687 * @returns {Array} Returns the new array of removed elements.
28688 * @example
28689 *
28690 * var array = ['a', 'b', 'c', 'd'];
28691 * var pulled = _.pullAt(array, [1, 3]);
28692 *
28693 * console.log(array);
28694 * // => ['a', 'c']
28695 *
28696 * console.log(pulled);
28697 * // => ['b', 'd']
28698 */
28699 var pullAt = flatRest(function(array, indexes) {
28700 var length = array == null ? 0 : array.length,
28701 result = baseAt(array, indexes);
28702
28703 basePullAt(array, arrayMap(indexes, function(index) {
28704 return isIndex(index, length) ? +index : index;
28705 }).sort(compareAscending));
28706
28707 return result;
28708 });
28709
28710 /**
28711 * Removes all elements from `array` that `predicate` returns truthy for
28712 * and returns an array of the removed elements. The predicate is invoked
28713 * with three arguments: (value, index, array).
28714 *
28715 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
28716 * to pull elements from an array by value.
28717 *
28718 * @static
28719 * @memberOf _
28720 * @since 2.0.0
28721 * @category Array
28722 * @param {Array} array The array to modify.
28723 * @param {Function} [predicate=_.identity] The function invoked per iteration.
28724 * @returns {Array} Returns the new array of removed elements.
28725 * @example
28726 *
28727 * var array = [1, 2, 3, 4];
28728 * var evens = _.remove(array, function(n) {
28729 * return n % 2 == 0;
28730 * });
28731 *
28732 * console.log(array);
28733 * // => [1, 3]
28734 *
28735 * console.log(evens);
28736 * // => [2, 4]
28737 */
28738 function remove(array, predicate) {
28739 var result = [];
28740 if (!(array && array.length)) {
28741 return result;
28742 }
28743 var index = -1,
28744 indexes = [],
28745 length = array.length;
28746
28747 predicate = getIteratee(predicate, 3);
28748 while (++index < length) {
28749 var value = array[index];
28750 if (predicate(value, index, array)) {
28751 result.push(value);
28752 indexes.push(index);
28753 }
28754 }
28755 basePullAt(array, indexes);
28756 return result;
28757 }
28758
28759 /**
28760 * Reverses `array` so that the first element becomes the last, the second
28761 * element becomes the second to last, and so on.
28762 *
28763 * **Note:** This method mutates `array` and is based on
28764 * [`Array#reverse`](https://mdn.io/Array/reverse).
28765 *
28766 * @static
28767 * @memberOf _
28768 * @since 4.0.0
28769 * @category Array
28770 * @param {Array} array The array to modify.
28771 * @returns {Array} Returns `array`.
28772 * @example
28773 *
28774 * var array = [1, 2, 3];
28775 *
28776 * _.reverse(array);
28777 * // => [3, 2, 1]
28778 *
28779 * console.log(array);
28780 * // => [3, 2, 1]
28781 */
28782 function reverse(array) {
28783 return array == null ? array : nativeReverse.call(array);
28784 }
28785
28786 /**
28787 * Creates a slice of `array` from `start` up to, but not including, `end`.
28788 *
28789 * **Note:** This method is used instead of
28790 * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
28791 * returned.
28792 *
28793 * @static
28794 * @memberOf _
28795 * @since 3.0.0
28796 * @category Array
28797 * @param {Array} array The array to slice.
28798 * @param {number} [start=0] The start position.
28799 * @param {number} [end=array.length] The end position.
28800 * @returns {Array} Returns the slice of `array`.
28801 */
28802 function slice(array, start, end) {
28803 var length = array == null ? 0 : array.length;
28804 if (!length) {
28805 return [];
28806 }
28807 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
28808 start = 0;
28809 end = length;
28810 }
28811 else {
28812 start = start == null ? 0 : toInteger(start);
28813 end = end === undefined$1 ? length : toInteger(end);
28814 }
28815 return baseSlice(array, start, end);
28816 }
28817
28818 /**
28819 * Uses a binary search to determine the lowest index at which `value`
28820 * should be inserted into `array` in order to maintain its sort order.
28821 *
28822 * @static
28823 * @memberOf _
28824 * @since 0.1.0
28825 * @category Array
28826 * @param {Array} array The sorted array to inspect.
28827 * @param {*} value The value to evaluate.
28828 * @returns {number} Returns the index at which `value` should be inserted
28829 * into `array`.
28830 * @example
28831 *
28832 * _.sortedIndex([30, 50], 40);
28833 * // => 1
28834 */
28835 function sortedIndex(array, value) {
28836 return baseSortedIndex(array, value);
28837 }
28838
28839 /**
28840 * This method is like `_.sortedIndex` except that it accepts `iteratee`
28841 * which is invoked for `value` and each element of `array` to compute their
28842 * sort ranking. The iteratee is invoked with one argument: (value).
28843 *
28844 * @static
28845 * @memberOf _
28846 * @since 4.0.0
28847 * @category Array
28848 * @param {Array} array The sorted array to inspect.
28849 * @param {*} value The value to evaluate.
28850 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
28851 * @returns {number} Returns the index at which `value` should be inserted
28852 * into `array`.
28853 * @example
28854 *
28855 * var objects = [{ 'x': 4 }, { 'x': 5 }];
28856 *
28857 * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
28858 * // => 0
28859 *
28860 * // The `_.property` iteratee shorthand.
28861 * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
28862 * // => 0
28863 */
28864 function sortedIndexBy(array, value, iteratee) {
28865 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
28866 }
28867
28868 /**
28869 * This method is like `_.indexOf` except that it performs a binary
28870 * search on a sorted `array`.
28871 *
28872 * @static
28873 * @memberOf _
28874 * @since 4.0.0
28875 * @category Array
28876 * @param {Array} array The array to inspect.
28877 * @param {*} value The value to search for.
28878 * @returns {number} Returns the index of the matched value, else `-1`.
28879 * @example
28880 *
28881 * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
28882 * // => 1
28883 */
28884 function sortedIndexOf(array, value) {
28885 var length = array == null ? 0 : array.length;
28886 if (length) {
28887 var index = baseSortedIndex(array, value);
28888 if (index < length && eq(array[index], value)) {
28889 return index;
28890 }
28891 }
28892 return -1;
28893 }
28894
28895 /**
28896 * This method is like `_.sortedIndex` except that it returns the highest
28897 * index at which `value` should be inserted into `array` in order to
28898 * maintain its sort order.
28899 *
28900 * @static
28901 * @memberOf _
28902 * @since 3.0.0
28903 * @category Array
28904 * @param {Array} array The sorted array to inspect.
28905 * @param {*} value The value to evaluate.
28906 * @returns {number} Returns the index at which `value` should be inserted
28907 * into `array`.
28908 * @example
28909 *
28910 * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
28911 * // => 4
28912 */
28913 function sortedLastIndex(array, value) {
28914 return baseSortedIndex(array, value, true);
28915 }
28916
28917 /**
28918 * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
28919 * which is invoked for `value` and each element of `array` to compute their
28920 * sort ranking. The iteratee is invoked with one argument: (value).
28921 *
28922 * @static
28923 * @memberOf _
28924 * @since 4.0.0
28925 * @category Array
28926 * @param {Array} array The sorted array to inspect.
28927 * @param {*} value The value to evaluate.
28928 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
28929 * @returns {number} Returns the index at which `value` should be inserted
28930 * into `array`.
28931 * @example
28932 *
28933 * var objects = [{ 'x': 4 }, { 'x': 5 }];
28934 *
28935 * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
28936 * // => 1
28937 *
28938 * // The `_.property` iteratee shorthand.
28939 * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
28940 * // => 1
28941 */
28942 function sortedLastIndexBy(array, value, iteratee) {
28943 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
28944 }
28945
28946 /**
28947 * This method is like `_.lastIndexOf` except that it performs a binary
28948 * search on a sorted `array`.
28949 *
28950 * @static
28951 * @memberOf _
28952 * @since 4.0.0
28953 * @category Array
28954 * @param {Array} array The array to inspect.
28955 * @param {*} value The value to search for.
28956 * @returns {number} Returns the index of the matched value, else `-1`.
28957 * @example
28958 *
28959 * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
28960 * // => 3
28961 */
28962 function sortedLastIndexOf(array, value) {
28963 var length = array == null ? 0 : array.length;
28964 if (length) {
28965 var index = baseSortedIndex(array, value, true) - 1;
28966 if (eq(array[index], value)) {
28967 return index;
28968 }
28969 }
28970 return -1;
28971 }
28972
28973 /**
28974 * This method is like `_.uniq` except that it's designed and optimized
28975 * for sorted arrays.
28976 *
28977 * @static
28978 * @memberOf _
28979 * @since 4.0.0
28980 * @category Array
28981 * @param {Array} array The array to inspect.
28982 * @returns {Array} Returns the new duplicate free array.
28983 * @example
28984 *
28985 * _.sortedUniq([1, 1, 2]);
28986 * // => [1, 2]
28987 */
28988 function sortedUniq(array) {
28989 return (array && array.length)
28990 ? baseSortedUniq(array)
28991 : [];
28992 }
28993
28994 /**
28995 * This method is like `_.uniqBy` except that it's designed and optimized
28996 * for sorted arrays.
28997 *
28998 * @static
28999 * @memberOf _
29000 * @since 4.0.0
29001 * @category Array
29002 * @param {Array} array The array to inspect.
29003 * @param {Function} [iteratee] The iteratee invoked per element.
29004 * @returns {Array} Returns the new duplicate free array.
29005 * @example
29006 *
29007 * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
29008 * // => [1.1, 2.3]
29009 */
29010 function sortedUniqBy(array, iteratee) {
29011 return (array && array.length)
29012 ? baseSortedUniq(array, getIteratee(iteratee, 2))
29013 : [];
29014 }
29015
29016 /**
29017 * Gets all but the first element of `array`.
29018 *
29019 * @static
29020 * @memberOf _
29021 * @since 4.0.0
29022 * @category Array
29023 * @param {Array} array The array to query.
29024 * @returns {Array} Returns the slice of `array`.
29025 * @example
29026 *
29027 * _.tail([1, 2, 3]);
29028 * // => [2, 3]
29029 */
29030 function tail(array) {
29031 var length = array == null ? 0 : array.length;
29032 return length ? baseSlice(array, 1, length) : [];
29033 }
29034
29035 /**
29036 * Creates a slice of `array` with `n` elements taken from the beginning.
29037 *
29038 * @static
29039 * @memberOf _
29040 * @since 0.1.0
29041 * @category Array
29042 * @param {Array} array The array to query.
29043 * @param {number} [n=1] The number of elements to take.
29044 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
29045 * @returns {Array} Returns the slice of `array`.
29046 * @example
29047 *
29048 * _.take([1, 2, 3]);
29049 * // => [1]
29050 *
29051 * _.take([1, 2, 3], 2);
29052 * // => [1, 2]
29053 *
29054 * _.take([1, 2, 3], 5);
29055 * // => [1, 2, 3]
29056 *
29057 * _.take([1, 2, 3], 0);
29058 * // => []
29059 */
29060 function take(array, n, guard) {
29061 if (!(array && array.length)) {
29062 return [];
29063 }
29064 n = (guard || n === undefined$1) ? 1 : toInteger(n);
29065 return baseSlice(array, 0, n < 0 ? 0 : n);
29066 }
29067
29068 /**
29069 * Creates a slice of `array` with `n` elements taken from the end.
29070 *
29071 * @static
29072 * @memberOf _
29073 * @since 3.0.0
29074 * @category Array
29075 * @param {Array} array The array to query.
29076 * @param {number} [n=1] The number of elements to take.
29077 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
29078 * @returns {Array} Returns the slice of `array`.
29079 * @example
29080 *
29081 * _.takeRight([1, 2, 3]);
29082 * // => [3]
29083 *
29084 * _.takeRight([1, 2, 3], 2);
29085 * // => [2, 3]
29086 *
29087 * _.takeRight([1, 2, 3], 5);
29088 * // => [1, 2, 3]
29089 *
29090 * _.takeRight([1, 2, 3], 0);
29091 * // => []
29092 */
29093 function takeRight(array, n, guard) {
29094 var length = array == null ? 0 : array.length;
29095 if (!length) {
29096 return [];
29097 }
29098 n = (guard || n === undefined$1) ? 1 : toInteger(n);
29099 n = length - n;
29100 return baseSlice(array, n < 0 ? 0 : n, length);
29101 }
29102
29103 /**
29104 * Creates a slice of `array` with elements taken from the end. Elements are
29105 * taken until `predicate` returns falsey. The predicate is invoked with
29106 * three arguments: (value, index, array).
29107 *
29108 * @static
29109 * @memberOf _
29110 * @since 3.0.0
29111 * @category Array
29112 * @param {Array} array The array to query.
29113 * @param {Function} [predicate=_.identity] The function invoked per iteration.
29114 * @returns {Array} Returns the slice of `array`.
29115 * @example
29116 *
29117 * var users = [
29118 * { 'user': 'barney', 'active': true },
29119 * { 'user': 'fred', 'active': false },
29120 * { 'user': 'pebbles', 'active': false }
29121 * ];
29122 *
29123 * _.takeRightWhile(users, function(o) { return !o.active; });
29124 * // => objects for ['fred', 'pebbles']
29125 *
29126 * // The `_.matches` iteratee shorthand.
29127 * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
29128 * // => objects for ['pebbles']
29129 *
29130 * // The `_.matchesProperty` iteratee shorthand.
29131 * _.takeRightWhile(users, ['active', false]);
29132 * // => objects for ['fred', 'pebbles']
29133 *
29134 * // The `_.property` iteratee shorthand.
29135 * _.takeRightWhile(users, 'active');
29136 * // => []
29137 */
29138 function takeRightWhile(array, predicate) {
29139 return (array && array.length)
29140 ? baseWhile(array, getIteratee(predicate, 3), false, true)
29141 : [];
29142 }
29143
29144 /**
29145 * Creates a slice of `array` with elements taken from the beginning. Elements
29146 * are taken until `predicate` returns falsey. The predicate is invoked with
29147 * three arguments: (value, index, array).
29148 *
29149 * @static
29150 * @memberOf _
29151 * @since 3.0.0
29152 * @category Array
29153 * @param {Array} array The array to query.
29154 * @param {Function} [predicate=_.identity] The function invoked per iteration.
29155 * @returns {Array} Returns the slice of `array`.
29156 * @example
29157 *
29158 * var users = [
29159 * { 'user': 'barney', 'active': false },
29160 * { 'user': 'fred', 'active': false },
29161 * { 'user': 'pebbles', 'active': true }
29162 * ];
29163 *
29164 * _.takeWhile(users, function(o) { return !o.active; });
29165 * // => objects for ['barney', 'fred']
29166 *
29167 * // The `_.matches` iteratee shorthand.
29168 * _.takeWhile(users, { 'user': 'barney', 'active': false });
29169 * // => objects for ['barney']
29170 *
29171 * // The `_.matchesProperty` iteratee shorthand.
29172 * _.takeWhile(users, ['active', false]);
29173 * // => objects for ['barney', 'fred']
29174 *
29175 * // The `_.property` iteratee shorthand.
29176 * _.takeWhile(users, 'active');
29177 * // => []
29178 */
29179 function takeWhile(array, predicate) {
29180 return (array && array.length)
29181 ? baseWhile(array, getIteratee(predicate, 3))
29182 : [];
29183 }
29184
29185 /**
29186 * Creates an array of unique values, in order, from all given arrays using
29187 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
29188 * for equality comparisons.
29189 *
29190 * @static
29191 * @memberOf _
29192 * @since 0.1.0
29193 * @category Array
29194 * @param {...Array} [arrays] The arrays to inspect.
29195 * @returns {Array} Returns the new array of combined values.
29196 * @example
29197 *
29198 * _.union([2], [1, 2]);
29199 * // => [2, 1]
29200 */
29201 var union = baseRest(function(arrays) {
29202 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
29203 });
29204
29205 /**
29206 * This method is like `_.union` except that it accepts `iteratee` which is
29207 * invoked for each element of each `arrays` to generate the criterion by
29208 * which uniqueness is computed. Result values are chosen from the first
29209 * array in which the value occurs. The iteratee is invoked with one argument:
29210 * (value).
29211 *
29212 * @static
29213 * @memberOf _
29214 * @since 4.0.0
29215 * @category Array
29216 * @param {...Array} [arrays] The arrays to inspect.
29217 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
29218 * @returns {Array} Returns the new array of combined values.
29219 * @example
29220 *
29221 * _.unionBy([2.1], [1.2, 2.3], Math.floor);
29222 * // => [2.1, 1.2]
29223 *
29224 * // The `_.property` iteratee shorthand.
29225 * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
29226 * // => [{ 'x': 1 }, { 'x': 2 }]
29227 */
29228 var unionBy = baseRest(function(arrays) {
29229 var iteratee = last(arrays);
29230 if (isArrayLikeObject(iteratee)) {
29231 iteratee = undefined$1;
29232 }
29233 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
29234 });
29235
29236 /**
29237 * This method is like `_.union` except that it accepts `comparator` which
29238 * is invoked to compare elements of `arrays`. Result values are chosen from
29239 * the first array in which the value occurs. The comparator is invoked
29240 * with two arguments: (arrVal, othVal).
29241 *
29242 * @static
29243 * @memberOf _
29244 * @since 4.0.0
29245 * @category Array
29246 * @param {...Array} [arrays] The arrays to inspect.
29247 * @param {Function} [comparator] The comparator invoked per element.
29248 * @returns {Array} Returns the new array of combined values.
29249 * @example
29250 *
29251 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
29252 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
29253 *
29254 * _.unionWith(objects, others, _.isEqual);
29255 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
29256 */
29257 var unionWith = baseRest(function(arrays) {
29258 var comparator = last(arrays);
29259 comparator = typeof comparator == 'function' ? comparator : undefined$1;
29260 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined$1, comparator);
29261 });
29262
29263 /**
29264 * Creates a duplicate-free version of an array, using
29265 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
29266 * for equality comparisons, in which only the first occurrence of each element
29267 * is kept. The order of result values is determined by the order they occur
29268 * in the array.
29269 *
29270 * @static
29271 * @memberOf _
29272 * @since 0.1.0
29273 * @category Array
29274 * @param {Array} array The array to inspect.
29275 * @returns {Array} Returns the new duplicate free array.
29276 * @example
29277 *
29278 * _.uniq([2, 1, 2]);
29279 * // => [2, 1]
29280 */
29281 function uniq(array) {
29282 return (array && array.length) ? baseUniq(array) : [];
29283 }
29284
29285 /**
29286 * This method is like `_.uniq` except that it accepts `iteratee` which is
29287 * invoked for each element in `array` to generate the criterion by which
29288 * uniqueness is computed. The order of result values is determined by the
29289 * order they occur in the array. The iteratee is invoked with one argument:
29290 * (value).
29291 *
29292 * @static
29293 * @memberOf _
29294 * @since 4.0.0
29295 * @category Array
29296 * @param {Array} array The array to inspect.
29297 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
29298 * @returns {Array} Returns the new duplicate free array.
29299 * @example
29300 *
29301 * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
29302 * // => [2.1, 1.2]
29303 *
29304 * // The `_.property` iteratee shorthand.
29305 * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
29306 * // => [{ 'x': 1 }, { 'x': 2 }]
29307 */
29308 function uniqBy(array, iteratee) {
29309 return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
29310 }
29311
29312 /**
29313 * This method is like `_.uniq` except that it accepts `comparator` which
29314 * is invoked to compare elements of `array`. The order of result values is
29315 * determined by the order they occur in the array.The comparator is invoked
29316 * with two arguments: (arrVal, othVal).
29317 *
29318 * @static
29319 * @memberOf _
29320 * @since 4.0.0
29321 * @category Array
29322 * @param {Array} array The array to inspect.
29323 * @param {Function} [comparator] The comparator invoked per element.
29324 * @returns {Array} Returns the new duplicate free array.
29325 * @example
29326 *
29327 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
29328 *
29329 * _.uniqWith(objects, _.isEqual);
29330 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
29331 */
29332 function uniqWith(array, comparator) {
29333 comparator = typeof comparator == 'function' ? comparator : undefined$1;
29334 return (array && array.length) ? baseUniq(array, undefined$1, comparator) : [];
29335 }
29336
29337 /**
29338 * This method is like `_.zip` except that it accepts an array of grouped
29339 * elements and creates an array regrouping the elements to their pre-zip
29340 * configuration.
29341 *
29342 * @static
29343 * @memberOf _
29344 * @since 1.2.0
29345 * @category Array
29346 * @param {Array} array The array of grouped elements to process.
29347 * @returns {Array} Returns the new array of regrouped elements.
29348 * @example
29349 *
29350 * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
29351 * // => [['a', 1, true], ['b', 2, false]]
29352 *
29353 * _.unzip(zipped);
29354 * // => [['a', 'b'], [1, 2], [true, false]]
29355 */
29356 function unzip(array) {
29357 if (!(array && array.length)) {
29358 return [];
29359 }
29360 var length = 0;
29361 array = arrayFilter(array, function(group) {
29362 if (isArrayLikeObject(group)) {
29363 length = nativeMax(group.length, length);
29364 return true;
29365 }
29366 });
29367 return baseTimes(length, function(index) {
29368 return arrayMap(array, baseProperty(index));
29369 });
29370 }
29371
29372 /**
29373 * This method is like `_.unzip` except that it accepts `iteratee` to specify
29374 * how regrouped values should be combined. The iteratee is invoked with the
29375 * elements of each group: (...group).
29376 *
29377 * @static
29378 * @memberOf _
29379 * @since 3.8.0
29380 * @category Array
29381 * @param {Array} array The array of grouped elements to process.
29382 * @param {Function} [iteratee=_.identity] The function to combine
29383 * regrouped values.
29384 * @returns {Array} Returns the new array of regrouped elements.
29385 * @example
29386 *
29387 * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
29388 * // => [[1, 10, 100], [2, 20, 200]]
29389 *
29390 * _.unzipWith(zipped, _.add);
29391 * // => [3, 30, 300]
29392 */
29393 function unzipWith(array, iteratee) {
29394 if (!(array && array.length)) {
29395 return [];
29396 }
29397 var result = unzip(array);
29398 if (iteratee == null) {
29399 return result;
29400 }
29401 return arrayMap(result, function(group) {
29402 return apply(iteratee, undefined$1, group);
29403 });
29404 }
29405
29406 /**
29407 * Creates an array excluding all given values using
29408 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
29409 * for equality comparisons.
29410 *
29411 * **Note:** Unlike `_.pull`, this method returns a new array.
29412 *
29413 * @static
29414 * @memberOf _
29415 * @since 0.1.0
29416 * @category Array
29417 * @param {Array} array The array to inspect.
29418 * @param {...*} [values] The values to exclude.
29419 * @returns {Array} Returns the new array of filtered values.
29420 * @see _.difference, _.xor
29421 * @example
29422 *
29423 * _.without([2, 1, 2, 3], 1, 2);
29424 * // => [3]
29425 */
29426 var without = baseRest(function(array, values) {
29427 return isArrayLikeObject(array)
29428 ? baseDifference(array, values)
29429 : [];
29430 });
29431
29432 /**
29433 * Creates an array of unique values that is the
29434 * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
29435 * of the given arrays. The order of result values is determined by the order
29436 * they occur in the arrays.
29437 *
29438 * @static
29439 * @memberOf _
29440 * @since 2.4.0
29441 * @category Array
29442 * @param {...Array} [arrays] The arrays to inspect.
29443 * @returns {Array} Returns the new array of filtered values.
29444 * @see _.difference, _.without
29445 * @example
29446 *
29447 * _.xor([2, 1], [2, 3]);
29448 * // => [1, 3]
29449 */
29450 var xor = baseRest(function(arrays) {
29451 return baseXor(arrayFilter(arrays, isArrayLikeObject));
29452 });
29453
29454 /**
29455 * This method is like `_.xor` except that it accepts `iteratee` which is
29456 * invoked for each element of each `arrays` to generate the criterion by
29457 * which by which they're compared. The order of result values is determined
29458 * by the order they occur in the arrays. The iteratee is invoked with one
29459 * argument: (value).
29460 *
29461 * @static
29462 * @memberOf _
29463 * @since 4.0.0
29464 * @category Array
29465 * @param {...Array} [arrays] The arrays to inspect.
29466 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
29467 * @returns {Array} Returns the new array of filtered values.
29468 * @example
29469 *
29470 * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
29471 * // => [1.2, 3.4]
29472 *
29473 * // The `_.property` iteratee shorthand.
29474 * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
29475 * // => [{ 'x': 2 }]
29476 */
29477 var xorBy = baseRest(function(arrays) {
29478 var iteratee = last(arrays);
29479 if (isArrayLikeObject(iteratee)) {
29480 iteratee = undefined$1;
29481 }
29482 return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
29483 });
29484
29485 /**
29486 * This method is like `_.xor` except that it accepts `comparator` which is
29487 * invoked to compare elements of `arrays`. The order of result values is
29488 * determined by the order they occur in the arrays. The comparator is invoked
29489 * with two arguments: (arrVal, othVal).
29490 *
29491 * @static
29492 * @memberOf _
29493 * @since 4.0.0
29494 * @category Array
29495 * @param {...Array} [arrays] The arrays to inspect.
29496 * @param {Function} [comparator] The comparator invoked per element.
29497 * @returns {Array} Returns the new array of filtered values.
29498 * @example
29499 *
29500 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
29501 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
29502 *
29503 * _.xorWith(objects, others, _.isEqual);
29504 * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
29505 */
29506 var xorWith = baseRest(function(arrays) {
29507 var comparator = last(arrays);
29508 comparator = typeof comparator == 'function' ? comparator : undefined$1;
29509 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined$1, comparator);
29510 });
29511
29512 /**
29513 * Creates an array of grouped elements, the first of which contains the
29514 * first elements of the given arrays, the second of which contains the
29515 * second elements of the given arrays, and so on.
29516 *
29517 * @static
29518 * @memberOf _
29519 * @since 0.1.0
29520 * @category Array
29521 * @param {...Array} [arrays] The arrays to process.
29522 * @returns {Array} Returns the new array of grouped elements.
29523 * @example
29524 *
29525 * _.zip(['a', 'b'], [1, 2], [true, false]);
29526 * // => [['a', 1, true], ['b', 2, false]]
29527 */
29528 var zip = baseRest(unzip);
29529
29530 /**
29531 * This method is like `_.fromPairs` except that it accepts two arrays,
29532 * one of property identifiers and one of corresponding values.
29533 *
29534 * @static
29535 * @memberOf _
29536 * @since 0.4.0
29537 * @category Array
29538 * @param {Array} [props=[]] The property identifiers.
29539 * @param {Array} [values=[]] The property values.
29540 * @returns {Object} Returns the new object.
29541 * @example
29542 *
29543 * _.zipObject(['a', 'b'], [1, 2]);
29544 * // => { 'a': 1, 'b': 2 }
29545 */
29546 function zipObject(props, values) {
29547 return baseZipObject(props || [], values || [], assignValue);
29548 }
29549
29550 /**
29551 * This method is like `_.zipObject` except that it supports property paths.
29552 *
29553 * @static
29554 * @memberOf _
29555 * @since 4.1.0
29556 * @category Array
29557 * @param {Array} [props=[]] The property identifiers.
29558 * @param {Array} [values=[]] The property values.
29559 * @returns {Object} Returns the new object.
29560 * @example
29561 *
29562 * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
29563 * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
29564 */
29565 function zipObjectDeep(props, values) {
29566 return baseZipObject(props || [], values || [], baseSet);
29567 }
29568
29569 /**
29570 * This method is like `_.zip` except that it accepts `iteratee` to specify
29571 * how grouped values should be combined. The iteratee is invoked with the
29572 * elements of each group: (...group).
29573 *
29574 * @static
29575 * @memberOf _
29576 * @since 3.8.0
29577 * @category Array
29578 * @param {...Array} [arrays] The arrays to process.
29579 * @param {Function} [iteratee=_.identity] The function to combine
29580 * grouped values.
29581 * @returns {Array} Returns the new array of grouped elements.
29582 * @example
29583 *
29584 * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
29585 * return a + b + c;
29586 * });
29587 * // => [111, 222]
29588 */
29589 var zipWith = baseRest(function(arrays) {
29590 var length = arrays.length,
29591 iteratee = length > 1 ? arrays[length - 1] : undefined$1;
29592
29593 iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined$1;
29594 return unzipWith(arrays, iteratee);
29595 });
29596
29597 /*------------------------------------------------------------------------*/
29598
29599 /**
29600 * Creates a `lodash` wrapper instance that wraps `value` with explicit method
29601 * chain sequences enabled. The result of such sequences must be unwrapped
29602 * with `_#value`.
29603 *
29604 * @static
29605 * @memberOf _
29606 * @since 1.3.0
29607 * @category Seq
29608 * @param {*} value The value to wrap.
29609 * @returns {Object} Returns the new `lodash` wrapper instance.
29610 * @example
29611 *
29612 * var users = [
29613 * { 'user': 'barney', 'age': 36 },
29614 * { 'user': 'fred', 'age': 40 },
29615 * { 'user': 'pebbles', 'age': 1 }
29616 * ];
29617 *
29618 * var youngest = _
29619 * .chain(users)
29620 * .sortBy('age')
29621 * .map(function(o) {
29622 * return o.user + ' is ' + o.age;
29623 * })
29624 * .head()
29625 * .value();
29626 * // => 'pebbles is 1'
29627 */
29628 function chain(value) {
29629 var result = lodash(value);
29630 result.__chain__ = true;
29631 return result;
29632 }
29633
29634 /**
29635 * This method invokes `interceptor` and returns `value`. The interceptor
29636 * is invoked with one argument; (value). The purpose of this method is to
29637 * "tap into" a method chain sequence in order to modify intermediate results.
29638 *
29639 * @static
29640 * @memberOf _
29641 * @since 0.1.0
29642 * @category Seq
29643 * @param {*} value The value to provide to `interceptor`.
29644 * @param {Function} interceptor The function to invoke.
29645 * @returns {*} Returns `value`.
29646 * @example
29647 *
29648 * _([1, 2, 3])
29649 * .tap(function(array) {
29650 * // Mutate input array.
29651 * array.pop();
29652 * })
29653 * .reverse()
29654 * .value();
29655 * // => [2, 1]
29656 */
29657 function tap(value, interceptor) {
29658 interceptor(value);
29659 return value;
29660 }
29661
29662 /**
29663 * This method is like `_.tap` except that it returns the result of `interceptor`.
29664 * The purpose of this method is to "pass thru" values replacing intermediate
29665 * results in a method chain sequence.
29666 *
29667 * @static
29668 * @memberOf _
29669 * @since 3.0.0
29670 * @category Seq
29671 * @param {*} value The value to provide to `interceptor`.
29672 * @param {Function} interceptor The function to invoke.
29673 * @returns {*} Returns the result of `interceptor`.
29674 * @example
29675 *
29676 * _(' abc ')
29677 * .chain()
29678 * .trim()
29679 * .thru(function(value) {
29680 * return [value];
29681 * })
29682 * .value();
29683 * // => ['abc']
29684 */
29685 function thru(value, interceptor) {
29686 return interceptor(value);
29687 }
29688
29689 /**
29690 * This method is the wrapper version of `_.at`.
29691 *
29692 * @name at
29693 * @memberOf _
29694 * @since 1.0.0
29695 * @category Seq
29696 * @param {...(string|string[])} [paths] The property paths to pick.
29697 * @returns {Object} Returns the new `lodash` wrapper instance.
29698 * @example
29699 *
29700 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
29701 *
29702 * _(object).at(['a[0].b.c', 'a[1]']).value();
29703 * // => [3, 4]
29704 */
29705 var wrapperAt = flatRest(function(paths) {
29706 var length = paths.length,
29707 start = length ? paths[0] : 0,
29708 value = this.__wrapped__,
29709 interceptor = function(object) { return baseAt(object, paths); };
29710
29711 if (length > 1 || this.__actions__.length ||
29712 !(value instanceof LazyWrapper) || !isIndex(start)) {
29713 return this.thru(interceptor);
29714 }
29715 value = value.slice(start, +start + (length ? 1 : 0));
29716 value.__actions__.push({
29717 'func': thru,
29718 'args': [interceptor],
29719 'thisArg': undefined$1
29720 });
29721 return new LodashWrapper(value, this.__chain__).thru(function(array) {
29722 if (length && !array.length) {
29723 array.push(undefined$1);
29724 }
29725 return array;
29726 });
29727 });
29728
29729 /**
29730 * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
29731 *
29732 * @name chain
29733 * @memberOf _
29734 * @since 0.1.0
29735 * @category Seq
29736 * @returns {Object} Returns the new `lodash` wrapper instance.
29737 * @example
29738 *
29739 * var users = [
29740 * { 'user': 'barney', 'age': 36 },
29741 * { 'user': 'fred', 'age': 40 }
29742 * ];
29743 *
29744 * // A sequence without explicit chaining.
29745 * _(users).head();
29746 * // => { 'user': 'barney', 'age': 36 }
29747 *
29748 * // A sequence with explicit chaining.
29749 * _(users)
29750 * .chain()
29751 * .head()
29752 * .pick('user')
29753 * .value();
29754 * // => { 'user': 'barney' }
29755 */
29756 function wrapperChain() {
29757 return chain(this);
29758 }
29759
29760 /**
29761 * Executes the chain sequence and returns the wrapped result.
29762 *
29763 * @name commit
29764 * @memberOf _
29765 * @since 3.2.0
29766 * @category Seq
29767 * @returns {Object} Returns the new `lodash` wrapper instance.
29768 * @example
29769 *
29770 * var array = [1, 2];
29771 * var wrapped = _(array).push(3);
29772 *
29773 * console.log(array);
29774 * // => [1, 2]
29775 *
29776 * wrapped = wrapped.commit();
29777 * console.log(array);
29778 * // => [1, 2, 3]
29779 *
29780 * wrapped.last();
29781 * // => 3
29782 *
29783 * console.log(array);
29784 * // => [1, 2, 3]
29785 */
29786 function wrapperCommit() {
29787 return new LodashWrapper(this.value(), this.__chain__);
29788 }
29789
29790 /**
29791 * Gets the next value on a wrapped object following the
29792 * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
29793 *
29794 * @name next
29795 * @memberOf _
29796 * @since 4.0.0
29797 * @category Seq
29798 * @returns {Object} Returns the next iterator value.
29799 * @example
29800 *
29801 * var wrapped = _([1, 2]);
29802 *
29803 * wrapped.next();
29804 * // => { 'done': false, 'value': 1 }
29805 *
29806 * wrapped.next();
29807 * // => { 'done': false, 'value': 2 }
29808 *
29809 * wrapped.next();
29810 * // => { 'done': true, 'value': undefined }
29811 */
29812 function wrapperNext() {
29813 if (this.__values__ === undefined$1) {
29814 this.__values__ = toArray(this.value());
29815 }
29816 var done = this.__index__ >= this.__values__.length,
29817 value = done ? undefined$1 : this.__values__[this.__index__++];
29818
29819 return { 'done': done, 'value': value };
29820 }
29821
29822 /**
29823 * Enables the wrapper to be iterable.
29824 *
29825 * @name Symbol.iterator
29826 * @memberOf _
29827 * @since 4.0.0
29828 * @category Seq
29829 * @returns {Object} Returns the wrapper object.
29830 * @example
29831 *
29832 * var wrapped = _([1, 2]);
29833 *
29834 * wrapped[Symbol.iterator]() === wrapped;
29835 * // => true
29836 *
29837 * Array.from(wrapped);
29838 * // => [1, 2]
29839 */
29840 function wrapperToIterator() {
29841 return this;
29842 }
29843
29844 /**
29845 * Creates a clone of the chain sequence planting `value` as the wrapped value.
29846 *
29847 * @name plant
29848 * @memberOf _
29849 * @since 3.2.0
29850 * @category Seq
29851 * @param {*} value The value to plant.
29852 * @returns {Object} Returns the new `lodash` wrapper instance.
29853 * @example
29854 *
29855 * function square(n) {
29856 * return n * n;
29857 * }
29858 *
29859 * var wrapped = _([1, 2]).map(square);
29860 * var other = wrapped.plant([3, 4]);
29861 *
29862 * other.value();
29863 * // => [9, 16]
29864 *
29865 * wrapped.value();
29866 * // => [1, 4]
29867 */
29868 function wrapperPlant(value) {
29869 var result,
29870 parent = this;
29871
29872 while (parent instanceof baseLodash) {
29873 var clone = wrapperClone(parent);
29874 clone.__index__ = 0;
29875 clone.__values__ = undefined$1;
29876 if (result) {
29877 previous.__wrapped__ = clone;
29878 } else {
29879 result = clone;
29880 }
29881 var previous = clone;
29882 parent = parent.__wrapped__;
29883 }
29884 previous.__wrapped__ = value;
29885 return result;
29886 }
29887
29888 /**
29889 * This method is the wrapper version of `_.reverse`.
29890 *
29891 * **Note:** This method mutates the wrapped array.
29892 *
29893 * @name reverse
29894 * @memberOf _
29895 * @since 0.1.0
29896 * @category Seq
29897 * @returns {Object} Returns the new `lodash` wrapper instance.
29898 * @example
29899 *
29900 * var array = [1, 2, 3];
29901 *
29902 * _(array).reverse().value()
29903 * // => [3, 2, 1]
29904 *
29905 * console.log(array);
29906 * // => [3, 2, 1]
29907 */
29908 function wrapperReverse() {
29909 var value = this.__wrapped__;
29910 if (value instanceof LazyWrapper) {
29911 var wrapped = value;
29912 if (this.__actions__.length) {
29913 wrapped = new LazyWrapper(this);
29914 }
29915 wrapped = wrapped.reverse();
29916 wrapped.__actions__.push({
29917 'func': thru,
29918 'args': [reverse],
29919 'thisArg': undefined$1
29920 });
29921 return new LodashWrapper(wrapped, this.__chain__);
29922 }
29923 return this.thru(reverse);
29924 }
29925
29926 /**
29927 * Executes the chain sequence to resolve the unwrapped value.
29928 *
29929 * @name value
29930 * @memberOf _
29931 * @since 0.1.0
29932 * @alias toJSON, valueOf
29933 * @category Seq
29934 * @returns {*} Returns the resolved unwrapped value.
29935 * @example
29936 *
29937 * _([1, 2, 3]).value();
29938 * // => [1, 2, 3]
29939 */
29940 function wrapperValue() {
29941 return baseWrapperValue(this.__wrapped__, this.__actions__);
29942 }
29943
29944 /*------------------------------------------------------------------------*/
29945
29946 /**
29947 * Creates an object composed of keys generated from the results of running
29948 * each element of `collection` thru `iteratee`. The corresponding value of
29949 * each key is the number of times the key was returned by `iteratee`. The
29950 * iteratee is invoked with one argument: (value).
29951 *
29952 * @static
29953 * @memberOf _
29954 * @since 0.5.0
29955 * @category Collection
29956 * @param {Array|Object} collection The collection to iterate over.
29957 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
29958 * @returns {Object} Returns the composed aggregate object.
29959 * @example
29960 *
29961 * _.countBy([6.1, 4.2, 6.3], Math.floor);
29962 * // => { '4': 1, '6': 2 }
29963 *
29964 * // The `_.property` iteratee shorthand.
29965 * _.countBy(['one', 'two', 'three'], 'length');
29966 * // => { '3': 2, '5': 1 }
29967 */
29968 var countBy = createAggregator(function(result, value, key) {
29969 if (hasOwnProperty.call(result, key)) {
29970 ++result[key];
29971 } else {
29972 baseAssignValue(result, key, 1);
29973 }
29974 });
29975
29976 /**
29977 * Checks if `predicate` returns truthy for **all** elements of `collection`.
29978 * Iteration is stopped once `predicate` returns falsey. The predicate is
29979 * invoked with three arguments: (value, index|key, collection).
29980 *
29981 * **Note:** This method returns `true` for
29982 * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
29983 * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
29984 * elements of empty collections.
29985 *
29986 * @static
29987 * @memberOf _
29988 * @since 0.1.0
29989 * @category Collection
29990 * @param {Array|Object} collection The collection to iterate over.
29991 * @param {Function} [predicate=_.identity] The function invoked per iteration.
29992 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
29993 * @returns {boolean} Returns `true` if all elements pass the predicate check,
29994 * else `false`.
29995 * @example
29996 *
29997 * _.every([true, 1, null, 'yes'], Boolean);
29998 * // => false
29999 *
30000 * var users = [
30001 * { 'user': 'barney', 'age': 36, 'active': false },
30002 * { 'user': 'fred', 'age': 40, 'active': false }
30003 * ];
30004 *
30005 * // The `_.matches` iteratee shorthand.
30006 * _.every(users, { 'user': 'barney', 'active': false });
30007 * // => false
30008 *
30009 * // The `_.matchesProperty` iteratee shorthand.
30010 * _.every(users, ['active', false]);
30011 * // => true
30012 *
30013 * // The `_.property` iteratee shorthand.
30014 * _.every(users, 'active');
30015 * // => false
30016 */
30017 function every(collection, predicate, guard) {
30018 var func = isArray(collection) ? arrayEvery : baseEvery;
30019 if (guard && isIterateeCall(collection, predicate, guard)) {
30020 predicate = undefined$1;
30021 }
30022 return func(collection, getIteratee(predicate, 3));
30023 }
30024
30025 /**
30026 * Iterates over elements of `collection`, returning an array of all elements
30027 * `predicate` returns truthy for. The predicate is invoked with three
30028 * arguments: (value, index|key, collection).
30029 *
30030 * **Note:** Unlike `_.remove`, this method returns a new array.
30031 *
30032 * @static
30033 * @memberOf _
30034 * @since 0.1.0
30035 * @category Collection
30036 * @param {Array|Object} collection The collection to iterate over.
30037 * @param {Function} [predicate=_.identity] The function invoked per iteration.
30038 * @returns {Array} Returns the new filtered array.
30039 * @see _.reject
30040 * @example
30041 *
30042 * var users = [
30043 * { 'user': 'barney', 'age': 36, 'active': true },
30044 * { 'user': 'fred', 'age': 40, 'active': false }
30045 * ];
30046 *
30047 * _.filter(users, function(o) { return !o.active; });
30048 * // => objects for ['fred']
30049 *
30050 * // The `_.matches` iteratee shorthand.
30051 * _.filter(users, { 'age': 36, 'active': true });
30052 * // => objects for ['barney']
30053 *
30054 * // The `_.matchesProperty` iteratee shorthand.
30055 * _.filter(users, ['active', false]);
30056 * // => objects for ['fred']
30057 *
30058 * // The `_.property` iteratee shorthand.
30059 * _.filter(users, 'active');
30060 * // => objects for ['barney']
30061 */
30062 function filter(collection, predicate) {
30063 var func = isArray(collection) ? arrayFilter : baseFilter;
30064 return func(collection, getIteratee(predicate, 3));
30065 }
30066
30067 /**
30068 * Iterates over elements of `collection`, returning the first element
30069 * `predicate` returns truthy for. The predicate is invoked with three
30070 * arguments: (value, index|key, collection).
30071 *
30072 * @static
30073 * @memberOf _
30074 * @since 0.1.0
30075 * @category Collection
30076 * @param {Array|Object} collection The collection to inspect.
30077 * @param {Function} [predicate=_.identity] The function invoked per iteration.
30078 * @param {number} [fromIndex=0] The index to search from.
30079 * @returns {*} Returns the matched element, else `undefined`.
30080 * @example
30081 *
30082 * var users = [
30083 * { 'user': 'barney', 'age': 36, 'active': true },
30084 * { 'user': 'fred', 'age': 40, 'active': false },
30085 * { 'user': 'pebbles', 'age': 1, 'active': true }
30086 * ];
30087 *
30088 * _.find(users, function(o) { return o.age < 40; });
30089 * // => object for 'barney'
30090 *
30091 * // The `_.matches` iteratee shorthand.
30092 * _.find(users, { 'age': 1, 'active': true });
30093 * // => object for 'pebbles'
30094 *
30095 * // The `_.matchesProperty` iteratee shorthand.
30096 * _.find(users, ['active', false]);
30097 * // => object for 'fred'
30098 *
30099 * // The `_.property` iteratee shorthand.
30100 * _.find(users, 'active');
30101 * // => object for 'barney'
30102 */
30103 var find = createFind(findIndex);
30104
30105 /**
30106 * This method is like `_.find` except that it iterates over elements of
30107 * `collection` from right to left.
30108 *
30109 * @static
30110 * @memberOf _
30111 * @since 2.0.0
30112 * @category Collection
30113 * @param {Array|Object} collection The collection to inspect.
30114 * @param {Function} [predicate=_.identity] The function invoked per iteration.
30115 * @param {number} [fromIndex=collection.length-1] The index to search from.
30116 * @returns {*} Returns the matched element, else `undefined`.
30117 * @example
30118 *
30119 * _.findLast([1, 2, 3, 4], function(n) {
30120 * return n % 2 == 1;
30121 * });
30122 * // => 3
30123 */
30124 var findLast = createFind(findLastIndex);
30125
30126 /**
30127 * Creates a flattened array of values by running each element in `collection`
30128 * thru `iteratee` and flattening the mapped results. The iteratee is invoked
30129 * with three arguments: (value, index|key, collection).
30130 *
30131 * @static
30132 * @memberOf _
30133 * @since 4.0.0
30134 * @category Collection
30135 * @param {Array|Object} collection The collection to iterate over.
30136 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30137 * @returns {Array} Returns the new flattened array.
30138 * @example
30139 *
30140 * function duplicate(n) {
30141 * return [n, n];
30142 * }
30143 *
30144 * _.flatMap([1, 2], duplicate);
30145 * // => [1, 1, 2, 2]
30146 */
30147 function flatMap(collection, iteratee) {
30148 return baseFlatten(map(collection, iteratee), 1);
30149 }
30150
30151 /**
30152 * This method is like `_.flatMap` except that it recursively flattens the
30153 * mapped results.
30154 *
30155 * @static
30156 * @memberOf _
30157 * @since 4.7.0
30158 * @category Collection
30159 * @param {Array|Object} collection The collection to iterate over.
30160 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30161 * @returns {Array} Returns the new flattened array.
30162 * @example
30163 *
30164 * function duplicate(n) {
30165 * return [[[n, n]]];
30166 * }
30167 *
30168 * _.flatMapDeep([1, 2], duplicate);
30169 * // => [1, 1, 2, 2]
30170 */
30171 function flatMapDeep(collection, iteratee) {
30172 return baseFlatten(map(collection, iteratee), INFINITY);
30173 }
30174
30175 /**
30176 * This method is like `_.flatMap` except that it recursively flattens the
30177 * mapped results up to `depth` times.
30178 *
30179 * @static
30180 * @memberOf _
30181 * @since 4.7.0
30182 * @category Collection
30183 * @param {Array|Object} collection The collection to iterate over.
30184 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30185 * @param {number} [depth=1] The maximum recursion depth.
30186 * @returns {Array} Returns the new flattened array.
30187 * @example
30188 *
30189 * function duplicate(n) {
30190 * return [[[n, n]]];
30191 * }
30192 *
30193 * _.flatMapDepth([1, 2], duplicate, 2);
30194 * // => [[1, 1], [2, 2]]
30195 */
30196 function flatMapDepth(collection, iteratee, depth) {
30197 depth = depth === undefined$1 ? 1 : toInteger(depth);
30198 return baseFlatten(map(collection, iteratee), depth);
30199 }
30200
30201 /**
30202 * Iterates over elements of `collection` and invokes `iteratee` for each element.
30203 * The iteratee is invoked with three arguments: (value, index|key, collection).
30204 * Iteratee functions may exit iteration early by explicitly returning `false`.
30205 *
30206 * **Note:** As with other "Collections" methods, objects with a "length"
30207 * property are iterated like arrays. To avoid this behavior use `_.forIn`
30208 * or `_.forOwn` for object iteration.
30209 *
30210 * @static
30211 * @memberOf _
30212 * @since 0.1.0
30213 * @alias each
30214 * @category Collection
30215 * @param {Array|Object} collection The collection to iterate over.
30216 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30217 * @returns {Array|Object} Returns `collection`.
30218 * @see _.forEachRight
30219 * @example
30220 *
30221 * _.forEach([1, 2], function(value) {
30222 * console.log(value);
30223 * });
30224 * // => Logs `1` then `2`.
30225 *
30226 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
30227 * console.log(key);
30228 * });
30229 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
30230 */
30231 function forEach(collection, iteratee) {
30232 var func = isArray(collection) ? arrayEach : baseEach;
30233 return func(collection, getIteratee(iteratee, 3));
30234 }
30235
30236 /**
30237 * This method is like `_.forEach` except that it iterates over elements of
30238 * `collection` from right to left.
30239 *
30240 * @static
30241 * @memberOf _
30242 * @since 2.0.0
30243 * @alias eachRight
30244 * @category Collection
30245 * @param {Array|Object} collection The collection to iterate over.
30246 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30247 * @returns {Array|Object} Returns `collection`.
30248 * @see _.forEach
30249 * @example
30250 *
30251 * _.forEachRight([1, 2], function(value) {
30252 * console.log(value);
30253 * });
30254 * // => Logs `2` then `1`.
30255 */
30256 function forEachRight(collection, iteratee) {
30257 var func = isArray(collection) ? arrayEachRight : baseEachRight;
30258 return func(collection, getIteratee(iteratee, 3));
30259 }
30260
30261 /**
30262 * Creates an object composed of keys generated from the results of running
30263 * each element of `collection` thru `iteratee`. The order of grouped values
30264 * is determined by the order they occur in `collection`. The corresponding
30265 * value of each key is an array of elements responsible for generating the
30266 * key. The iteratee is invoked with one argument: (value).
30267 *
30268 * @static
30269 * @memberOf _
30270 * @since 0.1.0
30271 * @category Collection
30272 * @param {Array|Object} collection The collection to iterate over.
30273 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
30274 * @returns {Object} Returns the composed aggregate object.
30275 * @example
30276 *
30277 * _.groupBy([6.1, 4.2, 6.3], Math.floor);
30278 * // => { '4': [4.2], '6': [6.1, 6.3] }
30279 *
30280 * // The `_.property` iteratee shorthand.
30281 * _.groupBy(['one', 'two', 'three'], 'length');
30282 * // => { '3': ['one', 'two'], '5': ['three'] }
30283 */
30284 var groupBy = createAggregator(function(result, value, key) {
30285 if (hasOwnProperty.call(result, key)) {
30286 result[key].push(value);
30287 } else {
30288 baseAssignValue(result, key, [value]);
30289 }
30290 });
30291
30292 /**
30293 * Checks if `value` is in `collection`. If `collection` is a string, it's
30294 * checked for a substring of `value`, otherwise
30295 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
30296 * is used for equality comparisons. If `fromIndex` is negative, it's used as
30297 * the offset from the end of `collection`.
30298 *
30299 * @static
30300 * @memberOf _
30301 * @since 0.1.0
30302 * @category Collection
30303 * @param {Array|Object|string} collection The collection to inspect.
30304 * @param {*} value The value to search for.
30305 * @param {number} [fromIndex=0] The index to search from.
30306 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
30307 * @returns {boolean} Returns `true` if `value` is found, else `false`.
30308 * @example
30309 *
30310 * _.includes([1, 2, 3], 1);
30311 * // => true
30312 *
30313 * _.includes([1, 2, 3], 1, 2);
30314 * // => false
30315 *
30316 * _.includes({ 'a': 1, 'b': 2 }, 1);
30317 * // => true
30318 *
30319 * _.includes('abcd', 'bc');
30320 * // => true
30321 */
30322 function includes(collection, value, fromIndex, guard) {
30323 collection = isArrayLike(collection) ? collection : values(collection);
30324 fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
30325
30326 var length = collection.length;
30327 if (fromIndex < 0) {
30328 fromIndex = nativeMax(length + fromIndex, 0);
30329 }
30330 return isString(collection)
30331 ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
30332 : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
30333 }
30334
30335 /**
30336 * Invokes the method at `path` of each element in `collection`, returning
30337 * an array of the results of each invoked method. Any additional arguments
30338 * are provided to each invoked method. If `path` is a function, it's invoked
30339 * for, and `this` bound to, each element in `collection`.
30340 *
30341 * @static
30342 * @memberOf _
30343 * @since 4.0.0
30344 * @category Collection
30345 * @param {Array|Object} collection The collection to iterate over.
30346 * @param {Array|Function|string} path The path of the method to invoke or
30347 * the function invoked per iteration.
30348 * @param {...*} [args] The arguments to invoke each method with.
30349 * @returns {Array} Returns the array of results.
30350 * @example
30351 *
30352 * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
30353 * // => [[1, 5, 7], [1, 2, 3]]
30354 *
30355 * _.invokeMap([123, 456], String.prototype.split, '');
30356 * // => [['1', '2', '3'], ['4', '5', '6']]
30357 */
30358 var invokeMap = baseRest(function(collection, path, args) {
30359 var index = -1,
30360 isFunc = typeof path == 'function',
30361 result = isArrayLike(collection) ? Array(collection.length) : [];
30362
30363 baseEach(collection, function(value) {
30364 result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
30365 });
30366 return result;
30367 });
30368
30369 /**
30370 * Creates an object composed of keys generated from the results of running
30371 * each element of `collection` thru `iteratee`. The corresponding value of
30372 * each key is the last element responsible for generating the key. The
30373 * iteratee is invoked with one argument: (value).
30374 *
30375 * @static
30376 * @memberOf _
30377 * @since 4.0.0
30378 * @category Collection
30379 * @param {Array|Object} collection The collection to iterate over.
30380 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
30381 * @returns {Object} Returns the composed aggregate object.
30382 * @example
30383 *
30384 * var array = [
30385 * { 'dir': 'left', 'code': 97 },
30386 * { 'dir': 'right', 'code': 100 }
30387 * ];
30388 *
30389 * _.keyBy(array, function(o) {
30390 * return String.fromCharCode(o.code);
30391 * });
30392 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
30393 *
30394 * _.keyBy(array, 'dir');
30395 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
30396 */
30397 var keyBy = createAggregator(function(result, value, key) {
30398 baseAssignValue(result, key, value);
30399 });
30400
30401 /**
30402 * Creates an array of values by running each element in `collection` thru
30403 * `iteratee`. The iteratee is invoked with three arguments:
30404 * (value, index|key, collection).
30405 *
30406 * Many lodash methods are guarded to work as iteratees for methods like
30407 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
30408 *
30409 * The guarded methods are:
30410 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
30411 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
30412 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
30413 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
30414 *
30415 * @static
30416 * @memberOf _
30417 * @since 0.1.0
30418 * @category Collection
30419 * @param {Array|Object} collection The collection to iterate over.
30420 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30421 * @returns {Array} Returns the new mapped array.
30422 * @example
30423 *
30424 * function square(n) {
30425 * return n * n;
30426 * }
30427 *
30428 * _.map([4, 8], square);
30429 * // => [16, 64]
30430 *
30431 * _.map({ 'a': 4, 'b': 8 }, square);
30432 * // => [16, 64] (iteration order is not guaranteed)
30433 *
30434 * var users = [
30435 * { 'user': 'barney' },
30436 * { 'user': 'fred' }
30437 * ];
30438 *
30439 * // The `_.property` iteratee shorthand.
30440 * _.map(users, 'user');
30441 * // => ['barney', 'fred']
30442 */
30443 function map(collection, iteratee) {
30444 var func = isArray(collection) ? arrayMap : baseMap;
30445 return func(collection, getIteratee(iteratee, 3));
30446 }
30447
30448 /**
30449 * This method is like `_.sortBy` except that it allows specifying the sort
30450 * orders of the iteratees to sort by. If `orders` is unspecified, all values
30451 * are sorted in ascending order. Otherwise, specify an order of "desc" for
30452 * descending or "asc" for ascending sort order of corresponding values.
30453 *
30454 * @static
30455 * @memberOf _
30456 * @since 4.0.0
30457 * @category Collection
30458 * @param {Array|Object} collection The collection to iterate over.
30459 * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
30460 * The iteratees to sort by.
30461 * @param {string[]} [orders] The sort orders of `iteratees`.
30462 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
30463 * @returns {Array} Returns the new sorted array.
30464 * @example
30465 *
30466 * var users = [
30467 * { 'user': 'fred', 'age': 48 },
30468 * { 'user': 'barney', 'age': 34 },
30469 * { 'user': 'fred', 'age': 40 },
30470 * { 'user': 'barney', 'age': 36 }
30471 * ];
30472 *
30473 * // Sort by `user` in ascending order and by `age` in descending order.
30474 * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
30475 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
30476 */
30477 function orderBy(collection, iteratees, orders, guard) {
30478 if (collection == null) {
30479 return [];
30480 }
30481 if (!isArray(iteratees)) {
30482 iteratees = iteratees == null ? [] : [iteratees];
30483 }
30484 orders = guard ? undefined$1 : orders;
30485 if (!isArray(orders)) {
30486 orders = orders == null ? [] : [orders];
30487 }
30488 return baseOrderBy(collection, iteratees, orders);
30489 }
30490
30491 /**
30492 * Creates an array of elements split into two groups, the first of which
30493 * contains elements `predicate` returns truthy for, the second of which
30494 * contains elements `predicate` returns falsey for. The predicate is
30495 * invoked with one argument: (value).
30496 *
30497 * @static
30498 * @memberOf _
30499 * @since 3.0.0
30500 * @category Collection
30501 * @param {Array|Object} collection The collection to iterate over.
30502 * @param {Function} [predicate=_.identity] The function invoked per iteration.
30503 * @returns {Array} Returns the array of grouped elements.
30504 * @example
30505 *
30506 * var users = [
30507 * { 'user': 'barney', 'age': 36, 'active': false },
30508 * { 'user': 'fred', 'age': 40, 'active': true },
30509 * { 'user': 'pebbles', 'age': 1, 'active': false }
30510 * ];
30511 *
30512 * _.partition(users, function(o) { return o.active; });
30513 * // => objects for [['fred'], ['barney', 'pebbles']]
30514 *
30515 * // The `_.matches` iteratee shorthand.
30516 * _.partition(users, { 'age': 1, 'active': false });
30517 * // => objects for [['pebbles'], ['barney', 'fred']]
30518 *
30519 * // The `_.matchesProperty` iteratee shorthand.
30520 * _.partition(users, ['active', false]);
30521 * // => objects for [['barney', 'pebbles'], ['fred']]
30522 *
30523 * // The `_.property` iteratee shorthand.
30524 * _.partition(users, 'active');
30525 * // => objects for [['fred'], ['barney', 'pebbles']]
30526 */
30527 var partition = createAggregator(function(result, value, key) {
30528 result[key ? 0 : 1].push(value);
30529 }, function() { return [[], []]; });
30530
30531 /**
30532 * Reduces `collection` to a value which is the accumulated result of running
30533 * each element in `collection` thru `iteratee`, where each successive
30534 * invocation is supplied the return value of the previous. If `accumulator`
30535 * is not given, the first element of `collection` is used as the initial
30536 * value. The iteratee is invoked with four arguments:
30537 * (accumulator, value, index|key, collection).
30538 *
30539 * Many lodash methods are guarded to work as iteratees for methods like
30540 * `_.reduce`, `_.reduceRight`, and `_.transform`.
30541 *
30542 * The guarded methods are:
30543 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
30544 * and `sortBy`
30545 *
30546 * @static
30547 * @memberOf _
30548 * @since 0.1.0
30549 * @category Collection
30550 * @param {Array|Object} collection The collection to iterate over.
30551 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30552 * @param {*} [accumulator] The initial value.
30553 * @returns {*} Returns the accumulated value.
30554 * @see _.reduceRight
30555 * @example
30556 *
30557 * _.reduce([1, 2], function(sum, n) {
30558 * return sum + n;
30559 * }, 0);
30560 * // => 3
30561 *
30562 * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
30563 * (result[value] || (result[value] = [])).push(key);
30564 * return result;
30565 * }, {});
30566 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
30567 */
30568 function reduce(collection, iteratee, accumulator) {
30569 var func = isArray(collection) ? arrayReduce : baseReduce,
30570 initAccum = arguments.length < 3;
30571
30572 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
30573 }
30574
30575 /**
30576 * This method is like `_.reduce` except that it iterates over elements of
30577 * `collection` from right to left.
30578 *
30579 * @static
30580 * @memberOf _
30581 * @since 0.1.0
30582 * @category Collection
30583 * @param {Array|Object} collection The collection to iterate over.
30584 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
30585 * @param {*} [accumulator] The initial value.
30586 * @returns {*} Returns the accumulated value.
30587 * @see _.reduce
30588 * @example
30589 *
30590 * var array = [[0, 1], [2, 3], [4, 5]];
30591 *
30592 * _.reduceRight(array, function(flattened, other) {
30593 * return flattened.concat(other);
30594 * }, []);
30595 * // => [4, 5, 2, 3, 0, 1]
30596 */
30597 function reduceRight(collection, iteratee, accumulator) {
30598 var func = isArray(collection) ? arrayReduceRight : baseReduce,
30599 initAccum = arguments.length < 3;
30600
30601 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
30602 }
30603
30604 /**
30605 * The opposite of `_.filter`; this method returns the elements of `collection`
30606 * that `predicate` does **not** return truthy for.
30607 *
30608 * @static
30609 * @memberOf _
30610 * @since 0.1.0
30611 * @category Collection
30612 * @param {Array|Object} collection The collection to iterate over.
30613 * @param {Function} [predicate=_.identity] The function invoked per iteration.
30614 * @returns {Array} Returns the new filtered array.
30615 * @see _.filter
30616 * @example
30617 *
30618 * var users = [
30619 * { 'user': 'barney', 'age': 36, 'active': false },
30620 * { 'user': 'fred', 'age': 40, 'active': true }
30621 * ];
30622 *
30623 * _.reject(users, function(o) { return !o.active; });
30624 * // => objects for ['fred']
30625 *
30626 * // The `_.matches` iteratee shorthand.
30627 * _.reject(users, { 'age': 40, 'active': true });
30628 * // => objects for ['barney']
30629 *
30630 * // The `_.matchesProperty` iteratee shorthand.
30631 * _.reject(users, ['active', false]);
30632 * // => objects for ['fred']
30633 *
30634 * // The `_.property` iteratee shorthand.
30635 * _.reject(users, 'active');
30636 * // => objects for ['barney']
30637 */
30638 function reject(collection, predicate) {
30639 var func = isArray(collection) ? arrayFilter : baseFilter;
30640 return func(collection, negate(getIteratee(predicate, 3)));
30641 }
30642
30643 /**
30644 * Gets a random element from `collection`.
30645 *
30646 * @static
30647 * @memberOf _
30648 * @since 2.0.0
30649 * @category Collection
30650 * @param {Array|Object} collection The collection to sample.
30651 * @returns {*} Returns the random element.
30652 * @example
30653 *
30654 * _.sample([1, 2, 3, 4]);
30655 * // => 2
30656 */
30657 function sample(collection) {
30658 var func = isArray(collection) ? arraySample : baseSample;
30659 return func(collection);
30660 }
30661
30662 /**
30663 * Gets `n` random elements at unique keys from `collection` up to the
30664 * size of `collection`.
30665 *
30666 * @static
30667 * @memberOf _
30668 * @since 4.0.0
30669 * @category Collection
30670 * @param {Array|Object} collection The collection to sample.
30671 * @param {number} [n=1] The number of elements to sample.
30672 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
30673 * @returns {Array} Returns the random elements.
30674 * @example
30675 *
30676 * _.sampleSize([1, 2, 3], 2);
30677 * // => [3, 1]
30678 *
30679 * _.sampleSize([1, 2, 3], 4);
30680 * // => [2, 3, 1]
30681 */
30682 function sampleSize(collection, n, guard) {
30683 if ((guard ? isIterateeCall(collection, n, guard) : n === undefined$1)) {
30684 n = 1;
30685 } else {
30686 n = toInteger(n);
30687 }
30688 var func = isArray(collection) ? arraySampleSize : baseSampleSize;
30689 return func(collection, n);
30690 }
30691
30692 /**
30693 * Creates an array of shuffled values, using a version of the
30694 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
30695 *
30696 * @static
30697 * @memberOf _
30698 * @since 0.1.0
30699 * @category Collection
30700 * @param {Array|Object} collection The collection to shuffle.
30701 * @returns {Array} Returns the new shuffled array.
30702 * @example
30703 *
30704 * _.shuffle([1, 2, 3, 4]);
30705 * // => [4, 1, 3, 2]
30706 */
30707 function shuffle(collection) {
30708 var func = isArray(collection) ? arrayShuffle : baseShuffle;
30709 return func(collection);
30710 }
30711
30712 /**
30713 * Gets the size of `collection` by returning its length for array-like
30714 * values or the number of own enumerable string keyed properties for objects.
30715 *
30716 * @static
30717 * @memberOf _
30718 * @since 0.1.0
30719 * @category Collection
30720 * @param {Array|Object|string} collection The collection to inspect.
30721 * @returns {number} Returns the collection size.
30722 * @example
30723 *
30724 * _.size([1, 2, 3]);
30725 * // => 3
30726 *
30727 * _.size({ 'a': 1, 'b': 2 });
30728 * // => 2
30729 *
30730 * _.size('pebbles');
30731 * // => 7
30732 */
30733 function size(collection) {
30734 if (collection == null) {
30735 return 0;
30736 }
30737 if (isArrayLike(collection)) {
30738 return isString(collection) ? stringSize(collection) : collection.length;
30739 }
30740 var tag = getTag(collection);
30741 if (tag == mapTag || tag == setTag) {
30742 return collection.size;
30743 }
30744 return baseKeys(collection).length;
30745 }
30746
30747 /**
30748 * Checks if `predicate` returns truthy for **any** element of `collection`.
30749 * Iteration is stopped once `predicate` returns truthy. The predicate is
30750 * invoked with three arguments: (value, index|key, collection).
30751 *
30752 * @static
30753 * @memberOf _
30754 * @since 0.1.0
30755 * @category Collection
30756 * @param {Array|Object} collection The collection to iterate over.
30757 * @param {Function} [predicate=_.identity] The function invoked per iteration.
30758 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
30759 * @returns {boolean} Returns `true` if any element passes the predicate check,
30760 * else `false`.
30761 * @example
30762 *
30763 * _.some([null, 0, 'yes', false], Boolean);
30764 * // => true
30765 *
30766 * var users = [
30767 * { 'user': 'barney', 'active': true },
30768 * { 'user': 'fred', 'active': false }
30769 * ];
30770 *
30771 * // The `_.matches` iteratee shorthand.
30772 * _.some(users, { 'user': 'barney', 'active': false });
30773 * // => false
30774 *
30775 * // The `_.matchesProperty` iteratee shorthand.
30776 * _.some(users, ['active', false]);
30777 * // => true
30778 *
30779 * // The `_.property` iteratee shorthand.
30780 * _.some(users, 'active');
30781 * // => true
30782 */
30783 function some(collection, predicate, guard) {
30784 var func = isArray(collection) ? arraySome : baseSome;
30785 if (guard && isIterateeCall(collection, predicate, guard)) {
30786 predicate = undefined$1;
30787 }
30788 return func(collection, getIteratee(predicate, 3));
30789 }
30790
30791 /**
30792 * Creates an array of elements, sorted in ascending order by the results of
30793 * running each element in a collection thru each iteratee. This method
30794 * performs a stable sort, that is, it preserves the original sort order of
30795 * equal elements. The iteratees are invoked with one argument: (value).
30796 *
30797 * @static
30798 * @memberOf _
30799 * @since 0.1.0
30800 * @category Collection
30801 * @param {Array|Object} collection The collection to iterate over.
30802 * @param {...(Function|Function[])} [iteratees=[_.identity]]
30803 * The iteratees to sort by.
30804 * @returns {Array} Returns the new sorted array.
30805 * @example
30806 *
30807 * var users = [
30808 * { 'user': 'fred', 'age': 48 },
30809 * { 'user': 'barney', 'age': 36 },
30810 * { 'user': 'fred', 'age': 40 },
30811 * { 'user': 'barney', 'age': 34 }
30812 * ];
30813 *
30814 * _.sortBy(users, [function(o) { return o.user; }]);
30815 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
30816 *
30817 * _.sortBy(users, ['user', 'age']);
30818 * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
30819 */
30820 var sortBy = baseRest(function(collection, iteratees) {
30821 if (collection == null) {
30822 return [];
30823 }
30824 var length = iteratees.length;
30825 if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
30826 iteratees = [];
30827 } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
30828 iteratees = [iteratees[0]];
30829 }
30830 return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
30831 });
30832
30833 /*------------------------------------------------------------------------*/
30834
30835 /**
30836 * Gets the timestamp of the number of milliseconds that have elapsed since
30837 * the Unix epoch (1 January 1970 00:00:00 UTC).
30838 *
30839 * @static
30840 * @memberOf _
30841 * @since 2.4.0
30842 * @category Date
30843 * @returns {number} Returns the timestamp.
30844 * @example
30845 *
30846 * _.defer(function(stamp) {
30847 * console.log(_.now() - stamp);
30848 * }, _.now());
30849 * // => Logs the number of milliseconds it took for the deferred invocation.
30850 */
30851 var now = ctxNow || function() {
30852 return root.Date.now();
30853 };
30854
30855 /*------------------------------------------------------------------------*/
30856
30857 /**
30858 * The opposite of `_.before`; this method creates a function that invokes
30859 * `func` once it's called `n` or more times.
30860 *
30861 * @static
30862 * @memberOf _
30863 * @since 0.1.0
30864 * @category Function
30865 * @param {number} n The number of calls before `func` is invoked.
30866 * @param {Function} func The function to restrict.
30867 * @returns {Function} Returns the new restricted function.
30868 * @example
30869 *
30870 * var saves = ['profile', 'settings'];
30871 *
30872 * var done = _.after(saves.length, function() {
30873 * console.log('done saving!');
30874 * });
30875 *
30876 * _.forEach(saves, function(type) {
30877 * asyncSave({ 'type': type, 'complete': done });
30878 * });
30879 * // => Logs 'done saving!' after the two async saves have completed.
30880 */
30881 function after(n, func) {
30882 if (typeof func != 'function') {
30883 throw new Error(FUNC_ERROR_TEXT);
30884 }
30885 n = toInteger(n);
30886 return function() {
30887 if (--n < 1) {
30888 return func.apply(this, arguments);
30889 }
30890 };
30891 }
30892
30893 /**
30894 * Creates a function that invokes `func`, with up to `n` arguments,
30895 * ignoring any additional arguments.
30896 *
30897 * @static
30898 * @memberOf _
30899 * @since 3.0.0
30900 * @category Function
30901 * @param {Function} func The function to cap arguments for.
30902 * @param {number} [n=func.length] The arity cap.
30903 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
30904 * @returns {Function} Returns the new capped function.
30905 * @example
30906 *
30907 * _.map(['6', '8', '10'], _.ary(parseInt, 1));
30908 * // => [6, 8, 10]
30909 */
30910 function ary(func, n, guard) {
30911 n = guard ? undefined$1 : n;
30912 n = (func && n == null) ? func.length : n;
30913 return createWrap(func, WRAP_ARY_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, n);
30914 }
30915
30916 /**
30917 * Creates a function that invokes `func`, with the `this` binding and arguments
30918 * of the created function, while it's called less than `n` times. Subsequent
30919 * calls to the created function return the result of the last `func` invocation.
30920 *
30921 * @static
30922 * @memberOf _
30923 * @since 3.0.0
30924 * @category Function
30925 * @param {number} n The number of calls at which `func` is no longer invoked.
30926 * @param {Function} func The function to restrict.
30927 * @returns {Function} Returns the new restricted function.
30928 * @example
30929 *
30930 * jQuery(element).on('click', _.before(5, addContactToList));
30931 * // => Allows adding up to 4 contacts to the list.
30932 */
30933 function before(n, func) {
30934 var result;
30935 if (typeof func != 'function') {
30936 throw new Error(FUNC_ERROR_TEXT);
30937 }
30938 n = toInteger(n);
30939 return function() {
30940 if (--n > 0) {
30941 result = func.apply(this, arguments);
30942 }
30943 if (n <= 1) {
30944 func = undefined$1;
30945 }
30946 return result;
30947 };
30948 }
30949
30950 /**
30951 * Creates a function that invokes `func` with the `this` binding of `thisArg`
30952 * and `partials` prepended to the arguments it receives.
30953 *
30954 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
30955 * may be used as a placeholder for partially applied arguments.
30956 *
30957 * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
30958 * property of bound functions.
30959 *
30960 * @static
30961 * @memberOf _
30962 * @since 0.1.0
30963 * @category Function
30964 * @param {Function} func The function to bind.
30965 * @param {*} thisArg The `this` binding of `func`.
30966 * @param {...*} [partials] The arguments to be partially applied.
30967 * @returns {Function} Returns the new bound function.
30968 * @example
30969 *
30970 * function greet(greeting, punctuation) {
30971 * return greeting + ' ' + this.user + punctuation;
30972 * }
30973 *
30974 * var object = { 'user': 'fred' };
30975 *
30976 * var bound = _.bind(greet, object, 'hi');
30977 * bound('!');
30978 * // => 'hi fred!'
30979 *
30980 * // Bound with placeholders.
30981 * var bound = _.bind(greet, object, _, '!');
30982 * bound('hi');
30983 * // => 'hi fred!'
30984 */
30985 var bind = baseRest(function(func, thisArg, partials) {
30986 var bitmask = WRAP_BIND_FLAG;
30987 if (partials.length) {
30988 var holders = replaceHolders(partials, getHolder(bind));
30989 bitmask |= WRAP_PARTIAL_FLAG;
30990 }
30991 return createWrap(func, bitmask, thisArg, partials, holders);
30992 });
30993
30994 /**
30995 * Creates a function that invokes the method at `object[key]` with `partials`
30996 * prepended to the arguments it receives.
30997 *
30998 * This method differs from `_.bind` by allowing bound functions to reference
30999 * methods that may be redefined or don't yet exist. See
31000 * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
31001 * for more details.
31002 *
31003 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
31004 * builds, may be used as a placeholder for partially applied arguments.
31005 *
31006 * @static
31007 * @memberOf _
31008 * @since 0.10.0
31009 * @category Function
31010 * @param {Object} object The object to invoke the method on.
31011 * @param {string} key The key of the method.
31012 * @param {...*} [partials] The arguments to be partially applied.
31013 * @returns {Function} Returns the new bound function.
31014 * @example
31015 *
31016 * var object = {
31017 * 'user': 'fred',
31018 * 'greet': function(greeting, punctuation) {
31019 * return greeting + ' ' + this.user + punctuation;
31020 * }
31021 * };
31022 *
31023 * var bound = _.bindKey(object, 'greet', 'hi');
31024 * bound('!');
31025 * // => 'hi fred!'
31026 *
31027 * object.greet = function(greeting, punctuation) {
31028 * return greeting + 'ya ' + this.user + punctuation;
31029 * };
31030 *
31031 * bound('!');
31032 * // => 'hiya fred!'
31033 *
31034 * // Bound with placeholders.
31035 * var bound = _.bindKey(object, 'greet', _, '!');
31036 * bound('hi');
31037 * // => 'hiya fred!'
31038 */
31039 var bindKey = baseRest(function(object, key, partials) {
31040 var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
31041 if (partials.length) {
31042 var holders = replaceHolders(partials, getHolder(bindKey));
31043 bitmask |= WRAP_PARTIAL_FLAG;
31044 }
31045 return createWrap(key, bitmask, object, partials, holders);
31046 });
31047
31048 /**
31049 * Creates a function that accepts arguments of `func` and either invokes
31050 * `func` returning its result, if at least `arity` number of arguments have
31051 * been provided, or returns a function that accepts the remaining `func`
31052 * arguments, and so on. The arity of `func` may be specified if `func.length`
31053 * is not sufficient.
31054 *
31055 * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
31056 * may be used as a placeholder for provided arguments.
31057 *
31058 * **Note:** This method doesn't set the "length" property of curried functions.
31059 *
31060 * @static
31061 * @memberOf _
31062 * @since 2.0.0
31063 * @category Function
31064 * @param {Function} func The function to curry.
31065 * @param {number} [arity=func.length] The arity of `func`.
31066 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
31067 * @returns {Function} Returns the new curried function.
31068 * @example
31069 *
31070 * var abc = function(a, b, c) {
31071 * return [a, b, c];
31072 * };
31073 *
31074 * var curried = _.curry(abc);
31075 *
31076 * curried(1)(2)(3);
31077 * // => [1, 2, 3]
31078 *
31079 * curried(1, 2)(3);
31080 * // => [1, 2, 3]
31081 *
31082 * curried(1, 2, 3);
31083 * // => [1, 2, 3]
31084 *
31085 * // Curried with placeholders.
31086 * curried(1)(_, 3)(2);
31087 * // => [1, 2, 3]
31088 */
31089 function curry(func, arity, guard) {
31090 arity = guard ? undefined$1 : arity;
31091 var result = createWrap(func, WRAP_CURRY_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, undefined$1, arity);
31092 result.placeholder = curry.placeholder;
31093 return result;
31094 }
31095
31096 /**
31097 * This method is like `_.curry` except that arguments are applied to `func`
31098 * in the manner of `_.partialRight` instead of `_.partial`.
31099 *
31100 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
31101 * builds, may be used as a placeholder for provided arguments.
31102 *
31103 * **Note:** This method doesn't set the "length" property of curried functions.
31104 *
31105 * @static
31106 * @memberOf _
31107 * @since 3.0.0
31108 * @category Function
31109 * @param {Function} func The function to curry.
31110 * @param {number} [arity=func.length] The arity of `func`.
31111 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
31112 * @returns {Function} Returns the new curried function.
31113 * @example
31114 *
31115 * var abc = function(a, b, c) {
31116 * return [a, b, c];
31117 * };
31118 *
31119 * var curried = _.curryRight(abc);
31120 *
31121 * curried(3)(2)(1);
31122 * // => [1, 2, 3]
31123 *
31124 * curried(2, 3)(1);
31125 * // => [1, 2, 3]
31126 *
31127 * curried(1, 2, 3);
31128 * // => [1, 2, 3]
31129 *
31130 * // Curried with placeholders.
31131 * curried(3)(1, _)(2);
31132 * // => [1, 2, 3]
31133 */
31134 function curryRight(func, arity, guard) {
31135 arity = guard ? undefined$1 : arity;
31136 var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined$1, undefined$1, undefined$1, undefined$1, undefined$1, arity);
31137 result.placeholder = curryRight.placeholder;
31138 return result;
31139 }
31140
31141 /**
31142 * Creates a debounced function that delays invoking `func` until after `wait`
31143 * milliseconds have elapsed since the last time the debounced function was
31144 * invoked. The debounced function comes with a `cancel` method to cancel
31145 * delayed `func` invocations and a `flush` method to immediately invoke them.
31146 * Provide `options` to indicate whether `func` should be invoked on the
31147 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
31148 * with the last arguments provided to the debounced function. Subsequent
31149 * calls to the debounced function return the result of the last `func`
31150 * invocation.
31151 *
31152 * **Note:** If `leading` and `trailing` options are `true`, `func` is
31153 * invoked on the trailing edge of the timeout only if the debounced function
31154 * is invoked more than once during the `wait` timeout.
31155 *
31156 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
31157 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
31158 *
31159 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
31160 * for details over the differences between `_.debounce` and `_.throttle`.
31161 *
31162 * @static
31163 * @memberOf _
31164 * @since 0.1.0
31165 * @category Function
31166 * @param {Function} func The function to debounce.
31167 * @param {number} [wait=0] The number of milliseconds to delay.
31168 * @param {Object} [options={}] The options object.
31169 * @param {boolean} [options.leading=false]
31170 * Specify invoking on the leading edge of the timeout.
31171 * @param {number} [options.maxWait]
31172 * The maximum time `func` is allowed to be delayed before it's invoked.
31173 * @param {boolean} [options.trailing=true]
31174 * Specify invoking on the trailing edge of the timeout.
31175 * @returns {Function} Returns the new debounced function.
31176 * @example
31177 *
31178 * // Avoid costly calculations while the window size is in flux.
31179 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
31180 *
31181 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
31182 * jQuery(element).on('click', _.debounce(sendMail, 300, {
31183 * 'leading': true,
31184 * 'trailing': false
31185 * }));
31186 *
31187 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
31188 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
31189 * var source = new EventSource('/stream');
31190 * jQuery(source).on('message', debounced);
31191 *
31192 * // Cancel the trailing debounced invocation.
31193 * jQuery(window).on('popstate', debounced.cancel);
31194 */
31195 function debounce(func, wait, options) {
31196 var lastArgs,
31197 lastThis,
31198 maxWait,
31199 result,
31200 timerId,
31201 lastCallTime,
31202 lastInvokeTime = 0,
31203 leading = false,
31204 maxing = false,
31205 trailing = true;
31206
31207 if (typeof func != 'function') {
31208 throw new Error(FUNC_ERROR_TEXT);
31209 }
31210 wait = toNumber(wait) || 0;
31211 if (isObject(options)) {
31212 leading = !!options.leading;
31213 maxing = 'maxWait' in options;
31214 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
31215 trailing = 'trailing' in options ? !!options.trailing : trailing;
31216 }
31217
31218 function invokeFunc(time) {
31219 var args = lastArgs,
31220 thisArg = lastThis;
31221
31222 lastArgs = lastThis = undefined$1;
31223 lastInvokeTime = time;
31224 result = func.apply(thisArg, args);
31225 return result;
31226 }
31227
31228 function leadingEdge(time) {
31229 // Reset any `maxWait` timer.
31230 lastInvokeTime = time;
31231 // Start the timer for the trailing edge.
31232 timerId = setTimeout(timerExpired, wait);
31233 // Invoke the leading edge.
31234 return leading ? invokeFunc(time) : result;
31235 }
31236
31237 function remainingWait(time) {
31238 var timeSinceLastCall = time - lastCallTime,
31239 timeSinceLastInvoke = time - lastInvokeTime,
31240 timeWaiting = wait - timeSinceLastCall;
31241
31242 return maxing
31243 ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
31244 : timeWaiting;
31245 }
31246
31247 function shouldInvoke(time) {
31248 var timeSinceLastCall = time - lastCallTime,
31249 timeSinceLastInvoke = time - lastInvokeTime;
31250
31251 // Either this is the first call, activity has stopped and we're at the
31252 // trailing edge, the system time has gone backwards and we're treating
31253 // it as the trailing edge, or we've hit the `maxWait` limit.
31254 return (lastCallTime === undefined$1 || (timeSinceLastCall >= wait) ||
31255 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
31256 }
31257
31258 function timerExpired() {
31259 var time = now();
31260 if (shouldInvoke(time)) {
31261 return trailingEdge(time);
31262 }
31263 // Restart the timer.
31264 timerId = setTimeout(timerExpired, remainingWait(time));
31265 }
31266
31267 function trailingEdge(time) {
31268 timerId = undefined$1;
31269
31270 // Only invoke if we have `lastArgs` which means `func` has been
31271 // debounced at least once.
31272 if (trailing && lastArgs) {
31273 return invokeFunc(time);
31274 }
31275 lastArgs = lastThis = undefined$1;
31276 return result;
31277 }
31278
31279 function cancel() {
31280 if (timerId !== undefined$1) {
31281 clearTimeout(timerId);
31282 }
31283 lastInvokeTime = 0;
31284 lastArgs = lastCallTime = lastThis = timerId = undefined$1;
31285 }
31286
31287 function flush() {
31288 return timerId === undefined$1 ? result : trailingEdge(now());
31289 }
31290
31291 function debounced() {
31292 var time = now(),
31293 isInvoking = shouldInvoke(time);
31294
31295 lastArgs = arguments;
31296 lastThis = this;
31297 lastCallTime = time;
31298
31299 if (isInvoking) {
31300 if (timerId === undefined$1) {
31301 return leadingEdge(lastCallTime);
31302 }
31303 if (maxing) {
31304 // Handle invocations in a tight loop.
31305 clearTimeout(timerId);
31306 timerId = setTimeout(timerExpired, wait);
31307 return invokeFunc(lastCallTime);
31308 }
31309 }
31310 if (timerId === undefined$1) {
31311 timerId = setTimeout(timerExpired, wait);
31312 }
31313 return result;
31314 }
31315 debounced.cancel = cancel;
31316 debounced.flush = flush;
31317 return debounced;
31318 }
31319
31320 /**
31321 * Defers invoking the `func` until the current call stack has cleared. Any
31322 * additional arguments are provided to `func` when it's invoked.
31323 *
31324 * @static
31325 * @memberOf _
31326 * @since 0.1.0
31327 * @category Function
31328 * @param {Function} func The function to defer.
31329 * @param {...*} [args] The arguments to invoke `func` with.
31330 * @returns {number} Returns the timer id.
31331 * @example
31332 *
31333 * _.defer(function(text) {
31334 * console.log(text);
31335 * }, 'deferred');
31336 * // => Logs 'deferred' after one millisecond.
31337 */
31338 var defer = baseRest(function(func, args) {
31339 return baseDelay(func, 1, args);
31340 });
31341
31342 /**
31343 * Invokes `func` after `wait` milliseconds. Any additional arguments are
31344 * provided to `func` when it's invoked.
31345 *
31346 * @static
31347 * @memberOf _
31348 * @since 0.1.0
31349 * @category Function
31350 * @param {Function} func The function to delay.
31351 * @param {number} wait The number of milliseconds to delay invocation.
31352 * @param {...*} [args] The arguments to invoke `func` with.
31353 * @returns {number} Returns the timer id.
31354 * @example
31355 *
31356 * _.delay(function(text) {
31357 * console.log(text);
31358 * }, 1000, 'later');
31359 * // => Logs 'later' after one second.
31360 */
31361 var delay = baseRest(function(func, wait, args) {
31362 return baseDelay(func, toNumber(wait) || 0, args);
31363 });
31364
31365 /**
31366 * Creates a function that invokes `func` with arguments reversed.
31367 *
31368 * @static
31369 * @memberOf _
31370 * @since 4.0.0
31371 * @category Function
31372 * @param {Function} func The function to flip arguments for.
31373 * @returns {Function} Returns the new flipped function.
31374 * @example
31375 *
31376 * var flipped = _.flip(function() {
31377 * return _.toArray(arguments);
31378 * });
31379 *
31380 * flipped('a', 'b', 'c', 'd');
31381 * // => ['d', 'c', 'b', 'a']
31382 */
31383 function flip(func) {
31384 return createWrap(func, WRAP_FLIP_FLAG);
31385 }
31386
31387 /**
31388 * Creates a function that memoizes the result of `func`. If `resolver` is
31389 * provided, it determines the cache key for storing the result based on the
31390 * arguments provided to the memoized function. By default, the first argument
31391 * provided to the memoized function is used as the map cache key. The `func`
31392 * is invoked with the `this` binding of the memoized function.
31393 *
31394 * **Note:** The cache is exposed as the `cache` property on the memoized
31395 * function. Its creation may be customized by replacing the `_.memoize.Cache`
31396 * constructor with one whose instances implement the
31397 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
31398 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
31399 *
31400 * @static
31401 * @memberOf _
31402 * @since 0.1.0
31403 * @category Function
31404 * @param {Function} func The function to have its output memoized.
31405 * @param {Function} [resolver] The function to resolve the cache key.
31406 * @returns {Function} Returns the new memoized function.
31407 * @example
31408 *
31409 * var object = { 'a': 1, 'b': 2 };
31410 * var other = { 'c': 3, 'd': 4 };
31411 *
31412 * var values = _.memoize(_.values);
31413 * values(object);
31414 * // => [1, 2]
31415 *
31416 * values(other);
31417 * // => [3, 4]
31418 *
31419 * object.a = 2;
31420 * values(object);
31421 * // => [1, 2]
31422 *
31423 * // Modify the result cache.
31424 * values.cache.set(object, ['a', 'b']);
31425 * values(object);
31426 * // => ['a', 'b']
31427 *
31428 * // Replace `_.memoize.Cache`.
31429 * _.memoize.Cache = WeakMap;
31430 */
31431 function memoize(func, resolver) {
31432 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
31433 throw new Error(FUNC_ERROR_TEXT);
31434 }
31435 var memoized = function() {
31436 var args = arguments,
31437 key = resolver ? resolver.apply(this, args) : args[0],
31438 cache = memoized.cache;
31439
31440 if (cache.has(key)) {
31441 return cache.get(key);
31442 }
31443 var result = func.apply(this, args);
31444 memoized.cache = cache.set(key, result) || cache;
31445 return result;
31446 };
31447 memoized.cache = new (memoize.Cache || MapCache);
31448 return memoized;
31449 }
31450
31451 // Expose `MapCache`.
31452 memoize.Cache = MapCache;
31453
31454 /**
31455 * Creates a function that negates the result of the predicate `func`. The
31456 * `func` predicate is invoked with the `this` binding and arguments of the
31457 * created function.
31458 *
31459 * @static
31460 * @memberOf _
31461 * @since 3.0.0
31462 * @category Function
31463 * @param {Function} predicate The predicate to negate.
31464 * @returns {Function} Returns the new negated function.
31465 * @example
31466 *
31467 * function isEven(n) {
31468 * return n % 2 == 0;
31469 * }
31470 *
31471 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
31472 * // => [1, 3, 5]
31473 */
31474 function negate(predicate) {
31475 if (typeof predicate != 'function') {
31476 throw new Error(FUNC_ERROR_TEXT);
31477 }
31478 return function() {
31479 var args = arguments;
31480 switch (args.length) {
31481 case 0: return !predicate.call(this);
31482 case 1: return !predicate.call(this, args[0]);
31483 case 2: return !predicate.call(this, args[0], args[1]);
31484 case 3: return !predicate.call(this, args[0], args[1], args[2]);
31485 }
31486 return !predicate.apply(this, args);
31487 };
31488 }
31489
31490 /**
31491 * Creates a function that is restricted to invoking `func` once. Repeat calls
31492 * to the function return the value of the first invocation. The `func` is
31493 * invoked with the `this` binding and arguments of the created function.
31494 *
31495 * @static
31496 * @memberOf _
31497 * @since 0.1.0
31498 * @category Function
31499 * @param {Function} func The function to restrict.
31500 * @returns {Function} Returns the new restricted function.
31501 * @example
31502 *
31503 * var initialize = _.once(createApplication);
31504 * initialize();
31505 * initialize();
31506 * // => `createApplication` is invoked once
31507 */
31508 function once(func) {
31509 return before(2, func);
31510 }
31511
31512 /**
31513 * Creates a function that invokes `func` with its arguments transformed.
31514 *
31515 * @static
31516 * @since 4.0.0
31517 * @memberOf _
31518 * @category Function
31519 * @param {Function} func The function to wrap.
31520 * @param {...(Function|Function[])} [transforms=[_.identity]]
31521 * The argument transforms.
31522 * @returns {Function} Returns the new function.
31523 * @example
31524 *
31525 * function doubled(n) {
31526 * return n * 2;
31527 * }
31528 *
31529 * function square(n) {
31530 * return n * n;
31531 * }
31532 *
31533 * var func = _.overArgs(function(x, y) {
31534 * return [x, y];
31535 * }, [square, doubled]);
31536 *
31537 * func(9, 3);
31538 * // => [81, 6]
31539 *
31540 * func(10, 5);
31541 * // => [100, 10]
31542 */
31543 var overArgs = castRest(function(func, transforms) {
31544 transforms = (transforms.length == 1 && isArray(transforms[0]))
31545 ? arrayMap(transforms[0], baseUnary(getIteratee()))
31546 : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
31547
31548 var funcsLength = transforms.length;
31549 return baseRest(function(args) {
31550 var index = -1,
31551 length = nativeMin(args.length, funcsLength);
31552
31553 while (++index < length) {
31554 args[index] = transforms[index].call(this, args[index]);
31555 }
31556 return apply(func, this, args);
31557 });
31558 });
31559
31560 /**
31561 * Creates a function that invokes `func` with `partials` prepended to the
31562 * arguments it receives. This method is like `_.bind` except it does **not**
31563 * alter the `this` binding.
31564 *
31565 * The `_.partial.placeholder` value, which defaults to `_` in monolithic
31566 * builds, may be used as a placeholder for partially applied arguments.
31567 *
31568 * **Note:** This method doesn't set the "length" property of partially
31569 * applied functions.
31570 *
31571 * @static
31572 * @memberOf _
31573 * @since 0.2.0
31574 * @category Function
31575 * @param {Function} func The function to partially apply arguments to.
31576 * @param {...*} [partials] The arguments to be partially applied.
31577 * @returns {Function} Returns the new partially applied function.
31578 * @example
31579 *
31580 * function greet(greeting, name) {
31581 * return greeting + ' ' + name;
31582 * }
31583 *
31584 * var sayHelloTo = _.partial(greet, 'hello');
31585 * sayHelloTo('fred');
31586 * // => 'hello fred'
31587 *
31588 * // Partially applied with placeholders.
31589 * var greetFred = _.partial(greet, _, 'fred');
31590 * greetFred('hi');
31591 * // => 'hi fred'
31592 */
31593 var partial = baseRest(function(func, partials) {
31594 var holders = replaceHolders(partials, getHolder(partial));
31595 return createWrap(func, WRAP_PARTIAL_FLAG, undefined$1, partials, holders);
31596 });
31597
31598 /**
31599 * This method is like `_.partial` except that partially applied arguments
31600 * are appended to the arguments it receives.
31601 *
31602 * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
31603 * builds, may be used as a placeholder for partially applied arguments.
31604 *
31605 * **Note:** This method doesn't set the "length" property of partially
31606 * applied functions.
31607 *
31608 * @static
31609 * @memberOf _
31610 * @since 1.0.0
31611 * @category Function
31612 * @param {Function} func The function to partially apply arguments to.
31613 * @param {...*} [partials] The arguments to be partially applied.
31614 * @returns {Function} Returns the new partially applied function.
31615 * @example
31616 *
31617 * function greet(greeting, name) {
31618 * return greeting + ' ' + name;
31619 * }
31620 *
31621 * var greetFred = _.partialRight(greet, 'fred');
31622 * greetFred('hi');
31623 * // => 'hi fred'
31624 *
31625 * // Partially applied with placeholders.
31626 * var sayHelloTo = _.partialRight(greet, 'hello', _);
31627 * sayHelloTo('fred');
31628 * // => 'hello fred'
31629 */
31630 var partialRight = baseRest(function(func, partials) {
31631 var holders = replaceHolders(partials, getHolder(partialRight));
31632 return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined$1, partials, holders);
31633 });
31634
31635 /**
31636 * Creates a function that invokes `func` with arguments arranged according
31637 * to the specified `indexes` where the argument value at the first index is
31638 * provided as the first argument, the argument value at the second index is
31639 * provided as the second argument, and so on.
31640 *
31641 * @static
31642 * @memberOf _
31643 * @since 3.0.0
31644 * @category Function
31645 * @param {Function} func The function to rearrange arguments for.
31646 * @param {...(number|number[])} indexes The arranged argument indexes.
31647 * @returns {Function} Returns the new function.
31648 * @example
31649 *
31650 * var rearged = _.rearg(function(a, b, c) {
31651 * return [a, b, c];
31652 * }, [2, 0, 1]);
31653 *
31654 * rearged('b', 'c', 'a')
31655 * // => ['a', 'b', 'c']
31656 */
31657 var rearg = flatRest(function(func, indexes) {
31658 return createWrap(func, WRAP_REARG_FLAG, undefined$1, undefined$1, undefined$1, indexes);
31659 });
31660
31661 /**
31662 * Creates a function that invokes `func` with the `this` binding of the
31663 * created function and arguments from `start` and beyond provided as
31664 * an array.
31665 *
31666 * **Note:** This method is based on the
31667 * [rest parameter](https://mdn.io/rest_parameters).
31668 *
31669 * @static
31670 * @memberOf _
31671 * @since 4.0.0
31672 * @category Function
31673 * @param {Function} func The function to apply a rest parameter to.
31674 * @param {number} [start=func.length-1] The start position of the rest parameter.
31675 * @returns {Function} Returns the new function.
31676 * @example
31677 *
31678 * var say = _.rest(function(what, names) {
31679 * return what + ' ' + _.initial(names).join(', ') +
31680 * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
31681 * });
31682 *
31683 * say('hello', 'fred', 'barney', 'pebbles');
31684 * // => 'hello fred, barney, & pebbles'
31685 */
31686 function rest(func, start) {
31687 if (typeof func != 'function') {
31688 throw new Error(FUNC_ERROR_TEXT);
31689 }
31690 start = start === undefined$1 ? start : toInteger(start);
31691 return baseRest(func, start);
31692 }
31693
31694 /**
31695 * Creates a function that invokes `func` with the `this` binding of the
31696 * create function and an array of arguments much like
31697 * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
31698 *
31699 * **Note:** This method is based on the
31700 * [spread operator](https://mdn.io/spread_operator).
31701 *
31702 * @static
31703 * @memberOf _
31704 * @since 3.2.0
31705 * @category Function
31706 * @param {Function} func The function to spread arguments over.
31707 * @param {number} [start=0] The start position of the spread.
31708 * @returns {Function} Returns the new function.
31709 * @example
31710 *
31711 * var say = _.spread(function(who, what) {
31712 * return who + ' says ' + what;
31713 * });
31714 *
31715 * say(['fred', 'hello']);
31716 * // => 'fred says hello'
31717 *
31718 * var numbers = Promise.all([
31719 * Promise.resolve(40),
31720 * Promise.resolve(36)
31721 * ]);
31722 *
31723 * numbers.then(_.spread(function(x, y) {
31724 * return x + y;
31725 * }));
31726 * // => a Promise of 76
31727 */
31728 function spread(func, start) {
31729 if (typeof func != 'function') {
31730 throw new Error(FUNC_ERROR_TEXT);
31731 }
31732 start = start == null ? 0 : nativeMax(toInteger(start), 0);
31733 return baseRest(function(args) {
31734 var array = args[start],
31735 otherArgs = castSlice(args, 0, start);
31736
31737 if (array) {
31738 arrayPush(otherArgs, array);
31739 }
31740 return apply(func, this, otherArgs);
31741 });
31742 }
31743
31744 /**
31745 * Creates a throttled function that only invokes `func` at most once per
31746 * every `wait` milliseconds. The throttled function comes with a `cancel`
31747 * method to cancel delayed `func` invocations and a `flush` method to
31748 * immediately invoke them. Provide `options` to indicate whether `func`
31749 * should be invoked on the leading and/or trailing edge of the `wait`
31750 * timeout. The `func` is invoked with the last arguments provided to the
31751 * throttled function. Subsequent calls to the throttled function return the
31752 * result of the last `func` invocation.
31753 *
31754 * **Note:** If `leading` and `trailing` options are `true`, `func` is
31755 * invoked on the trailing edge of the timeout only if the throttled function
31756 * is invoked more than once during the `wait` timeout.
31757 *
31758 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
31759 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
31760 *
31761 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
31762 * for details over the differences between `_.throttle` and `_.debounce`.
31763 *
31764 * @static
31765 * @memberOf _
31766 * @since 0.1.0
31767 * @category Function
31768 * @param {Function} func The function to throttle.
31769 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
31770 * @param {Object} [options={}] The options object.
31771 * @param {boolean} [options.leading=true]
31772 * Specify invoking on the leading edge of the timeout.
31773 * @param {boolean} [options.trailing=true]
31774 * Specify invoking on the trailing edge of the timeout.
31775 * @returns {Function} Returns the new throttled function.
31776 * @example
31777 *
31778 * // Avoid excessively updating the position while scrolling.
31779 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
31780 *
31781 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
31782 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
31783 * jQuery(element).on('click', throttled);
31784 *
31785 * // Cancel the trailing throttled invocation.
31786 * jQuery(window).on('popstate', throttled.cancel);
31787 */
31788 function throttle(func, wait, options) {
31789 var leading = true,
31790 trailing = true;
31791
31792 if (typeof func != 'function') {
31793 throw new Error(FUNC_ERROR_TEXT);
31794 }
31795 if (isObject(options)) {
31796 leading = 'leading' in options ? !!options.leading : leading;
31797 trailing = 'trailing' in options ? !!options.trailing : trailing;
31798 }
31799 return debounce(func, wait, {
31800 'leading': leading,
31801 'maxWait': wait,
31802 'trailing': trailing
31803 });
31804 }
31805
31806 /**
31807 * Creates a function that accepts up to one argument, ignoring any
31808 * additional arguments.
31809 *
31810 * @static
31811 * @memberOf _
31812 * @since 4.0.0
31813 * @category Function
31814 * @param {Function} func The function to cap arguments for.
31815 * @returns {Function} Returns the new capped function.
31816 * @example
31817 *
31818 * _.map(['6', '8', '10'], _.unary(parseInt));
31819 * // => [6, 8, 10]
31820 */
31821 function unary(func) {
31822 return ary(func, 1);
31823 }
31824
31825 /**
31826 * Creates a function that provides `value` to `wrapper` as its first
31827 * argument. Any additional arguments provided to the function are appended
31828 * to those provided to the `wrapper`. The wrapper is invoked with the `this`
31829 * binding of the created function.
31830 *
31831 * @static
31832 * @memberOf _
31833 * @since 0.1.0
31834 * @category Function
31835 * @param {*} value The value to wrap.
31836 * @param {Function} [wrapper=identity] The wrapper function.
31837 * @returns {Function} Returns the new function.
31838 * @example
31839 *
31840 * var p = _.wrap(_.escape, function(func, text) {
31841 * return '<p>' + func(text) + '</p>';
31842 * });
31843 *
31844 * p('fred, barney, & pebbles');
31845 * // => '<p>fred, barney, &amp; pebbles</p>'
31846 */
31847 function wrap(value, wrapper) {
31848 return partial(castFunction(wrapper), value);
31849 }
31850
31851 /*------------------------------------------------------------------------*/
31852
31853 /**
31854 * Casts `value` as an array if it's not one.
31855 *
31856 * @static
31857 * @memberOf _
31858 * @since 4.4.0
31859 * @category Lang
31860 * @param {*} value The value to inspect.
31861 * @returns {Array} Returns the cast array.
31862 * @example
31863 *
31864 * _.castArray(1);
31865 * // => [1]
31866 *
31867 * _.castArray({ 'a': 1 });
31868 * // => [{ 'a': 1 }]
31869 *
31870 * _.castArray('abc');
31871 * // => ['abc']
31872 *
31873 * _.castArray(null);
31874 * // => [null]
31875 *
31876 * _.castArray(undefined);
31877 * // => [undefined]
31878 *
31879 * _.castArray();
31880 * // => []
31881 *
31882 * var array = [1, 2, 3];
31883 * console.log(_.castArray(array) === array);
31884 * // => true
31885 */
31886 function castArray() {
31887 if (!arguments.length) {
31888 return [];
31889 }
31890 var value = arguments[0];
31891 return isArray(value) ? value : [value];
31892 }
31893
31894 /**
31895 * Creates a shallow clone of `value`.
31896 *
31897 * **Note:** This method is loosely based on the
31898 * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
31899 * and supports cloning arrays, array buffers, booleans, date objects, maps,
31900 * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
31901 * arrays. The own enumerable properties of `arguments` objects are cloned
31902 * as plain objects. An empty object is returned for uncloneable values such
31903 * as error objects, functions, DOM nodes, and WeakMaps.
31904 *
31905 * @static
31906 * @memberOf _
31907 * @since 0.1.0
31908 * @category Lang
31909 * @param {*} value The value to clone.
31910 * @returns {*} Returns the cloned value.
31911 * @see _.cloneDeep
31912 * @example
31913 *
31914 * var objects = [{ 'a': 1 }, { 'b': 2 }];
31915 *
31916 * var shallow = _.clone(objects);
31917 * console.log(shallow[0] === objects[0]);
31918 * // => true
31919 */
31920 function clone(value) {
31921 return baseClone(value, CLONE_SYMBOLS_FLAG);
31922 }
31923
31924 /**
31925 * This method is like `_.clone` except that it accepts `customizer` which
31926 * is invoked to produce the cloned value. If `customizer` returns `undefined`,
31927 * cloning is handled by the method instead. The `customizer` is invoked with
31928 * up to four arguments; (value [, index|key, object, stack]).
31929 *
31930 * @static
31931 * @memberOf _
31932 * @since 4.0.0
31933 * @category Lang
31934 * @param {*} value The value to clone.
31935 * @param {Function} [customizer] The function to customize cloning.
31936 * @returns {*} Returns the cloned value.
31937 * @see _.cloneDeepWith
31938 * @example
31939 *
31940 * function customizer(value) {
31941 * if (_.isElement(value)) {
31942 * return value.cloneNode(false);
31943 * }
31944 * }
31945 *
31946 * var el = _.cloneWith(document.body, customizer);
31947 *
31948 * console.log(el === document.body);
31949 * // => false
31950 * console.log(el.nodeName);
31951 * // => 'BODY'
31952 * console.log(el.childNodes.length);
31953 * // => 0
31954 */
31955 function cloneWith(value, customizer) {
31956 customizer = typeof customizer == 'function' ? customizer : undefined$1;
31957 return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
31958 }
31959
31960 /**
31961 * This method is like `_.clone` except that it recursively clones `value`.
31962 *
31963 * @static
31964 * @memberOf _
31965 * @since 1.0.0
31966 * @category Lang
31967 * @param {*} value The value to recursively clone.
31968 * @returns {*} Returns the deep cloned value.
31969 * @see _.clone
31970 * @example
31971 *
31972 * var objects = [{ 'a': 1 }, { 'b': 2 }];
31973 *
31974 * var deep = _.cloneDeep(objects);
31975 * console.log(deep[0] === objects[0]);
31976 * // => false
31977 */
31978 function cloneDeep(value) {
31979 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
31980 }
31981
31982 /**
31983 * This method is like `_.cloneWith` except that it recursively clones `value`.
31984 *
31985 * @static
31986 * @memberOf _
31987 * @since 4.0.0
31988 * @category Lang
31989 * @param {*} value The value to recursively clone.
31990 * @param {Function} [customizer] The function to customize cloning.
31991 * @returns {*} Returns the deep cloned value.
31992 * @see _.cloneWith
31993 * @example
31994 *
31995 * function customizer(value) {
31996 * if (_.isElement(value)) {
31997 * return value.cloneNode(true);
31998 * }
31999 * }
32000 *
32001 * var el = _.cloneDeepWith(document.body, customizer);
32002 *
32003 * console.log(el === document.body);
32004 * // => false
32005 * console.log(el.nodeName);
32006 * // => 'BODY'
32007 * console.log(el.childNodes.length);
32008 * // => 20
32009 */
32010 function cloneDeepWith(value, customizer) {
32011 customizer = typeof customizer == 'function' ? customizer : undefined$1;
32012 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
32013 }
32014
32015 /**
32016 * Checks if `object` conforms to `source` by invoking the predicate
32017 * properties of `source` with the corresponding property values of `object`.
32018 *
32019 * **Note:** This method is equivalent to `_.conforms` when `source` is
32020 * partially applied.
32021 *
32022 * @static
32023 * @memberOf _
32024 * @since 4.14.0
32025 * @category Lang
32026 * @param {Object} object The object to inspect.
32027 * @param {Object} source The object of property predicates to conform to.
32028 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
32029 * @example
32030 *
32031 * var object = { 'a': 1, 'b': 2 };
32032 *
32033 * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
32034 * // => true
32035 *
32036 * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
32037 * // => false
32038 */
32039 function conformsTo(object, source) {
32040 return source == null || baseConformsTo(object, source, keys(source));
32041 }
32042
32043 /**
32044 * Performs a
32045 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
32046 * comparison between two values to determine if they are equivalent.
32047 *
32048 * @static
32049 * @memberOf _
32050 * @since 4.0.0
32051 * @category Lang
32052 * @param {*} value The value to compare.
32053 * @param {*} other The other value to compare.
32054 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
32055 * @example
32056 *
32057 * var object = { 'a': 1 };
32058 * var other = { 'a': 1 };
32059 *
32060 * _.eq(object, object);
32061 * // => true
32062 *
32063 * _.eq(object, other);
32064 * // => false
32065 *
32066 * _.eq('a', 'a');
32067 * // => true
32068 *
32069 * _.eq('a', Object('a'));
32070 * // => false
32071 *
32072 * _.eq(NaN, NaN);
32073 * // => true
32074 */
32075 function eq(value, other) {
32076 return value === other || (value !== value && other !== other);
32077 }
32078
32079 /**
32080 * Checks if `value` is greater than `other`.
32081 *
32082 * @static
32083 * @memberOf _
32084 * @since 3.9.0
32085 * @category Lang
32086 * @param {*} value The value to compare.
32087 * @param {*} other The other value to compare.
32088 * @returns {boolean} Returns `true` if `value` is greater than `other`,
32089 * else `false`.
32090 * @see _.lt
32091 * @example
32092 *
32093 * _.gt(3, 1);
32094 * // => true
32095 *
32096 * _.gt(3, 3);
32097 * // => false
32098 *
32099 * _.gt(1, 3);
32100 * // => false
32101 */
32102 var gt = createRelationalOperation(baseGt);
32103
32104 /**
32105 * Checks if `value` is greater than or equal to `other`.
32106 *
32107 * @static
32108 * @memberOf _
32109 * @since 3.9.0
32110 * @category Lang
32111 * @param {*} value The value to compare.
32112 * @param {*} other The other value to compare.
32113 * @returns {boolean} Returns `true` if `value` is greater than or equal to
32114 * `other`, else `false`.
32115 * @see _.lte
32116 * @example
32117 *
32118 * _.gte(3, 1);
32119 * // => true
32120 *
32121 * _.gte(3, 3);
32122 * // => true
32123 *
32124 * _.gte(1, 3);
32125 * // => false
32126 */
32127 var gte = createRelationalOperation(function(value, other) {
32128 return value >= other;
32129 });
32130
32131 /**
32132 * Checks if `value` is likely an `arguments` object.
32133 *
32134 * @static
32135 * @memberOf _
32136 * @since 0.1.0
32137 * @category Lang
32138 * @param {*} value The value to check.
32139 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
32140 * else `false`.
32141 * @example
32142 *
32143 * _.isArguments(function() { return arguments; }());
32144 * // => true
32145 *
32146 * _.isArguments([1, 2, 3]);
32147 * // => false
32148 */
32149 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
32150 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
32151 !propertyIsEnumerable.call(value, 'callee');
32152 };
32153
32154 /**
32155 * Checks if `value` is classified as an `Array` object.
32156 *
32157 * @static
32158 * @memberOf _
32159 * @since 0.1.0
32160 * @category Lang
32161 * @param {*} value The value to check.
32162 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
32163 * @example
32164 *
32165 * _.isArray([1, 2, 3]);
32166 * // => true
32167 *
32168 * _.isArray(document.body.children);
32169 * // => false
32170 *
32171 * _.isArray('abc');
32172 * // => false
32173 *
32174 * _.isArray(_.noop);
32175 * // => false
32176 */
32177 var isArray = Array.isArray;
32178
32179 /**
32180 * Checks if `value` is classified as an `ArrayBuffer` object.
32181 *
32182 * @static
32183 * @memberOf _
32184 * @since 4.3.0
32185 * @category Lang
32186 * @param {*} value The value to check.
32187 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
32188 * @example
32189 *
32190 * _.isArrayBuffer(new ArrayBuffer(2));
32191 * // => true
32192 *
32193 * _.isArrayBuffer(new Array(2));
32194 * // => false
32195 */
32196 var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
32197
32198 /**
32199 * Checks if `value` is array-like. A value is considered array-like if it's
32200 * not a function and has a `value.length` that's an integer greater than or
32201 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
32202 *
32203 * @static
32204 * @memberOf _
32205 * @since 4.0.0
32206 * @category Lang
32207 * @param {*} value The value to check.
32208 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
32209 * @example
32210 *
32211 * _.isArrayLike([1, 2, 3]);
32212 * // => true
32213 *
32214 * _.isArrayLike(document.body.children);
32215 * // => true
32216 *
32217 * _.isArrayLike('abc');
32218 * // => true
32219 *
32220 * _.isArrayLike(_.noop);
32221 * // => false
32222 */
32223 function isArrayLike(value) {
32224 return value != null && isLength(value.length) && !isFunction(value);
32225 }
32226
32227 /**
32228 * This method is like `_.isArrayLike` except that it also checks if `value`
32229 * is an object.
32230 *
32231 * @static
32232 * @memberOf _
32233 * @since 4.0.0
32234 * @category Lang
32235 * @param {*} value The value to check.
32236 * @returns {boolean} Returns `true` if `value` is an array-like object,
32237 * else `false`.
32238 * @example
32239 *
32240 * _.isArrayLikeObject([1, 2, 3]);
32241 * // => true
32242 *
32243 * _.isArrayLikeObject(document.body.children);
32244 * // => true
32245 *
32246 * _.isArrayLikeObject('abc');
32247 * // => false
32248 *
32249 * _.isArrayLikeObject(_.noop);
32250 * // => false
32251 */
32252 function isArrayLikeObject(value) {
32253 return isObjectLike(value) && isArrayLike(value);
32254 }
32255
32256 /**
32257 * Checks if `value` is classified as a boolean primitive or object.
32258 *
32259 * @static
32260 * @memberOf _
32261 * @since 0.1.0
32262 * @category Lang
32263 * @param {*} value The value to check.
32264 * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
32265 * @example
32266 *
32267 * _.isBoolean(false);
32268 * // => true
32269 *
32270 * _.isBoolean(null);
32271 * // => false
32272 */
32273 function isBoolean(value) {
32274 return value === true || value === false ||
32275 (isObjectLike(value) && baseGetTag(value) == boolTag);
32276 }
32277
32278 /**
32279 * Checks if `value` is a buffer.
32280 *
32281 * @static
32282 * @memberOf _
32283 * @since 4.3.0
32284 * @category Lang
32285 * @param {*} value The value to check.
32286 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
32287 * @example
32288 *
32289 * _.isBuffer(new Buffer(2));
32290 * // => true
32291 *
32292 * _.isBuffer(new Uint8Array(2));
32293 * // => false
32294 */
32295 var isBuffer = nativeIsBuffer || stubFalse;
32296
32297 /**
32298 * Checks if `value` is classified as a `Date` object.
32299 *
32300 * @static
32301 * @memberOf _
32302 * @since 0.1.0
32303 * @category Lang
32304 * @param {*} value The value to check.
32305 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
32306 * @example
32307 *
32308 * _.isDate(new Date);
32309 * // => true
32310 *
32311 * _.isDate('Mon April 23 2012');
32312 * // => false
32313 */
32314 var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
32315
32316 /**
32317 * Checks if `value` is likely a DOM element.
32318 *
32319 * @static
32320 * @memberOf _
32321 * @since 0.1.0
32322 * @category Lang
32323 * @param {*} value The value to check.
32324 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
32325 * @example
32326 *
32327 * _.isElement(document.body);
32328 * // => true
32329 *
32330 * _.isElement('<body>');
32331 * // => false
32332 */
32333 function isElement(value) {
32334 return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
32335 }
32336
32337 /**
32338 * Checks if `value` is an empty object, collection, map, or set.
32339 *
32340 * Objects are considered empty if they have no own enumerable string keyed
32341 * properties.
32342 *
32343 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
32344 * jQuery-like collections are considered empty if they have a `length` of `0`.
32345 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
32346 *
32347 * @static
32348 * @memberOf _
32349 * @since 0.1.0
32350 * @category Lang
32351 * @param {*} value The value to check.
32352 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
32353 * @example
32354 *
32355 * _.isEmpty(null);
32356 * // => true
32357 *
32358 * _.isEmpty(true);
32359 * // => true
32360 *
32361 * _.isEmpty(1);
32362 * // => true
32363 *
32364 * _.isEmpty([1, 2, 3]);
32365 * // => false
32366 *
32367 * _.isEmpty({ 'a': 1 });
32368 * // => false
32369 */
32370 function isEmpty(value) {
32371 if (value == null) {
32372 return true;
32373 }
32374 if (isArrayLike(value) &&
32375 (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
32376 isBuffer(value) || isTypedArray(value) || isArguments(value))) {
32377 return !value.length;
32378 }
32379 var tag = getTag(value);
32380 if (tag == mapTag || tag == setTag) {
32381 return !value.size;
32382 }
32383 if (isPrototype(value)) {
32384 return !baseKeys(value).length;
32385 }
32386 for (var key in value) {
32387 if (hasOwnProperty.call(value, key)) {
32388 return false;
32389 }
32390 }
32391 return true;
32392 }
32393
32394 /**
32395 * Performs a deep comparison between two values to determine if they are
32396 * equivalent.
32397 *
32398 * **Note:** This method supports comparing arrays, array buffers, booleans,
32399 * date objects, error objects, maps, numbers, `Object` objects, regexes,
32400 * sets, strings, symbols, and typed arrays. `Object` objects are compared
32401 * by their own, not inherited, enumerable properties. Functions and DOM
32402 * nodes are compared by strict equality, i.e. `===`.
32403 *
32404 * @static
32405 * @memberOf _
32406 * @since 0.1.0
32407 * @category Lang
32408 * @param {*} value The value to compare.
32409 * @param {*} other The other value to compare.
32410 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
32411 * @example
32412 *
32413 * var object = { 'a': 1 };
32414 * var other = { 'a': 1 };
32415 *
32416 * _.isEqual(object, other);
32417 * // => true
32418 *
32419 * object === other;
32420 * // => false
32421 */
32422 function isEqual(value, other) {
32423 return baseIsEqual(value, other);
32424 }
32425
32426 /**
32427 * This method is like `_.isEqual` except that it accepts `customizer` which
32428 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
32429 * are handled by the method instead. The `customizer` is invoked with up to
32430 * six arguments: (objValue, othValue [, index|key, object, other, stack]).
32431 *
32432 * @static
32433 * @memberOf _
32434 * @since 4.0.0
32435 * @category Lang
32436 * @param {*} value The value to compare.
32437 * @param {*} other The other value to compare.
32438 * @param {Function} [customizer] The function to customize comparisons.
32439 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
32440 * @example
32441 *
32442 * function isGreeting(value) {
32443 * return /^h(?:i|ello)$/.test(value);
32444 * }
32445 *
32446 * function customizer(objValue, othValue) {
32447 * if (isGreeting(objValue) && isGreeting(othValue)) {
32448 * return true;
32449 * }
32450 * }
32451 *
32452 * var array = ['hello', 'goodbye'];
32453 * var other = ['hi', 'goodbye'];
32454 *
32455 * _.isEqualWith(array, other, customizer);
32456 * // => true
32457 */
32458 function isEqualWith(value, other, customizer) {
32459 customizer = typeof customizer == 'function' ? customizer : undefined$1;
32460 var result = customizer ? customizer(value, other) : undefined$1;
32461 return result === undefined$1 ? baseIsEqual(value, other, undefined$1, customizer) : !!result;
32462 }
32463
32464 /**
32465 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
32466 * `SyntaxError`, `TypeError`, or `URIError` object.
32467 *
32468 * @static
32469 * @memberOf _
32470 * @since 3.0.0
32471 * @category Lang
32472 * @param {*} value The value to check.
32473 * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
32474 * @example
32475 *
32476 * _.isError(new Error);
32477 * // => true
32478 *
32479 * _.isError(Error);
32480 * // => false
32481 */
32482 function isError(value) {
32483 if (!isObjectLike(value)) {
32484 return false;
32485 }
32486 var tag = baseGetTag(value);
32487 return tag == errorTag || tag == domExcTag ||
32488 (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
32489 }
32490
32491 /**
32492 * Checks if `value` is a finite primitive number.
32493 *
32494 * **Note:** This method is based on
32495 * [`Number.isFinite`](https://mdn.io/Number/isFinite).
32496 *
32497 * @static
32498 * @memberOf _
32499 * @since 0.1.0
32500 * @category Lang
32501 * @param {*} value The value to check.
32502 * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
32503 * @example
32504 *
32505 * _.isFinite(3);
32506 * // => true
32507 *
32508 * _.isFinite(Number.MIN_VALUE);
32509 * // => true
32510 *
32511 * _.isFinite(Infinity);
32512 * // => false
32513 *
32514 * _.isFinite('3');
32515 * // => false
32516 */
32517 function isFinite(value) {
32518 return typeof value == 'number' && nativeIsFinite(value);
32519 }
32520
32521 /**
32522 * Checks if `value` is classified as a `Function` object.
32523 *
32524 * @static
32525 * @memberOf _
32526 * @since 0.1.0
32527 * @category Lang
32528 * @param {*} value The value to check.
32529 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
32530 * @example
32531 *
32532 * _.isFunction(_);
32533 * // => true
32534 *
32535 * _.isFunction(/abc/);
32536 * // => false
32537 */
32538 function isFunction(value) {
32539 if (!isObject(value)) {
32540 return false;
32541 }
32542 // The use of `Object#toString` avoids issues with the `typeof` operator
32543 // in Safari 9 which returns 'object' for typed arrays and other constructors.
32544 var tag = baseGetTag(value);
32545 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
32546 }
32547
32548 /**
32549 * Checks if `value` is an integer.
32550 *
32551 * **Note:** This method is based on
32552 * [`Number.isInteger`](https://mdn.io/Number/isInteger).
32553 *
32554 * @static
32555 * @memberOf _
32556 * @since 4.0.0
32557 * @category Lang
32558 * @param {*} value The value to check.
32559 * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
32560 * @example
32561 *
32562 * _.isInteger(3);
32563 * // => true
32564 *
32565 * _.isInteger(Number.MIN_VALUE);
32566 * // => false
32567 *
32568 * _.isInteger(Infinity);
32569 * // => false
32570 *
32571 * _.isInteger('3');
32572 * // => false
32573 */
32574 function isInteger(value) {
32575 return typeof value == 'number' && value == toInteger(value);
32576 }
32577
32578 /**
32579 * Checks if `value` is a valid array-like length.
32580 *
32581 * **Note:** This method is loosely based on
32582 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
32583 *
32584 * @static
32585 * @memberOf _
32586 * @since 4.0.0
32587 * @category Lang
32588 * @param {*} value The value to check.
32589 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
32590 * @example
32591 *
32592 * _.isLength(3);
32593 * // => true
32594 *
32595 * _.isLength(Number.MIN_VALUE);
32596 * // => false
32597 *
32598 * _.isLength(Infinity);
32599 * // => false
32600 *
32601 * _.isLength('3');
32602 * // => false
32603 */
32604 function isLength(value) {
32605 return typeof value == 'number' &&
32606 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
32607 }
32608
32609 /**
32610 * Checks if `value` is the
32611 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
32612 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
32613 *
32614 * @static
32615 * @memberOf _
32616 * @since 0.1.0
32617 * @category Lang
32618 * @param {*} value The value to check.
32619 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
32620 * @example
32621 *
32622 * _.isObject({});
32623 * // => true
32624 *
32625 * _.isObject([1, 2, 3]);
32626 * // => true
32627 *
32628 * _.isObject(_.noop);
32629 * // => true
32630 *
32631 * _.isObject(null);
32632 * // => false
32633 */
32634 function isObject(value) {
32635 var type = typeof value;
32636 return value != null && (type == 'object' || type == 'function');
32637 }
32638
32639 /**
32640 * Checks if `value` is object-like. A value is object-like if it's not `null`
32641 * and has a `typeof` result of "object".
32642 *
32643 * @static
32644 * @memberOf _
32645 * @since 4.0.0
32646 * @category Lang
32647 * @param {*} value The value to check.
32648 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
32649 * @example
32650 *
32651 * _.isObjectLike({});
32652 * // => true
32653 *
32654 * _.isObjectLike([1, 2, 3]);
32655 * // => true
32656 *
32657 * _.isObjectLike(_.noop);
32658 * // => false
32659 *
32660 * _.isObjectLike(null);
32661 * // => false
32662 */
32663 function isObjectLike(value) {
32664 return value != null && typeof value == 'object';
32665 }
32666
32667 /**
32668 * Checks if `value` is classified as a `Map` object.
32669 *
32670 * @static
32671 * @memberOf _
32672 * @since 4.3.0
32673 * @category Lang
32674 * @param {*} value The value to check.
32675 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
32676 * @example
32677 *
32678 * _.isMap(new Map);
32679 * // => true
32680 *
32681 * _.isMap(new WeakMap);
32682 * // => false
32683 */
32684 var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
32685
32686 /**
32687 * Performs a partial deep comparison between `object` and `source` to
32688 * determine if `object` contains equivalent property values.
32689 *
32690 * **Note:** This method is equivalent to `_.matches` when `source` is
32691 * partially applied.
32692 *
32693 * Partial comparisons will match empty array and empty object `source`
32694 * values against any array or object value, respectively. See `_.isEqual`
32695 * for a list of supported value comparisons.
32696 *
32697 * @static
32698 * @memberOf _
32699 * @since 3.0.0
32700 * @category Lang
32701 * @param {Object} object The object to inspect.
32702 * @param {Object} source The object of property values to match.
32703 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
32704 * @example
32705 *
32706 * var object = { 'a': 1, 'b': 2 };
32707 *
32708 * _.isMatch(object, { 'b': 2 });
32709 * // => true
32710 *
32711 * _.isMatch(object, { 'b': 1 });
32712 * // => false
32713 */
32714 function isMatch(object, source) {
32715 return object === source || baseIsMatch(object, source, getMatchData(source));
32716 }
32717
32718 /**
32719 * This method is like `_.isMatch` except that it accepts `customizer` which
32720 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
32721 * are handled by the method instead. The `customizer` is invoked with five
32722 * arguments: (objValue, srcValue, index|key, object, source).
32723 *
32724 * @static
32725 * @memberOf _
32726 * @since 4.0.0
32727 * @category Lang
32728 * @param {Object} object The object to inspect.
32729 * @param {Object} source The object of property values to match.
32730 * @param {Function} [customizer] The function to customize comparisons.
32731 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
32732 * @example
32733 *
32734 * function isGreeting(value) {
32735 * return /^h(?:i|ello)$/.test(value);
32736 * }
32737 *
32738 * function customizer(objValue, srcValue) {
32739 * if (isGreeting(objValue) && isGreeting(srcValue)) {
32740 * return true;
32741 * }
32742 * }
32743 *
32744 * var object = { 'greeting': 'hello' };
32745 * var source = { 'greeting': 'hi' };
32746 *
32747 * _.isMatchWith(object, source, customizer);
32748 * // => true
32749 */
32750 function isMatchWith(object, source, customizer) {
32751 customizer = typeof customizer == 'function' ? customizer : undefined$1;
32752 return baseIsMatch(object, source, getMatchData(source), customizer);
32753 }
32754
32755 /**
32756 * Checks if `value` is `NaN`.
32757 *
32758 * **Note:** This method is based on
32759 * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
32760 * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
32761 * `undefined` and other non-number values.
32762 *
32763 * @static
32764 * @memberOf _
32765 * @since 0.1.0
32766 * @category Lang
32767 * @param {*} value The value to check.
32768 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
32769 * @example
32770 *
32771 * _.isNaN(NaN);
32772 * // => true
32773 *
32774 * _.isNaN(new Number(NaN));
32775 * // => true
32776 *
32777 * isNaN(undefined);
32778 * // => true
32779 *
32780 * _.isNaN(undefined);
32781 * // => false
32782 */
32783 function isNaN(value) {
32784 // An `NaN` primitive is the only value that is not equal to itself.
32785 // Perform the `toStringTag` check first to avoid errors with some
32786 // ActiveX objects in IE.
32787 return isNumber(value) && value != +value;
32788 }
32789
32790 /**
32791 * Checks if `value` is a pristine native function.
32792 *
32793 * **Note:** This method can't reliably detect native functions in the presence
32794 * of the core-js package because core-js circumvents this kind of detection.
32795 * Despite multiple requests, the core-js maintainer has made it clear: any
32796 * attempt to fix the detection will be obstructed. As a result, we're left
32797 * with little choice but to throw an error. Unfortunately, this also affects
32798 * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
32799 * which rely on core-js.
32800 *
32801 * @static
32802 * @memberOf _
32803 * @since 3.0.0
32804 * @category Lang
32805 * @param {*} value The value to check.
32806 * @returns {boolean} Returns `true` if `value` is a native function,
32807 * else `false`.
32808 * @example
32809 *
32810 * _.isNative(Array.prototype.push);
32811 * // => true
32812 *
32813 * _.isNative(_);
32814 * // => false
32815 */
32816 function isNative(value) {
32817 if (isMaskable(value)) {
32818 throw new Error(CORE_ERROR_TEXT);
32819 }
32820 return baseIsNative(value);
32821 }
32822
32823 /**
32824 * Checks if `value` is `null`.
32825 *
32826 * @static
32827 * @memberOf _
32828 * @since 0.1.0
32829 * @category Lang
32830 * @param {*} value The value to check.
32831 * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
32832 * @example
32833 *
32834 * _.isNull(null);
32835 * // => true
32836 *
32837 * _.isNull(void 0);
32838 * // => false
32839 */
32840 function isNull(value) {
32841 return value === null;
32842 }
32843
32844 /**
32845 * Checks if `value` is `null` or `undefined`.
32846 *
32847 * @static
32848 * @memberOf _
32849 * @since 4.0.0
32850 * @category Lang
32851 * @param {*} value The value to check.
32852 * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
32853 * @example
32854 *
32855 * _.isNil(null);
32856 * // => true
32857 *
32858 * _.isNil(void 0);
32859 * // => true
32860 *
32861 * _.isNil(NaN);
32862 * // => false
32863 */
32864 function isNil(value) {
32865 return value == null;
32866 }
32867
32868 /**
32869 * Checks if `value` is classified as a `Number` primitive or object.
32870 *
32871 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
32872 * classified as numbers, use the `_.isFinite` method.
32873 *
32874 * @static
32875 * @memberOf _
32876 * @since 0.1.0
32877 * @category Lang
32878 * @param {*} value The value to check.
32879 * @returns {boolean} Returns `true` if `value` is a number, else `false`.
32880 * @example
32881 *
32882 * _.isNumber(3);
32883 * // => true
32884 *
32885 * _.isNumber(Number.MIN_VALUE);
32886 * // => true
32887 *
32888 * _.isNumber(Infinity);
32889 * // => true
32890 *
32891 * _.isNumber('3');
32892 * // => false
32893 */
32894 function isNumber(value) {
32895 return typeof value == 'number' ||
32896 (isObjectLike(value) && baseGetTag(value) == numberTag);
32897 }
32898
32899 /**
32900 * Checks if `value` is a plain object, that is, an object created by the
32901 * `Object` constructor or one with a `[[Prototype]]` of `null`.
32902 *
32903 * @static
32904 * @memberOf _
32905 * @since 0.8.0
32906 * @category Lang
32907 * @param {*} value The value to check.
32908 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
32909 * @example
32910 *
32911 * function Foo() {
32912 * this.a = 1;
32913 * }
32914 *
32915 * _.isPlainObject(new Foo);
32916 * // => false
32917 *
32918 * _.isPlainObject([1, 2, 3]);
32919 * // => false
32920 *
32921 * _.isPlainObject({ 'x': 0, 'y': 0 });
32922 * // => true
32923 *
32924 * _.isPlainObject(Object.create(null));
32925 * // => true
32926 */
32927 function isPlainObject(value) {
32928 if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
32929 return false;
32930 }
32931 var proto = getPrototype(value);
32932 if (proto === null) {
32933 return true;
32934 }
32935 var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
32936 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
32937 funcToString.call(Ctor) == objectCtorString;
32938 }
32939
32940 /**
32941 * Checks if `value` is classified as a `RegExp` object.
32942 *
32943 * @static
32944 * @memberOf _
32945 * @since 0.1.0
32946 * @category Lang
32947 * @param {*} value The value to check.
32948 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
32949 * @example
32950 *
32951 * _.isRegExp(/abc/);
32952 * // => true
32953 *
32954 * _.isRegExp('/abc/');
32955 * // => false
32956 */
32957 var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
32958
32959 /**
32960 * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
32961 * double precision number which isn't the result of a rounded unsafe integer.
32962 *
32963 * **Note:** This method is based on
32964 * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
32965 *
32966 * @static
32967 * @memberOf _
32968 * @since 4.0.0
32969 * @category Lang
32970 * @param {*} value The value to check.
32971 * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
32972 * @example
32973 *
32974 * _.isSafeInteger(3);
32975 * // => true
32976 *
32977 * _.isSafeInteger(Number.MIN_VALUE);
32978 * // => false
32979 *
32980 * _.isSafeInteger(Infinity);
32981 * // => false
32982 *
32983 * _.isSafeInteger('3');
32984 * // => false
32985 */
32986 function isSafeInteger(value) {
32987 return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
32988 }
32989
32990 /**
32991 * Checks if `value` is classified as a `Set` object.
32992 *
32993 * @static
32994 * @memberOf _
32995 * @since 4.3.0
32996 * @category Lang
32997 * @param {*} value The value to check.
32998 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
32999 * @example
33000 *
33001 * _.isSet(new Set);
33002 * // => true
33003 *
33004 * _.isSet(new WeakSet);
33005 * // => false
33006 */
33007 var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
33008
33009 /**
33010 * Checks if `value` is classified as a `String` primitive or object.
33011 *
33012 * @static
33013 * @since 0.1.0
33014 * @memberOf _
33015 * @category Lang
33016 * @param {*} value The value to check.
33017 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
33018 * @example
33019 *
33020 * _.isString('abc');
33021 * // => true
33022 *
33023 * _.isString(1);
33024 * // => false
33025 */
33026 function isString(value) {
33027 return typeof value == 'string' ||
33028 (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
33029 }
33030
33031 /**
33032 * Checks if `value` is classified as a `Symbol` primitive or object.
33033 *
33034 * @static
33035 * @memberOf _
33036 * @since 4.0.0
33037 * @category Lang
33038 * @param {*} value The value to check.
33039 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
33040 * @example
33041 *
33042 * _.isSymbol(Symbol.iterator);
33043 * // => true
33044 *
33045 * _.isSymbol('abc');
33046 * // => false
33047 */
33048 function isSymbol(value) {
33049 return typeof value == 'symbol' ||
33050 (isObjectLike(value) && baseGetTag(value) == symbolTag);
33051 }
33052
33053 /**
33054 * Checks if `value` is classified as a typed array.
33055 *
33056 * @static
33057 * @memberOf _
33058 * @since 3.0.0
33059 * @category Lang
33060 * @param {*} value The value to check.
33061 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
33062 * @example
33063 *
33064 * _.isTypedArray(new Uint8Array);
33065 * // => true
33066 *
33067 * _.isTypedArray([]);
33068 * // => false
33069 */
33070 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
33071
33072 /**
33073 * Checks if `value` is `undefined`.
33074 *
33075 * @static
33076 * @since 0.1.0
33077 * @memberOf _
33078 * @category Lang
33079 * @param {*} value The value to check.
33080 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
33081 * @example
33082 *
33083 * _.isUndefined(void 0);
33084 * // => true
33085 *
33086 * _.isUndefined(null);
33087 * // => false
33088 */
33089 function isUndefined(value) {
33090 return value === undefined$1;
33091 }
33092
33093 /**
33094 * Checks if `value` is classified as a `WeakMap` object.
33095 *
33096 * @static
33097 * @memberOf _
33098 * @since 4.3.0
33099 * @category Lang
33100 * @param {*} value The value to check.
33101 * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
33102 * @example
33103 *
33104 * _.isWeakMap(new WeakMap);
33105 * // => true
33106 *
33107 * _.isWeakMap(new Map);
33108 * // => false
33109 */
33110 function isWeakMap(value) {
33111 return isObjectLike(value) && getTag(value) == weakMapTag;
33112 }
33113
33114 /**
33115 * Checks if `value` is classified as a `WeakSet` object.
33116 *
33117 * @static
33118 * @memberOf _
33119 * @since 4.3.0
33120 * @category Lang
33121 * @param {*} value The value to check.
33122 * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
33123 * @example
33124 *
33125 * _.isWeakSet(new WeakSet);
33126 * // => true
33127 *
33128 * _.isWeakSet(new Set);
33129 * // => false
33130 */
33131 function isWeakSet(value) {
33132 return isObjectLike(value) && baseGetTag(value) == weakSetTag;
33133 }
33134
33135 /**
33136 * Checks if `value` is less than `other`.
33137 *
33138 * @static
33139 * @memberOf _
33140 * @since 3.9.0
33141 * @category Lang
33142 * @param {*} value The value to compare.
33143 * @param {*} other The other value to compare.
33144 * @returns {boolean} Returns `true` if `value` is less than `other`,
33145 * else `false`.
33146 * @see _.gt
33147 * @example
33148 *
33149 * _.lt(1, 3);
33150 * // => true
33151 *
33152 * _.lt(3, 3);
33153 * // => false
33154 *
33155 * _.lt(3, 1);
33156 * // => false
33157 */
33158 var lt = createRelationalOperation(baseLt);
33159
33160 /**
33161 * Checks if `value` is less than or equal to `other`.
33162 *
33163 * @static
33164 * @memberOf _
33165 * @since 3.9.0
33166 * @category Lang
33167 * @param {*} value The value to compare.
33168 * @param {*} other The other value to compare.
33169 * @returns {boolean} Returns `true` if `value` is less than or equal to
33170 * `other`, else `false`.
33171 * @see _.gte
33172 * @example
33173 *
33174 * _.lte(1, 3);
33175 * // => true
33176 *
33177 * _.lte(3, 3);
33178 * // => true
33179 *
33180 * _.lte(3, 1);
33181 * // => false
33182 */
33183 var lte = createRelationalOperation(function(value, other) {
33184 return value <= other;
33185 });
33186
33187 /**
33188 * Converts `value` to an array.
33189 *
33190 * @static
33191 * @since 0.1.0
33192 * @memberOf _
33193 * @category Lang
33194 * @param {*} value The value to convert.
33195 * @returns {Array} Returns the converted array.
33196 * @example
33197 *
33198 * _.toArray({ 'a': 1, 'b': 2 });
33199 * // => [1, 2]
33200 *
33201 * _.toArray('abc');
33202 * // => ['a', 'b', 'c']
33203 *
33204 * _.toArray(1);
33205 * // => []
33206 *
33207 * _.toArray(null);
33208 * // => []
33209 */
33210 function toArray(value) {
33211 if (!value) {
33212 return [];
33213 }
33214 if (isArrayLike(value)) {
33215 return isString(value) ? stringToArray(value) : copyArray(value);
33216 }
33217 if (symIterator && value[symIterator]) {
33218 return iteratorToArray(value[symIterator]());
33219 }
33220 var tag = getTag(value),
33221 func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
33222
33223 return func(value);
33224 }
33225
33226 /**
33227 * Converts `value` to a finite number.
33228 *
33229 * @static
33230 * @memberOf _
33231 * @since 4.12.0
33232 * @category Lang
33233 * @param {*} value The value to convert.
33234 * @returns {number} Returns the converted number.
33235 * @example
33236 *
33237 * _.toFinite(3.2);
33238 * // => 3.2
33239 *
33240 * _.toFinite(Number.MIN_VALUE);
33241 * // => 5e-324
33242 *
33243 * _.toFinite(Infinity);
33244 * // => 1.7976931348623157e+308
33245 *
33246 * _.toFinite('3.2');
33247 * // => 3.2
33248 */
33249 function toFinite(value) {
33250 if (!value) {
33251 return value === 0 ? value : 0;
33252 }
33253 value = toNumber(value);
33254 if (value === INFINITY || value === -INFINITY) {
33255 var sign = (value < 0 ? -1 : 1);
33256 return sign * MAX_INTEGER;
33257 }
33258 return value === value ? value : 0;
33259 }
33260
33261 /**
33262 * Converts `value` to an integer.
33263 *
33264 * **Note:** This method is loosely based on
33265 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
33266 *
33267 * @static
33268 * @memberOf _
33269 * @since 4.0.0
33270 * @category Lang
33271 * @param {*} value The value to convert.
33272 * @returns {number} Returns the converted integer.
33273 * @example
33274 *
33275 * _.toInteger(3.2);
33276 * // => 3
33277 *
33278 * _.toInteger(Number.MIN_VALUE);
33279 * // => 0
33280 *
33281 * _.toInteger(Infinity);
33282 * // => 1.7976931348623157e+308
33283 *
33284 * _.toInteger('3.2');
33285 * // => 3
33286 */
33287 function toInteger(value) {
33288 var result = toFinite(value),
33289 remainder = result % 1;
33290
33291 return result === result ? (remainder ? result - remainder : result) : 0;
33292 }
33293
33294 /**
33295 * Converts `value` to an integer suitable for use as the length of an
33296 * array-like object.
33297 *
33298 * **Note:** This method is based on
33299 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
33300 *
33301 * @static
33302 * @memberOf _
33303 * @since 4.0.0
33304 * @category Lang
33305 * @param {*} value The value to convert.
33306 * @returns {number} Returns the converted integer.
33307 * @example
33308 *
33309 * _.toLength(3.2);
33310 * // => 3
33311 *
33312 * _.toLength(Number.MIN_VALUE);
33313 * // => 0
33314 *
33315 * _.toLength(Infinity);
33316 * // => 4294967295
33317 *
33318 * _.toLength('3.2');
33319 * // => 3
33320 */
33321 function toLength(value) {
33322 return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
33323 }
33324
33325 /**
33326 * Converts `value` to a number.
33327 *
33328 * @static
33329 * @memberOf _
33330 * @since 4.0.0
33331 * @category Lang
33332 * @param {*} value The value to process.
33333 * @returns {number} Returns the number.
33334 * @example
33335 *
33336 * _.toNumber(3.2);
33337 * // => 3.2
33338 *
33339 * _.toNumber(Number.MIN_VALUE);
33340 * // => 5e-324
33341 *
33342 * _.toNumber(Infinity);
33343 * // => Infinity
33344 *
33345 * _.toNumber('3.2');
33346 * // => 3.2
33347 */
33348 function toNumber(value) {
33349 if (typeof value == 'number') {
33350 return value;
33351 }
33352 if (isSymbol(value)) {
33353 return NAN;
33354 }
33355 if (isObject(value)) {
33356 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
33357 value = isObject(other) ? (other + '') : other;
33358 }
33359 if (typeof value != 'string') {
33360 return value === 0 ? value : +value;
33361 }
33362 value = value.replace(reTrim, '');
33363 var isBinary = reIsBinary.test(value);
33364 return (isBinary || reIsOctal.test(value))
33365 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
33366 : (reIsBadHex.test(value) ? NAN : +value);
33367 }
33368
33369 /**
33370 * Converts `value` to a plain object flattening inherited enumerable string
33371 * keyed properties of `value` to own properties of the plain object.
33372 *
33373 * @static
33374 * @memberOf _
33375 * @since 3.0.0
33376 * @category Lang
33377 * @param {*} value The value to convert.
33378 * @returns {Object} Returns the converted plain object.
33379 * @example
33380 *
33381 * function Foo() {
33382 * this.b = 2;
33383 * }
33384 *
33385 * Foo.prototype.c = 3;
33386 *
33387 * _.assign({ 'a': 1 }, new Foo);
33388 * // => { 'a': 1, 'b': 2 }
33389 *
33390 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
33391 * // => { 'a': 1, 'b': 2, 'c': 3 }
33392 */
33393 function toPlainObject(value) {
33394 return copyObject(value, keysIn(value));
33395 }
33396
33397 /**
33398 * Converts `value` to a safe integer. A safe integer can be compared and
33399 * represented correctly.
33400 *
33401 * @static
33402 * @memberOf _
33403 * @since 4.0.0
33404 * @category Lang
33405 * @param {*} value The value to convert.
33406 * @returns {number} Returns the converted integer.
33407 * @example
33408 *
33409 * _.toSafeInteger(3.2);
33410 * // => 3
33411 *
33412 * _.toSafeInteger(Number.MIN_VALUE);
33413 * // => 0
33414 *
33415 * _.toSafeInteger(Infinity);
33416 * // => 9007199254740991
33417 *
33418 * _.toSafeInteger('3.2');
33419 * // => 3
33420 */
33421 function toSafeInteger(value) {
33422 return value
33423 ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
33424 : (value === 0 ? value : 0);
33425 }
33426
33427 /**
33428 * Converts `value` to a string. An empty string is returned for `null`
33429 * and `undefined` values. The sign of `-0` is preserved.
33430 *
33431 * @static
33432 * @memberOf _
33433 * @since 4.0.0
33434 * @category Lang
33435 * @param {*} value The value to convert.
33436 * @returns {string} Returns the converted string.
33437 * @example
33438 *
33439 * _.toString(null);
33440 * // => ''
33441 *
33442 * _.toString(-0);
33443 * // => '-0'
33444 *
33445 * _.toString([1, 2, 3]);
33446 * // => '1,2,3'
33447 */
33448 function toString(value) {
33449 return value == null ? '' : baseToString(value);
33450 }
33451
33452 /*------------------------------------------------------------------------*/
33453
33454 /**
33455 * Assigns own enumerable string keyed properties of source objects to the
33456 * destination object. Source objects are applied from left to right.
33457 * Subsequent sources overwrite property assignments of previous sources.
33458 *
33459 * **Note:** This method mutates `object` and is loosely based on
33460 * [`Object.assign`](https://mdn.io/Object/assign).
33461 *
33462 * @static
33463 * @memberOf _
33464 * @since 0.10.0
33465 * @category Object
33466 * @param {Object} object The destination object.
33467 * @param {...Object} [sources] The source objects.
33468 * @returns {Object} Returns `object`.
33469 * @see _.assignIn
33470 * @example
33471 *
33472 * function Foo() {
33473 * this.a = 1;
33474 * }
33475 *
33476 * function Bar() {
33477 * this.c = 3;
33478 * }
33479 *
33480 * Foo.prototype.b = 2;
33481 * Bar.prototype.d = 4;
33482 *
33483 * _.assign({ 'a': 0 }, new Foo, new Bar);
33484 * // => { 'a': 1, 'c': 3 }
33485 */
33486 var assign = createAssigner(function(object, source) {
33487 if (isPrototype(source) || isArrayLike(source)) {
33488 copyObject(source, keys(source), object);
33489 return;
33490 }
33491 for (var key in source) {
33492 if (hasOwnProperty.call(source, key)) {
33493 assignValue(object, key, source[key]);
33494 }
33495 }
33496 });
33497
33498 /**
33499 * This method is like `_.assign` except that it iterates over own and
33500 * inherited source properties.
33501 *
33502 * **Note:** This method mutates `object`.
33503 *
33504 * @static
33505 * @memberOf _
33506 * @since 4.0.0
33507 * @alias extend
33508 * @category Object
33509 * @param {Object} object The destination object.
33510 * @param {...Object} [sources] The source objects.
33511 * @returns {Object} Returns `object`.
33512 * @see _.assign
33513 * @example
33514 *
33515 * function Foo() {
33516 * this.a = 1;
33517 * }
33518 *
33519 * function Bar() {
33520 * this.c = 3;
33521 * }
33522 *
33523 * Foo.prototype.b = 2;
33524 * Bar.prototype.d = 4;
33525 *
33526 * _.assignIn({ 'a': 0 }, new Foo, new Bar);
33527 * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
33528 */
33529 var assignIn = createAssigner(function(object, source) {
33530 copyObject(source, keysIn(source), object);
33531 });
33532
33533 /**
33534 * This method is like `_.assignIn` except that it accepts `customizer`
33535 * which is invoked to produce the assigned values. If `customizer` returns
33536 * `undefined`, assignment is handled by the method instead. The `customizer`
33537 * is invoked with five arguments: (objValue, srcValue, key, object, source).
33538 *
33539 * **Note:** This method mutates `object`.
33540 *
33541 * @static
33542 * @memberOf _
33543 * @since 4.0.0
33544 * @alias extendWith
33545 * @category Object
33546 * @param {Object} object The destination object.
33547 * @param {...Object} sources The source objects.
33548 * @param {Function} [customizer] The function to customize assigned values.
33549 * @returns {Object} Returns `object`.
33550 * @see _.assignWith
33551 * @example
33552 *
33553 * function customizer(objValue, srcValue) {
33554 * return _.isUndefined(objValue) ? srcValue : objValue;
33555 * }
33556 *
33557 * var defaults = _.partialRight(_.assignInWith, customizer);
33558 *
33559 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
33560 * // => { 'a': 1, 'b': 2 }
33561 */
33562 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
33563 copyObject(source, keysIn(source), object, customizer);
33564 });
33565
33566 /**
33567 * This method is like `_.assign` except that it accepts `customizer`
33568 * which is invoked to produce the assigned values. If `customizer` returns
33569 * `undefined`, assignment is handled by the method instead. The `customizer`
33570 * is invoked with five arguments: (objValue, srcValue, key, object, source).
33571 *
33572 * **Note:** This method mutates `object`.
33573 *
33574 * @static
33575 * @memberOf _
33576 * @since 4.0.0
33577 * @category Object
33578 * @param {Object} object The destination object.
33579 * @param {...Object} sources The source objects.
33580 * @param {Function} [customizer] The function to customize assigned values.
33581 * @returns {Object} Returns `object`.
33582 * @see _.assignInWith
33583 * @example
33584 *
33585 * function customizer(objValue, srcValue) {
33586 * return _.isUndefined(objValue) ? srcValue : objValue;
33587 * }
33588 *
33589 * var defaults = _.partialRight(_.assignWith, customizer);
33590 *
33591 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
33592 * // => { 'a': 1, 'b': 2 }
33593 */
33594 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
33595 copyObject(source, keys(source), object, customizer);
33596 });
33597
33598 /**
33599 * Creates an array of values corresponding to `paths` of `object`.
33600 *
33601 * @static
33602 * @memberOf _
33603 * @since 1.0.0
33604 * @category Object
33605 * @param {Object} object The object to iterate over.
33606 * @param {...(string|string[])} [paths] The property paths to pick.
33607 * @returns {Array} Returns the picked values.
33608 * @example
33609 *
33610 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
33611 *
33612 * _.at(object, ['a[0].b.c', 'a[1]']);
33613 * // => [3, 4]
33614 */
33615 var at = flatRest(baseAt);
33616
33617 /**
33618 * Creates an object that inherits from the `prototype` object. If a
33619 * `properties` object is given, its own enumerable string keyed properties
33620 * are assigned to the created object.
33621 *
33622 * @static
33623 * @memberOf _
33624 * @since 2.3.0
33625 * @category Object
33626 * @param {Object} prototype The object to inherit from.
33627 * @param {Object} [properties] The properties to assign to the object.
33628 * @returns {Object} Returns the new object.
33629 * @example
33630 *
33631 * function Shape() {
33632 * this.x = 0;
33633 * this.y = 0;
33634 * }
33635 *
33636 * function Circle() {
33637 * Shape.call(this);
33638 * }
33639 *
33640 * Circle.prototype = _.create(Shape.prototype, {
33641 * 'constructor': Circle
33642 * });
33643 *
33644 * var circle = new Circle;
33645 * circle instanceof Circle;
33646 * // => true
33647 *
33648 * circle instanceof Shape;
33649 * // => true
33650 */
33651 function create(prototype, properties) {
33652 var result = baseCreate(prototype);
33653 return properties == null ? result : baseAssign(result, properties);
33654 }
33655
33656 /**
33657 * Assigns own and inherited enumerable string keyed properties of source
33658 * objects to the destination object for all destination properties that
33659 * resolve to `undefined`. Source objects are applied from left to right.
33660 * Once a property is set, additional values of the same property are ignored.
33661 *
33662 * **Note:** This method mutates `object`.
33663 *
33664 * @static
33665 * @since 0.1.0
33666 * @memberOf _
33667 * @category Object
33668 * @param {Object} object The destination object.
33669 * @param {...Object} [sources] The source objects.
33670 * @returns {Object} Returns `object`.
33671 * @see _.defaultsDeep
33672 * @example
33673 *
33674 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
33675 * // => { 'a': 1, 'b': 2 }
33676 */
33677 var defaults = baseRest(function(object, sources) {
33678 object = Object(object);
33679
33680 var index = -1;
33681 var length = sources.length;
33682 var guard = length > 2 ? sources[2] : undefined$1;
33683
33684 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
33685 length = 1;
33686 }
33687
33688 while (++index < length) {
33689 var source = sources[index];
33690 var props = keysIn(source);
33691 var propsIndex = -1;
33692 var propsLength = props.length;
33693
33694 while (++propsIndex < propsLength) {
33695 var key = props[propsIndex];
33696 var value = object[key];
33697
33698 if (value === undefined$1 ||
33699 (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
33700 object[key] = source[key];
33701 }
33702 }
33703 }
33704
33705 return object;
33706 });
33707
33708 /**
33709 * This method is like `_.defaults` except that it recursively assigns
33710 * default properties.
33711 *
33712 * **Note:** This method mutates `object`.
33713 *
33714 * @static
33715 * @memberOf _
33716 * @since 3.10.0
33717 * @category Object
33718 * @param {Object} object The destination object.
33719 * @param {...Object} [sources] The source objects.
33720 * @returns {Object} Returns `object`.
33721 * @see _.defaults
33722 * @example
33723 *
33724 * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
33725 * // => { 'a': { 'b': 2, 'c': 3 } }
33726 */
33727 var defaultsDeep = baseRest(function(args) {
33728 args.push(undefined$1, customDefaultsMerge);
33729 return apply(mergeWith, undefined$1, args);
33730 });
33731
33732 /**
33733 * This method is like `_.find` except that it returns the key of the first
33734 * element `predicate` returns truthy for instead of the element itself.
33735 *
33736 * @static
33737 * @memberOf _
33738 * @since 1.1.0
33739 * @category Object
33740 * @param {Object} object The object to inspect.
33741 * @param {Function} [predicate=_.identity] The function invoked per iteration.
33742 * @returns {string|undefined} Returns the key of the matched element,
33743 * else `undefined`.
33744 * @example
33745 *
33746 * var users = {
33747 * 'barney': { 'age': 36, 'active': true },
33748 * 'fred': { 'age': 40, 'active': false },
33749 * 'pebbles': { 'age': 1, 'active': true }
33750 * };
33751 *
33752 * _.findKey(users, function(o) { return o.age < 40; });
33753 * // => 'barney' (iteration order is not guaranteed)
33754 *
33755 * // The `_.matches` iteratee shorthand.
33756 * _.findKey(users, { 'age': 1, 'active': true });
33757 * // => 'pebbles'
33758 *
33759 * // The `_.matchesProperty` iteratee shorthand.
33760 * _.findKey(users, ['active', false]);
33761 * // => 'fred'
33762 *
33763 * // The `_.property` iteratee shorthand.
33764 * _.findKey(users, 'active');
33765 * // => 'barney'
33766 */
33767 function findKey(object, predicate) {
33768 return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
33769 }
33770
33771 /**
33772 * This method is like `_.findKey` except that it iterates over elements of
33773 * a collection in the opposite order.
33774 *
33775 * @static
33776 * @memberOf _
33777 * @since 2.0.0
33778 * @category Object
33779 * @param {Object} object The object to inspect.
33780 * @param {Function} [predicate=_.identity] The function invoked per iteration.
33781 * @returns {string|undefined} Returns the key of the matched element,
33782 * else `undefined`.
33783 * @example
33784 *
33785 * var users = {
33786 * 'barney': { 'age': 36, 'active': true },
33787 * 'fred': { 'age': 40, 'active': false },
33788 * 'pebbles': { 'age': 1, 'active': true }
33789 * };
33790 *
33791 * _.findLastKey(users, function(o) { return o.age < 40; });
33792 * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
33793 *
33794 * // The `_.matches` iteratee shorthand.
33795 * _.findLastKey(users, { 'age': 36, 'active': true });
33796 * // => 'barney'
33797 *
33798 * // The `_.matchesProperty` iteratee shorthand.
33799 * _.findLastKey(users, ['active', false]);
33800 * // => 'fred'
33801 *
33802 * // The `_.property` iteratee shorthand.
33803 * _.findLastKey(users, 'active');
33804 * // => 'pebbles'
33805 */
33806 function findLastKey(object, predicate) {
33807 return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
33808 }
33809
33810 /**
33811 * Iterates over own and inherited enumerable string keyed properties of an
33812 * object and invokes `iteratee` for each property. The iteratee is invoked
33813 * with three arguments: (value, key, object). Iteratee functions may exit
33814 * iteration early by explicitly returning `false`.
33815 *
33816 * @static
33817 * @memberOf _
33818 * @since 0.3.0
33819 * @category Object
33820 * @param {Object} object The object to iterate over.
33821 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
33822 * @returns {Object} Returns `object`.
33823 * @see _.forInRight
33824 * @example
33825 *
33826 * function Foo() {
33827 * this.a = 1;
33828 * this.b = 2;
33829 * }
33830 *
33831 * Foo.prototype.c = 3;
33832 *
33833 * _.forIn(new Foo, function(value, key) {
33834 * console.log(key);
33835 * });
33836 * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
33837 */
33838 function forIn(object, iteratee) {
33839 return object == null
33840 ? object
33841 : baseFor(object, getIteratee(iteratee, 3), keysIn);
33842 }
33843
33844 /**
33845 * This method is like `_.forIn` except that it iterates over properties of
33846 * `object` in the opposite order.
33847 *
33848 * @static
33849 * @memberOf _
33850 * @since 2.0.0
33851 * @category Object
33852 * @param {Object} object The object to iterate over.
33853 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
33854 * @returns {Object} Returns `object`.
33855 * @see _.forIn
33856 * @example
33857 *
33858 * function Foo() {
33859 * this.a = 1;
33860 * this.b = 2;
33861 * }
33862 *
33863 * Foo.prototype.c = 3;
33864 *
33865 * _.forInRight(new Foo, function(value, key) {
33866 * console.log(key);
33867 * });
33868 * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
33869 */
33870 function forInRight(object, iteratee) {
33871 return object == null
33872 ? object
33873 : baseForRight(object, getIteratee(iteratee, 3), keysIn);
33874 }
33875
33876 /**
33877 * Iterates over own enumerable string keyed properties of an object and
33878 * invokes `iteratee` for each property. The iteratee is invoked with three
33879 * arguments: (value, key, object). Iteratee functions may exit iteration
33880 * early by explicitly returning `false`.
33881 *
33882 * @static
33883 * @memberOf _
33884 * @since 0.3.0
33885 * @category Object
33886 * @param {Object} object The object to iterate over.
33887 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
33888 * @returns {Object} Returns `object`.
33889 * @see _.forOwnRight
33890 * @example
33891 *
33892 * function Foo() {
33893 * this.a = 1;
33894 * this.b = 2;
33895 * }
33896 *
33897 * Foo.prototype.c = 3;
33898 *
33899 * _.forOwn(new Foo, function(value, key) {
33900 * console.log(key);
33901 * });
33902 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
33903 */
33904 function forOwn(object, iteratee) {
33905 return object && baseForOwn(object, getIteratee(iteratee, 3));
33906 }
33907
33908 /**
33909 * This method is like `_.forOwn` except that it iterates over properties of
33910 * `object` in the opposite order.
33911 *
33912 * @static
33913 * @memberOf _
33914 * @since 2.0.0
33915 * @category Object
33916 * @param {Object} object The object to iterate over.
33917 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
33918 * @returns {Object} Returns `object`.
33919 * @see _.forOwn
33920 * @example
33921 *
33922 * function Foo() {
33923 * this.a = 1;
33924 * this.b = 2;
33925 * }
33926 *
33927 * Foo.prototype.c = 3;
33928 *
33929 * _.forOwnRight(new Foo, function(value, key) {
33930 * console.log(key);
33931 * });
33932 * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
33933 */
33934 function forOwnRight(object, iteratee) {
33935 return object && baseForOwnRight(object, getIteratee(iteratee, 3));
33936 }
33937
33938 /**
33939 * Creates an array of function property names from own enumerable properties
33940 * of `object`.
33941 *
33942 * @static
33943 * @since 0.1.0
33944 * @memberOf _
33945 * @category Object
33946 * @param {Object} object The object to inspect.
33947 * @returns {Array} Returns the function names.
33948 * @see _.functionsIn
33949 * @example
33950 *
33951 * function Foo() {
33952 * this.a = _.constant('a');
33953 * this.b = _.constant('b');
33954 * }
33955 *
33956 * Foo.prototype.c = _.constant('c');
33957 *
33958 * _.functions(new Foo);
33959 * // => ['a', 'b']
33960 */
33961 function functions(object) {
33962 return object == null ? [] : baseFunctions(object, keys(object));
33963 }
33964
33965 /**
33966 * Creates an array of function property names from own and inherited
33967 * enumerable properties of `object`.
33968 *
33969 * @static
33970 * @memberOf _
33971 * @since 4.0.0
33972 * @category Object
33973 * @param {Object} object The object to inspect.
33974 * @returns {Array} Returns the function names.
33975 * @see _.functions
33976 * @example
33977 *
33978 * function Foo() {
33979 * this.a = _.constant('a');
33980 * this.b = _.constant('b');
33981 * }
33982 *
33983 * Foo.prototype.c = _.constant('c');
33984 *
33985 * _.functionsIn(new Foo);
33986 * // => ['a', 'b', 'c']
33987 */
33988 function functionsIn(object) {
33989 return object == null ? [] : baseFunctions(object, keysIn(object));
33990 }
33991
33992 /**
33993 * Gets the value at `path` of `object`. If the resolved value is
33994 * `undefined`, the `defaultValue` is returned in its place.
33995 *
33996 * @static
33997 * @memberOf _
33998 * @since 3.7.0
33999 * @category Object
34000 * @param {Object} object The object to query.
34001 * @param {Array|string} path The path of the property to get.
34002 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
34003 * @returns {*} Returns the resolved value.
34004 * @example
34005 *
34006 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
34007 *
34008 * _.get(object, 'a[0].b.c');
34009 * // => 3
34010 *
34011 * _.get(object, ['a', '0', 'b', 'c']);
34012 * // => 3
34013 *
34014 * _.get(object, 'a.b.c', 'default');
34015 * // => 'default'
34016 */
34017 function get(object, path, defaultValue) {
34018 var result = object == null ? undefined$1 : baseGet(object, path);
34019 return result === undefined$1 ? defaultValue : result;
34020 }
34021
34022 /**
34023 * Checks if `path` is a direct property of `object`.
34024 *
34025 * @static
34026 * @since 0.1.0
34027 * @memberOf _
34028 * @category Object
34029 * @param {Object} object The object to query.
34030 * @param {Array|string} path The path to check.
34031 * @returns {boolean} Returns `true` if `path` exists, else `false`.
34032 * @example
34033 *
34034 * var object = { 'a': { 'b': 2 } };
34035 * var other = _.create({ 'a': _.create({ 'b': 2 }) });
34036 *
34037 * _.has(object, 'a');
34038 * // => true
34039 *
34040 * _.has(object, 'a.b');
34041 * // => true
34042 *
34043 * _.has(object, ['a', 'b']);
34044 * // => true
34045 *
34046 * _.has(other, 'a');
34047 * // => false
34048 */
34049 function has(object, path) {
34050 return object != null && hasPath(object, path, baseHas);
34051 }
34052
34053 /**
34054 * Checks if `path` is a direct or inherited property of `object`.
34055 *
34056 * @static
34057 * @memberOf _
34058 * @since 4.0.0
34059 * @category Object
34060 * @param {Object} object The object to query.
34061 * @param {Array|string} path The path to check.
34062 * @returns {boolean} Returns `true` if `path` exists, else `false`.
34063 * @example
34064 *
34065 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
34066 *
34067 * _.hasIn(object, 'a');
34068 * // => true
34069 *
34070 * _.hasIn(object, 'a.b');
34071 * // => true
34072 *
34073 * _.hasIn(object, ['a', 'b']);
34074 * // => true
34075 *
34076 * _.hasIn(object, 'b');
34077 * // => false
34078 */
34079 function hasIn(object, path) {
34080 return object != null && hasPath(object, path, baseHasIn);
34081 }
34082
34083 /**
34084 * Creates an object composed of the inverted keys and values of `object`.
34085 * If `object` contains duplicate values, subsequent values overwrite
34086 * property assignments of previous values.
34087 *
34088 * @static
34089 * @memberOf _
34090 * @since 0.7.0
34091 * @category Object
34092 * @param {Object} object The object to invert.
34093 * @returns {Object} Returns the new inverted object.
34094 * @example
34095 *
34096 * var object = { 'a': 1, 'b': 2, 'c': 1 };
34097 *
34098 * _.invert(object);
34099 * // => { '1': 'c', '2': 'b' }
34100 */
34101 var invert = createInverter(function(result, value, key) {
34102 if (value != null &&
34103 typeof value.toString != 'function') {
34104 value = nativeObjectToString.call(value);
34105 }
34106
34107 result[value] = key;
34108 }, constant(identity));
34109
34110 /**
34111 * This method is like `_.invert` except that the inverted object is generated
34112 * from the results of running each element of `object` thru `iteratee`. The
34113 * corresponding inverted value of each inverted key is an array of keys
34114 * responsible for generating the inverted value. The iteratee is invoked
34115 * with one argument: (value).
34116 *
34117 * @static
34118 * @memberOf _
34119 * @since 4.1.0
34120 * @category Object
34121 * @param {Object} object The object to invert.
34122 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
34123 * @returns {Object} Returns the new inverted object.
34124 * @example
34125 *
34126 * var object = { 'a': 1, 'b': 2, 'c': 1 };
34127 *
34128 * _.invertBy(object);
34129 * // => { '1': ['a', 'c'], '2': ['b'] }
34130 *
34131 * _.invertBy(object, function(value) {
34132 * return 'group' + value;
34133 * });
34134 * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
34135 */
34136 var invertBy = createInverter(function(result, value, key) {
34137 if (value != null &&
34138 typeof value.toString != 'function') {
34139 value = nativeObjectToString.call(value);
34140 }
34141
34142 if (hasOwnProperty.call(result, value)) {
34143 result[value].push(key);
34144 } else {
34145 result[value] = [key];
34146 }
34147 }, getIteratee);
34148
34149 /**
34150 * Invokes the method at `path` of `object`.
34151 *
34152 * @static
34153 * @memberOf _
34154 * @since 4.0.0
34155 * @category Object
34156 * @param {Object} object The object to query.
34157 * @param {Array|string} path The path of the method to invoke.
34158 * @param {...*} [args] The arguments to invoke the method with.
34159 * @returns {*} Returns the result of the invoked method.
34160 * @example
34161 *
34162 * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
34163 *
34164 * _.invoke(object, 'a[0].b.c.slice', 1, 3);
34165 * // => [2, 3]
34166 */
34167 var invoke = baseRest(baseInvoke);
34168
34169 /**
34170 * Creates an array of the own enumerable property names of `object`.
34171 *
34172 * **Note:** Non-object values are coerced to objects. See the
34173 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
34174 * for more details.
34175 *
34176 * @static
34177 * @since 0.1.0
34178 * @memberOf _
34179 * @category Object
34180 * @param {Object} object The object to query.
34181 * @returns {Array} Returns the array of property names.
34182 * @example
34183 *
34184 * function Foo() {
34185 * this.a = 1;
34186 * this.b = 2;
34187 * }
34188 *
34189 * Foo.prototype.c = 3;
34190 *
34191 * _.keys(new Foo);
34192 * // => ['a', 'b'] (iteration order is not guaranteed)
34193 *
34194 * _.keys('hi');
34195 * // => ['0', '1']
34196 */
34197 function keys(object) {
34198 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
34199 }
34200
34201 /**
34202 * Creates an array of the own and inherited enumerable property names of `object`.
34203 *
34204 * **Note:** Non-object values are coerced to objects.
34205 *
34206 * @static
34207 * @memberOf _
34208 * @since 3.0.0
34209 * @category Object
34210 * @param {Object} object The object to query.
34211 * @returns {Array} Returns the array of property names.
34212 * @example
34213 *
34214 * function Foo() {
34215 * this.a = 1;
34216 * this.b = 2;
34217 * }
34218 *
34219 * Foo.prototype.c = 3;
34220 *
34221 * _.keysIn(new Foo);
34222 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
34223 */
34224 function keysIn(object) {
34225 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
34226 }
34227
34228 /**
34229 * The opposite of `_.mapValues`; this method creates an object with the
34230 * same values as `object` and keys generated by running each own enumerable
34231 * string keyed property of `object` thru `iteratee`. The iteratee is invoked
34232 * with three arguments: (value, key, object).
34233 *
34234 * @static
34235 * @memberOf _
34236 * @since 3.8.0
34237 * @category Object
34238 * @param {Object} object The object to iterate over.
34239 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
34240 * @returns {Object} Returns the new mapped object.
34241 * @see _.mapValues
34242 * @example
34243 *
34244 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
34245 * return key + value;
34246 * });
34247 * // => { 'a1': 1, 'b2': 2 }
34248 */
34249 function mapKeys(object, iteratee) {
34250 var result = {};
34251 iteratee = getIteratee(iteratee, 3);
34252
34253 baseForOwn(object, function(value, key, object) {
34254 baseAssignValue(result, iteratee(value, key, object), value);
34255 });
34256 return result;
34257 }
34258
34259 /**
34260 * Creates an object with the same keys as `object` and values generated
34261 * by running each own enumerable string keyed property of `object` thru
34262 * `iteratee`. The iteratee is invoked with three arguments:
34263 * (value, key, object).
34264 *
34265 * @static
34266 * @memberOf _
34267 * @since 2.4.0
34268 * @category Object
34269 * @param {Object} object The object to iterate over.
34270 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
34271 * @returns {Object} Returns the new mapped object.
34272 * @see _.mapKeys
34273 * @example
34274 *
34275 * var users = {
34276 * 'fred': { 'user': 'fred', 'age': 40 },
34277 * 'pebbles': { 'user': 'pebbles', 'age': 1 }
34278 * };
34279 *
34280 * _.mapValues(users, function(o) { return o.age; });
34281 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
34282 *
34283 * // The `_.property` iteratee shorthand.
34284 * _.mapValues(users, 'age');
34285 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
34286 */
34287 function mapValues(object, iteratee) {
34288 var result = {};
34289 iteratee = getIteratee(iteratee, 3);
34290
34291 baseForOwn(object, function(value, key, object) {
34292 baseAssignValue(result, key, iteratee(value, key, object));
34293 });
34294 return result;
34295 }
34296
34297 /**
34298 * This method is like `_.assign` except that it recursively merges own and
34299 * inherited enumerable string keyed properties of source objects into the
34300 * destination object. Source properties that resolve to `undefined` are
34301 * skipped if a destination value exists. Array and plain object properties
34302 * are merged recursively. Other objects and value types are overridden by
34303 * assignment. Source objects are applied from left to right. Subsequent
34304 * sources overwrite property assignments of previous sources.
34305 *
34306 * **Note:** This method mutates `object`.
34307 *
34308 * @static
34309 * @memberOf _
34310 * @since 0.5.0
34311 * @category Object
34312 * @param {Object} object The destination object.
34313 * @param {...Object} [sources] The source objects.
34314 * @returns {Object} Returns `object`.
34315 * @example
34316 *
34317 * var object = {
34318 * 'a': [{ 'b': 2 }, { 'd': 4 }]
34319 * };
34320 *
34321 * var other = {
34322 * 'a': [{ 'c': 3 }, { 'e': 5 }]
34323 * };
34324 *
34325 * _.merge(object, other);
34326 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
34327 */
34328 var merge = createAssigner(function(object, source, srcIndex) {
34329 baseMerge(object, source, srcIndex);
34330 });
34331
34332 /**
34333 * This method is like `_.merge` except that it accepts `customizer` which
34334 * is invoked to produce the merged values of the destination and source
34335 * properties. If `customizer` returns `undefined`, merging is handled by the
34336 * method instead. The `customizer` is invoked with six arguments:
34337 * (objValue, srcValue, key, object, source, stack).
34338 *
34339 * **Note:** This method mutates `object`.
34340 *
34341 * @static
34342 * @memberOf _
34343 * @since 4.0.0
34344 * @category Object
34345 * @param {Object} object The destination object.
34346 * @param {...Object} sources The source objects.
34347 * @param {Function} customizer The function to customize assigned values.
34348 * @returns {Object} Returns `object`.
34349 * @example
34350 *
34351 * function customizer(objValue, srcValue) {
34352 * if (_.isArray(objValue)) {
34353 * return objValue.concat(srcValue);
34354 * }
34355 * }
34356 *
34357 * var object = { 'a': [1], 'b': [2] };
34358 * var other = { 'a': [3], 'b': [4] };
34359 *
34360 * _.mergeWith(object, other, customizer);
34361 * // => { 'a': [1, 3], 'b': [2, 4] }
34362 */
34363 var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
34364 baseMerge(object, source, srcIndex, customizer);
34365 });
34366
34367 /**
34368 * The opposite of `_.pick`; this method creates an object composed of the
34369 * own and inherited enumerable property paths of `object` that are not omitted.
34370 *
34371 * **Note:** This method is considerably slower than `_.pick`.
34372 *
34373 * @static
34374 * @since 0.1.0
34375 * @memberOf _
34376 * @category Object
34377 * @param {Object} object The source object.
34378 * @param {...(string|string[])} [paths] The property paths to omit.
34379 * @returns {Object} Returns the new object.
34380 * @example
34381 *
34382 * var object = { 'a': 1, 'b': '2', 'c': 3 };
34383 *
34384 * _.omit(object, ['a', 'c']);
34385 * // => { 'b': '2' }
34386 */
34387 var omit = flatRest(function(object, paths) {
34388 var result = {};
34389 if (object == null) {
34390 return result;
34391 }
34392 var isDeep = false;
34393 paths = arrayMap(paths, function(path) {
34394 path = castPath(path, object);
34395 isDeep || (isDeep = path.length > 1);
34396 return path;
34397 });
34398 copyObject(object, getAllKeysIn(object), result);
34399 if (isDeep) {
34400 result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
34401 }
34402 var length = paths.length;
34403 while (length--) {
34404 baseUnset(result, paths[length]);
34405 }
34406 return result;
34407 });
34408
34409 /**
34410 * The opposite of `_.pickBy`; this method creates an object composed of
34411 * the own and inherited enumerable string keyed properties of `object` that
34412 * `predicate` doesn't return truthy for. The predicate is invoked with two
34413 * arguments: (value, key).
34414 *
34415 * @static
34416 * @memberOf _
34417 * @since 4.0.0
34418 * @category Object
34419 * @param {Object} object The source object.
34420 * @param {Function} [predicate=_.identity] The function invoked per property.
34421 * @returns {Object} Returns the new object.
34422 * @example
34423 *
34424 * var object = { 'a': 1, 'b': '2', 'c': 3 };
34425 *
34426 * _.omitBy(object, _.isNumber);
34427 * // => { 'b': '2' }
34428 */
34429 function omitBy(object, predicate) {
34430 return pickBy(object, negate(getIteratee(predicate)));
34431 }
34432
34433 /**
34434 * Creates an object composed of the picked `object` properties.
34435 *
34436 * @static
34437 * @since 0.1.0
34438 * @memberOf _
34439 * @category Object
34440 * @param {Object} object The source object.
34441 * @param {...(string|string[])} [paths] The property paths to pick.
34442 * @returns {Object} Returns the new object.
34443 * @example
34444 *
34445 * var object = { 'a': 1, 'b': '2', 'c': 3 };
34446 *
34447 * _.pick(object, ['a', 'c']);
34448 * // => { 'a': 1, 'c': 3 }
34449 */
34450 var pick = flatRest(function(object, paths) {
34451 return object == null ? {} : basePick(object, paths);
34452 });
34453
34454 /**
34455 * Creates an object composed of the `object` properties `predicate` returns
34456 * truthy for. The predicate is invoked with two arguments: (value, key).
34457 *
34458 * @static
34459 * @memberOf _
34460 * @since 4.0.0
34461 * @category Object
34462 * @param {Object} object The source object.
34463 * @param {Function} [predicate=_.identity] The function invoked per property.
34464 * @returns {Object} Returns the new object.
34465 * @example
34466 *
34467 * var object = { 'a': 1, 'b': '2', 'c': 3 };
34468 *
34469 * _.pickBy(object, _.isNumber);
34470 * // => { 'a': 1, 'c': 3 }
34471 */
34472 function pickBy(object, predicate) {
34473 if (object == null) {
34474 return {};
34475 }
34476 var props = arrayMap(getAllKeysIn(object), function(prop) {
34477 return [prop];
34478 });
34479 predicate = getIteratee(predicate);
34480 return basePickBy(object, props, function(value, path) {
34481 return predicate(value, path[0]);
34482 });
34483 }
34484
34485 /**
34486 * This method is like `_.get` except that if the resolved value is a
34487 * function it's invoked with the `this` binding of its parent object and
34488 * its result is returned.
34489 *
34490 * @static
34491 * @since 0.1.0
34492 * @memberOf _
34493 * @category Object
34494 * @param {Object} object The object to query.
34495 * @param {Array|string} path The path of the property to resolve.
34496 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
34497 * @returns {*} Returns the resolved value.
34498 * @example
34499 *
34500 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
34501 *
34502 * _.result(object, 'a[0].b.c1');
34503 * // => 3
34504 *
34505 * _.result(object, 'a[0].b.c2');
34506 * // => 4
34507 *
34508 * _.result(object, 'a[0].b.c3', 'default');
34509 * // => 'default'
34510 *
34511 * _.result(object, 'a[0].b.c3', _.constant('default'));
34512 * // => 'default'
34513 */
34514 function result(object, path, defaultValue) {
34515 path = castPath(path, object);
34516
34517 var index = -1,
34518 length = path.length;
34519
34520 // Ensure the loop is entered when path is empty.
34521 if (!length) {
34522 length = 1;
34523 object = undefined$1;
34524 }
34525 while (++index < length) {
34526 var value = object == null ? undefined$1 : object[toKey(path[index])];
34527 if (value === undefined$1) {
34528 index = length;
34529 value = defaultValue;
34530 }
34531 object = isFunction(value) ? value.call(object) : value;
34532 }
34533 return object;
34534 }
34535
34536 /**
34537 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
34538 * it's created. Arrays are created for missing index properties while objects
34539 * are created for all other missing properties. Use `_.setWith` to customize
34540 * `path` creation.
34541 *
34542 * **Note:** This method mutates `object`.
34543 *
34544 * @static
34545 * @memberOf _
34546 * @since 3.7.0
34547 * @category Object
34548 * @param {Object} object The object to modify.
34549 * @param {Array|string} path The path of the property to set.
34550 * @param {*} value The value to set.
34551 * @returns {Object} Returns `object`.
34552 * @example
34553 *
34554 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
34555 *
34556 * _.set(object, 'a[0].b.c', 4);
34557 * console.log(object.a[0].b.c);
34558 * // => 4
34559 *
34560 * _.set(object, ['x', '0', 'y', 'z'], 5);
34561 * console.log(object.x[0].y.z);
34562 * // => 5
34563 */
34564 function set(object, path, value) {
34565 return object == null ? object : baseSet(object, path, value);
34566 }
34567
34568 /**
34569 * This method is like `_.set` except that it accepts `customizer` which is
34570 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
34571 * path creation is handled by the method instead. The `customizer` is invoked
34572 * with three arguments: (nsValue, key, nsObject).
34573 *
34574 * **Note:** This method mutates `object`.
34575 *
34576 * @static
34577 * @memberOf _
34578 * @since 4.0.0
34579 * @category Object
34580 * @param {Object} object The object to modify.
34581 * @param {Array|string} path The path of the property to set.
34582 * @param {*} value The value to set.
34583 * @param {Function} [customizer] The function to customize assigned values.
34584 * @returns {Object} Returns `object`.
34585 * @example
34586 *
34587 * var object = {};
34588 *
34589 * _.setWith(object, '[0][1]', 'a', Object);
34590 * // => { '0': { '1': 'a' } }
34591 */
34592 function setWith(object, path, value, customizer) {
34593 customizer = typeof customizer == 'function' ? customizer : undefined$1;
34594 return object == null ? object : baseSet(object, path, value, customizer);
34595 }
34596
34597 /**
34598 * Creates an array of own enumerable string keyed-value pairs for `object`
34599 * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
34600 * entries are returned.
34601 *
34602 * @static
34603 * @memberOf _
34604 * @since 4.0.0
34605 * @alias entries
34606 * @category Object
34607 * @param {Object} object The object to query.
34608 * @returns {Array} Returns the key-value pairs.
34609 * @example
34610 *
34611 * function Foo() {
34612 * this.a = 1;
34613 * this.b = 2;
34614 * }
34615 *
34616 * Foo.prototype.c = 3;
34617 *
34618 * _.toPairs(new Foo);
34619 * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
34620 */
34621 var toPairs = createToPairs(keys);
34622
34623 /**
34624 * Creates an array of own and inherited enumerable string keyed-value pairs
34625 * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
34626 * or set, its entries are returned.
34627 *
34628 * @static
34629 * @memberOf _
34630 * @since 4.0.0
34631 * @alias entriesIn
34632 * @category Object
34633 * @param {Object} object The object to query.
34634 * @returns {Array} Returns the key-value pairs.
34635 * @example
34636 *
34637 * function Foo() {
34638 * this.a = 1;
34639 * this.b = 2;
34640 * }
34641 *
34642 * Foo.prototype.c = 3;
34643 *
34644 * _.toPairsIn(new Foo);
34645 * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
34646 */
34647 var toPairsIn = createToPairs(keysIn);
34648
34649 /**
34650 * An alternative to `_.reduce`; this method transforms `object` to a new
34651 * `accumulator` object which is the result of running each of its own
34652 * enumerable string keyed properties thru `iteratee`, with each invocation
34653 * potentially mutating the `accumulator` object. If `accumulator` is not
34654 * provided, a new object with the same `[[Prototype]]` will be used. The
34655 * iteratee is invoked with four arguments: (accumulator, value, key, object).
34656 * Iteratee functions may exit iteration early by explicitly returning `false`.
34657 *
34658 * @static
34659 * @memberOf _
34660 * @since 1.3.0
34661 * @category Object
34662 * @param {Object} object The object to iterate over.
34663 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
34664 * @param {*} [accumulator] The custom accumulator value.
34665 * @returns {*} Returns the accumulated value.
34666 * @example
34667 *
34668 * _.transform([2, 3, 4], function(result, n) {
34669 * result.push(n *= n);
34670 * return n % 2 == 0;
34671 * }, []);
34672 * // => [4, 9]
34673 *
34674 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
34675 * (result[value] || (result[value] = [])).push(key);
34676 * }, {});
34677 * // => { '1': ['a', 'c'], '2': ['b'] }
34678 */
34679 function transform(object, iteratee, accumulator) {
34680 var isArr = isArray(object),
34681 isArrLike = isArr || isBuffer(object) || isTypedArray(object);
34682
34683 iteratee = getIteratee(iteratee, 4);
34684 if (accumulator == null) {
34685 var Ctor = object && object.constructor;
34686 if (isArrLike) {
34687 accumulator = isArr ? new Ctor : [];
34688 }
34689 else if (isObject(object)) {
34690 accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
34691 }
34692 else {
34693 accumulator = {};
34694 }
34695 }
34696 (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
34697 return iteratee(accumulator, value, index, object);
34698 });
34699 return accumulator;
34700 }
34701
34702 /**
34703 * Removes the property at `path` of `object`.
34704 *
34705 * **Note:** This method mutates `object`.
34706 *
34707 * @static
34708 * @memberOf _
34709 * @since 4.0.0
34710 * @category Object
34711 * @param {Object} object The object to modify.
34712 * @param {Array|string} path The path of the property to unset.
34713 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
34714 * @example
34715 *
34716 * var object = { 'a': [{ 'b': { 'c': 7 } }] };
34717 * _.unset(object, 'a[0].b.c');
34718 * // => true
34719 *
34720 * console.log(object);
34721 * // => { 'a': [{ 'b': {} }] };
34722 *
34723 * _.unset(object, ['a', '0', 'b', 'c']);
34724 * // => true
34725 *
34726 * console.log(object);
34727 * // => { 'a': [{ 'b': {} }] };
34728 */
34729 function unset(object, path) {
34730 return object == null ? true : baseUnset(object, path);
34731 }
34732
34733 /**
34734 * This method is like `_.set` except that accepts `updater` to produce the
34735 * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
34736 * is invoked with one argument: (value).
34737 *
34738 * **Note:** This method mutates `object`.
34739 *
34740 * @static
34741 * @memberOf _
34742 * @since 4.6.0
34743 * @category Object
34744 * @param {Object} object The object to modify.
34745 * @param {Array|string} path The path of the property to set.
34746 * @param {Function} updater The function to produce the updated value.
34747 * @returns {Object} Returns `object`.
34748 * @example
34749 *
34750 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
34751 *
34752 * _.update(object, 'a[0].b.c', function(n) { return n * n; });
34753 * console.log(object.a[0].b.c);
34754 * // => 9
34755 *
34756 * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
34757 * console.log(object.x[0].y.z);
34758 * // => 0
34759 */
34760 function update(object, path, updater) {
34761 return object == null ? object : baseUpdate(object, path, castFunction(updater));
34762 }
34763
34764 /**
34765 * This method is like `_.update` except that it accepts `customizer` which is
34766 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
34767 * path creation is handled by the method instead. The `customizer` is invoked
34768 * with three arguments: (nsValue, key, nsObject).
34769 *
34770 * **Note:** This method mutates `object`.
34771 *
34772 * @static
34773 * @memberOf _
34774 * @since 4.6.0
34775 * @category Object
34776 * @param {Object} object The object to modify.
34777 * @param {Array|string} path The path of the property to set.
34778 * @param {Function} updater The function to produce the updated value.
34779 * @param {Function} [customizer] The function to customize assigned values.
34780 * @returns {Object} Returns `object`.
34781 * @example
34782 *
34783 * var object = {};
34784 *
34785 * _.updateWith(object, '[0][1]', _.constant('a'), Object);
34786 * // => { '0': { '1': 'a' } }
34787 */
34788 function updateWith(object, path, updater, customizer) {
34789 customizer = typeof customizer == 'function' ? customizer : undefined$1;
34790 return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
34791 }
34792
34793 /**
34794 * Creates an array of the own enumerable string keyed property values of `object`.
34795 *
34796 * **Note:** Non-object values are coerced to objects.
34797 *
34798 * @static
34799 * @since 0.1.0
34800 * @memberOf _
34801 * @category Object
34802 * @param {Object} object The object to query.
34803 * @returns {Array} Returns the array of property values.
34804 * @example
34805 *
34806 * function Foo() {
34807 * this.a = 1;
34808 * this.b = 2;
34809 * }
34810 *
34811 * Foo.prototype.c = 3;
34812 *
34813 * _.values(new Foo);
34814 * // => [1, 2] (iteration order is not guaranteed)
34815 *
34816 * _.values('hi');
34817 * // => ['h', 'i']
34818 */
34819 function values(object) {
34820 return object == null ? [] : baseValues(object, keys(object));
34821 }
34822
34823 /**
34824 * Creates an array of the own and inherited enumerable string keyed property
34825 * values of `object`.
34826 *
34827 * **Note:** Non-object values are coerced to objects.
34828 *
34829 * @static
34830 * @memberOf _
34831 * @since 3.0.0
34832 * @category Object
34833 * @param {Object} object The object to query.
34834 * @returns {Array} Returns the array of property values.
34835 * @example
34836 *
34837 * function Foo() {
34838 * this.a = 1;
34839 * this.b = 2;
34840 * }
34841 *
34842 * Foo.prototype.c = 3;
34843 *
34844 * _.valuesIn(new Foo);
34845 * // => [1, 2, 3] (iteration order is not guaranteed)
34846 */
34847 function valuesIn(object) {
34848 return object == null ? [] : baseValues(object, keysIn(object));
34849 }
34850
34851 /*------------------------------------------------------------------------*/
34852
34853 /**
34854 * Clamps `number` within the inclusive `lower` and `upper` bounds.
34855 *
34856 * @static
34857 * @memberOf _
34858 * @since 4.0.0
34859 * @category Number
34860 * @param {number} number The number to clamp.
34861 * @param {number} [lower] The lower bound.
34862 * @param {number} upper The upper bound.
34863 * @returns {number} Returns the clamped number.
34864 * @example
34865 *
34866 * _.clamp(-10, -5, 5);
34867 * // => -5
34868 *
34869 * _.clamp(10, -5, 5);
34870 * // => 5
34871 */
34872 function clamp(number, lower, upper) {
34873 if (upper === undefined$1) {
34874 upper = lower;
34875 lower = undefined$1;
34876 }
34877 if (upper !== undefined$1) {
34878 upper = toNumber(upper);
34879 upper = upper === upper ? upper : 0;
34880 }
34881 if (lower !== undefined$1) {
34882 lower = toNumber(lower);
34883 lower = lower === lower ? lower : 0;
34884 }
34885 return baseClamp(toNumber(number), lower, upper);
34886 }
34887
34888 /**
34889 * Checks if `n` is between `start` and up to, but not including, `end`. If
34890 * `end` is not specified, it's set to `start` with `start` then set to `0`.
34891 * If `start` is greater than `end` the params are swapped to support
34892 * negative ranges.
34893 *
34894 * @static
34895 * @memberOf _
34896 * @since 3.3.0
34897 * @category Number
34898 * @param {number} number The number to check.
34899 * @param {number} [start=0] The start of the range.
34900 * @param {number} end The end of the range.
34901 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
34902 * @see _.range, _.rangeRight
34903 * @example
34904 *
34905 * _.inRange(3, 2, 4);
34906 * // => true
34907 *
34908 * _.inRange(4, 8);
34909 * // => true
34910 *
34911 * _.inRange(4, 2);
34912 * // => false
34913 *
34914 * _.inRange(2, 2);
34915 * // => false
34916 *
34917 * _.inRange(1.2, 2);
34918 * // => true
34919 *
34920 * _.inRange(5.2, 4);
34921 * // => false
34922 *
34923 * _.inRange(-3, -2, -6);
34924 * // => true
34925 */
34926 function inRange(number, start, end) {
34927 start = toFinite(start);
34928 if (end === undefined$1) {
34929 end = start;
34930 start = 0;
34931 } else {
34932 end = toFinite(end);
34933 }
34934 number = toNumber(number);
34935 return baseInRange(number, start, end);
34936 }
34937
34938 /**
34939 * Produces a random number between the inclusive `lower` and `upper` bounds.
34940 * If only one argument is provided a number between `0` and the given number
34941 * is returned. If `floating` is `true`, or either `lower` or `upper` are
34942 * floats, a floating-point number is returned instead of an integer.
34943 *
34944 * **Note:** JavaScript follows the IEEE-754 standard for resolving
34945 * floating-point values which can produce unexpected results.
34946 *
34947 * @static
34948 * @memberOf _
34949 * @since 0.7.0
34950 * @category Number
34951 * @param {number} [lower=0] The lower bound.
34952 * @param {number} [upper=1] The upper bound.
34953 * @param {boolean} [floating] Specify returning a floating-point number.
34954 * @returns {number} Returns the random number.
34955 * @example
34956 *
34957 * _.random(0, 5);
34958 * // => an integer between 0 and 5
34959 *
34960 * _.random(5);
34961 * // => also an integer between 0 and 5
34962 *
34963 * _.random(5, true);
34964 * // => a floating-point number between 0 and 5
34965 *
34966 * _.random(1.2, 5.2);
34967 * // => a floating-point number between 1.2 and 5.2
34968 */
34969 function random(lower, upper, floating) {
34970 if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
34971 upper = floating = undefined$1;
34972 }
34973 if (floating === undefined$1) {
34974 if (typeof upper == 'boolean') {
34975 floating = upper;
34976 upper = undefined$1;
34977 }
34978 else if (typeof lower == 'boolean') {
34979 floating = lower;
34980 lower = undefined$1;
34981 }
34982 }
34983 if (lower === undefined$1 && upper === undefined$1) {
34984 lower = 0;
34985 upper = 1;
34986 }
34987 else {
34988 lower = toFinite(lower);
34989 if (upper === undefined$1) {
34990 upper = lower;
34991 lower = 0;
34992 } else {
34993 upper = toFinite(upper);
34994 }
34995 }
34996 if (lower > upper) {
34997 var temp = lower;
34998 lower = upper;
34999 upper = temp;
35000 }
35001 if (floating || lower % 1 || upper % 1) {
35002 var rand = nativeRandom();
35003 return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
35004 }
35005 return baseRandom(lower, upper);
35006 }
35007
35008 /*------------------------------------------------------------------------*/
35009
35010 /**
35011 * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
35012 *
35013 * @static
35014 * @memberOf _
35015 * @since 3.0.0
35016 * @category String
35017 * @param {string} [string=''] The string to convert.
35018 * @returns {string} Returns the camel cased string.
35019 * @example
35020 *
35021 * _.camelCase('Foo Bar');
35022 * // => 'fooBar'
35023 *
35024 * _.camelCase('--foo-bar--');
35025 * // => 'fooBar'
35026 *
35027 * _.camelCase('__FOO_BAR__');
35028 * // => 'fooBar'
35029 */
35030 var camelCase = createCompounder(function(result, word, index) {
35031 word = word.toLowerCase();
35032 return result + (index ? capitalize(word) : word);
35033 });
35034
35035 /**
35036 * Converts the first character of `string` to upper case and the remaining
35037 * to lower case.
35038 *
35039 * @static
35040 * @memberOf _
35041 * @since 3.0.0
35042 * @category String
35043 * @param {string} [string=''] The string to capitalize.
35044 * @returns {string} Returns the capitalized string.
35045 * @example
35046 *
35047 * _.capitalize('FRED');
35048 * // => 'Fred'
35049 */
35050 function capitalize(string) {
35051 return upperFirst(toString(string).toLowerCase());
35052 }
35053
35054 /**
35055 * Deburrs `string` by converting
35056 * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
35057 * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
35058 * letters to basic Latin letters and removing
35059 * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
35060 *
35061 * @static
35062 * @memberOf _
35063 * @since 3.0.0
35064 * @category String
35065 * @param {string} [string=''] The string to deburr.
35066 * @returns {string} Returns the deburred string.
35067 * @example
35068 *
35069 * _.deburr('déjà vu');
35070 * // => 'deja vu'
35071 */
35072 function deburr(string) {
35073 string = toString(string);
35074 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
35075 }
35076
35077 /**
35078 * Checks if `string` ends with the given target string.
35079 *
35080 * @static
35081 * @memberOf _
35082 * @since 3.0.0
35083 * @category String
35084 * @param {string} [string=''] The string to inspect.
35085 * @param {string} [target] The string to search for.
35086 * @param {number} [position=string.length] The position to search up to.
35087 * @returns {boolean} Returns `true` if `string` ends with `target`,
35088 * else `false`.
35089 * @example
35090 *
35091 * _.endsWith('abc', 'c');
35092 * // => true
35093 *
35094 * _.endsWith('abc', 'b');
35095 * // => false
35096 *
35097 * _.endsWith('abc', 'b', 2);
35098 * // => true
35099 */
35100 function endsWith(string, target, position) {
35101 string = toString(string);
35102 target = baseToString(target);
35103
35104 var length = string.length;
35105 position = position === undefined$1
35106 ? length
35107 : baseClamp(toInteger(position), 0, length);
35108
35109 var end = position;
35110 position -= target.length;
35111 return position >= 0 && string.slice(position, end) == target;
35112 }
35113
35114 /**
35115 * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
35116 * corresponding HTML entities.
35117 *
35118 * **Note:** No other characters are escaped. To escape additional
35119 * characters use a third-party library like [_he_](https://mths.be/he).
35120 *
35121 * Though the ">" character is escaped for symmetry, characters like
35122 * ">" and "/" don't need escaping in HTML and have no special meaning
35123 * unless they're part of a tag or unquoted attribute value. See
35124 * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
35125 * (under "semi-related fun fact") for more details.
35126 *
35127 * When working with HTML you should always
35128 * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
35129 * XSS vectors.
35130 *
35131 * @static
35132 * @since 0.1.0
35133 * @memberOf _
35134 * @category String
35135 * @param {string} [string=''] The string to escape.
35136 * @returns {string} Returns the escaped string.
35137 * @example
35138 *
35139 * _.escape('fred, barney, & pebbles');
35140 * // => 'fred, barney, &amp; pebbles'
35141 */
35142 function escape(string) {
35143 string = toString(string);
35144 return (string && reHasUnescapedHtml.test(string))
35145 ? string.replace(reUnescapedHtml, escapeHtmlChar)
35146 : string;
35147 }
35148
35149 /**
35150 * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
35151 * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
35152 *
35153 * @static
35154 * @memberOf _
35155 * @since 3.0.0
35156 * @category String
35157 * @param {string} [string=''] The string to escape.
35158 * @returns {string} Returns the escaped string.
35159 * @example
35160 *
35161 * _.escapeRegExp('[lodash](https://lodash.com/)');
35162 * // => '\[lodash\]\(https://lodash\.com/\)'
35163 */
35164 function escapeRegExp(string) {
35165 string = toString(string);
35166 return (string && reHasRegExpChar.test(string))
35167 ? string.replace(reRegExpChar, '\\$&')
35168 : string;
35169 }
35170
35171 /**
35172 * Converts `string` to
35173 * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
35174 *
35175 * @static
35176 * @memberOf _
35177 * @since 3.0.0
35178 * @category String
35179 * @param {string} [string=''] The string to convert.
35180 * @returns {string} Returns the kebab cased string.
35181 * @example
35182 *
35183 * _.kebabCase('Foo Bar');
35184 * // => 'foo-bar'
35185 *
35186 * _.kebabCase('fooBar');
35187 * // => 'foo-bar'
35188 *
35189 * _.kebabCase('__FOO_BAR__');
35190 * // => 'foo-bar'
35191 */
35192 var kebabCase = createCompounder(function(result, word, index) {
35193 return result + (index ? '-' : '') + word.toLowerCase();
35194 });
35195
35196 /**
35197 * Converts `string`, as space separated words, to lower case.
35198 *
35199 * @static
35200 * @memberOf _
35201 * @since 4.0.0
35202 * @category String
35203 * @param {string} [string=''] The string to convert.
35204 * @returns {string} Returns the lower cased string.
35205 * @example
35206 *
35207 * _.lowerCase('--Foo-Bar--');
35208 * // => 'foo bar'
35209 *
35210 * _.lowerCase('fooBar');
35211 * // => 'foo bar'
35212 *
35213 * _.lowerCase('__FOO_BAR__');
35214 * // => 'foo bar'
35215 */
35216 var lowerCase = createCompounder(function(result, word, index) {
35217 return result + (index ? ' ' : '') + word.toLowerCase();
35218 });
35219
35220 /**
35221 * Converts the first character of `string` to lower case.
35222 *
35223 * @static
35224 * @memberOf _
35225 * @since 4.0.0
35226 * @category String
35227 * @param {string} [string=''] The string to convert.
35228 * @returns {string} Returns the converted string.
35229 * @example
35230 *
35231 * _.lowerFirst('Fred');
35232 * // => 'fred'
35233 *
35234 * _.lowerFirst('FRED');
35235 * // => 'fRED'
35236 */
35237 var lowerFirst = createCaseFirst('toLowerCase');
35238
35239 /**
35240 * Pads `string` on the left and right sides if it's shorter than `length`.
35241 * Padding characters are truncated if they can't be evenly divided by `length`.
35242 *
35243 * @static
35244 * @memberOf _
35245 * @since 3.0.0
35246 * @category String
35247 * @param {string} [string=''] The string to pad.
35248 * @param {number} [length=0] The padding length.
35249 * @param {string} [chars=' '] The string used as padding.
35250 * @returns {string} Returns the padded string.
35251 * @example
35252 *
35253 * _.pad('abc', 8);
35254 * // => ' abc '
35255 *
35256 * _.pad('abc', 8, '_-');
35257 * // => '_-abc_-_'
35258 *
35259 * _.pad('abc', 3);
35260 * // => 'abc'
35261 */
35262 function pad(string, length, chars) {
35263 string = toString(string);
35264 length = toInteger(length);
35265
35266 var strLength = length ? stringSize(string) : 0;
35267 if (!length || strLength >= length) {
35268 return string;
35269 }
35270 var mid = (length - strLength) / 2;
35271 return (
35272 createPadding(nativeFloor(mid), chars) +
35273 string +
35274 createPadding(nativeCeil(mid), chars)
35275 );
35276 }
35277
35278 /**
35279 * Pads `string` on the right side if it's shorter than `length`. Padding
35280 * characters are truncated if they exceed `length`.
35281 *
35282 * @static
35283 * @memberOf _
35284 * @since 4.0.0
35285 * @category String
35286 * @param {string} [string=''] The string to pad.
35287 * @param {number} [length=0] The padding length.
35288 * @param {string} [chars=' '] The string used as padding.
35289 * @returns {string} Returns the padded string.
35290 * @example
35291 *
35292 * _.padEnd('abc', 6);
35293 * // => 'abc '
35294 *
35295 * _.padEnd('abc', 6, '_-');
35296 * // => 'abc_-_'
35297 *
35298 * _.padEnd('abc', 3);
35299 * // => 'abc'
35300 */
35301 function padEnd(string, length, chars) {
35302 string = toString(string);
35303 length = toInteger(length);
35304
35305 var strLength = length ? stringSize(string) : 0;
35306 return (length && strLength < length)
35307 ? (string + createPadding(length - strLength, chars))
35308 : string;
35309 }
35310
35311 /**
35312 * Pads `string` on the left side if it's shorter than `length`. Padding
35313 * characters are truncated if they exceed `length`.
35314 *
35315 * @static
35316 * @memberOf _
35317 * @since 4.0.0
35318 * @category String
35319 * @param {string} [string=''] The string to pad.
35320 * @param {number} [length=0] The padding length.
35321 * @param {string} [chars=' '] The string used as padding.
35322 * @returns {string} Returns the padded string.
35323 * @example
35324 *
35325 * _.padStart('abc', 6);
35326 * // => ' abc'
35327 *
35328 * _.padStart('abc', 6, '_-');
35329 * // => '_-_abc'
35330 *
35331 * _.padStart('abc', 3);
35332 * // => 'abc'
35333 */
35334 function padStart(string, length, chars) {
35335 string = toString(string);
35336 length = toInteger(length);
35337
35338 var strLength = length ? stringSize(string) : 0;
35339 return (length && strLength < length)
35340 ? (createPadding(length - strLength, chars) + string)
35341 : string;
35342 }
35343
35344 /**
35345 * Converts `string` to an integer of the specified radix. If `radix` is
35346 * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
35347 * hexadecimal, in which case a `radix` of `16` is used.
35348 *
35349 * **Note:** This method aligns with the
35350 * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
35351 *
35352 * @static
35353 * @memberOf _
35354 * @since 1.1.0
35355 * @category String
35356 * @param {string} string The string to convert.
35357 * @param {number} [radix=10] The radix to interpret `value` by.
35358 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35359 * @returns {number} Returns the converted integer.
35360 * @example
35361 *
35362 * _.parseInt('08');
35363 * // => 8
35364 *
35365 * _.map(['6', '08', '10'], _.parseInt);
35366 * // => [6, 8, 10]
35367 */
35368 function parseInt(string, radix, guard) {
35369 if (guard || radix == null) {
35370 radix = 0;
35371 } else if (radix) {
35372 radix = +radix;
35373 }
35374 return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
35375 }
35376
35377 /**
35378 * Repeats the given string `n` times.
35379 *
35380 * @static
35381 * @memberOf _
35382 * @since 3.0.0
35383 * @category String
35384 * @param {string} [string=''] The string to repeat.
35385 * @param {number} [n=1] The number of times to repeat the string.
35386 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35387 * @returns {string} Returns the repeated string.
35388 * @example
35389 *
35390 * _.repeat('*', 3);
35391 * // => '***'
35392 *
35393 * _.repeat('abc', 2);
35394 * // => 'abcabc'
35395 *
35396 * _.repeat('abc', 0);
35397 * // => ''
35398 */
35399 function repeat(string, n, guard) {
35400 if ((guard ? isIterateeCall(string, n, guard) : n === undefined$1)) {
35401 n = 1;
35402 } else {
35403 n = toInteger(n);
35404 }
35405 return baseRepeat(toString(string), n);
35406 }
35407
35408 /**
35409 * Replaces matches for `pattern` in `string` with `replacement`.
35410 *
35411 * **Note:** This method is based on
35412 * [`String#replace`](https://mdn.io/String/replace).
35413 *
35414 * @static
35415 * @memberOf _
35416 * @since 4.0.0
35417 * @category String
35418 * @param {string} [string=''] The string to modify.
35419 * @param {RegExp|string} pattern The pattern to replace.
35420 * @param {Function|string} replacement The match replacement.
35421 * @returns {string} Returns the modified string.
35422 * @example
35423 *
35424 * _.replace('Hi Fred', 'Fred', 'Barney');
35425 * // => 'Hi Barney'
35426 */
35427 function replace() {
35428 var args = arguments,
35429 string = toString(args[0]);
35430
35431 return args.length < 3 ? string : string.replace(args[1], args[2]);
35432 }
35433
35434 /**
35435 * Converts `string` to
35436 * [snake case](https://en.wikipedia.org/wiki/Snake_case).
35437 *
35438 * @static
35439 * @memberOf _
35440 * @since 3.0.0
35441 * @category String
35442 * @param {string} [string=''] The string to convert.
35443 * @returns {string} Returns the snake cased string.
35444 * @example
35445 *
35446 * _.snakeCase('Foo Bar');
35447 * // => 'foo_bar'
35448 *
35449 * _.snakeCase('fooBar');
35450 * // => 'foo_bar'
35451 *
35452 * _.snakeCase('--FOO-BAR--');
35453 * // => 'foo_bar'
35454 */
35455 var snakeCase = createCompounder(function(result, word, index) {
35456 return result + (index ? '_' : '') + word.toLowerCase();
35457 });
35458
35459 /**
35460 * Splits `string` by `separator`.
35461 *
35462 * **Note:** This method is based on
35463 * [`String#split`](https://mdn.io/String/split).
35464 *
35465 * @static
35466 * @memberOf _
35467 * @since 4.0.0
35468 * @category String
35469 * @param {string} [string=''] The string to split.
35470 * @param {RegExp|string} separator The separator pattern to split by.
35471 * @param {number} [limit] The length to truncate results to.
35472 * @returns {Array} Returns the string segments.
35473 * @example
35474 *
35475 * _.split('a-b-c', '-', 2);
35476 * // => ['a', 'b']
35477 */
35478 function split(string, separator, limit) {
35479 if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
35480 separator = limit = undefined$1;
35481 }
35482 limit = limit === undefined$1 ? MAX_ARRAY_LENGTH : limit >>> 0;
35483 if (!limit) {
35484 return [];
35485 }
35486 string = toString(string);
35487 if (string && (
35488 typeof separator == 'string' ||
35489 (separator != null && !isRegExp(separator))
35490 )) {
35491 separator = baseToString(separator);
35492 if (!separator && hasUnicode(string)) {
35493 return castSlice(stringToArray(string), 0, limit);
35494 }
35495 }
35496 return string.split(separator, limit);
35497 }
35498
35499 /**
35500 * Converts `string` to
35501 * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
35502 *
35503 * @static
35504 * @memberOf _
35505 * @since 3.1.0
35506 * @category String
35507 * @param {string} [string=''] The string to convert.
35508 * @returns {string} Returns the start cased string.
35509 * @example
35510 *
35511 * _.startCase('--foo-bar--');
35512 * // => 'Foo Bar'
35513 *
35514 * _.startCase('fooBar');
35515 * // => 'Foo Bar'
35516 *
35517 * _.startCase('__FOO_BAR__');
35518 * // => 'FOO BAR'
35519 */
35520 var startCase = createCompounder(function(result, word, index) {
35521 return result + (index ? ' ' : '') + upperFirst(word);
35522 });
35523
35524 /**
35525 * Checks if `string` starts with the given target string.
35526 *
35527 * @static
35528 * @memberOf _
35529 * @since 3.0.0
35530 * @category String
35531 * @param {string} [string=''] The string to inspect.
35532 * @param {string} [target] The string to search for.
35533 * @param {number} [position=0] The position to search from.
35534 * @returns {boolean} Returns `true` if `string` starts with `target`,
35535 * else `false`.
35536 * @example
35537 *
35538 * _.startsWith('abc', 'a');
35539 * // => true
35540 *
35541 * _.startsWith('abc', 'b');
35542 * // => false
35543 *
35544 * _.startsWith('abc', 'b', 1);
35545 * // => true
35546 */
35547 function startsWith(string, target, position) {
35548 string = toString(string);
35549 position = position == null
35550 ? 0
35551 : baseClamp(toInteger(position), 0, string.length);
35552
35553 target = baseToString(target);
35554 return string.slice(position, position + target.length) == target;
35555 }
35556
35557 /**
35558 * Creates a compiled template function that can interpolate data properties
35559 * in "interpolate" delimiters, HTML-escape interpolated data properties in
35560 * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
35561 * properties may be accessed as free variables in the template. If a setting
35562 * object is given, it takes precedence over `_.templateSettings` values.
35563 *
35564 * **Note:** In the development build `_.template` utilizes
35565 * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
35566 * for easier debugging.
35567 *
35568 * For more information on precompiling templates see
35569 * [lodash's custom builds documentation](https://lodash.com/custom-builds).
35570 *
35571 * For more information on Chrome extension sandboxes see
35572 * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
35573 *
35574 * @static
35575 * @since 0.1.0
35576 * @memberOf _
35577 * @category String
35578 * @param {string} [string=''] The template string.
35579 * @param {Object} [options={}] The options object.
35580 * @param {RegExp} [options.escape=_.templateSettings.escape]
35581 * The HTML "escape" delimiter.
35582 * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
35583 * The "evaluate" delimiter.
35584 * @param {Object} [options.imports=_.templateSettings.imports]
35585 * An object to import into the template as free variables.
35586 * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
35587 * The "interpolate" delimiter.
35588 * @param {string} [options.sourceURL='lodash.templateSources[n]']
35589 * The sourceURL of the compiled template.
35590 * @param {string} [options.variable='obj']
35591 * The data object variable name.
35592 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35593 * @returns {Function} Returns the compiled template function.
35594 * @example
35595 *
35596 * // Use the "interpolate" delimiter to create a compiled template.
35597 * var compiled = _.template('hello <%= user %>!');
35598 * compiled({ 'user': 'fred' });
35599 * // => 'hello fred!'
35600 *
35601 * // Use the HTML "escape" delimiter to escape data property values.
35602 * var compiled = _.template('<b><%- value %></b>');
35603 * compiled({ 'value': '<script>' });
35604 * // => '<b>&lt;script&gt;</b>'
35605 *
35606 * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
35607 * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
35608 * compiled({ 'users': ['fred', 'barney'] });
35609 * // => '<li>fred</li><li>barney</li>'
35610 *
35611 * // Use the internal `print` function in "evaluate" delimiters.
35612 * var compiled = _.template('<% print("hello " + user); %>!');
35613 * compiled({ 'user': 'barney' });
35614 * // => 'hello barney!'
35615 *
35616 * // Use the ES template literal delimiter as an "interpolate" delimiter.
35617 * // Disable support by replacing the "interpolate" delimiter.
35618 * var compiled = _.template('hello ${ user }!');
35619 * compiled({ 'user': 'pebbles' });
35620 * // => 'hello pebbles!'
35621 *
35622 * // Use backslashes to treat delimiters as plain text.
35623 * var compiled = _.template('<%= "\\<%- value %\\>" %>');
35624 * compiled({ 'value': 'ignored' });
35625 * // => '<%- value %>'
35626 *
35627 * // Use the `imports` option to import `jQuery` as `jq`.
35628 * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
35629 * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
35630 * compiled({ 'users': ['fred', 'barney'] });
35631 * // => '<li>fred</li><li>barney</li>'
35632 *
35633 * // Use the `sourceURL` option to specify a custom sourceURL for the template.
35634 * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
35635 * compiled(data);
35636 * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
35637 *
35638 * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
35639 * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
35640 * compiled.source;
35641 * // => function(data) {
35642 * // var __t, __p = '';
35643 * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
35644 * // return __p;
35645 * // }
35646 *
35647 * // Use custom template delimiters.
35648 * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
35649 * var compiled = _.template('hello {{ user }}!');
35650 * compiled({ 'user': 'mustache' });
35651 * // => 'hello mustache!'
35652 *
35653 * // Use the `source` property to inline compiled templates for meaningful
35654 * // line numbers in error messages and stack traces.
35655 * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
35656 * var JST = {\
35657 * "main": ' + _.template(mainText).source + '\
35658 * };\
35659 * ');
35660 */
35661 function template(string, options, guard) {
35662 // Based on John Resig's `tmpl` implementation
35663 // (http://ejohn.org/blog/javascript-micro-templating/)
35664 // and Laura Doktorova's doT.js (https://github.com/olado/doT).
35665 var settings = lodash.templateSettings;
35666
35667 if (guard && isIterateeCall(string, options, guard)) {
35668 options = undefined$1;
35669 }
35670 string = toString(string);
35671 options = assignInWith({}, options, settings, customDefaultsAssignIn);
35672
35673 var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
35674 importsKeys = keys(imports),
35675 importsValues = baseValues(imports, importsKeys);
35676
35677 var isEscaping,
35678 isEvaluating,
35679 index = 0,
35680 interpolate = options.interpolate || reNoMatch,
35681 source = "__p += '";
35682
35683 // Compile the regexp to match each delimiter.
35684 var reDelimiters = RegExp(
35685 (options.escape || reNoMatch).source + '|' +
35686 interpolate.source + '|' +
35687 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
35688 (options.evaluate || reNoMatch).source + '|$'
35689 , 'g');
35690
35691 // Use a sourceURL for easier debugging.
35692 // The sourceURL gets injected into the source that's eval-ed, so be careful
35693 // with lookup (in case of e.g. prototype pollution), and strip newlines if any.
35694 // A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection.
35695 var sourceURL = '//# sourceURL=' +
35696 (hasOwnProperty.call(options, 'sourceURL')
35697 ? (options.sourceURL + '').replace(/[\r\n]/g, ' ')
35698 : ('lodash.templateSources[' + (++templateCounter) + ']')
35699 ) + '\n';
35700
35701 string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
35702 interpolateValue || (interpolateValue = esTemplateValue);
35703
35704 // Escape characters that can't be included in string literals.
35705 source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
35706
35707 // Replace delimiters with snippets.
35708 if (escapeValue) {
35709 isEscaping = true;
35710 source += "' +\n__e(" + escapeValue + ") +\n'";
35711 }
35712 if (evaluateValue) {
35713 isEvaluating = true;
35714 source += "';\n" + evaluateValue + ";\n__p += '";
35715 }
35716 if (interpolateValue) {
35717 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
35718 }
35719 index = offset + match.length;
35720
35721 // The JS engine embedded in Adobe products needs `match` returned in
35722 // order to produce the correct `offset` value.
35723 return match;
35724 });
35725
35726 source += "';\n";
35727
35728 // If `variable` is not specified wrap a with-statement around the generated
35729 // code to add the data object to the top of the scope chain.
35730 // Like with sourceURL, we take care to not check the option's prototype,
35731 // as this configuration is a code injection vector.
35732 var variable = hasOwnProperty.call(options, 'variable') && options.variable;
35733 if (!variable) {
35734 source = 'with (obj) {\n' + source + '\n}\n';
35735 }
35736 // Cleanup code by stripping empty strings.
35737 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
35738 .replace(reEmptyStringMiddle, '$1')
35739 .replace(reEmptyStringTrailing, '$1;');
35740
35741 // Frame code as the function body.
35742 source = 'function(' + (variable || 'obj') + ') {\n' +
35743 (variable
35744 ? ''
35745 : 'obj || (obj = {});\n'
35746 ) +
35747 "var __t, __p = ''" +
35748 (isEscaping
35749 ? ', __e = _.escape'
35750 : ''
35751 ) +
35752 (isEvaluating
35753 ? ', __j = Array.prototype.join;\n' +
35754 "function print() { __p += __j.call(arguments, '') }\n"
35755 : ';\n'
35756 ) +
35757 source +
35758 'return __p\n}';
35759
35760 var result = attempt(function() {
35761 return Function(importsKeys, sourceURL + 'return ' + source)
35762 .apply(undefined$1, importsValues);
35763 });
35764
35765 // Provide the compiled function's source by its `toString` method or
35766 // the `source` property as a convenience for inlining compiled templates.
35767 result.source = source;
35768 if (isError(result)) {
35769 throw result;
35770 }
35771 return result;
35772 }
35773
35774 /**
35775 * Converts `string`, as a whole, to lower case just like
35776 * [String#toLowerCase](https://mdn.io/toLowerCase).
35777 *
35778 * @static
35779 * @memberOf _
35780 * @since 4.0.0
35781 * @category String
35782 * @param {string} [string=''] The string to convert.
35783 * @returns {string} Returns the lower cased string.
35784 * @example
35785 *
35786 * _.toLower('--Foo-Bar--');
35787 * // => '--foo-bar--'
35788 *
35789 * _.toLower('fooBar');
35790 * // => 'foobar'
35791 *
35792 * _.toLower('__FOO_BAR__');
35793 * // => '__foo_bar__'
35794 */
35795 function toLower(value) {
35796 return toString(value).toLowerCase();
35797 }
35798
35799 /**
35800 * Converts `string`, as a whole, to upper case just like
35801 * [String#toUpperCase](https://mdn.io/toUpperCase).
35802 *
35803 * @static
35804 * @memberOf _
35805 * @since 4.0.0
35806 * @category String
35807 * @param {string} [string=''] The string to convert.
35808 * @returns {string} Returns the upper cased string.
35809 * @example
35810 *
35811 * _.toUpper('--foo-bar--');
35812 * // => '--FOO-BAR--'
35813 *
35814 * _.toUpper('fooBar');
35815 * // => 'FOOBAR'
35816 *
35817 * _.toUpper('__foo_bar__');
35818 * // => '__FOO_BAR__'
35819 */
35820 function toUpper(value) {
35821 return toString(value).toUpperCase();
35822 }
35823
35824 /**
35825 * Removes leading and trailing whitespace or specified characters from `string`.
35826 *
35827 * @static
35828 * @memberOf _
35829 * @since 3.0.0
35830 * @category String
35831 * @param {string} [string=''] The string to trim.
35832 * @param {string} [chars=whitespace] The characters to trim.
35833 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35834 * @returns {string} Returns the trimmed string.
35835 * @example
35836 *
35837 * _.trim(' abc ');
35838 * // => 'abc'
35839 *
35840 * _.trim('-_-abc-_-', '_-');
35841 * // => 'abc'
35842 *
35843 * _.map([' foo ', ' bar '], _.trim);
35844 * // => ['foo', 'bar']
35845 */
35846 function trim(string, chars, guard) {
35847 string = toString(string);
35848 if (string && (guard || chars === undefined$1)) {
35849 return string.replace(reTrim, '');
35850 }
35851 if (!string || !(chars = baseToString(chars))) {
35852 return string;
35853 }
35854 var strSymbols = stringToArray(string),
35855 chrSymbols = stringToArray(chars),
35856 start = charsStartIndex(strSymbols, chrSymbols),
35857 end = charsEndIndex(strSymbols, chrSymbols) + 1;
35858
35859 return castSlice(strSymbols, start, end).join('');
35860 }
35861
35862 /**
35863 * Removes trailing whitespace or specified characters from `string`.
35864 *
35865 * @static
35866 * @memberOf _
35867 * @since 4.0.0
35868 * @category String
35869 * @param {string} [string=''] The string to trim.
35870 * @param {string} [chars=whitespace] The characters to trim.
35871 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35872 * @returns {string} Returns the trimmed string.
35873 * @example
35874 *
35875 * _.trimEnd(' abc ');
35876 * // => ' abc'
35877 *
35878 * _.trimEnd('-_-abc-_-', '_-');
35879 * // => '-_-abc'
35880 */
35881 function trimEnd(string, chars, guard) {
35882 string = toString(string);
35883 if (string && (guard || chars === undefined$1)) {
35884 return string.replace(reTrimEnd, '');
35885 }
35886 if (!string || !(chars = baseToString(chars))) {
35887 return string;
35888 }
35889 var strSymbols = stringToArray(string),
35890 end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
35891
35892 return castSlice(strSymbols, 0, end).join('');
35893 }
35894
35895 /**
35896 * Removes leading whitespace or specified characters from `string`.
35897 *
35898 * @static
35899 * @memberOf _
35900 * @since 4.0.0
35901 * @category String
35902 * @param {string} [string=''] The string to trim.
35903 * @param {string} [chars=whitespace] The characters to trim.
35904 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35905 * @returns {string} Returns the trimmed string.
35906 * @example
35907 *
35908 * _.trimStart(' abc ');
35909 * // => 'abc '
35910 *
35911 * _.trimStart('-_-abc-_-', '_-');
35912 * // => 'abc-_-'
35913 */
35914 function trimStart(string, chars, guard) {
35915 string = toString(string);
35916 if (string && (guard || chars === undefined$1)) {
35917 return string.replace(reTrimStart, '');
35918 }
35919 if (!string || !(chars = baseToString(chars))) {
35920 return string;
35921 }
35922 var strSymbols = stringToArray(string),
35923 start = charsStartIndex(strSymbols, stringToArray(chars));
35924
35925 return castSlice(strSymbols, start).join('');
35926 }
35927
35928 /**
35929 * Truncates `string` if it's longer than the given maximum string length.
35930 * The last characters of the truncated string are replaced with the omission
35931 * string which defaults to "...".
35932 *
35933 * @static
35934 * @memberOf _
35935 * @since 4.0.0
35936 * @category String
35937 * @param {string} [string=''] The string to truncate.
35938 * @param {Object} [options={}] The options object.
35939 * @param {number} [options.length=30] The maximum string length.
35940 * @param {string} [options.omission='...'] The string to indicate text is omitted.
35941 * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
35942 * @returns {string} Returns the truncated string.
35943 * @example
35944 *
35945 * _.truncate('hi-diddly-ho there, neighborino');
35946 * // => 'hi-diddly-ho there, neighbo...'
35947 *
35948 * _.truncate('hi-diddly-ho there, neighborino', {
35949 * 'length': 24,
35950 * 'separator': ' '
35951 * });
35952 * // => 'hi-diddly-ho there,...'
35953 *
35954 * _.truncate('hi-diddly-ho there, neighborino', {
35955 * 'length': 24,
35956 * 'separator': /,? +/
35957 * });
35958 * // => 'hi-diddly-ho there...'
35959 *
35960 * _.truncate('hi-diddly-ho there, neighborino', {
35961 * 'omission': ' [...]'
35962 * });
35963 * // => 'hi-diddly-ho there, neig [...]'
35964 */
35965 function truncate(string, options) {
35966 var length = DEFAULT_TRUNC_LENGTH,
35967 omission = DEFAULT_TRUNC_OMISSION;
35968
35969 if (isObject(options)) {
35970 var separator = 'separator' in options ? options.separator : separator;
35971 length = 'length' in options ? toInteger(options.length) : length;
35972 omission = 'omission' in options ? baseToString(options.omission) : omission;
35973 }
35974 string = toString(string);
35975
35976 var strLength = string.length;
35977 if (hasUnicode(string)) {
35978 var strSymbols = stringToArray(string);
35979 strLength = strSymbols.length;
35980 }
35981 if (length >= strLength) {
35982 return string;
35983 }
35984 var end = length - stringSize(omission);
35985 if (end < 1) {
35986 return omission;
35987 }
35988 var result = strSymbols
35989 ? castSlice(strSymbols, 0, end).join('')
35990 : string.slice(0, end);
35991
35992 if (separator === undefined$1) {
35993 return result + omission;
35994 }
35995 if (strSymbols) {
35996 end += (result.length - end);
35997 }
35998 if (isRegExp(separator)) {
35999 if (string.slice(end).search(separator)) {
36000 var match,
36001 substring = result;
36002
36003 if (!separator.global) {
36004 separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
36005 }
36006 separator.lastIndex = 0;
36007 while ((match = separator.exec(substring))) {
36008 var newEnd = match.index;
36009 }
36010 result = result.slice(0, newEnd === undefined$1 ? end : newEnd);
36011 }
36012 } else if (string.indexOf(baseToString(separator), end) != end) {
36013 var index = result.lastIndexOf(separator);
36014 if (index > -1) {
36015 result = result.slice(0, index);
36016 }
36017 }
36018 return result + omission;
36019 }
36020
36021 /**
36022 * The inverse of `_.escape`; this method converts the HTML entities
36023 * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
36024 * their corresponding characters.
36025 *
36026 * **Note:** No other HTML entities are unescaped. To unescape additional
36027 * HTML entities use a third-party library like [_he_](https://mths.be/he).
36028 *
36029 * @static
36030 * @memberOf _
36031 * @since 0.6.0
36032 * @category String
36033 * @param {string} [string=''] The string to unescape.
36034 * @returns {string} Returns the unescaped string.
36035 * @example
36036 *
36037 * _.unescape('fred, barney, &amp; pebbles');
36038 * // => 'fred, barney, & pebbles'
36039 */
36040 function unescape(string) {
36041 string = toString(string);
36042 return (string && reHasEscapedHtml.test(string))
36043 ? string.replace(reEscapedHtml, unescapeHtmlChar)
36044 : string;
36045 }
36046
36047 /**
36048 * Converts `string`, as space separated words, to upper case.
36049 *
36050 * @static
36051 * @memberOf _
36052 * @since 4.0.0
36053 * @category String
36054 * @param {string} [string=''] The string to convert.
36055 * @returns {string} Returns the upper cased string.
36056 * @example
36057 *
36058 * _.upperCase('--foo-bar');
36059 * // => 'FOO BAR'
36060 *
36061 * _.upperCase('fooBar');
36062 * // => 'FOO BAR'
36063 *
36064 * _.upperCase('__foo_bar__');
36065 * // => 'FOO BAR'
36066 */
36067 var upperCase = createCompounder(function(result, word, index) {
36068 return result + (index ? ' ' : '') + word.toUpperCase();
36069 });
36070
36071 /**
36072 * Converts the first character of `string` to upper case.
36073 *
36074 * @static
36075 * @memberOf _
36076 * @since 4.0.0
36077 * @category String
36078 * @param {string} [string=''] The string to convert.
36079 * @returns {string} Returns the converted string.
36080 * @example
36081 *
36082 * _.upperFirst('fred');
36083 * // => 'Fred'
36084 *
36085 * _.upperFirst('FRED');
36086 * // => 'FRED'
36087 */
36088 var upperFirst = createCaseFirst('toUpperCase');
36089
36090 /**
36091 * Splits `string` into an array of its words.
36092 *
36093 * @static
36094 * @memberOf _
36095 * @since 3.0.0
36096 * @category String
36097 * @param {string} [string=''] The string to inspect.
36098 * @param {RegExp|string} [pattern] The pattern to match words.
36099 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
36100 * @returns {Array} Returns the words of `string`.
36101 * @example
36102 *
36103 * _.words('fred, barney, & pebbles');
36104 * // => ['fred', 'barney', 'pebbles']
36105 *
36106 * _.words('fred, barney, & pebbles', /[^, ]+/g);
36107 * // => ['fred', 'barney', '&', 'pebbles']
36108 */
36109 function words(string, pattern, guard) {
36110 string = toString(string);
36111 pattern = guard ? undefined$1 : pattern;
36112
36113 if (pattern === undefined$1) {
36114 return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
36115 }
36116 return string.match(pattern) || [];
36117 }
36118
36119 /*------------------------------------------------------------------------*/
36120
36121 /**
36122 * Attempts to invoke `func`, returning either the result or the caught error
36123 * object. Any additional arguments are provided to `func` when it's invoked.
36124 *
36125 * @static
36126 * @memberOf _
36127 * @since 3.0.0
36128 * @category Util
36129 * @param {Function} func The function to attempt.
36130 * @param {...*} [args] The arguments to invoke `func` with.
36131 * @returns {*} Returns the `func` result or error object.
36132 * @example
36133 *
36134 * // Avoid throwing errors for invalid selectors.
36135 * var elements = _.attempt(function(selector) {
36136 * return document.querySelectorAll(selector);
36137 * }, '>_>');
36138 *
36139 * if (_.isError(elements)) {
36140 * elements = [];
36141 * }
36142 */
36143 var attempt = baseRest(function(func, args) {
36144 try {
36145 return apply(func, undefined$1, args);
36146 } catch (e) {
36147 return isError(e) ? e : new Error(e);
36148 }
36149 });
36150
36151 /**
36152 * Binds methods of an object to the object itself, overwriting the existing
36153 * method.
36154 *
36155 * **Note:** This method doesn't set the "length" property of bound functions.
36156 *
36157 * @static
36158 * @since 0.1.0
36159 * @memberOf _
36160 * @category Util
36161 * @param {Object} object The object to bind and assign the bound methods to.
36162 * @param {...(string|string[])} methodNames The object method names to bind.
36163 * @returns {Object} Returns `object`.
36164 * @example
36165 *
36166 * var view = {
36167 * 'label': 'docs',
36168 * 'click': function() {
36169 * console.log('clicked ' + this.label);
36170 * }
36171 * };
36172 *
36173 * _.bindAll(view, ['click']);
36174 * jQuery(element).on('click', view.click);
36175 * // => Logs 'clicked docs' when clicked.
36176 */
36177 var bindAll = flatRest(function(object, methodNames) {
36178 arrayEach(methodNames, function(key) {
36179 key = toKey(key);
36180 baseAssignValue(object, key, bind(object[key], object));
36181 });
36182 return object;
36183 });
36184
36185 /**
36186 * Creates a function that iterates over `pairs` and invokes the corresponding
36187 * function of the first predicate to return truthy. The predicate-function
36188 * pairs are invoked with the `this` binding and arguments of the created
36189 * function.
36190 *
36191 * @static
36192 * @memberOf _
36193 * @since 4.0.0
36194 * @category Util
36195 * @param {Array} pairs The predicate-function pairs.
36196 * @returns {Function} Returns the new composite function.
36197 * @example
36198 *
36199 * var func = _.cond([
36200 * [_.matches({ 'a': 1 }), _.constant('matches A')],
36201 * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
36202 * [_.stubTrue, _.constant('no match')]
36203 * ]);
36204 *
36205 * func({ 'a': 1, 'b': 2 });
36206 * // => 'matches A'
36207 *
36208 * func({ 'a': 0, 'b': 1 });
36209 * // => 'matches B'
36210 *
36211 * func({ 'a': '1', 'b': '2' });
36212 * // => 'no match'
36213 */
36214 function cond(pairs) {
36215 var length = pairs == null ? 0 : pairs.length,
36216 toIteratee = getIteratee();
36217
36218 pairs = !length ? [] : arrayMap(pairs, function(pair) {
36219 if (typeof pair[1] != 'function') {
36220 throw new Error(FUNC_ERROR_TEXT);
36221 }
36222 return [toIteratee(pair[0]), pair[1]];
36223 });
36224
36225 return baseRest(function(args) {
36226 var index = -1;
36227 while (++index < length) {
36228 var pair = pairs[index];
36229 if (apply(pair[0], this, args)) {
36230 return apply(pair[1], this, args);
36231 }
36232 }
36233 });
36234 }
36235
36236 /**
36237 * Creates a function that invokes the predicate properties of `source` with
36238 * the corresponding property values of a given object, returning `true` if
36239 * all predicates return truthy, else `false`.
36240 *
36241 * **Note:** The created function is equivalent to `_.conformsTo` with
36242 * `source` partially applied.
36243 *
36244 * @static
36245 * @memberOf _
36246 * @since 4.0.0
36247 * @category Util
36248 * @param {Object} source The object of property predicates to conform to.
36249 * @returns {Function} Returns the new spec function.
36250 * @example
36251 *
36252 * var objects = [
36253 * { 'a': 2, 'b': 1 },
36254 * { 'a': 1, 'b': 2 }
36255 * ];
36256 *
36257 * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
36258 * // => [{ 'a': 1, 'b': 2 }]
36259 */
36260 function conforms(source) {
36261 return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
36262 }
36263
36264 /**
36265 * Creates a function that returns `value`.
36266 *
36267 * @static
36268 * @memberOf _
36269 * @since 2.4.0
36270 * @category Util
36271 * @param {*} value The value to return from the new function.
36272 * @returns {Function} Returns the new constant function.
36273 * @example
36274 *
36275 * var objects = _.times(2, _.constant({ 'a': 1 }));
36276 *
36277 * console.log(objects);
36278 * // => [{ 'a': 1 }, { 'a': 1 }]
36279 *
36280 * console.log(objects[0] === objects[1]);
36281 * // => true
36282 */
36283 function constant(value) {
36284 return function() {
36285 return value;
36286 };
36287 }
36288
36289 /**
36290 * Checks `value` to determine whether a default value should be returned in
36291 * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
36292 * or `undefined`.
36293 *
36294 * @static
36295 * @memberOf _
36296 * @since 4.14.0
36297 * @category Util
36298 * @param {*} value The value to check.
36299 * @param {*} defaultValue The default value.
36300 * @returns {*} Returns the resolved value.
36301 * @example
36302 *
36303 * _.defaultTo(1, 10);
36304 * // => 1
36305 *
36306 * _.defaultTo(undefined, 10);
36307 * // => 10
36308 */
36309 function defaultTo(value, defaultValue) {
36310 return (value == null || value !== value) ? defaultValue : value;
36311 }
36312
36313 /**
36314 * Creates a function that returns the result of invoking the given functions
36315 * with the `this` binding of the created function, where each successive
36316 * invocation is supplied the return value of the previous.
36317 *
36318 * @static
36319 * @memberOf _
36320 * @since 3.0.0
36321 * @category Util
36322 * @param {...(Function|Function[])} [funcs] The functions to invoke.
36323 * @returns {Function} Returns the new composite function.
36324 * @see _.flowRight
36325 * @example
36326 *
36327 * function square(n) {
36328 * return n * n;
36329 * }
36330 *
36331 * var addSquare = _.flow([_.add, square]);
36332 * addSquare(1, 2);
36333 * // => 9
36334 */
36335 var flow = createFlow();
36336
36337 /**
36338 * This method is like `_.flow` except that it creates a function that
36339 * invokes the given functions from right to left.
36340 *
36341 * @static
36342 * @since 3.0.0
36343 * @memberOf _
36344 * @category Util
36345 * @param {...(Function|Function[])} [funcs] The functions to invoke.
36346 * @returns {Function} Returns the new composite function.
36347 * @see _.flow
36348 * @example
36349 *
36350 * function square(n) {
36351 * return n * n;
36352 * }
36353 *
36354 * var addSquare = _.flowRight([square, _.add]);
36355 * addSquare(1, 2);
36356 * // => 9
36357 */
36358 var flowRight = createFlow(true);
36359
36360 /**
36361 * This method returns the first argument it receives.
36362 *
36363 * @static
36364 * @since 0.1.0
36365 * @memberOf _
36366 * @category Util
36367 * @param {*} value Any value.
36368 * @returns {*} Returns `value`.
36369 * @example
36370 *
36371 * var object = { 'a': 1 };
36372 *
36373 * console.log(_.identity(object) === object);
36374 * // => true
36375 */
36376 function identity(value) {
36377 return value;
36378 }
36379
36380 /**
36381 * Creates a function that invokes `func` with the arguments of the created
36382 * function. If `func` is a property name, the created function returns the
36383 * property value for a given element. If `func` is an array or object, the
36384 * created function returns `true` for elements that contain the equivalent
36385 * source properties, otherwise it returns `false`.
36386 *
36387 * @static
36388 * @since 4.0.0
36389 * @memberOf _
36390 * @category Util
36391 * @param {*} [func=_.identity] The value to convert to a callback.
36392 * @returns {Function} Returns the callback.
36393 * @example
36394 *
36395 * var users = [
36396 * { 'user': 'barney', 'age': 36, 'active': true },
36397 * { 'user': 'fred', 'age': 40, 'active': false }
36398 * ];
36399 *
36400 * // The `_.matches` iteratee shorthand.
36401 * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
36402 * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
36403 *
36404 * // The `_.matchesProperty` iteratee shorthand.
36405 * _.filter(users, _.iteratee(['user', 'fred']));
36406 * // => [{ 'user': 'fred', 'age': 40 }]
36407 *
36408 * // The `_.property` iteratee shorthand.
36409 * _.map(users, _.iteratee('user'));
36410 * // => ['barney', 'fred']
36411 *
36412 * // Create custom iteratee shorthands.
36413 * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
36414 * return !_.isRegExp(func) ? iteratee(func) : function(string) {
36415 * return func.test(string);
36416 * };
36417 * });
36418 *
36419 * _.filter(['abc', 'def'], /ef/);
36420 * // => ['def']
36421 */
36422 function iteratee(func) {
36423 return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
36424 }
36425
36426 /**
36427 * Creates a function that performs a partial deep comparison between a given
36428 * object and `source`, returning `true` if the given object has equivalent
36429 * property values, else `false`.
36430 *
36431 * **Note:** The created function is equivalent to `_.isMatch` with `source`
36432 * partially applied.
36433 *
36434 * Partial comparisons will match empty array and empty object `source`
36435 * values against any array or object value, respectively. See `_.isEqual`
36436 * for a list of supported value comparisons.
36437 *
36438 * @static
36439 * @memberOf _
36440 * @since 3.0.0
36441 * @category Util
36442 * @param {Object} source The object of property values to match.
36443 * @returns {Function} Returns the new spec function.
36444 * @example
36445 *
36446 * var objects = [
36447 * { 'a': 1, 'b': 2, 'c': 3 },
36448 * { 'a': 4, 'b': 5, 'c': 6 }
36449 * ];
36450 *
36451 * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
36452 * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
36453 */
36454 function matches(source) {
36455 return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
36456 }
36457
36458 /**
36459 * Creates a function that performs a partial deep comparison between the
36460 * value at `path` of a given object to `srcValue`, returning `true` if the
36461 * object value is equivalent, else `false`.
36462 *
36463 * **Note:** Partial comparisons will match empty array and empty object
36464 * `srcValue` values against any array or object value, respectively. See
36465 * `_.isEqual` for a list of supported value comparisons.
36466 *
36467 * @static
36468 * @memberOf _
36469 * @since 3.2.0
36470 * @category Util
36471 * @param {Array|string} path The path of the property to get.
36472 * @param {*} srcValue The value to match.
36473 * @returns {Function} Returns the new spec function.
36474 * @example
36475 *
36476 * var objects = [
36477 * { 'a': 1, 'b': 2, 'c': 3 },
36478 * { 'a': 4, 'b': 5, 'c': 6 }
36479 * ];
36480 *
36481 * _.find(objects, _.matchesProperty('a', 4));
36482 * // => { 'a': 4, 'b': 5, 'c': 6 }
36483 */
36484 function matchesProperty(path, srcValue) {
36485 return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
36486 }
36487
36488 /**
36489 * Creates a function that invokes the method at `path` of a given object.
36490 * Any additional arguments are provided to the invoked method.
36491 *
36492 * @static
36493 * @memberOf _
36494 * @since 3.7.0
36495 * @category Util
36496 * @param {Array|string} path The path of the method to invoke.
36497 * @param {...*} [args] The arguments to invoke the method with.
36498 * @returns {Function} Returns the new invoker function.
36499 * @example
36500 *
36501 * var objects = [
36502 * { 'a': { 'b': _.constant(2) } },
36503 * { 'a': { 'b': _.constant(1) } }
36504 * ];
36505 *
36506 * _.map(objects, _.method('a.b'));
36507 * // => [2, 1]
36508 *
36509 * _.map(objects, _.method(['a', 'b']));
36510 * // => [2, 1]
36511 */
36512 var method = baseRest(function(path, args) {
36513 return function(object) {
36514 return baseInvoke(object, path, args);
36515 };
36516 });
36517
36518 /**
36519 * The opposite of `_.method`; this method creates a function that invokes
36520 * the method at a given path of `object`. Any additional arguments are
36521 * provided to the invoked method.
36522 *
36523 * @static
36524 * @memberOf _
36525 * @since 3.7.0
36526 * @category Util
36527 * @param {Object} object The object to query.
36528 * @param {...*} [args] The arguments to invoke the method with.
36529 * @returns {Function} Returns the new invoker function.
36530 * @example
36531 *
36532 * var array = _.times(3, _.constant),
36533 * object = { 'a': array, 'b': array, 'c': array };
36534 *
36535 * _.map(['a[2]', 'c[0]'], _.methodOf(object));
36536 * // => [2, 0]
36537 *
36538 * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
36539 * // => [2, 0]
36540 */
36541 var methodOf = baseRest(function(object, args) {
36542 return function(path) {
36543 return baseInvoke(object, path, args);
36544 };
36545 });
36546
36547 /**
36548 * Adds all own enumerable string keyed function properties of a source
36549 * object to the destination object. If `object` is a function, then methods
36550 * are added to its prototype as well.
36551 *
36552 * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
36553 * avoid conflicts caused by modifying the original.
36554 *
36555 * @static
36556 * @since 0.1.0
36557 * @memberOf _
36558 * @category Util
36559 * @param {Function|Object} [object=lodash] The destination object.
36560 * @param {Object} source The object of functions to add.
36561 * @param {Object} [options={}] The options object.
36562 * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
36563 * @returns {Function|Object} Returns `object`.
36564 * @example
36565 *
36566 * function vowels(string) {
36567 * return _.filter(string, function(v) {
36568 * return /[aeiou]/i.test(v);
36569 * });
36570 * }
36571 *
36572 * _.mixin({ 'vowels': vowels });
36573 * _.vowels('fred');
36574 * // => ['e']
36575 *
36576 * _('fred').vowels().value();
36577 * // => ['e']
36578 *
36579 * _.mixin({ 'vowels': vowels }, { 'chain': false });
36580 * _('fred').vowels();
36581 * // => ['e']
36582 */
36583 function mixin(object, source, options) {
36584 var props = keys(source),
36585 methodNames = baseFunctions(source, props);
36586
36587 if (options == null &&
36588 !(isObject(source) && (methodNames.length || !props.length))) {
36589 options = source;
36590 source = object;
36591 object = this;
36592 methodNames = baseFunctions(source, keys(source));
36593 }
36594 var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
36595 isFunc = isFunction(object);
36596
36597 arrayEach(methodNames, function(methodName) {
36598 var func = source[methodName];
36599 object[methodName] = func;
36600 if (isFunc) {
36601 object.prototype[methodName] = function() {
36602 var chainAll = this.__chain__;
36603 if (chain || chainAll) {
36604 var result = object(this.__wrapped__),
36605 actions = result.__actions__ = copyArray(this.__actions__);
36606
36607 actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
36608 result.__chain__ = chainAll;
36609 return result;
36610 }
36611 return func.apply(object, arrayPush([this.value()], arguments));
36612 };
36613 }
36614 });
36615
36616 return object;
36617 }
36618
36619 /**
36620 * Reverts the `_` variable to its previous value and returns a reference to
36621 * the `lodash` function.
36622 *
36623 * @static
36624 * @since 0.1.0
36625 * @memberOf _
36626 * @category Util
36627 * @returns {Function} Returns the `lodash` function.
36628 * @example
36629 *
36630 * var lodash = _.noConflict();
36631 */
36632 function noConflict() {
36633 if (root._ === this) {
36634 root._ = oldDash;
36635 }
36636 return this;
36637 }
36638
36639 /**
36640 * This method returns `undefined`.
36641 *
36642 * @static
36643 * @memberOf _
36644 * @since 2.3.0
36645 * @category Util
36646 * @example
36647 *
36648 * _.times(2, _.noop);
36649 * // => [undefined, undefined]
36650 */
36651 function noop() {
36652 // No operation performed.
36653 }
36654
36655 /**
36656 * Creates a function that gets the argument at index `n`. If `n` is negative,
36657 * the nth argument from the end is returned.
36658 *
36659 * @static
36660 * @memberOf _
36661 * @since 4.0.0
36662 * @category Util
36663 * @param {number} [n=0] The index of the argument to return.
36664 * @returns {Function} Returns the new pass-thru function.
36665 * @example
36666 *
36667 * var func = _.nthArg(1);
36668 * func('a', 'b', 'c', 'd');
36669 * // => 'b'
36670 *
36671 * var func = _.nthArg(-2);
36672 * func('a', 'b', 'c', 'd');
36673 * // => 'c'
36674 */
36675 function nthArg(n) {
36676 n = toInteger(n);
36677 return baseRest(function(args) {
36678 return baseNth(args, n);
36679 });
36680 }
36681
36682 /**
36683 * Creates a function that invokes `iteratees` with the arguments it receives
36684 * and returns their results.
36685 *
36686 * @static
36687 * @memberOf _
36688 * @since 4.0.0
36689 * @category Util
36690 * @param {...(Function|Function[])} [iteratees=[_.identity]]
36691 * The iteratees to invoke.
36692 * @returns {Function} Returns the new function.
36693 * @example
36694 *
36695 * var func = _.over([Math.max, Math.min]);
36696 *
36697 * func(1, 2, 3, 4);
36698 * // => [4, 1]
36699 */
36700 var over = createOver(arrayMap);
36701
36702 /**
36703 * Creates a function that checks if **all** of the `predicates` return
36704 * truthy when invoked with the arguments it receives.
36705 *
36706 * @static
36707 * @memberOf _
36708 * @since 4.0.0
36709 * @category Util
36710 * @param {...(Function|Function[])} [predicates=[_.identity]]
36711 * The predicates to check.
36712 * @returns {Function} Returns the new function.
36713 * @example
36714 *
36715 * var func = _.overEvery([Boolean, isFinite]);
36716 *
36717 * func('1');
36718 * // => true
36719 *
36720 * func(null);
36721 * // => false
36722 *
36723 * func(NaN);
36724 * // => false
36725 */
36726 var overEvery = createOver(arrayEvery);
36727
36728 /**
36729 * Creates a function that checks if **any** of the `predicates` return
36730 * truthy when invoked with the arguments it receives.
36731 *
36732 * @static
36733 * @memberOf _
36734 * @since 4.0.0
36735 * @category Util
36736 * @param {...(Function|Function[])} [predicates=[_.identity]]
36737 * The predicates to check.
36738 * @returns {Function} Returns the new function.
36739 * @example
36740 *
36741 * var func = _.overSome([Boolean, isFinite]);
36742 *
36743 * func('1');
36744 * // => true
36745 *
36746 * func(null);
36747 * // => true
36748 *
36749 * func(NaN);
36750 * // => false
36751 */
36752 var overSome = createOver(arraySome);
36753
36754 /**
36755 * Creates a function that returns the value at `path` of a given object.
36756 *
36757 * @static
36758 * @memberOf _
36759 * @since 2.4.0
36760 * @category Util
36761 * @param {Array|string} path The path of the property to get.
36762 * @returns {Function} Returns the new accessor function.
36763 * @example
36764 *
36765 * var objects = [
36766 * { 'a': { 'b': 2 } },
36767 * { 'a': { 'b': 1 } }
36768 * ];
36769 *
36770 * _.map(objects, _.property('a.b'));
36771 * // => [2, 1]
36772 *
36773 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
36774 * // => [1, 2]
36775 */
36776 function property(path) {
36777 return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
36778 }
36779
36780 /**
36781 * The opposite of `_.property`; this method creates a function that returns
36782 * the value at a given path of `object`.
36783 *
36784 * @static
36785 * @memberOf _
36786 * @since 3.0.0
36787 * @category Util
36788 * @param {Object} object The object to query.
36789 * @returns {Function} Returns the new accessor function.
36790 * @example
36791 *
36792 * var array = [0, 1, 2],
36793 * object = { 'a': array, 'b': array, 'c': array };
36794 *
36795 * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
36796 * // => [2, 0]
36797 *
36798 * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
36799 * // => [2, 0]
36800 */
36801 function propertyOf(object) {
36802 return function(path) {
36803 return object == null ? undefined$1 : baseGet(object, path);
36804 };
36805 }
36806
36807 /**
36808 * Creates an array of numbers (positive and/or negative) progressing from
36809 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
36810 * `start` is specified without an `end` or `step`. If `end` is not specified,
36811 * it's set to `start` with `start` then set to `0`.
36812 *
36813 * **Note:** JavaScript follows the IEEE-754 standard for resolving
36814 * floating-point values which can produce unexpected results.
36815 *
36816 * @static
36817 * @since 0.1.0
36818 * @memberOf _
36819 * @category Util
36820 * @param {number} [start=0] The start of the range.
36821 * @param {number} end The end of the range.
36822 * @param {number} [step=1] The value to increment or decrement by.
36823 * @returns {Array} Returns the range of numbers.
36824 * @see _.inRange, _.rangeRight
36825 * @example
36826 *
36827 * _.range(4);
36828 * // => [0, 1, 2, 3]
36829 *
36830 * _.range(-4);
36831 * // => [0, -1, -2, -3]
36832 *
36833 * _.range(1, 5);
36834 * // => [1, 2, 3, 4]
36835 *
36836 * _.range(0, 20, 5);
36837 * // => [0, 5, 10, 15]
36838 *
36839 * _.range(0, -4, -1);
36840 * // => [0, -1, -2, -3]
36841 *
36842 * _.range(1, 4, 0);
36843 * // => [1, 1, 1]
36844 *
36845 * _.range(0);
36846 * // => []
36847 */
36848 var range = createRange();
36849
36850 /**
36851 * This method is like `_.range` except that it populates values in
36852 * descending order.
36853 *
36854 * @static
36855 * @memberOf _
36856 * @since 4.0.0
36857 * @category Util
36858 * @param {number} [start=0] The start of the range.
36859 * @param {number} end The end of the range.
36860 * @param {number} [step=1] The value to increment or decrement by.
36861 * @returns {Array} Returns the range of numbers.
36862 * @see _.inRange, _.range
36863 * @example
36864 *
36865 * _.rangeRight(4);
36866 * // => [3, 2, 1, 0]
36867 *
36868 * _.rangeRight(-4);
36869 * // => [-3, -2, -1, 0]
36870 *
36871 * _.rangeRight(1, 5);
36872 * // => [4, 3, 2, 1]
36873 *
36874 * _.rangeRight(0, 20, 5);
36875 * // => [15, 10, 5, 0]
36876 *
36877 * _.rangeRight(0, -4, -1);
36878 * // => [-3, -2, -1, 0]
36879 *
36880 * _.rangeRight(1, 4, 0);
36881 * // => [1, 1, 1]
36882 *
36883 * _.rangeRight(0);
36884 * // => []
36885 */
36886 var rangeRight = createRange(true);
36887
36888 /**
36889 * This method returns a new empty array.
36890 *
36891 * @static
36892 * @memberOf _
36893 * @since 4.13.0
36894 * @category Util
36895 * @returns {Array} Returns the new empty array.
36896 * @example
36897 *
36898 * var arrays = _.times(2, _.stubArray);
36899 *
36900 * console.log(arrays);
36901 * // => [[], []]
36902 *
36903 * console.log(arrays[0] === arrays[1]);
36904 * // => false
36905 */
36906 function stubArray() {
36907 return [];
36908 }
36909
36910 /**
36911 * This method returns `false`.
36912 *
36913 * @static
36914 * @memberOf _
36915 * @since 4.13.0
36916 * @category Util
36917 * @returns {boolean} Returns `false`.
36918 * @example
36919 *
36920 * _.times(2, _.stubFalse);
36921 * // => [false, false]
36922 */
36923 function stubFalse() {
36924 return false;
36925 }
36926
36927 /**
36928 * This method returns a new empty object.
36929 *
36930 * @static
36931 * @memberOf _
36932 * @since 4.13.0
36933 * @category Util
36934 * @returns {Object} Returns the new empty object.
36935 * @example
36936 *
36937 * var objects = _.times(2, _.stubObject);
36938 *
36939 * console.log(objects);
36940 * // => [{}, {}]
36941 *
36942 * console.log(objects[0] === objects[1]);
36943 * // => false
36944 */
36945 function stubObject() {
36946 return {};
36947 }
36948
36949 /**
36950 * This method returns an empty string.
36951 *
36952 * @static
36953 * @memberOf _
36954 * @since 4.13.0
36955 * @category Util
36956 * @returns {string} Returns the empty string.
36957 * @example
36958 *
36959 * _.times(2, _.stubString);
36960 * // => ['', '']
36961 */
36962 function stubString() {
36963 return '';
36964 }
36965
36966 /**
36967 * This method returns `true`.
36968 *
36969 * @static
36970 * @memberOf _
36971 * @since 4.13.0
36972 * @category Util
36973 * @returns {boolean} Returns `true`.
36974 * @example
36975 *
36976 * _.times(2, _.stubTrue);
36977 * // => [true, true]
36978 */
36979 function stubTrue() {
36980 return true;
36981 }
36982
36983 /**
36984 * Invokes the iteratee `n` times, returning an array of the results of
36985 * each invocation. The iteratee is invoked with one argument; (index).
36986 *
36987 * @static
36988 * @since 0.1.0
36989 * @memberOf _
36990 * @category Util
36991 * @param {number} n The number of times to invoke `iteratee`.
36992 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
36993 * @returns {Array} Returns the array of results.
36994 * @example
36995 *
36996 * _.times(3, String);
36997 * // => ['0', '1', '2']
36998 *
36999 * _.times(4, _.constant(0));
37000 * // => [0, 0, 0, 0]
37001 */
37002 function times(n, iteratee) {
37003 n = toInteger(n);
37004 if (n < 1 || n > MAX_SAFE_INTEGER) {
37005 return [];
37006 }
37007 var index = MAX_ARRAY_LENGTH,
37008 length = nativeMin(n, MAX_ARRAY_LENGTH);
37009
37010 iteratee = getIteratee(iteratee);
37011 n -= MAX_ARRAY_LENGTH;
37012
37013 var result = baseTimes(length, iteratee);
37014 while (++index < n) {
37015 iteratee(index);
37016 }
37017 return result;
37018 }
37019
37020 /**
37021 * Converts `value` to a property path array.
37022 *
37023 * @static
37024 * @memberOf _
37025 * @since 4.0.0
37026 * @category Util
37027 * @param {*} value The value to convert.
37028 * @returns {Array} Returns the new property path array.
37029 * @example
37030 *
37031 * _.toPath('a.b.c');
37032 * // => ['a', 'b', 'c']
37033 *
37034 * _.toPath('a[0].b.c');
37035 * // => ['a', '0', 'b', 'c']
37036 */
37037 function toPath(value) {
37038 if (isArray(value)) {
37039 return arrayMap(value, toKey);
37040 }
37041 return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
37042 }
37043
37044 /**
37045 * Generates a unique ID. If `prefix` is given, the ID is appended to it.
37046 *
37047 * @static
37048 * @since 0.1.0
37049 * @memberOf _
37050 * @category Util
37051 * @param {string} [prefix=''] The value to prefix the ID with.
37052 * @returns {string} Returns the unique ID.
37053 * @example
37054 *
37055 * _.uniqueId('contact_');
37056 * // => 'contact_104'
37057 *
37058 * _.uniqueId();
37059 * // => '105'
37060 */
37061 function uniqueId(prefix) {
37062 var id = ++idCounter;
37063 return toString(prefix) + id;
37064 }
37065
37066 /*------------------------------------------------------------------------*/
37067
37068 /**
37069 * Adds two numbers.
37070 *
37071 * @static
37072 * @memberOf _
37073 * @since 3.4.0
37074 * @category Math
37075 * @param {number} augend The first number in an addition.
37076 * @param {number} addend The second number in an addition.
37077 * @returns {number} Returns the total.
37078 * @example
37079 *
37080 * _.add(6, 4);
37081 * // => 10
37082 */
37083 var add = createMathOperation(function(augend, addend) {
37084 return augend + addend;
37085 }, 0);
37086
37087 /**
37088 * Computes `number` rounded up to `precision`.
37089 *
37090 * @static
37091 * @memberOf _
37092 * @since 3.10.0
37093 * @category Math
37094 * @param {number} number The number to round up.
37095 * @param {number} [precision=0] The precision to round up to.
37096 * @returns {number} Returns the rounded up number.
37097 * @example
37098 *
37099 * _.ceil(4.006);
37100 * // => 5
37101 *
37102 * _.ceil(6.004, 2);
37103 * // => 6.01
37104 *
37105 * _.ceil(6040, -2);
37106 * // => 6100
37107 */
37108 var ceil = createRound('ceil');
37109
37110 /**
37111 * Divide two numbers.
37112 *
37113 * @static
37114 * @memberOf _
37115 * @since 4.7.0
37116 * @category Math
37117 * @param {number} dividend The first number in a division.
37118 * @param {number} divisor The second number in a division.
37119 * @returns {number} Returns the quotient.
37120 * @example
37121 *
37122 * _.divide(6, 4);
37123 * // => 1.5
37124 */
37125 var divide = createMathOperation(function(dividend, divisor) {
37126 return dividend / divisor;
37127 }, 1);
37128
37129 /**
37130 * Computes `number` rounded down to `precision`.
37131 *
37132 * @static
37133 * @memberOf _
37134 * @since 3.10.0
37135 * @category Math
37136 * @param {number} number The number to round down.
37137 * @param {number} [precision=0] The precision to round down to.
37138 * @returns {number} Returns the rounded down number.
37139 * @example
37140 *
37141 * _.floor(4.006);
37142 * // => 4
37143 *
37144 * _.floor(0.046, 2);
37145 * // => 0.04
37146 *
37147 * _.floor(4060, -2);
37148 * // => 4000
37149 */
37150 var floor = createRound('floor');
37151
37152 /**
37153 * Computes the maximum value of `array`. If `array` is empty or falsey,
37154 * `undefined` is returned.
37155 *
37156 * @static
37157 * @since 0.1.0
37158 * @memberOf _
37159 * @category Math
37160 * @param {Array} array The array to iterate over.
37161 * @returns {*} Returns the maximum value.
37162 * @example
37163 *
37164 * _.max([4, 2, 8, 6]);
37165 * // => 8
37166 *
37167 * _.max([]);
37168 * // => undefined
37169 */
37170 function max(array) {
37171 return (array && array.length)
37172 ? baseExtremum(array, identity, baseGt)
37173 : undefined$1;
37174 }
37175
37176 /**
37177 * This method is like `_.max` except that it accepts `iteratee` which is
37178 * invoked for each element in `array` to generate the criterion by which
37179 * the value is ranked. The iteratee is invoked with one argument: (value).
37180 *
37181 * @static
37182 * @memberOf _
37183 * @since 4.0.0
37184 * @category Math
37185 * @param {Array} array The array to iterate over.
37186 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
37187 * @returns {*} Returns the maximum value.
37188 * @example
37189 *
37190 * var objects = [{ 'n': 1 }, { 'n': 2 }];
37191 *
37192 * _.maxBy(objects, function(o) { return o.n; });
37193 * // => { 'n': 2 }
37194 *
37195 * // The `_.property` iteratee shorthand.
37196 * _.maxBy(objects, 'n');
37197 * // => { 'n': 2 }
37198 */
37199 function maxBy(array, iteratee) {
37200 return (array && array.length)
37201 ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
37202 : undefined$1;
37203 }
37204
37205 /**
37206 * Computes the mean of the values in `array`.
37207 *
37208 * @static
37209 * @memberOf _
37210 * @since 4.0.0
37211 * @category Math
37212 * @param {Array} array The array to iterate over.
37213 * @returns {number} Returns the mean.
37214 * @example
37215 *
37216 * _.mean([4, 2, 8, 6]);
37217 * // => 5
37218 */
37219 function mean(array) {
37220 return baseMean(array, identity);
37221 }
37222
37223 /**
37224 * This method is like `_.mean` except that it accepts `iteratee` which is
37225 * invoked for each element in `array` to generate the value to be averaged.
37226 * The iteratee is invoked with one argument: (value).
37227 *
37228 * @static
37229 * @memberOf _
37230 * @since 4.7.0
37231 * @category Math
37232 * @param {Array} array The array to iterate over.
37233 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
37234 * @returns {number} Returns the mean.
37235 * @example
37236 *
37237 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
37238 *
37239 * _.meanBy(objects, function(o) { return o.n; });
37240 * // => 5
37241 *
37242 * // The `_.property` iteratee shorthand.
37243 * _.meanBy(objects, 'n');
37244 * // => 5
37245 */
37246 function meanBy(array, iteratee) {
37247 return baseMean(array, getIteratee(iteratee, 2));
37248 }
37249
37250 /**
37251 * Computes the minimum value of `array`. If `array` is empty or falsey,
37252 * `undefined` is returned.
37253 *
37254 * @static
37255 * @since 0.1.0
37256 * @memberOf _
37257 * @category Math
37258 * @param {Array} array The array to iterate over.
37259 * @returns {*} Returns the minimum value.
37260 * @example
37261 *
37262 * _.min([4, 2, 8, 6]);
37263 * // => 2
37264 *
37265 * _.min([]);
37266 * // => undefined
37267 */
37268 function min(array) {
37269 return (array && array.length)
37270 ? baseExtremum(array, identity, baseLt)
37271 : undefined$1;
37272 }
37273
37274 /**
37275 * This method is like `_.min` except that it accepts `iteratee` which is
37276 * invoked for each element in `array` to generate the criterion by which
37277 * the value is ranked. The iteratee is invoked with one argument: (value).
37278 *
37279 * @static
37280 * @memberOf _
37281 * @since 4.0.0
37282 * @category Math
37283 * @param {Array} array The array to iterate over.
37284 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
37285 * @returns {*} Returns the minimum value.
37286 * @example
37287 *
37288 * var objects = [{ 'n': 1 }, { 'n': 2 }];
37289 *
37290 * _.minBy(objects, function(o) { return o.n; });
37291 * // => { 'n': 1 }
37292 *
37293 * // The `_.property` iteratee shorthand.
37294 * _.minBy(objects, 'n');
37295 * // => { 'n': 1 }
37296 */
37297 function minBy(array, iteratee) {
37298 return (array && array.length)
37299 ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
37300 : undefined$1;
37301 }
37302
37303 /**
37304 * Multiply two numbers.
37305 *
37306 * @static
37307 * @memberOf _
37308 * @since 4.7.0
37309 * @category Math
37310 * @param {number} multiplier The first number in a multiplication.
37311 * @param {number} multiplicand The second number in a multiplication.
37312 * @returns {number} Returns the product.
37313 * @example
37314 *
37315 * _.multiply(6, 4);
37316 * // => 24
37317 */
37318 var multiply = createMathOperation(function(multiplier, multiplicand) {
37319 return multiplier * multiplicand;
37320 }, 1);
37321
37322 /**
37323 * Computes `number` rounded to `precision`.
37324 *
37325 * @static
37326 * @memberOf _
37327 * @since 3.10.0
37328 * @category Math
37329 * @param {number} number The number to round.
37330 * @param {number} [precision=0] The precision to round to.
37331 * @returns {number} Returns the rounded number.
37332 * @example
37333 *
37334 * _.round(4.006);
37335 * // => 4
37336 *
37337 * _.round(4.006, 2);
37338 * // => 4.01
37339 *
37340 * _.round(4060, -2);
37341 * // => 4100
37342 */
37343 var round = createRound('round');
37344
37345 /**
37346 * Subtract two numbers.
37347 *
37348 * @static
37349 * @memberOf _
37350 * @since 4.0.0
37351 * @category Math
37352 * @param {number} minuend The first number in a subtraction.
37353 * @param {number} subtrahend The second number in a subtraction.
37354 * @returns {number} Returns the difference.
37355 * @example
37356 *
37357 * _.subtract(6, 4);
37358 * // => 2
37359 */
37360 var subtract = createMathOperation(function(minuend, subtrahend) {
37361 return minuend - subtrahend;
37362 }, 0);
37363
37364 /**
37365 * Computes the sum of the values in `array`.
37366 *
37367 * @static
37368 * @memberOf _
37369 * @since 3.4.0
37370 * @category Math
37371 * @param {Array} array The array to iterate over.
37372 * @returns {number} Returns the sum.
37373 * @example
37374 *
37375 * _.sum([4, 2, 8, 6]);
37376 * // => 20
37377 */
37378 function sum(array) {
37379 return (array && array.length)
37380 ? baseSum(array, identity)
37381 : 0;
37382 }
37383
37384 /**
37385 * This method is like `_.sum` except that it accepts `iteratee` which is
37386 * invoked for each element in `array` to generate the value to be summed.
37387 * The iteratee is invoked with one argument: (value).
37388 *
37389 * @static
37390 * @memberOf _
37391 * @since 4.0.0
37392 * @category Math
37393 * @param {Array} array The array to iterate over.
37394 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
37395 * @returns {number} Returns the sum.
37396 * @example
37397 *
37398 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
37399 *
37400 * _.sumBy(objects, function(o) { return o.n; });
37401 * // => 20
37402 *
37403 * // The `_.property` iteratee shorthand.
37404 * _.sumBy(objects, 'n');
37405 * // => 20
37406 */
37407 function sumBy(array, iteratee) {
37408 return (array && array.length)
37409 ? baseSum(array, getIteratee(iteratee, 2))
37410 : 0;
37411 }
37412
37413 /*------------------------------------------------------------------------*/
37414
37415 // Add methods that return wrapped values in chain sequences.
37416 lodash.after = after;
37417 lodash.ary = ary;
37418 lodash.assign = assign;
37419 lodash.assignIn = assignIn;
37420 lodash.assignInWith = assignInWith;
37421 lodash.assignWith = assignWith;
37422 lodash.at = at;
37423 lodash.before = before;
37424 lodash.bind = bind;
37425 lodash.bindAll = bindAll;
37426 lodash.bindKey = bindKey;
37427 lodash.castArray = castArray;
37428 lodash.chain = chain;
37429 lodash.chunk = chunk;
37430 lodash.compact = compact;
37431 lodash.concat = concat;
37432 lodash.cond = cond;
37433 lodash.conforms = conforms;
37434 lodash.constant = constant;
37435 lodash.countBy = countBy;
37436 lodash.create = create;
37437 lodash.curry = curry;
37438 lodash.curryRight = curryRight;
37439 lodash.debounce = debounce;
37440 lodash.defaults = defaults;
37441 lodash.defaultsDeep = defaultsDeep;
37442 lodash.defer = defer;
37443 lodash.delay = delay;
37444 lodash.difference = difference;
37445 lodash.differenceBy = differenceBy;
37446 lodash.differenceWith = differenceWith;
37447 lodash.drop = drop;
37448 lodash.dropRight = dropRight;
37449 lodash.dropRightWhile = dropRightWhile;
37450 lodash.dropWhile = dropWhile;
37451 lodash.fill = fill;
37452 lodash.filter = filter;
37453 lodash.flatMap = flatMap;
37454 lodash.flatMapDeep = flatMapDeep;
37455 lodash.flatMapDepth = flatMapDepth;
37456 lodash.flatten = flatten;
37457 lodash.flattenDeep = flattenDeep;
37458 lodash.flattenDepth = flattenDepth;
37459 lodash.flip = flip;
37460 lodash.flow = flow;
37461 lodash.flowRight = flowRight;
37462 lodash.fromPairs = fromPairs;
37463 lodash.functions = functions;
37464 lodash.functionsIn = functionsIn;
37465 lodash.groupBy = groupBy;
37466 lodash.initial = initial;
37467 lodash.intersection = intersection;
37468 lodash.intersectionBy = intersectionBy;
37469 lodash.intersectionWith = intersectionWith;
37470 lodash.invert = invert;
37471 lodash.invertBy = invertBy;
37472 lodash.invokeMap = invokeMap;
37473 lodash.iteratee = iteratee;
37474 lodash.keyBy = keyBy;
37475 lodash.keys = keys;
37476 lodash.keysIn = keysIn;
37477 lodash.map = map;
37478 lodash.mapKeys = mapKeys;
37479 lodash.mapValues = mapValues;
37480 lodash.matches = matches;
37481 lodash.matchesProperty = matchesProperty;
37482 lodash.memoize = memoize;
37483 lodash.merge = merge;
37484 lodash.mergeWith = mergeWith;
37485 lodash.method = method;
37486 lodash.methodOf = methodOf;
37487 lodash.mixin = mixin;
37488 lodash.negate = negate;
37489 lodash.nthArg = nthArg;
37490 lodash.omit = omit;
37491 lodash.omitBy = omitBy;
37492 lodash.once = once;
37493 lodash.orderBy = orderBy;
37494 lodash.over = over;
37495 lodash.overArgs = overArgs;
37496 lodash.overEvery = overEvery;
37497 lodash.overSome = overSome;
37498 lodash.partial = partial;
37499 lodash.partialRight = partialRight;
37500 lodash.partition = partition;
37501 lodash.pick = pick;
37502 lodash.pickBy = pickBy;
37503 lodash.property = property;
37504 lodash.propertyOf = propertyOf;
37505 lodash.pull = pull;
37506 lodash.pullAll = pullAll;
37507 lodash.pullAllBy = pullAllBy;
37508 lodash.pullAllWith = pullAllWith;
37509 lodash.pullAt = pullAt;
37510 lodash.range = range;
37511 lodash.rangeRight = rangeRight;
37512 lodash.rearg = rearg;
37513 lodash.reject = reject;
37514 lodash.remove = remove;
37515 lodash.rest = rest;
37516 lodash.reverse = reverse;
37517 lodash.sampleSize = sampleSize;
37518 lodash.set = set;
37519 lodash.setWith = setWith;
37520 lodash.shuffle = shuffle;
37521 lodash.slice = slice;
37522 lodash.sortBy = sortBy;
37523 lodash.sortedUniq = sortedUniq;
37524 lodash.sortedUniqBy = sortedUniqBy;
37525 lodash.split = split;
37526 lodash.spread = spread;
37527 lodash.tail = tail;
37528 lodash.take = take;
37529 lodash.takeRight = takeRight;
37530 lodash.takeRightWhile = takeRightWhile;
37531 lodash.takeWhile = takeWhile;
37532 lodash.tap = tap;
37533 lodash.throttle = throttle;
37534 lodash.thru = thru;
37535 lodash.toArray = toArray;
37536 lodash.toPairs = toPairs;
37537 lodash.toPairsIn = toPairsIn;
37538 lodash.toPath = toPath;
37539 lodash.toPlainObject = toPlainObject;
37540 lodash.transform = transform;
37541 lodash.unary = unary;
37542 lodash.union = union;
37543 lodash.unionBy = unionBy;
37544 lodash.unionWith = unionWith;
37545 lodash.uniq = uniq;
37546 lodash.uniqBy = uniqBy;
37547 lodash.uniqWith = uniqWith;
37548 lodash.unset = unset;
37549 lodash.unzip = unzip;
37550 lodash.unzipWith = unzipWith;
37551 lodash.update = update;
37552 lodash.updateWith = updateWith;
37553 lodash.values = values;
37554 lodash.valuesIn = valuesIn;
37555 lodash.without = without;
37556 lodash.words = words;
37557 lodash.wrap = wrap;
37558 lodash.xor = xor;
37559 lodash.xorBy = xorBy;
37560 lodash.xorWith = xorWith;
37561 lodash.zip = zip;
37562 lodash.zipObject = zipObject;
37563 lodash.zipObjectDeep = zipObjectDeep;
37564 lodash.zipWith = zipWith;
37565
37566 // Add aliases.
37567 lodash.entries = toPairs;
37568 lodash.entriesIn = toPairsIn;
37569 lodash.extend = assignIn;
37570 lodash.extendWith = assignInWith;
37571
37572 // Add methods to `lodash.prototype`.
37573 mixin(lodash, lodash);
37574
37575 /*------------------------------------------------------------------------*/
37576
37577 // Add methods that return unwrapped values in chain sequences.
37578 lodash.add = add;
37579 lodash.attempt = attempt;
37580 lodash.camelCase = camelCase;
37581 lodash.capitalize = capitalize;
37582 lodash.ceil = ceil;
37583 lodash.clamp = clamp;
37584 lodash.clone = clone;
37585 lodash.cloneDeep = cloneDeep;
37586 lodash.cloneDeepWith = cloneDeepWith;
37587 lodash.cloneWith = cloneWith;
37588 lodash.conformsTo = conformsTo;
37589 lodash.deburr = deburr;
37590 lodash.defaultTo = defaultTo;
37591 lodash.divide = divide;
37592 lodash.endsWith = endsWith;
37593 lodash.eq = eq;
37594 lodash.escape = escape;
37595 lodash.escapeRegExp = escapeRegExp;
37596 lodash.every = every;
37597 lodash.find = find;
37598 lodash.findIndex = findIndex;
37599 lodash.findKey = findKey;
37600 lodash.findLast = findLast;
37601 lodash.findLastIndex = findLastIndex;
37602 lodash.findLastKey = findLastKey;
37603 lodash.floor = floor;
37604 lodash.forEach = forEach;
37605 lodash.forEachRight = forEachRight;
37606 lodash.forIn = forIn;
37607 lodash.forInRight = forInRight;
37608 lodash.forOwn = forOwn;
37609 lodash.forOwnRight = forOwnRight;
37610 lodash.get = get;
37611 lodash.gt = gt;
37612 lodash.gte = gte;
37613 lodash.has = has;
37614 lodash.hasIn = hasIn;
37615 lodash.head = head;
37616 lodash.identity = identity;
37617 lodash.includes = includes;
37618 lodash.indexOf = indexOf;
37619 lodash.inRange = inRange;
37620 lodash.invoke = invoke;
37621 lodash.isArguments = isArguments;
37622 lodash.isArray = isArray;
37623 lodash.isArrayBuffer = isArrayBuffer;
37624 lodash.isArrayLike = isArrayLike;
37625 lodash.isArrayLikeObject = isArrayLikeObject;
37626 lodash.isBoolean = isBoolean;
37627 lodash.isBuffer = isBuffer;
37628 lodash.isDate = isDate;
37629 lodash.isElement = isElement;
37630 lodash.isEmpty = isEmpty;
37631 lodash.isEqual = isEqual;
37632 lodash.isEqualWith = isEqualWith;
37633 lodash.isError = isError;
37634 lodash.isFinite = isFinite;
37635 lodash.isFunction = isFunction;
37636 lodash.isInteger = isInteger;
37637 lodash.isLength = isLength;
37638 lodash.isMap = isMap;
37639 lodash.isMatch = isMatch;
37640 lodash.isMatchWith = isMatchWith;
37641 lodash.isNaN = isNaN;
37642 lodash.isNative = isNative;
37643 lodash.isNil = isNil;
37644 lodash.isNull = isNull;
37645 lodash.isNumber = isNumber;
37646 lodash.isObject = isObject;
37647 lodash.isObjectLike = isObjectLike;
37648 lodash.isPlainObject = isPlainObject;
37649 lodash.isRegExp = isRegExp;
37650 lodash.isSafeInteger = isSafeInteger;
37651 lodash.isSet = isSet;
37652 lodash.isString = isString;
37653 lodash.isSymbol = isSymbol;
37654 lodash.isTypedArray = isTypedArray;
37655 lodash.isUndefined = isUndefined;
37656 lodash.isWeakMap = isWeakMap;
37657 lodash.isWeakSet = isWeakSet;
37658 lodash.join = join;
37659 lodash.kebabCase = kebabCase;
37660 lodash.last = last;
37661 lodash.lastIndexOf = lastIndexOf;
37662 lodash.lowerCase = lowerCase;
37663 lodash.lowerFirst = lowerFirst;
37664 lodash.lt = lt;
37665 lodash.lte = lte;
37666 lodash.max = max;
37667 lodash.maxBy = maxBy;
37668 lodash.mean = mean;
37669 lodash.meanBy = meanBy;
37670 lodash.min = min;
37671 lodash.minBy = minBy;
37672 lodash.stubArray = stubArray;
37673 lodash.stubFalse = stubFalse;
37674 lodash.stubObject = stubObject;
37675 lodash.stubString = stubString;
37676 lodash.stubTrue = stubTrue;
37677 lodash.multiply = multiply;
37678 lodash.nth = nth;
37679 lodash.noConflict = noConflict;
37680 lodash.noop = noop;
37681 lodash.now = now;
37682 lodash.pad = pad;
37683 lodash.padEnd = padEnd;
37684 lodash.padStart = padStart;
37685 lodash.parseInt = parseInt;
37686 lodash.random = random;
37687 lodash.reduce = reduce;
37688 lodash.reduceRight = reduceRight;
37689 lodash.repeat = repeat;
37690 lodash.replace = replace;
37691 lodash.result = result;
37692 lodash.round = round;
37693 lodash.runInContext = runInContext;
37694 lodash.sample = sample;
37695 lodash.size = size;
37696 lodash.snakeCase = snakeCase;
37697 lodash.some = some;
37698 lodash.sortedIndex = sortedIndex;
37699 lodash.sortedIndexBy = sortedIndexBy;
37700 lodash.sortedIndexOf = sortedIndexOf;
37701 lodash.sortedLastIndex = sortedLastIndex;
37702 lodash.sortedLastIndexBy = sortedLastIndexBy;
37703 lodash.sortedLastIndexOf = sortedLastIndexOf;
37704 lodash.startCase = startCase;
37705 lodash.startsWith = startsWith;
37706 lodash.subtract = subtract;
37707 lodash.sum = sum;
37708 lodash.sumBy = sumBy;
37709 lodash.template = template;
37710 lodash.times = times;
37711 lodash.toFinite = toFinite;
37712 lodash.toInteger = toInteger;
37713 lodash.toLength = toLength;
37714 lodash.toLower = toLower;
37715 lodash.toNumber = toNumber;
37716 lodash.toSafeInteger = toSafeInteger;
37717 lodash.toString = toString;
37718 lodash.toUpper = toUpper;
37719 lodash.trim = trim;
37720 lodash.trimEnd = trimEnd;
37721 lodash.trimStart = trimStart;
37722 lodash.truncate = truncate;
37723 lodash.unescape = unescape;
37724 lodash.uniqueId = uniqueId;
37725 lodash.upperCase = upperCase;
37726 lodash.upperFirst = upperFirst;
37727
37728 // Add aliases.
37729 lodash.each = forEach;
37730 lodash.eachRight = forEachRight;
37731 lodash.first = head;
37732
37733 mixin(lodash, (function() {
37734 var source = {};
37735 baseForOwn(lodash, function(func, methodName) {
37736 if (!hasOwnProperty.call(lodash.prototype, methodName)) {
37737 source[methodName] = func;
37738 }
37739 });
37740 return source;
37741 }()), { 'chain': false });
37742
37743 /*------------------------------------------------------------------------*/
37744
37745 /**
37746 * The semantic version number.
37747 *
37748 * @static
37749 * @memberOf _
37750 * @type {string}
37751 */
37752 lodash.VERSION = VERSION;
37753
37754 // Assign default placeholders.
37755 arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
37756 lodash[methodName].placeholder = lodash;
37757 });
37758
37759 // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
37760 arrayEach(['drop', 'take'], function(methodName, index) {
37761 LazyWrapper.prototype[methodName] = function(n) {
37762 n = n === undefined$1 ? 1 : nativeMax(toInteger(n), 0);
37763
37764 var result = (this.__filtered__ && !index)
37765 ? new LazyWrapper(this)
37766 : this.clone();
37767
37768 if (result.__filtered__) {
37769 result.__takeCount__ = nativeMin(n, result.__takeCount__);
37770 } else {
37771 result.__views__.push({
37772 'size': nativeMin(n, MAX_ARRAY_LENGTH),
37773 'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
37774 });
37775 }
37776 return result;
37777 };
37778
37779 LazyWrapper.prototype[methodName + 'Right'] = function(n) {
37780 return this.reverse()[methodName](n).reverse();
37781 };
37782 });
37783
37784 // Add `LazyWrapper` methods that accept an `iteratee` value.
37785 arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
37786 var type = index + 1,
37787 isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
37788
37789 LazyWrapper.prototype[methodName] = function(iteratee) {
37790 var result = this.clone();
37791 result.__iteratees__.push({
37792 'iteratee': getIteratee(iteratee, 3),
37793 'type': type
37794 });
37795 result.__filtered__ = result.__filtered__ || isFilter;
37796 return result;
37797 };
37798 });
37799
37800 // Add `LazyWrapper` methods for `_.head` and `_.last`.
37801 arrayEach(['head', 'last'], function(methodName, index) {
37802 var takeName = 'take' + (index ? 'Right' : '');
37803
37804 LazyWrapper.prototype[methodName] = function() {
37805 return this[takeName](1).value()[0];
37806 };
37807 });
37808
37809 // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
37810 arrayEach(['initial', 'tail'], function(methodName, index) {
37811 var dropName = 'drop' + (index ? '' : 'Right');
37812
37813 LazyWrapper.prototype[methodName] = function() {
37814 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
37815 };
37816 });
37817
37818 LazyWrapper.prototype.compact = function() {
37819 return this.filter(identity);
37820 };
37821
37822 LazyWrapper.prototype.find = function(predicate) {
37823 return this.filter(predicate).head();
37824 };
37825
37826 LazyWrapper.prototype.findLast = function(predicate) {
37827 return this.reverse().find(predicate);
37828 };
37829
37830 LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
37831 if (typeof path == 'function') {
37832 return new LazyWrapper(this);
37833 }
37834 return this.map(function(value) {
37835 return baseInvoke(value, path, args);
37836 });
37837 });
37838
37839 LazyWrapper.prototype.reject = function(predicate) {
37840 return this.filter(negate(getIteratee(predicate)));
37841 };
37842
37843 LazyWrapper.prototype.slice = function(start, end) {
37844 start = toInteger(start);
37845
37846 var result = this;
37847 if (result.__filtered__ && (start > 0 || end < 0)) {
37848 return new LazyWrapper(result);
37849 }
37850 if (start < 0) {
37851 result = result.takeRight(-start);
37852 } else if (start) {
37853 result = result.drop(start);
37854 }
37855 if (end !== undefined$1) {
37856 end = toInteger(end);
37857 result = end < 0 ? result.dropRight(-end) : result.take(end - start);
37858 }
37859 return result;
37860 };
37861
37862 LazyWrapper.prototype.takeRightWhile = function(predicate) {
37863 return this.reverse().takeWhile(predicate).reverse();
37864 };
37865
37866 LazyWrapper.prototype.toArray = function() {
37867 return this.take(MAX_ARRAY_LENGTH);
37868 };
37869
37870 // Add `LazyWrapper` methods to `lodash.prototype`.
37871 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
37872 var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
37873 isTaker = /^(?:head|last)$/.test(methodName),
37874 lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
37875 retUnwrapped = isTaker || /^find/.test(methodName);
37876
37877 if (!lodashFunc) {
37878 return;
37879 }
37880 lodash.prototype[methodName] = function() {
37881 var value = this.__wrapped__,
37882 args = isTaker ? [1] : arguments,
37883 isLazy = value instanceof LazyWrapper,
37884 iteratee = args[0],
37885 useLazy = isLazy || isArray(value);
37886
37887 var interceptor = function(value) {
37888 var result = lodashFunc.apply(lodash, arrayPush([value], args));
37889 return (isTaker && chainAll) ? result[0] : result;
37890 };
37891
37892 if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
37893 // Avoid lazy use if the iteratee has a "length" value other than `1`.
37894 isLazy = useLazy = false;
37895 }
37896 var chainAll = this.__chain__,
37897 isHybrid = !!this.__actions__.length,
37898 isUnwrapped = retUnwrapped && !chainAll,
37899 onlyLazy = isLazy && !isHybrid;
37900
37901 if (!retUnwrapped && useLazy) {
37902 value = onlyLazy ? value : new LazyWrapper(this);
37903 var result = func.apply(value, args);
37904 result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined$1 });
37905 return new LodashWrapper(result, chainAll);
37906 }
37907 if (isUnwrapped && onlyLazy) {
37908 return func.apply(this, args);
37909 }
37910 result = this.thru(interceptor);
37911 return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
37912 };
37913 });
37914
37915 // Add `Array` methods to `lodash.prototype`.
37916 arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
37917 var func = arrayProto[methodName],
37918 chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
37919 retUnwrapped = /^(?:pop|shift)$/.test(methodName);
37920
37921 lodash.prototype[methodName] = function() {
37922 var args = arguments;
37923 if (retUnwrapped && !this.__chain__) {
37924 var value = this.value();
37925 return func.apply(isArray(value) ? value : [], args);
37926 }
37927 return this[chainName](function(value) {
37928 return func.apply(isArray(value) ? value : [], args);
37929 });
37930 };
37931 });
37932
37933 // Map minified method names to their real names.
37934 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
37935 var lodashFunc = lodash[methodName];
37936 if (lodashFunc) {
37937 var key = lodashFunc.name + '';
37938 if (!hasOwnProperty.call(realNames, key)) {
37939 realNames[key] = [];
37940 }
37941 realNames[key].push({ 'name': methodName, 'func': lodashFunc });
37942 }
37943 });
37944
37945 realNames[createHybrid(undefined$1, WRAP_BIND_KEY_FLAG).name] = [{
37946 'name': 'wrapper',
37947 'func': undefined$1
37948 }];
37949
37950 // Add methods to `LazyWrapper`.
37951 LazyWrapper.prototype.clone = lazyClone;
37952 LazyWrapper.prototype.reverse = lazyReverse;
37953 LazyWrapper.prototype.value = lazyValue;
37954
37955 // Add chain sequence methods to the `lodash` wrapper.
37956 lodash.prototype.at = wrapperAt;
37957 lodash.prototype.chain = wrapperChain;
37958 lodash.prototype.commit = wrapperCommit;
37959 lodash.prototype.next = wrapperNext;
37960 lodash.prototype.plant = wrapperPlant;
37961 lodash.prototype.reverse = wrapperReverse;
37962 lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
37963
37964 // Add lazy aliases.
37965 lodash.prototype.first = lodash.prototype.head;
37966
37967 if (symIterator) {
37968 lodash.prototype[symIterator] = wrapperToIterator;
37969 }
37970 return lodash;
37971 });
37972
37973 /*--------------------------------------------------------------------------*/
37974
37975 // Export lodash.
37976 var _ = runInContext();
37977
37978 // Some AMD build optimizers, like r.js, check for condition patterns like:
37979 if (freeModule) {
37980 // Export for Node.js.
37981 (freeModule.exports = _)._ = _;
37982 // Export for CommonJS support.
37983 freeExports._ = _;
37984 }
37985 else {
37986 // Export to the global object.
37987 root._ = _;
37988 }
37989 }.call(commonjsGlobal));
37990 });
37991
37992 var store = createCommonjsModule(function (module, exports) {
37993 /*
37994 This file 'store' is part of Firebird Integrated Solution 1.0
37995
37996 Copyright (c) 2019 Lincong
37997
37998 Contact:
37999 Email: lincong1987@gmail.com
38000
38001 QQ: 159257119
38002
38003 See Usage at http://www.jplatformx.com/firebird
38004
38005 Create date: 2019-01-16 14:43
38006 */
38007
38008 /**
38009 * yox-store.js v0.10.0
38010 * (c) 2017-2019 musicode
38011 * Released under the MIT License.
38012 */
38013 (function (global, factory) {
38014 factory(exports);
38015 })(commonjsGlobal, function (exports) {
38016
38017 var API;
38018
38019 var Store = function () {
38020 this.$store = new API();
38021 };
38022 /**
38023 * 从本地存储读取,需自行实现
38024 *
38025 * @param {string} key 数据的 key
38026 * @param {Function} callback
38027 */
38028
38029
38030 Store.prototype.read = function (key, callback) {};
38031 /**
38032 * 把数据写到本地存储
38033 *
38034 * @param {string} key
38035 * @return {string|number|boolean} value 可以是字符串、数字、布尔,但从本地存储读取出来的都是字符串
38036 */
38037
38038
38039 Store.prototype.write = function (key, value) {};
38040 /**
38041 * 内存中的取值
38042 *
38043 * @param {string} key
38044 * @param {?boolean} readFromStorage 如果内存没有取到值,是否从本地存储尝试取值
38045 * @param {?Function} callback 如果 readFromStorage 为 true,则必须传入回调函数
38046 */
38047
38048
38049 Store.prototype.get = function (key, readFromStorage, callback) {
38050 var instance = this;
38051 var value = instance.$store.get(key);
38052
38053 if (readFromStorage) {
38054 return value === undefined ? instance.read(key, function (value) {
38055 instance.set(key, value);
38056 callback(value);
38057 }) : Yox.nextTick(function () {
38058 callback(value);
38059 });
38060 }
38061
38062 return value;
38063 };
38064 /**
38065 * 内存中的设值
38066 *
38067 * @param {string} key
38068 * @param {string|number|boolean} value
38069 * @param {?boolean} writeToStorage 是否写到本地存储中
38070 */
38071
38072
38073 Store.prototype.set = function (key, value, writeToStorage) {
38074 this.$store.set(key, value);
38075
38076 if (writeToStorage) {
38077 this.write(key, value);
38078 }
38079 };
38080
38081 Store.prototype.prepend = function (key, data) {
38082 this.$store.prepend(key, data);
38083 };
38084
38085 Store.prototype.append = function (key, data) {
38086 this.$store.append(key, data);
38087 };
38088 /**
38089 * 通过索引移除数组中的元素
38090 *
38091 * @param {string} keypath
38092 * @param {number} index
38093 * @return {?boolean} 是否移除成功
38094 */
38095
38096
38097 Store.prototype.removeAt = function (keypath, index) {
38098 return this.$store.removeAt(keypath, index);
38099 };
38100 /**
38101 * 直接移除数组中的元素
38102 *
38103 * @param {string} keypath
38104 * @param {*} item
38105 * @return {?boolean} 是否移除成功
38106 */
38107
38108
38109 Store.prototype.remove = function (keypath, item) {
38110 return this.$store.remove(keypath, item);
38111 };
38112
38113 Store.prototype.increase = function (key, step, max) {
38114 this.$store.increase(key, step, max);
38115 };
38116
38117 Store.prototype.decrease = function (key, step, min) {
38118 this.$store.decrease(key, step, min);
38119 };
38120 /**
38121 * 更新对象类型的数据
38122 *
38123 * @param {string} key
38124 * @param {Object} value
38125 */
38126
38127
38128 Store.prototype.extend = function (key, value) {
38129 if (Yox.is.object(value)) {
38130 var oldValue = this.get(key);
38131
38132 if (Yox.is.object(oldValue)) {
38133 value = Yox.object.extend(Yox.object.extend({}, oldValue), value);
38134 }
38135
38136 this.set(key, value);
38137 }
38138 };
38139 /**
38140 * 尝试设值
38141 *
38142 * @param {string} key
38143 * @param {string|number|boolean} value
38144 * @return {Function} 返回异步回调,传入是否失败
38145 */
38146
38147
38148 Store.prototype.setting = function (key, value) {
38149 var instance = this;
38150 var oldValue = instance.get(key);
38151 instance.set(key, value);
38152 return function (error) {
38153 if (error) {
38154 instance.set(key, oldValue);
38155 }
38156 };
38157 };
38158
38159 Store.prototype.increasing = function (key, step, max) {
38160 var instance = this;
38161 var oldValue = instance.get(key);
38162 instance.increase(key, step, max);
38163 return function (error) {
38164 if (error) {
38165 instance.set(key, oldValue);
38166 }
38167 };
38168 };
38169
38170 Store.prototype.decreasing = function (key, step, min) {
38171 var instance = this;
38172 var oldValue = instance.get(key);
38173 instance.decrease(key, step, min);
38174 return function (error) {
38175 if (error) {
38176 instance.set(key, oldValue);
38177 }
38178 };
38179 };
38180 /**
38181 * 数据监听
38182 *
38183 * @param {string} key
38184 * @param {Function} watcher
38185 * @param {boolean} immediate
38186 */
38187
38188
38189 Store.prototype.watch = function (key, watcher, immediate) {
38190 this.$store.watch(key, watcher, immediate);
38191 };
38192 /**
38193 * 取消数据监听
38194 *
38195 * @param {string} key
38196 * @param {Function} watcher
38197 */
38198
38199
38200 Store.prototype.unwatch = function (key, watcher) {
38201 this.$store.unwatch(key, watcher);
38202 };
38203
38204 Store.prototype.nextTick = function (fn) {
38205 this.$store.nextTick(fn);
38206 };
38207 /**
38208 * 版本
38209 */
38210
38211
38212 var version = "0.10.0";
38213 /**
38214 * 安装插件
38215 */
38216
38217 function install(Y) {
38218 API = Y;
38219 }
38220
38221 exports.Store = Store;
38222 exports.install = install;
38223 exports.version = version;
38224 Object.defineProperty(exports, '__esModule', {
38225 value: true
38226 });
38227 });
38228 });
38229 unwrapExports(store);
38230
38231 var yoxRouter = createCommonjsModule(function (module, exports) {
38232 /**
38233 * yox-router.js v1.0.0-alpha.51
38234 * (c) 2017-2019 musicode
38235 * Released under the MIT License.
38236 */
38237 (function (global, factory) {
38238 factory(exports);
38239 })(commonjsGlobal, function (exports) {
38240
38241 if (typeof window === "undefined") {
38242 console.log("no window, skip router");
38243
38244 exports.Router = function () {
38245 console.log("no window, skip");
38246 };
38247
38248 exports.install = function () {
38249 console.log("no window, skip install Router");
38250 };
38251
38252 exports.version = '1.0.0-alpha.51';
38253 return;
38254 }
38255
38256 var WINDOW = window;
38257 var LOCATION = WINDOW.location;
38258 var HISTORY = WINDOW.history;
38259 var UNDEFINED;
38260 var NULL = null;
38261 var TRUE = true;
38262 var FALSE = false;
38263 var RAW_NULL = 'null';
38264 var RAW_TRUE = 'true';
38265 var RAW_FALSE = 'false'; // path 中的参数前缀,如 /user/:userId
38266
38267 var PREFIX_PARAM = ':'; // path 分隔符
38268
38269 var SEPARATOR_PATH = '/'; // path 和 search 的分隔符
38270
38271 var SEPARATOR_SEARCH = '?'; // query 分隔符
38272
38273 var SEPARATOR_QUERY = '&'; // 键值对分隔符
38274
38275 var SEPARATOR_PAIR = '='; // 参数中的数组标识
38276
38277 var FLAG_ARRAY = '[]'; // history 模式
38278
38279 var MODE_HISTORY = 'history'; // 导航钩子 - 路由进入之前
38280
38281 var ROUTER_HOOK_BEFORE_ENTER = 'beforeEnter'; // 导航钩子 - 路由进入之后
38282
38283 var ROUTER_HOOK_AFTER_ENTER = 'afterEnter'; // 导航钩子 - 路由更新之前
38284
38285 var ROUTER_HOOK_BEFORE_UPDATE = 'beforeUpdate'; // 导航钩子 - 路由更新之后
38286
38287 var ROUTER_HOOK_AFTER_UPDATE = 'afterUpdate'; // 导航钩子 - 路由离开之前
38288
38289 var ROUTER_HOOK_BEFORE_LEAVE = 'beforeLeave'; // 导航钩子 - 路由离开之后
38290
38291 var ROUTER_HOOK_AFTER_LEAVE = 'afterLeave'; // 组件 Options 上的导航钩子
38292
38293 var COMPONENT_HOOK_BEFORE_ENTER = 'beforeRouteEnter';
38294 var COMPONENT_HOOK_AFTER_ENTER = 'afterRouteEnter';
38295 var COMPONENT_HOOK_BEFORE_UPDATE = 'beforeRouteUpdate';
38296 var COMPONENT_HOOK_AFTER_UPDATE = 'afterRouteUpdate';
38297 var COMPONENT_HOOK_BEFORE_LEAVE = 'beforeRouteLeave';
38298 var COMPONENT_HOOK_AFTER_LEAVE = 'afterRouteLeave';
38299
38300 var Hooks = function () {};
38301
38302 Hooks.prototype.setLocation = function (to, from) {
38303 this.to = to;
38304 this.from = from;
38305 return this;
38306 };
38307
38308 Hooks.prototype.clear = function () {
38309 this.list = [];
38310 return this;
38311 };
38312
38313 Hooks.prototype.add = function (hook, ctx) {
38314 var ref = this;
38315 var list = ref.list;
38316
38317 if (hook) {
38318 list.push({
38319 fn: hook,
38320 ctx: ctx
38321 });
38322 }
38323
38324 return this;
38325 };
38326
38327 Hooks.prototype.next = function (isGuard, next$1, callback) {
38328 var task = this.list.shift();
38329
38330 if (task) {
38331 if (isGuard) {
38332 task.fn.call(task.ctx, this.to, this.from, next$1);
38333 } else {
38334 task.fn.call(task.ctx, this.to, this.from);
38335 next$1();
38336 }
38337 } else {
38338 callback();
38339 }
38340 };
38341 /**
38342 * 把字符串 value 解析成最合适的类型
38343 */
38344
38345
38346 function parse(API, value) {
38347 var result;
38348
38349 if (API.is.numeric(value)) {
38350 result = +value;
38351 } else if (API.is.string(value)) {
38352 if (value === RAW_TRUE) {
38353 result = TRUE;
38354 } else if (value === RAW_FALSE) {
38355 result = FALSE;
38356 } else if (value === RAW_NULL) {
38357 result = NULL;
38358 } else {
38359 result = decodeURIComponent(value);
38360 }
38361 }
38362
38363 return result;
38364 }
38365
38366 function stringify(API, value) {
38367 if (API.is.string(value)) {
38368 return encodeURIComponent(value);
38369 } else if (API.is.number(value) || API.is["boolean"](value)) {
38370 return value.toString();
38371 } else if (value === NULL) {
38372 return RAW_NULL;
38373 }
38374 }
38375 /**
38376 * 把 GET 参数解析成对象
38377 */
38378
38379
38380 function parse$1(API, query) {
38381 var result;
38382 API.array.each(query.split(SEPARATOR_QUERY), function (term) {
38383 var terms = term.split(SEPARATOR_PAIR),
38384 key = API.string.trim(terms[0]),
38385 value = terms[1];
38386
38387 if (key) {
38388 if (!result) {
38389 result = {};
38390 }
38391
38392 value = parse(API, value);
38393
38394 if (API.string.endsWith(key, FLAG_ARRAY)) {
38395 key = API.string.slice(key, 0, -FLAG_ARRAY.length);
38396 API.array.push(result[key] || (result[key] = []), value);
38397 } else {
38398 result[key] = value;
38399 }
38400 }
38401 });
38402 return result;
38403 }
38404 /**
38405 * 把对象解析成 key1=value1&key2=value2
38406 */
38407
38408
38409 function stringify$1(API, query) {
38410 var result = [];
38411
38412 var loop = function (key) {
38413 var value = query[key];
38414
38415 if (API.is.array(value)) {
38416 API.array.each(value, function (value) {
38417 var str = stringify(API, value);
38418
38419 if (API.is.string(str)) {
38420 result.push(key + FLAG_ARRAY + SEPARATOR_PAIR + str);
38421 }
38422 });
38423 } else {
38424 var str = stringify(API, value);
38425
38426 if (API.is.string(str)) {
38427 result.push(key + SEPARATOR_PAIR + str);
38428 }
38429 }
38430 };
38431
38432 for (var key in query) {
38433 loop(key);
38434 }
38435
38436 return result.join(SEPARATOR_QUERY);
38437 }
38438
38439 var POP_STATE = 'popstate';
38440 var isSupported = 'pushState' in HISTORY;
38441
38442 function start(api, handler) {
38443 api.on(WINDOW, POP_STATE, handler);
38444 handler();
38445 }
38446
38447 function stop(api, handler) {
38448 api.off(WINDOW, POP_STATE, handler);
38449 }
38450
38451 function push(location, handler) {
38452 // 调用 pushState 不会触发 popstate 事件
38453 // 因此这里需要手动调用一次 handler
38454 HISTORY.pushState({}, '', location.url);
38455 handler();
38456 }
38457
38458 function replace(location, handler) {
38459 // 调用 replaceState 不会触发 popstate 事件
38460 // 因此这里需要手动调用一次 handler
38461 replaceState(location.url, handler);
38462 }
38463
38464 function go(n) {
38465 HISTORY.go(n);
38466 }
38467
38468 function current() {
38469 return LOCATION.pathname + LOCATION.search;
38470 }
38471
38472 function replaceState(url, handler) {
38473 // try...catch the pushState call to get around Safari
38474 // DOM Exception 18 where it limits to 100 pushState calls
38475 try {
38476 HISTORY.replaceState({}, '', url);
38477 handler();
38478 } catch (e) {
38479 LOCATION.replace(url);
38480 }
38481 }
38482
38483 var historyMode =
38484 /*#__PURE__*/
38485 {
38486 isSupported: isSupported,
38487 start: start,
38488 stop: stop,
38489 push: push,
38490 replace: replace,
38491 go: go,
38492 current: current,
38493 replaceState: replaceState
38494 }; // hash 前缀,Google 的规范是 #! 开头,如 #!/path/sub?key=value
38495
38496 var HASH_PREFIX = '#!',
38497 HASH_CHANGE = 'hashchange';
38498
38499 function start$1(api, handler) {
38500 api.on(WINDOW, HASH_CHANGE, handler);
38501 handler();
38502 }
38503
38504 function stop$1(api, handler) {
38505 api.off(WINDOW, HASH_CHANGE, handler);
38506 }
38507
38508 function push$1(location, handler) {
38509 LOCATION.hash = HASH_PREFIX + location.url;
38510 }
38511
38512 function replace$1(location, handler) {
38513 var url = LOCATION.protocol + '//' + LOCATION.host + LOCATION.pathname + HASH_PREFIX + location.url;
38514
38515 if (isSupported) {
38516 replaceState(url, handler);
38517 } else {
38518 LOCATION.replace(url);
38519 }
38520 }
38521
38522 function go$1(n) {
38523 HISTORY.go(n);
38524 }
38525
38526 function current$1() {
38527 // 不能直接读取 window.location.hash
38528 // 因为 Firefox 会做 pre-decode
38529 var href = LOCATION.href,
38530 index = href.indexOf(HASH_PREFIX);
38531 return index > 0 ? href.substr(index + HASH_PREFIX.length) : SEPARATOR_PATH;
38532 }
38533
38534 var hashMode =
38535 /*#__PURE__*/
38536 {
38537 start: start$1,
38538 stop: stop$1,
38539 push: push$1,
38540 replace: replace$1,
38541 go: go$1,
38542 current: current$1
38543 };
38544
38545 function template404(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) {
38546 var $0,
38547 $2 = !0;
38548 return q("div", $0, $0, "This is a default 404 page, please set \"route404\" for your own 404 page.", $2);
38549 }
38550
38551 function templatePlaceholder(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) {
38552 return r("router-view");
38553 }
38554
38555 function templateRouterView(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) {
38556 var $0;
38557 return r($0, $0, $0, $0, $0, "RouteComponent");
38558 }
38559
38560 var API,
38561 hookEvents,
38562 guid = 0;
38563 var ROUTE_COMPONENT = 'RouteComponent',
38564 NAMESPACE_HOOK = '.hook',
38565 EVENT_CLICK = 'click';
38566 /**
38567 * 格式化路径,确保它以 / 开头,不以 / 结尾
38568 */
38569
38570 function formatPath(path, parentPath) {
38571 // 如果不是 / 开头,表示是相对路径
38572 if (!API.string.startsWith(path, SEPARATOR_PATH)) {
38573 // 确保 parentPath 以 / 结尾
38574 if (parentPath) {
38575 if (!API.string.endsWith(parentPath, SEPARATOR_PATH)) {
38576 parentPath += SEPARATOR_PATH;
38577 }
38578 } else {
38579 parentPath = SEPARATOR_PATH;
38580 }
38581
38582 path = parentPath + path;
38583 } // 如果 path 以 / 结尾,删掉它
38584
38585
38586 if (path !== SEPARATOR_PATH && API.string.endsWith(path, SEPARATOR_PATH)) {
38587 path = API.string.slice(path, 0, -SEPARATOR_PATH.length);
38588 }
38589
38590 return path;
38591 }
38592 /**
38593 * 把结构化数据序列化成 url
38594 */
38595
38596
38597 function stringifyUrl(path, params, query) {
38598 if (/\/\:\w+/.test(path)) {
38599 var terms = [];
38600 API.array.each(path.split(SEPARATOR_PATH), function (item) {
38601 terms.push(API.string.startsWith(item, PREFIX_PARAM) && params ? params[item.substr(PREFIX_PARAM.length)] : item);
38602 });
38603 path = terms.join(SEPARATOR_PATH);
38604 }
38605
38606 if (query) {
38607 var queryStr = stringify$1(API, query);
38608
38609 if (queryStr) {
38610 path += SEPARATOR_SEARCH + queryStr;
38611 }
38612 }
38613
38614 return path;
38615 }
38616 /**
38617 * 按照 propTypes 定义的外部数据格式过滤路由参数,这样有两个好处:
38618 *
38619 * 1. 避免传入不符预期的数据
38620 * 2. 避免覆盖 data 定义的数据
38621 */
38622
38623
38624 function filterProps(route, location, options) {
38625 var result = {},
38626 propTypes = options.propTypes;
38627
38628 if (propTypes) {
38629 var props = location.query,
38630 routeParams = route.params,
38631 locationParams = location.params; // 从 location.params 挑出 route.params 定义过的参数
38632
38633 if (routeParams && locationParams) {
38634 props = props ? API.object.copy(props) : {};
38635
38636 for (var i = 0, length = routeParams.length; i < length; i++) {
38637 props[routeParams[i]] = locationParams[routeParams[i]];
38638 }
38639 }
38640
38641 if (props) {
38642 for (var key in propTypes) {
38643 var value = props[key];
38644
38645 if (value !== UNDEFINED) {
38646 result[key] = value;
38647 }
38648 }
38649 }
38650 }
38651
38652 return result;
38653 }
38654 /**
38655 * 是否是叶子节点
38656 * 如果把叶子节点放在 if 中,会出现即使不是定义时的叶子节点,却是运行时的叶子节点
38657 */
38658
38659
38660 function isLeafRoute(route) {
38661 var child = route.child;
38662 return !child || !child.context;
38663 }
38664
38665 function updateRoute(instance, componentHookName, routerHookName, upsert) {
38666 var route = instance.$route;
38667
38668 if (route) {
38669 route.context = upsert ? instance : UNDEFINED;
38670
38671 if (isLeafRoute(route)) {
38672 var router = instance.$router;
38673
38674 if (componentHookName && routerHookName) {
38675 router.hook(route, componentHookName, routerHookName, FALSE);
38676 }
38677
38678 if (upsert) {
38679 var pending = router.pending;
38680
38681 if (pending) {
38682 pending.onComplete();
38683 router.pending = UNDEFINED;
38684 }
38685 }
38686 }
38687 }
38688 }
38689
38690 var Router = function (options) {
38691 var instance = this,
38692 el = options.el,
38693 route404 = options.route404 || default404;
38694 instance.options = options;
38695 instance.el = API.is.string(el) ? API.dom.find(el) : el;
38696 {
38697 if (!instance.el) {
38698 API.logger.error("The \"el\" option must be an element or a selector.");
38699 return;
38700 }
38701 }
38702 instance.mode = options.mode === MODE_HISTORY && isSupported ? historyMode : hashMode;
38703
38704 instance.handler = function () {
38705 // 从地址栏读取最新 url
38706 instance.parseLocation(instance.mode.current(), function (location) {
38707 if (location) {
38708 instance.setRoute(location);
38709 } else {
38710 instance.push(instance.route404);
38711 }
38712 });
38713 };
38714
38715 instance.routes = [];
38716 instance.name2Path = {};
38717 instance.path2Route = {};
38718 instance.hooks = new Hooks();
38719 API.array.each(options.routes, function (route) {
38720 instance.add(route);
38721 });
38722 instance.route404 = instance.add(route404)[0];
38723 };
38724 /**
38725 * 添加一个新的路由
38726 */
38727
38728
38729 Router.prototype.add = function (routeOptions, parentRoute) {
38730 var instance = this,
38731 newRoutes = [],
38732 pathStack = [],
38733 routeStack = [],
38734 addRoute = function (routeOptions) {
38735 var name = routeOptions.name;
38736 var component = routeOptions.component;
38737 var children = routeOptions.children;
38738 var load = routeOptions.load;
38739 var parentPath = API.array.last(pathStack),
38740 parentRoute = API.array.last(routeStack),
38741 path = formatPath(routeOptions.path, parentPath),
38742 route = {
38743 path: path,
38744 route: routeOptions
38745 },
38746 params = [];
38747 API.array.each(path.split(SEPARATOR_PATH), function (item) {
38748 if (API.string.startsWith(item, PREFIX_PARAM)) {
38749 params.push(item.substr(PREFIX_PARAM.length));
38750 }
38751 });
38752
38753 if (params.length) {
38754 route.params = params;
38755 }
38756
38757 if (name) {
38758 route.name = name;
38759 } // component 和 load 二选一
38760
38761
38762 if (load) {
38763 route.load = load;
38764 } else {
38765 // 每一级都必须有一个组件
38766 // 如果没有,则用占位组件,避免业务层写太多无用的组件
38767 route.component = component || placeholderComponent;
38768 }
38769
38770 if (parentRoute) {
38771 route.parent = parentRoute;
38772 }
38773
38774 if (children) {
38775 pathStack.push(path);
38776 routeStack.push(route);
38777 API.array.each(children, addRoute);
38778 routeStack.pop();
38779 pathStack.pop();
38780 } else {
38781 newRoutes.push(route);
38782 instance.routes.push(route);
38783
38784 if (name) {
38785 {
38786 if (API.object.has(instance.name2Path, name)) {
38787 API.logger.error("The name \"" + name + "\" of the route is existed.");
38788 return;
38789 }
38790 }
38791 instance.name2Path[name] = path;
38792 }
38793
38794 {
38795 if (API.object.has(instance.path2Route, path)) {
38796 API.logger.error("The path \"" + path + "\" of the route is existed.");
38797 return;
38798 }
38799 }
38800 instance.path2Route[path] = route;
38801 }
38802 };
38803
38804 if (parentRoute) {
38805 pathStack.push(parentRoute.path);
38806 routeStack.push(parentRoute);
38807 }
38808
38809 addRoute(routeOptions);
38810 return newRoutes;
38811 };
38812 /**
38813 * 删除一个已注册的路由
38814 */
38815
38816
38817 Router.prototype.remove = function (route) {
38818 var instance = this;
38819 API.array.remove(instance.routes, route);
38820
38821 if (route.name) {
38822 delete instance.name2Path[route.name];
38823 }
38824
38825 delete instance.path2Route[route.path];
38826 };
38827 /**
38828 * target 有 3 种格式:
38829 *
38830 * 如果只是简单的 path,直接传字符串
38831 *
38832 * push('/index')
38833 *
38834 * 如果需要带参数,可传对象
38835 *
38836 * push({
38837 * path: '/index',
38838 * params: { },
38839 * query: { }
38840 * })
38841 *
38842 * 如果路由配置了 name,可用 name 代替 path,如下:
38843 *
38844 * push({
38845 * name: 'index'
38846 * })
38847 *
38848 * 也可以不传 path 或 name,只传 params 或 query
38849 * 表示不修改 path,仅修改 params 或 query
38850 *
38851 */
38852
38853
38854 Router.prototype.push = function (target) {
38855 var instance = this;
38856 var mode = instance.mode;
38857 instance.setUrl(instance.toUrl(target), function (location) {
38858 if (mode.current() !== location.url) {
38859 mode.push(location, instance.handler);
38860 }
38861 });
38862 };
38863 /**
38864 * 替换当前路由栈
38865 */
38866
38867
38868 Router.prototype.replace = function (target) {
38869 var instance = this;
38870 var mode = instance.mode;
38871 instance.setUrl(instance.toUrl(target), function (location) {
38872 if (mode.current() !== location.url) {
38873 mode.replace(location, instance.handler);
38874 }
38875 });
38876 };
38877 /**
38878 * 前进或后退 n 步
38879 */
38880
38881
38882 Router.prototype.go = function (n) {
38883 this.mode.go(n);
38884 };
38885 /**
38886 * 启动路由
38887 */
38888
38889
38890 Router.prototype.start = function () {
38891 this.mode.start(API.dom, this.handler);
38892 };
38893 /**
38894 * 停止路由
38895 */
38896
38897
38898 Router.prototype.stop = function () {
38899 this.mode.stop(API.dom, this.handler);
38900 };
38901 /**
38902 * 钩子函数
38903 */
38904
38905
38906 Router.prototype.hook = function (route, componentHook, routerHook, isGuard, callback) {
38907 var instance = this;
38908 var location = instance.location;
38909 var hooks = instance.hooks;
38910 var pending = instance.pending;
38911 var context = route.context;
38912
38913 var onComplete = function () {
38914 // 如果钩子未被拦截,则会走进 onComplete
38915 // 这里要把钩子事件冒泡上去,便于业务层处理
38916 // 加命名空间是为了和 yox 生命周期钩子事件保持一致
38917 if (context) {
38918 context.fire(componentHook + NAMESPACE_HOOK, {
38919 from: hooks.from,
38920 to: hooks.to
38921 });
38922 } // 在发事件之后调用 callback
38923 // 因为 callback 有可能销毁组件,导致事件发不出去
38924
38925
38926 if (callback) {
38927 callback();
38928 }
38929 },
38930 next = function (value) {
38931 if (value === UNDEFINED) {
38932 hooks.next(isGuard, next, onComplete);
38933 } else {
38934 // 只有前置守卫才有可能走进这里
38935 // 此时 instance.location 还是旧地址
38936 if (pending) {
38937 pending.onAbort();
38938 instance.pending = UNDEFINED;
38939 }
38940
38941 if (value === FALSE) {
38942 if (location) {
38943 instance.push(location);
38944 }
38945 } else {
38946 // 跳转到别的路由
38947 instance.push(value);
38948 }
38949 }
38950 };
38951
38952 hooks.clear() // 先调用组件的钩子
38953 .add(route.component[componentHook], context) // 再调用路由配置的钩子
38954 .add(route.route[routerHook], route.route) // 最后调用路由实例的钩子
38955 .add(instance.options[routerHook], instance);
38956 next();
38957 };
38958
38959 Router.prototype.toUrl = function (target) {
38960 if (API.is.string(target)) {
38961 return formatPath(target);
38962 }
38963
38964 var instance = this,
38965 location = instance.location,
38966 routeTarget = target,
38967 params = routeTarget.params,
38968 path;
38969
38970 if (routeTarget.name) {
38971 path = instance.name2Path[routeTarget.name];
38972 } else if (routeTarget.path) {
38973 path = formatPath(routeTarget.path);
38974 } else if (location) {
38975 path = location.path;
38976
38977 if (!params) {
38978 params = location.params;
38979 }
38980 }
38981
38982 {
38983 if (!API.is.string(path)) {
38984 API.logger.error("The path is not found.");
38985 }
38986 }
38987 return stringifyUrl(path, params, routeTarget.query);
38988 };
38989
38990 Router.prototype.setUrl = function (url, callback) {
38991 // 这里无需判断新旧 url 是否相同,因为存在 replace,即使它们相同也不等价于不用跳转
38992 var instance = this;
38993 instance.parseLocation(url, function (location) {
38994 if (location) {
38995 callback(location);
38996 }
38997 });
38998 };
38999
39000 Router.prototype.parseLocation = function (url, callback) {
39001 var realpath,
39002 search,
39003 index = url.indexOf(SEPARATOR_SEARCH);
39004
39005 if (index >= 0) {
39006 realpath = url.slice(0, index);
39007 search = url.slice(index + 1);
39008 } else {
39009 realpath = url;
39010 } // 匹配已注册的 route
39011
39012
39013 var instance = this,
39014 realpathTerms = realpath.split(SEPARATOR_PATH),
39015 length = realpathTerms.length,
39016 matchRoute = function (routes, callback) {
39017 var index = 0,
39018 route;
39019
39020 loop: while (route = routes[index++]) {
39021 var path = route.path; // 动态路由
39022
39023 if (route.params) {
39024 var pathTerms = path.split(SEPARATOR_PATH); // path 段数量必须一致,否则没有比较的意义
39025
39026 if (length === pathTerms.length) {
39027 var params = {};
39028
39029 for (var i = 0; i < length; i++) {
39030 if (API.string.startsWith(pathTerms[i], PREFIX_PARAM)) {
39031 params[pathTerms[i].substr(PREFIX_PARAM.length)] = parse(API, realpathTerms[i]);
39032 } // 非参数段不相同
39033 else if (pathTerms[i] !== realpathTerms[i]) {
39034 continue loop;
39035 }
39036 }
39037
39038 callback(route, params);
39039 return;
39040 }
39041 } // 懒加载路由,前缀匹配成功后,意味着懒加载回来的路由一定有我们想要的
39042 else if (route.load && API.string.startsWith(realpath, path)) {
39043 var routeCallback = function (lazyRoute) {
39044 instance.remove(route);
39045 matchRoute(instance.add(lazyRoute['default'] || lazyRoute, route.parent), callback);
39046 };
39047
39048 var promise = route.load(routeCallback);
39049
39050 if (promise) {
39051 promise.then(routeCallback);
39052 }
39053
39054 return;
39055 } else if (path === realpath) {
39056 callback(route);
39057 return;
39058 }
39059 }
39060
39061 callback();
39062 };
39063
39064 matchRoute(instance.routes, function (route, params) {
39065 if (route) {
39066 var location = {
39067 url: url,
39068 path: route.path
39069 };
39070
39071 if (params) {
39072 location.params = params;
39073 }
39074
39075 if (search) {
39076 var query = parse$1(API, search);
39077
39078 if (query) {
39079 location.query = query;
39080 }
39081 }
39082
39083 callback(location);
39084 } else {
39085 {
39086 API.logger.error("The path \"" + realpath + "\" can't match a route.");
39087 }
39088 callback();
39089 }
39090 });
39091 };
39092
39093 Router.prototype.diffRoute = function (route, oldRoute, onComplete, startRoute, childRoute, oldTopRoute) {
39094 // 更新链路
39095 if (childRoute) {
39096 route.child = childRoute;
39097 childRoute.parent = route;
39098 }
39099
39100 if (oldRoute) {
39101 // 同级的两个组件不同,疑似起始更新的路由
39102 if (oldRoute.component !== route.component) {
39103 startRoute = route;
39104 } else {
39105 // 把上次的组件实例搞过来
39106 route.context = oldRoute.context;
39107 }
39108 } else {
39109 startRoute = route;
39110 }
39111
39112 if (route.parent) {
39113 this.diffRoute(API.object.copy(route.parent), oldRoute ? oldRoute.parent : UNDEFINED, onComplete, startRoute, route, oldRoute || oldTopRoute);
39114 return;
39115 } // 整个组件树全换掉
39116
39117
39118 if (startRoute === route) {
39119 var context; // 当层级较多的路由切换到层级较少的路由
39120
39121 if (oldRoute) {
39122 while (oldRoute) {
39123 context = oldRoute.context;
39124 oldRoute = oldRoute.parent;
39125 }
39126 } // 当层级较少的路由切换到层级较多的路由
39127 else if (oldTopRoute) {
39128 context = oldTopRoute.context;
39129 }
39130
39131 if (context) {
39132 startRoute.context = context;
39133 }
39134 } // 到达根组件,结束
39135
39136
39137 onComplete(route, startRoute);
39138 };
39139
39140 Router.prototype.patchRoute = function (route, startRoute) {
39141 var instance = this,
39142 location = instance.location; // 从上往下更新 props
39143
39144 while (route) {
39145 var parent = route.parent;
39146 var context = route.context;
39147 var component = route.component;
39148
39149 if (route === startRoute) {
39150 if (parent) {
39151 context = parent.context;
39152 context.forceUpdate(filterProps(parent, location, parent.component));
39153 context = context.$routeView;
39154
39155 if (context) {
39156 var props = {},
39157 name = ROUTE_COMPONENT + ++guid;
39158 props[ROUTE_COMPONENT] = name;
39159 context.component(name, component);
39160 context.forceUpdate(props);
39161 }
39162 } else {
39163 if (context) {
39164 context.destroy();
39165 } // 每层路由组件都有 $route 和 $router 属性
39166
39167
39168 var extensions = {
39169 $router: instance,
39170 $route: route
39171 };
39172 var options = API.object.extend({
39173 el: instance.el,
39174 props: filterProps(route, location, component),
39175 extensions: extensions
39176 }, component);
39177 options.events = options.events ? API.object.extend(options.events, hookEvents) : hookEvents;
39178 route.context = new API(options);
39179 }
39180 } else if (context) {
39181 if (context.$vnode) {
39182 context.$route = route;
39183 context.forceUpdate(filterProps(route, location, component));
39184 } else {
39185 route.context = UNDEFINED;
39186 }
39187
39188 if (route.child) {
39189 route = route.child;
39190 continue;
39191 }
39192 }
39193
39194 break;
39195 }
39196 };
39197
39198 Router.prototype.setRoute = function (location) {
39199 var instance = this,
39200 linkedRoute = instance.path2Route[location.path],
39201 redirect = linkedRoute.route.redirect;
39202
39203 if (redirect) {
39204 if (API.is.func(redirect)) {
39205 redirect = redirect(location);
39206 }
39207
39208 if (redirect) {
39209 instance.push(redirect);
39210 return;
39211 }
39212 }
39213
39214 var newRoute = API.object.copy(linkedRoute),
39215 oldRoute = instance.route,
39216 oldLocation = instance.location,
39217 enterRoute = function () {
39218 instance.diffRoute(newRoute, oldRoute, function (route, startRoute) {
39219 instance.hook(newRoute, startRoute ? COMPONENT_HOOK_BEFORE_ENTER : COMPONENT_HOOK_BEFORE_UPDATE, startRoute ? ROUTER_HOOK_BEFORE_ENTER : ROUTER_HOOK_BEFORE_UPDATE, TRUE, function () {
39220 instance.route = newRoute;
39221 instance.location = location;
39222 instance.patchRoute(route, startRoute);
39223 });
39224 });
39225 };
39226
39227 instance.hooks.setLocation(location, oldLocation);
39228
39229 if (oldRoute && oldLocation && location.path !== oldLocation.path) {
39230 instance.hook(oldRoute, COMPONENT_HOOK_BEFORE_LEAVE, ROUTER_HOOK_BEFORE_LEAVE, TRUE, enterRoute);
39231 return;
39232 }
39233
39234 enterRoute();
39235 };
39236
39237 var default404 = {
39238 path: '/404',
39239 component: {
39240 template: template404
39241 }
39242 },
39243 // 占位组件
39244 placeholderComponent = {
39245 template: templatePlaceholder
39246 },
39247 directive = {
39248 bind: function bind(node, directive, vnode) {
39249 // 当前组件如果是根组件,则没有 $root 属性
39250 var $root = vnode.context.$root || vnode.context,
39251 router = $root.$router,
39252 listener = vnode.data[directive.key] = function (_) {
39253 var value = directive.value;
39254 var getter = directive.getter;
39255 var target = value;
39256
39257 if (value && getter && API.string.has(value, '{')) {
39258 target = getter();
39259 }
39260
39261 router[directive.name](target);
39262 };
39263
39264 if (vnode.isComponent) {
39265 node.on(EVENT_CLICK, listener);
39266 } else {
39267 API.dom.on(node, EVENT_CLICK, listener);
39268 }
39269 },
39270 unbind: function unbind(node, directive, vnode) {
39271 var listener = vnode.data[directive.key];
39272
39273 if (vnode.isComponent) {
39274 node.off(EVENT_CLICK, listener);
39275 } else {
39276 API.dom.off(node, EVENT_CLICK, listener);
39277 }
39278 }
39279 },
39280 RouterView = {
39281 template: templateRouterView,
39282 beforeCreate: function beforeCreate(options) {
39283 var context = options.context,
39284 // context 一定有 $route 属性
39285 route = context.$route.child;
39286
39287 if (route) {
39288 context.$routeView = this;
39289 var props = options.props = {},
39290 components = options.components = {},
39291 name = ROUTE_COMPONENT + ++guid;
39292 props[ROUTE_COMPONENT] = name;
39293 components[name] = route.component;
39294 }
39295 },
39296 beforeDestroy: function beforeDestroy() {
39297 this.$context.$routeView = UNDEFINED;
39298 }
39299 };
39300 /**
39301 * 版本
39302 */
39303
39304 var version = "1.0.0-alpha.51";
39305 /**
39306 * 安装插件
39307 */
39308
39309 function install(Y) {
39310 API = Y;
39311 API.directive({
39312 push: directive,
39313 replace: directive,
39314 go: directive
39315 });
39316 API.component('router-view', RouterView);
39317 hookEvents = {};
39318
39319 hookEvents['beforeCreate' + NAMESPACE_HOOK] = function (event, data) {
39320 if (data) {
39321 var options = data;
39322 var context = options.context; // 当前组件是 <router-view> 中的动态组件
39323
39324 if (context && context.$options.beforeCreate === RouterView.beforeCreate) {
39325 // 找到渲染 <router-view> 的父级组件,它是一定存在的
39326 context = context.$context;
39327 var router = context.$router,
39328 // context 一定有 $route 属性
39329 route = context.$route.child;
39330
39331 if (route) {
39332 options.extensions = {
39333 $router: router,
39334 $route: route
39335 };
39336
39337 if (router.location) {
39338 options.props = filterProps(route, router.location, options);
39339 }
39340 }
39341 }
39342 }
39343 };
39344
39345 hookEvents['afterMount' + NAMESPACE_HOOK] = function (event) {
39346 updateRoute(event.target, COMPONENT_HOOK_AFTER_ENTER, ROUTER_HOOK_AFTER_ENTER, TRUE);
39347 };
39348
39349 hookEvents['afterUpdate' + NAMESPACE_HOOK] = function (event) {
39350 updateRoute(event.target, COMPONENT_HOOK_AFTER_UPDATE, ROUTER_HOOK_AFTER_UPDATE, TRUE);
39351 };
39352
39353 hookEvents['afterDestroy' + NAMESPACE_HOOK] = function (event) {
39354 updateRoute(event.target, COMPONENT_HOOK_AFTER_LEAVE, ROUTER_HOOK_AFTER_LEAVE);
39355 };
39356 }
39357
39358 exports.Router = Router;
39359 exports.install = install;
39360 exports.version = version;
39361 Object.defineProperty(exports, '__esModule', {
39362 value: true
39363 });
39364 });
39365 });
39366 unwrapExports(yoxRouter);
39367
39368 var dayjs_min = createCommonjsModule(function (module, exports) {
39369 !function(t,n){module.exports=n();}(commonjsGlobal,function(){var t="millisecond",n="second",e="minute",r="hour",i="day",s="week",u="month",a="year",o=/^(\d{4})-?(\d{1,2})-?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d{1,3})?$/,h=/\[.*?\]|Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,f=function(t,n,e){var r=String(t);return !r||r.length>=n?t:""+Array(n+1-r.length).join(e)+t},c={padStart:f,padZoneStr:function(t){var n=Math.abs(t),e=Math.floor(n/60),r=n%60;return (t<=0?"+":"-")+f(e,2,"0")+":"+f(r,2,"0")},monthDiff:function(t,n){var e=12*(n.year()-t.year())+(n.month()-t.month()),r=t.clone().add(e,"months"),i=n-r<0,s=t.clone().add(e+(i?-1:1),"months");return Number(-(e+(n-r)/(i?r-s:s-r))||0)},absFloor:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},prettyUnit:function(o){return {M:u,y:a,w:s,d:i,h:r,m:e,s:n,ms:t}[o]||String(o||"").toLowerCase().replace(/s$/,"")},isUndefined:function(t){return void 0===t}},d={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},$="en",l={};l[$]=d;var m=function(t){return t instanceof D},y=function(t,n,e){var r;if(!t)return null;if("string"==typeof t)l[t]&&(r=t),n&&(l[t]=n,r=t);else{var i=t.name;l[i]=t,r=i;}return e||($=r),r},M=function(t,n){if(m(t))return t.clone();var e=n?"string"==typeof n?{format:n}:n:{};return e.date=t,new D(e)},S=function(t,n){return M(t,{locale:n.$L})},p=c;p.parseLocale=y,p.isDayjs=m,p.wrapper=S;var D=function(){function f(t){this.parse(t);}var c=f.prototype;return c.parse=function(t){var n,e;this.$d=null===(n=t.date)?new Date(NaN):p.isUndefined(n)?new Date:n instanceof Date?n:"string"==typeof n&&/.*[^Z]$/i.test(n)&&(e=n.match(o))?new Date(e[1],e[2]-1,e[3]||1,e[4]||0,e[5]||0,e[6]||0,e[7]||0):new Date(n),this.init(t);},c.init=function(t){var n=this.$d;this.$y=n.getFullYear(),this.$M=n.getMonth(),this.$D=n.getDate(),this.$W=n.getDay(),this.$H=n.getHours(),this.$m=n.getMinutes(),this.$s=n.getSeconds(),this.$ms=n.getMilliseconds(),this.$L=this.$L||y(t.locale,null,!0)||$;},c.$utils=function(){return p},c.isValid=function(){return !("Invalid Date"===this.$d.toString())},c.isSame=function(t,n){var e=M(t);return this.startOf(n)<=e&&e<=this.endOf(n)},c.isAfter=function(t,n){return M(t)<this.startOf(n)},c.isBefore=function(t,n){return this.endOf(n)<M(t)},c.year=function(){return this.$y},c.month=function(){return this.$M},c.day=function(){return this.$W},c.date=function(){return this.$D},c.hour=function(){return this.$H},c.minute=function(){return this.$m},c.second=function(){return this.$s},c.millisecond=function(){return this.$ms},c.unix=function(){return Math.floor(this.valueOf()/1e3)},c.valueOf=function(){return this.$d.getTime()},c.startOf=function(t,o){var h=this,f=!!p.isUndefined(o)||o,c=p.prettyUnit(t),d=function(t,n){var e=S(new Date(h.$y,n,t),h);return f?e:e.endOf(i)},$=function(t,n){return S(h.toDate()[t].apply(h.toDate(),(f?[0,0,0,0]:[23,59,59,999]).slice(n)),h)},l=this.$W,m=this.$M,y=this.$D;switch(c){case a:return f?d(1,0):d(31,11);case u:return f?d(1,m):d(0,m+1);case s:var M=this.$locale().weekStart||0,D=(l<M?l+7:l)-M;return d(f?y-D:y+(6-D),m);case i:case"date":return $("setHours",0);case r:return $("setMinutes",1);case e:return $("setSeconds",2);case n:return $("setMilliseconds",3);default:return this.clone()}},c.endOf=function(t){return this.startOf(t,!1)},c.$set=function(s,o){var h,f=p.prettyUnit(s),c=(h={},h[i]="setDate",h.date="setDate",h[u]="setMonth",h[a]="setFullYear",h[r]="setHours",h[e]="setMinutes",h[n]="setSeconds",h[t]="setMilliseconds",h)[f],d=f===i?this.$D+(o-this.$W):o;return this.$d[c]&&this.$d[c](d),this.init(),this},c.set=function(t,n){return this.clone().$set(t,n)},c.add=function(t,o){var h,f=this;t=Number(t);var c=p.prettyUnit(o),d=function(n,e){var r=f.set("date",1).set(n,e+t);return r.set("date",Math.min(f.$D,r.daysInMonth()))},$=function(n){var e=new Date(f.$d);return e.setDate(e.getDate()+n*t),S(e,f)};if(c===u)return d(u,this.$M);if(c===a)return d(a,this.$y);if(c===i)return $(1);if(c===s)return $(7);var l=(h={},h[e]=6e4,h[r]=36e5,h[n]=1e3,h)[c]||1,m=this.valueOf()+t*l;return S(m,this)},c.subtract=function(t,n){return this.add(-1*t,n)},c.format=function(t){var n=this;if(!this.isValid())return "Invalid Date";var e=t||"YYYY-MM-DDTHH:mm:ssZ",r=p.padZoneStr(this.$d.getTimezoneOffset()),i=this.$locale(),s=i.weekdays,u=i.months,a=function(t,n,e,r){return t&&t[n]||e[n].substr(0,r)},o=function(t){return 0===n.$H?12:p.padStart(n.$H<13?n.$H:n.$H-12,"hh"===t?2:1,"0")},f={YY:String(this.$y).slice(-2),YYYY:String(this.$y),M:String(this.$M+1),MM:p.padStart(this.$M+1,2,"0"),MMM:a(i.monthsShort,this.$M,u,3),MMMM:u[this.$M],D:String(this.$D),DD:p.padStart(this.$D,2,"0"),d:String(this.$W),dd:a(i.weekdaysMin,this.$W,s,2),ddd:a(i.weekdaysShort,this.$W,s,3),dddd:s[this.$W],H:String(this.$H),HH:p.padStart(this.$H,2,"0"),h:o("h"),hh:o("hh"),a:this.$H<12?"am":"pm",A:this.$H<12?"AM":"PM",m:String(this.$m),mm:p.padStart(this.$m,2,"0"),s:String(this.$s),ss:p.padStart(this.$s,2,"0"),SSS:p.padStart(this.$ms,3,"0"),Z:r};return e.replace(h,function(t){return t.indexOf("[")>-1?t.replace(/\[|\]/g,""):f[t]||r.replace(":","")})},c.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},c.diff=function(t,o,h){var f,c=p.prettyUnit(o),d=M(t),$=6e4*(d.utcOffset()-this.utcOffset()),l=this-d,m=p.monthDiff(this,d);return m=(f={},f[a]=m/12,f[u]=m,f.quarter=m/3,f[s]=(l-$)/6048e5,f[i]=(l-$)/864e5,f[r]=l/36e5,f[e]=l/6e4,f[n]=l/1e3,f)[c]||l,h?m:p.absFloor(m)},c.daysInMonth=function(){return this.endOf(u).$D},c.$locale=function(){return l[this.$L]},c.locale=function(t,n){var e=this.clone();return e.$L=y(t,n,!0),e},c.clone=function(){return S(this.toDate(),this)},c.toDate=function(){return new Date(this.$d)},c.toArray=function(){return [this.$y,this.$M,this.$D,this.$H,this.$m,this.$s,this.$ms]},c.toJSON=function(){return this.toISOString()},c.toISOString=function(){return this.$d.toISOString()},c.toObject=function(){return {years:this.$y,months:this.$M,date:this.$D,hours:this.$H,minutes:this.$m,seconds:this.$s,milliseconds:this.$ms}},c.toString=function(){return this.$d.toUTCString()},f}();return M.prototype=D.prototype,M.extend=function(t,n){return t(n,D,M),M},M.locale=y,M.isDayjs=m,M.unix=function(t){return M(1e3*t)},M.en=l[$],M});
39370 });
39371
39372 var zhCn = createCommonjsModule(function (module, exports) {
39373 !function(_,e){module.exports=e(dayjs_min);}(commonjsGlobal,function(_){_=_&&_.hasOwnProperty("default")?_["default"]:_;var e={name:"zh-cn",weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),ordinal:function(_){return _+"日"},weekStart:1,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah点mm分",LLLL:"YYYY年M月D日ddddAh点mm分"},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"}};return _.locale(e,null,!0),e});
39374 });
39375
39376 var zhTw = createCommonjsModule(function (module, exports) {
39377 !function(_,e){module.exports=e(dayjs_min);}(commonjsGlobal,function(_){_=_&&_.hasOwnProperty("default")?_["default"]:_;var e={name:"zh-tw",weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),ordinal:function(_){return _+"日"},formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm"},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}};return _.locale(e,null,!0),e});
39378 });
39379
39380 var en = createCommonjsModule(function (module, exports) {
39381 !function(e,n){module.exports=n();}(commonjsGlobal,function(){return {name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")}});
39382 });
39383
39384 var advancedFormat = createCommonjsModule(function (module, exports) {
39385 !function(t,e){module.exports=e();}(commonjsGlobal,function(){return function(t,e,n){var r=e.prototype,i=r.format;n.en.ordinal=function(t){var e=["th","st","nd","rd"],n=t%100;return "["+t+(e[(n-20)%10]||e[n]||e[0])+"]"},r.format=function(t){var e=this,n=this.$locale(),r=this.$utils(),o=(t||"YYYY-MM-DDTHH:mm:ssZ").replace(/Q|Do|X|x|k{1,2}|S/g,function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"k":case"kk":return r.padStart(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);default:return e.$d.getTime()}});return i.bind(this)(o)};}});
39386 });
39387
39388 var relativeTime = createCommonjsModule(function (module, exports) {
39389 !function(e,r){module.exports=r();}(commonjsGlobal,function(){return function(e,r,t){var n=r.prototype;t.en.relativeTime={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};var o=function(e,r,n,o){for(var d,i,a=n.$locale().relativeTime,u=[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],f=u.length,s=0;s<f;s+=1){var l=u[s];l.d&&(d=o?t(e).diff(n,l.d,!0):n.diff(e,l.d,!0));var m=Math.ceil(Math.abs(d));if(m<=l.r||!l.r){i=a[l.l].replace("%d",m);break}}return r?i:(d>0?a.future:a.past).replace("%s",i)};n.to=function(e,r){return o(e,r,this,!0)},n.from=function(e,r){return o(e,r,this)},n.toNow=function(e){return this.to(t(),e)},n.fromNow=function(e){return this.from(t(),e)};}});
39390 });
39391
39392 var isLeapYear = createCommonjsModule(function (module, exports) {
39393 !function(e,t){module.exports=t();}(commonjsGlobal,function(){return function(e,t){t.prototype.isLeapYear=function(){return this.$y%4==0&&this.$y%100!=0||this.$y%400==0};}});
39394 });
39395
39396 var weekOfYear = createCommonjsModule(function (module, exports) {
39397 !function(e,t){module.exports=t();}(commonjsGlobal,function(){var e="year";return function(t,i,n){var d=i.prototype;d.week=function(t){if(void 0===t&&(t=null),null!==t)return this.add(7*(t-this.week()),"day");var i=this.endOf(e);if(6!==i.day()&&11===this.month()&&31-this.date()<=i.day())return 1;var d=n(this.$d).startOf(e),r=d.subtract(d.day(),"day").subtract(1,"millisecond"),u=this.diff(r,"week",!0);return Math.ceil(u)},d.weeks=function(e){return void 0===e&&(e=null),this.week(e)};}});
39398 });
39399
39400 var isSameOrAfter = createCommonjsModule(function (module, exports) {
39401 !function(e,t){module.exports=t();}(commonjsGlobal,function(){return function(e,t){t.prototype.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)};}});
39402 });
39403
39404 var isSameOrBefore = createCommonjsModule(function (module, exports) {
39405 !function(e,t){module.exports=t();}(commonjsGlobal,function(){return function(e,t){t.prototype.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)};}});
39406 });
39407
39408 var isBetween = createCommonjsModule(function (module, exports) {
39409 !function(e,t){module.exports=t();}(commonjsGlobal,function(){return function(e,t,i){t.prototype.isBetween=function(e,t,s,f){var n=i(e),o=i(t),r="("===(f=f||"()")[0],u=")"===f[1];return (r?this.isAfter(n,s):!this.isBefore(n,s))&&(u?this.isBefore(o,s):!this.isAfter(o,s))||(r?this.isBefore(n,s):!this.isAfter(n,s))&&(u?this.isAfter(o,s):!this.isBefore(o,s))};}});
39410 });
39411
39412 var quarterOfYear = createCommonjsModule(function (module, exports) {
39413 !function(e,t){module.exports=t();}(commonjsGlobal,function(){return function(e,t){t.prototype.quarter=function(){return Math.ceil((this.month()+1)/3)};}});
39414 });
39415
39416 /*
39417 This file 'dayjs' is part of Firebird Integrated Solution 1.0
39418
39419 Copyright (c) 2019 Lincong
39420
39421 Contact:
39422 Email: lincong1987@gmail.com
39423
39424 QQ: 159257119
39425
39426 See Usage at http://www.jplatformx.com/firebird
39427
39428 Create date: 2019-01-15 16:22
39429 */
39430
39431 dayjs_min.locales = {
39432 "zh-cn": zhCn,
39433 "zh-tw": zhTw,
39434 "en": en
39435 };
39436 dayjs_min.extend(advancedFormat); // 使用插件
39437
39438 dayjs_min.extend(relativeTime);
39439 dayjs_min.extend(isLeapYear);
39440 dayjs_min.extend(weekOfYear);
39441 dayjs_min.extend(isSameOrAfter);
39442 dayjs_min.extend(isSameOrBefore);
39443 dayjs_min.extend(isBetween);
39444 dayjs_min.extend(quarterOfYear);
39445 dayjs_min.locale(zhCn);
39446 var dayjs_1 = {
39447 dayjs: dayjs_min
39448 };
39449
39450 var name = "fb-core";
39451 var version = "1.0.33";
39452 var description = "fb-core";
39453 var main = "./dist/fb-core.js";
39454 var scripts = {
39455 build: "node build/build.js",
39456 inspect: "node --inspect build/build.js",
39457 publish1: "npm publish"
39458 };
39459 var author = "lincong1987@gmail.com";
39460 var license = "MIT";
39461 var bugs = {
39462 url: "https://github.com/lincong1987/fb-core/issues"
39463 };
39464 var homepage = "https://github.com/lincong1987/fb-core#readme";
39465 var devDependencies = {
39466 "@babel/core": "^7.3.4",
39467 "@babel/helper-module-imports": "^7.0.0",
39468 "@babel/plugin-proposal-object-rest-spread": "^7.3.4",
39469 "@babel/plugin-transform-runtime": "^7.3.4",
39470 "@babel/preset-env": "^7.3.4",
39471 es3ify: "^0.2.2",
39472 esprima: "^4.0.1",
39473 jstransform: "^11.0.3",
39474 rollup: "^1.4.1",
39475 "rollup-plugin-babel": "^4.3.2",
39476 "rollup-plugin-commonjs": "^9.2.1",
39477 "rollup-plugin-json": "^3.1.0",
39478 "rollup-plugin-node-resolve": "^4.0.1",
39479 "rollup-plugin-serve": "^1.0.1",
39480 "uglify-es": "^3.3.9"
39481 };
39482 var dependencies = {
39483 dayjs: "^1.8.6",
39484 "fb-polyfill": "^1.0.2",
39485 jquery: "1.12.4",
39486 lodash: "^4.17.15"
39487 };
39488 var repository = {
39489 type: "git",
39490 url: "git+https://github.com/lincong1987/fb-core.git"
39491 };
39492 var _package = {
39493 name: name,
39494 version: version,
39495 description: description,
39496 main: main,
39497 scripts: scripts,
39498 author: author,
39499 license: license,
39500 bugs: bugs,
39501 homepage: homepage,
39502 devDependencies: devDependencies,
39503 dependencies: dependencies,
39504 repository: repository
39505 };
39506
39507 var _package$1 = /*#__PURE__*/{
39508 name: name,
39509 version: version,
39510 description: description,
39511 main: main,
39512 scripts: scripts,
39513 author: author,
39514 license: license,
39515 bugs: bugs,
39516 homepage: homepage,
39517 devDependencies: devDependencies,
39518 dependencies: dependencies,
39519 repository: repository,
39520 "default": _package
39521 };
39522
39523 var pkg = getCjsExportFromNamespace(_package$1);
39524
39525 /*
39526 This file 'index' is part of Firebird Integrated Solution 1.0
39527
39528 Copyright (c) 2019 Lincong
39529
39530 Contact:
39531 Email: lincong1987@gmail.com
39532
39533 QQ: 159257119
39534
39535 See Usage at http://www.jplatformx.com/firebird
39536
39537 Create date: 2019-03-06 16:20
39538 */
39539 //require("es5-polyfill")
39540
39541 var dayjs = dayjs_1.dayjs;
39542
39543 yox.prototype.getSlot = function (name) {
39544 return this.get("$slot_" + name);
39545 };
39546
39547 yox.prototype.hasSlot = function (name) {
39548 return typeof this.getSlot(name) !== "undefined";
39549 };
39550
39551 yox.prototype.$store = function (name) {
39552 return typeof this.getSlot(name) !== "undefined";
39553 };
39554
39555 yox.prototype.$http = function (options) {
39556 return jquery.ajax(options);
39557 }; //
39558 // Yox.prototype.$http.get = function (url, data, callback, type) {
39559 //
39560 // return jQuery.ajax(jQuery.extend({
39561 // url: url,
39562 // type: method,
39563 // dataType: type,
39564 // data: data,
39565 // success: callback
39566 // }, jQuery.isPlainObject(url) && url));
39567 //
39568 // return jQuery.get(options);
39569 // };
39570 //
39571 // Yox.prototype.$http.post = function (url, data, callback, type) {
39572 //
39573 // return jQuery.ajax(jQuery.extend({
39574 // url: url,
39575 // type: method,
39576 // dataType: type,
39577 // data: data,
39578 // success: callback
39579 // }, jQuery.isPlainObject(url) && url));
39580 //
39581 // return jQuery.get(options);
39582 // };
39583 //
39584 // Yox.prototype.$http.payload = function (url, data, callback, type) {
39585 //
39586 // return jQuery.ajax(jQuery.extend({
39587 // url: url,
39588 // type: method,
39589 // dataType: type,
39590 // data: data,
39591 // success: callback
39592 // }, jQuery.isPlainObject(url) && url));
39593 //
39594 // return jQuery.get(options);
39595 // };
39596 //
39597 // Yox.prototype.$http.interceptors = [
39598 // function (request, next) {
39599 // //...
39600 // //请求发送前的处理逻辑
39601 // //...
39602 // next(function (response) {
39603 // //...
39604 // //请求发送后的处理逻辑
39605 // //...
39606 // //根据请求的状态,response参数会返回给successCallback或errorCallback
39607 // return response
39608 // });
39609 // }
39610 // ];
39611 //
39612 // Yox.prototype.$http.addInterceptor = function () {
39613 //
39614 // };
39615 //
39616 // Yox.prototype.$dialog = function (name) {
39617 //
39618 // };
39619
39620
39621 var FireBird = function () {
39622 function FireBird(options) {
39623 return new yox(options);
39624 }
39625
39626 return FireBird;
39627 }();
39628
39629 FireBird.prototype = yox.prototype;
39630
39631 lodash.each(yox, function (func, name) {
39632 FireBird[name] = func;
39633 });
39634
39635 FireBird.log = function (msg) {
39636 console.log("[FireBird info]: " + msg);
39637 };
39638
39639 FireBird.warn = function (msg) {
39640 console.warn("[FireBird warn]: " + msg);
39641 };
39642
39643 FireBird.error = function (msg) {
39644 console.error("[FireBird error]: " + msg);
39645 };
39646
39647 FireBird.components = {};
39648 FireBird.classes = {};
39649
39650 FireBird.namespace = function () {
39651 var a = arguments,
39652 o,
39653 i = 0,
39654 j,
39655 d,
39656 arg;
39657
39658 for (; i < a.length; i++) {
39659 o = this; //Reset base object per argument or it will get reused from the last
39660
39661 arg = a[i];
39662
39663 if (arg.indexOf(".") > -1) {
39664 //Skip this if no "." is present
39665 d = arg.split(".");
39666
39667 for (j = d[0] == 'FireBird' ? 1 : 0; j < d.length; j++) {
39668 o[d[j]] = o[d[j]] || {};
39669 o = o[d[j]];
39670 }
39671 } else {
39672 o[arg] = o[arg] || {};
39673 o = o[arg]; //Reset base object to the new object so it's returned
39674 }
39675 }
39676
39677 return o;
39678 };
39679
39680 FireBird.create = function (name, options) {
39681 return new FireBird($.extend(true, {}, FireBird.components[name], options));
39682 };
39683
39684 FireBird.addMember = function (name, member) {
39685 yox.prototype[name] = member;
39686 return this;
39687 };
39688
39689 FireBird.component = function (name, options) {
39690 if (typeof name === "string") {
39691 if (typeof options === "function") ; else {
39692 options.$$name = name;
39693
39694 if (options.extend) {
39695 if (typeof options.extend === "string") {
39696 options.extend = FireBird.components[options.extend] || null;
39697 }
39698
39699 options = $.extend(true, {}, options.extend, options, {
39700 "$$parent": options.extend.$$name
39701 });
39702 }
39703 }
39704
39705 yox.component(name, options);
39706 FireBird.log("\u7EC4\u4EF6 " + name + " \u5DF2\u6CE8\u518C");
39707 FireBird.components[name] = options; //FireBird.defaults[name] = options;
39708
39709 FireBird.namespace(name);
39710 return options;
39711 }
39712
39713 if (typeof name === "object") {
39714 lodash.each(name, function (options, comp) {
39715 FireBird.component(comp, options);
39716 });
39717 }
39718 };
39719
39720 FireBird.partials = {};
39721
39722 FireBird.partial = function (name, template) {
39723 if (typeof name === "string") {
39724 yox.partial(name, template);
39725 FireBird.log("\u6A21\u7248 " + name + " \u5DF2\u6CE8\u518C");
39726 FireBird.partials[name] = template;
39727 return template;
39728 }
39729
39730 if (typeof name === "object") {
39731 lodash.each(name, function (template, partial) {
39732 FireBird.partial(partial, template);
39733 });
39734 }
39735 };
39736 /**
39737 * 组件 class 处理器
39738 * @param cssObject
39739 * @returns {string}
39740 *
39741 * @example
39742 *
39743 * FireBird.css({text: true, valid: true, invalid: false});
39744 *
39745 * // class="text valid"
39746 */
39747
39748
39749 FireBird.css = function (cssObject) {
39750 if (cssObject === void 0) {
39751 cssObject = {};
39752 }
39753
39754 var classes = [];
39755
39756 lodash.each(cssObject, function (value, cssName) {
39757 if (value === true) {
39758 classes.push(cssName);
39759 }
39760 });
39761
39762 return classes.join(" ");
39763 };
39764
39765 FireBird.style = function (styleObject) {
39766 if (styleObject === void 0) {
39767 styleObject = {};
39768 }
39769
39770 var style = [];
39771
39772 lodash.each(styleObject, function (v, k) {
39773 switch (k) {
39774 case "width":
39775 case "height":
39776 case "min-height":
39777 case "min-width":
39778 case "top":
39779 case "left":
39780 case "bottom":
39781 case "right":
39782 case "line-height":
39783 if (lodash.isNumber(v)) {
39784 style.push(k + ": " + v + "px");
39785 } else {
39786 style.push(k + ": " + v);
39787 }
39788
39789 break;
39790
39791 default:
39792 style.push(k + ": " + v);
39793 }
39794 });
39795
39796 return style.join("; ");
39797 };
39798
39799 FireBird.oneOf = function (value, defaults, array) {
39800 if (array === void 0) {
39801 array = [];
39802 }
39803
39804 if (!FireBird.array.has(array, value)) {
39805 return defaults;
39806 }
39807
39808 return value;
39809 };
39810
39811 FireBird.filter("css", FireBird.css);
39812 FireBird.filter("style", FireBird.style);
39813 FireBird.filter("oneOf", FireBird.oneOf);
39814 FireBird.compile = yox.compile;
39815 FireBird.filter("_defaults", function (val, def) {
39816 return typeof val === "undefined" ? typeof def === "undefined" ? "" : def : val;
39817 });
39818 FireBird.filter("Function", function (val, def) {
39819 return new Function("//this data from FireBird Filter 'Function' Wrapper; \n return " + (typeof val === "undefined" ? typeof def === "undefined" ? "" : def : val))();
39820 });
39821 FireBird.filter("JSON_parse", function (val, def) {
39822 return JSON.parse(typeof val === "undefined" ? typeof def === "undefined" ? "" : def : val);
39823 });
39824 FireBird.filter("JSON_stringify", function (val, def, replacer, space) {
39825 return JSON.stringify(typeof val === "undefined" ? typeof def === "undefined" ? "" : def : val, replacer, space);
39826 });
39827 FireBird.filter("dayjs_fromNow", function (withoutSuffix) {
39828 return dayjs.fromNow(withoutSuffix);
39829 });
39830 FireBird.filter("dayjs_from", function (val, withoutSuffix) {
39831 return dayjs.from(val, withoutSuffix);
39832 });
39833 FireBird.filter("dayjs_toNow", function (withoutSuffix) {
39834 return dayjs.toNow(withoutSuffix);
39835 });
39836 FireBird.filter("dayjs_to", function (val, withoutSuffix) {
39837 return dayjs.to(val, withoutSuffix);
39838 });
39839 FireBird.directive = yox.directive; // 将 lodash 注入
39840
39841 FireBird.filter(lodash);
39842 store.install(FireBird);
39843 yoxRouter.install(FireBird);
39844 FireBird.component("PageApp", {
39845 template: "<div></div>",
39846 data: function data() {
39847 return {};
39848 }
39849 });
39850
39851 FireBird.App = function () {
39852 console.log("FireBird.App");
39853 };
39854
39855 commonjsGlobal.FireBird = FireBird;
39856 var version$1 = pkg.version;
39857 console.log(" _______________________________________________________________________");
39858 console.log("| |");
39859 console.log("| ######## #### ######## ######## ######## #### ######## ######## |");
39860 console.log("| ## ## ## ## ## ## ## ## ## ## ## ## |");
39861 console.log("| ## ## ## ## ## ## ## ## ## ## ## ## |");
39862 console.log("| ###### ## ######## ###### ######## ## ######## ## ## |");
39863 console.log("| ## ## ## ## ## ## ## ## ## ## ## ## |");
39864 console.log("| ## ## ## ## ## ## ## ## ## ## ## ## |");
39865 console.log("| ## #### ## ## ######## ######## #### ## ## ######## |");
39866 console.log("| |");
39867 console.log("|" + lodash.pad("", 71) + "|");
39868 console.log("|" + lodash.pad("Version: " + version$1, 71) + "|");
39869 console.log("|" + lodash.pad("Date: 2019-12-15T23:23:25+08:00", 71) + "|");
39870 console.log("|" + lodash.pad("Author: lincong1987@gmail.com", 71) + "|"); //console.log("| |");
39871
39872 console.log("|_______________________________________________________________________|"); // return {
39873 // FireBird: FireBird,
39874 // jQuery: jQuery,
39875 // $: $,
39876 // Router: Router,
39877 // Store: Store,
39878 // dayjs: dayjs,
39879 // version: version,
39880 // _: _,
39881 // lodash: _
39882 // };
39883 // exports.FireBird = FireBird;
39884 // exports.Store = Store;
39885 // exports.Router = Router;
39886 // exports.jQuery = jQuery;
39887 // exports.$ = jQuery;
39888 // exports._ = _;
39889 // exports.dayjs = dayjs;
39890 // exports.version = version;
39891 // export default {
39892 // FireBird, Store, Router, jQuery, $, _, dayjs, version
39893 // }
39894
39895 var $ = jquery,
39896 lodash$1 = lodash;
39897 var src = {
39898 FireBird: FireBird,
39899 Store: store.Store,
39900 Router: yoxRouter,
39901 jQuery: jquery,
39902 $: $,
39903 _: lodash,
39904 lodash: lodash$1,
39905 dayjs: dayjs,
39906 version: version$1
39907 };
39908 var src_1 = src.FireBird;
39909 var src_2 = src.Store;
39910 var src_3 = src.Router;
39911 var src_4 = src.jQuery;
39912 var src_5 = src.$;
39913 var src_6 = src._;
39914 var src_7 = src.lodash;
39915 var src_8 = src.dayjs;
39916 var src_9 = src.version;
39917
39918 exports["default"] = src;
39919 exports.FireBird = src_1;
39920 exports.Store = src_2;
39921 exports.Router = src_3;
39922 exports.jQuery = src_4;
39923 exports.$ = src_5;
39924 exports._ = src_6;
39925 exports.lodash = src_7;
39926 exports.dayjs = src_8;
39927 exports.version = src_9;
39928
39929 Object.defineProperty(exports, '__esModule', { value: true });
39930
39931}));