PageSourceSearch

https://hihostels.ca/dist/scripts/main.js?ncp=5

js hihostels.ca collected 2026-10-04 00:01:28 UTC 1,690,339 bytes, 56,230 lines download raw bytes

vendor: 17,344 bytes, lines 1-685
1/*!
2 * jQuery JavaScript Library v3.1.1
3 * https://jquery.com/
4 *
5 * Includes Sizzle.js
6 * https://sizzlejs.com/
7 *
8 * Copyright jQuery Foundation and other contributors
9 * Released under the MIT license
10 * https://jquery.org/license
11 *
12 * Date: 2016-09-22T22:30Z
13 */
14( function( global, factory ) {
15
16	"use strict";
17
18	if ( typeof module === "object" && typeof module.exports === "object" ) {
19
20		// For CommonJS and CommonJS-like environments where a proper `window`
21		// is present, execute the factory and get jQuery.
22		// For environments that do not have a `window` with a `document`
23		// (such as Node.js), expose a factory as module.exports.
24		// This accentuates the need for the creation of a real `window`.
25		// e.g. var jQuery = require("jquery")(window);
26		// See ticket #14549 for more info.
27		module.exports = global.document ?
28			factory( global, true ) :
29			function( w ) {
30				if ( !w.document ) {
31					throw new Error( "jQuery requires a window with a document" );
32				}
33				return factory( w );
34			};
35	} else {
36		factory( global );
37	}
38
39// Pass this if window is not defined yet
40} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
41
42// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
43// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
44// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
45// enough that all such attempts are guarded in a try block.
46"use strict";
47
48var arr = [];
49
50var document = window.document;
51
52var getProto = Object.getPrototypeOf;
53
54var slice = arr.slice;
55
56var concat = arr.concat;
57
58var push = arr.push;
59
60var indexOf = arr.indexOf;
61
62var class2type = {};
63
64var toString = class2type.toString;
65
66var hasOwn = class2type.hasOwnProperty;
67
68var fnToString = hasOwn.toString;
69
70var ObjectFunctionString = fnToString.call( Object );
71
72var support = {};
73
74
75
76	function DOMEval( code, doc ) {
77		doc = doc || document;
78
79		var script = doc.createElement( "script" );
80
81		script.text = code;
82		doc.head.appendChild( script ).parentNode.removeChild( script );
83	}
84/* global Symbol */
85// Defining this global in .eslintrc.json would create a danger of using the global
86// unguarded in another place, it seems safer to define global only for this module
87
88
89
90var
91	version = "3.1.1",
92
93	// Define a local copy of jQuery
94	jQuery = function( selector, context ) {
95
96		// The jQuery object is actually just the init constructor 'enhanced'
97		// Need init if jQuery is called (just allow error to be thrown if not included)
98		return new jQuery.fn.init( selector, context );
99	},
100
101	// Support: Android <=4.0 only
102	// Make sure we trim BOM and NBSP
103	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
104
105	// Matches dashed string for camelizing
106	rmsPrefix = /^-ms-/,
107	rdashAlpha = /-([a-z])/g,
108
109	// Used by jQuery.camelCase as callback to replace()
110	fcamelCase = function( all, letter ) {
111		return letter.toUpperCase();
112	};
113
114jQuery.fn = jQuery.prototype = {
115
116	// The current version of jQuery being used
117	jquery: version,
118
119	constructor: jQuery,
120
121	// The default length of a jQuery object is 0
122	length: 0,
123
124	toArray: function() {
125		return slice.call( this );
126	},
127
128	// Get the Nth element in the matched element set OR
129	// Get the whole matched element set as a clean array
130	get: function( num ) {
131
132		// Return all the elements in a clean array
133		if ( num == null ) {
134			return slice.call( this );
135		}
136
137		// Return just the one element from the set
138		return num < 0 ? this[ num + this.length ] : this[ num ];
139	},
140
141	// Take an array of elements and push it onto the stack
142	// (returning the new matched element set)
143	pushStack: function( elems ) {
144
145		// Build a new jQuery matched element set
146		var ret = jQuery.merge( this.constructor(), elems );
147
148		// Add the old object onto the stack (as a reference)
149		ret.prevObject = this;
150
151		// Return the newly-formed element set
152		return ret;
153	},
154
155	// Execute a callback for every element in the matched set.
156	each: function( callback ) {
157		return jQuery.each( this, callback );
158	},
159
160	map: function( callback ) {
161		return this.pushStack( jQuery.map( this, function( elem, i ) {
162			return callback.call( elem, i, elem );
163		} ) );
164	},
165
166	slice: function() {
167		return this.pushStack( slice.apply( this, arguments ) );
168	},
169
170	first: function() {
171		return this.eq( 0 );
172	},
173
174	last: function() {
175		return this.eq( -1 );
176	},
177
178	eq: function( i ) {
179		var len = this.length,
180			j = +i + ( i < 0 ? len : 0 );
181		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
182	},
183
184	end: function() {
185		return this.prevObject || this.constructor();
186	},
187
188	// For internal use only.
189	// Behaves like an Array's method, not like a jQuery method.
190	push: push,
191	sort: arr.sort,
192	splice: arr.splice
193};
194
195jQuery.extend = jQuery.fn.extend = function() {
196	var options, name, src, copy, copyIsArray, clone,
197		target = arguments[ 0 ] || {},
198		i = 1,
199		length = arguments.length,
200		deep = false;
201
202	// Handle a deep copy situation
203	if ( typeof target === "boolean" ) {
204		deep = target;
205
206		// Skip the boolean and the target
207		target = arguments[ i ] || {};
208		i++;
209	}
210
211	// Handle case when target is a string or something (possible in deep copy)
212	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
213		target = {};
214	}
215
216	// Extend jQuery itself if only one argument is passed
217	if ( i === length ) {
218		target = this;
219		i--;
220	}
221
222	for ( ; i < length; i++ ) {
223
224		// Only deal with non-null/undefined values
225		if ( ( options = arguments[ i ] ) != null ) {
226
227			// Extend the base object
228			for ( name in options ) {
229				src = target[ name ];
230				copy = options[ name ];
231
232				// Prevent never-ending loop
233				if ( target === copy ) {
234					continue;
235				}
236
237				// Recurse if we're merging plain objects or arrays
238				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
239					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
240
241					if ( copyIsArray ) {
242						copyIsArray = false;
243						clone = src && jQuery.isArray( src ) ? src : [];
244
245					} else {
246						clone = src && jQuery.isPlainObject( src ) ? src : {};
247					}
248
249					// Never move original objects, clone them
250					target[ name ] = jQuery.extend( deep, clone, copy );
251
252				// Don't bring in undefined values
253				} else if ( copy !== undefined ) {
254					target[ name ] = copy;
255				}
256			}
257		}
258	}
259
260	// Return the modified object
261	return target;
262};
263
264jQuery.extend( {
265
266	// Unique for each copy of jQuery on the page
267	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
268
269	// Assume jQuery is ready without the ready module
270	isReady: true,
271
272	error: function( msg ) {
273		throw new Error( msg );
274	},
275
276	noop: function() {},
277
278	isFunction: function( obj ) {
279		return jQuery.type( obj ) === "function";
280	},
281
282	isArray: Array.isArray,
283
284	isWindow: function( obj ) {
285		return obj != null && obj === obj.window;
286	},
287
288	isNumeric: function( obj ) {
289
290		// As of jQuery 3.0, isNumeric is limited to
291		// strings and numbers (primitives or objects)
292		// that can be coerced to finite numbers (gh-2662)
293		var type = jQuery.type( obj );
294		return ( type === "number" || type === "string" ) &&
295
296			// parseFloat NaNs numeric-cast false positives ("")
297			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
298			// subtraction forces infinities to NaN
299			!isNaN( obj - parseFloat( obj ) );
300	},
301
302	isPlainObject: function( obj ) {
303		var proto, Ctor;
304
305		// Detect obvious negatives
306		// Use toString instead of jQuery.type to catch host objects
307		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
308			return false;
309		}
310
311		proto = getProto( obj );
312
313		// Objects with no prototype (e.g., `Object.create( null )`) are plain
314		if ( !proto ) {
315			return true;
316		}
317
318		// Objects with prototype are plain iff they were constructed by a global Object function
319		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
320		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
321	},
322
323	isEmptyObject: function( obj ) {
324
325		/* eslint-disable no-unused-vars */
326		// See https://github.com/eslint/eslint/issues/6125
327		var name;
328
329		for ( name in obj ) {
330			return false;
331		}
332		return true;
333	},
334
335	type: function( obj ) {
336		if ( obj == null ) {
337			return obj + "";
338		}
339
340		// Support: Android <=2.3 only (functionish RegExp)
341		return typeof obj === "object" || typeof obj === "function" ?
342			class2type[ toString.call( obj ) ] || "object" :
343			typeof obj;
344	},
345
346	// Evaluates a script in a global context
347	globalEval: function( code ) {
348		DOMEval( code );
349	},
350
351	// Convert dashed to camelCase; used by the css and data modules
352	// Support: IE <=9 - 11, Edge 12 - 13
353	// Microsoft forgot to hump their vendor prefix (#9572)
354	camelCase: function( string ) {
355		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
356	},
357
358	nodeName: function( elem, name ) {
359		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
360	},
361
362	each: function( obj, callback ) {
363		var length, i = 0;
364
365		if ( isArrayLike( obj ) ) {
366			length = obj.length;
367			for ( ; i < length; i++ ) {
368				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
369					break;
370				}
371			}
372		} else {
373			for ( i in obj ) {
374				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
375					break;
376				}
377			}
378		}
379
380		return obj;
381	},
382
383	// Support: Android <=4.0 only
384	trim: function( text ) {
385		return text == null ?
386			"" :
387			( text + "" ).replace( rtrim, "" );
388	},
389
390	// results is for internal usage only
391	makeArray: function( arr, results ) {
392		var ret = results || [];
393
394		if ( arr != null ) {
395			if ( isArrayLike( Object( arr ) ) ) {
396				jQuery.merge( ret,
397					typeof arr === "string" ?
398					[ arr ] : arr
399				);
400			} else {
401				push.call( ret, arr );
402			}
403		}
404
405		return ret;
406	},
407
408	inArray: function( elem, arr, i ) {
409		return arr == null ? -1 : indexOf.call( arr, elem, i );
410	},
411
412	// Support: Android <=4.0 only, PhantomJS 1 only
413	// push.apply(_, arraylike) throws on ancient WebKit
414	merge: function( first, second ) {
415		var len = +second.length,
416			j = 0,
417			i = first.length;
418
419		for ( ; j < len; j++ ) {
420			first[ i++ ] = second[ j ];
421		}
422
423		first.length = i;
424
425		return first;
426	},
427
428	grep: function( elems, callback, invert ) {
429		var callbackInverse,
430			matches = [],
431			i = 0,
432			length = elems.length,
433			callbackExpect = !invert;
434
435		// Go through the array, only saving the items
436		// that pass the validator function
437		for ( ; i < length; i++ ) {
438			callbackInverse = !callback( elems[ i ], i );
439			if ( callbackInverse !== callbackExpect ) {
440				matches.push( elems[ i ] );
441			}
442		}
443
444		return matches;
445	},
446
447	// arg is for internal usage only
448	map: function( elems, callback, arg ) {
449		var length, value,
450			i = 0,
451			ret = [];
452
453		// Go through the array, translating each of the items to their new values
454		if ( isArrayLike( elems ) ) {
455			length = elems.length;
456			for ( ; i < length; i++ ) {
457				value = callback( elems[ i ], i, arg );
458
459				if ( value != null ) {
460					ret.push( value );
461				}
462			}
463
464		// Go through every key on the object,
465		} else {
466			for ( i in elems ) {
467				value = callback( elems[ i ], i, arg );
468
469				if ( value != null ) {
470					ret.push( value );
471				}
472			}
473		}
474
475		// Flatten any nested arrays
476		return concat.apply( [], ret );
477	},
478
479	// A global GUID counter for objects
480	guid: 1,
481
482	// Bind a function to a context, optionally partially applying any
483	// arguments.
484	proxy: function( fn, context ) {
485		var tmp, args, proxy;
486
487		if ( typeof context === "string" ) {
488			tmp = fn[ context ];
489			context = fn;
490			fn = tmp;
491		}
492
493		// Quick check to determine if target is callable, in the spec
494		// this throws a TypeError, but we will just return undefined.
495		if ( !jQuery.isFunction( fn ) ) {
496			return undefined;
497		}
498
499		// Simulated bind
500		args = slice.call( arguments, 2 );
501		proxy = function() {
502			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
503		};
504
505		// Set the guid of unique handler to the same of original handler, so it can be removed
506		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
507
508		return proxy;
509	},
510
511	now: Date.now,
512
513	// jQuery.support is not used in Core but other projects attach their
514	// properties to it so it needs to exist.
515	support: support
516} );
517
518if ( typeof Symbol === "function" ) {
519	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
520}
521
522// Populate the class2type map
523jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
524function( i, name ) {
525	class2type[ "[object " + name + "]" ] = name.toLowerCase();
526} );
527
528function isArrayLike( obj ) {
529
530	// Support: real iOS 8.2 only (not reproducible in simulator)
531	// `in` check used to prevent JIT error (gh-2145)
532	// hasOwn isn't used here due to false negatives
533	// regarding Nodelist length in IE
534	var length = !!obj && "length" in obj && obj.length,
535		type = jQuery.type( obj );
536
537	if ( type === "function" || jQuery.isWindow( obj ) ) {
538		return false;
539	}
540
541	return type === "array" || length === 0 ||
542		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
543}
544var Sizzle =
545/*!
546 * Sizzle CSS Selector Engine v2.3.3
547 * https://sizzlejs.com/
548 *
549 * Copyright jQuery Foundation and other contributors
550 * Released under the MIT license
551 * http://jquery.org/license
552 *
553 * Date: 2016-08-08
554 */
555(function( window ) {
556
557var i,
558	support,
559	Expr,
560	getText,
561	isXML,
562	tokenize,
563	compile,
564	select,
565	outermostContext,
566	sortInput,
567	hasDuplicate,
568
569	// Local document vars
570	setDocument,
571	document,
572	docElem,
573	documentIsHTML,
574	rbuggyQSA,
575	rbuggyMatches,
576	matches,
577	contains,
578
579	// Instance-specific data
580	expando = "sizzle" + 1 * new Date(),
581	preferredDoc = window.document,
582	dirruns = 0,
583	done = 0,
584	classCache = createCache(),
585	tokenCache = createCache(),
586	compilerCache = createCache(),
587	sortOrder = function( a, b ) {
588		if ( a === b ) {
589			hasDuplicate = true;
590		}
591		return 0;
592	},
593
594	// Instance methods
595	hasOwn = ({}).hasOwnProperty,
596	arr = [],
597	pop = arr.pop,
598	push_native = arr.push,
599	push = arr.push,
600	slice = arr.slice,
601	// Use a stripped-down indexOf as it's faster than native
602	// https://jsperf.com/thor-indexof-vs-for/5
603	indexOf = function( list, elem ) {
604		var i = 0,
605			len = list.length;
606		for ( ; i < len; i++ ) {
607			if ( list[i] === elem ) {
608				return i;
609			}
610		}
611		return -1;
612	},
613
614	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
615
616	// Regular expressions
617
618	// http://www.w3.org/TR/css3-selectors/#whitespace
619	whitespace = "[\\x20\\t\\r\\n\\f]",
620
621	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
622	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
623
624	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
625	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
626		// Operator (capture 2)
627		"*([*^$|!~]?=)" + whitespace +
628		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
629		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
630		"*\\]",
631
632	pseudos = ":(" + identifier + ")(?:\\((" +
633		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
634		// 1. quoted (capture 3; capture 4 or capture 5)
635		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
636		// 2. simple (capture 6)
637		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
638		// 3. anything else (capture 2)
639		".*" +
640		")\\)|)",
641
642	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
643	rwhitespace = new RegExp( whitespace + "+", "g" ),
644	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
645
646	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
647	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
648
649	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
650
651	rpseudo = new RegExp( pseudos ),
652	ridentifier = new RegExp( "^" + identifier + "$" ),
653
654	matchExpr = {
655		"ID": new RegExp( "^#(" + identifier + ")" ),
656		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
657		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
658		"ATTR": new RegExp( "^" + attributes ),
659		"PSEUDO": new RegExp( "^" + pseudos ),
660		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
661			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
662			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
663		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
664		// For use in libraries implementing .is()
665		// We use this for POS matching in `select`
666		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
667			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
668	},
669
670	rinputs = /^(?:input|select|textarea|button)$/i,
671	rheader = /^h\d$/i,
672
673	rnative = /^[^{]+\{\s*\[native \w/,
674
675	// Easily-parseable/retrievable ID or TAG or CLASS selectors
676	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
677
678	rsibling = /[+~]/,
679
680	// CSS escapes
681	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
682	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
683	funescape = function( _, escaped, escapedWhitespace ) {
684		var high = "0x" + escaped - 0x10000;
685		// NaN means non-codepoint
vendor: 18,941 bytes, lines 686-1334
686		// Support: Firefox<24
687		// Workaround erroneous numeric interpretation of +"0x"
688		return high !== high || escapedWhitespace ?
689			escaped :
690			high < 0 ?
691				// BMP codepoint
692				String.fromCharCode( high + 0x10000 ) :
693				// Supplemental Plane codepoint (surrogate pair)
694				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
695	},
696
697	// CSS string/identifier serialization
698	// https://drafts.csswg.org/cssom/#common-serializing-idioms
699	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
700	fcssescape = function( ch, asCodePoint ) {
701		if ( asCodePoint ) {
702
703			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
704			if ( ch === "\0" ) {
705				return "\uFFFD";
706			}
707
708			// Control characters and (dependent upon position) numbers get escaped as code points
709			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
710		}
711
712		// Other potentially-special ASCII characters get backslash-escaped
713		return "\\" + ch;
714	},
715
716	// Used for iframes
717	// See setDocument()
718	// Removing the function wrapper causes a "Permission Denied"
719	// error in IE
720	unloadHandler = function() {
721		setDocument();
722	},
723
724	disabledAncestor = addCombinator(
725		function( elem ) {
726			return elem.disabled === true && ("form" in elem || "label" in elem);
727		},
728		{ dir: "parentNode", next: "legend" }
729	);
730
731// Optimize for push.apply( _, NodeList )
732try {
733	push.apply(
734		(arr = slice.call( preferredDoc.childNodes )),
735		preferredDoc.childNodes
736	);
737	// Support: Android<4.0
738	// Detect silently failing push.apply
739	arr[ preferredDoc.childNodes.length ].nodeType;
740} catch ( e ) {
741	push = { apply: arr.length ?
742
743		// Leverage slice if possible
744		function( target, els ) {
745			push_native.apply( target, slice.call(els) );
746		} :
747
748		// Support: IE<9
749		// Otherwise append directly
750		function( target, els ) {
751			var j = target.length,
752				i = 0;
753			// Can't trust NodeList.length
754			while ( (target[j++] = els[i++]) ) {}
755			target.length = j - 1;
756		}
757	};
758}
759
760function Sizzle( selector, context, results, seed ) {
761	var m, i, elem, nid, match, groups, newSelector,
762		newContext = context && context.ownerDocument,
763
764		// nodeType defaults to 9, since context defaults to document
765		nodeType = context ? context.nodeType : 9;
766
767	results = results || [];
768
769	// Return early from calls with invalid selector or context
770	if ( typeof selector !== "string" || !selector ||
771		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
772
773		return results;
774	}
775
776	// Try to shortcut find operations (as opposed to filters) in HTML documents
777	if ( !seed ) {
778
779		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
780			setDocument( context );
781		}
782		context = context || document;
783
784		if ( documentIsHTML ) {
785
786			// If the selector is sufficiently simple, try using a "get*By*" DOM method
787			// (excepting DocumentFragment context, where the methods don't exist)
788			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
789
790				// ID selector
791				if ( (m = match[1]) ) {
792
793					// Document context
794					if ( nodeType === 9 ) {
795						if ( (elem = context.getElementById( m )) ) {
796
797							// Support: IE, Opera, Webkit
798							// TODO: identify versions
799							// getElementById can match elements by name instead of ID
800							if ( elem.id === m ) {
801								results.push( elem );
802								return results;
803							}
804						} else {
805							return results;
806						}
807
808					// Element context
809					} else {
810
811						// Support: IE, Opera, Webkit
812						// TODO: identify versions
813						// getElementById can match elements by name instead of ID
814						if ( newContext && (elem = newContext.getElementById( m )) &&
815							contains( context, elem ) &&
816							elem.id === m ) {
817
818							results.push( elem );
819							return results;
820						}
821					}
822
823				// Type selector
824				} else if ( match[2] ) {
825					push.apply( results, context.getElementsByTagName( selector ) );
826					return results;
827
828				// Class selector
829				} else if ( (m = match[3]) && support.getElementsByClassName &&
830					context.getElementsByClassName ) {
831
832					push.apply( results, context.getElementsByClassName( m ) );
833					return results;
834				}
835			}
836
837			// Take advantage of querySelectorAll
838			if ( support.qsa &&
839				!compilerCache[ selector + " " ] &&
840				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
841
842				if ( nodeType !== 1 ) {
843					newContext = context;
844					newSelector = selector;
845
846				// qSA looks outside Element context, which is not what we want
847				// Thanks to Andrew Dupont for this workaround technique
848				// Support: IE <=8
849				// Exclude object elements
850				} else if ( context.nodeName.toLowerCase() !== "object" ) {
851
852					// Capture the context ID, setting it first if necessary
853					if ( (nid = context.getAttribute( "id" )) ) {
854						nid = nid.replace( rcssescape, fcssescape );
855					} else {
856						context.setAttribute( "id", (nid = expando) );
857					}
858
859					// Prefix every selector in the list
860					groups = tokenize( selector );
861					i = groups.length;
862					while ( i-- ) {
863						groups[i] = "#" + nid + " " + toSelector( groups[i] );
864					}
865					newSelector = groups.join( "," );
866
867					// Expand context for sibling selectors
868					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
869						context;
870				}
871
872				if ( newSelector ) {
873					try {
874						push.apply( results,
875							newContext.querySelectorAll( newSelector )
876						);
877						return results;
878					} catch ( qsaError ) {
879					} finally {
880						if ( nid === expando ) {
881							context.removeAttribute( "id" );
882						}
883					}
884				}
885			}
886		}
887	}
888
889	// All others
890	return select( selector.replace( rtrim, "$1" ), context, results, seed );
891}
892
893/**
894 * Create key-value caches of limited size
895 * @returns {function(string, object)} Returns the Object data after storing it on itself with
896 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
897 *	deleting the oldest entry
898 */
899function createCache() {
900	var keys = [];
901
902	function cache( key, value ) {
903		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
904		if ( keys.push( key + " " ) > Expr.cacheLength ) {
905			// Only keep the most recent entries
906			delete cache[ keys.shift() ];
907		}
908		return (cache[ key + " " ] = value);
909	}
910	return cache;
911}
912
913/**
914 * Mark a function for special use by Sizzle
915 * @param {Function} fn The function to mark
916 */
917function markFunction( fn ) {
918	fn[ expando ] = true;
919	return fn;
920}
921
922/**
923 * Support testing using an element
924 * @param {Function} fn Passed the created element and returns a boolean result
925 */
926function assert( fn ) {
927	var el = document.createElement("fieldset");
928
929	try {
930		return !!fn( el );
931	} catch (e) {
932		return false;
933	} finally {
934		// Remove from its parent by default
935		if ( el.parentNode ) {
936			el.parentNode.removeChild( el );
937		}
938		// release memory in IE
939		el = null;
940	}
941}
942
943/**
944 * Adds the same handler for all of the specified attrs
945 * @param {String} attrs Pipe-separated list of attributes
946 * @param {Function} handler The method that will be applied
947 */
948function addHandle( attrs, handler ) {
949	var arr = attrs.split("|"),
950		i = arr.length;
951
952	while ( i-- ) {
953		Expr.attrHandle[ arr[i] ] = handler;
954	}
955}
956
957/**
958 * Checks document order of two siblings
959 * @param {Element} a
960 * @param {Element} b
961 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
962 */
963function siblingCheck( a, b ) {
964	var cur = b && a,
965		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
966			a.sourceIndex - b.sourceIndex;
967
968	// Use IE sourceIndex if available on both nodes
969	if ( diff ) {
970		return diff;
971	}
972
973	// Check if b follows a
974	if ( cur ) {
975		while ( (cur = cur.nextSibling) ) {
976			if ( cur === b ) {
977				return -1;
978			}
979		}
980	}
981
982	return a ? 1 : -1;
983}
984
985/**
986 * Returns a function to use in pseudos for input types
987 * @param {String} type
988 */
989function createInputPseudo( type ) {
990	return function( elem ) {
991		var name = elem.nodeName.toLowerCase();
992		return name === "input" && elem.type === type;
993	};
994}
995
996/**
997 * Returns a function to use in pseudos for buttons
998 * @param {String} type
999 */
1000function createButtonPseudo( type ) {
1001	return function( elem ) {
1002		var name = elem.nodeName.toLowerCase();
1003		return (name === "input" || name === "button") && elem.type === type;
1004	};
1005}
1006
1007/**
1008 * Returns a function to use in pseudos for :enabled/:disabled
1009 * @param {Boolean} disabled true for :disabled; false for :enabled
1010 */
1011function createDisabledPseudo( disabled ) {
1012
1013	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1014	return function( elem ) {
1015
1016		// Only certain elements can match :enabled or :disabled
1017		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1018		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1019		if ( "form" in elem ) {
1020
1021			// Check for inherited disabledness on relevant non-disabled elements:
1022			// * listed form-associated elements in a disabled fieldset
1023			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1024			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1025			// * option elements in a disabled optgroup
1026			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1027			// All such elements have a "form" property.
1028			if ( elem.parentNode && elem.disabled === false ) {
1029
1030				// Option elements defer to a parent optgroup if present
1031				if ( "label" in elem ) {
1032					if ( "label" in elem.parentNode ) {
1033						return elem.parentNode.disabled === disabled;
1034					} else {
1035						return elem.disabled === disabled;
1036					}
1037				}
1038
1039				// Support: IE 6 - 11
1040				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
1041				return elem.isDisabled === disabled ||
1042
1043					// Where there is no isDisabled, check manually
1044					/* jshint -W018 */
1045					elem.isDisabled !== !disabled &&
1046						disabledAncestor( elem ) === disabled;
1047			}
1048
1049			return elem.disabled === disabled;
1050
1051		// Try to winnow out elements that can't be disabled before trusting the disabled property.
1052		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1053		// even exist on them, let alone have a boolean value.
1054		} else if ( "label" in elem ) {
1055			return elem.disabled === disabled;
1056		}
1057
1058		// Remaining elements are neither :enabled nor :disabled
1059		return false;
1060	};
1061}
1062
1063/**
1064 * Returns a function to use in pseudos for positionals
1065 * @param {Function} fn
1066 */
1067function createPositionalPseudo( fn ) {
1068	return markFunction(function( argument ) {
1069		argument = +argument;
1070		return markFunction(function( seed, matches ) {
1071			var j,
1072				matchIndexes = fn( [], seed.length, argument ),
1073				i = matchIndexes.length;
1074
1075			// Match elements found at the specified indexes
1076			while ( i-- ) {
1077				if ( seed[ (j = matchIndexes[i]) ] ) {
1078					seed[j] = !(matches[j] = seed[j]);
1079				}
1080			}
1081		});
1082	});
1083}
1084
1085/**
1086 * Checks a node for validity as a Sizzle context
1087 * @param {Element|Object=} context
1088 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1089 */
1090function testContext( context ) {
1091	return context && typeof context.getElementsByTagName !== "undefined" && context;
1092}
1093
1094// Expose support vars for convenience
1095support = Sizzle.support = {};
1096
1097/**
1098 * Detects XML nodes
1099 * @param {Element|Object} elem An element or a document
1100 * @returns {Boolean} True iff elem is a non-HTML XML node
1101 */
1102isXML = Sizzle.isXML = function( elem ) {
1103	// documentElement is verified for cases where it doesn't yet exist
1104	// (such as loading iframes in IE - #4833)
1105	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1106	return documentElement ? documentElement.nodeName !== "HTML" : false;
1107};
1108
1109/**
1110 * Sets document-related variables once based on the current document
1111 * @param {Element|Object} [doc] An element or document object to use to set the document
1112 * @returns {Object} Returns the current document
1113 */
1114setDocument = Sizzle.setDocument = function( node ) {
1115	var hasCompare, subWindow,
1116		doc = node ? node.ownerDocument || node : preferredDoc;
1117
1118	// Return early if doc is invalid or already selected
1119	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1120		return document;
1121	}
1122
1123	// Update global variables
1124	document = doc;
1125	docElem = document.documentElement;
1126	documentIsHTML = !isXML( document );
1127
1128	// Support: IE 9-11, Edge
1129	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1130	if ( preferredDoc !== document &&
1131		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
1132
1133		// Support: IE 11, Edge
1134		if ( subWindow.addEventListener ) {
1135			subWindow.addEventListener( "unload", unloadHandler, false );
1136
1137		// Support: IE 9 - 10 only
1138		} else if ( subWindow.attachEvent ) {
1139			subWindow.attachEvent( "onunload", unloadHandler );
1140		}
1141	}
1142
1143	/* Attributes
1144	---------------------------------------------------------------------- */
1145
1146	// Support: IE<8
1147	// Verify that getAttribute really returns attributes and not properties
1148	// (excepting IE8 booleans)
1149	support.attributes = assert(function( el ) {
1150		el.className = "i";
1151		return !el.getAttribute("className");
1152	});
1153
1154	/* getElement(s)By*
1155	---------------------------------------------------------------------- */
1156
1157	// Check if getElementsByTagName("*") returns only elements
1158	support.getElementsByTagName = assert(function( el ) {
1159		el.appendChild( document.createComment("") );
1160		return !el.getElementsByTagName("*").length;
1161	});
1162
1163	// Support: IE<9
1164	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1165
1166	// Support: IE<10
1167	// Check if getElementById returns elements by name
1168	// The broken getElementById methods don't pick up programmatically-set names,
1169	// so use a roundabout getElementsByName test
1170	support.getById = assert(function( el ) {
1171		docElem.appendChild( el ).id = expando;
1172		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1173	});
1174
1175	// ID filter and find
1176	if ( support.getById ) {
1177		Expr.filter["ID"] = function( id ) {
1178			var attrId = id.replace( runescape, funescape );
1179			return function( elem ) {
1180				return elem.getAttribute("id") === attrId;
1181			};
1182		};
1183		Expr.find["ID"] = function( id, context ) {
1184			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1185				var elem = context.getElementById( id );
1186				return elem ? [ elem ] : [];
1187			}
1188		};
1189	} else {
1190		Expr.filter["ID"] =  function( id ) {
1191			var attrId = id.replace( runescape, funescape );
1192			return function( elem ) {
1193				var node = typeof elem.getAttributeNode !== "undefined" &&
1194					elem.getAttributeNode("id");
1195				return node && node.value === attrId;
1196			};
1197		};
1198
1199		// Support: IE 6 - 7 only
1200		// getElementById is not reliable as a find shortcut
1201		Expr.find["ID"] = function( id, context ) {
1202			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1203				var node, i, elems,
1204					elem = context.getElementById( id );
1205
1206				if ( elem ) {
1207
1208					// Verify the id attribute
1209					node = elem.getAttributeNode("id");
1210					if ( node && node.value === id ) {
1211						return [ elem ];
1212					}
1213
1214					// Fall back on getElementsByName
1215					elems = context.getElementsByName( id );
1216					i = 0;
1217					while ( (elem = elems[i++]) ) {
1218						node = elem.getAttributeNode("id");
1219						if ( node && node.value === id ) {
1220							return [ elem ];
1221						}
1222					}
1223				}
1224
1225				return [];
1226			}
1227		};
1228	}
1229
1230	// Tag
1231	Expr.find["TAG"] = support.getElementsByTagName ?
1232		function( tag, context ) {
1233			if ( typeof context.getElementsByTagName !== "undefined" ) {
1234				return context.getElementsByTagName( tag );
1235
1236			// DocumentFragment nodes don't have gEBTN
1237			} else if ( support.qsa ) {
1238				return context.querySelectorAll( tag );
1239			}
1240		} :
1241
1242		function( tag, context ) {
1243			var elem,
1244				tmp = [],
1245				i = 0,
1246				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1247				results = context.getElementsByTagName( tag );
1248
1249			// Filter out possible comments
1250			if ( tag === "*" ) {
1251				while ( (elem = results[i++]) ) {
1252					if ( elem.nodeType === 1 ) {
1253						tmp.push( elem );
1254					}
1255				}
1256
1257				return tmp;
1258			}
1259			return results;
1260		};
1261
1262	// Class
1263	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1264		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1265			return context.getElementsByClassName( className );
1266		}
1267	};
1268
1269	/* QSA/matchesSelector
1270	---------------------------------------------------------------------- */
1271
1272	// QSA and matchesSelector support
1273
1274	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1275	rbuggyMatches = [];
1276
1277	// qSa(:focus) reports false when true (Chrome 21)
1278	// We allow this because of a bug in IE8/9 that throws an error
1279	// whenever `document.activeElement` is accessed on an iframe
1280	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1281	// See https://bugs.jquery.com/ticket/13378
1282	rbuggyQSA = [];
1283
1284	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1285		// Build QSA regex
1286		// Regex strategy adopted from Diego Perini
1287		assert(function( el ) {
1288			// Select is set to empty string on purpose
1289			// This is to test IE's treatment of not explicitly
1290			// setting a boolean content attribute,
1291			// since its presence should be enough
1292			// https://bugs.jquery.com/ticket/12359
1293			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1294				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1295				"<option selected=''></option></select>";
1296
1297			// Support: IE8, Opera 11-12.16
1298			// Nothing should be selected when empty strings follow ^= or $= or *=
1299			// The test attribute must be unknown in Opera but "safe" for WinRT
1300			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1301			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
1302				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1303			}
1304
1305			// Support: IE8
1306			// Boolean attributes and "value" are not treated correctly
1307			if ( !el.querySelectorAll("[selected]").length ) {
1308				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1309			}
1310
1311			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1312			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1313				rbuggyQSA.push("~=");
1314			}
1315
1316			// Webkit/Opera - :checked should return selected option elements
1317			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1318			// IE8 throws error here and will not see later tests
1319			if ( !el.querySelectorAll(":checked").length ) {
1320				rbuggyQSA.push(":checked");
1321			}
1322
1323			// Support: Safari 8+, iOS 8+
1324			// https://bugs.webkit.org/show_bug.cgi?id=136851
1325			// In-page `selector#id sibling-combinator selector` fails
1326			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1327				rbuggyQSA.push(".#.+[+~]");
1328			}
1329		});
1330
1331		assert(function( el ) {
1332			el.innerHTML = "<a href='' disabled='disabled'></a>" +
1333				"<select disabled='disabled'><option/></select>";
1334
vendor: 6,849 bytes, lines 1335-1582
1335			// Support: Windows 8 Native Apps
1336			// The type and name attributes are restricted during .innerHTML assignment
1337			var input = document.createElement("input");
1338			input.setAttribute( "type", "hidden" );
1339			el.appendChild( input ).setAttribute( "name", "D" );
1340
1341			// Support: IE8
1342			// Enforce case-sensitivity of name attribute
1343			if ( el.querySelectorAll("[name=d]").length ) {
1344				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1345			}
1346
1347			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1348			// IE8 throws error here and will not see later tests
1349			if ( el.querySelectorAll(":enabled").length !== 2 ) {
1350				rbuggyQSA.push( ":enabled", ":disabled" );
1351			}
1352
1353			// Support: IE9-11+
1354			// IE's :disabled selector does not pick up the children of disabled fieldsets
1355			docElem.appendChild( el ).disabled = true;
1356			if ( el.querySelectorAll(":disabled").length !== 2 ) {
1357				rbuggyQSA.push( ":enabled", ":disabled" );
1358			}
1359
1360			// Opera 10-11 does not throw on post-comma invalid pseudos
1361			el.querySelectorAll("*,:x");
1362			rbuggyQSA.push(",.*:");
1363		});
1364	}
1365
1366	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1367		docElem.webkitMatchesSelector ||
1368		docElem.mozMatchesSelector ||
1369		docElem.oMatchesSelector ||
1370		docElem.msMatchesSelector) )) ) {
1371
1372		assert(function( el ) {
1373			// Check to see if it's possible to do matchesSelector
1374			// on a disconnected node (IE 9)
1375			support.disconnectedMatch = matches.call( el, "*" );
1376
1377			// This should fail with an exception
1378			// Gecko does not error, returns false instead
1379			matches.call( el, "[s!='']:x" );
1380			rbuggyMatches.push( "!=", pseudos );
1381		});
1382	}
1383
1384	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1385	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1386
1387	/* Contains
1388	---------------------------------------------------------------------- */
1389	hasCompare = rnative.test( docElem.compareDocumentPosition );
1390
1391	// Element contains another
1392	// Purposefully self-exclusive
1393	// As in, an element does not contain itself
1394	contains = hasCompare || rnative.test( docElem.contains ) ?
1395		function( a, b ) {
1396			var adown = a.nodeType === 9 ? a.documentElement : a,
1397				bup = b && b.parentNode;
1398			return a === bup || !!( bup && bup.nodeType === 1 && (
1399				adown.contains ?
1400					adown.contains( bup ) :
1401					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1402			));
1403		} :
1404		function( a, b ) {
1405			if ( b ) {
1406				while ( (b = b.parentNode) ) {
1407					if ( b === a ) {
1408						return true;
1409					}
1410				}
1411			}
1412			return false;
1413		};
1414
1415	/* Sorting
1416	---------------------------------------------------------------------- */
1417
1418	// Document order sorting
1419	sortOrder = hasCompare ?
1420	function( a, b ) {
1421
1422		// Flag for duplicate removal
1423		if ( a === b ) {
1424			hasDuplicate = true;
1425			return 0;
1426		}
1427
1428		// Sort on method existence if only one input has compareDocumentPosition
1429		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1430		if ( compare ) {
1431			return compare;
1432		}
1433
1434		// Calculate position if both inputs belong to the same document
1435		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1436			a.compareDocumentPosition( b ) :
1437
1438			// Otherwise we know they are disconnected
1439			1;
1440
1441		// Disconnected nodes
1442		if ( compare & 1 ||
1443			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1444
1445			// Choose the first element that is related to our preferred document
1446			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1447				return -1;
1448			}
1449			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1450				return 1;
1451			}
1452
1453			// Maintain original order
1454			return sortInput ?
1455				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1456				0;
1457		}
1458
1459		return compare & 4 ? -1 : 1;
1460	} :
1461	function( a, b ) {
1462		// Exit early if the nodes are identical
1463		if ( a === b ) {
1464			hasDuplicate = true;
1465			return 0;
1466		}
1467
1468		var cur,
1469			i = 0,
1470			aup = a.parentNode,
1471			bup = b.parentNode,
1472			ap = [ a ],
1473			bp = [ b ];
1474
1475		// Parentless nodes are either documents or disconnected
1476		if ( !aup || !bup ) {
1477			return a === document ? -1 :
1478				b === document ? 1 :
1479				aup ? -1 :
1480				bup ? 1 :
1481				sortInput ?
1482				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1483				0;
1484
1485		// If the nodes are siblings, we can do a quick check
1486		} else if ( aup === bup ) {
1487			return siblingCheck( a, b );
1488		}
1489
1490		// Otherwise we need full lists of their ancestors for comparison
1491		cur = a;
1492		while ( (cur = cur.parentNode) ) {
1493			ap.unshift( cur );
1494		}
1495		cur = b;
1496		while ( (cur = cur.parentNode) ) {
1497			bp.unshift( cur );
1498		}
1499
1500		// Walk down the tree looking for a discrepancy
1501		while ( ap[i] === bp[i] ) {
1502			i++;
1503		}
1504
1505		return i ?
1506			// Do a sibling check if the nodes have a common ancestor
1507			siblingCheck( ap[i], bp[i] ) :
1508
1509			// Otherwise nodes in our document sort first
1510			ap[i] === preferredDoc ? -1 :
1511			bp[i] === preferredDoc ? 1 :
1512			0;
1513	};
1514
1515	return document;
1516};
1517
1518Sizzle.matches = function( expr, elements ) {
1519	return Sizzle( expr, null, null, elements );
1520};
1521
1522Sizzle.matchesSelector = function( elem, expr ) {
1523	// Set document vars if needed
1524	if ( ( elem.ownerDocument || elem ) !== document ) {
1525		setDocument( elem );
1526	}
1527
1528	// Make sure that attribute selectors are quoted
1529	expr = expr.replace( rattributeQuotes, "='$1']" );
1530
1531	if ( support.matchesSelector && documentIsHTML &&
1532		!compilerCache[ expr + " " ] &&
1533		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1534		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1535
1536		try {
1537			var ret = matches.call( elem, expr );
1538
1539			// IE 9's matchesSelector returns false on disconnected nodes
1540			if ( ret || support.disconnectedMatch ||
1541					// As well, disconnected nodes are said to be in a document
1542					// fragment in IE 9
1543					elem.document && elem.document.nodeType !== 11 ) {
1544				return ret;
1545			}
1546		} catch (e) {}
1547	}
1548
1549	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1550};
1551
1552Sizzle.contains = function( context, elem ) {
1553	// Set document vars if needed
1554	if ( ( context.ownerDocument || context ) !== document ) {
1555		setDocument( context );
1556	}
1557	return contains( context, elem );
1558};
1559
1560Sizzle.attr = function( elem, name ) {
1561	// Set document vars if needed
1562	if ( ( elem.ownerDocument || elem ) !== document ) {
1563		setDocument( elem );
1564	}
1565
1566	var fn = Expr.attrHandle[ name.toLowerCase() ],
1567		// Don't get fooled by Object.prototype properties (jQuery #13807)
1568		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1569			fn( elem, name, !documentIsHTML ) :
1570			undefined;
1571
1572	return val !== undefined ?
1573		val :
1574		support.attributes || !documentIsHTML ?
1575			elem.getAttribute( name ) :
1576			(val = elem.getAttributeNode(name)) && val.specified ?
1577				val.value :
1578				null;
1579};
1580
1581Sizzle.escape = function( sel ) {
1582	return (sel + "").replace( rcssescape, fcssescape )
vendor: 13,124 bytes, lines 1582-2033
1582;
1583};
1584
1585Sizzle.error = function( msg ) {
1586	throw new Error( "Syntax error, unrecognized expression: " + msg );
1587};
1588
1589/**
1590 * Document sorting and removing duplicates
1591 * @param {ArrayLike} results
1592 */
1593Sizzle.uniqueSort = function( results ) {
1594	var elem,
1595		duplicates = [],
1596		j = 0,
1597		i = 0;
1598
1599	// Unless we *know* we can detect duplicates, assume their presence
1600	hasDuplicate = !support.detectDuplicates;
1601	sortInput = !support.sortStable && results.slice( 0 );
1602	results.sort( sortOrder );
1603
1604	if ( hasDuplicate ) {
1605		while ( (elem = results[i++]) ) {
1606			if ( elem === results[ i ] ) {
1607				j = duplicates.push( i );
1608			}
1609		}
1610		while ( j-- ) {
1611			results.splice( duplicates[ j ], 1 );
1612		}
1613	}
1614
1615	// Clear input after sorting to release objects
1616	// See https://github.com/jquery/sizzle/pull/225
1617	sortInput = null;
1618
1619	return results;
1620};
1621
1622/**
1623 * Utility function for retrieving the text value of an array of DOM nodes
1624 * @param {Array|Element} elem
1625 */
1626getText = Sizzle.getText = function( elem ) {
1627	var node,
1628		ret = "",
1629		i = 0,
1630		nodeType = elem.nodeType;
1631
1632	if ( !nodeType ) {
1633		// If no nodeType, this is expected to be an array
1634		while ( (node = elem[i++]) ) {
1635			// Do not traverse comment nodes
1636			ret += getText( node );
1637		}
1638	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1639		// Use textContent for elements
1640		// innerText usage removed for consistency of new lines (jQuery #11153)
1641		if ( typeof elem.textContent === "string" ) {
1642			return elem.textContent;
1643		} else {
1644			// Traverse its children
1645			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1646				ret += getText( elem );
1647			}
1648		}
1649	} else if ( nodeType === 3 || nodeType === 4 ) {
1650		return elem.nodeValue;
1651	}
1652	// Do not include comment or processing instruction nodes
1653
1654	return ret;
1655};
1656
1657Expr = Sizzle.selectors = {
1658
1659	// Can be adjusted by the user
1660	cacheLength: 50,
1661
1662	createPseudo: markFunction,
1663
1664	match: matchExpr,
1665
1666	attrHandle: {},
1667
1668	find: {},
1669
1670	relative: {
1671		">": { dir: "parentNode", first: true },
1672		" ": { dir: "parentNode" },
1673		"+": { dir: "previousSibling", first: true },
1674		"~": { dir: "previousSibling" }
1675	},
1676
1677	preFilter: {
1678		"ATTR": function( match ) {
1679			match[1] = match[1].replace( runescape, funescape );
1680
1681			// Move the given value to match[3] whether quoted or unquoted
1682			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1683
1684			if ( match[2] === "~=" ) {
1685				match[3] = " " + match[3] + " ";
1686			}
1687
1688			return match.slice( 0, 4 );
1689		},
1690
1691		"CHILD": function( match ) {
1692			/* matches from matchExpr["CHILD"]
1693				1 type (only|nth|...)
1694				2 what (child|of-type)
1695				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1696				4 xn-component of xn+y argument ([+-]?\d*n|)
1697				5 sign of xn-component
1698				6 x of xn-component
1699				7 sign of y-component
1700				8 y of y-component
1701			*/
1702			match[1] = match[1].toLowerCase();
1703
1704			if ( match[1].slice( 0, 3 ) === "nth" ) {
1705				// nth-* requires argument
1706				if ( !match[3] ) {
1707					Sizzle.error( match[0] );
1708				}
1709
1710				// numeric x and y parameters for Expr.filter.CHILD
1711				// remember that false/true cast respectively to 0/1
1712				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1713				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1714
1715			// other types prohibit arguments
1716			} else if ( match[3] ) {
1717				Sizzle.error( match[0] );
1718			}
1719
1720			return match;
1721		},
1722
1723		"PSEUDO": function( match ) {
1724			var excess,
1725				unquoted = !match[6] && match[2];
1726
1727			if ( matchExpr["CHILD"].test( match[0] ) ) {
1728				return null;
1729			}
1730
1731			// Accept quoted arguments as-is
1732			if ( match[3] ) {
1733				match[2] = match[4] || match[5] || "";
1734
1735			// Strip excess characters from unquoted arguments
1736			} else if ( unquoted && rpseudo.test( unquoted ) &&
1737				// Get excess from tokenize (recursively)
1738				(excess = tokenize( unquoted, true )) &&
1739				// advance to the next closing parenthesis
1740				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1741
1742				// excess is a negative index
1743				match[0] = match[0].slice( 0, excess );
1744				match[2] = unquoted.slice( 0, excess );
1745			}
1746
1747			// Return only captures needed by the pseudo filter method (type and argument)
1748			return match.slice( 0, 3 );
1749		}
1750	},
1751
1752	filter: {
1753
1754		"TAG": function( nodeNameSelector ) {
1755			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1756			return nodeNameSelector === "*" ?
1757				function() { return true; } :
1758				function( elem ) {
1759					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1760				};
1761		},
1762
1763		"CLASS": function( className ) {
1764			var pattern = classCache[ className + " " ];
1765
1766			return pattern ||
1767				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1768				classCache( className, function( elem ) {
1769					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1770				});
1771		},
1772
1773		"ATTR": function( name, operator, check ) {
1774			return function( elem ) {
1775				var result = Sizzle.attr( elem, name );
1776
1777				if ( result == null ) {
1778					return operator === "!=";
1779				}
1780				if ( !operator ) {
1781					return true;
1782				}
1783
1784				result += "";
1785
1786				return operator === "=" ? result === check :
1787					operator === "!=" ? result !== check :
1788					operator === "^=" ? check && result.indexOf( check ) === 0 :
1789					operator === "*=" ? check && result.indexOf( check ) > -1 :
1790					operator === "$=" ? check && result.slice( -check.length ) === check :
1791					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1792					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1793					false;
1794			};
1795		},
1796
1797		"CHILD": function( type, what, argument, first, last ) {
1798			var simple = type.slice( 0, 3 ) !== "nth",
1799				forward = type.slice( -4 ) !== "last",
1800				ofType = what === "of-type";
1801
1802			return first === 1 && last === 0 ?
1803
1804				// Shortcut for :nth-*(n)
1805				function( elem ) {
1806					return !!elem.parentNode;
1807				} :
1808
1809				function( elem, context, xml ) {
1810					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1811						dir = simple !== forward ? "nextSibling" : "previousSibling",
1812						parent = elem.parentNode,
1813						name = ofType && elem.nodeName.toLowerCase(),
1814						useCache = !xml && !ofType,
1815						diff = false;
1816
1817					if ( parent ) {
1818
1819						// :(first|last|only)-(child|of-type)
1820						if ( simple ) {
1821							while ( dir ) {
1822								node = elem;
1823								while ( (node = node[ dir ]) ) {
1824									if ( ofType ?
1825										node.nodeName.toLowerCase() === name :
1826										node.nodeType === 1 ) {
1827
1828										return false;
1829									}
1830								}
1831								// Reverse direction for :only-* (if we haven't yet done so)
1832								start = dir = type === "only" && !start && "nextSibling";
1833							}
1834							return true;
1835						}
1836
1837						start = [ forward ? parent.firstChild : parent.lastChild ];
1838
1839						// non-xml :nth-child(...) stores cache data on `parent`
1840						if ( forward && useCache ) {
1841
1842							// Seek `elem` from a previously-cached index
1843
1844							// ...in a gzip-friendly way
1845							node = parent;
1846							outerCache = node[ expando ] || (node[ expando ] = {});
1847
1848							// Support: IE <9 only
1849							// Defend against cloned attroperties (jQuery gh-1709)
1850							uniqueCache = outerCache[ node.uniqueID ] ||
1851								(outerCache[ node.uniqueID ] = {});
1852
1853							cache = uniqueCache[ type ] || [];
1854							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1855							diff = nodeIndex && cache[ 2 ];
1856							node = nodeIndex && parent.childNodes[ nodeIndex ];
1857
1858							while ( (node = ++nodeIndex && node && node[ dir ] ||
1859
1860								// Fallback to seeking `elem` from the start
1861								(diff = nodeIndex = 0) || start.pop()) ) {
1862
1863								// When found, cache indexes on `parent` and break
1864								if ( node.nodeType === 1 && ++diff && node === elem ) {
1865									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1866									break;
1867								}
1868							}
1869
1870						} else {
1871							// Use previously-cached element index if available
1872							if ( useCache ) {
1873								// ...in a gzip-friendly way
1874								node = elem;
1875								outerCache = node[ expando ] || (node[ expando ] = {});
1876
1877								// Support: IE <9 only
1878								// Defend against cloned attroperties (jQuery gh-1709)
1879								uniqueCache = outerCache[ node.uniqueID ] ||
1880									(outerCache[ node.uniqueID ] = {});
1881
1882								cache = uniqueCache[ type ] || [];
1883								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1884								diff = nodeIndex;
1885							}
1886
1887							// xml :nth-child(...)
1888							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1889							if ( diff === false ) {
1890								// Use the same loop as above to seek `elem` from the start
1891								while ( (node = ++nodeIndex && node && node[ dir ] ||
1892									(diff = nodeIndex = 0) || start.pop()) ) {
1893
1894									if ( ( ofType ?
1895										node.nodeName.toLowerCase() === name :
1896										node.nodeType === 1 ) &&
1897										++diff ) {
1898
1899										// Cache the index of each encountered element
1900										if ( useCache ) {
1901											outerCache = node[ expando ] || (node[ expando ] = {});
1902
1903											// Support: IE <9 only
1904											// Defend against cloned attroperties (jQuery gh-1709)
1905											uniqueCache = outerCache[ node.uniqueID ] ||
1906												(outerCache[ node.uniqueID ] = {});
1907
1908											uniqueCache[ type ] = [ dirruns, diff ];
1909										}
1910
1911										if ( node === elem ) {
1912											break;
1913										}
1914									}
1915								}
1916							}
1917						}
1918
1919						// Incorporate the offset, then check against cycle size
1920						diff -= last;
1921						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1922					}
1923				};
1924		},
1925
1926		"PSEUDO": function( pseudo, argument ) {
1927			// pseudo-class names are case-insensitive
1928			// http://www.w3.org/TR/selectors/#pseudo-classes
1929			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1930			// Remember that setFilters inherits from pseudos
1931			var args,
1932				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1933					Sizzle.error( "unsupported pseudo: " + pseudo );
1934
1935			// The user may use createPseudo to indicate that
1936			// arguments are needed to create the filter function
1937			// just as Sizzle does
1938			if ( fn[ expando ] ) {
1939				return fn( argument );
1940			}
1941
1942			// But maintain support for old signatures
1943			if ( fn.length > 1 ) {
1944				args = [ pseudo, pseudo, "", argument ];
1945				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1946					markFunction(function( seed, matches ) {
1947						var idx,
1948							matched = fn( seed, argument ),
1949							i = matched.length;
1950						while ( i-- ) {
1951							idx = indexOf( seed, matched[i] );
1952							seed[ idx ] = !( matches[ idx ] = matched[i] );
1953						}
1954					}) :
1955					function( elem ) {
1956						return fn( elem, 0, args );
1957					};
1958			}
1959
1960			return fn;
1961		}
1962	},
1963
1964	pseudos: {
1965		// Potentially complex pseudos
1966		"not": markFunction(function( selector ) {
1967			// Trim the selector passed to compile
1968			// to avoid treating leading and trailing
1969			// spaces as combinators
1970			var input = [],
1971				results = [],
1972				matcher = compile( selector.replace( rtrim, "$1" ) );
1973
1974			return matcher[ expando ] ?
1975				markFunction(function( seed, matches, context, xml ) {
1976					var elem,
1977						unmatched = matcher( seed, null, xml, [] ),
1978						i = seed.length;
1979
1980					// Match elements unmatched by `matcher`
1981					while ( i-- ) {
1982						if ( (elem = unmatched[i]) ) {
1983							seed[i] = !(matches[i] = elem);
1984						}
1985					}
1986				}) :
1987				function( elem, context, xml ) {
1988					input[0] = elem;
1989					matcher( input, null, xml, results );
1990					// Don't keep the element (issue #299)
1991					input[0] = null;
1992					return !results.pop();
1993				};
1994		}),
1995
1996		"has": markFunction(function( selector ) {
1997			return function( elem ) {
1998				return Sizzle( selector, elem ).length > 0;
1999			};
2000		}),
2001
2002		"contains": markFunction(function( text ) {
2003			text = text.replace( runescape, funescape );
2004			return function( elem ) {
2005				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
2006			};
2007		}),
2008
2009		// "Whether an element is represented by a :lang() selector
2010		// is based solely on the element's language value
2011		// being equal to the identifier C,
2012		// or beginning with the identifier C immediately followed by "-".
2013		// The matching of C against the element's language value is performed case-insensitively.
2014		// The identifier C does not have to be a valid language name."
2015		// http://www.w3.org/TR/selectors/#lang-pseudo
2016		"lang": markFunction( function( lang ) {
2017			// lang value must be a valid identifier
2018			if ( !ridentifier.test(lang || "") ) {
2019				Sizzle.error( "unsupported lang: " + lang );
2020			}
2021			lang = lang.replace( runescape, funescape ).toLowerCase();
2022			return function( elem ) {
2023				var elemLang;
2024				do {
2025					if ( (elemLang = documentIsHTML ?
2026						elem.lang :
2027						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
2028
2029						elemLang = elemLang.toLowerCase();
2030						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2031					}
2032				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
2033				return false;
vendor: 22,514 bytes, lines 2034-2845
2034			};
2035		}),
2036
2037		// Miscellaneous
2038		"target": function( elem ) {
2039			var hash = window.location && window.location.hash;
2040			return hash && hash.slice( 1 ) === elem.id;
2041		},
2042
2043		"root": function( elem ) {
2044			return elem === docElem;
2045		},
2046
2047		"focus": function( elem ) {
2048			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2049		},
2050
2051		// Boolean properties
2052		"enabled": createDisabledPseudo( false ),
2053		"disabled": createDisabledPseudo( true ),
2054
2055		"checked": function( elem ) {
2056			// In CSS3, :checked should return both checked and selected elements
2057			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2058			var nodeName = elem.nodeName.toLowerCase();
2059			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2060		},
2061
2062		"selected": function( elem ) {
2063			// Accessing this property makes selected-by-default
2064			// options in Safari work properly
2065			if ( elem.parentNode ) {
2066				elem.parentNode.selectedIndex;
2067			}
2068
2069			return elem.selected === true;
2070		},
2071
2072		// Contents
2073		"empty": function( elem ) {
2074			// http://www.w3.org/TR/selectors/#empty-pseudo
2075			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2076			//   but not by others (comment: 8; processing instruction: 7; etc.)
2077			// nodeType < 6 works because attributes (2) do not appear as children
2078			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2079				if ( elem.nodeType < 6 ) {
2080					return false;
2081				}
2082			}
2083			return true;
2084		},
2085
2086		"parent": function( elem ) {
2087			return !Expr.pseudos["empty"]( elem );
2088		},
2089
2090		// Element/input types
2091		"header": function( elem ) {
2092			return rheader.test( elem.nodeName );
2093		},
2094
2095		"input": function( elem ) {
2096			return rinputs.test( elem.nodeName );
2097		},
2098
2099		"button": function( elem ) {
2100			var name = elem.nodeName.toLowerCase();
2101			return name === "input" && elem.type === "button" || name === "button";
2102		},
2103
2104		"text": function( elem ) {
2105			var attr;
2106			return elem.nodeName.toLowerCase() === "input" &&
2107				elem.type === "text" &&
2108
2109				// Support: IE<8
2110				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2111				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2112		},
2113
2114		// Position-in-collection
2115		"first": createPositionalPseudo(function() {
2116			return [ 0 ];
2117		}),
2118
2119		"last": createPositionalPseudo(function( matchIndexes, length ) {
2120			return [ length - 1 ];
2121		}),
2122
2123		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2124			return [ argument < 0 ? argument + length : argument ];
2125		}),
2126
2127		"even": createPositionalPseudo(function( matchIndexes, length ) {
2128			var i = 0;
2129			for ( ; i < length; i += 2 ) {
2130				matchIndexes.push( i );
2131			}
2132			return matchIndexes;
2133		}),
2134
2135		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2136			var i = 1;
2137			for ( ; i < length; i += 2 ) {
2138				matchIndexes.push( i );
2139			}
2140			return matchIndexes;
2141		}),
2142
2143		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2144			var i = argument < 0 ? argument + length : argument;
2145			for ( ; --i >= 0; ) {
2146				matchIndexes.push( i );
2147			}
2148			return matchIndexes;
2149		}),
2150
2151		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2152			var i = argument < 0 ? argument + length : argument;
2153			for ( ; ++i < length; ) {
2154				matchIndexes.push( i );
2155			}
2156			return matchIndexes;
2157		})
2158	}
2159};
2160
2161Expr.pseudos["nth"] = Expr.pseudos["eq"];
2162
2163// Add button/input type pseudos
2164for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2165	Expr.pseudos[ i ] = createInputPseudo( i );
2166}
2167for ( i in { submit: true, reset: true } ) {
2168	Expr.pseudos[ i ] = createButtonPseudo( i );
2169}
2170
2171// Easy API for creating new setFilters
2172function setFilters() {}
2173setFilters.prototype = Expr.filters = Expr.pseudos;
2174Expr.setFilters = new setFilters();
2175
2176tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2177	var matched, match, tokens, type,
2178		soFar, groups, preFilters,
2179		cached = tokenCache[ selector + " " ];
2180
2181	if ( cached ) {
2182		return parseOnly ? 0 : cached.slice( 0 );
2183	}
2184
2185	soFar = selector;
2186	groups = [];
2187	preFilters = Expr.preFilter;
2188
2189	while ( soFar ) {
2190
2191		// Comma and first run
2192		if ( !matched || (match = rcomma.exec( soFar )) ) {
2193			if ( match ) {
2194				// Don't consume trailing commas as valid
2195				soFar = soFar.slice( match[0].length ) || soFar;
2196			}
2197			groups.push( (tokens = []) );
2198		}
2199
2200		matched = false;
2201
2202		// Combinators
2203		if ( (match = rcombinators.exec( soFar )) ) {
2204			matched = match.shift();
2205			tokens.push({
2206				value: matched,
2207				// Cast descendant combinators to space
2208				type: match[0].replace( rtrim, " " )
2209			});
2210			soFar = soFar.slice( matched.length );
2211		}
2212
2213		// Filters
2214		for ( type in Expr.filter ) {
2215			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2216				(match = preFilters[ type ]( match ))) ) {
2217				matched = match.shift();
2218				tokens.push({
2219					value: matched,
2220					type: type,
2221					matches: match
2222				});
2223				soFar = soFar.slice( matched.length );
2224			}
2225		}
2226
2227		if ( !matched ) {
2228			break;
2229		}
2230	}
2231
2232	// Return the length of the invalid excess
2233	// if we're just parsing
2234	// Otherwise, throw an error or return tokens
2235	return parseOnly ?
2236		soFar.length :
2237		soFar ?
2238			Sizzle.error( selector ) :
2239			// Cache the tokens
2240			tokenCache( selector, groups ).slice( 0 );
2241};
2242
2243function toSelector( tokens ) {
2244	var i = 0,
2245		len = tokens.length,
2246		selector = "";
2247	for ( ; i < len; i++ ) {
2248		selector += tokens[i].value;
2249	}
2250	return selector;
2251}
2252
2253function addCombinator( matcher, combinator, base ) {
2254	var dir = combinator.dir,
2255		skip = combinator.next,
2256		key = skip || dir,
2257		checkNonElements = base && key === "parentNode",
2258		doneName = done++;
2259
2260	return combinator.first ?
2261		// Check against closest ancestor/preceding element
2262		function( elem, context, xml ) {
2263			while ( (elem = elem[ dir ]) ) {
2264				if ( elem.nodeType === 1 || checkNonElements ) {
2265					return matcher( elem, context, xml );
2266				}
2267			}
2268			return false;
2269		} :
2270
2271		// Check against all ancestor/preceding elements
2272		function( elem, context, xml ) {
2273			var oldCache, uniqueCache, outerCache,
2274				newCache = [ dirruns, doneName ];
2275
2276			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2277			if ( xml ) {
2278				while ( (elem = elem[ dir ]) ) {
2279					if ( elem.nodeType === 1 || checkNonElements ) {
2280						if ( matcher( elem, context, xml ) ) {
2281							return true;
2282						}
2283					}
2284				}
2285			} else {
2286				while ( (elem = elem[ dir ]) ) {
2287					if ( elem.nodeType === 1 || checkNonElements ) {
2288						outerCache = elem[ expando ] || (elem[ expando ] = {});
2289
2290						// Support: IE <9 only
2291						// Defend against cloned attroperties (jQuery gh-1709)
2292						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2293
2294						if ( skip && skip === elem.nodeName.toLowerCase() ) {
2295							elem = elem[ dir ] || elem;
2296						} else if ( (oldCache = uniqueCache[ key ]) &&
2297							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2298
2299							// Assign to newCache so results back-propagate to previous elements
2300							return (newCache[ 2 ] = oldCache[ 2 ]);
2301						} else {
2302							// Reuse newcache so results back-propagate to previous elements
2303							uniqueCache[ key ] = newCache;
2304
2305							// A match means we're done; a fail means we have to keep checking
2306							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2307								return true;
2308							}
2309						}
2310					}
2311				}
2312			}
2313			return false;
2314		};
2315}
2316
2317function elementMatcher( matchers ) {
2318	return matchers.length > 1 ?
2319		function( elem, context, xml ) {
2320			var i = matchers.length;
2321			while ( i-- ) {
2322				if ( !matchers[i]( elem, context, xml ) ) {
2323					return false;
2324				}
2325			}
2326			return true;
2327		} :
2328		matchers[0];
2329}
2330
2331function multipleContexts( selector, contexts, results ) {
2332	var i = 0,
2333		len = contexts.length;
2334	for ( ; i < len; i++ ) {
2335		Sizzle( selector, contexts[i], results );
2336	}
2337	return results;
2338}
2339
2340function condense( unmatched, map, filter, context, xml ) {
2341	var elem,
2342		newUnmatched = [],
2343		i = 0,
2344		len = unmatched.length,
2345		mapped = map != null;
2346
2347	for ( ; i < len; i++ ) {
2348		if ( (elem = unmatched[i]) ) {
2349			if ( !filter || filter( elem, context, xml ) ) {
2350				newUnmatched.push( elem );
2351				if ( mapped ) {
2352					map.push( i );
2353				}
2354			}
2355		}
2356	}
2357
2358	return newUnmatched;
2359}
2360
2361function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2362	if ( postFilter && !postFilter[ expando ] ) {
2363		postFilter = setMatcher( postFilter );
2364	}
2365	if ( postFinder && !postFinder[ expando ] ) {
2366		postFinder = setMatcher( postFinder, postSelector );
2367	}
2368	return markFunction(function( seed, results, context, xml ) {
2369		var temp, i, elem,
2370			preMap = [],
2371			postMap = [],
2372			preexisting = results.length,
2373
2374			// Get initial elements from seed or context
2375			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2376
2377			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2378			matcherIn = preFilter && ( seed || !selector ) ?
2379				condense( elems, preMap, preFilter, context, xml ) :
2380				elems,
2381
2382			matcherOut = matcher ?
2383				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2384				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2385
2386					// ...intermediate processing is necessary
2387					[] :
2388
2389					// ...otherwise use results directly
2390					results :
2391				matcherIn;
2392
2393		// Find primary matches
2394		if ( matcher ) {
2395			matcher( matcherIn, matcherOut, context, xml );
2396		}
2397
2398		// Apply postFilter
2399		if ( postFilter ) {
2400			temp = condense( matcherOut, postMap );
2401			postFilter( temp, [], context, xml );
2402
2403			// Un-match failing elements by moving them back to matcherIn
2404			i = temp.length;
2405			while ( i-- ) {
2406				if ( (elem = temp[i]) ) {
2407					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2408				}
2409			}
2410		}
2411
2412		if ( seed ) {
2413			if ( postFinder || preFilter ) {
2414				if ( postFinder ) {
2415					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2416					temp = [];
2417					i = matcherOut.length;
2418					while ( i-- ) {
2419						if ( (elem = matcherOut[i]) ) {
2420							// Restore matcherIn since elem is not yet a final match
2421							temp.push( (matcherIn[i] = elem) );
2422						}
2423					}
2424					postFinder( null, (matcherOut = []), temp, xml );
2425				}
2426
2427				// Move matched elements from seed to results to keep them synchronized
2428				i = matcherOut.length;
2429				while ( i-- ) {
2430					if ( (elem = matcherOut[i]) &&
2431						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2432
2433						seed[temp] = !(results[temp] = elem);
2434					}
2435				}
2436			}
2437
2438		// Add elements to results, through postFinder if defined
2439		} else {
2440			matcherOut = condense(
2441				matcherOut === results ?
2442					matcherOut.splice( preexisting, matcherOut.length ) :
2443					matcherOut
2444			);
2445			if ( postFinder ) {
2446				postFinder( null, results, matcherOut, xml );
2447			} else {
2448				push.apply( results, matcherOut );
2449			}
2450		}
2451	});
2452}
2453
2454function matcherFromTokens( tokens ) {
2455	var checkContext, matcher, j,
2456		len = tokens.length,
2457		leadingRelative = Expr.relative[ tokens[0].type ],
2458		implicitRelative = leadingRelative || Expr.relative[" "],
2459		i = leadingRelative ? 1 : 0,
2460
2461		// The foundational matcher ensures that elements are reachable from top-level context(s)
2462		matchContext = addCombinator( function( elem ) {
2463			return elem === checkContext;
2464		}, implicitRelative, true ),
2465		matchAnyContext = addCombinator( function( elem ) {
2466			return indexOf( checkContext, elem ) > -1;
2467		}, implicitRelative, true ),
2468		matchers = [ function( elem, context, xml ) {
2469			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2470				(checkContext = context).nodeType ?
2471					matchContext( elem, context, xml ) :
2472					matchAnyContext( elem, context, xml ) );
2473			// Avoid hanging onto element (issue #299)
2474			checkContext = null;
2475			return ret;
2476		} ];
2477
2478	for ( ; i < len; i++ ) {
2479		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2480			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2481		} else {
2482			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2483
2484			// Return special upon seeing a positional matcher
2485			if ( matcher[ expando ] ) {
2486				// Find the next relative operator (if any) for proper handling
2487				j = ++i;
2488				for ( ; j < len; j++ ) {
2489					if ( Expr.relative[ tokens[j].type ] ) {
2490						break;
2491					}
2492				}
2493				return setMatcher(
2494					i > 1 && elementMatcher( matchers ),
2495					i > 1 && toSelector(
2496						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2497						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2498					).replace( rtrim, "$1" ),
2499					matcher,
2500					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2501					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2502					j < len && toSelector( tokens )
2503				);
2504			}
2505			matchers.push( matcher );
2506		}
2507	}
2508
2509	return elementMatcher( matchers );
2510}
2511
2512function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2513	var bySet = setMatchers.length > 0,
2514		byElement = elementMatchers.length > 0,
2515		superMatcher = function( seed, context, xml, results, outermost ) {
2516			var elem, j, matcher,
2517				matchedCount = 0,
2518				i = "0",
2519				unmatched = seed && [],
2520				setMatched = [],
2521				contextBackup = outermostContext,
2522				// We must always have either seed elements or outermost context
2523				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2524				// Use integer dirruns iff this is the outermost matcher
2525				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2526				len = elems.length;
2527
2528			if ( outermost ) {
2529				outermostContext = context === document || context || outermost;
2530			}
2531
2532			// Add elements passing elementMatchers directly to results
2533			// Support: IE<9, Safari
2534			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2535			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2536				if ( byElement && elem ) {
2537					j = 0;
2538					if ( !context && elem.ownerDocument !== document ) {
2539						setDocument( elem );
2540						xml = !documentIsHTML;
2541					}
2542					while ( (matcher = elementMatchers[j++]) ) {
2543						if ( matcher( elem, context || document, xml) ) {
2544							results.push( elem );
2545							break;
2546						}
2547					}
2548					if ( outermost ) {
2549						dirruns = dirrunsUnique;
2550					}
2551				}
2552
2553				// Track unmatched elements for set filters
2554				if ( bySet ) {
2555					// They will have gone through all possible matchers
2556					if ( (elem = !matcher && elem) ) {
2557						matchedCount--;
2558					}
2559
2560					// Lengthen the array for every element, matched or not
2561					if ( seed ) {
2562						unmatched.push( elem );
2563					}
2564				}
2565			}
2566
2567			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2568			// makes the latter nonnegative.
2569			matchedCount += i;
2570
2571			// Apply set filters to unmatched elements
2572			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2573			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2574			// no element matchers and no seed.
2575			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2576			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2577			// numerically zero.
2578			if ( bySet && i !== matchedCount ) {
2579				j = 0;
2580				while ( (matcher = setMatchers[j++]) ) {
2581					matcher( unmatched, setMatched, context, xml );
2582				}
2583
2584				if ( seed ) {
2585					// Reintegrate element matches to eliminate the need for sorting
2586					if ( matchedCount > 0 ) {
2587						while ( i-- ) {
2588							if ( !(unmatched[i] || setMatched[i]) ) {
2589								setMatched[i] = pop.call( results );
2590							}
2591						}
2592					}
2593
2594					// Discard index placeholder values to get only actual matches
2595					setMatched = condense( setMatched );
2596				}
2597
2598				// Add matches to results
2599				push.apply( results, setMatched );
2600
2601				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2602				if ( outermost && !seed && setMatched.length > 0 &&
2603					( matchedCount + setMatchers.length ) > 1 ) {
2604
2605					Sizzle.uniqueSort( results );
2606				}
2607			}
2608
2609			// Override manipulation of globals by nested matchers
2610			if ( outermost ) {
2611				dirruns = dirrunsUnique;
2612				outermostContext = contextBackup;
2613			}
2614
2615			return unmatched;
2616		};
2617
2618	return bySet ?
2619		markFunction( superMatcher ) :
2620		superMatcher;
2621}
2622
2623compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2624	var i,
2625		setMatchers = [],
2626		elementMatchers = [],
2627		cached = compilerCache[ selector + " " ];
2628
2629	if ( !cached ) {
2630		// Generate a function of recursive functions that can be used to check each element
2631		if ( !match ) {
2632			match = tokenize( selector );
2633		}
2634		i = match.length;
2635		while ( i-- ) {
2636			cached = matcherFromTokens( match[i] );
2637			if ( cached[ expando ] ) {
2638				setMatchers.push( cached );
2639			} else {
2640				elementMatchers.push( cached );
2641			}
2642		}
2643
2644		// Cache the compiled function
2645		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2646
2647		// Save selector and tokenization
2648		cached.selector = selector;
2649	}
2650	return cached;
2651};
2652
2653/**
2654 * A low-level selection function that works with Sizzle's compiled
2655 *  selector functions
2656 * @param {String|Function} selector A selector or a pre-compiled
2657 *  selector function built with Sizzle.compile
2658 * @param {Element} context
2659 * @param {Array} [results]
2660 * @param {Array} [seed] A set of elements to match against
2661 */
2662select = Sizzle.select = function( selector, context, results, seed ) {
2663	var i, tokens, token, type, find,
2664		compiled = typeof selector === "function" && selector,
2665		match = !seed && tokenize( (selector = compiled.selector || selector) );
2666
2667	results = results || [];
2668
2669	// Try to minimize operations if there is only one selector in the list and no seed
2670	// (the latter of which guarantees us context)
2671	if ( match.length === 1 ) {
2672
2673		// Reduce context if the leading compound selector is an ID
2674		tokens = match[0] = match[0].slice( 0 );
2675		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2676				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
2677
2678			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2679			if ( !context ) {
2680				return results;
2681
2682			// Precompiled matchers will still verify ancestry, so step up a level
2683			} else if ( compiled ) {
2684				context = context.parentNode;
2685			}
2686
2687			selector = selector.slice( tokens.shift().value.length );
2688		}
2689
2690		// Fetch a seed set for right-to-left matching
2691		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2692		while ( i-- ) {
2693			token = tokens[i];
2694
2695			// Abort if we hit a combinator
2696			if ( Expr.relative[ (type = token.type) ] ) {
2697				break;
2698			}
2699			if ( (find = Expr.find[ type ]) ) {
2700				// Search, expanding context for leading sibling combinators
2701				if ( (seed = find(
2702					token.matches[0].replace( runescape, funescape ),
2703					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2704				)) ) {
2705
2706					// If seed is empty or no tokens remain, we can return early
2707					tokens.splice( i, 1 );
2708					selector = seed.length && toSelector( tokens );
2709					if ( !selector ) {
2710						push.apply( results, seed );
2711						return results;
2712					}
2713
2714					break;
2715				}
2716			}
2717		}
2718	}
2719
2720	// Compile and execute a filtering function if one is not provided
2721	// Provide `match` to avoid retokenization if we modified the selector above
2722	( compiled || compile( selector, match ) )(
2723		seed,
2724		context,
2725		!documentIsHTML,
2726		results,
2727		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2728	);
2729	return results;
2730};
2731
2732// One-time assignments
2733
2734// Sort stability
2735support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2736
2737// Support: Chrome 14-35+
2738// Always assume duplicates if they aren't passed to the comparison function
2739support.detectDuplicates = !!hasDuplicate;
2740
2741// Initialize against the default document
2742setDocument();
2743
2744// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2745// Detached nodes confoundingly follow *each other*
2746support.sortDetached = assert(function( el ) {
2747	// Should return 1, but returns 4 (following)
2748	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
2749});
2750
2751// Support: IE<8
2752// Prevent attribute/property "interpolation"
2753// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2754if ( !assert(function( el ) {
2755	el.innerHTML = "<a href='#'></a>";
2756	return el.firstChild.getAttribute("href") === "#" ;
2757}) ) {
2758	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2759		if ( !isXML ) {
2760			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2761		}
2762	});
2763}
2764
2765// Support: IE<9
2766// Use defaultValue in place of getAttribute("value")
2767if ( !support.attributes || !assert(function( el ) {
2768	el.innerHTML = "<input/>";
2769	el.firstChild.setAttribute( "value", "" );
2770	return el.firstChild.getAttribute( "value" ) === "";
2771}) ) {
2772	addHandle( "value", function( elem, name, isXML ) {
2773		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2774			return elem.defaultValue;
2775		}
2776	});
2777}
2778
2779// Support: IE<9
2780// Use getAttributeNode to fetch booleans when getAttribute lies
2781if ( !assert(function( el ) {
2782	return el.getAttribute("disabled") == null;
2783}) ) {
2784	addHandle( booleans, function( elem, name, isXML ) {
2785		var val;
2786		if ( !isXML ) {
2787			return elem[ name ] === true ? name.toLowerCase() :
2788					(val = elem.getAttributeNode( name )) && val.specified ?
2789					val.value :
2790				null;
2791		}
2792	});
2793}
2794
2795return Sizzle;
2796
2797})( window );
2798
2799
2800
2801jQuery.find = Sizzle;
2802jQuery.expr = Sizzle.selectors;
2803
2804// Deprecated
2805jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2806jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2807jQuery.text = Sizzle.getText;
2808jQuery.isXMLDoc = Sizzle.isXML;
2809jQuery.contains = Sizzle.contains;
2810jQuery.escapeSelector = Sizzle.escape;
2811
2812
2813
2814
2815var dir = function( elem, dir, until ) {
2816	var matched = [],
2817		truncate = until !== undefined;
2818
2819	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2820		if ( elem.nodeType === 1 ) {
2821			if ( truncate && jQuery( elem ).is( until ) ) {
2822				break;
2823			}
2824			matched.push( elem );
2825		}
2826	}
2827	return matched;
2828};
2829
2830
2831var siblings = function( n, elem ) {
2832	var matched = [];
2833
2834	for ( ; n; n = n.nextSibling ) {
2835		if ( n.nodeType === 1 && n !== elem ) {
2836			matched.push( n );
2837		}
2838	}
2839
2840	return matched;
2841};
2842
2843
2844var rneedsContext = jQuery.expr.match.needsContext;
2845
2846var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
2847
2848
2849
2850var risSimple = /^.[^:#\[\.,]*$/;
2851
2852// Implement the identical functionality for filter and not
2853function winnow( elements, qualifier, not ) {
2854	if ( jQuery.isFunction( qualifier ) ) {
2855		return jQuery.grep( elements, function( elem, i ) {
2856			return !!qualifier.call( elem, i, elem ) !== not;
2857		} );
2858	}
2859
2860	// Single element
2861	if ( qualifier.nodeType ) {
2862		return jQuery.grep( elements, function( elem ) {
2863			return ( elem === qualifier ) !== not;
2864		} );
2865	}
2866
2867	// Arraylike of elements (jQuery, arguments, Array)
2868	if ( typeof qualifier !== "string" ) {
2869		return jQuery.grep( elements, function( elem ) {
2870			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2871		} );
2872	}
2873
2874	// Simple selector that can be filtered directly, removing non-Elements
2875	if ( risSimple.test( qualifier ) ) {
2876		return jQuery.filter( qualifier, elements, not );
2877	}
2878
2879	// Complex selector, compare the two sets, removing non-Elements
2880	qualifier = jQuery.filter( qualifier, elements );
2881	return jQuery.grep( elements, function( elem ) {
2882		return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
2883	} );
2884}
2885
2886jQuery.filter = function( expr, elems, not ) {
2887	var elem = elems[ 0 ];
2888
2889	if ( not ) {
2890		expr = ":not(" + expr + ")";
2891	}
2892
2893	if ( elems.length === 1 && elem.nodeType === 1 ) {
2894		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
2895	}
2896
2897	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2898		return elem.nodeType === 1;
vendor: 8,116 bytes, lines 2899-3227
2899	} ) );
2900};
2901
2902jQuery.fn.extend( {
2903	find: function( selector ) {
2904		var i, ret,
2905			len = this.length,
2906			self = this;
2907
2908		if ( typeof selector !== "string" ) {
2909			return this.pushStack( jQuery( selector ).filter( function() {
2910				for ( i = 0; i < len; i++ ) {
2911					if ( jQuery.contains( self[ i ], this ) ) {
2912						return true;
2913					}
2914				}
2915			} ) );
2916		}
2917
2918		ret = this.pushStack( [] );
2919
2920		for ( i = 0; i < len; i++ ) {
2921			jQuery.find( selector, self[ i ], ret );
2922		}
2923
2924		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
2925	},
2926	filter: function( selector ) {
2927		return this.pushStack( winnow( this, selector || [], false ) );
2928	},
2929	not: function( selector ) {
2930		return this.pushStack( winnow( this, selector || [], true ) );
2931	},
2932	is: function( selector ) {
2933		return !!winnow(
2934			this,
2935
2936			// If this is a positional/relative selector, check membership in the returned set
2937			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2938			typeof selector === "string" && rneedsContext.test( selector ) ?
2939				jQuery( selector ) :
2940				selector || [],
2941			false
2942		).length;
2943	}
2944} );
2945
2946
2947// Initialize a jQuery object
2948
2949
2950// A central reference to the root jQuery(document)
2951var rootjQuery,
2952
2953	// A simple way to check for HTML strings
2954	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2955	// Strict HTML recognition (#11290: must start with <)
2956	// Shortcut simple #id case for speed
2957	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2958
2959	init = jQuery.fn.init = function( selector, context, root ) {
2960		var match, elem;
2961
2962		// HANDLE: $(""), $(null), $(undefined), $(false)
2963		if ( !selector ) {
2964			return this;
2965		}
2966
2967		// Method init() accepts an alternate rootjQuery
2968		// so migrate can support jQuery.sub (gh-2101)
2969		root = root || rootjQuery;
2970
2971		// Handle HTML strings
2972		if ( typeof selector === "string" ) {
2973			if ( selector[ 0 ] === "<" &&
2974				selector[ selector.length - 1 ] === ">" &&
2975				selector.length >= 3 ) {
2976
2977				// Assume that strings that start and end with <> are HTML and skip the regex check
2978				match = [ null, selector, null ];
2979
2980			} else {
2981				match = rquickExpr.exec( selector );
2982			}
2983
2984			// Match html or make sure no context is specified for #id
2985			if ( match && ( match[ 1 ] || !context ) ) {
2986
2987				// HANDLE: $(html) -> $(array)
2988				if ( match[ 1 ] ) {
2989					context = context instanceof jQuery ? context[ 0 ] : context;
2990
2991					// Option to run scripts is true for back-compat
2992					// Intentionally let the error be thrown if parseHTML is not present
2993					jQuery.merge( this, jQuery.parseHTML(
2994						match[ 1 ],
2995						context && context.nodeType ? context.ownerDocument || context : document,
2996						true
2997					) );
2998
2999					// HANDLE: $(html, props)
3000					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3001						for ( match in context ) {
3002
3003							// Properties of context are called as methods if possible
3004							if ( jQuery.isFunction( this[ match ] ) ) {
3005								this[ match ]( context[ match ] );
3006
3007							// ...and otherwise set as attributes
3008							} else {
3009								this.attr( match, context[ match ] );
3010							}
3011						}
3012					}
3013
3014					return this;
3015
3016				// HANDLE: $(#id)
3017				} else {
3018					elem = document.getElementById( match[ 2 ] );
3019
3020					if ( elem ) {
3021
3022						// Inject the element directly into the jQuery object
3023						this[ 0 ] = elem;
3024						this.length = 1;
3025					}
3026					return this;
3027				}
3028
3029			// HANDLE: $(expr, $(...))
3030			} else if ( !context || context.jquery ) {
3031				return ( context || root ).find( selector );
3032
3033			// HANDLE: $(expr, context)
3034			// (which is just equivalent to: $(context).find(expr)
3035			} else {
3036				return this.constructor( context ).find( selector );
3037			}
3038
3039		// HANDLE: $(DOMElement)
3040		} else if ( selector.nodeType ) {
3041			this[ 0 ] = selector;
3042			this.length = 1;
3043			return this;
3044
3045		// HANDLE: $(function)
3046		// Shortcut for document ready
3047		} else if ( jQuery.isFunction( selector ) ) {
3048			return root.ready !== undefined ?
3049				root.ready( selector ) :
3050
3051				// Execute immediately if ready is not present
3052				selector( jQuery );
3053		}
3054
3055		return jQuery.makeArray( selector, this );
3056	};
3057
3058// Give the init function the jQuery prototype for later instantiation
3059init.prototype = jQuery.fn;
3060
3061// Initialize central reference
3062rootjQuery = jQuery( document );
3063
3064
3065var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3066
3067	// Methods guaranteed to produce a unique set when starting from a unique set
3068	guaranteedUnique = {
3069		children: true,
3070		contents: true,
3071		next: true,
3072		prev: true
3073	};
3074
3075jQuery.fn.extend( {
3076	has: function( target ) {
3077		var targets = jQuery( target, this ),
3078			l = targets.length;
3079
3080		return this.filter( function() {
3081			var i = 0;
3082			for ( ; i < l; i++ ) {
3083				if ( jQuery.contains( this, targets[ i ] ) ) {
3084					return true;
3085				}
3086			}
3087		} );
3088	},
3089
3090	closest: function( selectors, context ) {
3091		var cur,
3092			i = 0,
3093			l = this.length,
3094			matched = [],
3095			targets = typeof selectors !== "string" && jQuery( selectors );
3096
3097		// Positional selectors never match, since there's no _selection_ context
3098		if ( !rneedsContext.test( selectors ) ) {
3099			for ( ; i < l; i++ ) {
3100				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3101
3102					// Always skip document fragments
3103					if ( cur.nodeType < 11 && ( targets ?
3104						targets.index( cur ) > -1 :
3105
3106						// Don't pass non-elements to Sizzle
3107						cur.nodeType === 1 &&
3108							jQuery.find.matchesSelector( cur, selectors ) ) ) {
3109
3110						matched.push( cur );
3111						break;
3112					}
3113				}
3114			}
3115		}
3116
3117		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3118	},
3119
3120	// Determine the position of an element within the set
3121	index: function( elem ) {
3122
3123		// No argument, return index in parent
3124		if ( !elem ) {
3125			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3126		}
3127
3128		// Index in selector
3129		if ( typeof elem === "string" ) {
3130			return indexOf.call( jQuery( elem ), this[ 0 ] );
3131		}
3132
3133		// Locate the position of the desired element
3134		return indexOf.call( this,
3135
3136			// If it receives a jQuery object, the first element is used
3137			elem.jquery ? elem[ 0 ] : elem
3138		);
3139	},
3140
3141	add: function( selector, context ) {
3142		return this.pushStack(
3143			jQuery.uniqueSort(
3144				jQuery.merge( this.get(), jQuery( selector, context ) )
3145			)
3146		);
3147	},
3148
3149	addBack: function( selector ) {
3150		return this.add( selector == null ?
3151			this.prevObject : this.prevObject.filter( selector )
3152		);
3153	}
3154} );
3155
3156function sibling( cur, dir ) {
3157	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3158	return cur;
3159}
3160
3161jQuery.each( {
3162	parent: function( elem ) {
3163		var parent = elem.parentNode;
3164		return parent && parent.nodeType !== 11 ? parent : null;
3165	},
3166	parents: function( elem ) {
3167		return dir( elem, "parentNode" );
3168	},
3169	parentsUntil: function( elem, i, until ) {
3170		return dir( elem, "parentNode", until );
3171	},
3172	next: function( elem ) {
3173		return sibling( elem, "nextSibling" );
3174	},
3175	prev: function( elem ) {
3176		return sibling( elem, "previousSibling" );
3177	},
3178	nextAll: function( elem ) {
3179		return dir( elem, "nextSibling" );
3180	},
3181	prevAll: function( elem ) {
3182		return dir( elem, "previousSibling" );
3183	},
3184	nextUntil: function( elem, i, until ) {
3185		return dir( elem, "nextSibling", until );
3186	},
3187	prevUntil: function( elem, i, until ) {
3188		return dir( elem, "previousSibling", until );
3189	},
3190	siblings: function( elem ) {
3191		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3192	},
3193	children: function( elem ) {
3194		return siblings( elem.firstChild );
3195	},
3196	contents: function( elem ) {
3197		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3198	}
3199}, function( name, fn ) {
3200	jQuery.fn[ name ] = function( until, selector ) {
3201		var matched = jQuery.map( this, fn, until );
3202
3203		if ( name.slice( -5 ) !== "Until" ) {
3204			selector = until;
3205		}
3206
3207		if ( selector && typeof selector === "string" ) {
3208			matched = jQuery.filter( selector, matched );
3209		}
3210
3211		if ( this.length > 1 ) {
3212
3213			// Remove duplicates
3214			if ( !guaranteedUnique[ name ] ) {
3215				jQuery.uniqueSort( matched );
3216			}
3217
3218			// Reverse order for parents* and prev-derivatives
3219			if ( rparentsprev.test( name ) ) {
3220				matched.reverse();
3221			}
3222		}
3223
3224		return this.pushStack( matched );
3225	};
3226} );
3227var rnot
vendor: 6,300 bytes, lines 3227-3488
3227htmlwhite = ( /[^\x20\t\r\n\f]+/g );
3228
3229
3230
3231// Convert String-formatted options into Object-formatted ones
3232function createOptions( options ) {
3233	var object = {};
3234	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3235		object[ flag ] = true;
3236	} );
3237	return object;
3238}
3239
3240/*
3241 * Create a callback list using the following parameters:
3242 *
3243 *	options: an optional list of space-separated options that will change how
3244 *			the callback list behaves or a more traditional option object
3245 *
3246 * By default a callback list will act like an event callback list and can be
3247 * "fired" multiple times.
3248 *
3249 * Possible options:
3250 *
3251 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3252 *
3253 *	memory:			will keep track of previous values and will call any callback added
3254 *					after the list has been fired right away with the latest "memorized"
3255 *					values (like a Deferred)
3256 *
3257 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3258 *
3259 *	stopOnFalse:	interrupt callings when a callback returns false
3260 *
3261 */
3262jQuery.Callbacks = function( options ) {
3263
3264	// Convert options from String-formatted to Object-formatted if needed
3265	// (we check in cache first)
3266	options = typeof options === "string" ?
3267		createOptions( options ) :
3268		jQuery.extend( {}, options );
3269
3270	var // Flag to know if list is currently firing
3271		firing,
3272
3273		// Last fire value for non-forgettable lists
3274		memory,
3275
3276		// Flag to know if list was already fired
3277		fired,
3278
3279		// Flag to prevent firing
3280		locked,
3281
3282		// Actual callback list
3283		list = [],
3284
3285		// Queue of execution data for repeatable lists
3286		queue = [],
3287
3288		// Index of currently firing callback (modified by add/remove as needed)
3289		firingIndex = -1,
3290
3291		// Fire callbacks
3292		fire = function() {
3293
3294			// Enforce single-firing
3295			locked = options.once;
3296
3297			// Execute callbacks for all pending executions,
3298			// respecting firingIndex overrides and runtime changes
3299			fired = firing = true;
3300			for ( ; queue.length; firingIndex = -1 ) {
3301				memory = queue.shift();
3302				while ( ++firingIndex < list.length ) {
3303
3304					// Run callback and check for early termination
3305					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3306						options.stopOnFalse ) {
3307
3308						// Jump to end and forget the data so .add doesn't re-fire
3309						firingIndex = list.length;
3310						memory = false;
3311					}
3312				}
3313			}
3314
3315			// Forget the data if we're done with it
3316			if ( !options.memory ) {
3317				memory = false;
3318			}
3319
3320			firing = false;
3321
3322			// Clean up if we're done firing for good
3323			if ( locked ) {
3324
3325				// Keep an empty list if we have data for future add calls
3326				if ( memory ) {
3327					list = [];
3328
3329				// Otherwise, this object is spent
3330				} else {
3331					list = "";
3332				}
3333			}
3334		},
3335
3336		// Actual Callbacks object
3337		self = {
3338
3339			// Add a callback or a collection of callbacks to the list
3340			add: function() {
3341				if ( list ) {
3342
3343					// If we have memory from a past run, we should fire after adding
3344					if ( memory && !firing ) {
3345						firingIndex = list.length - 1;
3346						queue.push( memory );
3347					}
3348
3349					( function add( args ) {
3350						jQuery.each( args, function( _, arg ) {
3351							if ( jQuery.isFunction( arg ) ) {
3352								if ( !options.unique || !self.has( arg ) ) {
3353									list.push( arg );
3354								}
3355							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3356
3357								// Inspect recursively
3358								add( arg );
3359							}
3360						} );
3361					} )( arguments );
3362
3363					if ( memory && !firing ) {
3364						fire();
3365					}
3366				}
3367				return this;
3368			},
3369
3370			// Remove a callback from the list
3371			remove: function() {
3372				jQuery.each( arguments, function( _, arg ) {
3373					var index;
3374					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3375						list.splice( index, 1 );
3376
3377						// Handle firing indexes
3378						if ( index <= firingIndex ) {
3379							firingIndex--;
3380						}
3381					}
3382				} );
3383				return this;
3384			},
3385
3386			// Check if a given callback is in the list.
3387			// If no argument is given, return whether or not list has callbacks attached.
3388			has: function( fn ) {
3389				return fn ?
3390					jQuery.inArray( fn, list ) > -1 :
3391					list.length > 0;
3392			},
3393
3394			// Remove all callbacks from the list
3395			empty: function() {
3396				if ( list ) {
3397					list = [];
3398				}
3399				return this;
3400			},
3401
3402			// Disable .fire and .add
3403			// Abort any current/pending executions
3404			// Clear all callbacks and values
3405			disable: function() {
3406				locked = queue = [];
3407				list = memory = "";
3408				return this;
3409			},
3410			disabled: function() {
3411				return !list;
3412			},
3413
3414			// Disable .fire
3415			// Also disable .add unless we have memory (since it would have no effect)
3416			// Abort any pending executions
3417			lock: function() {
3418				locked = queue = [];
3419				if ( !memory && !firing ) {
3420					list = memory = "";
3421				}
3422				return this;
3423			},
3424			locked: function() {
3425				return !!locked;
3426			},
3427
3428			// Call all callbacks with the given context and arguments
3429			fireWith: function( context, args ) {
3430				if ( !locked ) {
3431					args = args || [];
3432					args = [ context, args.slice ? args.slice() : args ];
3433					queue.push( args );
3434					if ( !firing ) {
3435						fire();
3436					}
3437				}
3438				return this;
3439			},
3440
3441			// Call all the callbacks with the given arguments
3442			fire: function() {
3443				self.fireWith( this, arguments );
3444				return this;
3445			},
3446
3447			// To know if the callbacks have already been called at least once
3448			fired: function() {
3449				return !!fired;
3450			}
3451		};
3452
3453	return self;
3454};
3455
3456
3457function Identity( v ) {
3458	return v;
3459}
3460function Thrower( ex ) {
3461	throw ex;
3462}
3463
3464function adoptValue( value, resolve, reject ) {
3465	var method;
3466
3467	try {
3468
3469		// Check for promise aspect first to privilege synchronous behavior
3470		if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
3471			method.call( value ).done( resolve ).fail( reject );
3472
3473		// Other thenables
3474		} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
3475			method.call( value, resolve, reject );
3476
3477		// Other non-thenables
3478		} else {
3479
3480			// Support: Android 4.0 only
3481			// Strict mode functions invoked without .call/.apply get global-object context
3482			resolve.call( undefined, value );
3483		}
3484
3485	// For Promises/A+, convert exceptions into rejections
3486	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3487	// Deferred#then to conditionally suppress rejection.
3488	} catch (
vendor: 10,289 bytes, lines 3488-3852
3488 value ) {
3489
3490		// Support: Android 4.0 only
3491		// Strict mode functions invoked without .call/.apply get global-object context
3492		reject.call( undefined, value );
3493	}
3494}
3495
3496jQuery.extend( {
3497
3498	Deferred: function( func ) {
3499		var tuples = [
3500
3501				// action, add listener, callbacks,
3502				// ... .then handlers, argument index, [final state]
3503				[ "notify", "progress", jQuery.Callbacks( "memory" ),
3504					jQuery.Callbacks( "memory" ), 2 ],
3505				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
3506					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3507				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
3508					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3509			],
3510			state = "pending",
3511			promise = {
3512				state: function() {
3513					return state;
3514				},
3515				always: function() {
3516					deferred.done( arguments ).fail( arguments );
3517					return this;
3518				},
3519				"catch": function( fn ) {
3520					return promise.then( null, fn );
3521				},
3522
3523				// Keep pipe for back-compat
3524				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3525					var fns = arguments;
3526
3527					return jQuery.Deferred( function( newDefer ) {
3528						jQuery.each( tuples, function( i, tuple ) {
3529
3530							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
3531							var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3532
3533							// deferred.progress(function() { bind to newDefer or newDefer.notify })
3534							// deferred.done(function() { bind to newDefer or newDefer.resolve })
3535							// deferred.fail(function() { bind to newDefer or newDefer.reject })
3536							deferred[ tuple[ 1 ] ]( function() {
3537								var returned = fn && fn.apply( this, arguments );
3538								if ( returned && jQuery.isFunction( returned.promise ) ) {
3539									returned.promise()
3540										.progress( newDefer.notify )
3541										.done( newDefer.resolve )
3542										.fail( newDefer.reject );
3543								} else {
3544									newDefer[ tuple[ 0 ] + "With" ](
3545										this,
3546										fn ? [ returned ] : arguments
3547									);
3548								}
3549							} );
3550						} );
3551						fns = null;
3552					} ).promise();
3553				},
3554				then: function( onFulfilled, onRejected, onProgress ) {
3555					var maxDepth = 0;
3556					function resolve( depth, deferred, handler, special ) {
3557						return function() {
3558							var that = this,
3559								args = arguments,
3560								mightThrow = function() {
3561									var returned, then;
3562
3563									// Support: Promises/A+ section 2.3.3.3.3
3564									// https://promisesaplus.com/#point-59
3565									// Ignore double-resolution attempts
3566									if ( depth < maxDepth ) {
3567										return;
3568									}
3569
3570									returned = handler.apply( that, args );
3571
3572									// Support: Promises/A+ section 2.3.1
3573									// https://promisesaplus.com/#point-48
3574									if ( returned === deferred.promise() ) {
3575										throw new TypeError( "Thenable self-resolution" );
3576									}
3577
3578									// Support: Promises/A+ sections 2.3.3.1, 3.5
3579									// https://promisesaplus.com/#point-54
3580									// https://promisesaplus.com/#point-75
3581									// Retrieve `then` only once
3582									then = returned &&
3583
3584										// Support: Promises/A+ section 2.3.4
3585										// https://promisesaplus.com/#point-64
3586										// Only check objects and functions for thenability
3587										( typeof returned === "object" ||
3588											typeof returned === "function" ) &&
3589										returned.then;
3590
3591									// Handle a returned thenable
3592									if ( jQuery.isFunction( then ) ) {
3593
3594										// Special processors (notify) just wait for resolution
3595										if ( special ) {
3596											then.call(
3597												returned,
3598												resolve( maxDepth, deferred, Identity, special ),
3599												resolve( maxDepth, deferred, Thrower, special )
3600											);
3601
3602										// Normal processors (resolve) also hook into progress
3603										} else {
3604
3605											// ...and disregard older resolution values
3606											maxDepth++;
3607
3608											then.call(
3609												returned,
3610												resolve( maxDepth, deferred, Identity, special ),
3611												resolve( maxDepth, deferred, Thrower, special ),
3612												resolve( maxDepth, deferred, Identity,
3613													deferred.notifyWith )
3614											);
3615										}
3616
3617									// Handle all other returned values
3618									} else {
3619
3620										// Only substitute handlers pass on context
3621										// and multiple values (non-spec behavior)
3622										if ( handler !== Identity ) {
3623											that = undefined;
3624											args = [ returned ];
3625										}
3626
3627										// Process the value(s)
3628										// Default process is resolve
3629										( special || deferred.resolveWith )( that, args );
3630									}
3631								},
3632
3633								// Only normal processors (resolve) catch and reject exceptions
3634								process = special ?
3635									mightThrow :
3636									function() {
3637										try {
3638											mightThrow();
3639										} catch ( e ) {
3640
3641											if ( jQuery.Deferred.exceptionHook ) {
3642												jQuery.Deferred.exceptionHook( e,
3643													process.stackTrace );
3644											}
3645
3646											// Support: Promises/A+ section 2.3.3.3.4.1
3647											// https://promisesaplus.com/#point-61
3648											// Ignore post-resolution exceptions
3649											if ( depth + 1 >= maxDepth ) {
3650
3651												// Only substitute handlers pass on context
3652												// and multiple values (non-spec behavior)
3653												if ( handler !== Thrower ) {
3654													that = undefined;
3655													args = [ e ];
3656												}
3657
3658												deferred.rejectWith( that, args );
3659											}
3660										}
3661									};
3662
3663							// Support: Promises/A+ section 2.3.3.3.1
3664							// https://promisesaplus.com/#point-57
3665							// Re-resolve promises immediately to dodge false rejection from
3666							// subsequent errors
3667							if ( depth ) {
3668								process();
3669							} else {
3670
3671								// Call an optional hook to record the stack, in case of exception
3672								// since it's otherwise lost when execution goes async
3673								if ( jQuery.Deferred.getStackHook ) {
3674									process.stackTrace = jQuery.Deferred.getStackHook();
3675								}
3676								window.setTimeout( process );
3677							}
3678						};
3679					}
3680
3681					return jQuery.Deferred( function( newDefer ) {
3682
3683						// progress_handlers.add( ... )
3684						tuples[ 0 ][ 3 ].add(
3685							resolve(
3686								0,
3687								newDefer,
3688								jQuery.isFunction( onProgress ) ?
3689									onProgress :
3690									Identity,
3691								newDefer.notifyWith
3692							)
3693						);
3694
3695						// fulfilled_handlers.add( ... )
3696						tuples[ 1 ][ 3 ].add(
3697							resolve(
3698								0,
3699								newDefer,
3700								jQuery.isFunction( onFulfilled ) ?
3701									onFulfilled :
3702									Identity
3703							)
3704						);
3705
3706						// rejected_handlers.add( ... )
3707						tuples[ 2 ][ 3 ].add(
3708							resolve(
3709								0,
3710								newDefer,
3711								jQuery.isFunction( onRejected ) ?
3712									onRejected :
3713									Thrower
3714							)
3715						);
3716					} ).promise();
3717				},
3718
3719				// Get a promise for this deferred
3720				// If obj is provided, the promise aspect is added to the object
3721				promise: function( obj ) {
3722					return obj != null ? jQuery.extend( obj, promise ) : promise;
3723				}
3724			},
3725			deferred = {};
3726
3727		// Add list-specific methods
3728		jQuery.each( tuples, function( i, tuple ) {
3729			var list = tuple[ 2 ],
3730				stateString = tuple[ 5 ];
3731
3732			// promise.progress = list.add
3733			// promise.done = list.add
3734			// promise.fail = list.add
3735			promise[ tuple[ 1 ] ] = list.add;
3736
3737			// Handle state
3738			if ( stateString ) {
3739				list.add(
3740					function() {
3741
3742						// state = "resolved" (i.e., fulfilled)
3743						// state = "rejected"
3744						state = stateString;
3745					},
3746
3747					// rejected_callbacks.disable
3748					// fulfilled_callbacks.disable
3749					tuples[ 3 - i ][ 2 ].disable,
3750
3751					// progress_callbacks.lock
3752					tuples[ 0 ][ 2 ].lock
3753				);
3754			}
3755
3756			// progress_handlers.fire
3757			// fulfilled_handlers.fire
3758			// rejected_handlers.fire
3759			list.add( tuple[ 3 ].fire );
3760
3761			// deferred.notify = function() { deferred.notifyWith(...) }
3762			// deferred.resolve = function() { deferred.resolveWith(...) }
3763			// deferred.reject = function() { deferred.rejectWith(...) }
3764			deferred[ tuple[ 0 ] ] = function() {
3765				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
3766				return this;
3767			};
3768
3769			// deferred.notifyWith = list.fireWith
3770			// deferred.resolveWith = list.fireWith
3771			// deferred.rejectWith = list.fireWith
3772			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3773		} );
3774
3775		// Make the deferred a promise
3776		promise.promise( deferred );
3777
3778		// Call given func if any
3779		if ( func ) {
3780			func.call( deferred, deferred );
3781		}
3782
3783		// All done!
3784		return deferred;
3785	},
3786
3787	// Deferred helper
3788	when: function( singleValue ) {
3789		var
3790
3791			// count of uncompleted subordinates
3792			remaining = arguments.length,
3793
3794			// count of unprocessed arguments
3795			i = remaining,
3796
3797			// subordinate fulfillment data
3798			resolveContexts = Array( i ),
3799			resolveValues = slice.call( arguments ),
3800
3801			// the master Deferred
3802			master = jQuery.Deferred(),
3803
3804			// subordinate callback factory
3805			updateFunc = function( i ) {
3806				return function( value ) {
3807					resolveContexts[ i ] = this;
3808					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3809					if ( !( --remaining ) ) {
3810						master.resolveWith( resolveContexts, resolveValues );
3811					}
3812				};
3813			};
3814
3815		// Single- and empty arguments are adopted like Promise.resolve
3816		if ( remaining <= 1 ) {
3817			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );
3818
3819			// Use .then() to unwrap secondary thenables (cf. gh-3000)
3820			if ( master.state() === "pending" ||
3821				jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
3822
3823				return master.then();
3824			}
3825		}
3826
3827		// Multiple arguments are aggregated like Promise.all array elements
3828		while ( i-- ) {
3829			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
3830		}
3831
3832		return master.promise();
3833	}
3834} );
3835
3836
3837// These usually indicate a programmer mistake during development,
3838// warn about them ASAP rather than swallowing them by default.
3839var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3840
3841jQuery.Deferred.exceptionHook = function( error, stack ) {
3842
3843	// Support: IE 8 - 9 only
3844	// Console exists when dev tools are open, which can happen at any time
3845	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
3846		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
3847	}
3848};
3849
3850
3851
3852
vendor: 1,236 bytes, lines 3853-3913
3853jQuery.readyException = function( error ) {
3854	window.setTimeout( function() {
3855		throw error;
3856	} );
3857};
3858
3859
3860
3861
3862// The deferred used on DOM ready
3863var readyList = jQuery.Deferred();
3864
3865jQuery.fn.ready = function( fn ) {
3866
3867	readyList
3868		.then( fn )
3869
3870		// Wrap jQuery.readyException in a function so that the lookup
3871		// happens at the time of error handling instead of callback
3872		// registration.
3873		.catch( function( error ) {
3874			jQuery.readyException( error );
3875		} );
3876
3877	return this;
3878};
3879
3880jQuery.extend( {
3881
3882	// Is the DOM ready to be used? Set to true once it occurs.
3883	isReady: false,
3884
3885	// A counter to track how many items to wait for before
3886	// the ready event fires. See #6781
3887	readyWait: 1,
3888
3889	// Hold (or release) the ready event
3890	holdReady: function( hold ) {
3891		if ( hold ) {
3892			jQuery.readyWait++;
3893		} else {
3894			jQuery.ready( true );
3895		}
3896	},
3897
3898	// Handle when the DOM is ready
3899	ready: function( wait ) {
3900
3901		// Abort if there are pending holds or we're already ready
3902		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3903			return;
3904		}
3905
3906		// Remember that the DOM is ready
3907		jQuery.isReady = true;
3908
3909		// If a normal DOM Ready event fired, decrement, and wait if need be
3910		if ( wait !== true && --jQuery.readyWait > 0 ) {
3911			return;
3912		}
3913
vendor: 4,098 bytes, lines 3914-4095
3914		// If there are functions bound, to execute
3915		readyList.resolveWith( document, [ jQuery ] );
3916	}
3917} );
3918
3919jQuery.ready.then = readyList.then;
3920
3921// The ready event handler and self cleanup method
3922function completed() {
3923	document.removeEventListener( "DOMContentLoaded", completed );
3924	window.removeEventListener( "load", completed );
3925	jQuery.ready();
3926}
3927
3928// Catch cases where $(document).ready() is called
3929// after the browser event has already occurred.
3930// Support: IE <=9 - 10 only
3931// Older IE sometimes signals "interactive" too soon
3932if ( document.readyState === "complete" ||
3933	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3934
3935	// Handle it asynchronously to allow scripts the opportunity to delay ready
3936	window.setTimeout( jQuery.ready );
3937
3938} else {
3939
3940	// Use the handy event callback
3941	document.addEventListener( "DOMContentLoaded", completed );
3942
3943	// A fallback to window.onload, that will always work
3944	window.addEventListener( "load", completed );
3945}
3946
3947
3948
3949
3950// Multifunctional method to get and set values of a collection
3951// The value/s can optionally be executed if it's a function
3952var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3953	var i = 0,
3954		len = elems.length,
3955		bulk = key == null;
3956
3957	// Sets many values
3958	if ( jQuery.type( key ) === "object" ) {
3959		chainable = true;
3960		for ( i in key ) {
3961			access( elems, fn, i, key[ i ], true, emptyGet, raw );
3962		}
3963
3964	// Sets one value
3965	} else if ( value !== undefined ) {
3966		chainable = true;
3967
3968		if ( !jQuery.isFunction( value ) ) {
3969			raw = true;
3970		}
3971
3972		if ( bulk ) {
3973
3974			// Bulk operations run against the entire set
3975			if ( raw ) {
3976				fn.call( elems, value );
3977				fn = null;
3978
3979			// ...except when executing function values
3980			} else {
3981				bulk = fn;
3982				fn = function( elem, key, value ) {
3983					return bulk.call( jQuery( elem ), value );
3984				};
3985			}
3986		}
3987
3988		if ( fn ) {
3989			for ( ; i < len; i++ ) {
3990				fn(
3991					elems[ i ], key, raw ?
3992					value :
3993					value.call( elems[ i ], i, fn( elems[ i ], key ) )
3994				);
3995			}
3996		}
3997	}
3998
3999	if ( chainable ) {
4000		return elems;
4001	}
4002
4003	// Gets
4004	if ( bulk ) {
4005		return fn.call( elems );
4006	}
4007
4008	return len ? fn( elems[ 0 ], key ) : emptyGet;
4009};
4010var acceptData = function( owner ) {
4011
4012	// Accepts only:
4013	//  - Node
4014	//    - Node.ELEMENT_NODE
4015	//    - Node.DOCUMENT_NODE
4016	//  - Object
4017	//    - Any
4018	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4019};
4020
4021
4022
4023
4024function Data() {
4025	this.expando = jQuery.expando + Data.uid++;
4026}
4027
4028Data.uid = 1;
4029
4030Data.prototype = {
4031
4032	cache: function( owner ) {
4033
4034		// Check if the owner object already has a cache
4035		var value = owner[ this.expando ];
4036
4037		// If not, create one
4038		if ( !value ) {
4039			value = {};
4040
4041			// We can accept data for non-element nodes in modern browsers,
4042			// but we should not, see #8335.
4043			// Always return an empty object.
4044			if ( acceptData( owner ) ) {
4045
4046				// If it is a node unlikely to be stringify-ed or looped over
4047				// use plain assignment
4048				if ( owner.nodeType ) {
4049					owner[ this.expando ] = value;
4050
4051				// Otherwise secure it in a non-enumerable property
4052				// configurable must be true to allow the property to be
4053				// deleted when data is removed
4054				} else {
4055					Object.defineProperty( owner, this.expando, {
4056						value: value,
4057						configurable: true
4058					} );
4059				}
4060			}
4061		}
4062
4063		return value;
4064	},
4065	set: function( owner, data, value ) {
4066		var prop,
4067			cache = this.cache( owner );
4068
4069		// Handle: [ owner, key, value ] args
4070		// Always use camelCase key (gh-2257)
4071		if ( typeof data === "string" ) {
4072			cache[ jQuery.camelCase( data ) ] = value;
4073
4074		// Handle: [ owner, { properties } ] args
4075		} else {
4076
4077			// Copy the properties one-by-one to the cache object
4078			for ( prop in data ) {
4079				cache[ jQuery.camelCase( prop ) ] = data[ prop ];
4080			}
4081		}
4082		return cache;
4083	},
4084	get: function( owner, key ) {
4085		return key === undefined ?
4086			this.cache( owner ) :
4087
4088			// Always use camelCase key (gh-2257)
4089			owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
4090	},
4091	access: function( owner, key, value ) {
4092
4093		// In cases where either:
4094		//
4095		//   1. No key was specified
vendor: 3,472 bytes, lines 4096-4229
4096		//   2. A string key was specified, but no value provided
4097		//
4098		// Take the "read" path and allow the get method to determine
4099		// which value to return, respectively either:
4100		//
4101		//   1. The entire cache object
4102		//   2. The data stored at the key
4103		//
4104		if ( key === undefined ||
4105				( ( key && typeof key === "string" ) && value === undefined ) ) {
4106
4107			return this.get( owner, key );
4108		}
4109
4110		// When the key is not a string, or both a key and value
4111		// are specified, set or extend (existing objects) with either:
4112		//
4113		//   1. An object of properties
4114		//   2. A key and value
4115		//
4116		this.set( owner, key, value );
4117
4118		// Since the "set" path can have two possible entry points
4119		// return the expected data based on which path was taken[*]
4120		return value !== undefined ? value : key;
4121	},
4122	remove: function( owner, key ) {
4123		var i,
4124			cache = owner[ this.expando ];
4125
4126		if ( cache === undefined ) {
4127			return;
4128		}
4129
4130		if ( key !== undefined ) {
4131
4132			// Support array or space separated string of keys
4133			if ( jQuery.isArray( key ) ) {
4134
4135				// If key is an array of keys...
4136				// We always set camelCase keys, so remove that.
4137				key = key.map( jQuery.camelCase );
4138			} else {
4139				key = jQuery.camelCase( key );
4140
4141				// If a key with the spaces exists, use it.
4142				// Otherwise, create an array by matching non-whitespace
4143				key = key in cache ?
4144					[ key ] :
4145					( key.match( rnothtmlwhite ) || [] );
4146			}
4147
4148			i = key.length;
4149
4150			while ( i-- ) {
4151				delete cache[ key[ i ] ];
4152			}
4153		}
4154
4155		// Remove the expando if there's no more data
4156		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4157
4158			// Support: Chrome <=35 - 45
4159			// Webkit & Blink performance suffers when deleting properties
4160			// from DOM nodes, so set to undefined instead
4161			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4162			if ( owner.nodeType ) {
4163				owner[ this.expando ] = undefined;
4164			} else {
4165				delete owner[ this.expando ];
4166			}
4167		}
4168	},
4169	hasData: function( owner ) {
4170		var cache = owner[ this.expando ];
4171		return cache !== undefined && !jQuery.isEmptyObject( cache );
4172	}
4173};
4174var dataPriv = new Data();
4175
4176var dataUser = new Data();
4177
4178
4179
4180//	Implementation Summary
4181//
4182//	1. Enforce API surface and semantic compatibility with 1.9.x branch
4183//	2. Improve the module's maintainability by reducing the storage
4184//		paths to a single mechanism.
4185//	3. Use the same single mechanism to support "private" and "user" data.
4186//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4187//	5. Avoid exposing implementation details on user objects (eg. expando properties)
4188//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
4189
4190var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4191	rmultiDash = /[A-Z]/g;
4192
4193function getData( data ) {
4194	if ( data === "true" ) {
4195		return true;
4196	}
4197
4198	if ( data === "false" ) {
4199		return false;
4200	}
4201
4202	if ( data === "null" ) {
4203		return null;
4204	}
4205
4206	// Only convert to a number if it doesn't change the string
4207	if ( data === +data + "" ) {
4208		return +data;
4209	}
4210
4211	if ( rbrace.test( data ) ) {
4212		return JSON.parse( data );
4213	}
4214
4215	return data;
4216}
4217
4218function dataAttr( elem, key, data ) {
4219	var name;
4220
4221	// If nothing was found internally, try to fetch any
4222	// data from the HTML5 data-* attribute
4223	if ( data === undefined && elem.nodeType === 1 ) {
4224		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4225		data = elem.getAttribute( name );
4226
4227		if ( typeof data === "string" ) {
4228			try {
4229				data = getData( data )
vendor: 7,075 bytes, lines 4229-4536
4229;
4230			} catch ( e ) {}
4231
4232			// Make sure we set the data so it isn't changed later
4233			dataUser.set( elem, key, data );
4234		} else {
4235			data = undefined;
4236		}
4237	}
4238	return data;
4239}
4240
4241jQuery.extend( {
4242	hasData: function( elem ) {
4243		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4244	},
4245
4246	data: function( elem, name, data ) {
4247		return dataUser.access( elem, name, data );
4248	},
4249
4250	removeData: function( elem, name ) {
4251		dataUser.remove( elem, name );
4252	},
4253
4254	// TODO: Now that all calls to _data and _removeData have been replaced
4255	// with direct calls to dataPriv methods, these can be deprecated.
4256	_data: function( elem, name, data ) {
4257		return dataPriv.access( elem, name, data );
4258	},
4259
4260	_removeData: function( elem, name ) {
4261		dataPriv.remove( elem, name );
4262	}
4263} );
4264
4265jQuery.fn.extend( {
4266	data: function( key, value ) {
4267		var i, name, data,
4268			elem = this[ 0 ],
4269			attrs = elem && elem.attributes;
4270
4271		// Gets all values
4272		if ( key === undefined ) {
4273			if ( this.length ) {
4274				data = dataUser.get( elem );
4275
4276				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4277					i = attrs.length;
4278					while ( i-- ) {
4279
4280						// Support: IE 11 only
4281						// The attrs elements can be null (#14894)
4282						if ( attrs[ i ] ) {
4283							name = attrs[ i ].name;
4284							if ( name.indexOf( "data-" ) === 0 ) {
4285								name = jQuery.camelCase( name.slice( 5 ) );
4286								dataAttr( elem, name, data[ name ] );
4287							}
4288						}
4289					}
4290					dataPriv.set( elem, "hasDataAttrs", true );
4291				}
4292			}
4293
4294			return data;
4295		}
4296
4297		// Sets multiple values
4298		if ( typeof key === "object" ) {
4299			return this.each( function() {
4300				dataUser.set( this, key );
4301			} );
4302		}
4303
4304		return access( this, function( value ) {
4305			var data;
4306
4307			// The calling jQuery object (element matches) is not empty
4308			// (and therefore has an element appears at this[ 0 ]) and the
4309			// `value` parameter was not undefined. An empty jQuery object
4310			// will result in `undefined` for elem = this[ 0 ] which will
4311			// throw an exception if an attempt to read a data cache is made.
4312			if ( elem && value === undefined ) {
4313
4314				// Attempt to get data from the cache
4315				// The key will always be camelCased in Data
4316				data = dataUser.get( elem, key );
4317				if ( data !== undefined ) {
4318					return data;
4319				}
4320
4321				// Attempt to "discover" the data in
4322				// HTML5 custom data-* attrs
4323				data = dataAttr( elem, key );
4324				if ( data !== undefined ) {
4325					return data;
4326				}
4327
4328				// We tried really hard, but the data doesn't exist.
4329				return;
4330			}
4331
4332			// Set the data...
4333			this.each( function() {
4334
4335				// We always store the camelCased key
4336				dataUser.set( this, key, value );
4337			} );
4338		}, null, value, arguments.length > 1, null, true );
4339	},
4340
4341	removeData: function( key ) {
4342		return this.each( function() {
4343			dataUser.remove( this, key );
4344		} );
4345	}
4346} );
4347
4348
4349jQuery.extend( {
4350	queue: function( elem, type, data ) {
4351		var queue;
4352
4353		if ( elem ) {
4354			type = ( type || "fx" ) + "queue";
4355			queue = dataPriv.get( elem, type );
4356
4357			// Speed up dequeue by getting out quickly if this is just a lookup
4358			if ( data ) {
4359				if ( !queue || jQuery.isArray( data ) ) {
4360					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4361				} else {
4362					queue.push( data );
4363				}
4364			}
4365			return queue || [];
4366		}
4367	},
4368
4369	dequeue: function( elem, type ) {
4370		type = type || "fx";
4371
4372		var queue = jQuery.queue( elem, type ),
4373			startLength = queue.length,
4374			fn = queue.shift(),
4375			hooks = jQuery._queueHooks( elem, type ),
4376			next = function() {
4377				jQuery.dequeue( elem, type );
4378			};
4379
4380		// If the fx queue is dequeued, always remove the progress sentinel
4381		if ( fn === "inprogress" ) {
4382			fn = queue.shift();
4383			startLength--;
4384		}
4385
4386		if ( fn ) {
4387
4388			// Add a progress sentinel to prevent the fx queue from being
4389			// automatically dequeued
4390			if ( type === "fx" ) {
4391				queue.unshift( "inprogress" );
4392			}
4393
4394			// Clear up the last queue stop function
4395			delete hooks.stop;
4396			fn.call( elem, next, hooks );
4397		}
4398
4399		if ( !startLength && hooks ) {
4400			hooks.empty.fire();
4401		}
4402	},
4403
4404	// Not public - generate a queueHooks object, or return the current one
4405	_queueHooks: function( elem, type ) {
4406		var key = type + "queueHooks";
4407		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4408			empty: jQuery.Callbacks( "once memory" ).add( function() {
4409				dataPriv.remove( elem, [ type + "queue", key ] );
4410			} )
4411		} );
4412	}
4413} );
4414
4415jQuery.fn.extend( {
4416	queue: function( type, data ) {
4417		var setter = 2;
4418
4419		if ( typeof type !== "string" ) {
4420			data = type;
4421			type = "fx";
4422			setter--;
4423		}
4424
4425		if ( arguments.length < setter ) {
4426			return jQuery.queue( this[ 0 ], type );
4427		}
4428
4429		return data === undefined ?
4430			this :
4431			this.each( function() {
4432				var queue = jQuery.queue( this, type, data );
4433
4434				// Ensure a hooks for this queue
4435				jQuery._queueHooks( this, type );
4436
4437				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4438					jQuery.dequeue( this, type );
4439				}
4440			} );
4441	},
4442	dequeue: function( type ) {
4443		return this.each( function() {
4444			jQuery.dequeue( this, type );
4445		} );
4446	},
4447	clearQueue: function( type ) {
4448		return this.queue( type || "fx", [] );
4449	},
4450
4451	// Get a promise resolved when queues of a certain type
4452	// are emptied (fx is the type by default)
4453	promise: function( type, obj ) {
4454		var tmp,
4455			count = 1,
4456			defer = jQuery.Deferred(),
4457			elements = this,
4458			i = this.length,
4459			resolve = function() {
4460				if ( !( --count ) ) {
4461					defer.resolveWith( elements, [ elements ] );
4462				}
4463			};
4464
4465		if ( typeof type !== "string" ) {
4466			obj = type;
4467			type = undefined;
4468		}
4469		type = type || "fx";
4470
4471		while ( i-- ) {
4472			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4473			if ( tmp && tmp.empty ) {
4474				count++;
4475				tmp.empty.add( resolve );
4476			}
4477		}
4478		resolve();
4479		return defer.promise( obj );
4480	}
4481} );
4482var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4483
4484var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4485
4486
4487var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4488
4489var isHiddenWithinTree = function( elem, el ) {
4490
4491		// isHiddenWithinTree might be called from jQuery#filter function;
4492		// in that case, element will be second argument
4493		elem = el || elem;
4494
4495		// Inline style trumps all
4496		return elem.style.display === "none" ||
4497			elem.style.display === "" &&
4498
4499			// Otherwise, check computed style
4500			// Support: Firefox <=43 - 45
4501			// Disconnected elements can have computed display: none, so first confirm that elem is
4502			// in the document.
4503			jQuery.contains( elem.ownerDocument, elem ) &&
4504
4505			jQuery.css( elem, "display" ) === "none";
4506	};
4507
4508var swap = function( elem, options, callback, args ) {
4509	var ret, name,
4510		old = {};
4511
4512	// Remember the old values, and insert the new ones
4513	for ( name in options ) {
4514		old[ name ] = elem.style[ name ];
4515		elem.style[ name ] = options[ name ];
4516	}
4517
4518	ret = callback.apply( elem, args || [] );
4519
4520	// Revert the old values
4521	for ( name in options ) {
4522		elem.style[ name ] = old[ name ];
4523	}
4524
4525	return ret;
4526};
4527
4528
4529
4530
4531function adjustCSS( elem, prop, valueParts, tween ) {
4532	var adjusted,
4533		scale = 1,
4534		maxIterations = 20,
4535		currentValue = tween ?
4536			function() {
vendor: 1,837 bytes, lines 4536-4602
4536
4537				return tween.cur();
4538			} :
4539			function() {
4540				return jQuery.css( elem, prop, "" );
4541			},
4542		initial = currentValue(),
4543		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4544
4545		// Starting value computation is required for potential unit mismatches
4546		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4547			rcssNum.exec( jQuery.css( elem, prop ) );
4548
4549	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4550
4551		// Trust units reported by jQuery.css
4552		unit = unit || initialInUnit[ 3 ];
4553
4554		// Make sure we update the tween properties later on
4555		valueParts = valueParts || [];
4556
4557		// Iteratively approximate from a nonzero starting point
4558		initialInUnit = +initial || 1;
4559
4560		do {
4561
4562			// If previous iteration zeroed out, double until we get *something*.
4563			// Use string for doubling so we don't accidentally see scale as unchanged below
4564			scale = scale || ".5";
4565
4566			// Adjust and apply
4567			initialInUnit = initialInUnit / scale;
4568			jQuery.style( elem, prop, initialInUnit + unit );
4569
4570		// Update scale, tolerating zero or NaN from tween.cur()
4571		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4572		} while (
4573			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4574		);
4575	}
4576
4577	if ( valueParts ) {
4578		initialInUnit = +initialInUnit || +initial || 0;
4579
4580		// Apply relative offset (+=/-=) if specified
4581		adjusted = valueParts[ 1 ] ?
4582			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4583			+valueParts[ 2 ];
4584		if ( tween ) {
4585			tween.unit = unit;
4586			tween.start = initialInUnit;
4587			tween.end = adjusted;
4588		}
4589	}
4590	return adjusted;
4591}
4592
4593
4594var defaultDisplayMap = {};
4595
4596function getDefaultDisplay( elem ) {
4597	var temp,
4598		doc = elem.ownerDocument,
4599		nodeName = elem.nodeName,
4600		display = defaultDisplayMap[ nodeName ];
4601
4602	if ( display ) {
vendor: 4,008 bytes, lines 4603-4774
4603		return display;
4604	}
4605
4606	temp = doc.body.appendChild( doc.createElement( nodeName ) );
4607	display = jQuery.css( temp, "display" );
4608
4609	temp.parentNode.removeChild( temp );
4610
4611	if ( display === "none" ) {
4612		display = "block";
4613	}
4614	defaultDisplayMap[ nodeName ] = display;
4615
4616	return display;
4617}
4618
4619function showHide( elements, show ) {
4620	var display, elem,
4621		values = [],
4622		index = 0,
4623		length = elements.length;
4624
4625	// Determine new display value for elements that need to change
4626	for ( ; index < length; index++ ) {
4627		elem = elements[ index ];
4628		if ( !elem.style ) {
4629			continue;
4630		}
4631
4632		display = elem.style.display;
4633		if ( show ) {
4634
4635			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4636			// check is required in this first loop unless we have a nonempty display value (either
4637			// inline or about-to-be-restored)
4638			if ( display === "none" ) {
4639				values[ index ] = dataPriv.get( elem, "display" ) || null;
4640				if ( !values[ index ] ) {
4641					elem.style.display = "";
4642				}
4643			}
4644			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4645				values[ index ] = getDefaultDisplay( elem );
4646			}
4647		} else {
4648			if ( display !== "none" ) {
4649				values[ index ] = "none";
4650
4651				// Remember what we're overwriting
4652				dataPriv.set( elem, "display", display );
4653			}
4654		}
4655	}
4656
4657	// Set the display of the elements in a second loop to avoid constant reflow
4658	for ( index = 0; index < length; index++ ) {
4659		if ( values[ index ] != null ) {
4660			elements[ index ].style.display = values[ index ];
4661		}
4662	}
4663
4664	return elements;
4665}
4666
4667jQuery.fn.extend( {
4668	show: function() {
4669		return showHide( this, true );
4670	},
4671	hide: function() {
4672		return showHide( this );
4673	},
4674	toggle: function( state ) {
4675		if ( typeof state === "boolean" ) {
4676			return state ? this.show() : this.hide();
4677		}
4678
4679		return this.each( function() {
4680			if ( isHiddenWithinTree( this ) ) {
4681				jQuery( this ).show();
4682			} else {
4683				jQuery( this ).hide();
4684			}
4685		} );
4686	}
4687} );
4688var rcheckableType = ( /^(?:checkbox|radio)$/i );
4689
4690var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
4691
4692var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4693
4694
4695
4696// We have to close these tags to support XHTML (#13200)
4697var wrapMap = {
4698
4699	// Support: IE <=9 only
4700	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4701
4702	// XHTML parsers do not magically insert elements in the
4703	// same way that tag soup parsers do. So we cannot shorten
4704	// this by omitting <tbody> or other required elements.
4705	thead: [ 1, "<table>", "</table>" ],
4706	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4707	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4708	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4709
4710	_default: [ 0, "", "" ]
4711};
4712
4713// Support: IE <=9 only
4714wrapMap.optgroup = wrapMap.option;
4715
4716wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4717wrapMap.th = wrapMap.td;
4718
4719
4720function getAll( context, tag ) {
4721
4722	// Support: IE <=9 - 11 only
4723	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
4724	var ret;
4725
4726	if ( typeof context.getElementsByTagName !== "undefined" ) {
4727		ret = context.getElementsByTagName( tag || "*" );
4728
4729	} else if ( typeof context.querySelectorAll !== "undefined" ) {
4730		ret = context.querySelectorAll( tag || "*" );
4731
4732	} else {
4733		ret = [];
4734	}
4735
4736	if ( tag === undefined || tag && jQuery.nodeName( context, tag ) ) {
4737		return jQuery.merge( [ context ], ret );
4738	}
4739
4740	return ret;
4741}
4742
4743
4744// Mark scripts as having already been evaluated
4745function setGlobalEval( elems, refElements ) {
4746	var i = 0,
4747		l = elems.length;
4748
4749	for ( ; i < l; i++ ) {
4750		dataPriv.set(
4751			elems[ i ],
4752			"globalEval",
4753			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
4754		);
4755	}
4756}
4757
4758
4759var rhtml = /<|&#?\w+;/;
4760
4761function buildFragment( elems, context, scripts, selection, ignored ) {
4762	var elem, tmp, tag, wrap, contains, j,
4763		fragment = context.createDocumentFragment(),
4764		nodes = [],
4765		i = 0,
4766		l = elems.length;
4767
4768	for ( ; i < l; i++ ) {
4769		elem = elems[ i ];
4770
4771		if ( elem || elem === 0 ) {
4772
4773			// Add nodes directly
4774			if ( jQuery.t
vendor: 14,415 bytes, lines 4774-5284
4774ype( elem ) === "object" ) {
4775
4776				// Support: Android <=4.0 only, PhantomJS 1 only
4777				// push.apply(_, arraylike) throws on ancient WebKit
4778				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4779
4780			// Convert non-html into a text node
4781			} else if ( !rhtml.test( elem ) ) {
4782				nodes.push( context.createTextNode( elem ) );
4783
4784			// Convert html into DOM nodes
4785			} else {
4786				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4787
4788				// Deserialize a standard representation
4789				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4790				wrap = wrapMap[ tag ] || wrapMap._default;
4791				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4792
4793				// Descend through wrappers to the right content
4794				j = wrap[ 0 ];
4795				while ( j-- ) {
4796					tmp = tmp.lastChild;
4797				}
4798
4799				// Support: Android <=4.0 only, PhantomJS 1 only
4800				// push.apply(_, arraylike) throws on ancient WebKit
4801				jQuery.merge( nodes, tmp.childNodes );
4802
4803				// Remember the top-level container
4804				tmp = fragment.firstChild;
4805
4806				// Ensure the created nodes are orphaned (#12392)
4807				tmp.textContent = "";
4808			}
4809		}
4810	}
4811
4812	// Remove wrapper from fragment
4813	fragment.textContent = "";
4814
4815	i = 0;
4816	while ( ( elem = nodes[ i++ ] ) ) {
4817
4818		// Skip elements already in the context collection (trac-4087)
4819		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4820			if ( ignored ) {
4821				ignored.push( elem );
4822			}
4823			continue;
4824		}
4825
4826		contains = jQuery.contains( elem.ownerDocument, elem );
4827
4828		// Append to fragment
4829		tmp = getAll( fragment.appendChild( elem ), "script" );
4830
4831		// Preserve script evaluation history
4832		if ( contains ) {
4833			setGlobalEval( tmp );
4834		}
4835
4836		// Capture executables
4837		if ( scripts ) {
4838			j = 0;
4839			while ( ( elem = tmp[ j++ ] ) ) {
4840				if ( rscriptType.test( elem.type || "" ) ) {
4841					scripts.push( elem );
4842				}
4843			}
4844		}
4845	}
4846
4847	return fragment;
4848}
4849
4850
4851( function() {
4852	var fragment = document.createDocumentFragment(),
4853		div = fragment.appendChild( document.createElement( "div" ) ),
4854		input = document.createElement( "input" );
4855
4856	// Support: Android 4.0 - 4.3 only
4857	// Check state lost if the name is set (#11217)
4858	// Support: Windows Web Apps (WWA)
4859	// `name` and `type` must use .setAttribute for WWA (#14901)
4860	input.setAttribute( "type", "radio" );
4861	input.setAttribute( "checked", "checked" );
4862	input.setAttribute( "name", "t" );
4863
4864	div.appendChild( input );
4865
4866	// Support: Android <=4.1 only
4867	// Older WebKit doesn't clone checked state correctly in fragments
4868	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4869
4870	// Support: IE <=11 only
4871	// Make sure textarea (and checkbox) defaultValue is properly cloned
4872	div.innerHTML = "<textarea>x</textarea>";
4873	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4874} )();
4875var documentElement = document.documentElement;
4876
4877
4878
4879var
4880	rkeyEvent = /^key/,
4881	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4882	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4883
4884function returnTrue() {
4885	return true;
4886}
4887
4888function returnFalse() {
4889	return false;
4890}
4891
4892// Support: IE <=9 only
4893// See #13393 for more info
4894function safeActiveElement() {
4895	try {
4896		return document.activeElement;
4897	} catch ( err ) { }
4898}
4899
4900function on( elem, types, selector, data, fn, one ) {
4901	var origFn, type;
4902
4903	// Types can be a map of types/handlers
4904	if ( typeof types === "object" ) {
4905
4906		// ( types-Object, selector, data )
4907		if ( typeof selector !== "string" ) {
4908
4909			// ( types-Object, data )
4910			data = data || selector;
4911			selector = undefined;
4912		}
4913		for ( type in types ) {
4914			on( elem, type, selector, data, types[ type ], one );
4915		}
4916		return elem;
4917	}
4918
4919	if ( data == null && fn == null ) {
4920
4921		// ( types, fn )
4922		fn = selector;
4923		data = selector = undefined;
4924	} else if ( fn == null ) {
4925		if ( typeof selector === "string" ) {
4926
4927			// ( types, selector, fn )
4928			fn = data;
4929			data = undefined;
4930		} else {
4931
4932			// ( types, data, fn )
4933			fn = data;
4934			data = selector;
4935			selector = undefined;
4936		}
4937	}
4938	if ( fn === false ) {
4939		fn = returnFalse;
4940	} else if ( !fn ) {
4941		return elem;
4942	}
4943
4944	if ( one === 1 ) {
4945		origFn = fn;
4946		fn = function( event ) {
4947
4948			// Can use an empty set, since event contains the info
4949			jQuery().off( event );
4950			return origFn.apply( this, arguments );
4951		};
4952
4953		// Use same guid so caller can remove using origFn
4954		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4955	}
4956	return elem.each( function() {
4957		jQuery.event.add( this, types, fn, data, selector );
4958	} );
4959}
4960
4961/*
4962 * Helper functions for managing events -- not part of the public interface.
4963 * Props to Dean Edwards' addEvent library for many of the ideas.
4964 */
4965jQuery.event = {
4966
4967	global: {},
4968
4969	add: function( elem, types, handler, data, selector ) {
4970
4971		var handleObjIn, eventHandle, tmp,
4972			events, t, handleObj,
4973			special, handlers, type, namespaces, origType,
4974			elemData = dataPriv.get( elem );
4975
4976		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4977		if ( !elemData ) {
4978			return;
4979		}
4980
4981		// Caller can pass in an object of custom data in lieu of the handler
4982		if ( handler.handler ) {
4983			handleObjIn = handler;
4984			handler = handleObjIn.handler;
4985			selector = handleObjIn.selector;
4986		}
4987
4988		// Ensure that invalid selectors throw exceptions at attach time
4989		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
4990		if ( selector ) {
4991			jQuery.find.matchesSelector( documentElement, selector );
4992		}
4993
4994		// Make sure that the handler has a unique ID, used to find/remove it later
4995		if ( !handler.guid ) {
4996			handler.guid = jQuery.guid++;
4997		}
4998
4999		// Init the element's event structure and main handler, if this is the first
5000		if ( !( events = elemData.events ) ) {
5001			events = elemData.events = {};
5002		}
5003		if ( !( eventHandle = elemData.handle ) ) {
5004			eventHandle = elemData.handle = function( e ) {
5005
5006				// Discard the second event of a jQuery.event.trigger() and
5007				// when an event is called after a page has unloaded
5008				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5009					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5010			};
5011		}
5012
5013		// Handle multiple events separated by a space
5014		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5015		t = types.length;
5016		while ( t-- ) {
5017			tmp = rtypenamespace.exec( types[ t ] ) || [];
5018			type = origType = tmp[ 1 ];
5019			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5020
5021			// There *must* be a type, no attaching namespace-only handlers
5022			if ( !type ) {
5023				continue;
5024			}
5025
5026			// If event changes its type, use the special event handlers for the changed type
5027			special = jQuery.event.special[ type ] || {};
5028
5029			// If selector defined, determine special event api type, otherwise given type
5030			type = ( selector ? special.delegateType : special.bindType ) || type;
5031
5032			// Update special based on newly reset type
5033			special = jQuery.event.special[ type ] || {};
5034
5035			// handleObj is passed to all event handlers
5036			handleObj = jQuery.extend( {
5037				type: type,
5038				origType: origType,
5039				data: data,
5040				handler: handler,
5041				guid: handler.guid,
5042				selector: selector,
5043				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5044				namespace: namespaces.join( "." )
5045			}, handleObjIn );
5046
5047			// Init the event handler queue if we're the first
5048			if ( !( handlers = events[ type ] ) ) {
5049				handlers = events[ type ] = [];
5050				handlers.delegateCount = 0;
5051
5052				// Only use addEventListener if the special events handler returns false
5053				if ( !special.setup ||
5054					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5055
5056					if ( elem.addEventListener ) {
5057						elem.addEventListener( type, eventHandle );
5058					}
5059				}
5060			}
5061
5062			if ( special.add ) {
5063				special.add.call( elem, handleObj );
5064
5065				if ( !handleObj.handler.guid ) {
5066					handleObj.handler.guid = handler.guid;
5067				}
5068			}
5069
5070			// Add to the element's handler list, delegates in front
5071			if ( selector ) {
5072				handlers.splice( handlers.delegateCount++, 0, handleObj );
5073			} else {
5074				handlers.push( handleObj );
5075			}
5076
5077			// Keep track of which events have ever been used, for event optimization
5078			jQuery.event.global[ type ] = true;
5079		}
5080
5081	},
5082
5083	// Detach an event or set of events from an element
5084	remove: function( elem, types, handler, selector, mappedTypes ) {
5085
5086		var j, origCount, tmp,
5087			events, t, handleObj,
5088			special, handlers, type, namespaces, origType,
5089			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5090
5091		if ( !elemData || !( events = elemData.events ) ) {
5092			return;
5093		}
5094
5095		// Once for each type.namespace in types; type may be omitted
5096		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5097		t = types.length;
5098		while ( t-- ) {
5099			tmp = rtypenamespace.exec( types[ t ] ) || [];
5100			type = origType = tmp[ 1 ];
5101			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5102
5103			// Unbind all events (on this namespace, if provided) for the element
5104			if ( !type ) {
5105				for ( type in events ) {
5106					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5107				}
5108				continue;
5109			}
5110
5111			special = jQuery.event.special[ type ] || {};
5112			type = ( selector ? special.delegateType : special.bindType ) || type;
5113			handlers = events[ type ] || [];
5114			tmp = tmp[ 2 ] &&
5115				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5116
5117			// Remove matching events
5118			origCount = j = handlers.length;
5119			while ( j-- ) {
5120				handleObj = handlers[ j ];
5121
5122				if ( ( mappedTypes || origType === handleObj.origType ) &&
5123					( !handler || handler.guid === handleObj.guid ) &&
5124					( !tmp || tmp.test( handleObj.namespace ) ) &&
5125					( !selector || selector === handleObj.selector ||
5126						selector === "**" && handleObj.selector ) ) {
5127					handlers.splice( j, 1 );
5128
5129					if ( handleObj.selector ) {
5130						handlers.delegateCount--;
5131					}
5132					if ( special.remove ) {
5133						special.remove.call( elem, handleObj );
5134					}
5135				}
5136			}
5137
5138			// Remove generic event handler if we removed something and no more handlers exist
5139			// (avoids potential for endless recursion during removal of special event handlers)
5140			if ( origCount && !handlers.length ) {
5141				if ( !special.teardown ||
5142					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5143
5144					jQuery.removeEvent( elem, type, elemData.handle );
5145				}
5146
5147				delete events[ type ];
5148			}
5149		}
5150
5151		// Remove data and the expando if it's no longer used
5152		if ( jQuery.isEmptyObject( events ) ) {
5153			dataPriv.remove( elem, "handle events" );
5154		}
5155	},
5156
5157	dispatch: function( nativeEvent ) {
5158
5159		// Make a writable jQuery.Event from the native event object
5160		var event = jQuery.event.fix( nativeEvent );
5161
5162		var i, j, ret, matched, handleObj, handlerQueue,
5163			args = new Array( arguments.length ),
5164			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
5165			special = jQuery.event.special[ event.type ] || {};
5166
5167		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5168		args[ 0 ] = event;
5169
5170		for ( i = 1; i < arguments.length; i++ ) {
5171			args[ i ] = arguments[ i ];
5172		}
5173
5174		event.delegateTarget = this;
5175
5176		// Call the preDispatch hook for the mapped type, and let it bail if desired
5177		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5178			return;
5179		}
5180
5181		// Determine handlers
5182		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5183
5184		// Run delegates first; they may want to stop propagation beneath us
5185		i = 0;
5186		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5187			event.currentTarget = matched.elem;
5188
5189			j = 0;
5190			while ( ( handleObj = matched.handlers[ j++ ] ) &&
5191				!event.isImmediatePropagationStopped() ) {
5192
5193				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
5194				// a subset or equal to those in the bound event (both can have no namespace).
5195				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5196
5197					event.handleObj = handleObj;
5198					event.data = handleObj.data;
5199
5200					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5201						handleObj.handler ).apply( matched.elem, args );
5202
5203					if ( ret !== undefined ) {
5204						if ( ( event.result = ret ) === false ) {
5205							event.preventDefault();
5206							event.stopPropagation();
5207						}
5208					}
5209				}
5210			}
5211		}
5212
5213		// Call the postDispatch hook for the mapped type
5214		if ( special.postDispatch ) {
5215			special.postDispatch.call( this, event );
5216		}
5217
5218		return event.result;
5219	},
5220
5221	handlers: function( event, handlers ) {
5222		var i, handleObj, sel, matchedHandlers, matchedSelectors,
5223			handlerQueue = [],
5224			delegateCount = handlers.delegateCount,
5225			cur = event.target;
5226
5227		// Find delegate handlers
5228		if ( delegateCount &&
5229
5230			// Support: IE <=9
5231			// Black-hole SVG <use> instance trees (trac-13180)
5232			cur.nodeType &&
5233
5234			// Support: Firefox <=42
5235			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5236			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5237			// Support: IE 11 only
5238			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5239			!( event.type === "click" && event.button >= 1 ) ) {
5240
5241			for ( ; cur !== this; cur = cur.parentNode || this ) {
5242
5243				// Don't check non-elements (#13208)
5244				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5245				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5246					matchedHandlers = [];
5247					matchedSelectors = {};
5248					for ( i = 0; i < delegateCount; i++ ) {
5249						handleObj = handlers[ i ];
5250
5251						// Don't conflict with Object.prototype properties (#13203)
5252						sel = handleObj.selector + " ";
5253
5254						if ( matchedSelectors[ sel ] === undefined ) {
5255							matchedSelectors[ sel ] = handleObj.needsContext ?
5256								jQuery( sel, this ).index( cur ) > -1 :
5257								jQuery.find( sel, this, null, [ cur ] ).length;
5258						}
5259						if ( matchedSelectors[ sel ] ) {
5260							matchedHandlers.push( handleObj );
5261						}
5262					}
5263					if ( matchedHandlers.length ) {
5264						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5265					}
5266				}
5267			}
5268		}
5269
5270		// Add the remaining (directly-bound) handlers
5271		cur = this;
5272		if ( delegateCount < handlers.length ) {
5273			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5274		}
5275
5276		return handlerQueue;
5277	},
5278
5279	addProp: function( name, hook ) {
5280		Object.defineProperty( jQuery.Event.prototype, name, {
5281			enumerable: true,
5282			configurable: true,
5283
5284			get: 
vendor: 2,487 bytes, lines 5284-5392
5284jQuery.isFunction( hook ) ?
5285				function() {
5286					if ( this.originalEvent ) {
5287							return hook( this.originalEvent );
5288					}
5289				} :
5290				function() {
5291					if ( this.originalEvent ) {
5292							return this.originalEvent[ name ];
5293					}
5294				},
5295
5296			set: function( value ) {
5297				Object.defineProperty( this, name, {
5298					enumerable: true,
5299					configurable: true,
5300					writable: true,
5301					value: value
5302				} );
5303			}
5304		} );
5305	},
5306
5307	fix: function( originalEvent ) {
5308		return originalEvent[ jQuery.expando ] ?
5309			originalEvent :
5310			new jQuery.Event( originalEvent );
5311	},
5312
5313	special: {
5314		load: {
5315
5316			// Prevent triggered image.load events from bubbling to window.load
5317			noBubble: true
5318		},
5319		focus: {
5320
5321			// Fire native event if possible so blur/focus sequence is correct
5322			trigger: function() {
5323				if ( this !== safeActiveElement() && this.focus ) {
5324					this.focus();
5325					return false;
5326				}
5327			},
5328			delegateType: "focusin"
5329		},
5330		blur: {
5331			trigger: function() {
5332				if ( this === safeActiveElement() && this.blur ) {
5333					this.blur();
5334					return false;
5335				}
5336			},
5337			delegateType: "focusout"
5338		},
5339		click: {
5340
5341			// For checkbox, fire native event so checked state will be right
5342			trigger: function() {
5343				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
5344					this.click();
5345					return false;
5346				}
5347			},
5348
5349			// For cross-browser consistency, don't fire native .click() on links
5350			_default: function( event ) {
5351				return jQuery.nodeName( event.target, "a" );
5352			}
5353		},
5354
5355		beforeunload: {
5356			postDispatch: function( event ) {
5357
5358				// Support: Firefox 20+
5359				// Firefox doesn't alert if the returnValue field is not set.
5360				if ( event.result !== undefined && event.originalEvent ) {
5361					event.originalEvent.returnValue = event.result;
5362				}
5363			}
5364		}
5365	}
5366};
5367
5368jQuery.removeEvent = function( elem, type, handle ) {
5369
5370	// This "if" is needed for plain objects
5371	if ( elem.removeEventListener ) {
5372		elem.removeEventListener( type, handle );
5373	}
5374};
5375
5376jQuery.Event = function( src, props ) {
5377
5378	// Allow instantiation without the 'new' keyword
5379	if ( !( this instanceof jQuery.Event ) ) {
5380		return new jQuery.Event( src, props );
5381	}
5382
5383	// Event object
5384	if ( src && src.type ) {
5385		this.originalEvent = src;
5386		this.type = src.type;
5387
5388		// Events bubbling up the document may have been marked as prevented
5389		// by a handler lower down the tree; reflect the correct value.
5390		this.isDefaultPrevented = src.defaultPrevented ||
5391				src.defaultPrevented === undefined &&
5392
vendor: 5,276 bytes, lines 5393-5616
5393				// Support: Android <=2.3 only
5394				src.returnValue === false ?
5395			returnTrue :
5396			returnFalse;
5397
5398		// Create target properties
5399		// Support: Safari <=6 - 7 only
5400		// Target should not be a text node (#504, #13143)
5401		this.target = ( src.target && src.target.nodeType === 3 ) ?
5402			src.target.parentNode :
5403			src.target;
5404
5405		this.currentTarget = src.currentTarget;
5406		this.relatedTarget = src.relatedTarget;
5407
5408	// Event type
5409	} else {
5410		this.type = src;
5411	}
5412
5413	// Put explicitly provided properties onto the event object
5414	if ( props ) {
5415		jQuery.extend( this, props );
5416	}
5417
5418	// Create a timestamp if incoming event doesn't have one
5419	this.timeStamp = src && src.timeStamp || jQuery.now();
5420
5421	// Mark it as fixed
5422	this[ jQuery.expando ] = true;
5423};
5424
5425// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5426// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5427jQuery.Event.prototype = {
5428	constructor: jQuery.Event,
5429	isDefaultPrevented: returnFalse,
5430	isPropagationStopped: returnFalse,
5431	isImmediatePropagationStopped: returnFalse,
5432	isSimulated: false,
5433
5434	preventDefault: function() {
5435		var e = this.originalEvent;
5436
5437		this.isDefaultPrevented = returnTrue;
5438
5439		if ( e && !this.isSimulated ) {
5440			e.preventDefault();
5441		}
5442	},
5443	stopPropagation: function() {
5444		var e = this.originalEvent;
5445
5446		this.isPropagationStopped = returnTrue;
5447
5448		if ( e && !this.isSimulated ) {
5449			e.stopPropagation();
5450		}
5451	},
5452	stopImmediatePropagation: function() {
5453		var e = this.originalEvent;
5454
5455		this.isImmediatePropagationStopped = returnTrue;
5456
5457		if ( e && !this.isSimulated ) {
5458			e.stopImmediatePropagation();
5459		}
5460
5461		this.stopPropagation();
5462	}
5463};
5464
5465// Includes all common event props including KeyEvent and MouseEvent specific props
5466jQuery.each( {
5467	altKey: true,
5468	bubbles: true,
5469	cancelable: true,
5470	changedTouches: true,
5471	ctrlKey: true,
5472	detail: true,
5473	eventPhase: true,
5474	metaKey: true,
5475	pageX: true,
5476	pageY: true,
5477	shiftKey: true,
5478	view: true,
5479	"char": true,
5480	charCode: true,
5481	key: true,
5482	keyCode: true,
5483	button: true,
5484	buttons: true,
5485	clientX: true,
5486	clientY: true,
5487	offsetX: true,
5488	offsetY: true,
5489	pointerId: true,
5490	pointerType: true,
5491	screenX: true,
5492	screenY: true,
5493	targetTouches: true,
5494	toElement: true,
5495	touches: true,
5496
5497	which: function( event ) {
5498		var button = event.button;
5499
5500		// Add which for key events
5501		if ( event.which == null && rkeyEvent.test( event.type ) ) {
5502			return event.charCode != null ? event.charCode : event.keyCode;
5503		}
5504
5505		// Add which for click: 1 === left; 2 === middle; 3 === right
5506		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
5507			if ( button & 1 ) {
5508				return 1;
5509			}
5510
5511			if ( button & 2 ) {
5512				return 3;
5513			}
5514
5515			if ( button & 4 ) {
5516				return 2;
5517			}
5518
5519			return 0;
5520		}
5521
5522		return event.which;
5523	}
5524}, jQuery.event.addProp );
5525
5526// Create mouseenter/leave events using mouseover/out and event-time checks
5527// so that event delegation works in jQuery.
5528// Do the same for pointerenter/pointerleave and pointerover/pointerout
5529//
5530// Support: Safari 7 only
5531// Safari sends mouseenter too often; see:
5532// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5533// for the description of the bug (it existed in older Chrome versions as well).
5534jQuery.each( {
5535	mouseenter: "mouseover",
5536	mouseleave: "mouseout",
5537	pointerenter: "pointerover",
5538	pointerleave: "pointerout"
5539}, function( orig, fix ) {
5540	jQuery.event.special[ orig ] = {
5541		delegateType: fix,
5542		bindType: fix,
5543
5544		handle: function( event ) {
5545			var ret,
5546				target = this,
5547				related = event.relatedTarget,
5548				handleObj = event.handleObj;
5549
5550			// For mouseenter/leave call the handler if related is outside the target.
5551			// NB: No relatedTarget if the mouse left/entered the browser window
5552			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5553				event.type = handleObj.origType;
5554				ret = handleObj.handler.apply( this, arguments );
5555				event.type = fix;
5556			}
5557			return ret;
5558		}
5559	};
5560} );
5561
5562jQuery.fn.extend( {
5563
5564	on: function( types, selector, data, fn ) {
5565		return on( this, types, selector, data, fn );
5566	},
5567	one: function( types, selector, data, fn ) {
5568		return on( this, types, selector, data, fn, 1 );
5569	},
5570	off: function( types, selector, fn ) {
5571		var handleObj, type;
5572		if ( types && types.preventDefault && types.handleObj ) {
5573
5574			// ( event )  dispatched jQuery.Event
5575			handleObj = types.handleObj;
5576			jQuery( types.delegateTarget ).off(
5577				handleObj.namespace ?
5578					handleObj.origType + "." + handleObj.namespace :
5579					handleObj.origType,
5580				handleObj.selector,
5581				handleObj.handler
5582			);
5583			return this;
5584		}
5585		if ( typeof types === "object" ) {
5586
5587			// ( types-object [, selector] )
5588			for ( type in types ) {
5589				this.off( type, selector, types[ type ] );
5590			}
5591			return this;
5592		}
5593		if ( selector === false || typeof selector === "function" ) {
5594
5595			// ( types [, fn] )
5596			fn = selector;
5597			selector = undefined;
5598		}
5599		if ( fn === false ) {
5600			fn = returnFalse;
5601		}
5602		return this.each( function() {
5603			jQuery.event.remove( this, types, fn, selector );
5604		} );
5605	}
5606} );
5607
5608
5609var
5610
5611	/* eslint-disable max-len */
5612
5613	// See https://github.com/eslint/eslint/issues/3229
5614	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
5615
5616	/* eslint-enable */
vendor: 7,144 bytes, lines 5616-5880
5616
5617
5618	// Support: IE <=10 - 11, Edge 12 - 13
5619	// In IE/Edge using regex groups here causes severe slowdowns.
5620	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5621	rnoInnerhtml = /<script|<style|<link/i,
5622
5623	// checked="checked" or checked
5624	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5625	rscriptTypeMasked = /^true\/(.*)/,
5626	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5627
5628function manipulationTarget( elem, content ) {
5629	if ( jQuery.nodeName( elem, "table" ) &&
5630		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5631
5632		return elem.getElementsByTagName( "tbody" )[ 0 ] || elem;
5633	}
5634
5635	return elem;
5636}
5637
5638// Replace/restore the type attribute of script elements for safe DOM manipulation
5639function disableScript( elem ) {
5640	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5641	return elem;
5642}
5643function restoreScript( elem ) {
5644	var match = rscriptTypeMasked.exec( elem.type );
5645
5646	if ( match ) {
5647		elem.type = match[ 1 ];
5648	} else {
5649		elem.removeAttribute( "type" );
5650	}
5651
5652	return elem;
5653}
5654
5655function cloneCopyEvent( src, dest ) {
5656	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5657
5658	if ( dest.nodeType !== 1 ) {
5659		return;
5660	}
5661
5662	// 1. Copy private data: events, handlers, etc.
5663	if ( dataPriv.hasData( src ) ) {
5664		pdataOld = dataPriv.access( src );
5665		pdataCur = dataPriv.set( dest, pdataOld );
5666		events = pdataOld.events;
5667
5668		if ( events ) {
5669			delete pdataCur.handle;
5670			pdataCur.events = {};
5671
5672			for ( type in events ) {
5673				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5674					jQuery.event.add( dest, type, events[ type ][ i ] );
5675				}
5676			}
5677		}
5678	}
5679
5680	// 2. Copy user data
5681	if ( dataUser.hasData( src ) ) {
5682		udataOld = dataUser.access( src );
5683		udataCur = jQuery.extend( {}, udataOld );
5684
5685		dataUser.set( dest, udataCur );
5686	}
5687}
5688
5689// Fix IE bugs, see support tests
5690function fixInput( src, dest ) {
5691	var nodeName = dest.nodeName.toLowerCase();
5692
5693	// Fails to persist the checked state of a cloned checkbox or radio button.
5694	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5695		dest.checked = src.checked;
5696
5697	// Fails to return the selected option to the default selected state when cloning options
5698	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5699		dest.defaultValue = src.defaultValue;
5700	}
5701}
5702
5703function domManip( collection, args, callback, ignored ) {
5704
5705	// Flatten any nested arrays
5706	args = concat.apply( [], args );
5707
5708	var fragment, first, scripts, hasScripts, node, doc,
5709		i = 0,
5710		l = collection.length,
5711		iNoClone = l - 1,
5712		value = args[ 0 ],
5713		isFunction = jQuery.isFunction( value );
5714
5715	// We can't cloneNode fragments that contain checked, in WebKit
5716	if ( isFunction ||
5717			( l > 1 && typeof value === "string" &&
5718				!support.checkClone && rchecked.test( value ) ) ) {
5719		return collection.each( function( index ) {
5720			var self = collection.eq( index );
5721			if ( isFunction ) {
5722				args[ 0 ] = value.call( this, index, self.html() );
5723			}
5724			domManip( self, args, callback, ignored );
5725		} );
5726	}
5727
5728	if ( l ) {
5729		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5730		first = fragment.firstChild;
5731
5732		if ( fragment.childNodes.length === 1 ) {
5733			fragment = first;
5734		}
5735
5736		// Require either new content or an interest in ignored elements to invoke the callback
5737		if ( first || ignored ) {
5738			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5739			hasScripts = scripts.length;
5740
5741			// Use the original fragment for the last item
5742			// instead of the first because it can end up
5743			// being emptied incorrectly in certain situations (#8070).
5744			for ( ; i < l; i++ ) {
5745				node = fragment;
5746
5747				if ( i !== iNoClone ) {
5748					node = jQuery.clone( node, true, true );
5749
5750					// Keep references to cloned scripts for later restoration
5751					if ( hasScripts ) {
5752
5753						// Support: Android <=4.0 only, PhantomJS 1 only
5754						// push.apply(_, arraylike) throws on ancient WebKit
5755						jQuery.merge( scripts, getAll( node, "script" ) );
5756					}
5757				}
5758
5759				callback.call( collection[ i ], node, i );
5760			}
5761
5762			if ( hasScripts ) {
5763				doc = scripts[ scripts.length - 1 ].ownerDocument;
5764
5765				// Reenable scripts
5766				jQuery.map( scripts, restoreScript );
5767
5768				// Evaluate executable scripts on first document insertion
5769				for ( i = 0; i < hasScripts; i++ ) {
5770					node = scripts[ i ];
5771					if ( rscriptType.test( node.type || "" ) &&
5772						!dataPriv.access( node, "globalEval" ) &&
5773						jQuery.contains( doc, node ) ) {
5774
5775						if ( node.src ) {
5776
5777							// Optional AJAX dependency, but won't run scripts if not present
5778							if ( jQuery._evalUrl ) {
5779								jQuery._evalUrl( node.src );
5780							}
5781						} else {
5782							DOMEval( node.textContent.replace( rcleanScript, "" ), doc );
5783						}
5784					}
5785				}
5786			}
5787		}
5788	}
5789
5790	return collection;
5791}
5792
5793function remove( elem, selector, keepData ) {
5794	var node,
5795		nodes = selector ? jQuery.filter( selector, elem ) : elem,
5796		i = 0;
5797
5798	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5799		if ( !keepData && node.nodeType === 1 ) {
5800			jQuery.cleanData( getAll( node ) );
5801		}
5802
5803		if ( node.parentNode ) {
5804			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5805				setGlobalEval( getAll( node, "script" ) );
5806			}
5807			node.parentNode.removeChild( node );
5808		}
5809	}
5810
5811	return elem;
5812}
5813
5814jQuery.extend( {
5815	htmlPrefilter: function( html ) {
5816		return html.replace( rxhtmlTag, "<$1></$2>" );
5817	},
5818
5819	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5820		var i, l, srcElements, destElements,
5821			clone = elem.cloneNode( true ),
5822			inPage = jQuery.contains( elem.ownerDocument, elem );
5823
5824		// Fix IE cloning issues
5825		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5826				!jQuery.isXMLDoc( elem ) ) {
5827
5828			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
5829			destElements = getAll( clone );
5830			srcElements = getAll( elem );
5831
5832			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5833				fixInput( srcElements[ i ], destElements[ i ] );
5834			}
5835		}
5836
5837		// Copy the events from the original to the clone
5838		if ( dataAndEvents ) {
5839			if ( deepDataAndEvents ) {
5840				srcElements = srcElements || getAll( elem );
5841				destElements = destElements || getAll( clone );
5842
5843				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5844					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5845				}
5846			} else {
5847				cloneCopyEvent( elem, clone );
5848			}
5849		}
5850
5851		// Preserve script evaluation history
5852		destElements = getAll( clone, "script" );
5853		if ( destElements.length > 0 ) {
5854			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5855		}
5856
5857		// Return the cloned set
5858		return clone;
5859	},
5860
5861	cleanData: function( elems ) {
5862		var data, elem, type,
5863			special = jQuery.event.special,
5864			i = 0;
5865
5866		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5867			if ( acceptData( elem ) ) {
5868				if ( ( data = elem[ dataPriv.expando ] ) ) {
5869					if ( data.events ) {
5870						for ( type in data.events ) {
5871							if ( special[ type ] ) {
5872								jQuery.event.remove( elem, type );
5873
5874							// This is a shortcut to avoid jQuery.event.remove's overhead
5875							} else {
5876								jQuery.removeEvent( elem, type, data.handle );
5877							}
5878						}
5879					}
5880
vendor: 1,119 bytes, lines 5881-5925
5881					// Support: Chrome <=35 - 45+
5882					// Assign undefined instead of using delete, see Data#remove
5883					elem[ dataPriv.expando ] = undefined;
5884				}
5885				if ( elem[ dataUser.expando ] ) {
5886
5887					// Support: Chrome <=35 - 45+
5888					// Assign undefined instead of using delete, see Data#remove
5889					elem[ dataUser.expando ] = undefined;
5890				}
5891			}
5892		}
5893	}
5894} );
5895
5896jQuery.fn.extend( {
5897	detach: function( selector ) {
5898		return remove( this, selector, true );
5899	},
5900
5901	remove: function( selector ) {
5902		return remove( this, selector );
5903	},
5904
5905	text: function( value ) {
5906		return access( this, function( value ) {
5907			return value === undefined ?
5908				jQuery.text( this ) :
5909				this.empty().each( function() {
5910					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5911						this.textContent = value;
5912					}
5913				} );
5914		}, null, value, arguments.length );
5915	},
5916
5917	append: function() {
5918		return domManip( this, arguments, function( elem ) {
5919			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5920				var target = manipulationTarget( this, elem );
5921				target.appendChild( elem );
5922			}
5923		} );
5924	},
5925
vendor: 9,102 bytes, lines 5926-6275
5926	prepend: function() {
5927		return domManip( this, arguments, function( elem ) {
5928			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5929				var target = manipulationTarget( this, elem );
5930				target.insertBefore( elem, target.firstChild );
5931			}
5932		} );
5933	},
5934
5935	before: function() {
5936		return domManip( this, arguments, function( elem ) {
5937			if ( this.parentNode ) {
5938				this.parentNode.insertBefore( elem, this );
5939			}
5940		} );
5941	},
5942
5943	after: function() {
5944		return domManip( this, arguments, function( elem ) {
5945			if ( this.parentNode ) {
5946				this.parentNode.insertBefore( elem, this.nextSibling );
5947			}
5948		} );
5949	},
5950
5951	empty: function() {
5952		var elem,
5953			i = 0;
5954
5955		for ( ; ( elem = this[ i ] ) != null; i++ ) {
5956			if ( elem.nodeType === 1 ) {
5957
5958				// Prevent memory leaks
5959				jQuery.cleanData( getAll( elem, false ) );
5960
5961				// Remove any remaining nodes
5962				elem.textContent = "";
5963			}
5964		}
5965
5966		return this;
5967	},
5968
5969	clone: function( dataAndEvents, deepDataAndEvents ) {
5970		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5971		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5972
5973		return this.map( function() {
5974			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5975		} );
5976	},
5977
5978	html: function( value ) {
5979		return access( this, function( value ) {
5980			var elem = this[ 0 ] || {},
5981				i = 0,
5982				l = this.length;
5983
5984			if ( value === undefined && elem.nodeType === 1 ) {
5985				return elem.innerHTML;
5986			}
5987
5988			// See if we can take a shortcut and just use innerHTML
5989			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5990				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5991
5992				value = jQuery.htmlPrefilter( value );
5993
5994				try {
5995					for ( ; i < l; i++ ) {
5996						elem = this[ i ] || {};
5997
5998						// Remove element nodes and prevent memory leaks
5999						if ( elem.nodeType === 1 ) {
6000							jQuery.cleanData( getAll( elem, false ) );
6001							elem.innerHTML = value;
6002						}
6003					}
6004
6005					elem = 0;
6006
6007				// If using innerHTML throws an exception, use the fallback method
6008				} catch ( e ) {}
6009			}
6010
6011			if ( elem ) {
6012				this.empty().append( value );
6013			}
6014		}, null, value, arguments.length );
6015	},
6016
6017	replaceWith: function() {
6018		var ignored = [];
6019
6020		// Make the changes, replacing each non-ignored context element with the new content
6021		return domManip( this, arguments, function( elem ) {
6022			var parent = this.parentNode;
6023
6024			if ( jQuery.inArray( this, ignored ) < 0 ) {
6025				jQuery.cleanData( getAll( this ) );
6026				if ( parent ) {
6027					parent.replaceChild( elem, this );
6028				}
6029			}
6030
6031		// Force callback invocation
6032		}, ignored );
6033	}
6034} );
6035
6036jQuery.each( {
6037	appendTo: "append",
6038	prependTo: "prepend",
6039	insertBefore: "before",
6040	insertAfter: "after",
6041	replaceAll: "replaceWith"
6042}, function( name, original ) {
6043	jQuery.fn[ name ] = function( selector ) {
6044		var elems,
6045			ret = [],
6046			insert = jQuery( selector ),
6047			last = insert.length - 1,
6048			i = 0;
6049
6050		for ( ; i <= last; i++ ) {
6051			elems = i === last ? this : this.clone( true );
6052			jQuery( insert[ i ] )[ original ]( elems );
6053
6054			// Support: Android <=4.0 only, PhantomJS 1 only
6055			// .get() because push.apply(_, arraylike) throws on ancient WebKit
6056			push.apply( ret, elems.get() );
6057		}
6058
6059		return this.pushStack( ret );
6060	};
6061} );
6062var rmargin = ( /^margin/ );
6063
6064var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6065
6066var getStyles = function( elem ) {
6067
6068		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6069		// IE throws on elements created in popups
6070		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6071		var view = elem.ownerDocument.defaultView;
6072
6073		if ( !view || !view.opener ) {
6074			view = window;
6075		}
6076
6077		return view.getComputedStyle( elem );
6078	};
6079
6080
6081
6082( function() {
6083
6084	// Executing both pixelPosition & boxSizingReliable tests require only one layout
6085	// so they're executed at the same time to save the second computation.
6086	function computeStyleTests() {
6087
6088		// This is a singleton, we need to execute it only once
6089		if ( !div ) {
6090			return;
6091		}
6092
6093		div.style.cssText =
6094			"box-sizing:border-box;" +
6095			"position:relative;display:block;" +
6096			"margin:auto;border:1px;padding:1px;" +
6097			"top:1%;width:50%";
6098		div.innerHTML = "";
6099		documentElement.appendChild( container );
6100
6101		var divStyle = window.getComputedStyle( div );
6102		pixelPositionVal = divStyle.top !== "1%";
6103
6104		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6105		reliableMarginLeftVal = divStyle.marginLeft === "2px";
6106		boxSizingReliableVal = divStyle.width === "4px";
6107
6108		// Support: Android 4.0 - 4.3 only
6109		// Some styles come back with percentage values, even though they shouldn't
6110		div.style.marginRight = "50%";
6111		pixelMarginRightVal = divStyle.marginRight === "4px";
6112
6113		documentElement.removeChild( container );
6114
6115		// Nullify the div so it wouldn't be stored in the memory and
6116		// it will also be a sign that checks already performed
6117		div = null;
6118	}
6119
6120	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
6121		container = document.createElement( "div" ),
6122		div = document.createElement( "div" );
6123
6124	// Finish early in limited (non-browser) environments
6125	if ( !div.style ) {
6126		return;
6127	}
6128
6129	// Support: IE <=9 - 11 only
6130	// Style of cloned element affects source element cloned (#8908)
6131	div.style.backgroundClip = "content-box";
6132	div.cloneNode( true ).style.backgroundClip = "";
6133	support.clearCloneStyle = div.style.backgroundClip === "content-box";
6134
6135	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6136		"padding:0;margin-top:1px;position:absolute";
6137	container.appendChild( div );
6138
6139	jQuery.extend( support, {
6140		pixelPosition: function() {
6141			computeStyleTests();
6142			return pixelPositionVal;
6143		},
6144		boxSizingReliable: function() {
6145			computeStyleTests();
6146			return boxSizingReliableVal;
6147		},
6148		pixelMarginRight: function() {
6149			computeStyleTests();
6150			return pixelMarginRightVal;
6151		},
6152		reliableMarginLeft: function() {
6153			computeStyleTests();
6154			return reliableMarginLeftVal;
6155		}
6156	} );
6157} )();
6158
6159
6160function curCSS( elem, name, computed ) {
6161	var width, minWidth, maxWidth, ret,
6162		style = elem.style;
6163
6164	computed = computed || getStyles( elem );
6165
6166	// Support: IE <=9 only
6167	// getPropertyValue is only needed for .css('filter') (#12537)
6168	if ( computed ) {
6169		ret = computed.getPropertyValue( name ) || computed[ name ];
6170
6171		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6172			ret = jQuery.style( elem, name );
6173		}
6174
6175		// A tribute to the "awesome hack by Dean Edwards"
6176		// Android Browser returns percentage for some values,
6177		// but width seems to be reliably pixels.
6178		// This is against the CSSOM draft spec:
6179		// https://drafts.csswg.org/cssom/#resolved-values
6180		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6181
6182			// Remember the original values
6183			width = style.width;
6184			minWidth = style.minWidth;
6185			maxWidth = style.maxWidth;
6186
6187			// Put in the new values to get a computed value out
6188			style.minWidth = style.maxWidth = style.width = ret;
6189			ret = computed.width;
6190
6191			// Revert the changed values
6192			style.width = width;
6193			style.minWidth = minWidth;
6194			style.maxWidth = maxWidth;
6195		}
6196	}
6197
6198	return ret !== undefined ?
6199
6200		// Support: IE <=9 - 11 only
6201		// IE returns zIndex value as an integer.
6202		ret + "" :
6203		ret;
6204}
6205
6206
6207function addGetHookIf( conditionFn, hookFn ) {
6208
6209	// Define the hook, we'll check on the first run if it's really needed.
6210	return {
6211		get: function() {
6212			if ( conditionFn() ) {
6213
6214				// Hook not needed (or it's not possible to use it due
6215				// to missing dependency), remove it.
6216				delete this.get;
6217				return;
6218			}
6219
6220			// Hook needed; redefine it so that the support test is not executed again.
6221			return ( this.get = hookFn ).apply( this, arguments );
6222		}
6223	};
6224}
6225
6226
6227var
6228
6229	// Swappable if display is none or starts with table
6230	// except "table", "table-cell", or "table-caption"
6231	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6232	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6233	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6234	cssNormalTransform = {
6235		letterSpacing: "0",
6236		fontWeight: "400"
6237	},
6238
6239	cssPrefixes = [ "Webkit", "Moz", "ms" ],
6240	emptyStyle = document.createElement( "div" ).style;
6241
6242// Return a css property mapped to a potentially vendor prefixed property
6243function vendorPropName( name ) {
6244
6245	// Shortcut for names that are not vendor prefixed
6246	if ( name in emptyStyle ) {
6247		return name;
6248	}
6249
6250	// Check for vendor prefixed names
6251	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6252		i = cssPrefixes.length;
6253
6254	while ( i-- ) {
6255		name = cssPrefixes[ i ] + capName;
6256		if ( name in emptyStyle ) {
6257			return name;
6258		}
6259	}
6260}
6261
6262function setPositiveNumber( elem, value, subtract ) {
6263
6264	// Any relative (+/-) values have already been
6265	// normalized at this point
6266	var matches = rcssNum.exec( value );
6267	return matches ?
6268
6269		// Guard against undefined "subtract", e.g., when used as in cssHooks
6270		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6271		value;
6272}
6273
6274function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6275	var i
vendor: 9,745 bytes, lines 6275-6632
6275,
6276		val = 0;
6277
6278	// If we already have the right measurement, avoid augmentation
6279	if ( extra === ( isBorderBox ? "border" : "content" ) ) {
6280		i = 4;
6281
6282	// Otherwise initialize for horizontal or vertical properties
6283	} else {
6284		i = name === "width" ? 1 : 0;
6285	}
6286
6287	for ( ; i < 4; i += 2 ) {
6288
6289		// Both box models exclude margin, so add it if we want it
6290		if ( extra === "margin" ) {
6291			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6292		}
6293
6294		if ( isBorderBox ) {
6295
6296			// border-box includes padding, so remove it if we want content
6297			if ( extra === "content" ) {
6298				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6299			}
6300
6301			// At this point, extra isn't border nor margin, so remove border
6302			if ( extra !== "margin" ) {
6303				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6304			}
6305		} else {
6306
6307			// At this point, extra isn't content, so add padding
6308			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6309
6310			// At this point, extra isn't content nor padding, so add border
6311			if ( extra !== "padding" ) {
6312				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6313			}
6314		}
6315	}
6316
6317	return val;
6318}
6319
6320function getWidthOrHeight( elem, name, extra ) {
6321
6322	// Start with offset property, which is equivalent to the border-box value
6323	var val,
6324		valueIsBorderBox = true,
6325		styles = getStyles( elem ),
6326		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6327
6328	// Support: IE <=11 only
6329	// Running getBoundingClientRect on a disconnected node
6330	// in IE throws an error.
6331	if ( elem.getClientRects().length ) {
6332		val = elem.getBoundingClientRect()[ name ];
6333	}
6334
6335	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
6336	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6337	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6338	if ( val <= 0 || val == null ) {
6339
6340		// Fall back to computed then uncomputed css if necessary
6341		val = curCSS( elem, name, styles );
6342		if ( val < 0 || val == null ) {
6343			val = elem.style[ name ];
6344		}
6345
6346		// Computed unit is not pixels. Stop here and return.
6347		if ( rnumnonpx.test( val ) ) {
6348			return val;
6349		}
6350
6351		// Check for style in case a browser which returns unreliable values
6352		// for getComputedStyle silently falls back to the reliable elem.style
6353		valueIsBorderBox = isBorderBox &&
6354			( support.boxSizingReliable() || val === elem.style[ name ] );
6355
6356		// Normalize "", auto, and prepare for extra
6357		val = parseFloat( val ) || 0;
6358	}
6359
6360	// Use the active box-sizing model to add/subtract irrelevant styles
6361	return ( val +
6362		augmentWidthOrHeight(
6363			elem,
6364			name,
6365			extra || ( isBorderBox ? "border" : "content" ),
6366			valueIsBorderBox,
6367			styles
6368		)
6369	) + "px";
6370}
6371
6372jQuery.extend( {
6373
6374	// Add in style property hooks for overriding the default
6375	// behavior of getting and setting a style property
6376	cssHooks: {
6377		opacity: {
6378			get: function( elem, computed ) {
6379				if ( computed ) {
6380
6381					// We should always get a number back from opacity
6382					var ret = curCSS( elem, "opacity" );
6383					return ret === "" ? "1" : ret;
6384				}
6385			}
6386		}
6387	},
6388
6389	// Don't automatically add "px" to these possibly-unitless properties
6390	cssNumber: {
6391		"animationIterationCount": true,
6392		"columnCount": true,
6393		"fillOpacity": true,
6394		"flexGrow": true,
6395		"flexShrink": true,
6396		"fontWeight": true,
6397		"lineHeight": true,
6398		"opacity": true,
6399		"order": true,
6400		"orphans": true,
6401		"widows": true,
6402		"zIndex": true,
6403		"zoom": true
6404	},
6405
6406	// Add in properties whose names you wish to fix before
6407	// setting or getting the value
6408	cssProps: {
6409		"float": "cssFloat"
6410	},
6411
6412	// Get and set the style property on a DOM Node
6413	style: function( elem, name, value, extra ) {
6414
6415		// Don't set styles on text and comment nodes
6416		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6417			return;
6418		}
6419
6420		// Make sure that we're working with the right name
6421		var ret, type, hooks,
6422			origName = jQuery.camelCase( name ),
6423			style = elem.style;
6424
6425		name = jQuery.cssProps[ origName ] ||
6426			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6427
6428		// Gets hook for the prefixed version, then unprefixed version
6429		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6430
6431		// Check if we're setting a value
6432		if ( value !== undefined ) {
6433			type = typeof value;
6434
6435			// Convert "+=" or "-=" to relative numbers (#7345)
6436			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6437				value = adjustCSS( elem, name, ret );
6438
6439				// Fixes bug #9237
6440				type = "number";
6441			}
6442
6443			// Make sure that null and NaN values aren't set (#7116)
6444			if ( value == null || value !== value ) {
6445				return;
6446			}
6447
6448			// If a number was passed in, add the unit (except for certain CSS properties)
6449			if ( type === "number" ) {
6450				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6451			}
6452
6453			// background-* props affect original clone's values
6454			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6455				style[ name ] = "inherit";
6456			}
6457
6458			// If a hook was provided, use that value, otherwise just set the specified value
6459			if ( !hooks || !( "set" in hooks ) ||
6460				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6461
6462				style[ name ] = value;
6463			}
6464
6465		} else {
6466
6467			// If a hook was provided get the non-computed value from there
6468			if ( hooks && "get" in hooks &&
6469				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6470
6471				return ret;
6472			}
6473
6474			// Otherwise just get the value from the style object
6475			return style[ name ];
6476		}
6477	},
6478
6479	css: function( elem, name, extra, styles ) {
6480		var val, num, hooks,
6481			origName = jQuery.camelCase( name );
6482
6483		// Make sure that we're working with the right name
6484		name = jQuery.cssProps[ origName ] ||
6485			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6486
6487		// Try prefixed name followed by the unprefixed name
6488		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6489
6490		// If a hook was provided get the computed value from there
6491		if ( hooks && "get" in hooks ) {
6492			val = hooks.get( elem, true, extra );
6493		}
6494
6495		// Otherwise, if a way to get the computed value exists, use that
6496		if ( val === undefined ) {
6497			val = curCSS( elem, name, styles );
6498		}
6499
6500		// Convert "normal" to computed value
6501		if ( val === "normal" && name in cssNormalTransform ) {
6502			val = cssNormalTransform[ name ];
6503		}
6504
6505		// Make numeric if forced or a qualifier was provided and val looks numeric
6506		if ( extra === "" || extra ) {
6507			num = parseFloat( val );
6508			return extra === true || isFinite( num ) ? num || 0 : val;
6509		}
6510		return val;
6511	}
6512} );
6513
6514jQuery.each( [ "height", "width" ], function( i, name ) {
6515	jQuery.cssHooks[ name ] = {
6516		get: function( elem, computed, extra ) {
6517			if ( computed ) {
6518
6519				// Certain elements can have dimension info if we invisibly show them
6520				// but it must have a current display style that would benefit
6521				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6522
6523					// Support: Safari 8+
6524					// Table columns in Safari have non-zero offsetWidth & zero
6525					// getBoundingClientRect().width unless display is changed.
6526					// Support: IE <=11 only
6527					// Running getBoundingClientRect on a disconnected node
6528					// in IE throws an error.
6529					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
6530						swap( elem, cssShow, function() {
6531							return getWidthOrHeight( elem, name, extra );
6532						} ) :
6533						getWidthOrHeight( elem, name, extra );
6534			}
6535		},
6536
6537		set: function( elem, value, extra ) {
6538			var matches,
6539				styles = extra && getStyles( elem ),
6540				subtract = extra && augmentWidthOrHeight(
6541					elem,
6542					name,
6543					extra,
6544					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6545					styles
6546				);
6547
6548			// Convert to pixels if value adjustment is needed
6549			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6550				( matches[ 3 ] || "px" ) !== "px" ) {
6551
6552				elem.style[ name ] = value;
6553				value = jQuery.css( elem, name );
6554			}
6555
6556			return setPositiveNumber( elem, value, subtract );
6557		}
6558	};
6559} );
6560
6561jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6562	function( elem, computed ) {
6563		if ( computed ) {
6564			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6565				elem.getBoundingClientRect().left -
6566					swap( elem, { marginLeft: 0 }, function() {
6567						return elem.getBoundingClientRect().left;
6568					} )
6569				) + "px";
6570		}
6571	}
6572);
6573
6574// These hooks are used by animate to expand properties
6575jQuery.each( {
6576	margin: "",
6577	padding: "",
6578	border: "Width"
6579}, function( prefix, suffix ) {
6580	jQuery.cssHooks[ prefix + suffix ] = {
6581		expand: function( value ) {
6582			var i = 0,
6583				expanded = {},
6584
6585				// Assumes a single number if not a string
6586				parts = typeof value === "string" ? value.split( " " ) : [ value ];
6587
6588			for ( ; i < 4; i++ ) {
6589				expanded[ prefix + cssExpand[ i ] + suffix ] =
6590					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6591			}
6592
6593			return expanded;
6594		}
6595	};
6596
6597	if ( !rmargin.test( prefix ) ) {
6598		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6599	}
6600} );
6601
6602jQuery.fn.extend( {
6603	css: function( name, value ) {
6604		return access( this, function( elem, name, value ) {
6605			var styles, len,
6606				map = {},
6607				i = 0;
6608
6609			if ( jQuery.isArray( name ) ) {
6610				styles = getStyles( elem );
6611				len = name.length;
6612
6613				for ( ; i < len; i++ ) {
6614					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6615				}
6616
6617				return map;
6618			}
6619
6620			return value !== undefined ?
6621				jQuery.style( elem, name, value ) :
6622				jQuery.css( elem, name );
6623		}, name, value, arguments.length > 1 );
6624	}
6625} );
6626
6627
6628function Tween( elem, options, prop, end, easing ) {
6629	return new Tween.prototype.init( elem, options, prop, end, easing );
6630}
6631jQuery.Tween = Tween;
6632
vendor: 6,060 bytes, lines 6633-6866
6633Tween.prototype = {
6634	constructor: Tween,
6635	init: function( elem, options, prop, end, easing, unit ) {
6636		this.elem = elem;
6637		this.prop = prop;
6638		this.easing = easing || jQuery.easing._default;
6639		this.options = options;
6640		this.start = this.now = this.cur();
6641		this.end = end;
6642		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6643	},
6644	cur: function() {
6645		var hooks = Tween.propHooks[ this.prop ];
6646
6647		return hooks && hooks.get ?
6648			hooks.get( this ) :
6649			Tween.propHooks._default.get( this );
6650	},
6651	run: function( percent ) {
6652		var eased,
6653			hooks = Tween.propHooks[ this.prop ];
6654
6655		if ( this.options.duration ) {
6656			this.pos = eased = jQuery.easing[ this.easing ](
6657				percent, this.options.duration * percent, 0, 1, this.options.duration
6658			);
6659		} else {
6660			this.pos = eased = percent;
6661		}
6662		this.now = ( this.end - this.start ) * eased + this.start;
6663
6664		if ( this.options.step ) {
6665			this.options.step.call( this.elem, this.now, this );
6666		}
6667
6668		if ( hooks && hooks.set ) {
6669			hooks.set( this );
6670		} else {
6671			Tween.propHooks._default.set( this );
6672		}
6673		return this;
6674	}
6675};
6676
6677Tween.prototype.init.prototype = Tween.prototype;
6678
6679Tween.propHooks = {
6680	_default: {
6681		get: function( tween ) {
6682			var result;
6683
6684			// Use a property on the element directly when it is not a DOM element,
6685			// or when there is no matching style property that exists.
6686			if ( tween.elem.nodeType !== 1 ||
6687				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6688				return tween.elem[ tween.prop ];
6689			}
6690
6691			// Passing an empty string as a 3rd parameter to .css will automatically
6692			// attempt a parseFloat and fallback to a string if the parse fails.
6693			// Simple values such as "10px" are parsed to Float;
6694			// complex values such as "rotate(1rad)" are returned as-is.
6695			result = jQuery.css( tween.elem, tween.prop, "" );
6696
6697			// Empty strings, null, undefined and "auto" are converted to 0.
6698			return !result || result === "auto" ? 0 : result;
6699		},
6700		set: function( tween ) {
6701
6702			// Use step hook for back compat.
6703			// Use cssHook if its there.
6704			// Use .style if available and use plain properties where available.
6705			if ( jQuery.fx.step[ tween.prop ] ) {
6706				jQuery.fx.step[ tween.prop ]( tween );
6707			} else if ( tween.elem.nodeType === 1 &&
6708				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6709					jQuery.cssHooks[ tween.prop ] ) ) {
6710				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6711			} else {
6712				tween.elem[ tween.prop ] = tween.now;
6713			}
6714		}
6715	}
6716};
6717
6718// Support: IE <=9 only
6719// Panic based approach to setting things on disconnected nodes
6720Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6721	set: function( tween ) {
6722		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6723			tween.elem[ tween.prop ] = tween.now;
6724		}
6725	}
6726};
6727
6728jQuery.easing = {
6729	linear: function( p ) {
6730		return p;
6731	},
6732	swing: function( p ) {
6733		return 0.5 - Math.cos( p * Math.PI ) / 2;
6734	},
6735	_default: "swing"
6736};
6737
6738jQuery.fx = Tween.prototype.init;
6739
6740// Back compat <1.8 extension point
6741jQuery.fx.step = {};
6742
6743
6744
6745
6746var
6747	fxNow, timerId,
6748	rfxtypes = /^(?:toggle|show|hide)$/,
6749	rrun = /queueHooks$/;
6750
6751function raf() {
6752	if ( timerId ) {
6753		window.requestAnimationFrame( raf );
6754		jQuery.fx.tick();
6755	}
6756}
6757
6758// Animations created synchronously will run synchronously
6759function createFxNow() {
6760	window.setTimeout( function() {
6761		fxNow = undefined;
6762	} );
6763	return ( fxNow = jQuery.now() );
6764}
6765
6766// Generate parameters to create a standard animation
6767function genFx( type, includeWidth ) {
6768	var which,
6769		i = 0,
6770		attrs = { height: type };
6771
6772	// If we include width, step value is 1 to do all cssExpand values,
6773	// otherwise step value is 2 to skip over Left and Right
6774	includeWidth = includeWidth ? 1 : 0;
6775	for ( ; i < 4; i += 2 - includeWidth ) {
6776		which = cssExpand[ i ];
6777		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6778	}
6779
6780	if ( includeWidth ) {
6781		attrs.opacity = attrs.width = type;
6782	}
6783
6784	return attrs;
6785}
6786
6787function createTween( value, prop, animation ) {
6788	var tween,
6789		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6790		index = 0,
6791		length = collection.length;
6792	for ( ; index < length; index++ ) {
6793		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6794
6795			// We're done with this property
6796			return tween;
6797		}
6798	}
6799}
6800
6801function defaultPrefilter( elem, props, opts ) {
6802	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
6803		isBox = "width" in props || "height" in props,
6804		anim = this,
6805		orig = {},
6806		style = elem.style,
6807		hidden = elem.nodeType && isHiddenWithinTree( elem ),
6808		dataShow = dataPriv.get( elem, "fxshow" );
6809
6810	// Queue-skipping animations hijack the fx hooks
6811	if ( !opts.queue ) {
6812		hooks = jQuery._queueHooks( elem, "fx" );
6813		if ( hooks.unqueued == null ) {
6814			hooks.unqueued = 0;
6815			oldfire = hooks.empty.fire;
6816			hooks.empty.fire = function() {
6817				if ( !hooks.unqueued ) {
6818					oldfire();
6819				}
6820			};
6821		}
6822		hooks.unqueued++;
6823
6824		anim.always( function() {
6825
6826			// Ensure the complete handler is called before this completes
6827			anim.always( function() {
6828				hooks.unqueued--;
6829				if ( !jQuery.queue( elem, "fx" ).length ) {
6830					hooks.empty.fire();
6831				}
6832			} );
6833		} );
6834	}
6835
6836	// Detect show/hide animations
6837	for ( prop in props ) {
6838		value = props[ prop ];
6839		if ( rfxtypes.test( value ) ) {
6840			delete props[ prop ];
6841			toggle = toggle || value === "toggle";
6842			if ( value === ( hidden ? "hide" : "show" ) ) {
6843
6844				// Pretend to be hidden if this is a "show" and
6845				// there is still data from a stopped show/hide
6846				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6847					hidden = true;
6848
6849				// Ignore all other no-op show/hide data
6850				} else {
6851					continue;
6852				}
6853			}
6854			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6855		}
6856	}
6857
6858	// Bail out if this is a no-op like .hide().hide()
6859	propTween = !jQuery.isEmptyObject( props );
6860	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
6861		return;
6862	}
6863
6864	// Restrict "overflow" and "display" styles during box animations
6865	if ( isBox && elem.nodeType === 1 ) {
6866
vendor: 4,174 bytes, lines 6867-7025
6867		// Support: IE <=9 - 11, Edge 12 - 13
6868		// Record all 3 overflow attributes because IE does not infer the shorthand
6869		// from identically-valued overflowX and overflowY
6870		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6871
6872		// Identify a display type, preferring old show/hide data over the CSS cascade
6873		restoreDisplay = dataShow && dataShow.display;
6874		if ( restoreDisplay == null ) {
6875			restoreDisplay = dataPriv.get( elem, "display" );
6876		}
6877		display = jQuery.css( elem, "display" );
6878		if ( display === "none" ) {
6879			if ( restoreDisplay ) {
6880				display = restoreDisplay;
6881			} else {
6882
6883				// Get nonempty value(s) by temporarily forcing visibility
6884				showHide( [ elem ], true );
6885				restoreDisplay = elem.style.display || restoreDisplay;
6886				display = jQuery.css( elem, "display" );
6887				showHide( [ elem ] );
6888			}
6889		}
6890
6891		// Animate inline elements as inline-block
6892		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
6893			if ( jQuery.css( elem, "float" ) === "none" ) {
6894
6895				// Restore the original display value at the end of pure show/hide animations
6896				if ( !propTween ) {
6897					anim.done( function() {
6898						style.display = restoreDisplay;
6899					} );
6900					if ( restoreDisplay == null ) {
6901						display = style.display;
6902						restoreDisplay = display === "none" ? "" : display;
6903					}
6904				}
6905				style.display = "inline-block";
6906			}
6907		}
6908	}
6909
6910	if ( opts.overflow ) {
6911		style.overflow = "hidden";
6912		anim.always( function() {
6913			style.overflow = opts.overflow[ 0 ];
6914			style.overflowX = opts.overflow[ 1 ];
6915			style.overflowY = opts.overflow[ 2 ];
6916		} );
6917	}
6918
6919	// Implement show/hide animations
6920	propTween = false;
6921	for ( prop in orig ) {
6922
6923		// General show/hide setup for this element animation
6924		if ( !propTween ) {
6925			if ( dataShow ) {
6926				if ( "hidden" in dataShow ) {
6927					hidden = dataShow.hidden;
6928				}
6929			} else {
6930				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
6931			}
6932
6933			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
6934			if ( toggle ) {
6935				dataShow.hidden = !hidden;
6936			}
6937
6938			// Show elements before animating them
6939			if ( hidden ) {
6940				showHide( [ elem ], true );
6941			}
6942
6943			/* eslint-disable no-loop-func */
6944
6945			anim.done( function() {
6946
6947			/* eslint-enable no-loop-func */
6948
6949				// The final step of a "hide" animation is actually hiding the element
6950				if ( !hidden ) {
6951					showHide( [ elem ] );
6952				}
6953				dataPriv.remove( elem, "fxshow" );
6954				for ( prop in orig ) {
6955					jQuery.style( elem, prop, orig[ prop ] );
6956				}
6957			} );
6958		}
6959
6960		// Per-property setup
6961		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6962		if ( !( prop in dataShow ) ) {
6963			dataShow[ prop ] = propTween.start;
6964			if ( hidden ) {
6965				propTween.end = propTween.start;
6966				propTween.start = 0;
6967			}
6968		}
6969	}
6970}
6971
6972function propFilter( props, specialEasing ) {
6973	var index, name, easing, value, hooks;
6974
6975	// camelCase, specialEasing and expand cssHook pass
6976	for ( index in props ) {
6977		name = jQuery.camelCase( index );
6978		easing = specialEasing[ name ];
6979		value = props[ index ];
6980		if ( jQuery.isArray( value ) ) {
6981			easing = value[ 1 ];
6982			value = props[ index ] = value[ 0 ];
6983		}
6984
6985		if ( index !== name ) {
6986			props[ name ] = value;
6987			delete props[ index ];
6988		}
6989
6990		hooks = jQuery.cssHooks[ name ];
6991		if ( hooks && "expand" in hooks ) {
6992			value = hooks.expand( value );
6993			delete props[ name ];
6994
6995			// Not quite $.extend, this won't overwrite existing keys.
6996			// Reusing 'index' because we have the correct "name"
6997			for ( index in value ) {
6998				if ( !( index in props ) ) {
6999					props[ index ] = value[ index ];
7000					specialEasing[ index ] = easing;
7001				}
7002			}
7003		} else {
7004			specialEasing[ name ] = easing;
7005		}
7006	}
7007}
7008
7009function Animation( elem, properties, options ) {
7010	var result,
7011		stopped,
7012		index = 0,
7013		length = Animation.prefilters.length,
7014		deferred = jQuery.Deferred().always( function() {
7015
7016			// Don't match elem in the :animated selector
7017			delete tick.elem;
7018		} ),
7019		tick = function() {
7020			if ( stopped ) {
7021				return false;
7022			}
7023			var currentTime = fxNow || createFxNow(),
7024				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7025
vendor: 6,479 bytes, lines 7026-7275
7026				// Support: Android 2.3 only
7027				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7028				temp = remaining / animation.duration || 0,
7029				percent = 1 - temp,
7030				index = 0,
7031				length = animation.tweens.length;
7032
7033			for ( ; index < length; index++ ) {
7034				animation.tweens[ index ].run( percent );
7035			}
7036
7037			deferred.notifyWith( elem, [ animation, percent, remaining ] );
7038
7039			if ( percent < 1 && length ) {
7040				return remaining;
7041			} else {
7042				deferred.resolveWith( elem, [ animation ] );
7043				return false;
7044			}
7045		},
7046		animation = deferred.promise( {
7047			elem: elem,
7048			props: jQuery.extend( {}, properties ),
7049			opts: jQuery.extend( true, {
7050				specialEasing: {},
7051				easing: jQuery.easing._default
7052			}, options ),
7053			originalProperties: properties,
7054			originalOptions: options,
7055			startTime: fxNow || createFxNow(),
7056			duration: options.duration,
7057			tweens: [],
7058			createTween: function( prop, end ) {
7059				var tween = jQuery.Tween( elem, animation.opts, prop, end,
7060						animation.opts.specialEasing[ prop ] || animation.opts.easing );
7061				animation.tweens.push( tween );
7062				return tween;
7063			},
7064			stop: function( gotoEnd ) {
7065				var index = 0,
7066
7067					// If we are going to the end, we want to run all the tweens
7068					// otherwise we skip this part
7069					length = gotoEnd ? animation.tweens.length : 0;
7070				if ( stopped ) {
7071					return this;
7072				}
7073				stopped = true;
7074				for ( ; index < length; index++ ) {
7075					animation.tweens[ index ].run( 1 );
7076				}
7077
7078				// Resolve when we played the last frame; otherwise, reject
7079				if ( gotoEnd ) {
7080					deferred.notifyWith( elem, [ animation, 1, 0 ] );
7081					deferred.resolveWith( elem, [ animation, gotoEnd ] );
7082				} else {
7083					deferred.rejectWith( elem, [ animation, gotoEnd ] );
7084				}
7085				return this;
7086			}
7087		} ),
7088		props = animation.props;
7089
7090	propFilter( props, animation.opts.specialEasing );
7091
7092	for ( ; index < length; index++ ) {
7093		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7094		if ( result ) {
7095			if ( jQuery.isFunction( result.stop ) ) {
7096				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7097					jQuery.proxy( result.stop, result );
7098			}
7099			return result;
7100		}
7101	}
7102
7103	jQuery.map( props, createTween, animation );
7104
7105	if ( jQuery.isFunction( animation.opts.start ) ) {
7106		animation.opts.start.call( elem, animation );
7107	}
7108
7109	jQuery.fx.timer(
7110		jQuery.extend( tick, {
7111			elem: elem,
7112			anim: animation,
7113			queue: animation.opts.queue
7114		} )
7115	);
7116
7117	// attach callbacks from options
7118	return animation.progress( animation.opts.progress )
7119		.done( animation.opts.done, animation.opts.complete )
7120		.fail( animation.opts.fail )
7121		.always( animation.opts.always );
7122}
7123
7124jQuery.Animation = jQuery.extend( Animation, {
7125
7126	tweeners: {
7127		"*": [ function( prop, value ) {
7128			var tween = this.createTween( prop, value );
7129			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7130			return tween;
7131		} ]
7132	},
7133
7134	tweener: function( props, callback ) {
7135		if ( jQuery.isFunction( props ) ) {
7136			callback = props;
7137			props = [ "*" ];
7138		} else {
7139			props = props.match( rnothtmlwhite );
7140		}
7141
7142		var prop,
7143			index = 0,
7144			length = props.length;
7145
7146		for ( ; index < length; index++ ) {
7147			prop = props[ index ];
7148			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7149			Animation.tweeners[ prop ].unshift( callback );
7150		}
7151	},
7152
7153	prefilters: [ defaultPrefilter ],
7154
7155	prefilter: function( callback, prepend ) {
7156		if ( prepend ) {
7157			Animation.prefilters.unshift( callback );
7158		} else {
7159			Animation.prefilters.push( callback );
7160		}
7161	}
7162} );
7163
7164jQuery.speed = function( speed, easing, fn ) {
7165	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7166		complete: fn || !fn && easing ||
7167			jQuery.isFunction( speed ) && speed,
7168		duration: speed,
7169		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7170	};
7171
7172	// Go to the end state if fx are off or if document is hidden
7173	if ( jQuery.fx.off || document.hidden ) {
7174		opt.duration = 0;
7175
7176	} else {
7177		if ( typeof opt.duration !== "number" ) {
7178			if ( opt.duration in jQuery.fx.speeds ) {
7179				opt.duration = jQuery.fx.speeds[ opt.duration ];
7180
7181			} else {
7182				opt.duration = jQuery.fx.speeds._default;
7183			}
7184		}
7185	}
7186
7187	// Normalize opt.queue - true/undefined/null -> "fx"
7188	if ( opt.queue == null || opt.queue === true ) {
7189		opt.queue = "fx";
7190	}
7191
7192	// Queueing
7193	opt.old = opt.complete;
7194
7195	opt.complete = function() {
7196		if ( jQuery.isFunction( opt.old ) ) {
7197			opt.old.call( this );
7198		}
7199
7200		if ( opt.queue ) {
7201			jQuery.dequeue( this, opt.queue );
7202		}
7203	};
7204
7205	return opt;
7206};
7207
7208jQuery.fn.extend( {
7209	fadeTo: function( speed, to, easing, callback ) {
7210
7211		// Show any hidden elements after setting opacity to 0
7212		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7213
7214			// Animate to the value specified
7215			.end().animate( { opacity: to }, speed, easing, callback );
7216	},
7217	animate: function( prop, speed, easing, callback ) {
7218		var empty = jQuery.isEmptyObject( prop ),
7219			optall = jQuery.speed( speed, easing, callback ),
7220			doAnimation = function() {
7221
7222				// Operate on a copy of prop so per-property easing won't be lost
7223				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7224
7225				// Empty animations, or finishing resolves immediately
7226				if ( empty || dataPriv.get( this, "finish" ) ) {
7227					anim.stop( true );
7228				}
7229			};
7230			doAnimation.finish = doAnimation;
7231
7232		return empty || optall.queue === false ?
7233			this.each( doAnimation ) :
7234			this.queue( optall.queue, doAnimation );
7235	},
7236	stop: function( type, clearQueue, gotoEnd ) {
7237		var stopQueue = function( hooks ) {
7238			var stop = hooks.stop;
7239			delete hooks.stop;
7240			stop( gotoEnd );
7241		};
7242
7243		if ( typeof type !== "string" ) {
7244			gotoEnd = clearQueue;
7245			clearQueue = type;
7246			type = undefined;
7247		}
7248		if ( clearQueue && type !== false ) {
7249			this.queue( type || "fx", [] );
7250		}
7251
7252		return this.each( function() {
7253			var dequeue = true,
7254				index = type != null && type + "queueHooks",
7255				timers = jQuery.timers,
7256				data = dataPriv.get( this );
7257
7258			if ( index ) {
7259				if ( data[ index ] && data[ index ].stop ) {
7260					stopQueue( data[ index ] );
7261				}
7262			} else {
7263				for ( index in data ) {
7264					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7265						stopQueue( data[ index ] );
7266					}
7267				}
7268			}
7269
7270			for ( index = timers.length; index--; ) {
7271				if ( timers[ index ].elem === this &&
7272					( type == null || timers[ index ].queue === type ) ) {
7273
7274					timers[ index ].anim.stop( gotoEnd );
7275					dequeue = false;
vendor: 3,274 bytes, lines 7276-7415
7276					timers.splice( index, 1 );
7277				}
7278			}
7279
7280			// Start the next in the queue if the last step wasn't forced.
7281			// Timers currently will call their complete callbacks, which
7282			// will dequeue but only if they were gotoEnd.
7283			if ( dequeue || !gotoEnd ) {
7284				jQuery.dequeue( this, type );
7285			}
7286		} );
7287	},
7288	finish: function( type ) {
7289		if ( type !== false ) {
7290			type = type || "fx";
7291		}
7292		return this.each( function() {
7293			var index,
7294				data = dataPriv.get( this ),
7295				queue = data[ type + "queue" ],
7296				hooks = data[ type + "queueHooks" ],
7297				timers = jQuery.timers,
7298				length = queue ? queue.length : 0;
7299
7300			// Enable finishing flag on private data
7301			data.finish = true;
7302
7303			// Empty the queue first
7304			jQuery.queue( this, type, [] );
7305
7306			if ( hooks && hooks.stop ) {
7307				hooks.stop.call( this, true );
7308			}
7309
7310			// Look for any active animations, and finish them
7311			for ( index = timers.length; index--; ) {
7312				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7313					timers[ index ].anim.stop( true );
7314					timers.splice( index, 1 );
7315				}
7316			}
7317
7318			// Look for any animations in the old queue and finish them
7319			for ( index = 0; index < length; index++ ) {
7320				if ( queue[ index ] && queue[ index ].finish ) {
7321					queue[ index ].finish.call( this );
7322				}
7323			}
7324
7325			// Turn off finishing flag
7326			delete data.finish;
7327		} );
7328	}
7329} );
7330
7331jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
7332	var cssFn = jQuery.fn[ name ];
7333	jQuery.fn[ name ] = function( speed, easing, callback ) {
7334		return speed == null || typeof speed === "boolean" ?
7335			cssFn.apply( this, arguments ) :
7336			this.animate( genFx( name, true ), speed, easing, callback );
7337	};
7338} );
7339
7340// Generate shortcuts for custom animations
7341jQuery.each( {
7342	slideDown: genFx( "show" ),
7343	slideUp: genFx( "hide" ),
7344	slideToggle: genFx( "toggle" ),
7345	fadeIn: { opacity: "show" },
7346	fadeOut: { opacity: "hide" },
7347	fadeToggle: { opacity: "toggle" }
7348}, function( name, props ) {
7349	jQuery.fn[ name ] = function( speed, easing, callback ) {
7350		return this.animate( props, speed, easing, callback );
7351	};
7352} );
7353
7354jQuery.timers = [];
7355jQuery.fx.tick = function() {
7356	var timer,
7357		i = 0,
7358		timers = jQuery.timers;
7359
7360	fxNow = jQuery.now();
7361
7362	for ( ; i < timers.length; i++ ) {
7363		timer = timers[ i ];
7364
7365		// Checks the timer has not already been removed
7366		if ( !timer() && timers[ i ] === timer ) {
7367			timers.splice( i--, 1 );
7368		}
7369	}
7370
7371	if ( !timers.length ) {
7372		jQuery.fx.stop();
7373	}
7374	fxNow = undefined;
7375};
7376
7377jQuery.fx.timer = function( timer ) {
7378	jQuery.timers.push( timer );
7379	if ( timer() ) {
7380		jQuery.fx.start();
7381	} else {
7382		jQuery.timers.pop();
7383	}
7384};
7385
7386jQuery.fx.interval = 13;
7387jQuery.fx.start = function() {
7388	if ( !timerId ) {
7389		timerId = window.requestAnimationFrame ?
7390			window.requestAnimationFrame( raf ) :
7391			window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
7392	}
7393};
7394
7395jQuery.fx.stop = function() {
7396	if ( window.cancelAnimationFrame ) {
7397		window.cancelAnimationFrame( timerId );
7398	} else {
7399		window.clearInterval( timerId );
7400	}
7401
7402	timerId = null;
7403};
7404
7405jQuery.fx.speeds = {
7406	slow: 600,
7407	fast: 200,
7408
7409	// Default speed
7410	_default: 400
7411};
7412
7413
7414// Based off of the plugin by Clint Helfers, with permission.
7415// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
vendor: 11,255 bytes, lines 7416-7888
7416jQuery.fn.delay = function( time, type ) {
7417	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7418	type = type || "fx";
7419
7420	return this.queue( type, function( next, hooks ) {
7421		var timeout = window.setTimeout( next, time );
7422		hooks.stop = function() {
7423			window.clearTimeout( timeout );
7424		};
7425	} );
7426};
7427
7428
7429( function() {
7430	var input = document.createElement( "input" ),
7431		select = document.createElement( "select" ),
7432		opt = select.appendChild( document.createElement( "option" ) );
7433
7434	input.type = "checkbox";
7435
7436	// Support: Android <=4.3 only
7437	// Default value for a checkbox should be "on"
7438	support.checkOn = input.value !== "";
7439
7440	// Support: IE <=11 only
7441	// Must access selectedIndex to make default options select
7442	support.optSelected = opt.selected;
7443
7444	// Support: IE <=11 only
7445	// An input loses its value after becoming a radio
7446	input = document.createElement( "input" );
7447	input.value = "t";
7448	input.type = "radio";
7449	support.radioValue = input.value === "t";
7450} )();
7451
7452
7453var boolHook,
7454	attrHandle = jQuery.expr.attrHandle;
7455
7456jQuery.fn.extend( {
7457	attr: function( name, value ) {
7458		return access( this, jQuery.attr, name, value, arguments.length > 1 );
7459	},
7460
7461	removeAttr: function( name ) {
7462		return this.each( function() {
7463			jQuery.removeAttr( this, name );
7464		} );
7465	}
7466} );
7467
7468jQuery.extend( {
7469	attr: function( elem, name, value ) {
7470		var ret, hooks,
7471			nType = elem.nodeType;
7472
7473		// Don't get/set attributes on text, comment and attribute nodes
7474		if ( nType === 3 || nType === 8 || nType === 2 ) {
7475			return;
7476		}
7477
7478		// Fallback to prop when attributes are not supported
7479		if ( typeof elem.getAttribute === "undefined" ) {
7480			return jQuery.prop( elem, name, value );
7481		}
7482
7483		// Attribute hooks are determined by the lowercase version
7484		// Grab necessary hook if one is defined
7485		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7486			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
7487				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7488		}
7489
7490		if ( value !== undefined ) {
7491			if ( value === null ) {
7492				jQuery.removeAttr( elem, name );
7493				return;
7494			}
7495
7496			if ( hooks && "set" in hooks &&
7497				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7498				return ret;
7499			}
7500
7501			elem.setAttribute( name, value + "" );
7502			return value;
7503		}
7504
7505		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7506			return ret;
7507		}
7508
7509		ret = jQuery.find.attr( elem, name );
7510
7511		// Non-existent attributes return null, we normalize to undefined
7512		return ret == null ? undefined : ret;
7513	},
7514
7515	attrHooks: {
7516		type: {
7517			set: function( elem, value ) {
7518				if ( !support.radioValue && value === "radio" &&
7519					jQuery.nodeName( elem, "input" ) ) {
7520					var val = elem.value;
7521					elem.setAttribute( "type", value );
7522					if ( val ) {
7523						elem.value = val;
7524					}
7525					return value;
7526				}
7527			}
7528		}
7529	},
7530
7531	removeAttr: function( elem, value ) {
7532		var name,
7533			i = 0,
7534
7535			// Attribute names can contain non-HTML whitespace characters
7536			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
7537			attrNames = value && value.match( rnothtmlwhite );
7538
7539		if ( attrNames && elem.nodeType === 1 ) {
7540			while ( ( name = attrNames[ i++ ] ) ) {
7541				elem.removeAttribute( name );
7542			}
7543		}
7544	}
7545} );
7546
7547// Hooks for boolean attributes
7548boolHook = {
7549	set: function( elem, value, name ) {
7550		if ( value === false ) {
7551
7552			// Remove boolean attributes when set to false
7553			jQuery.removeAttr( elem, name );
7554		} else {
7555			elem.setAttribute( name, name );
7556		}
7557		return name;
7558	}
7559};
7560
7561jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7562	var getter = attrHandle[ name ] || jQuery.find.attr;
7563
7564	attrHandle[ name ] = function( elem, name, isXML ) {
7565		var ret, handle,
7566			lowercaseName = name.toLowerCase();
7567
7568		if ( !isXML ) {
7569
7570			// Avoid an infinite loop by temporarily removing this function from the getter
7571			handle = attrHandle[ lowercaseName ];
7572			attrHandle[ lowercaseName ] = ret;
7573			ret = getter( elem, name, isXML ) != null ?
7574				lowercaseName :
7575				null;
7576			attrHandle[ lowercaseName ] = handle;
7577		}
7578		return ret;
7579	};
7580} );
7581
7582
7583
7584
7585var rfocusable = /^(?:input|select|textarea|button)$/i,
7586	rclickable = /^(?:a|area)$/i;
7587
7588jQuery.fn.extend( {
7589	prop: function( name, value ) {
7590		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7591	},
7592
7593	removeProp: function( name ) {
7594		return this.each( function() {
7595			delete this[ jQuery.propFix[ name ] || name ];
7596		} );
7597	}
7598} );
7599
7600jQuery.extend( {
7601	prop: function( elem, name, value ) {
7602		var ret, hooks,
7603			nType = elem.nodeType;
7604
7605		// Don't get/set properties on text, comment and attribute nodes
7606		if ( nType === 3 || nType === 8 || nType === 2 ) {
7607			return;
7608		}
7609
7610		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7611
7612			// Fix name and attach hooks
7613			name = jQuery.propFix[ name ] || name;
7614			hooks = jQuery.propHooks[ name ];
7615		}
7616
7617		if ( value !== undefined ) {
7618			if ( hooks && "set" in hooks &&
7619				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7620				return ret;
7621			}
7622
7623			return ( elem[ name ] = value );
7624		}
7625
7626		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7627			return ret;
7628		}
7629
7630		return elem[ name ];
7631	},
7632
7633	propHooks: {
7634		tabIndex: {
7635			get: function( elem ) {
7636
7637				// Support: IE <=9 - 11 only
7638				// elem.tabIndex doesn't always return the
7639				// correct value when it hasn't been explicitly set
7640				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7641				// Use proper attribute retrieval(#12072)
7642				var tabindex = jQuery.find.attr( elem, "tabindex" );
7643
7644				if ( tabindex ) {
7645					return parseInt( tabindex, 10 );
7646				}
7647
7648				if (
7649					rfocusable.test( elem.nodeName ) ||
7650					rclickable.test( elem.nodeName ) &&
7651					elem.href
7652				) {
7653					return 0;
7654				}
7655
7656				return -1;
7657			}
7658		}
7659	},
7660
7661	propFix: {
7662		"for": "htmlFor",
7663		"class": "className"
7664	}
7665} );
7666
7667// Support: IE <=11 only
7668// Accessing the selectedIndex property
7669// forces the browser to respect setting selected
7670// on the option
7671// The getter ensures a default option is selected
7672// when in an optgroup
7673// eslint rule "no-unused-expressions" is disabled for this code
7674// since it considers such accessions noop
7675if ( !support.optSelected ) {
7676	jQuery.propHooks.selected = {
7677		get: function( elem ) {
7678
7679			/* eslint no-unused-expressions: "off" */
7680
7681			var parent = elem.parentNode;
7682			if ( parent && parent.parentNode ) {
7683				parent.parentNode.selectedIndex;
7684			}
7685			return null;
7686		},
7687		set: function( elem ) {
7688
7689			/* eslint no-unused-expressions: "off" */
7690
7691			var parent = elem.parentNode;
7692			if ( parent ) {
7693				parent.selectedIndex;
7694
7695				if ( parent.parentNode ) {
7696					parent.parentNode.selectedIndex;
7697				}
7698			}
7699		}
7700	};
7701}
7702
7703jQuery.each( [
7704	"tabIndex",
7705	"readOnly",
7706	"maxLength",
7707	"cellSpacing",
7708	"cellPadding",
7709	"rowSpan",
7710	"colSpan",
7711	"useMap",
7712	"frameBorder",
7713	"contentEditable"
7714], function() {
7715	jQuery.propFix[ this.toLowerCase() ] = this;
7716} );
7717
7718
7719
7720
7721	// Strip and collapse whitespace according to HTML spec
7722	// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
7723	function stripAndCollapse( value ) {
7724		var tokens = value.match( rnothtmlwhite ) || [];
7725		return tokens.join( " " );
7726	}
7727
7728
7729function getClass( elem ) {
7730	return elem.getAttribute && elem.getAttribute( "class" ) || "";
7731}
7732
7733jQuery.fn.extend( {
7734	addClass: function( value ) {
7735		var classes, elem, cur, curValue, clazz, j, finalValue,
7736			i = 0;
7737
7738		if ( jQuery.isFunction( value ) ) {
7739			return this.each( function( j ) {
7740				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7741			} );
7742		}
7743
7744		if ( typeof value === "string" && value ) {
7745			classes = value.match( rnothtmlwhite ) || [];
7746
7747			while ( ( elem = this[ i++ ] ) ) {
7748				curValue = getClass( elem );
7749				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
7750
7751				if ( cur ) {
7752					j = 0;
7753					while ( ( clazz = classes[ j++ ] ) ) {
7754						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7755							cur += clazz + " ";
7756						}
7757					}
7758
7759					// Only assign if different to avoid unneeded rendering.
7760					finalValue = stripAndCollapse( cur );
7761					if ( curValue !== finalValue ) {
7762						elem.setAttribute( "class", finalValue );
7763					}
7764				}
7765			}
7766		}
7767
7768		return this;
7769	},
7770
7771	removeClass: function( value ) {
7772		var classes, elem, cur, curValue, clazz, j, finalValue,
7773			i = 0;
7774
7775		if ( jQuery.isFunction( value ) ) {
7776			return this.each( function( j ) {
7777				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7778			} );
7779		}
7780
7781		if ( !arguments.length ) {
7782			return this.attr( "class", "" );
7783		}
7784
7785		if ( typeof value === "string" && value ) {
7786			classes = value.match( rnothtmlwhite ) || [];
7787
7788			while ( ( elem = this[ i++ ] ) ) {
7789				curValue = getClass( elem );
7790
7791				// This expression is here for better compressibility (see addClass)
7792				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
7793
7794				if ( cur ) {
7795					j = 0;
7796					while ( ( clazz = classes[ j++ ] ) ) {
7797
7798						// Remove *all* instances
7799						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7800							cur = cur.replace( " " + clazz + " ", " " );
7801						}
7802					}
7803
7804					// Only assign if different to avoid unneeded rendering.
7805					finalValue = stripAndCollapse( cur );
7806					if ( curValue !== finalValue ) {
7807						elem.setAttribute( "class", finalValue );
7808					}
7809				}
7810			}
7811		}
7812
7813		return this;
7814	},
7815
7816	toggleClass: function( value, stateVal ) {
7817		var type = typeof value;
7818
7819		if ( typeof stateVal === "boolean" && type === "string" ) {
7820			return stateVal ? this.addClass( value ) : this.removeClass( value );
7821		}
7822
7823		if ( jQuery.isFunction( value ) ) {
7824			return this.each( function( i ) {
7825				jQuery( this ).toggleClass(
7826					value.call( this, i, getClass( this ), stateVal ),
7827					stateVal
7828				);
7829			} );
7830		}
7831
7832		return this.each( function() {
7833			var className, i, self, classNames;
7834
7835			if ( type === "string" ) {
7836
7837				// Toggle individual class names
7838				i = 0;
7839				self = jQuery( this );
7840				classNames = value.match( rnothtmlwhite ) || [];
7841
7842				while ( ( className = classNames[ i++ ] ) ) {
7843
7844					// Check each className given, space separated list
7845					if ( self.hasClass( className ) ) {
7846						self.removeClass( className );
7847					} else {
7848						self.addClass( className );
7849					}
7850				}
7851
7852			// Toggle whole class name
7853			} else if ( value === undefined || type === "boolean" ) {
7854				className = getClass( this );
7855				if ( className ) {
7856
7857					// Store className if set
7858					dataPriv.set( this, "__className__", className );
7859				}
7860
7861				// If the element has a class name or if we're passed `false`,
7862				// then remove the whole classname (if there was one, the above saved it).
7863				// Otherwise bring back whatever was previously saved (if anything),
7864				// falling back to the empty string if nothing was stored.
7865				if ( this.setAttribute ) {
7866					this.setAttribute( "class",
7867						className || value === false ?
7868						"" :
7869						dataPriv.get( this, "__className__" ) || ""
7870					);
7871				}
7872			}
7873		} );
7874	},
7875
7876	hasClass: function( selector ) {
7877		var className, elem,
7878			i = 0;
7879
7880		className = " " + selector + " ";
7881		while ( ( elem = this[ i++ ] ) ) {
7882			if ( elem.nodeType === 1 &&
7883				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
7884					return true;
7885			}
7886		}
7887
7888		return false;
vendor: 1,378 bytes, lines 7889-7958
7889	}
7890} );
7891
7892
7893
7894
7895var rreturn = /\r/g;
7896
7897jQuery.fn.extend( {
7898	val: function( value ) {
7899		var hooks, ret, isFunction,
7900			elem = this[ 0 ];
7901
7902		if ( !arguments.length ) {
7903			if ( elem ) {
7904				hooks = jQuery.valHooks[ elem.type ] ||
7905					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7906
7907				if ( hooks &&
7908					"get" in hooks &&
7909					( ret = hooks.get( elem, "value" ) ) !== undefined
7910				) {
7911					return ret;
7912				}
7913
7914				ret = elem.value;
7915
7916				// Handle most common string cases
7917				if ( typeof ret === "string" ) {
7918					return ret.replace( rreturn, "" );
7919				}
7920
7921				// Handle cases where value is null/undef or number
7922				return ret == null ? "" : ret;
7923			}
7924
7925			return;
7926		}
7927
7928		isFunction = jQuery.isFunction( value );
7929
7930		return this.each( function( i ) {
7931			var val;
7932
7933			if ( this.nodeType !== 1 ) {
7934				return;
7935			}
7936
7937			if ( isFunction ) {
7938				val = value.call( this, i, jQuery( this ).val() );
7939			} else {
7940				val = value;
7941			}
7942
7943			// Treat null/undefined as ""; convert numbers to string
7944			if ( val == null ) {
7945				val = "";
7946
7947			} else if ( typeof val === "number" ) {
7948				val += "";
7949
7950			} else if ( jQuery.isArray( val ) ) {
7951				val = jQuery.map( val, function( value ) {
7952					return value == null ? "" : value + "";
7953				} );
7954			}
7955
7956			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7957
7958			// If set returns undefined, fall back to normal setting
vendor: 8,168 bytes, lines 7959-8277
7959			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
7960				this.value = val;
7961			}
7962		} );
7963	}
7964} );
7965
7966jQuery.extend( {
7967	valHooks: {
7968		option: {
7969			get: function( elem ) {
7970
7971				var val = jQuery.find.attr( elem, "value" );
7972				return val != null ?
7973					val :
7974
7975					// Support: IE <=10 - 11 only
7976					// option.text throws exceptions (#14686, #14858)
7977					// Strip and collapse whitespace
7978					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
7979					stripAndCollapse( jQuery.text( elem ) );
7980			}
7981		},
7982		select: {
7983			get: function( elem ) {
7984				var value, option, i,
7985					options = elem.options,
7986					index = elem.selectedIndex,
7987					one = elem.type === "select-one",
7988					values = one ? null : [],
7989					max = one ? index + 1 : options.length;
7990
7991				if ( index < 0 ) {
7992					i = max;
7993
7994				} else {
7995					i = one ? index : 0;
7996				}
7997
7998				// Loop through all the selected options
7999				for ( ; i < max; i++ ) {
8000					option = options[ i ];
8001
8002					// Support: IE <=9 only
8003					// IE8-9 doesn't update selected after form reset (#2551)
8004					if ( ( option.selected || i === index ) &&
8005
8006							// Don't return options that are disabled or in a disabled optgroup
8007							!option.disabled &&
8008							( !option.parentNode.disabled ||
8009								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
8010
8011						// Get the specific value for the option
8012						value = jQuery( option ).val();
8013
8014						// We don't need an array for one selects
8015						if ( one ) {
8016							return value;
8017						}
8018
8019						// Multi-Selects return an array
8020						values.push( value );
8021					}
8022				}
8023
8024				return values;
8025			},
8026
8027			set: function( elem, value ) {
8028				var optionSet, option,
8029					options = elem.options,
8030					values = jQuery.makeArray( value ),
8031					i = options.length;
8032
8033				while ( i-- ) {
8034					option = options[ i ];
8035
8036					/* eslint-disable no-cond-assign */
8037
8038					if ( option.selected =
8039						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8040					) {
8041						optionSet = true;
8042					}
8043
8044					/* eslint-enable no-cond-assign */
8045				}
8046
8047				// Force browsers to behave consistently when non-matching value is set
8048				if ( !optionSet ) {
8049					elem.selectedIndex = -1;
8050				}
8051				return values;
8052			}
8053		}
8054	}
8055} );
8056
8057// Radios and checkboxes getter/setter
8058jQuery.each( [ "radio", "checkbox" ], function() {
8059	jQuery.valHooks[ this ] = {
8060		set: function( elem, value ) {
8061			if ( jQuery.isArray( value ) ) {
8062				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8063			}
8064		}
8065	};
8066	if ( !support.checkOn ) {
8067		jQuery.valHooks[ this ].get = function( elem ) {
8068			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8069		};
8070	}
8071} );
8072
8073
8074
8075
8076// Return jQuery for attributes-only inclusion
8077
8078
8079var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
8080
8081jQuery.extend( jQuery.event, {
8082
8083	trigger: function( event, data, elem, onlyHandlers ) {
8084
8085		var i, cur, tmp, bubbleType, ontype, handle, special,
8086			eventPath = [ elem || document ],
8087			type = hasOwn.call( event, "type" ) ? event.type : event,
8088			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8089
8090		cur = tmp = elem = elem || document;
8091
8092		// Don't do events on text and comment nodes
8093		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8094			return;
8095		}
8096
8097		// focus/blur morphs to focusin/out; ensure we're not firing them right now
8098		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8099			return;
8100		}
8101
8102		if ( type.indexOf( "." ) > -1 ) {
8103
8104			// Namespaced trigger; create a regexp to match event type in handle()
8105			namespaces = type.split( "." );
8106			type = namespaces.shift();
8107			namespaces.sort();
8108		}
8109		ontype = type.indexOf( ":" ) < 0 && "on" + type;
8110
8111		// Caller can pass in a jQuery.Event object, Object, or just an event type string
8112		event = event[ jQuery.expando ] ?
8113			event :
8114			new jQuery.Event( type, typeof event === "object" && event );
8115
8116		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8117		event.isTrigger = onlyHandlers ? 2 : 3;
8118		event.namespace = namespaces.join( "." );
8119		event.rnamespace = event.namespace ?
8120			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8121			null;
8122
8123		// Clean up the event in case it is being reused
8124		event.result = undefined;
8125		if ( !event.target ) {
8126			event.target = elem;
8127		}
8128
8129		// Clone any incoming data and prepend the event, creating the handler arg list
8130		data = data == null ?
8131			[ event ] :
8132			jQuery.makeArray( data, [ event ] );
8133
8134		// Allow special events to draw outside the lines
8135		special = jQuery.event.special[ type ] || {};
8136		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8137			return;
8138		}
8139
8140		// Determine event propagation path in advance, per W3C events spec (#9951)
8141		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8142		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
8143
8144			bubbleType = special.delegateType || type;
8145			if ( !rfocusMorph.test( bubbleType + type ) ) {
8146				cur = cur.parentNode;
8147			}
8148			for ( ; cur; cur = cur.parentNode ) {
8149				eventPath.push( cur );
8150				tmp = cur;
8151			}
8152
8153			// Only add window if we got to document (e.g., not plain obj or detached DOM)
8154			if ( tmp === ( elem.ownerDocument || document ) ) {
8155				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8156			}
8157		}
8158
8159		// Fire handlers on the event path
8160		i = 0;
8161		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8162
8163			event.type = i > 1 ?
8164				bubbleType :
8165				special.bindType || type;
8166
8167			// jQuery handler
8168			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
8169				dataPriv.get( cur, "handle" );
8170			if ( handle ) {
8171				handle.apply( cur, data );
8172			}
8173
8174			// Native handler
8175			handle = ontype && cur[ ontype ];
8176			if ( handle && handle.apply && acceptData( cur ) ) {
8177				event.result = handle.apply( cur, data );
8178				if ( event.result === false ) {
8179					event.preventDefault();
8180				}
8181			}
8182		}
8183		event.type = type;
8184
8185		// If nobody prevented the default action, do it now
8186		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8187
8188			if ( ( !special._default ||
8189				special._default.apply( eventPath.pop(), data ) === false ) &&
8190				acceptData( elem ) ) {
8191
8192				// Call a native DOM method on the target with the same name as the event.
8193				// Don't do default actions on window, that's where global variables be (#6170)
8194				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
8195
8196					// Don't re-trigger an onFOO event when we call its FOO() method
8197					tmp = elem[ ontype ];
8198
8199					if ( tmp ) {
8200						elem[ ontype ] = null;
8201					}
8202
8203					// Prevent re-triggering of the same event, since we already bubbled it above
8204					jQuery.event.triggered = type;
8205					elem[ type ]();
8206					jQuery.event.triggered = undefined;
8207
8208					if ( tmp ) {
8209						elem[ ontype ] = tmp;
8210					}
8211				}
8212			}
8213		}
8214
8215		return event.result;
8216	},
8217
8218	// Piggyback on a donor event to simulate a different one
8219	// Used only for `focus(in | out)` events
8220	simulate: function( type, elem, event ) {
8221		var e = jQuery.extend(
8222			new jQuery.Event(),
8223			event,
8224			{
8225				type: type,
8226				isSimulated: true
8227			}
8228		);
8229
8230		jQuery.event.trigger( e, null, elem );
8231	}
8232
8233} );
8234
8235jQuery.fn.extend( {
8236
8237	trigger: function( type, data ) {
8238		return this.each( function() {
8239			jQuery.event.trigger( type, data, this );
8240		} );
8241	},
8242	triggerHandler: function( type, data ) {
8243		var elem = this[ 0 ];
8244		if ( elem ) {
8245			return jQuery.event.trigger( type, data, elem, true );
8246		}
8247	}
8248} );
8249
8250
8251jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
8252	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8253	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
8254	function( i, name ) {
8255
8256	// Handle event binding
8257	jQuery.fn[ name ] = function( data, fn ) {
8258		return arguments.length > 0 ?
8259			this.on( name, null, data, fn ) :
8260			this.trigger( name );
8261	};
8262} );
8263
8264jQuery.fn.extend( {
8265	hover: function( fnOver, fnOut ) {
8266		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8267	}
8268} );
8269
8270
8271
8272
8273support.focusin = "onfocusin" in window;
8274
8275
8276// Support: Firefox <=44
8277// Firefox doesn't have focus(in | out) events
vendor: 4,176 bytes, lines 8278-8441
8278// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8279//
8280// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8281// focus(in | out) events fire after focus & blur events,
8282// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8283// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8284if ( !support.focusin ) {
8285	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8286
8287		// Attach a single capturing handler on the document while someone wants focusin/focusout
8288		var handler = function( event ) {
8289			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8290		};
8291
8292		jQuery.event.special[ fix ] = {
8293			setup: function() {
8294				var doc = this.ownerDocument || this,
8295					attaches = dataPriv.access( doc, fix );
8296
8297				if ( !attaches ) {
8298					doc.addEventListener( orig, handler, true );
8299				}
8300				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8301			},
8302			teardown: function() {
8303				var doc = this.ownerDocument || this,
8304					attaches = dataPriv.access( doc, fix ) - 1;
8305
8306				if ( !attaches ) {
8307					doc.removeEventListener( orig, handler, true );
8308					dataPriv.remove( doc, fix );
8309
8310				} else {
8311					dataPriv.access( doc, fix, attaches );
8312				}
8313			}
8314		};
8315	} );
8316}
8317var location = window.location;
8318
8319var nonce = jQuery.now();
8320
8321var rquery = ( /\?/ );
8322
8323
8324
8325// Cross-browser xml parsing
8326jQuery.parseXML = function( data ) {
8327	var xml;
8328	if ( !data || typeof data !== "string" ) {
8329		return null;
8330	}
8331
8332	// Support: IE 9 - 11 only
8333	// IE throws on parseFromString with invalid input.
8334	try {
8335		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8336	} catch ( e ) {
8337		xml = undefined;
8338	}
8339
8340	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
8341		jQuery.error( "Invalid XML: " + data );
8342	}
8343	return xml;
8344};
8345
8346
8347var
8348	rbracket = /\[\]$/,
8349	rCRLF = /\r?\n/g,
8350	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8351	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8352
8353function buildParams( prefix, obj, traditional, add ) {
8354	var name;
8355
8356	if ( jQuery.isArray( obj ) ) {
8357
8358		// Serialize array item.
8359		jQuery.each( obj, function( i, v ) {
8360			if ( traditional || rbracket.test( prefix ) ) {
8361
8362				// Treat each array item as a scalar.
8363				add( prefix, v );
8364
8365			} else {
8366
8367				// Item is non-scalar (array or object), encode its numeric index.
8368				buildParams(
8369					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8370					v,
8371					traditional,
8372					add
8373				);
8374			}
8375		} );
8376
8377	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
8378
8379		// Serialize object item.
8380		for ( name in obj ) {
8381			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8382		}
8383
8384	} else {
8385
8386		// Serialize scalar item.
8387		add( prefix, obj );
8388	}
8389}
8390
8391// Serialize an array of form elements or a set of
8392// key/values into a query string
8393jQuery.param = function( a, traditional ) {
8394	var prefix,
8395		s = [],
8396		add = function( key, valueOrFunction ) {
8397
8398			// If value is a function, invoke it and use its return value
8399			var value = jQuery.isFunction( valueOrFunction ) ?
8400				valueOrFunction() :
8401				valueOrFunction;
8402
8403			s[ s.length ] = encodeURIComponent( key ) + "=" +
8404				encodeURIComponent( value == null ? "" : value );
8405		};
8406
8407	// If an array was passed in, assume that it is an array of form elements.
8408	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8409
8410		// Serialize the form elements
8411		jQuery.each( a, function() {
8412			add( this.name, this.value );
8413		} );
8414
8415	} else {
8416
8417		// If traditional, encode the "old" way (the way 1.3.2 or older
8418		// did it), otherwise encode params recursively.
8419		for ( prefix in a ) {
8420			buildParams( prefix, a[ prefix ], traditional, add );
8421		}
8422	}
8423
8424	// Return the resulting serialization
8425	return s.join( "&" );
8426};
8427
8428jQuery.fn.extend( {
8429	serialize: function() {
8430		return jQuery.param( this.serializeArray() );
8431	},
8432	serializeArray: function() {
8433		return this.map( function() {
8434
8435			// Can add propHook for "elements" to filter or add form elements
8436			var elements = jQuery.prop( this, "elements" );
8437			return elements ? jQuery.makeArray( elements ) : this;
8438		} )
8439		.filter( function() {
8440			var type = this.type;
8441
vendor: 4,940 bytes, lines 8442-8614
8442			// Use .is( ":disabled" ) so that fieldset[disabled] works
8443			return this.name && !jQuery( this ).is( ":disabled" ) &&
8444				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8445				( this.checked || !rcheckableType.test( type ) );
8446		} )
8447		.map( function( i, elem ) {
8448			var val = jQuery( this ).val();
8449
8450			if ( val == null ) {
8451				return null;
8452			}
8453
8454			if ( jQuery.isArray( val ) ) {
8455				return jQuery.map( val, function( val ) {
8456					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8457				} );
8458			}
8459
8460			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8461		} ).get();
8462	}
8463} );
8464
8465
8466var
8467	r20 = /%20/g,
8468	rhash = /#.*$/,
8469	rantiCache = /([?&])_=[^&]*/,
8470	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8471
8472	// #7653, #8125, #8152: local protocol detection
8473	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8474	rnoContent = /^(?:GET|HEAD)$/,
8475	rprotocol = /^\/\//,
8476
8477	/* Prefilters
8478	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8479	 * 2) These are called:
8480	 *    - BEFORE asking for a transport
8481	 *    - AFTER param serialization (s.data is a string if s.processData is true)
8482	 * 3) key is the dataType
8483	 * 4) the catchall symbol "*" can be used
8484	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8485	 */
8486	prefilters = {},
8487
8488	/* Transports bindings
8489	 * 1) key is the dataType
8490	 * 2) the catchall symbol "*" can be used
8491	 * 3) selection will start with transport dataType and THEN go to "*" if needed
8492	 */
8493	transports = {},
8494
8495	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8496	allTypes = "*/".concat( "*" ),
8497
8498	// Anchor tag for parsing the document origin
8499	originAnchor = document.createElement( "a" );
8500	originAnchor.href = location.href;
8501
8502// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8503function addToPrefiltersOrTransports( structure ) {
8504
8505	// dataTypeExpression is optional and defaults to "*"
8506	return function( dataTypeExpression, func ) {
8507
8508		if ( typeof dataTypeExpression !== "string" ) {
8509			func = dataTypeExpression;
8510			dataTypeExpression = "*";
8511		}
8512
8513		var dataType,
8514			i = 0,
8515			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
8516
8517		if ( jQuery.isFunction( func ) ) {
8518
8519			// For each dataType in the dataTypeExpression
8520			while ( ( dataType = dataTypes[ i++ ] ) ) {
8521
8522				// Prepend if requested
8523				if ( dataType[ 0 ] === "+" ) {
8524					dataType = dataType.slice( 1 ) || "*";
8525					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8526
8527				// Otherwise append
8528				} else {
8529					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8530				}
8531			}
8532		}
8533	};
8534}
8535
8536// Base inspection function for prefilters and transports
8537function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8538
8539	var inspected = {},
8540		seekingTransport = ( structure === transports );
8541
8542	function inspect( dataType ) {
8543		var selected;
8544		inspected[ dataType ] = true;
8545		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8546			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8547			if ( typeof dataTypeOrTransport === "string" &&
8548				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8549
8550				options.dataTypes.unshift( dataTypeOrTransport );
8551				inspect( dataTypeOrTransport );
8552				return false;
8553			} else if ( seekingTransport ) {
8554				return !( selected = dataTypeOrTransport );
8555			}
8556		} );
8557		return selected;
8558	}
8559
8560	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8561}
8562
8563// A special extend for ajax options
8564// that takes "flat" options (not to be deep extended)
8565// Fixes #9887
8566function ajaxExtend( target, src ) {
8567	var key, deep,
8568		flatOptions = jQuery.ajaxSettings.flatOptions || {};
8569
8570	for ( key in src ) {
8571		if ( src[ key ] !== undefined ) {
8572			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8573		}
8574	}
8575	if ( deep ) {
8576		jQuery.extend( true, target, deep );
8577	}
8578
8579	return target;
8580}
8581
8582/* Handles responses to an ajax request:
8583 * - finds the right dataType (mediates between content-type and expected dataType)
8584 * - returns the corresponding response
8585 */
8586function ajaxHandleResponses( s, jqXHR, responses ) {
8587
8588	var ct, type, finalDataType, firstDataType,
8589		contents = s.contents,
8590		dataTypes = s.dataTypes;
8591
8592	// Remove auto dataType and get content-type in the process
8593	while ( dataTypes[ 0 ] === "*" ) {
8594		dataTypes.shift();
8595		if ( ct === undefined ) {
8596			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8597		}
8598	}
8599
8600	// Check if we're dealing with a known content-type
8601	if ( ct ) {
8602		for ( type in contents ) {
8603			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8604				dataTypes.unshift( type );
8605				break;
8606			}
8607		}
8608	}
8609
8610	// Check to see if we have a response for the expected dataType
8611	if ( dataTypes[ 0 ] in responses ) {
8612		finalDataType = dataTypes[ 0 ];
8613	} else {
8614
vendor: 18,932 bytes, lines 8615-9372
8615		// Try convertible dataTypes
8616		for ( type in responses ) {
8617			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8618				finalDataType = type;
8619				break;
8620			}
8621			if ( !firstDataType ) {
8622				firstDataType = type;
8623			}
8624		}
8625
8626		// Or just use first one
8627		finalDataType = finalDataType || firstDataType;
8628	}
8629
8630	// If we found a dataType
8631	// We add the dataType to the list if needed
8632	// and return the corresponding response
8633	if ( finalDataType ) {
8634		if ( finalDataType !== dataTypes[ 0 ] ) {
8635			dataTypes.unshift( finalDataType );
8636		}
8637		return responses[ finalDataType ];
8638	}
8639}
8640
8641/* Chain conversions given the request and the original response
8642 * Also sets the responseXXX fields on the jqXHR instance
8643 */
8644function ajaxConvert( s, response, jqXHR, isSuccess ) {
8645	var conv2, current, conv, tmp, prev,
8646		converters = {},
8647
8648		// Work with a copy of dataTypes in case we need to modify it for conversion
8649		dataTypes = s.dataTypes.slice();
8650
8651	// Create converters map with lowercased keys
8652	if ( dataTypes[ 1 ] ) {
8653		for ( conv in s.converters ) {
8654			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8655		}
8656	}
8657
8658	current = dataTypes.shift();
8659
8660	// Convert to each sequential dataType
8661	while ( current ) {
8662
8663		if ( s.responseFields[ current ] ) {
8664			jqXHR[ s.responseFields[ current ] ] = response;
8665		}
8666
8667		// Apply the dataFilter if provided
8668		if ( !prev && isSuccess && s.dataFilter ) {
8669			response = s.dataFilter( response, s.dataType );
8670		}
8671
8672		prev = current;
8673		current = dataTypes.shift();
8674
8675		if ( current ) {
8676
8677			// There's only work to do if current dataType is non-auto
8678			if ( current === "*" ) {
8679
8680				current = prev;
8681
8682			// Convert response if prev dataType is non-auto and differs from current
8683			} else if ( prev !== "*" && prev !== current ) {
8684
8685				// Seek a direct converter
8686				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8687
8688				// If none found, seek a pair
8689				if ( !conv ) {
8690					for ( conv2 in converters ) {
8691
8692						// If conv2 outputs current
8693						tmp = conv2.split( " " );
8694						if ( tmp[ 1 ] === current ) {
8695
8696							// If prev can be converted to accepted input
8697							conv = converters[ prev + " " + tmp[ 0 ] ] ||
8698								converters[ "* " + tmp[ 0 ] ];
8699							if ( conv ) {
8700
8701								// Condense equivalence converters
8702								if ( conv === true ) {
8703									conv = converters[ conv2 ];
8704
8705								// Otherwise, insert the intermediate dataType
8706								} else if ( converters[ conv2 ] !== true ) {
8707									current = tmp[ 0 ];
8708									dataTypes.unshift( tmp[ 1 ] );
8709								}
8710								break;
8711							}
8712						}
8713					}
8714				}
8715
8716				// Apply converter (if not an equivalence)
8717				if ( conv !== true ) {
8718
8719					// Unless errors are allowed to bubble, catch and return them
8720					if ( conv && s.throws ) {
8721						response = conv( response );
8722					} else {
8723						try {
8724							response = conv( response );
8725						} catch ( e ) {
8726							return {
8727								state: "parsererror",
8728								error: conv ? e : "No conversion from " + prev + " to " + current
8729							};
8730						}
8731					}
8732				}
8733			}
8734		}
8735	}
8736
8737	return { state: "success", data: response };
8738}
8739
8740jQuery.extend( {
8741
8742	// Counter for holding the number of active queries
8743	active: 0,
8744
8745	// Last-Modified header cache for next request
8746	lastModified: {},
8747	etag: {},
8748
8749	ajaxSettings: {
8750		url: location.href,
8751		type: "GET",
8752		isLocal: rlocalProtocol.test( location.protocol ),
8753		global: true,
8754		processData: true,
8755		async: true,
8756		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8757
8758		/*
8759		timeout: 0,
8760		data: null,
8761		dataType: null,
8762		username: null,
8763		password: null,
8764		cache: null,
8765		throws: false,
8766		traditional: false,
8767		headers: {},
8768		*/
8769
8770		accepts: {
8771			"*": allTypes,
8772			text: "text/plain",
8773			html: "text/html",
8774			xml: "application/xml, text/xml",
8775			json: "application/json, text/javascript"
8776		},
8777
8778		contents: {
8779			xml: /\bxml\b/,
8780			html: /\bhtml/,
8781			json: /\bjson\b/
8782		},
8783
8784		responseFields: {
8785			xml: "responseXML",
8786			text: "responseText",
8787			json: "responseJSON"
8788		},
8789
8790		// Data converters
8791		// Keys separate source (or catchall "*") and destination types with a single space
8792		converters: {
8793
8794			// Convert anything to text
8795			"* text": String,
8796
8797			// Text to html (true = no transformation)
8798			"text html": true,
8799
8800			// Evaluate text as a json expression
8801			"text json": JSON.parse,
8802
8803			// Parse text as xml
8804			"text xml": jQuery.parseXML
8805		},
8806
8807		// For options that shouldn't be deep extended:
8808		// you can add your own custom options here if
8809		// and when you create one that shouldn't be
8810		// deep extended (see ajaxExtend)
8811		flatOptions: {
8812			url: true,
8813			context: true
8814		}
8815	},
8816
8817	// Creates a full fledged settings object into target
8818	// with both ajaxSettings and settings fields.
8819	// If target is omitted, writes into ajaxSettings.
8820	ajaxSetup: function( target, settings ) {
8821		return settings ?
8822
8823			// Building a settings object
8824			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8825
8826			// Extending ajaxSettings
8827			ajaxExtend( jQuery.ajaxSettings, target );
8828	},
8829
8830	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8831	ajaxTransport: addToPrefiltersOrTransports( transports ),
8832
8833	// Main method
8834	ajax: function( url, options ) {
8835
8836		// If url is an object, simulate pre-1.5 signature
8837		if ( typeof url === "object" ) {
8838			options = url;
8839			url = undefined;
8840		}
8841
8842		// Force options to be an object
8843		options = options || {};
8844
8845		var transport,
8846
8847			// URL without anti-cache param
8848			cacheURL,
8849
8850			// Response headers
8851			responseHeadersString,
8852			responseHeaders,
8853
8854			// timeout handle
8855			timeoutTimer,
8856
8857			// Url cleanup var
8858			urlAnchor,
8859
8860			// Request state (becomes false upon send and true upon completion)
8861			completed,
8862
8863			// To know if global events are to be dispatched
8864			fireGlobals,
8865
8866			// Loop variable
8867			i,
8868
8869			// uncached part of the url
8870			uncached,
8871
8872			// Create the final options object
8873			s = jQuery.ajaxSetup( {}, options ),
8874
8875			// Callbacks context
8876			callbackContext = s.context || s,
8877
8878			// Context for global events is callbackContext if it is a DOM node or jQuery collection
8879			globalEventContext = s.context &&
8880				( callbackContext.nodeType || callbackContext.jquery ) ?
8881					jQuery( callbackContext ) :
8882					jQuery.event,
8883
8884			// Deferreds
8885			deferred = jQuery.Deferred(),
8886			completeDeferred = jQuery.Callbacks( "once memory" ),
8887
8888			// Status-dependent callbacks
8889			statusCode = s.statusCode || {},
8890
8891			// Headers (they are sent all at once)
8892			requestHeaders = {},
8893			requestHeadersNames = {},
8894
8895			// Default abort message
8896			strAbort = "canceled",
8897
8898			// Fake xhr
8899			jqXHR = {
8900				readyState: 0,
8901
8902				// Builds headers hashtable if needed
8903				getResponseHeader: function( key ) {
8904					var match;
8905					if ( completed ) {
8906						if ( !responseHeaders ) {
8907							responseHeaders = {};
8908							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8909								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8910							}
8911						}
8912						match = responseHeaders[ key.toLowerCase() ];
8913					}
8914					return match == null ? null : match;
8915				},
8916
8917				// Raw string
8918				getAllResponseHeaders: function() {
8919					return completed ? responseHeadersString : null;
8920				},
8921
8922				// Caches the header
8923				setRequestHeader: function( name, value ) {
8924					if ( completed == null ) {
8925						name = requestHeadersNames[ name.toLowerCase() ] =
8926							requestHeadersNames[ name.toLowerCase() ] || name;
8927						requestHeaders[ name ] = value;
8928					}
8929					return this;
8930				},
8931
8932				// Overrides response content-type header
8933				overrideMimeType: function( type ) {
8934					if ( completed == null ) {
8935						s.mimeType = type;
8936					}
8937					return this;
8938				},
8939
8940				// Status-dependent callbacks
8941				statusCode: function( map ) {
8942					var code;
8943					if ( map ) {
8944						if ( completed ) {
8945
8946							// Execute the appropriate callbacks
8947							jqXHR.always( map[ jqXHR.status ] );
8948						} else {
8949
8950							// Lazy-add the new callbacks in a way that preserves old ones
8951							for ( code in map ) {
8952								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8953							}
8954						}
8955					}
8956					return this;
8957				},
8958
8959				// Cancel the request
8960				abort: function( statusText ) {
8961					var finalText = statusText || strAbort;
8962					if ( transport ) {
8963						transport.abort( finalText );
8964					}
8965					done( 0, finalText );
8966					return this;
8967				}
8968			};
8969
8970		// Attach deferreds
8971		deferred.promise( jqXHR );
8972
8973		// Add protocol if not provided (prefilters might expect it)
8974		// Handle falsy url in the settings object (#10093: consistency with old signature)
8975		// We also use the url parameter if available
8976		s.url = ( ( url || s.url || location.href ) + "" )
8977			.replace( rprotocol, location.protocol + "//" );
8978
8979		// Alias method option to type as per ticket #12004
8980		s.type = options.method || options.type || s.method || s.type;
8981
8982		// Extract dataTypes list
8983		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
8984
8985		// A cross-domain request is in order when the origin doesn't match the current origin.
8986		if ( s.crossDomain == null ) {
8987			urlAnchor = document.createElement( "a" );
8988
8989			// Support: IE <=8 - 11, Edge 12 - 13
8990			// IE throws exception on accessing the href property if url is malformed,
8991			// e.g. http://example.com:80x/
8992			try {
8993				urlAnchor.href = s.url;
8994
8995				// Support: IE <=8 - 11 only
8996				// Anchor's host property isn't correctly set when s.url is relative
8997				urlAnchor.href = urlAnchor.href;
8998				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
8999					urlAnchor.protocol + "//" + urlAnchor.host;
9000			} catch ( e ) {
9001
9002				// If there is an error parsing the URL, assume it is crossDomain,
9003				// it can be rejected by the transport if it is invalid
9004				s.crossDomain = true;
9005			}
9006		}
9007
9008		// Convert data if not already a string
9009		if ( s.data && s.processData && typeof s.data !== "string" ) {
9010			s.data = jQuery.param( s.data, s.traditional );
9011		}
9012
9013		// Apply prefilters
9014		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9015
9016		// If request was aborted inside a prefilter, stop there
9017		if ( completed ) {
9018			return jqXHR;
9019		}
9020
9021		// We can fire global events as of now if asked to
9022		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9023		fireGlobals = jQuery.event && s.global;
9024
9025		// Watch for a new set of requests
9026		if ( fireGlobals && jQuery.active++ === 0 ) {
9027			jQuery.event.trigger( "ajaxStart" );
9028		}
9029
9030		// Uppercase the type
9031		s.type = s.type.toUpperCase();
9032
9033		// Determine if request has content
9034		s.hasContent = !rnoContent.test( s.type );
9035
9036		// Save the URL in case we're toying with the If-Modified-Since
9037		// and/or If-None-Match header later on
9038		// Remove hash to simplify url manipulation
9039		cacheURL = s.url.replace( rhash, "" );
9040
9041		// More options handling for requests with no content
9042		if ( !s.hasContent ) {
9043
9044			// Remember the hash so we can put it back
9045			uncached = s.url.slice( cacheURL.length );
9046
9047			// If data is available, append data to url
9048			if ( s.data ) {
9049				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9050
9051				// #9682: remove data so that it's not used in an eventual retry
9052				delete s.data;
9053			}
9054
9055			// Add or update anti-cache param if needed
9056			if ( s.cache === false ) {
9057				cacheURL = cacheURL.replace( rantiCache, "$1" );
9058				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
9059			}
9060
9061			// Put hash and anti-cache on the URL that will be requested (gh-1732)
9062			s.url = cacheURL + uncached;
9063
9064		// Change '%20' to '+' if this is encoded form body content (gh-2658)
9065		} else if ( s.data && s.processData &&
9066			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9067			s.data = s.data.replace( r20, "+" );
9068		}
9069
9070		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9071		if ( s.ifModified ) {
9072			if ( jQuery.lastModified[ cacheURL ] ) {
9073				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9074			}
9075			if ( jQuery.etag[ cacheURL ] ) {
9076				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9077			}
9078		}
9079
9080		// Set the correct header, if data is being sent
9081		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9082			jqXHR.setRequestHeader( "Content-Type", s.contentType );
9083		}
9084
9085		// Set the Accepts header for the server, depending on the dataType
9086		jqXHR.setRequestHeader(
9087			"Accept",
9088			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9089				s.accepts[ s.dataTypes[ 0 ] ] +
9090					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9091				s.accepts[ "*" ]
9092		);
9093
9094		// Check for headers option
9095		for ( i in s.headers ) {
9096			jqXHR.setRequestHeader( i, s.headers[ i ] );
9097		}
9098
9099		// Allow custom headers/mimetypes and early abort
9100		if ( s.beforeSend &&
9101			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9102
9103			// Abort if not done already and return
9104			return jqXHR.abort();
9105		}
9106
9107		// Aborting is no longer a cancellation
9108		strAbort = "abort";
9109
9110		// Install callbacks on deferreds
9111		completeDeferred.add( s.complete );
9112		jqXHR.done( s.success );
9113		jqXHR.fail( s.error );
9114
9115		// Get transport
9116		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9117
9118		// If no transport, we auto-abort
9119		if ( !transport ) {
9120			done( -1, "No Transport" );
9121		} else {
9122			jqXHR.readyState = 1;
9123
9124			// Send global event
9125			if ( fireGlobals ) {
9126				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9127			}
9128
9129			// If request was aborted inside ajaxSend, stop there
9130			if ( completed ) {
9131				return jqXHR;
9132			}
9133
9134			// Timeout
9135			if ( s.async && s.timeout > 0 ) {
9136				timeoutTimer = window.setTimeout( function() {
9137					jqXHR.abort( "timeout" );
9138				}, s.timeout );
9139			}
9140
9141			try {
9142				completed = false;
9143				transport.send( requestHeaders, done );
9144			} catch ( e ) {
9145
9146				// Rethrow post-completion exceptions
9147				if ( completed ) {
9148					throw e;
9149				}
9150
9151				// Propagate others as results
9152				done( -1, e );
9153			}
9154		}
9155
9156		// Callback for when everything is done
9157		function done( status, nativeStatusText, responses, headers ) {
9158			var isSuccess, success, error, response, modified,
9159				statusText = nativeStatusText;
9160
9161			// Ignore repeat invocations
9162			if ( completed ) {
9163				return;
9164			}
9165
9166			completed = true;
9167
9168			// Clear timeout if it exists
9169			if ( timeoutTimer ) {
9170				window.clearTimeout( timeoutTimer );
9171			}
9172
9173			// Dereference transport for early garbage collection
9174			// (no matter how long the jqXHR object will be used)
9175			transport = undefined;
9176
9177			// Cache response headers
9178			responseHeadersString = headers || "";
9179
9180			// Set readyState
9181			jqXHR.readyState = status > 0 ? 4 : 0;
9182
9183			// Determine if successful
9184			isSuccess = status >= 200 && status < 300 || status === 304;
9185
9186			// Get response data
9187			if ( responses ) {
9188				response = ajaxHandleResponses( s, jqXHR, responses );
9189			}
9190
9191			// Convert no matter what (that way responseXXX fields are always set)
9192			response = ajaxConvert( s, response, jqXHR, isSuccess );
9193
9194			// If successful, handle type chaining
9195			if ( isSuccess ) {
9196
9197				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9198				if ( s.ifModified ) {
9199					modified = jqXHR.getResponseHeader( "Last-Modified" );
9200					if ( modified ) {
9201						jQuery.lastModified[ cacheURL ] = modified;
9202					}
9203					modified = jqXHR.getResponseHeader( "etag" );
9204					if ( modified ) {
9205						jQuery.etag[ cacheURL ] = modified;
9206					}
9207				}
9208
9209				// if no content
9210				if ( status === 204 || s.type === "HEAD" ) {
9211					statusText = "nocontent";
9212
9213				// if not modified
9214				} else if ( status === 304 ) {
9215					statusText = "notmodified";
9216
9217				// If we have data, let's convert it
9218				} else {
9219					statusText = response.state;
9220					success = response.data;
9221					error = response.error;
9222					isSuccess = !error;
9223				}
9224			} else {
9225
9226				// Extract error from statusText and normalize for non-aborts
9227				error = statusText;
9228				if ( status || !statusText ) {
9229					statusText = "error";
9230					if ( status < 0 ) {
9231						status = 0;
9232					}
9233				}
9234			}
9235
9236			// Set data for the fake xhr object
9237			jqXHR.status = status;
9238			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9239
9240			// Success/Error
9241			if ( isSuccess ) {
9242				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9243			} else {
9244				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9245			}
9246
9247			// Status-dependent callbacks
9248			jqXHR.statusCode( statusCode );
9249			statusCode = undefined;
9250
9251			if ( fireGlobals ) {
9252				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9253					[ jqXHR, s, isSuccess ? success : error ] );
9254			}
9255
9256			// Complete
9257			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9258
9259			if ( fireGlobals ) {
9260				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9261
9262				// Handle the global AJAX counter
9263				if ( !( --jQuery.active ) ) {
9264					jQuery.event.trigger( "ajaxStop" );
9265				}
9266			}
9267		}
9268
9269		return jqXHR;
9270	},
9271
9272	getJSON: function( url, data, callback ) {
9273		return jQuery.get( url, data, callback, "json" );
9274	},
9275
9276	getScript: function( url, callback ) {
9277		return jQuery.get( url, undefined, callback, "script" );
9278	}
9279} );
9280
9281jQuery.each( [ "get", "post" ], function( i, method ) {
9282	jQuery[ method ] = function( url, data, callback, type ) {
9283
9284		// Shift arguments if data argument was omitted
9285		if ( jQuery.isFunction( data ) ) {
9286			type = type || callback;
9287			callback = data;
9288			data = undefined;
9289		}
9290
9291		// The url can be an options object (which then must have .url)
9292		return jQuery.ajax( jQuery.extend( {
9293			url: url,
9294			type: method,
9295			dataType: type,
9296			data: data,
9297			success: callback
9298		}, jQuery.isPlainObject( url ) && url ) );
9299	};
9300} );
9301
9302
9303jQuery._evalUrl = function( url ) {
9304	return jQuery.ajax( {
9305		url: url,
9306
9307		// Make this explicit, since user can override this through ajaxSetup (#11264)
9308		type: "GET",
9309		dataType: "script",
9310		cache: true,
9311		async: false,
9312		global: false,
9313		"throws": true
9314	} );
9315};
9316
9317
9318jQuery.fn.extend( {
9319	wrapAll: function( html ) {
9320		var wrap;
9321
9322		if ( this[ 0 ] ) {
9323			if ( jQuery.isFunction( html ) ) {
9324				html = html.call( this[ 0 ] );
9325			}
9326
9327			// The elements to wrap the target around
9328			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9329
9330			if ( this[ 0 ].parentNode ) {
9331				wrap.insertBefore( this[ 0 ] );
9332			}
9333
9334			wrap.map( function() {
9335				var elem = this;
9336
9337				while ( elem.firstElementChild ) {
9338					elem = elem.firstElementChild;
9339				}
9340
9341				return elem;
9342			} ).append( this );
9343		}
9344
9345		return this;
9346	},
9347
9348	wrapInner: function( html ) {
9349		if ( jQuery.isFunction( html ) ) {
9350			return this.each( function( i ) {
9351				jQuery( this ).wrapInner( html.call( this, i ) );
9352			} );
9353		}
9354
9355		return this.each( function() {
9356			var self = jQuery( this ),
9357				contents = self.contents();
9358
9359			if ( contents.length ) {
9360				contents.wrapAll( html );
9361
9362			} else {
9363				self.append( html );
9364			}
9365		} );
9366	},
9367
9368	wrap: function( html ) {
9369		var isFunction = jQuery.isFunction( html );
9370
9371		return this.each( function( i ) {
9372			jQuery( this ).wrapAll( i
vendor: 2,399 bytes, lines 9372-9464
9372sFunction ? html.call( this, i ) : html );
9373		} );
9374	},
9375
9376	unwrap: function( selector ) {
9377		this.parent( selector ).not( "body" ).each( function() {
9378			jQuery( this ).replaceWith( this.childNodes );
9379		} );
9380		return this;
9381	}
9382} );
9383
9384
9385jQuery.expr.pseudos.hidden = function( elem ) {
9386	return !jQuery.expr.pseudos.visible( elem );
9387};
9388jQuery.expr.pseudos.visible = function( elem ) {
9389	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
9390};
9391
9392
9393
9394
9395jQuery.ajaxSettings.xhr = function() {
9396	try {
9397		return new window.XMLHttpRequest();
9398	} catch ( e ) {}
9399};
9400
9401var xhrSuccessStatus = {
9402
9403		// File protocol always yields status code 0, assume 200
9404		0: 200,
9405
9406		// Support: IE <=9 only
9407		// #1450: sometimes IE returns 1223 when it should be 204
9408		1223: 204
9409	},
9410	xhrSupported = jQuery.ajaxSettings.xhr();
9411
9412support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9413support.ajax = xhrSupported = !!xhrSupported;
9414
9415jQuery.ajaxTransport( function( options ) {
9416	var callback, errorCallback;
9417
9418	// Cross domain only allowed if supported through XMLHttpRequest
9419	if ( support.cors || xhrSupported && !options.crossDomain ) {
9420		return {
9421			send: function( headers, complete ) {
9422				var i,
9423					xhr = options.xhr();
9424
9425				xhr.open(
9426					options.type,
9427					options.url,
9428					options.async,
9429					options.username,
9430					options.password
9431				);
9432
9433				// Apply custom fields if provided
9434				if ( options.xhrFields ) {
9435					for ( i in options.xhrFields ) {
9436						xhr[ i ] = options.xhrFields[ i ];
9437					}
9438				}
9439
9440				// Override mime type if needed
9441				if ( options.mimeType && xhr.overrideMimeType ) {
9442					xhr.overrideMimeType( options.mimeType );
9443				}
9444
9445				// X-Requested-With header
9446				// For cross-domain requests, seeing as conditions for a preflight are
9447				// akin to a jigsaw puzzle, we simply never set it to be sure.
9448				// (it can always be set on a per-request basis or even using ajaxSetup)
9449				// For same-domain requests, won't change header if already provided.
9450				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9451					headers[ "X-Requested-With" ] = "XMLHttpRequest";
9452				}
9453
9454				// Set headers
9455				for ( i in headers ) {
9456					xhr.setRequestHeader( i, headers[ i ] );
9457				}
9458
9459				// Callback
9460				callback = function( type ) {
9461					return function() {
9462						if ( callback ) {
9463							callback = errorCallback = xhr.onload =
9464								xhr.onerror = xhr.onabort = xhr.on
vendor: 5,102 bytes, lines 9464-9669
9464readystatechange = null;
9465
9466							if ( type === "abort" ) {
9467								xhr.abort();
9468							} else if ( type === "error" ) {
9469
9470								// Support: IE <=9 only
9471								// On a manual native abort, IE9 throws
9472								// errors on any property access that is not readyState
9473								if ( typeof xhr.status !== "number" ) {
9474									complete( 0, "error" );
9475								} else {
9476									complete(
9477
9478										// File: protocol always yields status 0; see #8605, #14207
9479										xhr.status,
9480										xhr.statusText
9481									);
9482								}
9483							} else {
9484								complete(
9485									xhrSuccessStatus[ xhr.status ] || xhr.status,
9486									xhr.statusText,
9487
9488									// Support: IE <=9 only
9489									// IE9 has no XHR2 but throws on binary (trac-11426)
9490									// For XHR2 non-text, let the caller handle it (gh-2498)
9491									( xhr.responseType || "text" ) !== "text"  ||
9492									typeof xhr.responseText !== "string" ?
9493										{ binary: xhr.response } :
9494										{ text: xhr.responseText },
9495									xhr.getAllResponseHeaders()
9496								);
9497							}
9498						}
9499					};
9500				};
9501
9502				// Listen to events
9503				xhr.onload = callback();
9504				errorCallback = xhr.onerror = callback( "error" );
9505
9506				// Support: IE 9 only
9507				// Use onreadystatechange to replace onabort
9508				// to handle uncaught aborts
9509				if ( xhr.onabort !== undefined ) {
9510					xhr.onabort = errorCallback;
9511				} else {
9512					xhr.onreadystatechange = function() {
9513
9514						// Check readyState before timeout as it changes
9515						if ( xhr.readyState === 4 ) {
9516
9517							// Allow onerror to be called first,
9518							// but that will not handle a native abort
9519							// Also, save errorCallback to a variable
9520							// as xhr.onerror cannot be accessed
9521							window.setTimeout( function() {
9522								if ( callback ) {
9523									errorCallback();
9524								}
9525							} );
9526						}
9527					};
9528				}
9529
9530				// Create the abort callback
9531				callback = callback( "abort" );
9532
9533				try {
9534
9535					// Do send the request (this may raise an exception)
9536					xhr.send( options.hasContent && options.data || null );
9537				} catch ( e ) {
9538
9539					// #14683: Only rethrow if this hasn't been notified as an error yet
9540					if ( callback ) {
9541						throw e;
9542					}
9543				}
9544			},
9545
9546			abort: function() {
9547				if ( callback ) {
9548					callback();
9549				}
9550			}
9551		};
9552	}
9553} );
9554
9555
9556
9557
9558// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
9559jQuery.ajaxPrefilter( function( s ) {
9560	if ( s.crossDomain ) {
9561		s.contents.script = false;
9562	}
9563} );
9564
9565// Install script dataType
9566jQuery.ajaxSetup( {
9567	accepts: {
9568		script: "text/javascript, application/javascript, " +
9569			"application/ecmascript, application/x-ecmascript"
9570	},
9571	contents: {
9572		script: /\b(?:java|ecma)script\b/
9573	},
9574	converters: {
9575		"text script": function( text ) {
9576			jQuery.globalEval( text );
9577			return text;
9578		}
9579	}
9580} );
9581
9582// Handle cache's special case and crossDomain
9583jQuery.ajaxPrefilter( "script", function( s ) {
9584	if ( s.cache === undefined ) {
9585		s.cache = false;
9586	}
9587	if ( s.crossDomain ) {
9588		s.type = "GET";
9589	}
9590} );
9591
9592// Bind script tag hack transport
9593jQuery.ajaxTransport( "script", function( s ) {
9594
9595	// This transport only deals with cross domain requests
9596	if ( s.crossDomain ) {
9597		var script, callback;
9598		return {
9599			send: function( _, complete ) {
9600				script = jQuery( "<script>" ).prop( {
9601					charset: s.scriptCharset,
9602					src: s.url
9603				} ).on(
9604					"load error",
9605					callback = function( evt ) {
9606						script.remove();
9607						callback = null;
9608						if ( evt ) {
9609							complete( evt.type === "error" ? 404 : 200, evt.type );
9610						}
9611					}
9612				);
9613
9614				// Use native DOM manipulation to avoid our domManip AJAX trickery
9615				document.head.appendChild( script[ 0 ] );
9616			},
9617			abort: function() {
9618				if ( callback ) {
9619					callback();
9620				}
9621			}
9622		};
9623	}
9624} );
9625
9626
9627
9628
9629var oldCallbacks = [],
9630	rjsonp = /(=)\?(?=&|$)|\?\?/;
9631
9632// Default jsonp settings
9633jQuery.ajaxSetup( {
9634	jsonp: "callback",
9635	jsonpCallback: function() {
9636		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9637		this[ callback ] = true;
9638		return callback;
9639	}
9640} );
9641
9642// Detect, normalize options and install callbacks for jsonp requests
9643jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9644
9645	var callbackName, overwritten, responseContainer,
9646		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9647			"url" :
9648			typeof s.data === "string" &&
9649				( s.contentType || "" )
9650					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9651				rjsonp.test( s.data ) && "data"
9652		);
9653
9654	// Handle iff the expected data type is "jsonp" or we have a parameter to set
9655	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9656
9657		// Get callback name, remembering preexisting value associated with it
9658		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9659			s.jsonpCallback() :
9660			s.jsonpCallback;
9661
9662		// Insert callback into url or form data
9663		if ( jsonProp ) {
9664			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9665		} else if ( s.jsonp !== false ) {
9666			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9667		}
9668
9669		// Use data converter to retrieve json after script execution
vendor: 2,994 bytes, lines 9670-9779
9670		s.converters[ "script json" ] = function() {
9671			if ( !responseContainer ) {
9672				jQuery.error( callbackName + " was not called" );
9673			}
9674			return responseContainer[ 0 ];
9675		};
9676
9677		// Force json dataType
9678		s.dataTypes[ 0 ] = "json";
9679
9680		// Install callback
9681		overwritten = window[ callbackName ];
9682		window[ callbackName ] = function() {
9683			responseContainer = arguments;
9684		};
9685
9686		// Clean-up function (fires after converters)
9687		jqXHR.always( function() {
9688
9689			// If previous value didn't exist - remove it
9690			if ( overwritten === undefined ) {
9691				jQuery( window ).removeProp( callbackName );
9692
9693			// Otherwise restore preexisting value
9694			} else {
9695				window[ callbackName ] = overwritten;
9696			}
9697
9698			// Save back as free
9699			if ( s[ callbackName ] ) {
9700
9701				// Make sure that re-using the options doesn't screw things around
9702				s.jsonpCallback = originalSettings.jsonpCallback;
9703
9704				// Save the callback name for future use
9705				oldCallbacks.push( callbackName );
9706			}
9707
9708			// Call if it was a function and we have a response
9709			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9710				overwritten( responseContainer[ 0 ] );
9711			}
9712
9713			responseContainer = overwritten = undefined;
9714		} );
9715
9716		// Delegate to script
9717		return "script";
9718	}
9719} );
9720
9721
9722
9723
9724// Support: Safari 8 only
9725// In Safari 8 documents created via document.implementation.createHTMLDocument
9726// collapse sibling forms: the second one becomes a child of the first one.
9727// Because of that, this security measure has to be disabled in Safari 8.
9728// https://bugs.webkit.org/show_bug.cgi?id=137337
9729support.createHTMLDocument = ( function() {
9730	var body = document.implementation.createHTMLDocument( "" ).body;
9731	body.innerHTML = "<form></form><form></form>";
9732	return body.childNodes.length === 2;
9733} )();
9734
9735
9736// Argument "data" should be string of html
9737// context (optional): If specified, the fragment will be created in this context,
9738// defaults to document
9739// keepScripts (optional): If true, will include scripts passed in the html string
9740jQuery.parseHTML = function( data, context, keepScripts ) {
9741	if ( typeof data !== "string" ) {
9742		return [];
9743	}
9744	if ( typeof context === "boolean" ) {
9745		keepScripts = context;
9746		context = false;
9747	}
9748
9749	var base, parsed, scripts;
9750
9751	if ( !context ) {
9752
9753		// Stop scripts or inline event handlers from being executed immediately
9754		// by using document.implementation
9755		if ( support.createHTMLDocument ) {
9756			context = document.implementation.createHTMLDocument( "" );
9757
9758			// Set the base href for the created document
9759			// so any parsed elements with URLs
9760			// are based on the document's URL (gh-2965)
9761			base = context.createElement( "base" );
9762			base.href = document.location.href;
9763			context.head.appendChild( base );
9764		} else {
9765			context = document;
9766		}
9767	}
9768
9769	parsed = rsingleTag.exec( data );
9770	scripts = !keepScripts && [];
9771
9772	// Single tag
9773	if ( parsed ) {
9774		return [ context.createElement( parsed[ 1 ] ) ];
9775	}
9776
9777	parsed = buildFragment( [ data ], context, scripts );
9778
9779	if ( scripts && scripts.length ) {
vendor: 4,169 bytes, lines 9780-9956
9780		jQuery( scripts ).remove();
9781	}
9782
9783	return jQuery.merge( [], parsed.childNodes );
9784};
9785
9786
9787/**
9788 * Load a url into a page
9789 */
9790jQuery.fn.load = function( url, params, callback ) {
9791	var selector, type, response,
9792		self = this,
9793		off = url.indexOf( " " );
9794
9795	if ( off > -1 ) {
9796		selector = stripAndCollapse( url.slice( off ) );
9797		url = url.slice( 0, off );
9798	}
9799
9800	// If it's a function
9801	if ( jQuery.isFunction( params ) ) {
9802
9803		// We assume that it's the callback
9804		callback = params;
9805		params = undefined;
9806
9807	// Otherwise, build a param string
9808	} else if ( params && typeof params === "object" ) {
9809		type = "POST";
9810	}
9811
9812	// If we have elements to modify, make the request
9813	if ( self.length > 0 ) {
9814		jQuery.ajax( {
9815			url: url,
9816
9817			// If "type" variable is undefined, then "GET" method will be used.
9818			// Make value of this field explicit since
9819			// user can override it through ajaxSetup method
9820			type: type || "GET",
9821			dataType: "html",
9822			data: params
9823		} ).done( function( responseText ) {
9824
9825			// Save response for use in complete callback
9826			response = arguments;
9827
9828			self.html( selector ?
9829
9830				// If a selector was specified, locate the right elements in a dummy div
9831				// Exclude scripts to avoid IE 'Permission Denied' errors
9832				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9833
9834				// Otherwise use the full result
9835				responseText );
9836
9837		// If the request succeeds, this function gets "data", "status", "jqXHR"
9838		// but they are ignored because response was set above.
9839		// If it fails, this function gets "jqXHR", "status", "error"
9840		} ).always( callback && function( jqXHR, status ) {
9841			self.each( function() {
9842				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9843			} );
9844		} );
9845	}
9846
9847	return this;
9848};
9849
9850
9851
9852
9853// Attach a bunch of functions for handling common AJAX events
9854jQuery.each( [
9855	"ajaxStart",
9856	"ajaxStop",
9857	"ajaxComplete",
9858	"ajaxError",
9859	"ajaxSuccess",
9860	"ajaxSend"
9861], function( i, type ) {
9862	jQuery.fn[ type ] = function( fn ) {
9863		return this.on( type, fn );
9864	};
9865} );
9866
9867
9868
9869
9870jQuery.expr.pseudos.animated = function( elem ) {
9871	return jQuery.grep( jQuery.timers, function( fn ) {
9872		return elem === fn.elem;
9873	} ).length;
9874};
9875
9876
9877
9878
9879/**
9880 * Gets a window from an element
9881 */
9882function getWindow( elem ) {
9883	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
9884}
9885
9886jQuery.offset = {
9887	setOffset: function( elem, options, i ) {
9888		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9889			position = jQuery.css( elem, "position" ),
9890			curElem = jQuery( elem ),
9891			props = {};
9892
9893		// Set position first, in-case top/left are set even on static elem
9894		if ( position === "static" ) {
9895			elem.style.position = "relative";
9896		}
9897
9898		curOffset = curElem.offset();
9899		curCSSTop = jQuery.css( elem, "top" );
9900		curCSSLeft = jQuery.css( elem, "left" );
9901		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9902			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9903
9904		// Need to be able to calculate position if either
9905		// top or left is auto and position is either absolute or fixed
9906		if ( calculatePosition ) {
9907			curPosition = curElem.position();
9908			curTop = curPosition.top;
9909			curLeft = curPosition.left;
9910
9911		} else {
9912			curTop = parseFloat( curCSSTop ) || 0;
9913			curLeft = parseFloat( curCSSLeft ) || 0;
9914		}
9915
9916		if ( jQuery.isFunction( options ) ) {
9917
9918			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9919			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9920		}
9921
9922		if ( options.top != null ) {
9923			props.top = ( options.top - curOffset.top ) + curTop;
9924		}
9925		if ( options.left != null ) {
9926			props.left = ( options.left - curOffset.left ) + curLeft;
9927		}
9928
9929		if ( "using" in options ) {
9930			options.using.call( elem, props );
9931
9932		} else {
9933			curElem.css( props );
9934		}
9935	}
9936};
9937
9938jQuery.fn.extend( {
9939	offset: function( options ) {
9940
9941		// Preserve chaining for setter
9942		if ( arguments.length ) {
9943			return options === undefined ?
9944				this :
9945				this.each( function( i ) {
9946					jQuery.offset.setOffset( this, options, i );
9947				} );
9948		}
9949
9950		var docElem, win, rect, doc,
9951			elem = this[ 0 ];
9952
9953		if ( !elem ) {
9954			return;
9955		}
9956
vendor: 4,167 bytes, lines 9957-10094
9957		// Support: IE <=11 only
9958		// Running getBoundingClientRect on a
9959		// disconnected node in IE throws an error
9960		if ( !elem.getClientRects().length ) {
9961			return { top: 0, left: 0 };
9962		}
9963
9964		rect = elem.getBoundingClientRect();
9965
9966		// Make sure element is not hidden (display: none)
9967		if ( rect.width || rect.height ) {
9968			doc = elem.ownerDocument;
9969			win = getWindow( doc );
9970			docElem = doc.documentElement;
9971
9972			return {
9973				top: rect.top + win.pageYOffset - docElem.clientTop,
9974				left: rect.left + win.pageXOffset - docElem.clientLeft
9975			};
9976		}
9977
9978		// Return zeros for disconnected and hidden elements (gh-2310)
9979		return rect;
9980	},
9981
9982	position: function() {
9983		if ( !this[ 0 ] ) {
9984			return;
9985		}
9986
9987		var offsetParent, offset,
9988			elem = this[ 0 ],
9989			parentOffset = { top: 0, left: 0 };
9990
9991		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9992		// because it is its only offset parent
9993		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9994
9995			// Assume getBoundingClientRect is there when computed position is fixed
9996			offset = elem.getBoundingClientRect();
9997
9998		} else {
9999
10000			// Get *real* offsetParent
10001			offsetParent = this.offsetParent();
10002
10003			// Get correct offsets
10004			offset = this.offset();
10005			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10006				parentOffset = offsetParent.offset();
10007			}
10008
10009			// Add offsetParent borders
10010			parentOffset = {
10011				top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
10012				left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true )
10013			};
10014		}
10015
10016		// Subtract parent offsets and element margins
10017		return {
10018			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10019			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10020		};
10021	},
10022
10023	// This method will return documentElement in the following cases:
10024	// 1) For the element inside the iframe without offsetParent, this method will return
10025	//    documentElement of the parent window
10026	// 2) For the hidden or detached element
10027	// 3) For body or html element, i.e. in case of the html node - it will return itself
10028	//
10029	// but those exceptions were never presented as a real life use-cases
10030	// and might be considered as more preferable results.
10031	//
10032	// This logic, however, is not guaranteed and can change at any point in the future
10033	offsetParent: function() {
10034		return this.map( function() {
10035			var offsetParent = this.offsetParent;
10036
10037			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10038				offsetParent = offsetParent.offsetParent;
10039			}
10040
10041			return offsetParent || documentElement;
10042		} );
10043	}
10044} );
10045
10046// Create scrollLeft and scrollTop methods
10047jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10048	var top = "pageYOffset" === prop;
10049
10050	jQuery.fn[ method ] = function( val ) {
10051		return access( this, function( elem, method, val ) {
10052			var win = getWindow( elem );
10053
10054			if ( val === undefined ) {
10055				return win ? win[ prop ] : elem[ method ];
10056			}
10057
10058			if ( win ) {
10059				win.scrollTo(
10060					!top ? val : win.pageXOffset,
10061					top ? val : win.pageYOffset
10062				);
10063
10064			} else {
10065				elem[ method ] = val;
10066			}
10067		}, method, val, arguments.length );
10068	};
10069} );
10070
10071// Support: Safari <=7 - 9.1, Chrome <=37 - 49
10072// Add the top/left cssHooks using jQuery.fn.position
10073// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10074// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10075// getComputedStyle returns percent when specified for top/left/bottom/right;
10076// rather than make the css module depend on the offset module, just check for it here
10077jQuery.each( [ "top", "left" ], function( i, prop ) {
10078	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10079		function( elem, computed ) {
10080			if ( computed ) {
10081				computed = curCSS( elem, prop );
10082
10083				// If curCSS returns percentage, fallback to offset
10084				return rnumnonpx.test( computed ) ?
10085					jQuery( elem ).position()[ prop ] + "px" :
10086					computed;
10087			}
10088		}
10089	);
10090} );
10091
10092
10093// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10094jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10095	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10096		function( defaultExtra, funcName ) {
10097
10098		// Margin is only for outerHeight, outerWidth
10099		jQuery.fn[ funcName ] = function( margin, value ) {
10100			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10101				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10102
10103			return access( this, function( elem, type, value ) {
10104				var doc;
10105
10106				if ( jQuery.isWindow( elem ) ) {
10107
10108					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10109					return funcName.indexOf( "outer" ) === 0 ?
10110						elem[ "inner" + name ] :
10111						elem.document.documentElement[ "client" + name ];
10112				}
10113
10114				// Get document width or height
10115				if ( elem.nodeType === 9 ) {
10116					doc = elem.documentElement;
10117
10118					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10119					// whichever is greatest
10120					return Math.max(
10121						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10122						elem.body[ "offset" + name ], doc[ "offset" + name ],
10123						doc[ "client" + name ]
10124					);
10125				}
10126
10127				return value === undefined ?
10128
10129					// Get width or height on the element, requesting but not forcing parseFloat
10130					jQuery.css( elem, type, extra ) :
10131
10132					// Set width or height on the element
10133					jQuery.style( elem, type, value, extra );
10134			}, type, chainable ? margin : undefined, chainable );
10135		};
10136	} );
10137} );
10138
10139
10140jQuery.fn.extend( {
10141
10142	bind: function( types, data, fn ) {
10143		return this.on( types, null, data, fn );
10144	},
10145	unbind: function( types, fn ) {
10146		return this.off( types, null, fn );
10147	},
10148
10149	delegate: function( selector, types, data, fn ) {
10150		return this.on( types, selector, data, fn );
10151	},
10152	undelegate: function( selector, types, fn ) {
10153
10154		// ( namespace ) or ( selector, types [, fn] )
10155		return arguments.length === 1 ?
10156			this.off( selector, "**" ) :
10157			this.off( types, selector || "**", fn );
10158	}
10159} );
10160
10161jQuery.parseJSON = JSON.parse;
10162
10163
10164
10165
10166// Register as a named AMD module, since jQuery can be concatenated with other
10167// files that may use define, but not via a proper concatenation script that
10168// understands anonymous AMD modules. A named AMD is safest and most robust
10169// way to register. Lowercase jquery is used because AMD module names are
10170// derived from file names, and jQuery is normally delivered in a lowercase
10171// file name. Do this after creating the global so that if an AMD module wants
10172// to call noConflict to hide this version of jQuery, it will work.
10173
10174// Note that for maximum portability, libraries that are not jQuery should
10175// declare themselves as anonymous modules, and avoid setting a global if an
10176// AMD loader is present. jQuery is a special case. For more information, see
10177// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10178
10179if ( typeof define === "function" && define.amd ) {
10180	define( "jquery", [], function() {
10181		return jQuery;
10182	} );
10183}
10184
10185
10186
10187
10188var
10189
10190	// Map over jQuery in case of overwrite
10191	_jQuery = window.jQuery,
10192
10193	// Map over the $ in case of overwrite
10194	_$ = window.$;
10195
10196jQuery.noConflict = function( deep ) {
10197	if ( window.$ === jQuery ) {
10198		window.$ = _$;
10199	}
10200
10201	if ( deep && window.jQuery === jQuery ) {
10202		window.jQuery = _jQuery;
10203	}
10204
10205	return jQuery;
10206};
10207
10208// Expose jQuery and $ identifiers, even in AMD
10209// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10210// and CommonJS for browser emulators (#13566)
10211if ( !noGlobal ) {
10212	window.jQuery = window.$ = jQuery;
10213}
10214
10215
10216
10217
10218
10219return jQuery;
10220} );
10221
10222/*
10223     _ _      _       _
10224 ___| (_) ___| | __  (_)___
10225/ __| | |/ __| |/ /  | / __|
10226\__ \ | | (__|   < _ | \__ \
10227|___/_|_|\___|_|\_(_)/ |___/
10228                   |__/
10229
10230 Version: 1.8.0
10231  Author: Ken Wheeler
10232 Website: http://kenwheeler.github.io
10233    Docs: http://kenwheeler.github.io/slick
10234    Repo: http://github.com/kenwheeler/slick
10235  Issues: http://github.com/kenwheeler/slick/issues
10236
10237 */
10238/* global window, document, define, jQuery, setInterval, clearInterval */
10239;(function(factory) {
10240    'use strict';
10241    if (typeof define === 'function' && define.amd) {
10242        define(['jquery'], factory);
10243    } else if (typeof exports !== 'undefined') {
10244        module.exports = factory(require('jquery'));
10245    } else {
10246        factory(jQuery);
10247    }
10248
10249}(function($) {
10250    'use strict';
vendor: 31,932 bytes, lines 10250-11313
10250
10251    var Slick = window.Slick || {};
10252
10253    Slick = (function() {
10254
10255        var instanceUid = 0;
10256
10257        function Slick(element, settings) {
10258
10259            var _ = this, dataSettings;
10260
10261            _.defaults = {
10262                accessibility: true,
10263                adaptiveHeight: false,
10264                appendArrows: $(element),
10265                appendDots: $(element),
10266                arrows: true,
10267                asNavFor: null,
10268                prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',
10269                nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>',
10270                autoplay: false,
10271                autoplaySpeed: 3000,
10272                centerMode: false,
10273                centerPadding: '50px',
10274                cssEase: 'ease',
10275                customPaging: function(slider, i) {
10276                    return $('<button type="button" />').text(i + 1);
10277                },
10278                dots: false,
10279                dotsClass: 'slick-dots',
10280                draggable: true,
10281                easing: 'linear',
10282                edgeFriction: 0.35,
10283                fade: false,
10284                focusOnSelect: false,
10285                focusOnChange: false,
10286                infinite: true,
10287                initialSlide: 0,
10288                lazyLoad: 'ondemand',
10289                mobileFirst: false,
10290                pauseOnHover: true,
10291                pauseOnFocus: true,
10292                pauseOnDotsHover: false,
10293                respondTo: 'window',
10294                responsive: null,
10295                rows: 1,
10296                rtl: false,
10297                slide: '',
10298                slidesPerRow: 1,
10299                slidesToShow: 1,
10300                slidesToScroll: 1,
10301                speed: 500,
10302                swipe: true,
10303                swipeToSlide: false,
10304                touchMove: true,
10305                touchThreshold: 5,
10306                useCSS: true,
10307                useTransform: true,
10308                variableWidth: false,
10309                vertical: false,
10310                verticalSwiping: false,
10311                waitForAnimate: true,
10312                zIndex: 1000
10313            };
10314
10315            _.initials = {
10316                animating: false,
10317                dragging: false,
10318                autoPlayTimer: null,
10319                currentDirection: 0,
10320                currentLeft: null,
10321                currentSlide: 0,
10322                direction: 1,
10323                $dots: null,
10324                listWidth: null,
10325                listHeight: null,
10326                loadIndex: 0,
10327                $nextArrow: null,
10328                $prevArrow: null,
10329                scrolling: false,
10330                slideCount: null,
10331                slideWidth: null,
10332                $slideTrack: null,
10333                $slides: null,
10334                sliding: false,
10335                slideOffset: 0,
10336                swipeLeft: null,
10337                swiping: false,
10338                $list: null,
10339                touchObject: {},
10340                transformsEnabled: false,
10341                unslicked: false
10342            };
10343
10344            $.extend(_, _.initials);
10345
10346            _.activeBreakpoint = null;
10347            _.animType = null;
10348            _.animProp = null;
10349            _.breakpoints = [];
10350            _.breakpointSettings = [];
10351            _.cssTransitions = false;
10352            _.focussed = false;
10353            _.interrupted = false;
10354            _.hidden = 'hidden';
10355            _.paused = true;
10356            _.positionProp = null;
10357            _.respondTo = null;
10358            _.rowCount = 1;
10359            _.shouldClick = true;
10360            _.$slider = $(element);
10361            _.$slidesCache = null;
10362            _.transformType = null;
10363            _.transitionType = null;
10364            _.visibilityChange = 'visibilitychange';
10365            _.windowWidth = 0;
10366            _.windowTimer = null;
10367
10368            dataSettings = $(element).data('slick') || {};
10369
10370            _.options = $.extend({}, _.defaults, settings, dataSettings);
10371
10372            _.currentSlide = _.options.initialSlide;
10373
10374            _.originalSettings = _.options;
10375
10376            if (typeof document.mozHidden !== 'undefined') {
10377                _.hidden = 'mozHidden';
10378                _.visibilityChange = 'mozvisibilitychange';
10379            } else if (typeof document.webkitHidden !== 'undefined') {
10380                _.hidden = 'webkitHidden';
10381                _.visibilityChange = 'webkitvisibilitychange';
10382            }
10383
10384            _.autoPlay = $.proxy(_.autoPlay, _);
10385            _.autoPlayClear = $.proxy(_.autoPlayClear, _);
10386            _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
10387            _.changeSlide = $.proxy(_.changeSlide, _);
10388            _.clickHandler = $.proxy(_.clickHandler, _);
10389            _.selectHandler = $.proxy(_.selectHandler, _);
10390            _.setPosition = $.proxy(_.setPosition, _);
10391            _.swipeHandler = $.proxy(_.swipeHandler, _);
10392            _.dragHandler = $.proxy(_.dragHandler, _);
10393            _.keyHandler = $.proxy(_.keyHandler, _);
10394
10395            _.instanceUid = instanceUid++;
10396
10397            // A simple way to check for HTML strings
10398            // Strict HTML recognition (must start with <)
10399            // Extracted from jQuery v1.11 source
10400            _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
10401
10402
10403            _.registerBreakpoints();
10404            _.init(true);
10405
10406        }
10407
10408        return Slick;
10409
10410    }());
10411
10412    Slick.prototype.activateADA = function() {
10413        var _ = this;
10414
10415        _.$slideTrack.find('.slick-active').attr({
10416            'aria-hidden': 'false'
10417        }).find('a, input, button, select').attr({
10418            'tabindex': '0'
10419        });
10420
10421    };
10422
10423    Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
10424
10425        var _ = this;
10426
10427        if (typeof(index) === 'boolean') {
10428            addBefore = index;
10429            index = null;
10430        } else if (index < 0 || (index >= _.slideCount)) {
10431            return false;
10432        }
10433
10434        _.unload();
10435
10436        if (typeof(index) === 'number') {
10437            if (index === 0 && _.$slides.length === 0) {
10438                $(markup).appendTo(_.$slideTrack);
10439            } else if (addBefore) {
10440                $(markup).insertBefore(_.$slides.eq(index));
10441            } else {
10442                $(markup).insertAfter(_.$slides.eq(index));
10443            }
10444        } else {
10445            if (addBefore === true) {
10446                $(markup).prependTo(_.$slideTrack);
10447            } else {
10448                $(markup).appendTo(_.$slideTrack);
10449            }
10450        }
10451
10452        _.$slides = _.$slideTrack.children(this.options.slide);
10453
10454        _.$slideTrack.children(this.options.slide).detach();
10455
10456        _.$slideTrack.append(_.$slides);
10457
10458        _.$slides.each(function(index, element) {
10459            $(element).attr('data-slick-index', index);
10460        });
10461
10462        _.$slidesCache = _.$slides;
10463
10464        _.reinit();
10465
10466    };
10467
10468    Slick.prototype.animateHeight = function() {
10469        var _ = this;
10470        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
10471            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
10472            _.$list.animate({
10473                height: targetHeight
10474            }, _.options.speed);
10475        }
10476    };
10477
10478    Slick.prototype.animateSlide = function(targetLeft, callback) {
10479
10480        var animProps = {},
10481            _ = this;
10482
10483        _.animateHeight();
10484
10485        if (_.options.rtl === true && _.options.vertical === false) {
10486            targetLeft = -targetLeft;
10487        }
10488        if (_.transformsEnabled === false) {
10489            if (_.options.vertical === false) {
10490                _.$slideTrack.animate({
10491                    left: targetLeft
10492                }, _.options.speed, _.options.easing, callback);
10493            } else {
10494                _.$slideTrack.animate({
10495                    top: targetLeft
10496                }, _.options.speed, _.options.easing, callback);
10497            }
10498
10499        } else {
10500
10501            if (_.cssTransitions === false) {
10502                if (_.options.rtl === true) {
10503                    _.currentLeft = -(_.currentLeft);
10504                }
10505                $({
10506                    animStart: _.currentLeft
10507                }).animate({
10508                    animStart: targetLeft
10509                }, {
10510                    duration: _.options.speed,
10511                    easing: _.options.easing,
10512                    step: function(now) {
10513                        now = Math.ceil(now);
10514                        if (_.options.vertical === false) {
10515                            animProps[_.animType] = 'translate(' +
10516                                now + 'px, 0px)';
10517                            _.$slideTrack.css(animProps);
10518                        } else {
10519                            animProps[_.animType] = 'translate(0px,' +
10520                                now + 'px)';
10521                            _.$slideTrack.css(animProps);
10522                        }
10523                    },
10524                    complete: function() {
10525                        if (callback) {
10526                            callback.call();
10527                        }
10528                    }
10529                });
10530
10531            } else {
10532
10533                _.applyTransition();
10534                targetLeft = Math.ceil(targetLeft);
10535
10536                if (_.options.vertical === false) {
10537                    animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
10538                } else {
10539                    animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
10540                }
10541                _.$slideTrack.css(animProps);
10542
10543                if (callback) {
10544                    setTimeout(function() {
10545
10546                        _.disableTransition();
10547
10548                        callback.call();
10549                    }, _.options.speed);
10550                }
10551
10552            }
10553
10554        }
10555
10556    };
10557
10558    Slick.prototype.getNavTarget = function() {
10559
10560        var _ = this,
10561            asNavFor = _.options.asNavFor;
10562
10563        if ( asNavFor && asNavFor !== null ) {
10564            asNavFor = $(asNavFor).not(_.$slider);
10565        }
10566
10567        return asNavFor;
10568
10569    };
10570
10571    Slick.prototype.asNavFor = function(index) {
10572
10573        var _ = this,
10574            asNavFor = _.getNavTarget();
10575
10576        if ( asNavFor !== null && typeof asNavFor === 'object' ) {
10577            asNavFor.each(function() {
10578                var target = $(this).slick('getSlick');
10579                if(!target.unslicked) {
10580                    target.slideHandler(index, true);
10581                }
10582            });
10583        }
10584
10585    };
10586
10587    Slick.prototype.applyTransition = function(slide) {
10588
10589        var _ = this,
10590            transition = {};
10591
10592        if (_.options.fade === false) {
10593            transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
10594        } else {
10595            transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
10596        }
10597
10598        if (_.options.fade === false) {
10599            _.$slideTrack.css(transition);
10600        } else {
10601            _.$slides.eq(slide).css(transition);
10602        }
10603
10604    };
10605
10606    Slick.prototype.autoPlay = function() {
10607
10608        var _ = this;
10609
10610        _.autoPlayClear();
10611
10612        if ( _.slideCount > _.options.slidesToShow ) {
10613            _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
10614        }
10615
10616    };
10617
10618    Slick.prototype.autoPlayClear = function() {
10619
10620        var _ = this;
10621
10622        if (_.autoPlayTimer) {
10623            clearInterval(_.autoPlayTimer);
10624        }
10625
10626    };
10627
10628    Slick.prototype.autoPlayIterator = function() {
10629
10630        var _ = this,
10631            slideTo = _.currentSlide + _.options.slidesToScroll;
10632
10633        if ( !_.paused && !_.interrupted && !_.focussed ) {
10634
10635            if ( _.options.infinite === false ) {
10636
10637                if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
10638                    _.direction = 0;
10639                }
10640
10641                else if ( _.direction === 0 ) {
10642
10643                    slideTo = _.currentSlide - _.options.slidesToScroll;
10644
10645                    if ( _.currentSlide - 1 === 0 ) {
10646                        _.direction = 1;
10647                    }
10648
10649                }
10650
10651            }
10652
10653            _.slideHandler( slideTo );
10654
10655        }
10656
10657    };
10658
10659    Slick.prototype.buildArrows = function() {
10660
10661        var _ = this;
10662
10663        if (_.options.arrows === true ) {
10664
10665            _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
10666            _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
10667
10668            if( _.slideCount > _.options.slidesToShow ) {
10669
10670                _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
10671                _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
10672
10673                if (_.htmlExpr.test(_.options.prevArrow)) {
10674                    _.$prevArrow.prependTo(_.options.appendArrows);
10675                }
10676
10677                if (_.htmlExpr.test(_.options.nextArrow)) {
10678                    _.$nextArrow.appendTo(_.options.appendArrows);
10679                }
10680
10681                if (_.options.infinite !== true) {
10682                    _.$prevArrow
10683                        .addClass('slick-disabled')
10684                        .attr('aria-disabled', 'true');
10685                }
10686
10687            } else {
10688
10689                _.$prevArrow.add( _.$nextArrow )
10690
10691                    .addClass('slick-hidden')
10692                    .attr({
10693                        'aria-disabled': 'true',
10694                        'tabindex': '-1'
10695                    });
10696
10697            }
10698
10699        }
10700
10701    };
10702
10703    Slick.prototype.buildDots = function() {
10704
10705        var _ = this,
10706            i, dot;
10707
10708        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
10709
10710            _.$slider.addClass('slick-dotted');
10711
10712            dot = $('<ul />').addClass(_.options.dotsClass);
10713
10714            for (i = 0; i <= _.getDotCount(); i += 1) {
10715                dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
10716            }
10717
10718            _.$dots = dot.appendTo(_.options.appendDots);
10719
10720            _.$dots.find('li').first().addClass('slick-active');
10721
10722        }
10723
10724    };
10725
10726    Slick.prototype.buildOut = function() {
10727
10728        var _ = this;
10729
10730        _.$slides =
10731            _.$slider
10732                .children( _.options.slide + ':not(.slick-cloned)')
10733                .addClass('slick-slide');
10734
10735        _.slideCount = _.$slides.length;
10736
10737        _.$slides.each(function(index, element) {
10738            $(element)
10739                .attr('data-slick-index', index)
10740                .data('originalStyling', $(element).attr('style') || '');
10741        });
10742
10743        _.$slider.addClass('slick-slider');
10744
10745        _.$slideTrack = (_.slideCount === 0) ?
10746            $('<div class="slick-track"/>').appendTo(_.$slider) :
10747            _.$slides.wrapAll('<div class="slick-track"/>').parent();
10748
10749        _.$list = _.$slideTrack.wrap(
10750            '<div class="slick-list"/>').parent();
10751        _.$slideTrack.css('opacity', 0);
10752
10753        if (_.options.centerMode === true || _.options.swipeToSlide === true) {
10754            _.options.slidesToScroll = 1;
10755        }
10756
10757        $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
10758
10759        _.setupInfinite();
10760
10761        _.buildArrows();
10762
10763        _.buildDots();
10764
10765        _.updateDots();
10766
10767
10768        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
10769
10770        if (_.options.draggable === true) {
10771            _.$list.addClass('draggable');
10772        }
10773
10774    };
10775
10776    Slick.prototype.buildRows = function() {
10777
10778        var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
10779
10780        newSlides = document.createDocumentFragment();
10781        originalSlides = _.$slider.children();
10782
10783        if(_.options.rows > 0) {
10784
10785            slidesPerSection = _.options.slidesPerRow * _.options.rows;
10786            numOfSlides = Math.ceil(
10787                originalSlides.length / slidesPerSection
10788            );
10789
10790            for(a = 0; a < numOfSlides; a++){
10791                var slide = document.createElement('div');
10792                for(b = 0; b < _.options.rows; b++) {
10793                    var row = document.createElement('div');
10794                    for(c = 0; c < _.options.slidesPerRow; c++) {
10795                        var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
10796                        if (originalSlides.get(target)) {
10797                            row.appendChild(originalSlides.get(target));
10798                        }
10799                    }
10800                    slide.appendChild(row);
10801                }
10802                newSlides.appendChild(slide);
10803            }
10804
10805            _.$slider.empty().append(newSlides);
10806            _.$slider.children().children().children()
10807                .css({
10808                    'width':(100 / _.options.slidesPerRow) + '%',
10809                    'display': 'inline-block'
10810                });
10811
10812        }
10813
10814    };
10815
10816    Slick.prototype.checkResponsive = function(initial, forceUpdate) {
10817
10818        var _ = this,
10819            breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
10820        var sliderWidth = _.$slider.width();
10821        var windowWidth = window.innerWidth || $(window).width();
10822
10823        if (_.respondTo === 'window') {
10824            respondToWidth = windowWidth;
10825        } else if (_.respondTo === 'slider') {
10826            respondToWidth = sliderWidth;
10827        } else if (_.respondTo === 'min') {
10828            respondToWidth = Math.min(windowWidth, sliderWidth);
10829        }
10830
10831        if ( _.options.responsive &&
10832            _.options.responsive.length &&
10833            _.options.responsive !== null) {
10834
10835            targetBreakpoint = null;
10836
10837            for (breakpoint in _.breakpoints) {
10838                if (_.breakpoints.hasOwnProperty(breakpoint)) {
10839                    if (_.originalSettings.mobileFirst === false) {
10840                        if (respondToWidth < _.breakpoints[breakpoint]) {
10841                            targetBreakpoint = _.breakpoints[breakpoint];
10842                        }
10843                    } else {
10844                        if (respondToWidth > _.breakpoints[breakpoint]) {
10845                            targetBreakpoint = _.breakpoints[breakpoint];
10846                        }
10847                    }
10848                }
10849            }
10850
10851            if (targetBreakpoint !== null) {
10852                if (_.activeBreakpoint !== null) {
10853                    if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
10854                        _.activeBreakpoint =
10855                            targetBreakpoint;
10856                        if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
10857                            _.unslick(targetBreakpoint);
10858                        } else {
10859                            _.options = $.extend({}, _.originalSettings,
10860                                _.breakpointSettings[
10861                                    targetBreakpoint]);
10862                            if (initial === true) {
10863                                _.currentSlide = _.options.initialSlide;
10864                            }
10865                            _.refresh(initial);
10866                        }
10867                        triggerBreakpoint = targetBreakpoint;
10868                    }
10869                } else {
10870                    _.activeBreakpoint = targetBreakpoint;
10871                    if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
10872                        _.unslick(targetBreakpoint);
10873                    } else {
10874                        _.options = $.extend({}, _.originalSettings,
10875                            _.breakpointSettings[
10876                                targetBreakpoint]);
10877                        if (initial === true) {
10878                            _.currentSlide = _.options.initialSlide;
10879                        }
10880                        _.refresh(initial);
10881                    }
10882                    triggerBreakpoint = targetBreakpoint;
10883                }
10884            } else {
10885                if (_.activeBreakpoint !== null) {
10886                    _.activeBreakpoint = null;
10887                    _.options = _.originalSettings;
10888                    if (initial === true) {
10889                        _.currentSlide = _.options.initialSlide;
10890                    }
10891                    _.refresh(initial);
10892                    triggerBreakpoint = targetBreakpoint;
10893                }
10894            }
10895
10896            // only trigger breakpoints during an actual break. not on initialize.
10897            if( !initial && triggerBreakpoint !== false ) {
10898                _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
10899            }
10900        }
10901
10902    };
10903
10904    Slick.prototype.changeSlide = function(event, dontAnimate) {
10905
10906        var _ = this,
10907            $target = $(event.currentTarget),
10908            indexOffset, slideOffset, unevenOffset;
10909
10910        // If target is a link, prevent default action.
10911        if($target.is('a')) {
10912            event.preventDefault();
10913        }
10914
10915        // If target is not the <li> element (ie: a child), find the <li>.
10916        if(!$target.is('li')) {
10917            $target = $target.closest('li');
10918        }
10919
10920        unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
10921        indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
10922
10923        switch (event.data.message) {
10924
10925            case 'previous':
10926                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
10927                if (_.slideCount > _.options.slidesToShow) {
10928                    _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
10929                }
10930                break;
10931
10932            case 'next':
10933                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
10934                if (_.slideCount > _.options.slidesToShow) {
10935                    _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
10936                }
10937                break;
10938
10939            case 'index':
10940                var index = event.data.index === 0 ? 0 :
10941                    event.data.index || $target.index() * _.options.slidesToScroll;
10942
10943                _.slideHandler(_.checkNavigable(index), false, dontAnimate);
10944                $target.children().trigger('focus');
10945                break;
10946
10947            default:
10948                return;
10949        }
10950
10951    };
10952
10953    Slick.prototype.checkNavigable = function(index) {
10954
10955        var _ = this,
10956            navigables, prevNavigable;
10957
10958        navigables = _.getNavigableIndexes();
10959        prevNavigable = 0;
10960        if (index > navigables[navigables.length - 1]) {
10961            index = navigables[navigables.length - 1];
10962        } else {
10963            for (var n in navigables) {
10964                if (index < navigables[n]) {
10965                    index = prevNavigable;
10966                    break;
10967                }
10968                prevNavigable = navigables[n];
10969            }
10970        }
10971
10972        return index;
10973    };
10974
10975    Slick.prototype.cleanUpEvents = function() {
10976
10977        var _ = this;
10978
10979        if (_.options.dots && _.$dots !== null) {
10980
10981            $('li', _.$dots)
10982                .off('click.slick', _.changeSlide)
10983                .off('mouseenter.slick', $.proxy(_.interrupt, _, true))
10984                .off('mouseleave.slick', $.proxy(_.interrupt, _, false));
10985
10986            if (_.options.accessibility === true) {
10987                _.$dots.off('keydown.slick', _.keyHandler);
10988            }
10989        }
10990
10991        _.$slider.off('focus.slick blur.slick');
10992
10993        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
10994            _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
10995            _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
10996
10997            if (_.options.accessibility === true) {
10998                _.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler);
10999                _.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler);
11000            }
11001        }
11002
11003        _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
11004        _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
11005        _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
11006        _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
11007
11008        _.$list.off('click.slick', _.clickHandler);
11009
11010        $(document).off(_.visibilityChange, _.visibility);
11011
11012        _.cleanUpSlideEvents();
11013
11014        if (_.options.accessibility === true) {
11015            _.$list.off('keydown.slick', _.keyHandler);
11016        }
11017
11018        if (_.options.focusOnSelect === true) {
11019            $(_.$slideTrack).children().off('click.slick', _.selectHandler);
11020        }
11021
11022        $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
11023
11024        $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
11025
11026        $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
11027
11028        $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
11029
11030    };
11031
11032    Slick.prototype.cleanUpSlideEvents = function() {
11033
11034        var _ = this;
11035
11036        _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
11037        _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
11038
11039    };
11040
11041    Slick.prototype.cleanUpRows = function() {
11042
11043        var _ = this, originalSlides;
11044
11045        if(_.options.rows > 0) {
11046            originalSlides = _.$slides.children().children();
11047            originalSlides.removeAttr('style');
11048            _.$slider.empty().append(originalSlides);
11049        }
11050
11051    };
11052
11053    Slick.prototype.clickHandler = function(event) {
11054
11055        var _ = this;
11056
11057        if (_.shouldClick === false) {
11058            event.stopImmediatePropagation();
11059            event.stopPropagation();
11060            event.preventDefault();
11061        }
11062
11063    };
11064
11065    Slick.prototype.destroy = function(refresh) {
11066
11067        var _ = this;
11068
11069        _.autoPlayClear();
11070
11071        _.touchObject = {};
11072
11073        _.cleanUpEvents();
11074
11075        $('.slick-cloned', _.$slider).detach();
11076
11077        if (_.$dots) {
11078            _.$dots.remove();
11079        }
11080
11081        if ( _.$prevArrow && _.$prevArrow.length ) {
11082
11083            _.$prevArrow
11084                .removeClass('slick-disabled slick-arrow slick-hidden')
11085                .removeAttr('aria-hidden aria-disabled tabindex')
11086                .css('display','');
11087
11088            if ( _.htmlExpr.test( _.options.prevArrow )) {
11089                _.$prevArrow.remove();
11090            }
11091        }
11092
11093        if ( _.$nextArrow && _.$nextArrow.length ) {
11094
11095            _.$nextArrow
11096                .removeClass('slick-disabled slick-arrow slick-hidden')
11097                .removeAttr('aria-hidden aria-disabled tabindex')
11098                .css('display','');
11099
11100            if ( _.htmlExpr.test( _.options.nextArrow )) {
11101                _.$nextArrow.remove();
11102            }
11103        }
11104
11105
11106        if (_.$slides) {
11107
11108            _.$slides
11109                .removeClass('slick-slide slick-active slick-center slick-visible slick-current')
11110                .removeAttr('aria-hidden')
11111                .removeAttr('data-slick-index')
11112                .each(function(){
11113                    $(this).attr('style', $(this).data('originalStyling'));
11114                });
11115
11116            _.$slideTrack.children(this.options.slide).detach();
11117
11118            _.$slideTrack.detach();
11119
11120            _.$list.detach();
11121
11122            _.$slider.append(_.$slides);
11123        }
11124
11125        _.cleanUpRows();
11126
11127        _.$slider.removeClass('slick-slider');
11128        _.$slider.removeClass('slick-initialized');
11129        _.$slider.removeClass('slick-dotted');
11130
11131        _.unslicked = true;
11132
11133        if(!refresh) {
11134            _.$slider.trigger('destroy', [_]);
11135        }
11136
11137    };
11138
11139    Slick.prototype.disableTransition = function(slide) {
11140
11141        var _ = this,
11142            transition = {};
11143
11144        transition[_.transitionType] = '';
11145
11146        if (_.options.fade === false) {
11147            _.$slideTrack.css(transition);
11148        } else {
11149            _.$slides.eq(slide).css(transition);
11150        }
11151
11152    };
11153
11154    Slick.prototype.fadeSlide = function(slideIndex, callback) {
11155
11156        var _ = this;
11157
11158        if (_.cssTransitions === false) {
11159
11160            _.$slides.eq(slideIndex).css({
11161                zIndex: _.options.zIndex
11162            });
11163
11164            _.$slides.eq(slideIndex).animate({
11165                opacity: 1
11166            }, _.options.speed, _.options.easing, callback);
11167
11168        } else {
11169
11170            _.applyTransition(slideIndex);
11171
11172            _.$slides.eq(slideIndex).css({
11173                opacity: 1,
11174                zIndex: _.options.zIndex
11175            });
11176
11177            if (callback) {
11178                setTimeout(function() {
11179
11180                    _.disableTransition(slideIndex);
11181
11182                    callback.call();
11183                }, _.options.speed);
11184            }
11185
11186        }
11187
11188    };
11189
11190    Slick.prototype.fadeSlideOut = function(slideIndex) {
11191
11192        var _ = this;
11193
11194        if (_.cssTransitions === false) {
11195
11196            _.$slides.eq(slideIndex).animate({
11197                opacity: 0,
11198                zIndex: _.options.zIndex - 2
11199            }, _.options.speed, _.options.easing);
11200
11201        } else {
11202
11203            _.applyTransition(slideIndex);
11204
11205            _.$slides.eq(slideIndex).css({
11206                opacity: 0,
11207                zIndex: _.options.zIndex - 2
11208            });
11209
11210        }
11211
11212    };
11213
11214    Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
11215
11216        var _ = this;
11217
11218        if (filter !== null) {
11219
11220            _.$slidesCache = _.$slides;
11221
11222            _.unload();
11223
11224            _.$slideTrack.children(this.options.slide).detach();
11225
11226            _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
11227
11228            _.reinit();
11229
11230        }
11231
11232    };
11233
11234    Slick.prototype.focusHandler = function() {
11235
11236        var _ = this;
11237
11238        _.$slider
11239            .off('focus.slick blur.slick')
11240            .on('focus.slick blur.slick', '*', function(event) {
11241
11242            event.stopImmediatePropagation();
11243            var $sf = $(this);
11244
11245            setTimeout(function() {
11246
11247                if( _.options.pauseOnFocus ) {
11248                    _.focussed = $sf.is(':focus');
11249                    _.autoPlay();
11250                }
11251
11252            }, 0);
11253
11254        });
11255    };
11256
11257    Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
11258
11259        var _ = this;
11260        return _.currentSlide;
11261
11262    };
11263
11264    Slick.prototype.getDotCount = function() {
11265
11266        var _ = this;
11267
11268        var breakPoint = 0;
11269        var counter = 0;
11270        var pagerQty = 0;
11271
11272        if (_.options.infinite === true) {
11273            if (_.slideCount <= _.options.slidesToShow) {
11274                 ++pagerQty;
11275            } else {
11276                while (breakPoint < _.slideCount) {
11277                    ++pagerQty;
11278                    breakPoint = counter + _.options.slidesToScroll;
11279                    counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
11280                }
11281            }
11282        } else if (_.options.centerMode === true) {
11283            pagerQty = _.slideCount;
11284        } else if(!_.options.asNavFor) {
11285            pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
11286        }else {
11287            while (breakPoint < _.slideCount) {
11288                ++pagerQty;
11289                breakPoint = counter + _.options.slidesToScroll;
11290                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
11291            }
11292        }
11293
11294        return pagerQty - 1;
11295
11296    };
11297
11298    Slick.prototype.getLeft = function(slideIndex) {
11299
11300        var _ = this,
11301            targetLeft,
11302            verticalHeight,
11303            verticalOffset = 0,
11304            targetSlide,
11305            coef;
11306
11307        _.slideOffset = 0;
11308        verticalHeight = _.$slides.first().outerHeight(true);
11309
11310        if (_.options.infinite === true) {
11311            if (_.slideCount > _.options.slidesToShow) {
11312                _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
11313                coef = -1
11313
11314
11315                if (_.options.vertical === true && _.options.centerMode === true) {
11316                    if (_.options.slidesToShow === 2) {
11317                        coef = -1.5;
11318                    } else if (_.options.slidesToShow === 1) {
11319                        coef = -2
vendor: 47,517 bytes, lines 11319-12922
11319
11320                    }
11321                }
11322                verticalOffset = (verticalHeight * _.options.slidesToShow) * coef;
11323            }
11324            if (_.slideCount % _.options.slidesToScroll !== 0) {
11325                if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
11326                    if (slideIndex > _.slideCount) {
11327                        _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
11328                        verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
11329                    } else {
11330                        _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
11331                        verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
11332                    }
11333                }
11334            }
11335        } else {
11336            if (slideIndex + _.options.slidesToShow > _.slideCount) {
11337                _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
11338                verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
11339            }
11340        }
11341
11342        if (_.slideCount <= _.options.slidesToShow) {
11343            _.slideOffset = 0;
11344            verticalOffset = 0;
11345        }
11346
11347        if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) {
11348            _.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2);
11349        } else if (_.options.centerMode === true && _.options.infinite === true) {
11350            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
11351        } else if (_.options.centerMode === true) {
11352            _.slideOffset = 0;
11353            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
11354        }
11355
11356        if (_.options.vertical === false) {
11357            targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
11358        } else {
11359            targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
11360        }
11361
11362        if (_.options.variableWidth === true) {
11363
11364            if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
11365                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
11366            } else {
11367                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
11368            }
11369
11370            if (_.options.rtl === true) {
11371                if (targetSlide[0]) {
11372                    targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
11373                } else {
11374                    targetLeft =  0;
11375                }
11376            } else {
11377                targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
11378            }
11379
11380            if (_.options.centerMode === true) {
11381                if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
11382                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
11383                } else {
11384                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
11385                }
11386
11387                if (_.options.rtl === true) {
11388                    if (targetSlide[0]) {
11389                        targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
11390                    } else {
11391                        targetLeft =  0;
11392                    }
11393                } else {
11394                    targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
11395                }
11396
11397                targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
11398            }
11399        }
11400
11401        return targetLeft;
11402
11403    };
11404
11405    Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
11406
11407        var _ = this;
11408
11409        return _.options[option];
11410
11411    };
11412
11413    Slick.prototype.getNavigableIndexes = function() {
11414
11415        var _ = this,
11416            breakPoint = 0,
11417            counter = 0,
11418            indexes = [],
11419            max;
11420
11421        if (_.options.infinite === false) {
11422            max = _.slideCount;
11423        } else {
11424            breakPoint = _.options.slidesToScroll * -1;
11425            counter = _.options.slidesToScroll * -1;
11426            max = _.slideCount * 2;
11427        }
11428
11429        while (breakPoint < max) {
11430            indexes.push(breakPoint);
11431            breakPoint = counter + _.options.slidesToScroll;
11432            counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
11433        }
11434
11435        return indexes;
11436
11437    };
11438
11439    Slick.prototype.getSlick = function() {
11440
11441        return this;
11442
11443    };
11444
11445    Slick.prototype.getSlideCount = function() {
11446
11447        var _ = this,
11448            slidesTraversed, swipedSlide, centerOffset;
11449
11450        centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
11451
11452        if (_.options.swipeToSlide === true) {
11453            _.$slideTrack.find('.slick-slide').each(function(index, slide) {
11454                if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
11455                    swipedSlide = slide;
11456                    return false;
11457                }
11458            });
11459
11460            slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
11461
11462            return slidesTraversed;
11463
11464        } else {
11465            return _.options.slidesToScroll;
11466        }
11467
11468    };
11469
11470    Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
11471
11472        var _ = this;
11473
11474        _.changeSlide({
11475            data: {
11476                message: 'index',
11477                index: parseInt(slide)
11478            }
11479        }, dontAnimate);
11480
11481    };
11482
11483    Slick.prototype.init = function(creation) {
11484
11485        var _ = this;
11486
11487        if (!$(_.$slider).hasClass('slick-initialized')) {
11488
11489            $(_.$slider).addClass('slick-initialized');
11490
11491            _.buildRows();
11492            _.buildOut();
11493            _.setProps();
11494            _.startLoad();
11495            _.loadSlider();
11496            _.initializeEvents();
11497            _.updateArrows();
11498            _.updateDots();
11499            _.checkResponsive(true);
11500            _.focusHandler();
11501
11502        }
11503
11504        if (creation) {
11505            _.$slider.trigger('init', [_]);
11506        }
11507
11508        if (_.options.accessibility === true) {
11509            _.initADA();
11510        }
11511
11512        if ( _.options.autoplay ) {
11513
11514            _.paused = false;
11515            _.autoPlay();
11516
11517        }
11518
11519    };
11520
11521    Slick.prototype.initADA = function() {
11522        var _ = this,
11523                numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow),
11524                tabControlIndexes = _.getNavigableIndexes().filter(function(val) {
11525                    return (val >= 0) && (val < _.slideCount);
11526                });
11527
11528        _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
11529            'aria-hidden': 'true',
11530            'tabindex': '-1'
11531        }).find('a, input, button, select').attr({
11532            'tabindex': '-1'
11533        });
11534
11535        if (_.$dots !== null) {
11536            _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
11537                var slideControlIndex = tabControlIndexes.indexOf(i);
11538
11539                $(this).attr({
11540                    'role': 'tabpanel',
11541                    'id': 'slick-slide' + _.instanceUid + i,
11542                    'tabindex': -1
11543                });
11544
11545                if (slideControlIndex !== -1) {
11546                   var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex
11547                   if ($('#' + ariaButtonControl).length) {
11548                     $(this).attr({
11549                         'aria-describedby': ariaButtonControl
11550                     });
11551                   }
11552                }
11553            });
11554
11555            _.$dots.attr('role', 'tablist').find('li').each(function(i) {
11556                var mappedSlideIndex = tabControlIndexes[i];
11557
11558                $(this).attr({
11559                    'role': 'presentation'
11560                });
11561
11562                $(this).find('button').first().attr({
11563                    'role': 'tab',
11564                    'id': 'slick-slide-control' + _.instanceUid + i,
11565                    'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex,
11566                    'aria-label': (i + 1) + ' of ' + numDotGroups,
11567                    'aria-selected': null,
11568                    'tabindex': '-1'
11569                });
11570
11571            }).eq(_.currentSlide).find('button').attr({
11572                'aria-selected': 'true',
11573                'tabindex': '0'
11574            }).end();
11575        }
11576
11577        for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) {
11578          if (_.options.focusOnChange) {
11579            _.$slides.eq(i).attr({'tabindex': '0'});
11580          } else {
11581            _.$slides.eq(i).removeAttr('tabindex');
11582          }
11583        }
11584
11585        _.activateADA();
11586
11587    };
11588
11589    Slick.prototype.initArrowEvents = function() {
11590
11591        var _ = this;
11592
11593        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
11594            _.$prevArrow
11595               .off('click.slick')
11596               .on('click.slick', {
11597                    message: 'previous'
11598               }, _.changeSlide);
11599            _.$nextArrow
11600               .off('click.slick')
11601               .on('click.slick', {
11602                    message: 'next'
11603               }, _.changeSlide);
11604
11605            if (_.options.accessibility === true) {
11606                _.$prevArrow.on('keydown.slick', _.keyHandler);
11607                _.$nextArrow.on('keydown.slick', _.keyHandler);
11608            }
11609        }
11610
11611    };
11612
11613    Slick.prototype.initDotEvents = function() {
11614
11615        var _ = this;
11616
11617        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
11618            $('li', _.$dots).on('click.slick', {
11619                message: 'index'
11620            }, _.changeSlide);
11621
11622            if (_.options.accessibility === true) {
11623                _.$dots.on('keydown.slick', _.keyHandler);
11624            }
11625        }
11626
11627        if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) {
11628
11629            $('li', _.$dots)
11630                .on('mouseenter.slick', $.proxy(_.interrupt, _, true))
11631                .on('mouseleave.slick', $.proxy(_.interrupt, _, false));
11632
11633        }
11634
11635    };
11636
11637    Slick.prototype.initSlideEvents = function() {
11638
11639        var _ = this;
11640
11641        if ( _.options.pauseOnHover ) {
11642
11643            _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
11644            _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
11645
11646        }
11647
11648    };
11649
11650    Slick.prototype.initializeEvents = function() {
11651
11652        var _ = this;
11653
11654        _.initArrowEvents();
11655
11656        _.initDotEvents();
11657        _.initSlideEvents();
11658
11659        _.$list.on('touchstart.slick mousedown.slick', {
11660            action: 'start'
11661        }, _.swipeHandler);
11662        _.$list.on('touchmove.slick mousemove.slick', {
11663            action: 'move'
11664        }, _.swipeHandler);
11665        _.$list.on('touchend.slick mouseup.slick', {
11666            action: 'end'
11667        }, _.swipeHandler);
11668        _.$list.on('touchcancel.slick mouseleave.slick', {
11669            action: 'end'
11670        }, _.swipeHandler);
11671
11672        _.$list.on('click.slick', _.clickHandler);
11673
11674        $(document).on(_.visibilityChange, $.proxy(_.visibility, _));
11675
11676        if (_.options.accessibility === true) {
11677            _.$list.on('keydown.slick', _.keyHandler);
11678        }
11679
11680        if (_.options.focusOnSelect === true) {
11681            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
11682        }
11683
11684        $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
11685
11686        $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
11687
11688        $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
11689
11690        $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
11691        $(_.setPosition);
11692
11693    };
11694
11695    Slick.prototype.initUI = function() {
11696
11697        var _ = this;
11698
11699        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
11700
11701            _.$prevArrow.show();
11702            _.$nextArrow.show();
11703
11704        }
11705
11706        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
11707
11708            _.$dots.show();
11709
11710        }
11711
11712    };
11713
11714    Slick.prototype.keyHandler = function(event) {
11715
11716        var _ = this;
11717         //Dont slide if the cursor is inside the form fields and arrow keys are pressed
11718        if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
11719            if (event.keyCode === 37 && _.options.accessibility === true) {
11720                _.changeSlide({
11721                    data: {
11722                        message: _.options.rtl === true ? 'next' :  'previous'
11723                    }
11724                });
11725            } else if (event.keyCode === 39 && _.options.accessibility === true) {
11726                _.changeSlide({
11727                    data: {
11728                        message: _.options.rtl === true ? 'previous' : 'next'
11729                    }
11730                });
11731            }
11732        }
11733
11734    };
11735
11736    Slick.prototype.lazyLoad = function() {
11737
11738        var _ = this,
11739            loadRange, cloneRange, rangeStart, rangeEnd;
11740
11741        function loadImages(imagesScope) {
11742
11743            $('img[data-lazy]', imagesScope).each(function() {
11744
11745                var image = $(this),
11746                    imageSource = $(this).attr('data-lazy'),
11747                    imageSrcSet = $(this).attr('data-srcset'),
11748                    imageSizes  = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'),
11749                    imageToLoad = document.createElement('img');
11750
11751                imageToLoad.onload = function() {
11752
11753                    image
11754                        .animate({ opacity: 0 }, 100, function() {
11755
11756                            if (imageSrcSet) {
11757                                image
11758                                    .attr('srcset', imageSrcSet );
11759
11760                                if (imageSizes) {
11761                                    image
11762                                        .attr('sizes', imageSizes );
11763                                }
11764                            }
11765
11766                            image
11767                                .attr('src', imageSource)
11768                                .animate({ opacity: 1 }, 200, function() {
11769                                    image
11770                                        .removeAttr('data-lazy data-srcset data-sizes')
11771                                        .removeClass('slick-loading');
11772                                });
11773                            _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
11774                        });
11775
11776                };
11777
11778                imageToLoad.onerror = function() {
11779
11780                    image
11781                        .removeAttr( 'data-lazy' )
11782                        .removeClass( 'slick-loading' )
11783                        .addClass( 'slick-lazyload-error' );
11784
11785                    _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
11786
11787                };
11788
11789                imageToLoad.src = imageSource;
11790
11791            });
11792
11793        }
11794
11795        if (_.options.centerMode === true) {
11796            if (_.options.infinite === true) {
11797                rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
11798                rangeEnd = rangeStart + _.options.slidesToShow + 2;
11799            } else {
11800                rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
11801                rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
11802            }
11803        } else {
11804            rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
11805            rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
11806            if (_.options.fade === true) {
11807                if (rangeStart > 0) rangeStart--;
11808                if (rangeEnd <= _.slideCount) rangeEnd++;
11809            }
11810        }
11811
11812        loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
11813
11814        if (_.options.lazyLoad === 'anticipated') {
11815            var prevSlide = rangeStart - 1,
11816                nextSlide = rangeEnd,
11817                $slides = _.$slider.find('.slick-slide');
11818
11819            for (var i = 0; i < _.options.slidesToScroll; i++) {
11820                if (prevSlide < 0) prevSlide = _.slideCount - 1;
11821                loadRange = loadRange.add($slides.eq(prevSlide));
11822                loadRange = loadRange.add($slides.eq(nextSlide));
11823                prevSlide--;
11824                nextSlide++;
11825            }
11826        }
11827
11828        loadImages(loadRange);
11829
11830        if (_.slideCount <= _.options.slidesToShow) {
11831            cloneRange = _.$slider.find('.slick-slide');
11832            loadImages(cloneRange);
11833        } else
11834        if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
11835            cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
11836            loadImages(cloneRange);
11837        } else if (_.currentSlide === 0) {
11838            cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
11839            loadImages(cloneRange);
11840        }
11841
11842    };
11843
11844    Slick.prototype.loadSlider = function() {
11845
11846        var _ = this;
11847
11848        _.setPosition();
11849
11850        _.$slideTrack.css({
11851            opacity: 1
11852        });
11853
11854        _.$slider.removeClass('slick-loading');
11855
11856        _.initUI();
11857
11858        if (_.options.lazyLoad === 'progressive') {
11859            _.progressiveLazyLoad();
11860        }
11861
11862    };
11863
11864    Slick.prototype.next = Slick.prototype.slickNext = function() {
11865
11866        var _ = this;
11867
11868        _.changeSlide({
11869            data: {
11870                message: 'next'
11871            }
11872        });
11873
11874    };
11875
11876    Slick.prototype.orientationChange = function() {
11877
11878        var _ = this;
11879
11880        _.checkResponsive();
11881        _.setPosition();
11882
11883    };
11884
11885    Slick.prototype.pause = Slick.prototype.slickPause = function() {
11886
11887        var _ = this;
11888
11889        _.autoPlayClear();
11890        _.paused = true;
11891
11892    };
11893
11894    Slick.prototype.play = Slick.prototype.slickPlay = function() {
11895
11896        var _ = this;
11897
11898        _.autoPlay();
11899        _.options.autoplay = true;
11900        _.paused = false;
11901        _.focussed = false;
11902        _.interrupted = false;
11903
11904    };
11905
11906    Slick.prototype.postSlide = function(index) {
11907
11908        var _ = this;
11909
11910        if( !_.unslicked ) {
11911
11912            _.$slider.trigger('afterChange', [_, index]);
11913
11914            _.animating = false;
11915
11916            if (_.slideCount > _.options.slidesToShow) {
11917                _.setPosition();
11918            }
11919
11920            _.swipeLeft = null;
11921
11922            if ( _.options.autoplay ) {
11923                _.autoPlay();
11924            }
11925
11926            if (_.options.accessibility === true) {
11927                _.initADA();
11928
11929                if (_.options.focusOnChange) {
11930                    var $currentSlide = $(_.$slides.get(_.currentSlide));
11931                    $currentSlide.attr('tabindex', 0).focus();
11932                }
11933            }
11934
11935        }
11936
11937    };
11938
11939    Slick.prototype.prev = Slick.prototype.slickPrev = function() {
11940
11941        var _ = this;
11942
11943        _.changeSlide({
11944            data: {
11945                message: 'previous'
11946            }
11947        });
11948
11949    };
11950
11951    Slick.prototype.preventDefault = function(event) {
11952
11953        event.preventDefault();
11954
11955    };
11956
11957    Slick.prototype.progressiveLazyLoad = function( tryCount ) {
11958
11959        tryCount = tryCount || 1;
11960
11961        var _ = this,
11962            $imgsToLoad = $( 'img[data-lazy]', _.$slider ),
11963            image,
11964            imageSource,
11965            imageSrcSet,
11966            imageSizes,
11967            imageToLoad;
11968
11969        if ( $imgsToLoad.length ) {
11970
11971            image = $imgsToLoad.first();
11972            imageSource = image.attr('data-lazy');
11973            imageSrcSet = image.attr('data-srcset');
11974            imageSizes  = image.attr('data-sizes') || _.$slider.attr('data-sizes');
11975            imageToLoad = document.createElement('img');
11976
11977            imageToLoad.onload = function() {
11978
11979                if (imageSrcSet) {
11980                    image
11981                        .attr('srcset', imageSrcSet );
11982
11983                    if (imageSizes) {
11984                        image
11985                            .attr('sizes', imageSizes );
11986                    }
11987                }
11988
11989                image
11990                    .attr( 'src', imageSource )
11991                    .removeAttr('data-lazy data-srcset data-sizes')
11992                    .removeClass('slick-loading');
11993
11994                if ( _.options.adaptiveHeight === true ) {
11995                    _.setPosition();
11996                }
11997
11998                _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
11999                _.progressiveLazyLoad();
12000
12001            };
12002
12003            imageToLoad.onerror = function() {
12004
12005                if ( tryCount < 3 ) {
12006
12007                    /**
12008                     * try to load the image 3 times,
12009                     * leave a slight delay so we don't get
12010                     * servers blocking the request.
12011                     */
12012                    setTimeout( function() {
12013                        _.progressiveLazyLoad( tryCount + 1 );
12014                    }, 500 );
12015
12016                } else {
12017
12018                    image
12019                        .removeAttr( 'data-lazy' )
12020                        .removeClass( 'slick-loading' )
12021                        .addClass( 'slick-lazyload-error' );
12022
12023                    _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
12024
12025                    _.progressiveLazyLoad();
12026
12027                }
12028
12029            };
12030
12031            imageToLoad.src = imageSource;
12032
12033        } else {
12034
12035            _.$slider.trigger('allImagesLoaded', [ _ ]);
12036
12037        }
12038
12039    };
12040
12041    Slick.prototype.refresh = function( initializing ) {
12042
12043        var _ = this, currentSlide, lastVisibleIndex;
12044
12045        lastVisibleIndex = _.slideCount - _.options.slidesToShow;
12046
12047        // in non-infinite sliders, we don't want to go past the
12048        // last visible index.
12049        if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
12050            _.currentSlide = lastVisibleIndex;
12051        }
12052
12053        // if less slides than to show, go to start.
12054        if ( _.slideCount <= _.options.slidesToShow ) {
12055            _.currentSlide = 0;
12056
12057        }
12058
12059        currentSlide = _.currentSlide;
12060
12061        _.destroy(true);
12062
12063        $.extend(_, _.initials, { currentSlide: currentSlide });
12064
12065        _.init();
12066
12067        if( !initializing ) {
12068
12069            _.changeSlide({
12070                data: {
12071                    message: 'index',
12072                    index: currentSlide
12073                }
12074            }, false);
12075
12076        }
12077
12078    };
12079
12080    Slick.prototype.registerBreakpoints = function() {
12081
12082        var _ = this, breakpoint, currentBreakpoint, l,
12083            responsiveSettings = _.options.responsive || null;
12084
12085        if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
12086
12087            _.respondTo = _.options.respondTo || 'window';
12088
12089            for ( breakpoint in responsiveSettings ) {
12090
12091                l = _.breakpoints.length-1;
12092
12093                if (responsiveSettings.hasOwnProperty(breakpoint)) {
12094                    currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
12095
12096                    // loop through the breakpoints and cut out any existing
12097                    // ones with the same breakpoint number, we don't want dupes.
12098                    while( l >= 0 ) {
12099                        if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
12100                            _.breakpoints.splice(l,1);
12101                        }
12102                        l--;
12103                    }
12104
12105                    _.breakpoints.push(currentBreakpoint);
12106                    _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
12107
12108                }
12109
12110            }
12111
12112            _.breakpoints.sort(function(a, b) {
12113                return ( _.options.mobileFirst ) ? a-b : b-a;
12114            });
12115
12116        }
12117
12118    };
12119
12120    Slick.prototype.reinit = function() {
12121
12122        var _ = this;
12123
12124        _.$slides =
12125            _.$slideTrack
12126                .children(_.options.slide)
12127                .addClass('slick-slide');
12128
12129        _.slideCount = _.$slides.length;
12130
12131        if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
12132            _.currentSlide = _.currentSlide - _.options.slidesToScroll;
12133        }
12134
12135        if (_.slideCount <= _.options.slidesToShow) {
12136            _.currentSlide = 0;
12137        }
12138
12139        _.registerBreakpoints();
12140
12141        _.setProps();
12142        _.setupInfinite();
12143        _.buildArrows();
12144        _.updateArrows();
12145        _.initArrowEvents();
12146        _.buildDots();
12147        _.updateDots();
12148        _.initDotEvents();
12149        _.cleanUpSlideEvents();
12150        _.initSlideEvents();
12151
12152        _.checkResponsive(false, true);
12153
12154        if (_.options.focusOnSelect === true) {
12155            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
12156        }
12157
12158        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
12159
12160        _.setPosition();
12161        _.focusHandler();
12162
12163        _.paused = !_.options.autoplay;
12164        _.autoPlay();
12165
12166        _.$slider.trigger('reInit', [_]);
12167
12168    };
12169
12170    Slick.prototype.resize = function() {
12171
12172        var _ = this;
12173
12174        if ($(window).width() !== _.windowWidth) {
12175            clearTimeout(_.windowDelay);
12176            _.windowDelay = window.setTimeout(function() {
12177                _.windowWidth = $(window).width();
12178                _.checkResponsive();
12179                if( !_.unslicked ) { _.setPosition(); }
12180            }, 50);
12181        }
12182    };
12183
12184    Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
12185
12186        var _ = this;
12187
12188        if (typeof(index) === 'boolean') {
12189            removeBefore = index;
12190            index = removeBefore === true ? 0 : _.slideCount - 1;
12191        } else {
12192            index = removeBefore === true ? --index : index;
12193        }
12194
12195        if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
12196            return false;
12197        }
12198
12199        _.unload();
12200
12201        if (removeAll === true) {
12202            _.$slideTrack.children().remove();
12203        } else {
12204            _.$slideTrack.children(this.options.slide).eq(index).remove();
12205        }
12206
12207        _.$slides = _.$slideTrack.children(this.options.slide);
12208
12209        _.$slideTrack.children(this.options.slide).detach();
12210
12211        _.$slideTrack.append(_.$slides);
12212
12213        _.$slidesCache = _.$slides;
12214
12215        _.reinit();
12216
12217    };
12218
12219    Slick.prototype.setCSS = function(position) {
12220
12221        var _ = this,
12222            positionProps = {},
12223            x, y;
12224
12225        if (_.options.rtl === true) {
12226            position = -position;
12227        }
12228        x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
12229        y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
12230
12231        positionProps[_.positionProp] = position;
12232
12233        if (_.transformsEnabled === false) {
12234            _.$slideTrack.css(positionProps);
12235        } else {
12236            positionProps = {};
12237            if (_.cssTransitions === false) {
12238                positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
12239                _.$slideTrack.css(positionProps);
12240            } else {
12241                positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
12242                _.$slideTrack.css(positionProps);
12243            }
12244        }
12245
12246    };
12247
12248    Slick.prototype.setDimensions = function() {
12249
12250        var _ = this;
12251
12252        if (_.options.vertical === false) {
12253            if (_.options.centerMode === true) {
12254                _.$list.css({
12255                    padding: ('0px ' + _.options.centerPadding)
12256                });
12257            }
12258        } else {
12259            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
12260            if (_.options.centerMode === true) {
12261                _.$list.css({
12262                    padding: (_.options.centerPadding + ' 0px')
12263                });
12264            }
12265        }
12266
12267        _.listWidth = _.$list.width();
12268        _.listHeight = _.$list.height();
12269
12270
12271        if (_.options.vertical === false && _.options.variableWidth === false) {
12272            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
12273            _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
12274
12275        } else if (_.options.variableWidth === true) {
12276            _.$slideTrack.width(5000 * _.slideCount);
12277        } else {
12278            _.slideWidth = Math.ceil(_.listWidth);
12279            _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
12280        }
12281
12282        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
12283        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
12284
12285    };
12286
12287    Slick.prototype.setFade = function() {
12288
12289        var _ = this,
12290            targetLeft;
12291
12292        _.$slides.each(function(index, element) {
12293            targetLeft = (_.slideWidth * index) * -1;
12294            if (_.options.rtl === true) {
12295                $(element).css({
12296                    position: 'relative',
12297                    right: targetLeft,
12298                    top: 0,
12299                    zIndex: _.options.zIndex - 2,
12300                    opacity: 0
12301                });
12302            } else {
12303                $(element).css({
12304                    position: 'relative',
12305                    left: targetLeft,
12306                    top: 0,
12307                    zIndex: _.options.zIndex - 2,
12308                    opacity: 0
12309                });
12310            }
12311        });
12312
12313        _.$slides.eq(_.currentSlide).css({
12314            zIndex: _.options.zIndex - 1,
12315            opacity: 1
12316        });
12317
12318    };
12319
12320    Slick.prototype.setHeight = function() {
12321
12322        var _ = this;
12323
12324        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
12325            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
12326            _.$list.css('height', targetHeight);
12327        }
12328
12329    };
12330
12331    Slick.prototype.setOption =
12332    Slick.prototype.slickSetOption = function() {
12333
12334        /**
12335         * accepts arguments in format of:
12336         *
12337         *  - for changing a single option's value:
12338         *     .slick("setOption", option, value, refresh )
12339         *
12340         *  - for changing a set of responsive options:
12341         *     .slick("setOption", 'responsive', [{}, ...], refresh )
12342         *
12343         *  - for updating multiple values at once (not responsive)
12344         *     .slick("setOption", { 'option': value, ... }, refresh )
12345         */
12346
12347        var _ = this, l, item, option, value, refresh = false, type;
12348
12349        if( $.type( arguments[0] ) === 'object' ) {
12350
12351            option =  arguments[0];
12352            refresh = arguments[1];
12353            type = 'multiple';
12354
12355        } else if ( $.type( arguments[0] ) === 'string' ) {
12356
12357            option =  arguments[0];
12358            value = arguments[1];
12359            refresh = arguments[2];
12360
12361            if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
12362
12363                type = 'responsive';
12364
12365            } else if ( typeof arguments[1] !== 'undefined' ) {
12366
12367                type = 'single';
12368
12369            }
12370
12371        }
12372
12373        if ( type === 'single' ) {
12374
12375            _.options[option] = value;
12376
12377
12378        } else if ( type === 'multiple' ) {
12379
12380            $.each( option , function( opt, val ) {
12381
12382                _.options[opt] = val;
12383
12384            });
12385
12386
12387        } else if ( type === 'responsive' ) {
12388
12389            for ( item in value ) {
12390
12391                if( $.type( _.options.responsive ) !== 'array' ) {
12392
12393                    _.options.responsive = [ value[item] ];
12394
12395                } else {
12396
12397                    l = _.options.responsive.length-1;
12398
12399                    // loop through the responsive object and splice out duplicates.
12400                    while( l >= 0 ) {
12401
12402                        if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
12403
12404                            _.options.responsive.splice(l,1);
12405
12406                        }
12407
12408                        l--;
12409
12410                    }
12411
12412                    _.options.responsive.push( value[item] );
12413
12414                }
12415
12416            }
12417
12418        }
12419
12420        if ( refresh ) {
12421
12422            _.unload();
12423            _.reinit();
12424
12425        }
12426
12427    };
12428
12429    Slick.prototype.setPosition = function() {
12430
12431        var _ = this;
12432
12433        _.setDimensions();
12434
12435        _.setHeight();
12436
12437        if (_.options.fade === false) {
12438            _.setCSS(_.getLeft(_.currentSlide));
12439        } else {
12440            _.setFade();
12441        }
12442
12443        _.$slider.trigger('setPosition', [_]);
12444
12445    };
12446
12447    Slick.prototype.setProps = function() {
12448
12449        var _ = this,
12450            bodyStyle = document.body.style;
12451
12452        _.positionProp = _.options.vertical === true ? 'top' : 'left';
12453
12454        if (_.positionProp === 'top') {
12455            _.$slider.addClass('slick-vertical');
12456        } else {
12457            _.$slider.removeClass('slick-vertical');
12458        }
12459
12460        if (bodyStyle.WebkitTransition !== undefined ||
12461            bodyStyle.MozTransition !== undefined ||
12462            bodyStyle.msTransition !== undefined) {
12463            if (_.options.useCSS === true) {
12464                _.cssTransitions = true;
12465            }
12466        }
12467
12468        if ( _.options.fade ) {
12469            if ( typeof _.options.zIndex === 'number' ) {
12470                if( _.options.zIndex < 3 ) {
12471                    _.options.zIndex = 3;
12472                }
12473            } else {
12474                _.options.zIndex = _.defaults.zIndex;
12475            }
12476        }
12477
12478        if (bodyStyle.OTransform !== undefined) {
12479            _.animType = 'OTransform';
12480            _.transformType = '-o-transform';
12481            _.transitionType = 'OTransition';
12482            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
12483        }
12484        if (bodyStyle.MozTransform !== undefined) {
12485            _.animType = 'MozTransform';
12486            _.transformType = '-moz-transform';
12487            _.transitionType = 'MozTransition';
12488            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
12489        }
12490        if (bodyStyle.webkitTransform !== undefined) {
12491            _.animType = 'webkitTransform';
12492            _.transformType = '-webkit-transform';
12493            _.transitionType = 'webkitTransition';
12494            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
12495        }
12496        if (bodyStyle.msTransform !== undefined) {
12497            _.animType = 'msTransform';
12498            _.transformType = '-ms-transform';
12499            _.transitionType = 'msTransition';
12500            if (bodyStyle.msTransform === undefined) _.animType = false;
12501        }
12502        if (bodyStyle.transform !== undefined && _.animType !== false) {
12503            _.animType = 'transform';
12504            _.transformType = 'transform';
12505            _.transitionType = 'transition';
12506        }
12507        _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
12508    };
12509
12510
12511    Slick.prototype.setSlideClasses = function(index) {
12512
12513        var _ = this,
12514            centerOffset, allSlides, indexOffset, remainder;
12515
12516        allSlides = _.$slider
12517            .find('.slick-slide')
12518            .removeClass('slick-active slick-center slick-current')
12519            .attr('aria-hidden', 'true');
12520
12521        _.$slides
12522            .eq(index)
12523            .addClass('slick-current');
12524
12525        if (_.options.centerMode === true) {
12526
12527            var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0;
12528
12529            centerOffset = Math.floor(_.options.slidesToShow / 2);
12530
12531            if (_.options.infinite === true) {
12532
12533                if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
12534                    _.$slides
12535                        .slice(index - centerOffset + evenCoef, index + centerOffset + 1)
12536                        .addClass('slick-active')
12537                        .attr('aria-hidden', 'false');
12538
12539                } else {
12540
12541                    indexOffset = _.options.slidesToShow + index;
12542                    allSlides
12543                        .slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2)
12544                        .addClass('slick-active')
12545                        .attr('aria-hidden', 'false');
12546
12547                }
12548
12549                if (index === 0) {
12550
12551                    allSlides
12552                        .eq(allSlides.length - 1 - _.options.slidesToShow)
12553                        .addClass('slick-center');
12554
12555                } else if (index === _.slideCount - 1) {
12556
12557                    allSlides
12558                        .eq(_.options.slidesToShow)
12559                        .addClass('slick-center');
12560
12561                }
12562
12563            }
12564
12565            _.$slides
12566                .eq(index)
12567                .addClass('slick-center');
12568
12569        } else {
12570
12571            if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
12572
12573                _.$slides
12574                    .slice(index, index + _.options.slidesToShow)
12575                    .addClass('slick-active')
12576                    .attr('aria-hidden', 'false');
12577
12578            } else if (allSlides.length <= _.options.slidesToShow) {
12579
12580                allSlides
12581                    .addClass('slick-active')
12582                    .attr('aria-hidden', 'false');
12583
12584            } else {
12585
12586                remainder = _.slideCount % _.options.slidesToShow;
12587                indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
12588
12589                if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
12590
12591                    allSlides
12592                        .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
12593                        .addClass('slick-active')
12594                        .attr('aria-hidden', 'false');
12595
12596                } else {
12597
12598                    allSlides
12599                        .slice(indexOffset, indexOffset + _.options.slidesToShow)
12600                        .addClass('slick-active')
12601                        .attr('aria-hidden', 'false');
12602
12603                }
12604
12605            }
12606
12607        }
12608
12609        if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') {
12610            _.lazyLoad();
12611        }
12612    };
12613
12614    Slick.prototype.setupInfinite = function() {
12615
12616        var _ = this,
12617            i, slideIndex, infiniteCount;
12618
12619        if (_.options.fade === true) {
12620            _.options.centerMode = false;
12621        }
12622
12623        if (_.options.infinite === true && _.options.fade === false) {
12624
12625            slideIndex = null;
12626
12627            if (_.slideCount > _.options.slidesToShow) {
12628
12629                if (_.options.centerMode === true) {
12630                    infiniteCount = _.options.slidesToShow + 1;
12631                } else {
12632                    infiniteCount = _.options.slidesToShow;
12633                }
12634
12635                for (i = _.slideCount; i > (_.slideCount -
12636                        infiniteCount); i -= 1) {
12637                    slideIndex = i - 1;
12638                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
12639                        .attr('data-slick-index', slideIndex - _.slideCount)
12640                        .prependTo(_.$slideTrack).addClass('slick-cloned');
12641                }
12642                for (i = 0; i < infiniteCount  + _.slideCount; i += 1) {
12643                    slideIndex = i;
12644                    $(_.$slides[slideIndex]).clone(true).attr('id', '')
12645                        .attr('data-slick-index', slideIndex + _.slideCount)
12646                        .appendTo(_.$slideTrack).addClass('slick-cloned');
12647                }
12648                _.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
12649                    $(this).attr('id', '');
12650                });
12651
12652            }
12653
12654        }
12655
12656    };
12657
12658    Slick.prototype.interrupt = function( toggle ) {
12659
12660        var _ = this;
12661
12662        if( !toggle ) {
12663            _.autoPlay();
12664        }
12665        _.interrupted = toggle;
12666
12667    };
12668
12669    Slick.prototype.selectHandler = function(event) {
12670
12671        var _ = this;
12672
12673        var targetElement =
12674            $(event.target).is('.slick-slide') ?
12675                $(event.target) :
12676                $(event.target).parents('.slick-slide');
12677
12678        var index = parseInt(targetElement.attr('data-slick-index'));
12679
12680        if (!index) index = 0;
12681
12682        if (_.slideCount <= _.options.slidesToShow) {
12683
12684            _.slideHandler(index, false, true);
12685            return;
12686
12687        }
12688
12689        _.slideHandler(index);
12690
12691    };
12692
12693    Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
12694
12695        var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
12696            _ = this, navTarget;
12697
12698        sync = sync || false;
12699
12700        if (_.animating === true && _.options.waitForAnimate === true) {
12701            return;
12702        }
12703
12704        if (_.options.fade === true && _.currentSlide === index) {
12705            return;
12706        }
12707
12708        if (sync === false) {
12709            _.asNavFor(index);
12710        }
12711
12712        targetSlide = index;
12713        targetLeft = _.getLeft(targetSlide);
12714        slideLeft = _.getLeft(_.currentSlide);
12715
12716        _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
12717
12718        if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
12719            if (_.options.fade === false) {
12720                targetSlide = _.currentSlide;
12721                if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
12722                    _.animateSlide(slideLeft, function() {
12723                        _.postSlide(targetSlide);
12724                    });
12725                } else {
12726                    _.postSlide(targetSlide);
12727                }
12728            }
12729            return;
12730        } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
12731            if (_.options.fade === false) {
12732                targetSlide = _.currentSlide;
12733                if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
12734                    _.animateSlide(slideLeft, function() {
12735                        _.postSlide(targetSlide);
12736                    });
12737                } else {
12738                    _.postSlide(targetSlide);
12739                }
12740            }
12741            return;
12742        }
12743
12744        if ( _.options.autoplay ) {
12745            clearInterval(_.autoPlayTimer);
12746        }
12747
12748        if (targetSlide < 0) {
12749            if (_.slideCount % _.options.slidesToScroll !== 0) {
12750                animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
12751            } else {
12752                animSlide = _.slideCount + targetSlide;
12753            }
12754        } else if (targetSlide >= _.slideCount) {
12755            if (_.slideCount % _.options.slidesToScroll !== 0) {
12756                animSlide = 0;
12757            } else {
12758                animSlide = targetSlide - _.slideCount;
12759            }
12760        } else {
12761            animSlide = targetSlide;
12762        }
12763
12764        _.animating = true;
12765
12766        _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
12767
12768        oldSlide = _.currentSlide;
12769        _.currentSlide = animSlide;
12770
12771        _.setSlideClasses(_.currentSlide);
12772
12773        if ( _.options.asNavFor ) {
12774
12775            navTarget = _.getNavTarget();
12776            navTarget = navTarget.slick('getSlick');
12777
12778            if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
12779                navTarget.setSlideClasses(_.currentSlide);
12780            }
12781
12782        }
12783
12784        _.updateDots();
12785        _.updateArrows();
12786
12787        if (_.options.fade === true) {
12788            if (dontAnimate !== true) {
12789
12790                _.fadeSlideOut(oldSlide);
12791
12792                _.fadeSlide(animSlide, function() {
12793                    _.postSlide(animSlide);
12794                });
12795
12796            } else {
12797                _.postSlide(animSlide);
12798            }
12799            _.animateHeight();
12800            return;
12801        }
12802
12803        if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
12804            _.animateSlide(targetLeft, function() {
12805                _.postSlide(animSlide);
12806            });
12807        } else {
12808            _.postSlide(animSlide);
12809        }
12810
12811    };
12812
12813    Slick.prototype.startLoad = function() {
12814
12815        var _ = this;
12816
12817        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
12818
12819            _.$prevArrow.hide();
12820            _.$nextArrow.hide();
12821
12822        }
12823
12824        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
12825
12826            _.$dots.hide();
12827
12828        }
12829
12830        _.$slider.addClass('slick-loading');
12831
12832    };
12833
12834    Slick.prototype.swipeDirection = function() {
12835
12836        var xDist, yDist, r, swipeAngle, _ = this;
12837
12838        xDist = _.touchObject.startX - _.touchObject.curX;
12839        yDist = _.touchObject.startY - _.touchObject.curY;
12840        r = Math.atan2(yDist, xDist);
12841
12842        swipeAngle = Math.round(r * 180 / Math.PI);
12843        if (swipeAngle < 0) {
12844            swipeAngle = 360 - Math.abs(swipeAngle);
12845        }
12846
12847        if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
12848            return (_.options.rtl === false ? 'left' : 'right');
12849        }
12850        if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
12851            return (_.options.rtl === false ? 'left' : 'right');
12852        }
12853        if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
12854            return (_.options.rtl === false ? 'right' : 'left');
12855        }
12856        if (_.options.verticalSwiping === true) {
12857            if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
12858                return 'down';
12859            } else {
12860                return 'up';
12861            }
12862        }
12863
12864        return 'vertical';
12865
12866    };
12867
12868    Slick.prototype.swipeEnd = function(event) {
12869
12870        var _ = this,
12871            slideCount,
12872            direction;
12873
12874        _.dragging = false;
12875        _.swiping = false;
12876
12877        if (_.scrolling) {
12878            _.scrolling = false;
12879            return false;
12880        }
12881
12882        _.interrupted = false;
12883        _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
12884
12885        if ( _.touchObject.curX === undefined ) {
12886            return false;
12887        }
12888
12889        if ( _.touchObject.edgeHit === true ) {
12890            _.$slider.trigger('edge', [_, _.swipeDirection() ]);
12891        }
12892
12893        if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
12894
12895            direction = _.swipeDirection();
12896
12897            switch ( direction ) {
12898
12899                case 'left':
12900                case 'down':
12901
12902                    slideCount =
12903                        _.options.swipeToSlide ?
12904                            _.checkNavigable( _.currentSlide + _.getSlideCount() ) :
12905                            _.currentSlide + _.getSlideCount();
12906
12907                    _.currentDirection = 0;
12908
12909                    break;
12910
12911                case 'right':
12912                case 'up':
12913
12914                    slideCount =
12915                        _.options.swipeToSlide ?
12916                            _.checkNavigable( _.currentSlide - _.getSlideCount() ) :
12917                            _.currentSlide - _.getSlideCount();
12918
12919                    _.currentDirection = 1;
12920
12921                    break;
12922
vendor: 9,281 bytes, lines 12923-13258
12923                default:
12924
12925
12926            }
12927
12928            if( direction != 'vertical' ) {
12929
12930                _.slideHandler( slideCount );
12931                _.touchObject = {};
12932                _.$slider.trigger('swipe', [_, direction ]);
12933
12934            }
12935
12936        } else {
12937
12938            if ( _.touchObject.startX !== _.touchObject.curX ) {
12939
12940                _.slideHandler( _.currentSlide );
12941                _.touchObject = {};
12942
12943            }
12944
12945        }
12946
12947    };
12948
12949    Slick.prototype.swipeHandler = function(event) {
12950
12951        var _ = this;
12952
12953        if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
12954            return;
12955        } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
12956            return;
12957        }
12958
12959        _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
12960            event.originalEvent.touches.length : 1;
12961
12962        _.touchObject.minSwipe = _.listWidth / _.options
12963            .touchThreshold;
12964
12965        if (_.options.verticalSwiping === true) {
12966            _.touchObject.minSwipe = _.listHeight / _.options
12967                .touchThreshold;
12968        }
12969
12970        switch (event.data.action) {
12971
12972            case 'start':
12973                _.swipeStart(event);
12974                break;
12975
12976            case 'move':
12977                _.swipeMove(event);
12978                break;
12979
12980            case 'end':
12981                _.swipeEnd(event);
12982                break;
12983
12984        }
12985
12986    };
12987
12988    Slick.prototype.swipeMove = function(event) {
12989
12990        var _ = this,
12991            edgeWasHit = false,
12992            curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength;
12993
12994        touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
12995
12996        if (!_.dragging || _.scrolling || touches && touches.length !== 1) {
12997            return false;
12998        }
12999
13000        curLeft = _.getLeft(_.currentSlide);
13001
13002        _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
13003        _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
13004
13005        _.touchObject.swipeLength = Math.round(Math.sqrt(
13006            Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
13007
13008        verticalSwipeLength = Math.round(Math.sqrt(
13009            Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
13010
13011        if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > 4) {
13012            _.scrolling = true;
13013            return false;
13014        }
13015
13016        if (_.options.verticalSwiping === true) {
13017            _.touchObject.swipeLength = verticalSwipeLength;
13018        }
13019
13020        swipeDirection = _.swipeDirection();
13021
13022        if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
13023            _.swiping = true;
13024            event.preventDefault();
13025        }
13026
13027        positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
13028        if (_.options.verticalSwiping === true) {
13029            positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
13030        }
13031
13032
13033        swipeLength = _.touchObject.swipeLength;
13034
13035        _.touchObject.edgeHit = false;
13036
13037        if (_.options.infinite === false) {
13038            if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
13039                swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
13040                _.touchObject.edgeHit = true;
13041            }
13042        }
13043
13044        if (_.options.vertical === false) {
13045            _.swipeLeft = curLeft + swipeLength * positionOffset;
13046        } else {
13047            _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
13048        }
13049        if (_.options.verticalSwiping === true) {
13050            _.swipeLeft = curLeft + swipeLength * positionOffset;
13051        }
13052
13053        if (_.options.fade === true || _.options.touchMove === false) {
13054            return false;
13055        }
13056
13057        if (_.animating === true) {
13058            _.swipeLeft = null;
13059            return false;
13060        }
13061
13062        _.setCSS(_.swipeLeft);
13063
13064    };
13065
13066    Slick.prototype.swipeStart = function(event) {
13067
13068        var _ = this,
13069            touches;
13070
13071        _.interrupted = true;
13072
13073        if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
13074            _.touchObject = {};
13075            return false;
13076        }
13077
13078        if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
13079            touches = event.originalEvent.touches[0];
13080        }
13081
13082        _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
13083        _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
13084
13085        _.dragging = true;
13086
13087    };
13088
13089    Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
13090
13091        var _ = this;
13092
13093        if (_.$slidesCache !== null) {
13094
13095            _.unload();
13096
13097            _.$slideTrack.children(this.options.slide).detach();
13098
13099            _.$slidesCache.appendTo(_.$slideTrack);
13100
13101            _.reinit();
13102
13103        }
13104
13105    };
13106
13107    Slick.prototype.unload = function() {
13108
13109        var _ = this;
13110
13111        $('.slick-cloned', _.$slider).remove();
13112
13113        if (_.$dots) {
13114            _.$dots.remove();
13115        }
13116
13117        if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
13118            _.$prevArrow.remove();
13119        }
13120
13121        if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
13122            _.$nextArrow.remove();
13123        }
13124
13125        _.$slides
13126            .removeClass('slick-slide slick-active slick-visible slick-current')
13127            .attr('aria-hidden', 'true')
13128            .css('width', '');
13129
13130    };
13131
13132    Slick.prototype.unslick = function(fromBreakpoint) {
13133
13134        var _ = this;
13135        _.$slider.trigger('unslick', [_, fromBreakpoint]);
13136        _.destroy();
13137
13138    };
13139
13140    Slick.prototype.updateArrows = function() {
13141
13142        var _ = this,
13143            centerOffset;
13144
13145        centerOffset = Math.floor(_.options.slidesToShow / 2);
13146
13147        if ( _.options.arrows === true &&
13148            _.slideCount > _.options.slidesToShow &&
13149            !_.options.infinite ) {
13150
13151            _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
13152            _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
13153
13154            if (_.currentSlide === 0) {
13155
13156                _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
13157                _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
13158
13159            } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
13160
13161                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
13162                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
13163
13164            } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
13165
13166                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
13167                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
13168
13169            }
13170
13171        }
13172
13173    };
13174
13175    Slick.prototype.updateDots = function() {
13176
13177        var _ = this;
13178
13179        if (_.$dots !== null) {
13180
13181            _.$dots
13182                .find('li')
13183                    .removeClass('slick-active')
13184                    .end();
13185
13186            _.$dots
13187                .find('li')
13188                .eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
13189                .addClass('slick-active');
13190
13191        }
13192
13193    };
13194
13195    Slick.prototype.visibility = function() {
13196
13197        var _ = this;
13198
13199        if ( _.options.autoplay ) {
13200
13201            if ( document[_.hidden] ) {
13202
13203                _.interrupted = true;
13204
13205            } else {
13206
13207                _.interrupted = false;
13208
13209            }
13210
13211        }
13212
13213    };
13214
13215    $.fn.slick = function() {
13216        var _ = this,
13217            opt = arguments[0],
13218            args = Array.prototype.slice.call(arguments, 1),
13219            l = _.length,
13220            i,
13221            ret;
13222        for (i = 0; i < l; i++) {
13223            if (typeof opt == 'object' || typeof opt == 'undefined')
13224                _[i].slick = new Slick(_[i], opt);
13225            else
13226                ret = _[i].slick[opt].apply(_[i].slick, args);
13227            if (typeof ret != 'undefined') return ret;
13228        }
13229        return _;
13230    };
13231
13232}));
13233
13234/*!
13235 * jQuery Mousewheel 3.1.13
13236 *
13237 * Copyright jQuery Foundation and other contributors
13238 * Released under the MIT license
13239 * http://jquery.org/license
13240 */
13241
13242(function (factory) {
13243    if ( typeof define === 'function' && define.amd ) {
13244        // AMD. Register as an anonymous module.
13245        define(['jquery'], factory);
13246    } else if (typeof exports === 'object') {
13247        // Node/CommonJS style for Browserify
13248        module.exports = factory;
13249    } else {
13250        // Browser globals
13251        factory(jQuery);
13252    }
13253}(function ($) {
13254
13255    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
13256        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
13257                    ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
13258        slice  = Array.prototype.slice,
vendor: 6,451 bytes, lines 13259-13432
13259        nullLowestDeltaTimeout, lowestDelta;
13260
13261    if ( $.event.fixHooks ) {
13262        for ( var i = toFix.length; i; ) {
13263            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
13264        }
13265    }
13266
13267    var special = $.event.special.mousewheel = {
13268        version: '3.1.12',
13269
13270        setup: function() {
13271            if ( this.addEventListener ) {
13272                for ( var i = toBind.length; i; ) {
13273                    this.addEventListener( toBind[--i], handler, false );
13274                }
13275            } else {
13276                this.onmousewheel = handler;
13277            }
13278            // Store the line height and page height for this particular element
13279            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
13280            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
13281        },
13282
13283        teardown: function() {
13284            if ( this.removeEventListener ) {
13285                for ( var i = toBind.length; i; ) {
13286                    this.removeEventListener( toBind[--i], handler, false );
13287                }
13288            } else {
13289                this.onmousewheel = null;
13290            }
13291            // Clean up the data we added to the element
13292            $.removeData(this, 'mousewheel-line-height');
13293            $.removeData(this, 'mousewheel-page-height');
13294        },
13295
13296        getLineHeight: function(elem) {
13297            var $elem = $(elem),
13298                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
13299            if (!$parent.length) {
13300                $parent = $('body');
13301            }
13302            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
13303        },
13304
13305        getPageHeight: function(elem) {
13306            return $(elem).height();
13307        },
13308
13309        settings: {
13310            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
13311            normalizeOffset: true  // calls getBoundingClientRect for each event
13312        }
13313    };
13314
13315    $.fn.extend({
13316        mousewheel: function(fn) {
13317            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
13318        },
13319
13320        unmousewheel: function(fn) {
13321            return this.unbind('mousewheel', fn);
13322        }
13323    });
13324
13325
13326    function handler(event) {
13327        var orgEvent   = event || window.event,
13328            args       = slice.call(arguments, 1),
13329            delta      = 0,
13330            deltaX     = 0,
13331            deltaY     = 0,
13332            absDelta   = 0,
13333            offsetX    = 0,
13334            offsetY    = 0;
13335        event = $.event.fix(orgEvent);
13336        event.type = 'mousewheel';
13337
13338        // Old school scrollwheel delta
13339        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
13340        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
13341        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
13342        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
13343
13344        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
13345        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
13346            deltaX = deltaY * -1;
13347            deltaY = 0;
13348        }
13349
13350        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
13351        delta = deltaY === 0 ? deltaX : deltaY;
13352
13353        // New school wheel delta (wheel event)
13354        if ( 'deltaY' in orgEvent ) {
13355            deltaY = orgEvent.deltaY * -1;
13356            delta  = deltaY;
13357        }
13358        if ( 'deltaX' in orgEvent ) {
13359            deltaX = orgEvent.deltaX;
13360            if ( deltaY === 0 ) { delta  = deltaX * -1; }
13361        }
13362
13363        // No change actually happened, no reason to go any further
13364        if ( deltaY === 0 && deltaX === 0 ) { return; }
13365
13366        // Need to convert lines and pages to pixels if we aren't already in pixels
13367        // There are three delta modes:
13368        //   * deltaMode 0 is by pixels, nothing to do
13369        //   * deltaMode 1 is by lines
13370        //   * deltaMode 2 is by pages
13371        if ( orgEvent.deltaMode === 1 ) {
13372            var lineHeight = $.data(this, 'mousewheel-line-height');
13373            delta  *= lineHeight;
13374            deltaY *= lineHeight;
13375            deltaX *= lineHeight;
13376        } else if ( orgEvent.deltaMode === 2 ) {
13377            var pageHeight = $.data(this, 'mousewheel-page-height');
13378            delta  *= pageHeight;
13379            deltaY *= pageHeight;
13380            deltaX *= pageHeight;
13381        }
13382
13383        // Store lowest absolute delta to normalize the delta values
13384        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
13385
13386        if ( !lowestDelta || absDelta < lowestDelta ) {
13387            lowestDelta = absDelta;
13388
13389            // Adjust older deltas if necessary
13390            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
13391                lowestDelta /= 40;
13392            }
13393        }
13394
13395        // Adjust older deltas if necessary
13396        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
13397            // Divide all the things by 40!
13398            delta  /= 40;
13399            deltaX /= 40;
13400            deltaY /= 40;
13401        }
13402
13403        // Get a whole, normalized value for the deltas
13404        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
13405        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
13406        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
13407
13408        // Normalise offsetX and offsetY properties
13409        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
13410            var boundingRect = this.getBoundingClientRect();
13411            offsetX = event.clientX - boundingRect.left;
13412            offsetY = event.clientY - boundingRect.top;
13413        }
13414
13415        // Add information to the event object
13416        event.deltaX = deltaX;
13417        event.deltaY = deltaY;
13418        event.deltaFactor = lowestDelta;
13419        event.offsetX = offsetX;
13420        event.offsetY = offsetY;
13421        // Go ahead and set deltaMode to 0 since we converted to pixels
13422        // Although this is a little odd since we overwrite the deltaX/Y
13423        // properties with normalized deltas.
13424        event.deltaMode = 0;
13425
13426        // Add event and delta to the front of the arguments
13427        args.unshift(event, delta, deltaX, deltaY);
13428
13429        // Clearout lowestDelta after sometime to better
13430        // handle multiple device types that give different
13431        // a different lowestDelta
13432        // Ex: trackpad = 3 and mouse wheel = 120
13433        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
13434        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
13435
13436        return ($.event.dispatch || $.event.handle).apply(this, args);
13437    }
13438
13439    function nullLowestDelta() {
13440        lowestDelta = null;
13441    }
13442
13443    function shouldAdjustOldDeltas(orgEvent, absDelta) {
13444        // If this is an older event and the delta is divisable by 120,
13445        // then we are assuming that the browser is treating this as an
13446        // older mouse wheel event and that we should divide the deltas
13447        // by 40 to try and get a more usable deltaFactor.
13448        // Side note, this actually impacts the reported scroll distance
13449        // in older browsers and can cause scrolling to be slower than native.
13450        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
13451        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
13452    }
13453
13454}));
13455
13456/*!
13457 * Select2 4.0.13
13458 * https://select2.github.io
13459 *
13460 * Released under the MIT license
13461 * https://github.com/select2/select2/blob/master/LICENSE.md
13462 */
13463;
vendor: 18,996 bytes, lines 13463-14032
13463(function (factory) {
13464  if (typeof define === 'function' && define.amd) {
13465    // AMD. Register as an anonymous module.
13466    define(['jquery'], factory);
13467  } else if (typeof module === 'object' && module.exports) {
13468    // Node/CommonJS
13469    module.exports = function (root, jQuery) {
13470      if (jQuery === undefined) {
13471        // require('jQuery') returns a factory that requires window to
13472        // build a jQuery instance, we normalize how we use modules
13473        // that require this pattern but the window provided is a noop
13474        // if it's defined (how jquery works)
13475        if (typeof window !== 'undefined') {
13476          jQuery = require('jquery');
13477        }
13478        else {
13479          jQuery = require('jquery')(root);
13480        }
13481      }
13482      factory(jQuery);
13483      return jQuery;
13484    };
13485  } else {
13486    // Browser globals
13487    factory(jQuery);
13488  }
13489} (function (jQuery) {
13490  // This is needed so we can catch the AMD loader configuration and use it
13491  // The inner file should be wrapped (by `banner.start.js`) in a function that
13492  // returns the AMD loader references.
13493  var S2 =(function () {
13494  // Restore the Select2 AMD loader so it can be used
13495  // Needed mostly in the language files, where the loader is not inserted
13496  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
13497    var S2 = jQuery.fn.select2.amd;
13498  }
13499var S2;(function () { if (!S2 || !S2.requirejs) {
13500if (!S2) { S2 = {}; } else { require = S2; }
13501/**
13502 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
13503 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
13504 */
13505//Going sloppy to avoid 'use strict' string cost, but strict practices should
13506//be followed.
13507/*global setTimeout: false */
13508
13509var requirejs, require, define;
13510(function (undef) {
13511    var main, req, makeMap, handlers,
13512        defined = {},
13513        waiting = {},
13514        config = {},
13515        defining = {},
13516        hasOwn = Object.prototype.hasOwnProperty,
13517        aps = [].slice,
13518        jsSuffixRegExp = /\.js$/;
13519
13520    function hasProp(obj, prop) {
13521        return hasOwn.call(obj, prop);
13522    }
13523
13524    /**
13525     * Given a relative module name, like ./something, normalize it to
13526     * a real name that can be mapped to a path.
13527     * @param {String} name the relative name
13528     * @param {String} baseName a real name that the name arg is relative
13529     * to.
13530     * @returns {String} normalized name
13531     */
13532    function normalize(name, baseName) {
13533        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
13534            foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
13535            baseParts = baseName && baseName.split("/"),
13536            map = config.map,
13537            starMap = (map && map['*']) || {};
13538
13539        //Adjust any relative paths.
13540        if (name) {
13541            name = name.split('/');
13542            lastIndex = name.length - 1;
13543
13544            // If wanting node ID compatibility, strip .js from end
13545            // of IDs. Have to do this here, and not in nameToUrl
13546            // because node allows either .js or non .js to map
13547            // to same file.
13548            if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
13549                name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
13550            }
13551
13552            // Starts with a '.' so need the baseName
13553            if (name[0].charAt(0) === '.' && baseParts) {
13554                //Convert baseName to array, and lop off the last part,
13555                //so that . matches that 'directory' and not name of the baseName's
13556                //module. For instance, baseName of 'one/two/three', maps to
13557                //'one/two/three.js', but we want the directory, 'one/two' for
13558                //this normalization.
13559                normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
13560                name = normalizedBaseParts.concat(name);
13561            }
13562
13563            //start trimDots
13564            for (i = 0; i < name.length; i++) {
13565                part = name[i];
13566                if (part === '.') {
13567                    name.splice(i, 1);
13568                    i -= 1;
13569                } else if (part === '..') {
13570                    // If at the start, or previous value is still ..,
13571                    // keep them so that when converted to a path it may
13572                    // still work when converted to a path, even though
13573                    // as an ID it is less than ideal. In larger point
13574                    // releases, may be better to just kick out an error.
13575                    if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
13576                        continue;
13577                    } else if (i > 0) {
13578                        name.splice(i - 1, 2);
13579                        i -= 2;
13580                    }
13581                }
13582            }
13583            //end trimDots
13584
13585            name = name.join('/');
13586        }
13587
13588        //Apply map config if available.
13589        if ((baseParts || starMap) && map) {
13590            nameParts = name.split('/');
13591
13592            for (i = nameParts.length; i > 0; i -= 1) {
13593                nameSegment = nameParts.slice(0, i).join("/");
13594
13595                if (baseParts) {
13596                    //Find the longest baseName segment match in the config.
13597                    //So, do joins on the biggest to smallest lengths of baseParts.
13598                    for (j = baseParts.length; j > 0; j -= 1) {
13599                        mapValue = map[baseParts.slice(0, j).join('/')];
13600
13601                        //baseName segment has  config, find if it has one for
13602                        //this name.
13603                        if (mapValue) {
13604                            mapValue = mapValue[nameSegment];
13605                            if (mapValue) {
13606                                //Match, update name to the new value.
13607                                foundMap = mapValue;
13608                                foundI = i;
13609                                break;
13610                            }
13611                        }
13612                    }
13613                }
13614
13615                if (foundMap) {
13616                    break;
13617                }
13618
13619                //Check for a star map match, but just hold on to it,
13620                //if there is a shorter segment match later in a matching
13621                //config, then favor over this star map.
13622                if (!foundStarMap && starMap && starMap[nameSegment]) {
13623                    foundStarMap = starMap[nameSegment];
13624                    starI = i;
13625                }
13626            }
13627
13628            if (!foundMap && foundStarMap) {
13629                foundMap = foundStarMap;
13630                foundI = starI;
13631            }
13632
13633            if (foundMap) {
13634                nameParts.splice(0, foundI, foundMap);
13635                name = nameParts.join('/');
13636            }
13637        }
13638
13639        return name;
13640    }
13641
13642    function makeRequire(relName, forceSync) {
13643        return function () {
13644            //A version of a require function that passes a moduleName
13645            //value for items that may need to
13646            //look up paths relative to the moduleName
13647            var args = aps.call(arguments, 0);
13648
13649            //If first arg is not require('string'), and there is only
13650            //one arg, it is the array form without a callback. Insert
13651            //a null so that the following concat is correct.
13652            if (typeof args[0] !== 'string' && args.length === 1) {
13653                args.push(null);
13654            }
13655            return req.apply(undef, args.concat([relName, forceSync]));
13656        };
13657    }
13658
13659    function makeNormalize(relName) {
13660        return function (name) {
13661            return normalize(name, relName);
13662        };
13663    }
13664
13665    function makeLoad(depName) {
13666        return function (value) {
13667            defined[depName] = value;
13668        };
13669    }
13670
13671    function callDep(name) {
13672        if (hasProp(waiting, name)) {
13673            var args = waiting[name];
13674            delete waiting[name];
13675            defining[name] = true;
13676            main.apply(undef, args);
13677        }
13678
13679        if (!hasProp(defined, name) && !hasProp(defining, name)) {
13680            throw new Error('No ' + name);
13681        }
13682        return defined[name];
13683    }
13684
13685    //Turns a plugin!resource to [plugin, resource]
13686    //with the plugin being undefined if the name
13687    //did not have a plugin prefix.
13688    function splitPrefix(name) {
13689        var prefix,
13690            index = name ? name.indexOf('!') : -1;
13691        if (index > -1) {
13692            prefix = name.substring(0, index);
13693            name = name.substring(index + 1, name.length);
13694        }
13695        return [prefix, name];
13696    }
13697
13698    //Creates a parts array for a relName where first part is plugin ID,
13699    //second part is resource ID. Assumes relName has already been normalized.
13700    function makeRelParts(relName) {
13701        return relName ? splitPrefix(relName) : [];
13702    }
13703
13704    /**
13705     * Makes a name map, normalizing the name, and using a plugin
13706     * for normalization if necessary. Grabs a ref to plugin
13707     * too, as an optimization.
13708     */
13709    makeMap = function (name, relParts) {
13710        var plugin,
13711            parts = splitPrefix(name),
13712            prefix = parts[0],
13713            relResourceName = relParts[1];
13714
13715        name = parts[1];
13716
13717        if (prefix) {
13718            prefix = normalize(prefix, relResourceName);
13719            plugin = callDep(prefix);
13720        }
13721
13722        //Normalize according
13723        if (prefix) {
13724            if (plugin && plugin.normalize) {
13725                name = plugin.normalize(name, makeNormalize(relResourceName));
13726            } else {
13727                name = normalize(name, relResourceName);
13728            }
13729        } else {
13730            name = normalize(name, relResourceName);
13731            parts = splitPrefix(name);
13732            prefix = parts[0];
13733            name = parts[1];
13734            if (prefix) {
13735                plugin = callDep(prefix);
13736            }
13737        }
13738
13739        //Using ridiculous property names for space reasons
13740        return {
13741            f: prefix ? prefix + '!' + name : name, //fullName
13742            n: name,
13743            pr: prefix,
13744            p: plugin
13745        };
13746    };
13747
13748    function makeConfig(name) {
13749        return function () {
13750            return (config && config.config && config.config[name]) || {};
13751        };
13752    }
13753
13754    handlers = {
13755        require: function (name) {
13756            return makeRequire(name);
13757        },
13758        exports: function (name) {
13759            var e = defined[name];
13760            if (typeof e !== 'undefined') {
13761                return e;
13762            } else {
13763                return (defined[name] = {});
13764            }
13765        },
13766        module: function (name) {
13767            return {
13768                id: name,
13769                uri: '',
13770                exports: defined[name],
13771                config: makeConfig(name)
13772            };
13773        }
13774    };
13775
13776    main = function (name, deps, callback, relName) {
13777        var cjsModule, depName, ret, map, i, relParts,
13778            args = [],
13779            callbackType = typeof callback,
13780            usingExports;
13781
13782        //Use name if no relName
13783        relName = relName || name;
13784        relParts = makeRelParts(relName);
13785
13786        //Call the callback to define the module, if necessary.
13787        if (callbackType === 'undefined' || callbackType === 'function') {
13788            //Pull out the defined dependencies and pass the ordered
13789            //values to the callback.
13790            //Default to [require, exports, module] if no deps
13791            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
13792            for (i = 0; i < deps.length; i += 1) {
13793                map = makeMap(deps[i], relParts);
13794                depName = map.f;
13795
13796                //Fast path CommonJS standard dependencies.
13797                if (depName === "require") {
13798                    args[i] = handlers.require(name);
13799                } else if (depName === "exports") {
13800                    //CommonJS module spec 1.1
13801                    args[i] = handlers.exports(name);
13802                    usingExports = true;
13803                } else if (depName === "module") {
13804                    //CommonJS module spec 1.1
13805                    cjsModule = args[i] = handlers.module(name);
13806                } else if (hasProp(defined, depName) ||
13807                           hasProp(waiting, depName) ||
13808                           hasProp(defining, depName)) {
13809                    args[i] = callDep(depName);
13810                } else if (map.p) {
13811                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
13812                    args[i] = defined[depName];
13813                } else {
13814                    throw new Error(name + ' missing ' + depName);
13815                }
13816            }
13817
13818            ret = callback ? callback.apply(defined[name], args) : undefined;
13819
13820            if (name) {
13821                //If setting exports via "module" is in play,
13822                //favor that over return value and exports. After that,
13823                //favor a non-undefined return value over exports use.
13824                if (cjsModule && cjsModule.exports !== undef &&
13825                        cjsModule.exports !== defined[name]) {
13826                    defined[name] = cjsModule.exports;
13827                } else if (ret !== undef || !usingExports) {
13828                    //Use the return value from the function.
13829                    defined[name] = ret;
13830                }
13831            }
13832        } else if (name) {
13833            //May just be an object definition for the module. Only
13834            //worry about defining if have a module name.
13835            defined[name] = callback;
13836        }
13837    };
13838
13839    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
13840        if (typeof deps === "string") {
13841            if (handlers[deps]) {
13842                //callback in this case is really relName
13843                return handlers[deps](callback);
13844            }
13845            //Just return the module wanted. In this scenario, the
13846            //deps arg is the module name, and second arg (if passed)
13847            //is just the relName.
13848            //Normalize module name, if it contains . or ..
13849            return callDep(makeMap(deps, makeRelParts(callback)).f);
13850        } else if (!deps.splice) {
13851            //deps is a config object, not an array.
13852            config = deps;
13853            if (config.deps) {
13854                req(config.deps, config.callback);
13855            }
13856            if (!callback) {
13857                return;
13858            }
13859
13860            if (callback.splice) {
13861                //callback is an array, which means it is a dependency list.
13862                //Adjust args if there are dependencies
13863                deps = callback;
13864                callback = relName;
13865                relName = null;
13866            } else {
13867                deps = undef;
13868            }
13869        }
13870
13871        //Support require(['a'])
13872        callback = callback || function () {};
13873
13874        //If relName is a function, it is an errback handler,
13875        //so remove it.
13876        if (typeof relName === 'function') {
13877            relName = forceSync;
13878            forceSync = alt;
13879        }
13880
13881        //Simulate async callback;
13882        if (forceSync) {
13883            main(undef, deps, callback, relName);
13884        } else {
13885            //Using a non-zero value because of concern for what old browsers
13886            //do, and latest browsers "upgrade" to 4 if lower value is used:
13887            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
13888            //If want a value immediately, use require('id') instead -- something
13889            //that works in almond on the global level, but not guaranteed and
13890            //unlikely to work in other AMD implementations.
13891            setTimeout(function () {
13892                main(undef, deps, callback, relName);
13893            }, 4);
13894        }
13895
13896        return req;
13897    };
13898
13899    /**
13900     * Just drops the config on the floor, but returns req in case
13901     * the config return value is used.
13902     */
13903    req.config = function (cfg) {
13904        return req(cfg);
13905    };
13906
13907    /**
13908     * Expose module registry for debugging and tooling
13909     */
13910    requirejs._defined = defined;
13911
13912    define = function (name, deps, callback) {
13913        if (typeof name !== 'string') {
13914            throw new Error('See almond README: incorrect module build, no module name');
13915        }
13916
13917        //This module may not have dependencies
13918        if (!deps.splice) {
13919            //deps is not an array, so probably means
13920            //an object literal or factory function for
13921            //the value. Adjust args.
13922            callback = deps;
13923            deps = [];
13924        }
13925
13926        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
13927            waiting[name] = [name, deps, callback];
13928        }
13929    };
13930
13931    define.amd = {
13932        jQuery: true
13933    };
13934}());
13935
13936S2.requirejs = requirejs;S2.require = require;S2.define = define;
13937}
13938}());
13939S2.define("almond", function(){});
13940
13941/* global jQuery:false, $:false */
13942S2.define('jquery',[],function () {
13943  var _$ = jQuery || $;
13944
13945  if (_$ == null && console && console.error) {
13946    console.error(
13947      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
13948      'found. Make sure that you are including jQuery before Select2 on your ' +
13949      'web page.'
13950    );
13951  }
13952
13953  return _$;
13954});
13955
13956S2.define('select2/utils',[
13957  'jquery'
13958], function ($) {
13959  var Utils = {};
13960
13961  Utils.Extend = function (ChildClass, SuperClass) {
13962    var __hasProp = {}.hasOwnProperty;
13963
13964    function BaseConstructor () {
13965      this.constructor = ChildClass;
13966    }
13967
13968    for (var key in SuperClass) {
13969      if (__hasProp.call(SuperClass, key)) {
13970        ChildClass[key] = SuperClass[key];
13971      }
13972    }
13973
13974    BaseConstructor.prototype = SuperClass.prototype;
13975    ChildClass.prototype = new BaseConstructor();
13976    ChildClass.__super__ = SuperClass.prototype;
13977
13978    return ChildClass;
13979  };
13980
13981  function getMethods (theClass) {
13982    var proto = theClass.prototype;
13983
13984    var methods = [];
13985
13986    for (var methodName in proto) {
13987      var m = proto[methodName];
13988
13989      if (typeof m !== 'function') {
13990        continue;
13991      }
13992
13993      if (methodName === 'constructor') {
13994        continue;
13995      }
13996
13997      methods.push(methodName);
13998    }
13999
14000    return methods;
14001  }
14002
14003  Utils.Decorate = function (SuperClass, DecoratorClass) {
14004    var decoratedMethods = getMethods(DecoratorClass);
14005    var superMethods = getMethods(SuperClass);
14006
14007    function DecoratedClass () {
14008      var unshift = Array.prototype.unshift;
14009
14010      var argCount = DecoratorClass.prototype.constructor.length;
14011
14012      var calledConstructor = SuperClass.prototype.constructor;
14013
14014      if (argCount > 0) {
14015        unshift.call(arguments, SuperClass.prototype.constructor);
14016
14017        calledConstructor = DecoratorClass.prototype.constructor;
14018      }
14019
14020      calledConstructor.apply(this, arguments);
14021    }
14022
14023    DecoratorClass.displayName = SuperClass.displayName;
14024
14025    function ctr () {
14026      this.constructor = DecoratedClass;
14027    }
14028
14029    DecoratedClass.prototype = new ctr();
14030
14031    for (var m = 0; m < superMethods.length; m++) {
14032      
vendor: 3,385 bytes, lines 14032-14169
14032var superMethod = superMethods[m];
14033
14034      DecoratedClass.prototype[superMethod] =
14035        SuperClass.prototype[superMethod];
14036    }
14037
14038    var calledMethod = function (methodName) {
14039      // Stub out the original method if it's not decorating an actual method
14040      var originalMethod = function () {};
14041
14042      if (methodName in DecoratedClass.prototype) {
14043        originalMethod = DecoratedClass.prototype[methodName];
14044      }
14045
14046      var decoratedMethod = DecoratorClass.prototype[methodName];
14047
14048      return function () {
14049        var unshift = Array.prototype.unshift;
14050
14051        unshift.call(arguments, originalMethod);
14052
14053        return decoratedMethod.apply(this, arguments);
14054      };
14055    };
14056
14057    for (var d = 0; d < decoratedMethods.length; d++) {
14058      var decoratedMethod = decoratedMethods[d];
14059
14060      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
14061    }
14062
14063    return DecoratedClass;
14064  };
14065
14066  var Observable = function () {
14067    this.listeners = {};
14068  };
14069
14070  Observable.prototype.on = function (event, callback) {
14071    this.listeners = this.listeners || {};
14072
14073    if (event in this.listeners) {
14074      this.listeners[event].push(callback);
14075    } else {
14076      this.listeners[event] = [callback];
14077    }
14078  };
14079
14080  Observable.prototype.trigger = function (event) {
14081    var slice = Array.prototype.slice;
14082    var params = slice.call(arguments, 1);
14083
14084    this.listeners = this.listeners || {};
14085
14086    // Params should always come in as an array
14087    if (params == null) {
14088      params = [];
14089    }
14090
14091    // If there are no arguments to the event, use a temporary object
14092    if (params.length === 0) {
14093      params.push({});
14094    }
14095
14096    // Set the `_type` of the first object to the event
14097    params[0]._type = event;
14098
14099    if (event in this.listeners) {
14100      this.invoke(this.listeners[event], slice.call(arguments, 1));
14101    }
14102
14103    if ('*' in this.listeners) {
14104      this.invoke(this.listeners['*'], arguments);
14105    }
14106  };
14107
14108  Observable.prototype.invoke = function (listeners, params) {
14109    for (var i = 0, len = listeners.length; i < len; i++) {
14110      listeners[i].apply(this, params);
14111    }
14112  };
14113
14114  Utils.Observable = Observable;
14115
14116  Utils.generateChars = function (length) {
14117    var chars = '';
14118
14119    for (var i = 0; i < length; i++) {
14120      var randomChar = Math.floor(Math.random() * 36);
14121      chars += randomChar.toString(36);
14122    }
14123
14124    return chars;
14125  };
14126
14127  Utils.bind = function (func, context) {
14128    return function () {
14129      func.apply(context, arguments);
14130    };
14131  };
14132
14133  Utils._convertData = function (data) {
14134    for (var originalKey in data) {
14135      var keys = originalKey.split('-');
14136
14137      var dataLevel = data;
14138
14139      if (keys.length === 1) {
14140        continue;
14141      }
14142
14143      for (var k = 0; k < keys.length; k++) {
14144        var key = keys[k];
14145
14146        // Lowercase the first letter
14147        // By default, dash-separated becomes camelCase
14148        key = key.substring(0, 1).toLowerCase() + key.substring(1);
14149
14150        if (!(key in dataLevel)) {
14151          dataLevel[key] = {};
14152        }
14153
14154        if (k == keys.length - 1) {
14155          dataLevel[key] = data[originalKey];
14156        }
14157
14158        dataLevel = dataLevel[key];
14159      }
14160
14161      delete data[originalKey];
14162    }
14163
14164    return data;
14165  };
14166
14167  Utils.hasScroll = function (index, el) {
14168    // Adapted from the function created by @ShadowScripter
14169    // and adapted by @BillBarry on the Stack Exchange Code Review website.
14170    // The original code can be found at
14171    // http://codereview.stackexchange.com/q/13338
14172    // and was designed to be used with the Sizzle selector engine.
14173
14174    var $el = $(el);
14175    var overflowX = el.style.overflowX;
14176    var overflowY = el.style.overflowY;
14177
14178    //Check both x and y declarations
14179    if (overflowX === overflowY &&
14180        (overflowY === 'hidden' || overflowY === 'visible')) {
14181      return false;
14182    }
14183
14184    if (overflowX === 'scroll' || overflowY === 'scroll') {
14185      return true;
14186    }
14187
14188    return ($el.innerHeight() < el.scrollHeight ||
14189      $el.innerWidth() < el.scrollWidth);
14190  };
14191
14192  Utils.escapeMarkup = function (markup) {
14193    var replaceMap = {
14194      '\\': '&#92;',
14195      '&': '&amp;',
14196      '<': '&lt;',
14197      '>': '&gt;',
14198      '"': '&quot;',
14199      '\'': '&#39;',
14200      '/': '&#47;'
14201    };
14202
14203    // Do not try to escape the markup if it's not a string
14204    if (typeof markup !== 'string') {
14205      return markup;
14206    }
14207
14208    return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
14209      return replaceMap[match];
14210    });
14211  };
14212
14213  // Append an array of jQuery nodes to a given element.
14214  Utils.appendMany = function ($element, $nodes) {
14215    // jQuery 1.7.x does not support $.fn.append() with an array
14216    // Fall back to a jQuery object collection using $.fn.add()
14217    if ($.fn.jquery.substr(0, 3) === '1.7') {
14218      var $jqNodes = $();
14219
14220      $.map($nodes, function (node) {
14221        $jqNodes = $jqNodes.add(node);
14222      });
14223
14224      $nodes = $jqNodes;
14225    }
14226
14227    $element.append($nodes);
14228  };
14229
14230  // Cache objects in Utils.__cache instead of $.data (see #4346)
14231  Utils.__cache = {};
14232
14233  var id = 0;
14234  Utils.GetUniqueElementId = function (element) {
14235    // Get a unique element Id. If element has no id,
14236    // creates a new unique number, stores it in the id
14237    // attribute and returns the new id.
14238    // If an id already exists, it simply returns it.
14239
14240    var select2Id = element.getAttribute('data-select2-id');
14241    if (select2Id == null) {
14242      // If element has id, use it.
14243      if (element.id) {
14244        select2Id = element.id;
14245        element.setAttribute('data-select2-id', select2Id);
14246      } else {
14247        element.setAttribute('data-select2-id', ++id);
14248        select2Id = id.toString();
14249      }
14250    }
14251    return select2Id;
14252  };
14253
14254  Utils.StoreData = function (element, name, value) {
14255    // Stores an item in the cache for a specified element.
14256    // name is the cache key.
14257    var id = Utils.GetUniqueElementId(element);
14258    if (!Utils.__cache[id]) {
14259      Utils.__cache[id] = {};
14260    }
14261
14262    Utils.__cache[id][name] = value;
14263  };
14264
14265  Utils.GetData = function (element, name) {
14266    // Retrieves a value from the cache by its key (name)
14267    // name is optional. If no name specified, return
14268    // all cache items for the specified element.
14269    // and for a specified element.
14270    var id = Utils.GetUniqueElementId(element);
14271    if (name) {
14272      if (Utils.__cache[id]) {
14273        if (Utils.__cache[id][name] != null) {
14274          return Utils.__cache[id][name];
14275        }
14276        return $(element).data(name); // Fallback to HTML5 data attribs.
14277      }
14278      return $(element).data(name); // Fallback to HTML5 data attribs.
14279    } else {
14280      return Utils.__cache[id];
14281    }
14282  };
14283
14284  Utils.RemoveData = function (element) {
14285    // Removes all cached items for a specified element.
14286    var id = Utils.GetUniqueElementId(element);
14287    if (Utils.__cache[id] != null) {
14288      delete Utils.__cache[id];
14289    }
14290
14291    element.removeAttribute('data-select2-id');
14292  };
14293
14294  return Utils;
14295});
14296
14297S2.define('select2/results',[
14298  'jquery',
14299  './utils'
14300], function ($, Utils) {
14301  function Results ($element, options, dataAdapter) {
14302    this.$element = $element;
14303    this.data = dataAdapter;
14304    this.options = options;
14305
14306    Results.__super__.constructor.call(this);
14307  }
14308
14309  Utils.Extend(Results, Utils.Observable);
14310
14311  Results.prototype.render = function () {
14312    var $results = $(
14313      '<ul class="select2-results__options" role="listbox"></ul>'
14314    );
14315
14316    if (this.options.get('multiple')) {
14317      $results.attr('aria-multiselectable', 'true');
14318    }
14319
14320    this.$results = $results;
14321
14322    return $results;
14323  };
14324
14325  Results.prototype.clear = function () {
14326    this.$results.empty();
14327  };
14328
14329  Results.prototype.displayMessage = function (params) {
14330    var escapeMarkup = this.options.get('escapeMarkup');
14331
14332    this.clear();
14333    this.hideLoading();
14334
14335    var $message = $(
14336      '<li role="alert" aria-live="assertive"' +
14337      ' class="select2-results__option"></li>'
14338    );
14339
14340    var message = this.options.get('translations').get(params.message);
14341
14342    $message.append(
14343      escapeMarkup(
14344        message(params.args)
14345      )
14346    );
14347
14348    $message[0].className += ' select2-results__message';
vendor: 9,101 bytes, lines 14349-14711
14349
14350    this.$results.append($message);
14351  };
14352
14353  Results.prototype.hideMessages = function () {
14354    this.$results.find('.select2-results__message').remove();
14355  };
14356
14357  Results.prototype.append = function (data) {
14358    this.hideLoading();
14359
14360    var $options = [];
14361
14362    if (data.results == null || data.results.length === 0) {
14363      if (this.$results.children().length === 0) {
14364        this.trigger('results:message', {
14365          message: 'noResults'
14366        });
14367      }
14368
14369      return;
14370    }
14371
14372    data.results = this.sort(data.results);
14373
14374    for (var d = 0; d < data.results.length; d++) {
14375      var item = data.results[d];
14376
14377      var $option = this.option(item);
14378
14379      $options.push($option);
14380    }
14381
14382    this.$results.append($options);
14383  };
14384
14385  Results.prototype.position = function ($results, $dropdown) {
14386    var $resultsContainer = $dropdown.find('.select2-results');
14387    $resultsContainer.append($results);
14388  };
14389
14390  Results.prototype.sort = function (data) {
14391    var sorter = this.options.get('sorter');
14392
14393    return sorter(data);
14394  };
14395
14396  Results.prototype.highlightFirstItem = function () {
14397    var $options = this.$results
14398      .find('.select2-results__option[aria-selected]');
14399
14400    var $selected = $options.filter('[aria-selected=true]');
14401
14402    // Check if there are any selected options
14403    if ($selected.length > 0) {
14404      // If there are selected options, highlight the first
14405      $selected.first().trigger('mouseenter');
14406    } else {
14407      // If there are no selected options, highlight the first option
14408      // in the dropdown
14409      $options.first().trigger('mouseenter');
14410    }
14411
14412    this.ensureHighlightVisible();
14413  };
14414
14415  Results.prototype.setClasses = function () {
14416    var self = this;
14417
14418    this.data.current(function (selected) {
14419      var selectedIds = $.map(selected, function (s) {
14420        return s.id.toString();
14421      });
14422
14423      var $options = self.$results
14424        .find('.select2-results__option[aria-selected]');
14425
14426      $options.each(function () {
14427        var $option = $(this);
14428
14429        var item = Utils.GetData(this, 'data');
14430
14431        // id needs to be converted to a string when comparing
14432        var id = '' + item.id;
14433
14434        if ((item.element != null && item.element.selected) ||
14435            (item.element == null && $.inArray(id, selectedIds) > -1)) {
14436          $option.attr('aria-selected', 'true');
14437        } else {
14438          $option.attr('aria-selected', 'false');
14439        }
14440      });
14441
14442    });
14443  };
14444
14445  Results.prototype.showLoading = function (params) {
14446    this.hideLoading();
14447
14448    var loadingMore = this.options.get('translations').get('searching');
14449
14450    var loading = {
14451      disabled: true,
14452      loading: true,
14453      text: loadingMore(params)
14454    };
14455    var $loading = this.option(loading);
14456    $loading.className += ' loading-results';
14457
14458    this.$results.prepend($loading);
14459  };
14460
14461  Results.prototype.hideLoading = function () {
14462    this.$results.find('.loading-results').remove();
14463  };
14464
14465  Results.prototype.option = function (data) {
14466    var option = document.createElement('li');
14467    option.className = 'select2-results__option';
14468
14469    var attrs = {
14470      'role': 'option',
14471      'aria-selected': 'false'
14472    };
14473
14474    var matches = window.Element.prototype.matches ||
14475      window.Element.prototype.msMatchesSelector ||
14476      window.Element.prototype.webkitMatchesSelector;
14477
14478    if ((data.element != null && matches.call(data.element, ':disabled')) ||
14479        (data.element == null && data.disabled)) {
14480      delete attrs['aria-selected'];
14481      attrs['aria-disabled'] = 'true';
14482    }
14483
14484    if (data.id == null) {
14485      delete attrs['aria-selected'];
14486    }
14487
14488    if (data._resultId != null) {
14489      option.id = data._resultId;
14490    }
14491
14492    if (data.title) {
14493      option.title = data.title;
14494    }
14495
14496    if (data.children) {
14497      attrs.role = 'group';
14498      attrs['aria-label'] = data.text;
14499      delete attrs['aria-selected'];
14500    }
14501
14502    for (var attr in attrs) {
14503      var val = attrs[attr];
14504
14505      option.setAttribute(attr, val);
14506    }
14507
14508    if (data.children) {
14509      var $option = $(option);
14510
14511      var label = document.createElement('strong');
14512      label.className = 'select2-results__group';
14513
14514      var $label = $(label);
14515      this.template(data, label);
14516
14517      var $children = [];
14518
14519      for (var c = 0; c < data.children.length; c++) {
14520        var child = data.children[c];
14521
14522        var $child = this.option(child);
14523
14524        $children.push($child);
14525      }
14526
14527      var $childrenContainer = $('<ul></ul>', {
14528        'class': 'select2-results__options select2-results__options--nested'
14529      });
14530
14531      $childrenContainer.append($children);
14532
14533      $option.append(label);
14534      $option.append($childrenContainer);
14535    } else {
14536      this.template(data, option);
14537    }
14538
14539    Utils.StoreData(option, 'data', data);
14540
14541    return option;
14542  };
14543
14544  Results.prototype.bind = function (container, $container) {
14545    var self = this;
14546
14547    var id = container.id + '-results';
14548
14549    this.$results.attr('id', id);
14550
14551    container.on('results:all', function (params) {
14552      self.clear();
14553      self.append(params.data);
14554
14555      if (container.isOpen()) {
14556        self.setClasses();
14557        self.highlightFirstItem();
14558      }
14559    });
14560
14561    container.on('results:append', function (params) {
14562      self.append(params.data);
14563
14564      if (container.isOpen()) {
14565        self.setClasses();
14566      }
14567    });
14568
14569    container.on('query', function (params) {
14570      self.hideMessages();
14571      self.showLoading(params);
14572    });
14573
14574    container.on('select', function () {
14575      if (!container.isOpen()) {
14576        return;
14577      }
14578
14579      self.setClasses();
14580
14581      if (self.options.get('scrollAfterSelect')) {
14582        self.highlightFirstItem();
14583      }
14584    });
14585
14586    container.on('unselect', function () {
14587      if (!container.isOpen()) {
14588        return;
14589      }
14590
14591      self.setClasses();
14592
14593      if (self.options.get('scrollAfterSelect')) {
14594        self.highlightFirstItem();
14595      }
14596    });
14597
14598    container.on('open', function () {
14599      // When the dropdown is open, aria-expended="true"
14600      self.$results.attr('aria-expanded', 'true');
14601      self.$results.attr('aria-hidden', 'false');
14602
14603      self.setClasses();
14604      self.ensureHighlightVisible();
14605    });
14606
14607    container.on('close', function () {
14608      // When the dropdown is closed, aria-expended="false"
14609      self.$results.attr('aria-expanded', 'false');
14610      self.$results.attr('aria-hidden', 'true');
14611      self.$results.removeAttr('aria-activedescendant');
14612    });
14613
14614    container.on('results:toggle', function () {
14615      var $highlighted = self.getHighlightedResults();
14616
14617      if ($highlighted.length === 0) {
14618        return;
14619      }
14620
14621      $highlighted.trigger('mouseup');
14622    });
14623
14624    container.on('results:select', function () {
14625      var $highlighted = self.getHighlightedResults();
14626
14627      if ($highlighted.length === 0) {
14628        return;
14629      }
14630
14631      var data = Utils.GetData($highlighted[0], 'data');
14632
14633      if ($highlighted.attr('aria-selected') == 'true') {
14634        self.trigger('close', {});
14635      } else {
14636        self.trigger('select', {
14637          data: data
14638        });
14639      }
14640    });
14641
14642    container.on('results:previous', function () {
14643      var $highlighted = self.getHighlightedResults();
14644
14645      var $options = self.$results.find('[aria-selected]');
14646
14647      var currentIndex = $options.index($highlighted);
14648
14649      // If we are already at the top, don't move further
14650      // If no options, currentIndex will be -1
14651      if (currentIndex <= 0) {
14652        return;
14653      }
14654
14655      var nextIndex = currentIndex - 1;
14656
14657      // If none are highlighted, highlight the first
14658      if ($highlighted.length === 0) {
14659        nextIndex = 0;
14660      }
14661
14662      var $next = $options.eq(nextIndex);
14663
14664      $next.trigger('mouseenter');
14665
14666      var currentOffset = self.$results.offset().top;
14667      var nextTop = $next.offset().top;
14668      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
14669
14670      if (nextIndex === 0) {
14671        self.$results.scrollTop(0);
14672      } else if (nextTop - currentOffset < 0) {
14673        self.$results.scrollTop(nextOffset);
14674      }
14675    });
14676
14677    container.on('results:next', function () {
14678      var $highlighted = self.getHighlightedResults();
14679
14680      var $options = self.$results.find('[aria-selected]');
14681
14682      var currentIndex = $options.index($highlighted);
14683
14684      var nextIndex = currentIndex + 1;
14685
14686      // If we are at the last option, stay there
14687      if (nextIndex >= $options.length) {
14688        return;
14689      }
14690
14691      var $next = $options.eq(nextIndex);
14692
14693      $next.trigger('mouseenter');
14694
14695      var currentOffset = self.$results.offset().top +
14696        self.$results.outerHeight(false);
14697      var nextBottom = $next.offset().top + $next.outerHeight(false);
14698      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
14699
14700      if (nextIndex === 0) {
14701        self.$results.scrollTop(0);
14702      } else if (nextBottom > currentOffset) {
14703        self.$results.scrollTop(nextOffset);
14704      }
14705    });
14706
14707    container.on('results:focus', function (params) {
14708      params.element.addClass('select2-results__option--highlighted');
14709    });
14710
14711    container.on('results:message', function (params) {
vendor: 24,175 bytes, lines 14712-15633
14712      self.displayMessage(params);
14713    });
14714
14715    if ($.fn.mousewheel) {
14716      this.$results.on('mousewheel', function (e) {
14717        var top = self.$results.scrollTop();
14718
14719        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
14720
14721        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
14722        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
14723
14724        if (isAtTop) {
14725          self.$results.scrollTop(0);
14726
14727          e.preventDefault();
14728          e.stopPropagation();
14729        } else if (isAtBottom) {
14730          self.$results.scrollTop(
14731            self.$results.get(0).scrollHeight - self.$results.height()
14732          );
14733
14734          e.preventDefault();
14735          e.stopPropagation();
14736        }
14737      });
14738    }
14739
14740    this.$results.on('mouseup', '.select2-results__option[aria-selected]',
14741      function (evt) {
14742      var $this = $(this);
14743
14744      var data = Utils.GetData(this, 'data');
14745
14746      if ($this.attr('aria-selected') === 'true') {
14747        if (self.options.get('multiple')) {
14748          self.trigger('unselect', {
14749            originalEvent: evt,
14750            data: data
14751          });
14752        } else {
14753          self.trigger('close', {});
14754        }
14755
14756        return;
14757      }
14758
14759      self.trigger('select', {
14760        originalEvent: evt,
14761        data: data
14762      });
14763    });
14764
14765    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
14766      function (evt) {
14767      var data = Utils.GetData(this, 'data');
14768
14769      self.getHighlightedResults()
14770          .removeClass('select2-results__option--highlighted');
14771
14772      self.trigger('results:focus', {
14773        data: data,
14774        element: $(this)
14775      });
14776    });
14777  };
14778
14779  Results.prototype.getHighlightedResults = function () {
14780    var $highlighted = this.$results
14781    .find('.select2-results__option--highlighted');
14782
14783    return $highlighted;
14784  };
14785
14786  Results.prototype.destroy = function () {
14787    this.$results.remove();
14788  };
14789
14790  Results.prototype.ensureHighlightVisible = function () {
14791    var $highlighted = this.getHighlightedResults();
14792
14793    if ($highlighted.length === 0) {
14794      return;
14795    }
14796
14797    var $options = this.$results.find('[aria-selected]');
14798
14799    var currentIndex = $options.index($highlighted);
14800
14801    var currentOffset = this.$results.offset().top;
14802    var nextTop = $highlighted.offset().top;
14803    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
14804
14805    var offsetDelta = nextTop - currentOffset;
14806    nextOffset -= $highlighted.outerHeight(false) * 2;
14807
14808    if (currentIndex <= 2) {
14809      this.$results.scrollTop(0);
14810    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
14811      this.$results.scrollTop(nextOffset);
14812    }
14813  };
14814
14815  Results.prototype.template = function (result, container) {
14816    var template = this.options.get('templateResult');
14817    var escapeMarkup = this.options.get('escapeMarkup');
14818
14819    var content = template(result, container);
14820
14821    if (content == null) {
14822      container.style.display = 'none';
14823    } else if (typeof content === 'string') {
14824      container.innerHTML = escapeMarkup(content);
14825    } else {
14826      $(container).append(content);
14827    }
14828  };
14829
14830  return Results;
14831});
14832
14833S2.define('select2/keys',[
14834
14835], function () {
14836  var KEYS = {
14837    BACKSPACE: 8,
14838    TAB: 9,
14839    ENTER: 13,
14840    SHIFT: 16,
14841    CTRL: 17,
14842    ALT: 18,
14843    ESC: 27,
14844    SPACE: 32,
14845    PAGE_UP: 33,
14846    PAGE_DOWN: 34,
14847    END: 35,
14848    HOME: 36,
14849    LEFT: 37,
14850    UP: 38,
14851    RIGHT: 39,
14852    DOWN: 40,
14853    DELETE: 46
14854  };
14855
14856  return KEYS;
14857});
14858
14859S2.define('select2/selection/base',[
14860  'jquery',
14861  '../utils',
14862  '../keys'
14863], function ($, Utils, KEYS) {
14864  function BaseSelection ($element, options) {
14865    this.$element = $element;
14866    this.options = options;
14867
14868    BaseSelection.__super__.constructor.call(this);
14869  }
14870
14871  Utils.Extend(BaseSelection, Utils.Observable);
14872
14873  BaseSelection.prototype.render = function () {
14874    var $selection = $(
14875      '<span class="select2-selection" role="combobox" ' +
14876      ' aria-haspopup="true" aria-expanded="false">' +
14877      '</span>'
14878    );
14879
14880    this._tabindex = 0;
14881
14882    if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
14883      this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
14884    } else if (this.$element.attr('tabindex') != null) {
14885      this._tabindex = this.$element.attr('tabindex');
14886    }
14887
14888    $selection.attr('title', this.$element.attr('title'));
14889    $selection.attr('tabindex', this._tabindex);
14890    $selection.attr('aria-disabled', 'false');
14891
14892    this.$selection = $selection;
14893
14894    return $selection;
14895  };
14896
14897  BaseSelection.prototype.bind = function (container, $container) {
14898    var self = this;
14899
14900    var resultsId = container.id + '-results';
14901
14902    this.container = container;
14903
14904    this.$selection.on('focus', function (evt) {
14905      self.trigger('focus', evt);
14906    });
14907
14908    this.$selection.on('blur', function (evt) {
14909      self._handleBlur(evt);
14910    });
14911
14912    this.$selection.on('keydown', function (evt) {
14913      self.trigger('keypress', evt);
14914
14915      if (evt.which === KEYS.SPACE) {
14916        evt.preventDefault();
14917      }
14918    });
14919
14920    container.on('results:focus', function (params) {
14921      self.$selection.attr('aria-activedescendant', params.data._resultId);
14922    });
14923
14924    container.on('selection:update', function (params) {
14925      self.update(params.data);
14926    });
14927
14928    container.on('open', function () {
14929      // When the dropdown is open, aria-expanded="true"
14930      self.$selection.attr('aria-expanded', 'true');
14931      self.$selection.attr('aria-owns', resultsId);
14932
14933      self._attachCloseHandler(container);
14934    });
14935
14936    container.on('close', function () {
14937      // When the dropdown is closed, aria-expanded="false"
14938      self.$selection.attr('aria-expanded', 'false');
14939      self.$selection.removeAttr('aria-activedescendant');
14940      self.$selection.removeAttr('aria-owns');
14941
14942      self.$selection.trigger('focus');
14943
14944      self._detachCloseHandler(container);
14945    });
14946
14947    container.on('enable', function () {
14948      self.$selection.attr('tabindex', self._tabindex);
14949      self.$selection.attr('aria-disabled', 'false');
14950    });
14951
14952    container.on('disable', function () {
14953      self.$selection.attr('tabindex', '-1');
14954      self.$selection.attr('aria-disabled', 'true');
14955    });
14956  };
14957
14958  BaseSelection.prototype._handleBlur = function (evt) {
14959    var self = this;
14960
14961    // This needs to be delayed as the active element is the body when the tab
14962    // key is pressed, possibly along with others.
14963    window.setTimeout(function () {
14964      // Don't trigger `blur` if the focus is still in the selection
14965      if (
14966        (document.activeElement == self.$selection[0]) ||
14967        ($.contains(self.$selection[0], document.activeElement))
14968      ) {
14969        return;
14970      }
14971
14972      self.trigger('blur', evt);
14973    }, 1);
14974  };
14975
14976  BaseSelection.prototype._attachCloseHandler = function (container) {
14977
14978    $(document.body).on('mousedown.select2.' + container.id, function (e) {
14979      var $target = $(e.target);
14980
14981      var $select = $target.closest('.select2');
14982
14983      var $all = $('.select2.select2-container--open');
14984
14985      $all.each(function () {
14986        if (this == $select[0]) {
14987          return;
14988        }
14989
14990        var $element = Utils.GetData(this, 'element');
14991
14992        $element.select2('close');
14993      });
14994    });
14995  };
14996
14997  BaseSelection.prototype._detachCloseHandler = function (container) {
14998    $(document.body).off('mousedown.select2.' + container.id);
14999  };
15000
15001  BaseSelection.prototype.position = function ($selection, $container) {
15002    var $selectionContainer = $container.find('.selection');
15003    $selectionContainer.append($selection);
15004  };
15005
15006  BaseSelection.prototype.destroy = function () {
15007    this._detachCloseHandler(this.container);
15008  };
15009
15010  BaseSelection.prototype.update = function (data) {
15011    throw new Error('The `update` method must be defined in child classes.');
15012  };
15013
15014  /**
15015   * Helper method to abstract the "enabled" (not "disabled") state of this
15016   * object.
15017   *
15018   * @return {true} if the instance is not disabled.
15019   * @return {false} if the instance is disabled.
15020   */
15021  BaseSelection.prototype.isEnabled = function () {
15022    return !this.isDisabled();
15023  };
15024
15025  /**
15026   * Helper method to abstract the "disabled" state of this object.
15027   *
15028   * @return {true} if the disabled option is true.
15029   * @return {false} if the disabled option is false.
15030   */
15031  BaseSelection.prototype.isDisabled = function () {
15032    return this.options.get('disabled');
15033  };
15034
15035  return BaseSelection;
15036});
15037
15038S2.define('select2/selection/single',[
15039  'jquery',
15040  './base',
15041  '../utils',
15042  '../keys'
15043], function ($, BaseSelection, Utils, KEYS) {
15044  function SingleSelection () {
15045    SingleSelection.__super__.constructor.apply(this, arguments);
15046  }
15047
15048  Utils.Extend(SingleSelection, BaseSelection);
15049
15050  SingleSelection.prototype.render = function () {
15051    var $selection = SingleSelection.__super__.render.call(this);
15052
15053    $selection.addClass('select2-selection--single');
15054
15055    $selection.html(
15056      '<span class="select2-selection__rendered"></span>' +
15057      '<span class="select2-selection__arrow" role="presentation">' +
15058        '<b role="presentation"></b>' +
15059      '</span>'
15060    );
15061
15062    return $selection;
15063  };
15064
15065  SingleSelection.prototype.bind = function (container, $container) {
15066    var self = this;
15067
15068    SingleSelection.__super__.bind.apply(this, arguments);
15069
15070    var id = container.id + '-container';
15071
15072    this.$selection.find('.select2-selection__rendered')
15073      .attr('id', id)
15074      .attr('role', 'textbox')
15075      .attr('aria-readonly', 'true');
15076    this.$selection.attr('aria-labelledby', id);
15077
15078    this.$selection.on('mousedown', function (evt) {
15079      // Only respond to left clicks
15080      if (evt.which !== 1) {
15081        return;
15082      }
15083
15084      self.trigger('toggle', {
15085        originalEvent: evt
15086      });
15087    });
15088
15089    this.$selection.on('focus', function (evt) {
15090      // User focuses on the container
15091    });
15092
15093    this.$selection.on('blur', function (evt) {
15094      // User exits the container
15095    });
15096
15097    container.on('focus', function (evt) {
15098      if (!container.isOpen()) {
15099        self.$selection.trigger('focus');
15100      }
15101    });
15102  };
15103
15104  SingleSelection.prototype.clear = function () {
15105    var $rendered = this.$selection.find('.select2-selection__rendered');
15106    $rendered.empty();
15107    $rendered.removeAttr('title'); // clear tooltip on empty
15108  };
15109
15110  SingleSelection.prototype.display = function (data, container) {
15111    var template = this.options.get('templateSelection');
15112    var escapeMarkup = this.options.get('escapeMarkup');
15113
15114    return escapeMarkup(template(data, container));
15115  };
15116
15117  SingleSelection.prototype.selectionContainer = function () {
15118    return $('<span></span>');
15119  };
15120
15121  SingleSelection.prototype.update = function (data) {
15122    if (data.length === 0) {
15123      this.clear();
15124      return;
15125    }
15126
15127    var selection = data[0];
15128
15129    var $rendered = this.$selection.find('.select2-selection__rendered');
15130    var formatted = this.display(selection, $rendered);
15131
15132    $rendered.empty().append(formatted);
15133
15134    var title = selection.title || selection.text;
15135
15136    if (title) {
15137      $rendered.attr('title', title);
15138    } else {
15139      $rendered.removeAttr('title');
15140    }
15141  };
15142
15143  return SingleSelection;
15144});
15145
15146S2.define('select2/selection/multiple',[
15147  'jquery',
15148  './base',
15149  '../utils'
15150], function ($, BaseSelection, Utils) {
15151  function MultipleSelection ($element, options) {
15152    MultipleSelection.__super__.constructor.apply(this, arguments);
15153  }
15154
15155  Utils.Extend(MultipleSelection, BaseSelection);
15156
15157  MultipleSelection.prototype.render = function () {
15158    var $selection = MultipleSelection.__super__.render.call(this);
15159
15160    $selection.addClass('select2-selection--multiple');
15161
15162    $selection.html(
15163      '<ul class="select2-selection__rendered"></ul>'
15164    );
15165
15166    return $selection;
15167  };
15168
15169  MultipleSelection.prototype.bind = function (container, $container) {
15170    var self = this;
15171
15172    MultipleSelection.__super__.bind.apply(this, arguments);
15173
15174    this.$selection.on('click', function (evt) {
15175      self.trigger('toggle', {
15176        originalEvent: evt
15177      });
15178    });
15179
15180    this.$selection.on(
15181      'click',
15182      '.select2-selection__choice__remove',
15183      function (evt) {
15184        // Ignore the event if it is disabled
15185        if (self.isDisabled()) {
15186          return;
15187        }
15188
15189        var $remove = $(this);
15190        var $selection = $remove.parent();
15191
15192        var data = Utils.GetData($selection[0], 'data');
15193
15194        self.trigger('unselect', {
15195          originalEvent: evt,
15196          data: data
15197        });
15198      }
15199    );
15200  };
15201
15202  MultipleSelection.prototype.clear = function () {
15203    var $rendered = this.$selection.find('.select2-selection__rendered');
15204    $rendered.empty();
15205    $rendered.removeAttr('title');
15206  };
15207
15208  MultipleSelection.prototype.display = function (data, container) {
15209    var template = this.options.get('templateSelection');
15210    var escapeMarkup = this.options.get('escapeMarkup');
15211
15212    return escapeMarkup(template(data, container));
15213  };
15214
15215  MultipleSelection.prototype.selectionContainer = function () {
15216    var $container = $(
15217      '<li class="select2-selection__choice">' +
15218        '<span class="select2-selection__choice__remove" role="presentation">' +
15219          '&times;' +
15220        '</span>' +
15221      '</li>'
15222    );
15223
15224    return $container;
15225  };
15226
15227  MultipleSelection.prototype.update = function (data) {
15228    this.clear();
15229
15230    if (data.length === 0) {
15231      return;
15232    }
15233
15234    var $selections = [];
15235
15236    for (var d = 0; d < data.length; d++) {
15237      var selection = data[d];
15238
15239      var $selection = this.selectionContainer();
15240      var formatted = this.display(selection, $selection);
15241
15242      $selection.append(formatted);
15243
15244      var title = selection.title || selection.text;
15245
15246      if (title) {
15247        $selection.attr('title', title);
15248      }
15249
15250      Utils.StoreData($selection[0], 'data', selection);
15251
15252      $selections.push($selection);
15253    }
15254
15255    var $rendered = this.$selection.find('.select2-selection__rendered');
15256
15257    Utils.appendMany($rendered, $selections);
15258  };
15259
15260  return MultipleSelection;
15261});
15262
15263S2.define('select2/selection/placeholder',[
15264  '../utils'
15265], function (Utils) {
15266  function Placeholder (decorated, $element, options) {
15267    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
15268
15269    decorated.call(this, $element, options);
15270  }
15271
15272  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
15273    if (typeof placeholder === 'string') {
15274      placeholder = {
15275        id: '',
15276        text: placeholder
15277      };
15278    }
15279
15280    return placeholder;
15281  };
15282
15283  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
15284    var $placeholder = this.selectionContainer();
15285
15286    $placeholder.html(this.display(placeholder));
15287    $placeholder.addClass('select2-selection__placeholder')
15288                .removeClass('select2-selection__choice');
15289
15290    return $placeholder;
15291  };
15292
15293  Placeholder.prototype.update = function (decorated, data) {
15294    var singlePlaceholder = (
15295      data.length == 1 && data[0].id != this.placeholder.id
15296    );
15297    var multipleSelections = data.length > 1;
15298
15299    if (multipleSelections || singlePlaceholder) {
15300      return decorated.call(this, data);
15301    }
15302
15303    this.clear();
15304
15305    var $placeholder = this.createPlaceholder(this.placeholder);
15306
15307    this.$selection.find('.select2-selection__rendered').append($placeholder);
15308  };
15309
15310  return Placeholder;
15311});
15312
15313S2.define('select2/selection/allowClear',[
15314  'jquery',
15315  '../keys',
15316  '../utils'
15317], function ($, KEYS, Utils) {
15318  function AllowClear () { }
15319
15320  AllowClear.prototype.bind = function (decorated, container, $container) {
15321    var self = this;
15322
15323    decorated.call(this, container, $container);
15324
15325    if (this.placeholder == null) {
15326      if (this.options.get('debug') && window.console && console.error) {
15327        console.error(
15328          'Select2: The `allowClear` option should be used in combination ' +
15329          'with the `placeholder` option.'
15330        );
15331      }
15332    }
15333
15334    this.$selection.on('mousedown', '.select2-selection__clear',
15335      function (evt) {
15336        self._handleClear(evt);
15337    });
15338
15339    container.on('keypress', function (evt) {
15340      self._handleKeyboardClear(evt, container);
15341    });
15342  };
15343
15344  AllowClear.prototype._handleClear = function (_, evt) {
15345    // Ignore the event if it is disabled
15346    if (this.isDisabled()) {
15347      return;
15348    }
15349
15350    var $clear = this.$selection.find('.select2-selection__clear');
15351
15352    // Ignore the event if nothing has been selected
15353    if ($clear.length === 0) {
15354      return;
15355    }
15356
15357    evt.stopPropagation();
15358
15359    var data = Utils.GetData($clear[0], 'data');
15360
15361    var previousVal = this.$element.val();
15362    this.$element.val(this.placeholder.id);
15363
15364    var unselectData = {
15365      data: data
15366    };
15367    this.trigger('clear', unselectData);
15368    if (unselectData.prevented) {
15369      this.$element.val(previousVal);
15370      return;
15371    }
15372
15373    for (var d = 0; d < data.length; d++) {
15374      unselectData = {
15375        data: data[d]
15376      };
15377
15378      // Trigger the `unselect` event, so people can prevent it from being
15379      // cleared.
15380      this.trigger('unselect', unselectData);
15381
15382      // If the event was prevented, don't clear it out.
15383      if (unselectData.prevented) {
15384        this.$element.val(previousVal);
15385        return;
15386      }
15387    }
15388
15389    this.$element.trigger('input').trigger('change');
15390
15391    this.trigger('toggle', {});
15392  };
15393
15394  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
15395    if (container.isOpen()) {
15396      return;
15397    }
15398
15399    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
15400      this._handleClear(evt);
15401    }
15402  };
15403
15404  AllowClear.prototype.update = function (decorated, data) {
15405    decorated.call(this, data);
15406
15407    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
15408        data.length === 0) {
15409      return;
15410    }
15411
15412    var removeAll = this.options.get('translations').get('removeAllItems');
15413
15414    var $remove = $(
15415      '<span class="select2-selection__clear" title="' + removeAll() +'">' +
15416        '&times;' +
15417      '</span>'
15418    );
15419    Utils.StoreData($remove[0], 'data', data);
15420
15421    this.$selection.find('.select2-selection__rendered').prepend($remove);
15422  };
15423
15424  return AllowClear;
15425});
15426
15427S2.define('select2/selection/search',[
15428  'jquery',
15429  '../utils',
15430  '../keys'
15431], function ($, Utils, KEYS) {
15432  function Search (decorated, $element, options) {
15433    decorated.call(this, $element, options);
15434  }
15435
15436  Search.prototype.render = function (decorated) {
15437    var $search = $(
15438      '<li class="select2-search select2-search--inline">' +
15439        '<input class="select2-search__field" type="search" tabindex="-1"' +
15440        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
15441        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
15442      '</li>'
15443    );
15444
15445    this.$searchContainer = $search;
15446    this.$search = $search.find('input');
15447
15448    var $rendered = decorated.call(this);
15449
15450    this._transferTabIndex();
15451
15452    return $rendered;
15453  };
15454
15455  Search.prototype.bind = function (decorated, container, $container) {
15456    var self = this;
15457
15458    var resultsId = container.id + '-results';
15459
15460    decorated.call(this, container, $container);
15461
15462    container.on('open', function () {
15463      self.$search.attr('aria-controls', resultsId);
15464      self.$search.trigger('focus');
15465    });
15466
15467    container.on('close', function () {
15468      self.$search.val('');
15469      self.$search.removeAttr('aria-controls');
15470      self.$search.removeAttr('aria-activedescendant');
15471      self.$search.trigger('focus');
15472    });
15473
15474    container.on('enable', function () {
15475      self.$search.prop('disabled', false);
15476
15477      self._transferTabIndex();
15478    });
15479
15480    container.on('disable', function () {
15481      self.$search.prop('disabled', true);
15482    });
15483
15484    container.on('focus', function (evt) {
15485      self.$search.trigger('focus');
15486    });
15487
15488    container.on('results:focus', function (params) {
15489      if (params.data._resultId) {
15490        self.$search.attr('aria-activedescendant', params.data._resultId);
15491      } else {
15492        self.$search.removeAttr('aria-activedescendant');
15493      }
15494    });
15495
15496    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
15497      self.trigger('focus', evt);
15498    });
15499
15500    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
15501      self._handleBlur(evt);
15502    });
15503
15504    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
15505      evt.stopPropagation();
15506
15507      self.trigger('keypress', evt);
15508
15509      self._keyUpPrevented = evt.isDefaultPrevented();
15510
15511      var key = evt.which;
15512
15513      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
15514        var $previousChoice = self.$searchContainer
15515          .prev('.select2-selection__choice');
15516
15517        if ($previousChoice.length > 0) {
15518          var item = Utils.GetData($previousChoice[0], 'data');
15519
15520          self.searchRemoveChoice(item);
15521
15522          evt.preventDefault();
15523        }
15524      }
15525    });
15526
15527    this.$selection.on('click', '.select2-search--inline', function (evt) {
15528      if (self.$search.val()) {
15529        evt.stopPropagation();
15530      }
15531    });
15532
15533    // Try to detect the IE version should the `documentMode` property that
15534    // is stored on the document. This is only implemented in IE and is
15535    // slightly cleaner than doing a user agent check.
15536    // This property is not available in Edge, but Edge also doesn't have
15537    // this bug.
15538    var msie = document.documentMode;
15539    var disableInputEvents = msie && msie <= 11;
15540
15541    // Workaround for browsers which do not support the `input` event
15542    // This will prevent double-triggering of events for browsers which support
15543    // both the `keyup` and `input` events.
15544    this.$selection.on(
15545      'input.searchcheck',
15546      '.select2-search--inline',
15547      function (evt) {
15548        // IE will trigger the `input` event when a placeholder is used on a
15549        // search box. To get around this issue, we are forced to ignore all
15550        // `input` events in IE and keep using `keyup`.
15551        if (disableInputEvents) {
15552          self.$selection.off('input.search input.searchcheck');
15553          return;
15554        }
15555
15556        // Unbind the duplicated `keyup` event
15557        self.$selection.off('keyup.search');
15558      }
15559    );
15560
15561    this.$selection.on(
15562      'keyup.search input.search',
15563      '.select2-search--inline',
15564      function (evt) {
15565        // IE will trigger the `input` event when a placeholder is used on a
15566        // search box. To get around this issue, we are forced to ignore all
15567        // `input` events in IE and keep using `keyup`.
15568        if (disableInputEvents && evt.type === 'input') {
15569          self.$selection.off('input.search input.searchcheck');
15570          return;
15571        }
15572
15573        var key = evt.which;
15574
15575        // We can freely ignore events from modifier keys
15576        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
15577          return;
15578        }
15579
15580        // Tabbing will be handled during the `keydown` phase
15581        if (key == KEYS.TAB) {
15582          return;
15583        }
15584
15585        self.handleSearch(evt);
15586      }
15587    );
15588  };
15589
15590  /**
15591   * This method will transfer the tabindex attribute from the rendered
15592   * selection to the search box. This allows for the search box to be used as
15593   * the primary focus instead of the selection container.
15594   *
15595   * @private
15596   */
15597  Search.prototype._transferTabIndex = function (decorated) {
15598    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
15599    this.$selection.attr('tabindex', '-1');
15600  };
15601
15602  Search.prototype.createPlaceholder = function (decorated, placeholder) {
15603    this.$search.attr('placeholder', placeholder.text);
15604  };
15605
15606  Search.prototype.update = function (decorated, data) {
15607    var searchHadFocus = this.$search[0] == document.activeElement;
15608
15609    this.$search.attr('placeholder', '');
15610
15611    decorated.call(this, data);
15612
15613    this.$selection.find('.select2-selection__rendered')
15614                   .append(this.$searchContainer);
15615
15616    this.resizeSearch();
15617    if (searchHadFocus) {
15618      this.$search.trigger('focus');
15619    }
15620  };
15621
15622  Search.prototype.handleSearch = function () {
15623    this.resizeSearch();
15624
15625    if (!this._keyUpPrevented) {
15626      var input = this.$search.val();
15627
15628      this.trigger('query', {
15629        term: input
15630      });
15631    }
15632
15633    this._keyUpPrevented = false;
vendor: 43,019 bytes, lines 15634-17634
15634  };
15635
15636  Search.prototype.searchRemoveChoice = function (decorated, item) {
15637    this.trigger('unselect', {
15638      data: item
15639    });
15640
15641    this.$search.val(item.text);
15642    this.handleSearch();
15643  };
15644
15645  Search.prototype.resizeSearch = function () {
15646    this.$search.css('width', '25px');
15647
15648    var width = '';
15649
15650    if (this.$search.attr('placeholder') !== '') {
15651      width = this.$selection.find('.select2-selection__rendered').width();
15652    } else {
15653      var minimumWidth = this.$search.val().length + 1;
15654
15655      width = (minimumWidth * 0.75) + 'em';
15656    }
15657
15658    this.$search.css('width', width);
15659  };
15660
15661  return Search;
15662});
15663
15664S2.define('select2/selection/eventRelay',[
15665  'jquery'
15666], function ($) {
15667  function EventRelay () { }
15668
15669  EventRelay.prototype.bind = function (decorated, container, $container) {
15670    var self = this;
15671    var relayEvents = [
15672      'open', 'opening',
15673      'close', 'closing',
15674      'select', 'selecting',
15675      'unselect', 'unselecting',
15676      'clear', 'clearing'
15677    ];
15678
15679    var preventableEvents = [
15680      'opening', 'closing', 'selecting', 'unselecting', 'clearing'
15681    ];
15682
15683    decorated.call(this, container, $container);
15684
15685    container.on('*', function (name, params) {
15686      // Ignore events that should not be relayed
15687      if ($.inArray(name, relayEvents) === -1) {
15688        return;
15689      }
15690
15691      // The parameters should always be an object
15692      params = params || {};
15693
15694      // Generate the jQuery event for the Select2 event
15695      var evt = $.Event('select2:' + name, {
15696        params: params
15697      });
15698
15699      self.$element.trigger(evt);
15700
15701      // Only handle preventable events if it was one
15702      if ($.inArray(name, preventableEvents) === -1) {
15703        return;
15704      }
15705
15706      params.prevented = evt.isDefaultPrevented();
15707    });
15708  };
15709
15710  return EventRelay;
15711});
15712
15713S2.define('select2/translation',[
15714  'jquery',
15715  'require'
15716], function ($, require) {
15717  function Translation (dict) {
15718    this.dict = dict || {};
15719  }
15720
15721  Translation.prototype.all = function () {
15722    return this.dict;
15723  };
15724
15725  Translation.prototype.get = function (key) {
15726    return this.dict[key];
15727  };
15728
15729  Translation.prototype.extend = function (translation) {
15730    this.dict = $.extend({}, translation.all(), this.dict);
15731  };
15732
15733  // Static functions
15734
15735  Translation._cache = {};
15736
15737  Translation.loadPath = function (path) {
15738    if (!(path in Translation._cache)) {
15739      var translations = require(path);
15740
15741      Translation._cache[path] = translations;
15742    }
15743
15744    return new Translation(Translation._cache[path]);
15745  };
15746
15747  return Translation;
15748});
15749
15750S2.define('select2/diacritics',[
15751
15752], function () {
15753  var diacritics = {
15754    '\u24B6': 'A',
15755    '\uFF21': 'A',
15756    '\u00C0': 'A',
15757    '\u00C1': 'A',
15758    '\u00C2': 'A',
15759    '\u1EA6': 'A',
15760    '\u1EA4': 'A',
15761    '\u1EAA': 'A',
15762    '\u1EA8': 'A',
15763    '\u00C3': 'A',
15764    '\u0100': 'A',
15765    '\u0102': 'A',
15766    '\u1EB0': 'A',
15767    '\u1EAE': 'A',
15768    '\u1EB4': 'A',
15769    '\u1EB2': 'A',
15770    '\u0226': 'A',
15771    '\u01E0': 'A',
15772    '\u00C4': 'A',
15773    '\u01DE': 'A',
15774    '\u1EA2': 'A',
15775    '\u00C5': 'A',
15776    '\u01FA': 'A',
15777    '\u01CD': 'A',
15778    '\u0200': 'A',
15779    '\u0202': 'A',
15780    '\u1EA0': 'A',
15781    '\u1EAC': 'A',
15782    '\u1EB6': 'A',
15783    '\u1E00': 'A',
15784    '\u0104': 'A',
15785    '\u023A': 'A',
15786    '\u2C6F': 'A',
15787    '\uA732': 'AA',
15788    '\u00C6': 'AE',
15789    '\u01FC': 'AE',
15790    '\u01E2': 'AE',
15791    '\uA734': 'AO',
15792    '\uA736': 'AU',
15793    '\uA738': 'AV',
15794    '\uA73A': 'AV',
15795    '\uA73C': 'AY',
15796    '\u24B7': 'B',
15797    '\uFF22': 'B',
15798    '\u1E02': 'B',
15799    '\u1E04': 'B',
15800    '\u1E06': 'B',
15801    '\u0243': 'B',
15802    '\u0182': 'B',
15803    '\u0181': 'B',
15804    '\u24B8': 'C',
15805    '\uFF23': 'C',
15806    '\u0106': 'C',
15807    '\u0108': 'C',
15808    '\u010A': 'C',
15809    '\u010C': 'C',
15810    '\u00C7': 'C',
15811    '\u1E08': 'C',
15812    '\u0187': 'C',
15813    '\u023B': 'C',
15814    '\uA73E': 'C',
15815    '\u24B9': 'D',
15816    '\uFF24': 'D',
15817    '\u1E0A': 'D',
15818    '\u010E': 'D',
15819    '\u1E0C': 'D',
15820    '\u1E10': 'D',
15821    '\u1E12': 'D',
15822    '\u1E0E': 'D',
15823    '\u0110': 'D',
15824    '\u018B': 'D',
15825    '\u018A': 'D',
15826    '\u0189': 'D',
15827    '\uA779': 'D',
15828    '\u01F1': 'DZ',
15829    '\u01C4': 'DZ',
15830    '\u01F2': 'Dz',
15831    '\u01C5': 'Dz',
15832    '\u24BA': 'E',
15833    '\uFF25': 'E',
15834    '\u00C8': 'E',
15835    '\u00C9': 'E',
15836    '\u00CA': 'E',
15837    '\u1EC0': 'E',
15838    '\u1EBE': 'E',
15839    '\u1EC4': 'E',
15840    '\u1EC2': 'E',
15841    '\u1EBC': 'E',
15842    '\u0112': 'E',
15843    '\u1E14': 'E',
15844    '\u1E16': 'E',
15845    '\u0114': 'E',
15846    '\u0116': 'E',
15847    '\u00CB': 'E',
15848    '\u1EBA': 'E',
15849    '\u011A': 'E',
15850    '\u0204': 'E',
15851    '\u0206': 'E',
15852    '\u1EB8': 'E',
15853    '\u1EC6': 'E',
15854    '\u0228': 'E',
15855    '\u1E1C': 'E',
15856    '\u0118': 'E',
15857    '\u1E18': 'E',
15858    '\u1E1A': 'E',
15859    '\u0190': 'E',
15860    '\u018E': 'E',
15861    '\u24BB': 'F',
15862    '\uFF26': 'F',
15863    '\u1E1E': 'F',
15864    '\u0191': 'F',
15865    '\uA77B': 'F',
15866    '\u24BC': 'G',
15867    '\uFF27': 'G',
15868    '\u01F4': 'G',
15869    '\u011C': 'G',
15870    '\u1E20': 'G',
15871    '\u011E': 'G',
15872    '\u0120': 'G',
15873    '\u01E6': 'G',
15874    '\u0122': 'G',
15875    '\u01E4': 'G',
15876    '\u0193': 'G',
15877    '\uA7A0': 'G',
15878    '\uA77D': 'G',
15879    '\uA77E': 'G',
15880    '\u24BD': 'H',
15881    '\uFF28': 'H',
15882    '\u0124': 'H',
15883    '\u1E22': 'H',
15884    '\u1E26': 'H',
15885    '\u021E': 'H',
15886    '\u1E24': 'H',
15887    '\u1E28': 'H',
15888    '\u1E2A': 'H',
15889    '\u0126': 'H',
15890    '\u2C67': 'H',
15891    '\u2C75': 'H',
15892    '\uA78D': 'H',
15893    '\u24BE': 'I',
15894    '\uFF29': 'I',
15895    '\u00CC': 'I',
15896    '\u00CD': 'I',
15897    '\u00CE': 'I',
15898    '\u0128': 'I',
15899    '\u012A': 'I',
15900    '\u012C': 'I',
15901    '\u0130': 'I',
15902    '\u00CF': 'I',
15903    '\u1E2E': 'I',
15904    '\u1EC8': 'I',
15905    '\u01CF': 'I',
15906    '\u0208': 'I',
15907    '\u020A': 'I',
15908    '\u1ECA': 'I',
15909    '\u012E': 'I',
15910    '\u1E2C': 'I',
15911    '\u0197': 'I',
15912    '\u24BF': 'J',
15913    '\uFF2A': 'J',
15914    '\u0134': 'J',
15915    '\u0248': 'J',
15916    '\u24C0': 'K',
15917    '\uFF2B': 'K',
15918    '\u1E30': 'K',
15919    '\u01E8': 'K',
15920    '\u1E32': 'K',
15921    '\u0136': 'K',
15922    '\u1E34': 'K',
15923    '\u0198': 'K',
15924    '\u2C69': 'K',
15925    '\uA740': 'K',
15926    '\uA742': 'K',
15927    '\uA744': 'K',
15928    '\uA7A2': 'K',
15929    '\u24C1': 'L',
15930    '\uFF2C': 'L',
15931    '\u013F': 'L',
15932    '\u0139': 'L',
15933    '\u013D': 'L',
15934    '\u1E36': 'L',
15935    '\u1E38': 'L',
15936    '\u013B': 'L',
15937    '\u1E3C': 'L',
15938    '\u1E3A': 'L',
15939    '\u0141': 'L',
15940    '\u023D': 'L',
15941    '\u2C62': 'L',
15942    '\u2C60': 'L',
15943    '\uA748': 'L',
15944    '\uA746': 'L',
15945    '\uA780': 'L',
15946    '\u01C7': 'LJ',
15947    '\u01C8': 'Lj',
15948    '\u24C2': 'M',
15949    '\uFF2D': 'M',
15950    '\u1E3E': 'M',
15951    '\u1E40': 'M',
15952    '\u1E42': 'M',
15953    '\u2C6E': 'M',
15954    '\u019C': 'M',
15955    '\u24C3': 'N',
15956    '\uFF2E': 'N',
15957    '\u01F8': 'N',
15958    '\u0143': 'N',
15959    '\u00D1': 'N',
15960    '\u1E44': 'N',
15961    '\u0147': 'N',
15962    '\u1E46': 'N',
15963    '\u0145': 'N',
15964    '\u1E4A': 'N',
15965    '\u1E48': 'N',
15966    '\u0220': 'N',
15967    '\u019D': 'N',
15968    '\uA790': 'N',
15969    '\uA7A4': 'N',
15970    '\u01CA': 'NJ',
15971    '\u01CB': 'Nj',
15972    '\u24C4': 'O',
15973    '\uFF2F': 'O',
15974    '\u00D2': 'O',
15975    '\u00D3': 'O',
15976    '\u00D4': 'O',
15977    '\u1ED2': 'O',
15978    '\u1ED0': 'O',
15979    '\u1ED6': 'O',
15980    '\u1ED4': 'O',
15981    '\u00D5': 'O',
15982    '\u1E4C': 'O',
15983    '\u022C': 'O',
15984    '\u1E4E': 'O',
15985    '\u014C': 'O',
15986    '\u1E50': 'O',
15987    '\u1E52': 'O',
15988    '\u014E': 'O',
15989    '\u022E': 'O',
15990    '\u0230': 'O',
15991    '\u00D6': 'O',
15992    '\u022A': 'O',
15993    '\u1ECE': 'O',
15994    '\u0150': 'O',
15995    '\u01D1': 'O',
15996    '\u020C': 'O',
15997    '\u020E': 'O',
15998    '\u01A0': 'O',
15999    '\u1EDC': 'O',
16000    '\u1EDA': 'O',
16001    '\u1EE0': 'O',
16002    '\u1EDE': 'O',
16003    '\u1EE2': 'O',
16004    '\u1ECC': 'O',
16005    '\u1ED8': 'O',
16006    '\u01EA': 'O',
16007    '\u01EC': 'O',
16008    '\u00D8': 'O',
16009    '\u01FE': 'O',
16010    '\u0186': 'O',
16011    '\u019F': 'O',
16012    '\uA74A': 'O',
16013    '\uA74C': 'O',
16014    '\u0152': 'OE',
16015    '\u01A2': 'OI',
16016    '\uA74E': 'OO',
16017    '\u0222': 'OU',
16018    '\u24C5': 'P',
16019    '\uFF30': 'P',
16020    '\u1E54': 'P',
16021    '\u1E56': 'P',
16022    '\u01A4': 'P',
16023    '\u2C63': 'P',
16024    '\uA750': 'P',
16025    '\uA752': 'P',
16026    '\uA754': 'P',
16027    '\u24C6': 'Q',
16028    '\uFF31': 'Q',
16029    '\uA756': 'Q',
16030    '\uA758': 'Q',
16031    '\u024A': 'Q',
16032    '\u24C7': 'R',
16033    '\uFF32': 'R',
16034    '\u0154': 'R',
16035    '\u1E58': 'R',
16036    '\u0158': 'R',
16037    '\u0210': 'R',
16038    '\u0212': 'R',
16039    '\u1E5A': 'R',
16040    '\u1E5C': 'R',
16041    '\u0156': 'R',
16042    '\u1E5E': 'R',
16043    '\u024C': 'R',
16044    '\u2C64': 'R',
16045    '\uA75A': 'R',
16046    '\uA7A6': 'R',
16047    '\uA782': 'R',
16048    '\u24C8': 'S',
16049    '\uFF33': 'S',
16050    '\u1E9E': 'S',
16051    '\u015A': 'S',
16052    '\u1E64': 'S',
16053    '\u015C': 'S',
16054    '\u1E60': 'S',
16055    '\u0160': 'S',
16056    '\u1E66': 'S',
16057    '\u1E62': 'S',
16058    '\u1E68': 'S',
16059    '\u0218': 'S',
16060    '\u015E': 'S',
16061    '\u2C7E': 'S',
16062    '\uA7A8': 'S',
16063    '\uA784': 'S',
16064    '\u24C9': 'T',
16065    '\uFF34': 'T',
16066    '\u1E6A': 'T',
16067    '\u0164': 'T',
16068    '\u1E6C': 'T',
16069    '\u021A': 'T',
16070    '\u0162': 'T',
16071    '\u1E70': 'T',
16072    '\u1E6E': 'T',
16073    '\u0166': 'T',
16074    '\u01AC': 'T',
16075    '\u01AE': 'T',
16076    '\u023E': 'T',
16077    '\uA786': 'T',
16078    '\uA728': 'TZ',
16079    '\u24CA': 'U',
16080    '\uFF35': 'U',
16081    '\u00D9': 'U',
16082    '\u00DA': 'U',
16083    '\u00DB': 'U',
16084    '\u0168': 'U',
16085    '\u1E78': 'U',
16086    '\u016A': 'U',
16087    '\u1E7A': 'U',
16088    '\u016C': 'U',
16089    '\u00DC': 'U',
16090    '\u01DB': 'U',
16091    '\u01D7': 'U',
16092    '\u01D5': 'U',
16093    '\u01D9': 'U',
16094    '\u1EE6': 'U',
16095    '\u016E': 'U',
16096    '\u0170': 'U',
16097    '\u01D3': 'U',
16098    '\u0214': 'U',
16099    '\u0216': 'U',
16100    '\u01AF': 'U',
16101    '\u1EEA': 'U',
16102    '\u1EE8': 'U',
16103    '\u1EEE': 'U',
16104    '\u1EEC': 'U',
16105    '\u1EF0': 'U',
16106    '\u1EE4': 'U',
16107    '\u1E72': 'U',
16108    '\u0172': 'U',
16109    '\u1E76': 'U',
16110    '\u1E74': 'U',
16111    '\u0244': 'U',
16112    '\u24CB': 'V',
16113    '\uFF36': 'V',
16114    '\u1E7C': 'V',
16115    '\u1E7E': 'V',
16116    '\u01B2': 'V',
16117    '\uA75E': 'V',
16118    '\u0245': 'V',
16119    '\uA760': 'VY',
16120    '\u24CC': 'W',
16121    '\uFF37': 'W',
16122    '\u1E80': 'W',
16123    '\u1E82': 'W',
16124    '\u0174': 'W',
16125    '\u1E86': 'W',
16126    '\u1E84': 'W',
16127    '\u1E88': 'W',
16128    '\u2C72': 'W',
16129    '\u24CD': 'X',
16130    '\uFF38': 'X',
16131    '\u1E8A': 'X',
16132    '\u1E8C': 'X',
16133    '\u24CE': 'Y',
16134    '\uFF39': 'Y',
16135    '\u1EF2': 'Y',
16136    '\u00DD': 'Y',
16137    '\u0176': 'Y',
16138    '\u1EF8': 'Y',
16139    '\u0232': 'Y',
16140    '\u1E8E': 'Y',
16141    '\u0178': 'Y',
16142    '\u1EF6': 'Y',
16143    '\u1EF4': 'Y',
16144    '\u01B3': 'Y',
16145    '\u024E': 'Y',
16146    '\u1EFE': 'Y',
16147    '\u24CF': 'Z',
16148    '\uFF3A': 'Z',
16149    '\u0179': 'Z',
16150    '\u1E90': 'Z',
16151    '\u017B': 'Z',
16152    '\u017D': 'Z',
16153    '\u1E92': 'Z',
16154    '\u1E94': 'Z',
16155    '\u01B5': 'Z',
16156    '\u0224': 'Z',
16157    '\u2C7F': 'Z',
16158    '\u2C6B': 'Z',
16159    '\uA762': 'Z',
16160    '\u24D0': 'a',
16161    '\uFF41': 'a',
16162    '\u1E9A': 'a',
16163    '\u00E0': 'a',
16164    '\u00E1': 'a',
16165    '\u00E2': 'a',
16166    '\u1EA7': 'a',
16167    '\u1EA5': 'a',
16168    '\u1EAB': 'a',
16169    '\u1EA9': 'a',
16170    '\u00E3': 'a',
16171    '\u0101': 'a',
16172    '\u0103': 'a',
16173    '\u1EB1': 'a',
16174    '\u1EAF': 'a',
16175    '\u1EB5': 'a',
16176    '\u1EB3': 'a',
16177    '\u0227': 'a',
16178    '\u01E1': 'a',
16179    '\u00E4': 'a',
16180    '\u01DF': 'a',
16181    '\u1EA3': 'a',
16182    '\u00E5': 'a',
16183    '\u01FB': 'a',
16184    '\u01CE': 'a',
16185    '\u0201': 'a',
16186    '\u0203': 'a',
16187    '\u1EA1': 'a',
16188    '\u1EAD': 'a',
16189    '\u1EB7': 'a',
16190    '\u1E01': 'a',
16191    '\u0105': 'a',
16192    '\u2C65': 'a',
16193    '\u0250': 'a',
16194    '\uA733': 'aa',
16195    '\u00E6': 'ae',
16196    '\u01FD': 'ae',
16197    '\u01E3': 'ae',
16198    '\uA735': 'ao',
16199    '\uA737': 'au',
16200    '\uA739': 'av',
16201    '\uA73B': 'av',
16202    '\uA73D': 'ay',
16203    '\u24D1': 'b',
16204    '\uFF42': 'b',
16205    '\u1E03': 'b',
16206    '\u1E05': 'b',
16207    '\u1E07': 'b',
16208    '\u0180': 'b',
16209    '\u0183': 'b',
16210    '\u0253': 'b',
16211    '\u24D2': 'c',
16212    '\uFF43': 'c',
16213    '\u0107': 'c',
16214    '\u0109': 'c',
16215    '\u010B': 'c',
16216    '\u010D': 'c',
16217    '\u00E7': 'c',
16218    '\u1E09': 'c',
16219    '\u0188': 'c',
16220    '\u023C': 'c',
16221    '\uA73F': 'c',
16222    '\u2184': 'c',
16223    '\u24D3': 'd',
16224    '\uFF44': 'd',
16225    '\u1E0B': 'd',
16226    '\u010F': 'd',
16227    '\u1E0D': 'd',
16228    '\u1E11': 'd',
16229    '\u1E13': 'd',
16230    '\u1E0F': 'd',
16231    '\u0111': 'd',
16232    '\u018C': 'd',
16233    '\u0256': 'd',
16234    '\u0257': 'd',
16235    '\uA77A': 'd',
16236    '\u01F3': 'dz',
16237    '\u01C6': 'dz',
16238    '\u24D4': 'e',
16239    '\uFF45': 'e',
16240    '\u00E8': 'e',
16241    '\u00E9': 'e',
16242    '\u00EA': 'e',
16243    '\u1EC1': 'e',
16244    '\u1EBF': 'e',
16245    '\u1EC5': 'e',
16246    '\u1EC3': 'e',
16247    '\u1EBD': 'e',
16248    '\u0113': 'e',
16249    '\u1E15': 'e',
16250    '\u1E17': 'e',
16251    '\u0115': 'e',
16252    '\u0117': 'e',
16253    '\u00EB': 'e',
16254    '\u1EBB': 'e',
16255    '\u011B': 'e',
16256    '\u0205': 'e',
16257    '\u0207': 'e',
16258    '\u1EB9': 'e',
16259    '\u1EC7': 'e',
16260    '\u0229': 'e',
16261    '\u1E1D': 'e',
16262    '\u0119': 'e',
16263    '\u1E19': 'e',
16264    '\u1E1B': 'e',
16265    '\u0247': 'e',
16266    '\u025B': 'e',
16267    '\u01DD': 'e',
16268    '\u24D5': 'f',
16269    '\uFF46': 'f',
16270    '\u1E1F': 'f',
16271    '\u0192': 'f',
16272    '\uA77C': 'f',
16273    '\u24D6': 'g',
16274    '\uFF47': 'g',
16275    '\u01F5': 'g',
16276    '\u011D': 'g',
16277    '\u1E21': 'g',
16278    '\u011F': 'g',
16279    '\u0121': 'g',
16280    '\u01E7': 'g',
16281    '\u0123': 'g',
16282    '\u01E5': 'g',
16283    '\u0260': 'g',
16284    '\uA7A1': 'g',
16285    '\u1D79': 'g',
16286    '\uA77F': 'g',
16287    '\u24D7': 'h',
16288    '\uFF48': 'h',
16289    '\u0125': 'h',
16290    '\u1E23': 'h',
16291    '\u1E27': 'h',
16292    '\u021F': 'h',
16293    '\u1E25': 'h',
16294    '\u1E29': 'h',
16295    '\u1E2B': 'h',
16296    '\u1E96': 'h',
16297    '\u0127': 'h',
16298    '\u2C68': 'h',
16299    '\u2C76': 'h',
16300    '\u0265': 'h',
16301    '\u0195': 'hv',
16302    '\u24D8': 'i',
16303    '\uFF49': 'i',
16304    '\u00EC': 'i',
16305    '\u00ED': 'i',
16306    '\u00EE': 'i',
16307    '\u0129': 'i',
16308    '\u012B': 'i',
16309    '\u012D': 'i',
16310    '\u00EF': 'i',
16311    '\u1E2F': 'i',
16312    '\u1EC9': 'i',
16313    '\u01D0': 'i',
16314    '\u0209': 'i',
16315    '\u020B': 'i',
16316    '\u1ECB': 'i',
16317    '\u012F': 'i',
16318    '\u1E2D': 'i',
16319    '\u0268': 'i',
16320    '\u0131': 'i',
16321    '\u24D9': 'j',
16322    '\uFF4A': 'j',
16323    '\u0135': 'j',
16324    '\u01F0': 'j',
16325    '\u0249': 'j',
16326    '\u24DA': 'k',
16327    '\uFF4B': 'k',
16328    '\u1E31': 'k',
16329    '\u01E9': 'k',
16330    '\u1E33': 'k',
16331    '\u0137': 'k',
16332    '\u1E35': 'k',
16333    '\u0199': 'k',
16334    '\u2C6A': 'k',
16335    '\uA741': 'k',
16336    '\uA743': 'k',
16337    '\uA745': 'k',
16338    '\uA7A3': 'k',
16339    '\u24DB': 'l',
16340    '\uFF4C': 'l',
16341    '\u0140': 'l',
16342    '\u013A': 'l',
16343    '\u013E': 'l',
16344    '\u1E37': 'l',
16345    '\u1E39': 'l',
16346    '\u013C': 'l',
16347    '\u1E3D': 'l',
16348    '\u1E3B': 'l',
16349    '\u017F': 'l',
16350    '\u0142': 'l',
16351    '\u019A': 'l',
16352    '\u026B': 'l',
16353    '\u2C61': 'l',
16354    '\uA749': 'l',
16355    '\uA781': 'l',
16356    '\uA747': 'l',
16357    '\u01C9': 'lj',
16358    '\u24DC': 'm',
16359    '\uFF4D': 'm',
16360    '\u1E3F': 'm',
16361    '\u1E41': 'm',
16362    '\u1E43': 'm',
16363    '\u0271': 'm',
16364    '\u026F': 'm',
16365    '\u24DD': 'n',
16366    '\uFF4E': 'n',
16367    '\u01F9': 'n',
16368    '\u0144': 'n',
16369    '\u00F1': 'n',
16370    '\u1E45': 'n',
16371    '\u0148': 'n',
16372    '\u1E47': 'n',
16373    '\u0146': 'n',
16374    '\u1E4B': 'n',
16375    '\u1E49': 'n',
16376    '\u019E': 'n',
16377    '\u0272': 'n',
16378    '\u0149': 'n',
16379    '\uA791': 'n',
16380    '\uA7A5': 'n',
16381    '\u01CC': 'nj',
16382    '\u24DE': 'o',
16383    '\uFF4F': 'o',
16384    '\u00F2': 'o',
16385    '\u00F3': 'o',
16386    '\u00F4': 'o',
16387    '\u1ED3': 'o',
16388    '\u1ED1': 'o',
16389    '\u1ED7': 'o',
16390    '\u1ED5': 'o',
16391    '\u00F5': 'o',
16392    '\u1E4D': 'o',
16393    '\u022D': 'o',
16394    '\u1E4F': 'o',
16395    '\u014D': 'o',
16396    '\u1E51': 'o',
16397    '\u1E53': 'o',
16398    '\u014F': 'o',
16399    '\u022F': 'o',
16400    '\u0231': 'o',
16401    '\u00F6': 'o',
16402    '\u022B': 'o',
16403    '\u1ECF': 'o',
16404    '\u0151': 'o',
16405    '\u01D2': 'o',
16406    '\u020D': 'o',
16407    '\u020F': 'o',
16408    '\u01A1': 'o',
16409    '\u1EDD': 'o',
16410    '\u1EDB': 'o',
16411    '\u1EE1': 'o',
16412    '\u1EDF': 'o',
16413    '\u1EE3': 'o',
16414    '\u1ECD': 'o',
16415    '\u1ED9': 'o',
16416    '\u01EB': 'o',
16417    '\u01ED': 'o',
16418    '\u00F8': 'o',
16419    '\u01FF': 'o',
16420    '\u0254': 'o',
16421    '\uA74B': 'o',
16422    '\uA74D': 'o',
16423    '\u0275': 'o',
16424    '\u0153': 'oe',
16425    '\u01A3': 'oi',
16426    '\u0223': 'ou',
16427    '\uA74F': 'oo',
16428    '\u24DF': 'p',
16429    '\uFF50': 'p',
16430    '\u1E55': 'p',
16431    '\u1E57': 'p',
16432    '\u01A5': 'p',
16433    '\u1D7D': 'p',
16434    '\uA751': 'p',
16435    '\uA753': 'p',
16436    '\uA755': 'p',
16437    '\u24E0': 'q',
16438    '\uFF51': 'q',
16439    '\u024B': 'q',
16440    '\uA757': 'q',
16441    '\uA759': 'q',
16442    '\u24E1': 'r',
16443    '\uFF52': 'r',
16444    '\u0155': 'r',
16445    '\u1E59': 'r',
16446    '\u0159': 'r',
16447    '\u0211': 'r',
16448    '\u0213': 'r',
16449    '\u1E5B': 'r',
16450    '\u1E5D': 'r',
16451    '\u0157': 'r',
16452    '\u1E5F': 'r',
16453    '\u024D': 'r',
16454    '\u027D': 'r',
16455    '\uA75B': 'r',
16456    '\uA7A7': 'r',
16457    '\uA783': 'r',
16458    '\u24E2': 's',
16459    '\uFF53': 's',
16460    '\u00DF': 's',
16461    '\u015B': 's',
16462    '\u1E65': 's',
16463    '\u015D': 's',
16464    '\u1E61': 's',
16465    '\u0161': 's',
16466    '\u1E67': 's',
16467    '\u1E63': 's',
16468    '\u1E69': 's',
16469    '\u0219': 's',
16470    '\u015F': 's',
16471    '\u023F': 's',
16472    '\uA7A9': 's',
16473    '\uA785': 's',
16474    '\u1E9B': 's',
16475    '\u24E3': 't',
16476    '\uFF54': 't',
16477    '\u1E6B': 't',
16478    '\u1E97': 't',
16479    '\u0165': 't',
16480    '\u1E6D': 't',
16481    '\u021B': 't',
16482    '\u0163': 't',
16483    '\u1E71': 't',
16484    '\u1E6F': 't',
16485    '\u0167': 't',
16486    '\u01AD': 't',
16487    '\u0288': 't',
16488    '\u2C66': 't',
16489    '\uA787': 't',
16490    '\uA729': 'tz',
16491    '\u24E4': 'u',
16492    '\uFF55': 'u',
16493    '\u00F9': 'u',
16494    '\u00FA': 'u',
16495    '\u00FB': 'u',
16496    '\u0169': 'u',
16497    '\u1E79': 'u',
16498    '\u016B': 'u',
16499    '\u1E7B': 'u',
16500    '\u016D': 'u',
16501    '\u00FC': 'u',
16502    '\u01DC': 'u',
16503    '\u01D8': 'u',
16504    '\u01D6': 'u',
16505    '\u01DA': 'u',
16506    '\u1EE7': 'u',
16507    '\u016F': 'u',
16508    '\u0171': 'u',
16509    '\u01D4': 'u',
16510    '\u0215': 'u',
16511    '\u0217': 'u',
16512    '\u01B0': 'u',
16513    '\u1EEB': 'u',
16514    '\u1EE9': 'u',
16515    '\u1EEF': 'u',
16516    '\u1EED': 'u',
16517    '\u1EF1': 'u',
16518    '\u1EE5': 'u',
16519    '\u1E73': 'u',
16520    '\u0173': 'u',
16521    '\u1E77': 'u',
16522    '\u1E75': 'u',
16523    '\u0289': 'u',
16524    '\u24E5': 'v',
16525    '\uFF56': 'v',
16526    '\u1E7D': 'v',
16527    '\u1E7F': 'v',
16528    '\u028B': 'v',
16529    '\uA75F': 'v',
16530    '\u028C': 'v',
16531    '\uA761': 'vy',
16532    '\u24E6': 'w',
16533    '\uFF57': 'w',
16534    '\u1E81': 'w',
16535    '\u1E83': 'w',
16536    '\u0175': 'w',
16537    '\u1E87': 'w',
16538    '\u1E85': 'w',
16539    '\u1E98': 'w',
16540    '\u1E89': 'w',
16541    '\u2C73': 'w',
16542    '\u24E7': 'x',
16543    '\uFF58': 'x',
16544    '\u1E8B': 'x',
16545    '\u1E8D': 'x',
16546    '\u24E8': 'y',
16547    '\uFF59': 'y',
16548    '\u1EF3': 'y',
16549    '\u00FD': 'y',
16550    '\u0177': 'y',
16551    '\u1EF9': 'y',
16552    '\u0233': 'y',
16553    '\u1E8F': 'y',
16554    '\u00FF': 'y',
16555    '\u1EF7': 'y',
16556    '\u1E99': 'y',
16557    '\u1EF5': 'y',
16558    '\u01B4': 'y',
16559    '\u024F': 'y',
16560    '\u1EFF': 'y',
16561    '\u24E9': 'z',
16562    '\uFF5A': 'z',
16563    '\u017A': 'z',
16564    '\u1E91': 'z',
16565    '\u017C': 'z',
16566    '\u017E': 'z',
16567    '\u1E93': 'z',
16568    '\u1E95': 'z',
16569    '\u01B6': 'z',
16570    '\u0225': 'z',
16571    '\u0240': 'z',
16572    '\u2C6C': 'z',
16573    '\uA763': 'z',
16574    '\u0386': '\u0391',
16575    '\u0388': '\u0395',
16576    '\u0389': '\u0397',
16577    '\u038A': '\u0399',
16578    '\u03AA': '\u0399',
16579    '\u038C': '\u039F',
16580    '\u038E': '\u03A5',
16581    '\u03AB': '\u03A5',
16582    '\u038F': '\u03A9',
16583    '\u03AC': '\u03B1',
16584    '\u03AD': '\u03B5',
16585    '\u03AE': '\u03B7',
16586    '\u03AF': '\u03B9',
16587    '\u03CA': '\u03B9',
16588    '\u0390': '\u03B9',
16589    '\u03CC': '\u03BF',
16590    '\u03CD': '\u03C5',
16591    '\u03CB': '\u03C5',
16592    '\u03B0': '\u03C5',
16593    '\u03CE': '\u03C9',
16594    '\u03C2': '\u03C3',
16595    '\u2019': '\''
16596  };
16597
16598  return diacritics;
16599});
16600
16601S2.define('select2/data/base',[
16602  '../utils'
16603], function (Utils) {
16604  function BaseAdapter ($element, options) {
16605    BaseAdapter.__super__.constructor.call(this);
16606  }
16607
16608  Utils.Extend(BaseAdapter, Utils.Observable);
16609
16610  BaseAdapter.prototype.current = function (callback) {
16611    throw new Error('The `current` method must be defined in child classes.');
16612  };
16613
16614  BaseAdapter.prototype.query = function (params, callback) {
16615    throw new Error('The `query` method must be defined in child classes.');
16616  };
16617
16618  BaseAdapter.prototype.bind = function (container, $container) {
16619    // Can be implemented in subclasses
16620  };
16621
16622  BaseAdapter.prototype.destroy = function () {
16623    // Can be implemented in subclasses
16624  };
16625
16626  BaseAdapter.prototype.generateResultId = function (container, data) {
16627    var id = container.id + '-result-';
16628
16629    id += Utils.generateChars(4);
16630
16631    if (data.id != null) {
16632      id += '-' + data.id.toString();
16633    } else {
16634      id += '-' + Utils.generateChars(4);
16635    }
16636    return id;
16637  };
16638
16639  return BaseAdapter;
16640});
16641
16642S2.define('select2/data/select',[
16643  './base',
16644  '../utils',
16645  'jquery'
16646], function (BaseAdapter, Utils, $) {
16647  function SelectAdapter ($element, options) {
16648    this.$element = $element;
16649    this.options = options;
16650
16651    SelectAdapter.__super__.constructor.call(this);
16652  }
16653
16654  Utils.Extend(SelectAdapter, BaseAdapter);
16655
16656  SelectAdapter.prototype.current = function (callback) {
16657    var data = [];
16658    var self = this;
16659
16660    this.$element.find(':selected').each(function () {
16661      var $option = $(this);
16662
16663      var option = self.item($option);
16664
16665      data.push(option);
16666    });
16667
16668    callback(data);
16669  };
16670
16671  SelectAdapter.prototype.select = function (data) {
16672    var self = this;
16673
16674    data.selected = true;
16675
16676    // If data.element is a DOM node, use it instead
16677    if ($(data.element).is('option')) {
16678      data.element.selected = true;
16679
16680      this.$element.trigger('input').trigger('change');
16681
16682      return;
16683    }
16684
16685    if (this.$element.prop('multiple')) {
16686      this.current(function (currentData) {
16687        var val = [];
16688
16689        data = [data];
16690        data.push.apply(data, currentData);
16691
16692        for (var d = 0; d < data.length; d++) {
16693          var id = data[d].id;
16694
16695          if ($.inArray(id, val) === -1) {
16696            val.push(id);
16697          }
16698        }
16699
16700        self.$element.val(val);
16701        self.$element.trigger('input').trigger('change');
16702      });
16703    } else {
16704      var val = data.id;
16705
16706      this.$element.val(val);
16707      this.$element.trigger('input').trigger('change');
16708    }
16709  };
16710
16711  SelectAdapter.prototype.unselect = function (data) {
16712    var self = this;
16713
16714    if (!this.$element.prop('multiple')) {
16715      return;
16716    }
16717
16718    data.selected = false;
16719
16720    if ($(data.element).is('option')) {
16721      data.element.selected = false;
16722
16723      this.$element.trigger('input').trigger('change');
16724
16725      return;
16726    }
16727
16728    this.current(function (currentData) {
16729      var val = [];
16730
16731      for (var d = 0; d < currentData.length; d++) {
16732        var id = currentData[d].id;
16733
16734        if (id !== data.id && $.inArray(id, val) === -1) {
16735          val.push(id);
16736        }
16737      }
16738
16739      self.$element.val(val);
16740
16741      self.$element.trigger('input').trigger('change');
16742    });
16743  };
16744
16745  SelectAdapter.prototype.bind = function (container, $container) {
16746    var self = this;
16747
16748    this.container = container;
16749
16750    container.on('select', function (params) {
16751      self.select(params.data);
16752    });
16753
16754    container.on('unselect', function (params) {
16755      self.unselect(params.data);
16756    });
16757  };
16758
16759  SelectAdapter.prototype.destroy = function () {
16760    // Remove anything added to child elements
16761    this.$element.find('*').each(function () {
16762      // Remove any custom data set by Select2
16763      Utils.RemoveData(this);
16764    });
16765  };
16766
16767  SelectAdapter.prototype.query = function (params, callback) {
16768    var data = [];
16769    var self = this;
16770
16771    var $options = this.$element.children();
16772
16773    $options.each(function () {
16774      var $option = $(this);
16775
16776      if (!$option.is('option') && !$option.is('optgroup')) {
16777        return;
16778      }
16779
16780      var option = self.item($option);
16781
16782      var matches = self.matches(params, option);
16783
16784      if (matches !== null) {
16785        data.push(matches);
16786      }
16787    });
16788
16789    callback({
16790      results: data
16791    });
16792  };
16793
16794  SelectAdapter.prototype.addOptions = function ($options) {
16795    Utils.appendMany(this.$element, $options);
16796  };
16797
16798  SelectAdapter.prototype.option = function (data) {
16799    var option;
16800
16801    if (data.children) {
16802      option = document.createElement('optgroup');
16803      option.label = data.text;
16804    } else {
16805      option = document.createElement('option');
16806
16807      if (option.textContent !== undefined) {
16808        option.textContent = data.text;
16809      } else {
16810        option.innerText = data.text;
16811      }
16812    }
16813
16814    if (data.id !== undefined) {
16815      option.value = data.id;
16816    }
16817
16818    if (data.disabled) {
16819      option.disabled = true;
16820    }
16821
16822    if (data.selected) {
16823      option.selected = true;
16824    }
16825
16826    if (data.title) {
16827      option.title = data.title;
16828    }
16829
16830    var $option = $(option);
16831
16832    var normalizedData = this._normalizeItem(data);
16833    normalizedData.element = option;
16834
16835    // Override the option's data with the combined data
16836    Utils.StoreData(option, 'data', normalizedData);
16837
16838    return $option;
16839  };
16840
16841  SelectAdapter.prototype.item = function ($option) {
16842    var data = {};
16843
16844    data = Utils.GetData($option[0], 'data');
16845
16846    if (data != null) {
16847      return data;
16848    }
16849
16850    if ($option.is('option')) {
16851      data = {
16852        id: $option.val(),
16853        text: $option.text(),
16854        disabled: $option.prop('disabled'),
16855        selected: $option.prop('selected'),
16856        title: $option.prop('title')
16857      };
16858    } else if ($option.is('optgroup')) {
16859      data = {
16860        text: $option.prop('label'),
16861        children: [],
16862        title: $option.prop('title')
16863      };
16864
16865      var $children = $option.children('option');
16866      var children = [];
16867
16868      for (var c = 0; c < $children.length; c++) {
16869        var $child = $($children[c]);
16870
16871        var child = this.item($child);
16872
16873        children.push(child);
16874      }
16875
16876      data.children = children;
16877    }
16878
16879    data = this._normalizeItem(data);
16880    data.element = $option[0];
16881
16882    Utils.StoreData($option[0], 'data', data);
16883
16884    return data;
16885  };
16886
16887  SelectAdapter.prototype._normalizeItem = function (item) {
16888    if (item !== Object(item)) {
16889      item = {
16890        id: item,
16891        text: item
16892      };
16893    }
16894
16895    item = $.extend({}, {
16896      text: ''
16897    }, item);
16898
16899    var defaults = {
16900      selected: false,
16901      disabled: false
16902    };
16903
16904    if (item.id != null) {
16905      item.id = item.id.toString();
16906    }
16907
16908    if (item.text != null) {
16909      item.text = item.text.toString();
16910    }
16911
16912    if (item._resultId == null && item.id && this.container != null) {
16913      item._resultId = this.generateResultId(this.container, item);
16914    }
16915
16916    return $.extend({}, defaults, item);
16917  };
16918
16919  SelectAdapter.prototype.matches = function (params, data) {
16920    var matcher = this.options.get('matcher');
16921
16922    return matcher(params, data);
16923  };
16924
16925  return SelectAdapter;
16926});
16927
16928S2.define('select2/data/array',[
16929  './select',
16930  '../utils',
16931  'jquery'
16932], function (SelectAdapter, Utils, $) {
16933  function ArrayAdapter ($element, options) {
16934    this._dataToConvert = options.get('data') || [];
16935
16936    ArrayAdapter.__super__.constructor.call(this, $element, options);
16937  }
16938
16939  Utils.Extend(ArrayAdapter, SelectAdapter);
16940
16941  ArrayAdapter.prototype.bind = function (container, $container) {
16942    ArrayAdapter.__super__.bind.call(this, container, $container);
16943
16944    this.addOptions(this.convertToOptions(this._dataToConvert));
16945  };
16946
16947  ArrayAdapter.prototype.select = function (data) {
16948    var $option = this.$element.find('option').filter(function (i, elm) {
16949      return elm.value == data.id.toString();
16950    });
16951
16952    if ($option.length === 0) {
16953      $option = this.option(data);
16954
16955      this.addOptions($option);
16956    }
16957
16958    ArrayAdapter.__super__.select.call(this, data);
16959  };
16960
16961  ArrayAdapter.prototype.convertToOptions = function (data) {
16962    var self = this;
16963
16964    var $existing = this.$element.find('option');
16965    var existingIds = $existing.map(function () {
16966      return self.item($(this)).id;
16967    }).get();
16968
16969    var $options = [];
16970
16971    // Filter out all items except for the one passed in the argument
16972    function onlyItem (item) {
16973      return function () {
16974        return $(this).val() == item.id;
16975      };
16976    }
16977
16978    for (var d = 0; d < data.length; d++) {
16979      var item = this._normalizeItem(data[d]);
16980
16981      // Skip items which were pre-loaded, only merge the data
16982      if ($.inArray(item.id, existingIds) >= 0) {
16983        var $existingOption = $existing.filter(onlyItem(item));
16984
16985        var existingData = this.item($existingOption);
16986        var newData = $.extend(true, {}, item, existingData);
16987
16988        var $newOption = this.option(newData);
16989
16990        $existingOption.replaceWith($newOption);
16991
16992        continue;
16993      }
16994
16995      var $option = this.option(item);
16996
16997      if (item.children) {
16998        var $children = this.convertToOptions(item.children);
16999
17000        Utils.appendMany($option, $children);
17001      }
17002
17003      $options.push($option);
17004    }
17005
17006    return $options;
17007  };
17008
17009  return ArrayAdapter;
17010});
17011
17012S2.define('select2/data/ajax',[
17013  './array',
17014  '../utils',
17015  'jquery'
17016], function (ArrayAdapter, Utils, $) {
17017  function AjaxAdapter ($element, options) {
17018    this.ajaxOptions = this._applyDefaults(options.get('ajax'));
17019
17020    if (this.ajaxOptions.processResults != null) {
17021      this.processResults = this.ajaxOptions.processResults;
17022    }
17023
17024    AjaxAdapter.__super__.constructor.call(this, $element, options);
17025  }
17026
17027  Utils.Extend(AjaxAdapter, ArrayAdapter);
17028
17029  AjaxAdapter.prototype._applyDefaults = function (options) {
17030    var defaults = {
17031      data: function (params) {
17032        return $.extend({}, params, {
17033          q: params.term
17034        });
17035      },
17036      transport: function (params, success, failure) {
17037        var $request = $.ajax(params);
17038
17039        $request.then(success);
17040        $request.fail(failure);
17041
17042        return $request;
17043      }
17044    };
17045
17046    return $.extend({}, defaults, options, true);
17047  };
17048
17049  AjaxAdapter.prototype.processResults = function (results) {
17050    return results;
17051  };
17052
17053  AjaxAdapter.prototype.query = function (params, callback) {
17054    var matches = [];
17055    var self = this;
17056
17057    if (this._request != null) {
17058      // JSONP requests cannot always be aborted
17059      if ($.isFunction(this._request.abort)) {
17060        this._request.abort();
17061      }
17062
17063      this._request = null;
17064    }
17065
17066    var options = $.extend({
17067      type: 'GET'
17068    }, this.ajaxOptions);
17069
17070    if (typeof options.url === 'function') {
17071      options.url = options.url.call(this.$element, params);
17072    }
17073
17074    if (typeof options.data === 'function') {
17075      options.data = options.data.call(this.$element, params);
17076    }
17077
17078    function request () {
17079      var $request = options.transport(options, function (data) {
17080        var results = self.processResults(data, params);
17081
17082        if (self.options.get('debug') && window.console && console.error) {
17083          // Check to make sure that the response included a `results` key.
17084          if (!results || !results.results || !$.isArray(results.results)) {
17085            console.error(
17086              'Select2: The AJAX results did not return an array in the ' +
17087              '`results` key of the response.'
17088            );
17089          }
17090        }
17091
17092        callback(results);
17093      }, function () {
17094        // Attempt to detect if a request was aborted
17095        // Only works if the transport exposes a status property
17096        if ('status' in $request &&
17097            ($request.status === 0 || $request.status === '0')) {
17098          return;
17099        }
17100
17101        self.trigger('results:message', {
17102          message: 'errorLoading'
17103        });
17104      });
17105
17106      self._request = $request;
17107    }
17108
17109    if (this.ajaxOptions.delay && params.term != null) {
17110      if (this._queryTimeout) {
17111        window.clearTimeout(this._queryTimeout);
17112      }
17113
17114      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
17115    } else {
17116      request();
17117    }
17118  };
17119
17120  return AjaxAdapter;
17121});
17122
17123S2.define('select2/data/tags',[
17124  'jquery'
17125], function ($) {
17126  function Tags (decorated, $element, options) {
17127    var tags = options.get('tags');
17128
17129    var createTag = options.get('createTag');
17130
17131    if (createTag !== undefined) {
17132      this.createTag = createTag;
17133    }
17134
17135    var insertTag = options.get('insertTag');
17136
17137    if (insertTag !== undefined) {
17138        this.insertTag = insertTag;
17139    }
17140
17141    decorated.call(this, $element, options);
17142
17143    if ($.isArray(tags)) {
17144      for (var t = 0; t < tags.length; t++) {
17145        var tag = tags[t];
17146        var item = this._normalizeItem(tag);
17147
17148        var $option = this.option(item);
17149
17150        this.$element.append($option);
17151      }
17152    }
17153  }
17154
17155  Tags.prototype.query = function (decorated, params, callback) {
17156    var self = this;
17157
17158    this._removeOldTags();
17159
17160    if (params.term == null || params.page != null) {
17161      decorated.call(this, params, callback);
17162      return;
17163    }
17164
17165    function wrapper (obj, child) {
17166      var data = obj.results;
17167
17168      for (var i = 0; i < data.length; i++) {
17169        var option = data[i];
17170
17171        var checkChildren = (
17172          option.children != null &&
17173          !wrapper({
17174            results: option.children
17175          }, true)
17176        );
17177
17178        var optionText = (option.text || '').toUpperCase();
17179        var paramsTerm = (params.term || '').toUpperCase();
17180
17181        var checkText = optionText === paramsTerm;
17182
17183        if (checkText || checkChildren) {
17184          if (child) {
17185            return false;
17186          }
17187
17188          obj.data = data;
17189          callback(obj);
17190
17191          return;
17192        }
17193      }
17194
17195      if (child) {
17196        return true;
17197      }
17198
17199      var tag = self.createTag(params);
17200
17201      if (tag != null) {
17202        var $option = self.option(tag);
17203        $option.attr('data-select2-tag', true);
17204
17205        self.addOptions([$option]);
17206
17207        self.insertTag(data, tag);
17208      }
17209
17210      obj.results = data;
17211
17212      callback(obj);
17213    }
17214
17215    decorated.call(this, params, wrapper);
17216  };
17217
17218  Tags.prototype.createTag = function (decorated, params) {
17219    var term = $.trim(params.term);
17220
17221    if (term === '') {
17222      return null;
17223    }
17224
17225    return {
17226      id: term,
17227      text: term
17228    };
17229  };
17230
17231  Tags.prototype.insertTag = function (_, data, tag) {
17232    data.unshift(tag);
17233  };
17234
17235  Tags.prototype._removeOldTags = function (_) {
17236    var $options = this.$element.find('option[data-select2-tag]');
17237
17238    $options.each(function () {
17239      if (this.selected) {
17240        return;
17241      }
17242
17243      $(this).remove();
17244    });
17245  };
17246
17247  return Tags;
17248});
17249
17250S2.define('select2/data/tokenizer',[
17251  'jquery'
17252], function ($) {
17253  function Tokenizer (decorated, $element, options) {
17254    var tokenizer = options.get('tokenizer');
17255
17256    if (tokenizer !== undefined) {
17257      this.tokenizer = tokenizer;
17258    }
17259
17260    decorated.call(this, $element, options);
17261  }
17262
17263  Tokenizer.prototype.bind = function (decorated, container, $container) {
17264    decorated.call(this, container, $container);
17265
17266    this.$search =  container.dropdown.$search || container.selection.$search ||
17267      $container.find('.select2-search__field');
17268  };
17269
17270  Tokenizer.prototype.query = function (decorated, params, callback) {
17271    var self = this;
17272
17273    function createAndSelect (data) {
17274      // Normalize the data object so we can use it for checks
17275      var item = self._normalizeItem(data);
17276
17277      // Check if the data object already exists as a tag
17278      // Select it if it doesn't
17279      var $existingOptions = self.$element.find('option').filter(function () {
17280        return $(this).val() === item.id;
17281      });
17282
17283      // If an existing option wasn't found for it, create the option
17284      if (!$existingOptions.length) {
17285        var $option = self.option(item);
17286        $option.attr('data-select2-tag', true);
17287
17288        self._removeOldTags();
17289        self.addOptions([$option]);
17290      }
17291
17292      // Select the item, now that we know there is an option for it
17293      select(item);
17294    }
17295
17296    function select (data) {
17297      self.trigger('select', {
17298        data: data
17299      });
17300    }
17301
17302    params.term = params.term || '';
17303
17304    var tokenData = this.tokenizer(params, this.options, createAndSelect);
17305
17306    if (tokenData.term !== params.term) {
17307      // Replace the search term if we have the search box
17308      if (this.$search.length) {
17309        this.$search.val(tokenData.term);
17310        this.$search.trigger('focus');
17311      }
17312
17313      params.term = tokenData.term;
17314    }
17315
17316    decorated.call(this, params, callback);
17317  };
17318
17319  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
17320    var separators = options.get('tokenSeparators') || [];
17321    var term = params.term;
17322    var i = 0;
17323
17324    var createTag = this.createTag || function (params) {
17325      return {
17326        id: params.term,
17327        text: params.term
17328      };
17329    };
17330
17331    while (i < term.length) {
17332      var termChar = term[i];
17333
17334      if ($.inArray(termChar, separators) === -1) {
17335        i++;
17336
17337        continue;
17338      }
17339
17340      var part = term.substr(0, i);
17341      var partParams = $.extend({}, params, {
17342        term: part
17343      });
17344
17345      var data = createTag(partParams);
17346
17347      if (data == null) {
17348        i++;
17349        continue;
17350      }
17351
17352      callback(data);
17353
17354      // Reset the term to not include the tokenized portion
17355      term = term.substr(i + 1) || '';
17356      i = 0;
17357    }
17358
17359    return {
17360      term: term
17361    };
17362  };
17363
17364  return Tokenizer;
17365});
17366
17367S2.define('select2/data/minimumInputLength',[
17368
17369], function () {
17370  function MinimumInputLength (decorated, $e, options) {
17371    this.minimumInputLength = options.get('minimumInputLength');
17372
17373    decorated.call(this, $e, options);
17374  }
17375
17376  MinimumInputLength.prototype.query = function (decorated, params, callback) {
17377    params.term = params.term || '';
17378
17379    if (params.term.length < this.minimumInputLength) {
17380      this.trigger('results:message', {
17381        message: 'inputTooShort',
17382        args: {
17383          minimum: this.minimumInputLength,
17384          input: params.term,
17385          params: params
17386        }
17387      });
17388
17389      return;
17390    }
17391
17392    decorated.call(this, params, callback);
17393  };
17394
17395  return MinimumInputLength;
17396});
17397
17398S2.define('select2/data/maximumInputLength',[
17399
17400], function () {
17401  function MaximumInputLength (decorated, $e, options) {
17402    this.maximumInputLength = options.get('maximumInputLength');
17403
17404    decorated.call(this, $e, options);
17405  }
17406
17407  MaximumInputLength.prototype.query = function (decorated, params, callback) {
17408    params.term = params.term || '';
17409
17410    if (this.maximumInputLength > 0 &&
17411        params.term.length > this.maximumInputLength) {
17412      this.trigger('results:message', {
17413        message: 'inputTooLong',
17414        args: {
17415          maximum: this.maximumInputLength,
17416          input: params.term,
17417          params: params
17418        }
17419      });
17420
17421      return;
17422    }
17423
17424    decorated.call(this, params, callback);
17425  };
17426
17427  return MaximumInputLength;
17428});
17429
17430S2.define('select2/data/maximumSelectionLength',[
17431
17432], function (){
17433  function MaximumSelectionLength (decorated, $e, options) {
17434    this.maximumSelectionLength = options.get('maximumSelectionLength');
17435
17436    decorated.call(this, $e, options);
17437  }
17438
17439  MaximumSelectionLength.prototype.bind =
17440    function (decorated, container, $container) {
17441      var self = this;
17442
17443      decorated.call(this, container, $container);
17444
17445      container.on('select', function () {
17446        self._checkIfMaximumSelected();
17447      });
17448  };
17449
17450  MaximumSelectionLength.prototype.query =
17451    function (decorated, params, callback) {
17452      var self = this;
17453
17454      this._checkIfMaximumSelected(function () {
17455        decorated.call(self, params, callback);
17456      });
17457  };
17458
17459  MaximumSelectionLength.prototype._checkIfMaximumSelected =
17460    function (_, successCallback) {
17461      var self = this;
17462
17463      this.current(function (currentData) {
17464        var count = currentData != null ? currentData.length : 0;
17465        if (self.maximumSelectionLength > 0 &&
17466          count >= self.maximumSelectionLength) {
17467          self.trigger('results:message', {
17468            message: 'maximumSelected',
17469            args: {
17470              maximum: self.maximumSelectionLength
17471            }
17472          });
17473          return;
17474        }
17475
17476        if (successCallback) {
17477          successCallback();
17478        }
17479      });
17480  };
17481
17482  return MaximumSelectionLength;
17483});
17484
17485S2.define('select2/dropdown',[
17486  'jquery',
17487  './utils'
17488], function ($, Utils) {
17489  function Dropdown ($element, options) {
17490    this.$element = $element;
17491    this.options = options;
17492
17493    Dropdown.__super__.constructor.call(this);
17494  }
17495
17496  Utils.Extend(Dropdown, Utils.Observable);
17497
17498  Dropdown.prototype.render = function () {
17499    var $dropdown = $(
17500      '<span class="select2-dropdown">' +
17501        '<span class="select2-results"></span>' +
17502      '</span>'
17503    );
17504
17505    $dropdown.attr('dir', this.options.get('dir'));
17506
17507    this.$dropdown = $dropdown;
17508
17509    return $dropdown;
17510  };
17511
17512  Dropdown.prototype.bind = function () {
17513    // Should be implemented in subclasses
17514  };
17515
17516  Dropdown.prototype.position = function ($dropdown, $container) {
17517    // Should be implemented in subclasses
17518  };
17519
17520  Dropdown.prototype.destroy = function () {
17521    // Remove the dropdown from the DOM
17522    this.$dropdown.remove();
17523  };
17524
17525  return Dropdown;
17526});
17527
17528S2.define('select2/dropdown/search',[
17529  'jquery',
17530  '../utils'
17531], function ($, Utils) {
17532  function Search () { }
17533
17534  Search.prototype.render = function (decorated) {
17535    var $rendered = decorated.call(this);
17536
17537    var $search = $(
17538      '<span class="select2-search select2-search--dropdown">' +
17539        '<input class="select2-search__field" type="search" tabindex="-1"' +
17540        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
17541        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
17542      '</span>'
17543    );
17544
17545    this.$searchContainer = $search;
17546    this.$search = $search.find('input');
17547
17548    $rendered.prepend($search);
17549
17550    return $rendered;
17551  };
17552
17553  Search.prototype.bind = function (decorated, container, $container) {
17554    var self = this;
17555
17556    var resultsId = container.id + '-results';
17557
17558    decorated.call(this, container, $container);
17559
17560    this.$search.on('keydown', function (evt) {
17561      self.trigger('keypress', evt);
17562
17563      self._keyUpPrevented = evt.isDefaultPrevented();
17564    });
17565
17566    // Workaround for browsers which do not support the `input` event
17567    // This will prevent double-triggering of events for browsers which support
17568    // both the `keyup` and `input` events.
17569    this.$search.on('input', function (evt) {
17570      // Unbind the duplicated `keyup` event
17571      $(this).off('keyup');
17572    });
17573
17574    this.$search.on('keyup input', function (evt) {
17575      self.handleSearch(evt);
17576    });
17577
17578    container.on('open', function () {
17579      self.$search.attr('tabindex', 0);
17580      self.$search.attr('aria-controls', resultsId);
17581
17582      self.$search.trigger('focus');
17583
17584      window.setTimeout(function () {
17585        self.$search.trigger('focus');
17586      }, 0);
17587    });
17588
17589    container.on('close', function () {
17590      self.$search.attr('tabindex', -1);
17591      self.$search.removeAttr('aria-controls');
17592      self.$search.removeAttr('aria-activedescendant');
17593
17594      self.$search.val('');
17595      self.$search.trigger('blur');
17596    });
17597
17598    container.on('focus', function () {
17599      if (!container.isOpen()) {
17600        self.$search.trigger('focus');
17601      }
17602    });
17603
17604    container.on('results:all', function (params) {
17605      if (params.query.term == null || params.query.term === '') {
17606        var showSearch = self.showSearch(params);
17607
17608        if (showSearch) {
17609          self.$searchContainer.removeClass('select2-search--hide');
17610        } else {
17611          self.$searchContainer.addClass('select2-search--hide');
17612        }
17613      }
17614    });
17615
17616    container.on('results:focus', function (params) {
17617      if (params.data._resultId) {
17618        self.$search.attr('aria-activedescendant', params.data._resultId);
17619      } else {
17620        self.$search.removeAttr('aria-activedescendant');
17621      }
17622    });
17623  };
17624
17625  Search.prototype.handleSearch = function (evt) {
17626    if (!this._keyUpPrevented) {
17627      var input = this.$search.val();
17628
17629      this.trigger('query', {
17630        term: input
17631      });
17632    }
17633
17634    this._keyUpPrevented = false;
vendor: 18,179 bytes, lines 17635-18360
17635  };
17636
17637  Search.prototype.showSearch = function (_, params) {
17638    return true;
17639  };
17640
17641  return Search;
17642});
17643
17644S2.define('select2/dropdown/hidePlaceholder',[
17645
17646], function () {
17647  function HidePlaceholder (decorated, $element, options, dataAdapter) {
17648    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
17649
17650    decorated.call(this, $element, options, dataAdapter);
17651  }
17652
17653  HidePlaceholder.prototype.append = function (decorated, data) {
17654    data.results = this.removePlaceholder(data.results);
17655
17656    decorated.call(this, data);
17657  };
17658
17659  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
17660    if (typeof placeholder === 'string') {
17661      placeholder = {
17662        id: '',
17663        text: placeholder
17664      };
17665    }
17666
17667    return placeholder;
17668  };
17669
17670  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
17671    var modifiedData = data.slice(0);
17672
17673    for (var d = data.length - 1; d >= 0; d--) {
17674      var item = data[d];
17675
17676      if (this.placeholder.id === item.id) {
17677        modifiedData.splice(d, 1);
17678      }
17679    }
17680
17681    return modifiedData;
17682  };
17683
17684  return HidePlaceholder;
17685});
17686
17687S2.define('select2/dropdown/infiniteScroll',[
17688  'jquery'
17689], function ($) {
17690  function InfiniteScroll (decorated, $element, options, dataAdapter) {
17691    this.lastParams = {};
17692
17693    decorated.call(this, $element, options, dataAdapter);
17694
17695    this.$loadingMore = this.createLoadingMore();
17696    this.loading = false;
17697  }
17698
17699  InfiniteScroll.prototype.append = function (decorated, data) {
17700    this.$loadingMore.remove();
17701    this.loading = false;
17702
17703    decorated.call(this, data);
17704
17705    if (this.showLoadingMore(data)) {
17706      this.$results.append(this.$loadingMore);
17707      this.loadMoreIfNeeded();
17708    }
17709  };
17710
17711  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
17712    var self = this;
17713
17714    decorated.call(this, container, $container);
17715
17716    container.on('query', function (params) {
17717      self.lastParams = params;
17718      self.loading = true;
17719    });
17720
17721    container.on('query:append', function (params) {
17722      self.lastParams = params;
17723      self.loading = true;
17724    });
17725
17726    this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
17727  };
17728
17729  InfiniteScroll.prototype.loadMoreIfNeeded = function () {
17730    var isLoadMoreVisible = $.contains(
17731      document.documentElement,
17732      this.$loadingMore[0]
17733    );
17734
17735    if (this.loading || !isLoadMoreVisible) {
17736      return;
17737    }
17738
17739    var currentOffset = this.$results.offset().top +
17740      this.$results.outerHeight(false);
17741    var loadingMoreOffset = this.$loadingMore.offset().top +
17742      this.$loadingMore.outerHeight(false);
17743
17744    if (currentOffset + 50 >= loadingMoreOffset) {
17745      this.loadMore();
17746    }
17747  };
17748
17749  InfiniteScroll.prototype.loadMore = function () {
17750    this.loading = true;
17751
17752    var params = $.extend({}, {page: 1}, this.lastParams);
17753
17754    params.page++;
17755
17756    this.trigger('query:append', params);
17757  };
17758
17759  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
17760    return data.pagination && data.pagination.more;
17761  };
17762
17763  InfiniteScroll.prototype.createLoadingMore = function () {
17764    var $option = $(
17765      '<li ' +
17766      'class="select2-results__option select2-results__option--load-more"' +
17767      'role="option" aria-disabled="true"></li>'
17768    );
17769
17770    var message = this.options.get('translations').get('loadingMore');
17771
17772    $option.html(message(this.lastParams));
17773
17774    return $option;
17775  };
17776
17777  return InfiniteScroll;
17778});
17779
17780S2.define('select2/dropdown/attachBody',[
17781  'jquery',
17782  '../utils'
17783], function ($, Utils) {
17784  function AttachBody (decorated, $element, options) {
17785    this.$dropdownParent = $(options.get('dropdownParent') || document.body);
17786
17787    decorated.call(this, $element, options);
17788  }
17789
17790  AttachBody.prototype.bind = function (decorated, container, $container) {
17791    var self = this;
17792
17793    decorated.call(this, container, $container);
17794
17795    container.on('open', function () {
17796      self._showDropdown();
17797      self._attachPositioningHandler(container);
17798
17799      // Must bind after the results handlers to ensure correct sizing
17800      self._bindContainerResultHandlers(container);
17801    });
17802
17803    container.on('close', function () {
17804      self._hideDropdown();
17805      self._detachPositioningHandler(container);
17806    });
17807
17808    this.$dropdownContainer.on('mousedown', function (evt) {
17809      evt.stopPropagation();
17810    });
17811  };
17812
17813  AttachBody.prototype.destroy = function (decorated) {
17814    decorated.call(this);
17815
17816    this.$dropdownContainer.remove();
17817  };
17818
17819  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
17820    // Clone all of the container classes
17821    $dropdown.attr('class', $container.attr('class'));
17822
17823    $dropdown.removeClass('select2');
17824    $dropdown.addClass('select2-container--open');
17825
17826    $dropdown.css({
17827      position: 'absolute',
17828      top: -999999
17829    });
17830
17831    this.$container = $container;
17832  };
17833
17834  AttachBody.prototype.render = function (decorated) {
17835    var $container = $('<span></span>');
17836
17837    var $dropdown = decorated.call(this);
17838    $container.append($dropdown);
17839
17840    this.$dropdownContainer = $container;
17841
17842    return $container;
17843  };
17844
17845  AttachBody.prototype._hideDropdown = function (decorated) {
17846    this.$dropdownContainer.detach();
17847  };
17848
17849  AttachBody.prototype._bindContainerResultHandlers =
17850      function (decorated, container) {
17851
17852    // These should only be bound once
17853    if (this._containerResultsHandlersBound) {
17854      return;
17855    }
17856
17857    var self = this;
17858
17859    container.on('results:all', function () {
17860      self._positionDropdown();
17861      self._resizeDropdown();
17862    });
17863
17864    container.on('results:append', function () {
17865      self._positionDropdown();
17866      self._resizeDropdown();
17867    });
17868
17869    container.on('results:message', function () {
17870      self._positionDropdown();
17871      self._resizeDropdown();
17872    });
17873
17874    container.on('select', function () {
17875      self._positionDropdown();
17876      self._resizeDropdown();
17877    });
17878
17879    container.on('unselect', function () {
17880      self._positionDropdown();
17881      self._resizeDropdown();
17882    });
17883
17884    this._containerResultsHandlersBound = true;
17885  };
17886
17887  AttachBody.prototype._attachPositioningHandler =
17888      function (decorated, container) {
17889    var self = this;
17890
17891    var scrollEvent = 'scroll.select2.' + container.id;
17892    var resizeEvent = 'resize.select2.' + container.id;
17893    var orientationEvent = 'orientationchange.select2.' + container.id;
17894
17895    var $watchers = this.$container.parents().filter(Utils.hasScroll);
17896    $watchers.each(function () {
17897      Utils.StoreData(this, 'select2-scroll-position', {
17898        x: $(this).scrollLeft(),
17899        y: $(this).scrollTop()
17900      });
17901    });
17902
17903    $watchers.on(scrollEvent, function (ev) {
17904      var position = Utils.GetData(this, 'select2-scroll-position');
17905      $(this).scrollTop(position.y);
17906    });
17907
17908    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
17909      function (e) {
17910      self._positionDropdown();
17911      self._resizeDropdown();
17912    });
17913  };
17914
17915  AttachBody.prototype._detachPositioningHandler =
17916      function (decorated, container) {
17917    var scrollEvent = 'scroll.select2.' + container.id;
17918    var resizeEvent = 'resize.select2.' + container.id;
17919    var orientationEvent = 'orientationchange.select2.' + container.id;
17920
17921    var $watchers = this.$container.parents().filter(Utils.hasScroll);
17922    $watchers.off(scrollEvent);
17923
17924    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
17925  };
17926
17927  AttachBody.prototype._positionDropdown = function () {
17928    var $window = $(window);
17929
17930    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
17931    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
17932
17933    var newDirection = null;
17934
17935    var offset = this.$container.offset();
17936
17937    offset.bottom = offset.top + this.$container.outerHeight(false);
17938
17939    var container = {
17940      height: this.$container.outerHeight(false)
17941    };
17942
17943    container.top = offset.top;
17944    container.bottom = offset.top + container.height;
17945
17946    var dropdown = {
17947      height: this.$dropdown.outerHeight(false)
17948    };
17949
17950    var viewport = {
17951      top: $window.scrollTop(),
17952      bottom: $window.scrollTop() + $window.height()
17953    };
17954
17955    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
17956    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
17957
17958    var css = {
17959      left: offset.left,
17960      top: container.bottom
17961    };
17962
17963    // Determine what the parent element is to use for calculating the offset
17964    var $offsetParent = this.$dropdownParent;
17965
17966    // For statically positioned elements, we need to get the element
17967    // that is determining the offset
17968    if ($offsetParent.css('position') === 'static') {
17969      $offsetParent = $offsetParent.offsetParent();
17970    }
17971
17972    var parentOffset = {
17973      top: 0,
17974      left: 0
17975    };
17976
17977    if (
17978      $.contains(document.body, $offsetParent[0]) ||
17979      $offsetParent[0].isConnected
17980      ) {
17981      parentOffset = $offsetParent.offset();
17982    }
17983
17984    css.top -= parentOffset.top;
17985    css.left -= parentOffset.left;
17986
17987    if (!isCurrentlyAbove && !isCurrentlyBelow) {
17988      newDirection = 'below';
17989    }
17990
17991    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
17992      newDirection = 'above';
17993    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
17994      newDirection = 'below';
17995    }
17996
17997    if (newDirection == 'above' ||
17998      (isCurrentlyAbove && newDirection !== 'below')) {
17999      css.top = container.top - parentOffset.top - dropdown.height;
18000    }
18001
18002    if (newDirection != null) {
18003      this.$dropdown
18004        .removeClass('select2-dropdown--below select2-dropdown--above')
18005        .addClass('select2-dropdown--' + newDirection);
18006      this.$container
18007        .removeClass('select2-container--below select2-container--above')
18008        .addClass('select2-container--' + newDirection);
18009    }
18010
18011    this.$dropdownContainer.css(css);
18012  };
18013
18014  AttachBody.prototype._resizeDropdown = function () {
18015    var css = {
18016      width: this.$container.outerWidth(false) + 'px'
18017    };
18018
18019    if (this.options.get('dropdownAutoWidth')) {
18020      css.minWidth = css.width;
18021      css.position = 'relative';
18022      css.width = 'auto';
18023    }
18024
18025    this.$dropdown.css(css);
18026  };
18027
18028  AttachBody.prototype._showDropdown = function (decorated) {
18029    this.$dropdownContainer.appendTo(this.$dropdownParent);
18030
18031    this._positionDropdown();
18032    this._resizeDropdown();
18033  };
18034
18035  return AttachBody;
18036});
18037
18038S2.define('select2/dropdown/minimumResultsForSearch',[
18039
18040], function () {
18041  function countResults (data) {
18042    var count = 0;
18043
18044    for (var d = 0; d < data.length; d++) {
18045      var item = data[d];
18046
18047      if (item.children) {
18048        count += countResults(item.children);
18049      } else {
18050        count++;
18051      }
18052    }
18053
18054    return count;
18055  }
18056
18057  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
18058    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
18059
18060    if (this.minimumResultsForSearch < 0) {
18061      this.minimumResultsForSearch = Infinity;
18062    }
18063
18064    decorated.call(this, $element, options, dataAdapter);
18065  }
18066
18067  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
18068    if (countResults(params.data.results) < this.minimumResultsForSearch) {
18069      return false;
18070    }
18071
18072    return decorated.call(this, params);
18073  };
18074
18075  return MinimumResultsForSearch;
18076});
18077
18078S2.define('select2/dropdown/selectOnClose',[
18079  '../utils'
18080], function (Utils) {
18081  function SelectOnClose () { }
18082
18083  SelectOnClose.prototype.bind = function (decorated, container, $container) {
18084    var self = this;
18085
18086    decorated.call(this, container, $container);
18087
18088    container.on('close', function (params) {
18089      self._handleSelectOnClose(params);
18090    });
18091  };
18092
18093  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
18094    if (params && params.originalSelect2Event != null) {
18095      var event = params.originalSelect2Event;
18096
18097      // Don't select an item if the close event was triggered from a select or
18098      // unselect event
18099      if (event._type === 'select' || event._type === 'unselect') {
18100        return;
18101      }
18102    }
18103
18104    var $highlightedResults = this.getHighlightedResults();
18105
18106    // Only select highlighted results
18107    if ($highlightedResults.length < 1) {
18108      return;
18109    }
18110
18111    var data = Utils.GetData($highlightedResults[0], 'data');
18112
18113    // Don't re-select already selected resulte
18114    if (
18115      (data.element != null && data.element.selected) ||
18116      (data.element == null && data.selected)
18117    ) {
18118      return;
18119    }
18120
18121    this.trigger('select', {
18122        data: data
18123    });
18124  };
18125
18126  return SelectOnClose;
18127});
18128
18129S2.define('select2/dropdown/closeOnSelect',[
18130
18131], function () {
18132  function CloseOnSelect () { }
18133
18134  CloseOnSelect.prototype.bind = function (decorated, container, $container) {
18135    var self = this;
18136
18137    decorated.call(this, container, $container);
18138
18139    container.on('select', function (evt) {
18140      self._selectTriggered(evt);
18141    });
18142
18143    container.on('unselect', function (evt) {
18144      self._selectTriggered(evt);
18145    });
18146  };
18147
18148  CloseOnSelect.prototype._selectTriggered = function (_, evt) {
18149    var originalEvent = evt.originalEvent;
18150
18151    // Don't close if the control key is being held
18152    if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
18153      return;
18154    }
18155
18156    this.trigger('close', {
18157      originalEvent: originalEvent,
18158      originalSelect2Event: evt
18159    });
18160  };
18161
18162  return CloseOnSelect;
18163});
18164
18165S2.define('select2/i18n/en',[],function () {
18166  // English
18167  return {
18168    errorLoading: function () {
18169      return 'The results could not be loaded.';
18170    },
18171    inputTooLong: function (args) {
18172      var overChars = args.input.length - args.maximum;
18173
18174      var message = 'Please delete ' + overChars + ' character';
18175
18176      if (overChars != 1) {
18177        message += 's';
18178      }
18179
18180      return message;
18181    },
18182    inputTooShort: function (args) {
18183      var remainingChars = args.minimum - args.input.length;
18184
18185      var message = 'Please enter ' + remainingChars + ' or more characters';
18186
18187      return message;
18188    },
18189    loadingMore: function () {
18190      return 'Loading more results…';
18191    },
18192    maximumSelected: function (args) {
18193      var message = 'You can only select ' + args.maximum + ' item';
18194
18195      if (args.maximum != 1) {
18196        message += 's';
18197      }
18198
18199      return message;
18200    },
18201    noResults: function () {
18202      return 'No results found';
18203    },
18204    searching: function () {
18205      return 'Searching…';
18206    },
18207    removeAllItems: function () {
18208      return 'Remove all items';
18209    }
18210  };
18211});
18212
18213S2.define('select2/defaults',[
18214  'jquery',
18215  'require',
18216
18217  './results',
18218
18219  './selection/single',
18220  './selection/multiple',
18221  './selection/placeholder',
18222  './selection/allowClear',
18223  './selection/search',
18224  './selection/eventRelay',
18225
18226  './utils',
18227  './translation',
18228  './diacritics',
18229
18230  './data/select',
18231  './data/array',
18232  './data/ajax',
18233  './data/tags',
18234  './data/tokenizer',
18235  './data/minimumInputLength',
18236  './data/maximumInputLength',
18237  './data/maximumSelectionLength',
18238
18239  './dropdown',
18240  './dropdown/search',
18241  './dropdown/hidePlaceholder',
18242  './dropdown/infiniteScroll',
18243  './dropdown/attachBody',
18244  './dropdown/minimumResultsForSearch',
18245  './dropdown/selectOnClose',
18246  './dropdown/closeOnSelect',
18247
18248  './i18n/en'
18249], function ($, require,
18250
18251             ResultsList,
18252
18253             SingleSelection, MultipleSelection, Placeholder, AllowClear,
18254             SelectionSearch, EventRelay,
18255
18256             Utils, Translation, DIACRITICS,
18257
18258             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
18259             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
18260
18261             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
18262             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
18263
18264             EnglishTranslation) {
18265  function Defaults () {
18266    this.reset();
18267  }
18268
18269  Defaults.prototype.apply = function (options) {
18270    options = $.extend(true, {}, this.defaults, options);
18271
18272    if (options.dataAdapter == null) {
18273      if (options.ajax != null) {
18274        options.dataAdapter = AjaxData;
18275      } else if (options.data != null) {
18276        options.dataAdapter = ArrayData;
18277      } else {
18278        options.dataAdapter = SelectData;
18279      }
18280
18281      if (options.minimumInputLength > 0) {
18282        options.dataAdapter = Utils.Decorate(
18283          options.dataAdapter,
18284          MinimumInputLength
18285        );
18286      }
18287
18288      if (options.maximumInputLength > 0) {
18289        options.dataAdapter = Utils.Decorate(
18290          options.dataAdapter,
18291          MaximumInputLength
18292        );
18293      }
18294
18295      if (options.maximumSelectionLength > 0) {
18296        options.dataAdapter = Utils.Decorate(
18297          options.dataAdapter,
18298          MaximumSelectionLength
18299        );
18300      }
18301
18302      if (options.tags) {
18303        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
18304      }
18305
18306      if (options.tokenSeparators != null || options.tokenizer != null) {
18307        options.dataAdapter = Utils.Decorate(
18308          options.dataAdapter,
18309          Tokenizer
18310        );
18311      }
18312
18313      if (options.query != null) {
18314        var Query = require(options.amdBase + 'compat/query');
18315
18316        options.dataAdapter = Utils.Decorate(
18317          options.dataAdapter,
18318          Query
18319        );
18320      }
18321
18322      if (options.initSelection != null) {
18323        var InitSelection = require(options.amdBase + 'compat/initSelection');
18324
18325        options.dataAdapter = Utils.Decorate(
18326          options.dataAdapter,
18327          InitSelection
18328        );
18329      }
18330    }
18331
18332    if (options.resultsAdapter == null) {
18333      options.resultsAdapter = ResultsList;
18334
18335      if (options.ajax != null) {
18336        options.resultsAdapter = Utils.Decorate(
18337          options.resultsAdapter,
18338          InfiniteScroll
18339        );
18340      }
18341
18342      if (options.placeholder != null) {
18343        options.resultsAdapter = Utils.Decorate(
18344          options.resultsAdapter,
18345          HidePlaceholder
18346        );
18347      }
18348
18349      if (options.selectOnClose) {
18350        options.resultsAdapter = Utils.Decorate(
18351          options.resultsAdapter,
18352          SelectOnClose
18353        );
18354      }
18355    }
18356
18357    if (options.dropdownAdapter == null) {
18358      if (options.multiple) {
18359        options.dropdownAdapter = Dropdown;
18360      } else {
18361        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
18362
18363        options.dropdownAdapter = SearchableDropdown;
18364      }
18365
18366      if (options.minimumResultsForSearch !== 0) {
18367        options.dropdownAdapter = Utils.Decorate(
18368          options.dropdownAdapter,
18369          MinimumResultsForSearch
18370        );
18371      }
18372
18373      if (options.closeOnSelect) {
18374        options.dropdownAdapter = Utils.Decorate(
18375          options.dropdownAdapter,
18376          CloseOnSelect
18377        );
18378      }
18379
18380      if (
18381        options.dropdownCssClass != null ||
18382        options.dropdownCss != null ||
18383        options.adaptDropdownCssClass != null
18384      ) {
18385        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
18386
18387        options.dropdownAdapter = Utils.Decorate(
18388          options.dropdownAdapter,
18389          DropdownCSS
18390        );
18391      }
18392
18393      options.dropdownAdapter = Utils.Decorate(
18394        options.dropdownAdapter,
18395        AttachBody
18396      );
18397    }
18398
18399    if (options.selectionAdapter == null) {
18400      if (options.multiple) {
18401        options.selectionAdapter = MultipleSelection;
18402      } else {
18403        options.selectionAdapter = SingleSelection;
18404      }
18405
18406      // Add the placeholder mixin if a placeholder was specified
18407      if (options.placeholder != null) {
18408        options.selectionAdapter = Utils.Decorate(
18409          options.selectionAdapter,
18410          Placeholder
18411        );
18412      }
18413
18414      if (options.allowClear) {
18415        options.selectionAdapter = Utils.Decorate(
18416          options.selectionAdapter,
18417          AllowClear
18418        );
18419      }
18420
18421      if (options.multiple) {
18422        options.selectionAdapter = Utils.Decorate(
18423          options.selectionAdapter,
18424          SelectionSearch
18425        );
18426      }
18427
18428      if (
18429        options.containerCssClass != null ||
18430        options.containerCss != null ||
18431        options.adaptContainerCssClass != null
18432      ) {
18433        var ContainerCSS = require(options.amdBase + 'compat/containerCss');
18434
18435        options.selectionAdapter = Utils.Decorate(
18436          options.selectionAdapter,
18437          ContainerCSS
18438        );
18439      }
18440
18441      options.selectionAdapter = Utils.Decorate(
18442        options.selectionAdapter,
18443        EventRelay
18444      );
18445    }
18446
18447    // If the defaults were not previously applied from an element, it is
18448    // possible for the language option to have not been resolved
18449    options.language = this._resolveLanguage(options.language);
18450
18451    // Always fall back to English since it will always be complete
18452    options.language.push('en');
18453
18454    var uniqueLanguages = [];
18455
18456    for (var l = 0; l < options.language.length; l++) {
18457      var language = options.language[l];
18458
18459      if (uniqueLanguages.indexOf(language) === -1) {
18460        uniqueLanguages.push(language);
18461      }
18462    }
18463
18464    options.language = uniqueLanguages;
18465
18466    options.translations = this._processTranslations(
18467      options.language,
18468      options.debug
18469    );
18470
18471    return options;
18472  };
18473
18474  Defaults.prototype.reset = function () {
18475    function stripDiacritics (text) {
18476      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
18477      function match(a) {
18478        return DIACRITICS[a] || a;
18479      }
18480
vendor: 16,384 bytes, lines 18481-19083
18481      return text.replace(/[^\u0000-\u007E]/g, match);
18482    }
18483
18484    function matcher (params, data) {
18485      // Always return the object if there is nothing to compare
18486      if ($.trim(params.term) === '') {
18487        return data;
18488      }
18489
18490      // Do a recursive check for options with children
18491      if (data.children && data.children.length > 0) {
18492        // Clone the data object if there are children
18493        // This is required as we modify the object to remove any non-matches
18494        var match = $.extend(true, {}, data);
18495
18496        // Check each child of the option
18497        for (var c = data.children.length - 1; c >= 0; c--) {
18498          var child = data.children[c];
18499
18500          var matches = matcher(params, child);
18501
18502          // If there wasn't a match, remove the object in the array
18503          if (matches == null) {
18504            match.children.splice(c, 1);
18505          }
18506        }
18507
18508        // If any children matched, return the new object
18509        if (match.children.length > 0) {
18510          return match;
18511        }
18512
18513        // If there were no matching children, check just the plain object
18514        return matcher(params, match);
18515      }
18516
18517      var original = stripDiacritics(data.text).toUpperCase();
18518      var term = stripDiacritics(params.term).toUpperCase();
18519
18520      // Check if the text contains the term
18521      if (original.indexOf(term) > -1) {
18522        return data;
18523      }
18524
18525      // If it doesn't contain the term, don't return anything
18526      return null;
18527    }
18528
18529    this.defaults = {
18530      amdBase: './',
18531      amdLanguageBase: './i18n/',
18532      closeOnSelect: true,
18533      debug: false,
18534      dropdownAutoWidth: false,
18535      escapeMarkup: Utils.escapeMarkup,
18536      language: {},
18537      matcher: matcher,
18538      minimumInputLength: 0,
18539      maximumInputLength: 0,
18540      maximumSelectionLength: 0,
18541      minimumResultsForSearch: 0,
18542      selectOnClose: false,
18543      scrollAfterSelect: false,
18544      sorter: function (data) {
18545        return data;
18546      },
18547      templateResult: function (result) {
18548        return result.text;
18549      },
18550      templateSelection: function (selection) {
18551        return selection.text;
18552      },
18553      theme: 'default',
18554      width: 'resolve'
18555    };
18556  };
18557
18558  Defaults.prototype.applyFromElement = function (options, $element) {
18559    var optionLanguage = options.language;
18560    var defaultLanguage = this.defaults.language;
18561    var elementLanguage = $element.prop('lang');
18562    var parentLanguage = $element.closest('[lang]').prop('lang');
18563
18564    var languages = Array.prototype.concat.call(
18565      this._resolveLanguage(elementLanguage),
18566      this._resolveLanguage(optionLanguage),
18567      this._resolveLanguage(defaultLanguage),
18568      this._resolveLanguage(parentLanguage)
18569    );
18570
18571    options.language = languages;
18572
18573    return options;
18574  };
18575
18576  Defaults.prototype._resolveLanguage = function (language) {
18577    if (!language) {
18578      return [];
18579    }
18580
18581    if ($.isEmptyObject(language)) {
18582      return [];
18583    }
18584
18585    if ($.isPlainObject(language)) {
18586      return [language];
18587    }
18588
18589    var languages;
18590
18591    if (!$.isArray(language)) {
18592      languages = [language];
18593    } else {
18594      languages = language;
18595    }
18596
18597    var resolvedLanguages = [];
18598
18599    for (var l = 0; l < languages.length; l++) {
18600      resolvedLanguages.push(languages[l]);
18601
18602      if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
18603        // Extract the region information if it is included
18604        var languageParts = languages[l].split('-');
18605        var baseLanguage = languageParts[0];
18606
18607        resolvedLanguages.push(baseLanguage);
18608      }
18609    }
18610
18611    return resolvedLanguages;
18612  };
18613
18614  Defaults.prototype._processTranslations = function (languages, debug) {
18615    var translations = new Translation();
18616
18617    for (var l = 0; l < languages.length; l++) {
18618      var languageData = new Translation();
18619
18620      var language = languages[l];
18621
18622      if (typeof language === 'string') {
18623        try {
18624          // Try to load it with the original name
18625          languageData = Translation.loadPath(language);
18626        } catch (e) {
18627          try {
18628            // If we couldn't load it, check if it wasn't the full path
18629            language = this.defaults.amdLanguageBase + language;
18630            languageData = Translation.loadPath(language);
18631          } catch (ex) {
18632            // The translation could not be loaded at all. Sometimes this is
18633            // because of a configuration problem, other times this can be
18634            // because of how Select2 helps load all possible translation files
18635            if (debug && window.console && console.warn) {
18636              console.warn(
18637                'Select2: The language file for "' + language + '" could ' +
18638                'not be automatically loaded. A fallback will be used instead.'
18639              );
18640            }
18641          }
18642        }
18643      } else if ($.isPlainObject(language)) {
18644        languageData = new Translation(language);
18645      } else {
18646        languageData = language;
18647      }
18648
18649      translations.extend(languageData);
18650    }
18651
18652    return translations;
18653  };
18654
18655  Defaults.prototype.set = function (key, value) {
18656    var camelKey = $.camelCase(key);
18657
18658    var data = {};
18659    data[camelKey] = value;
18660
18661    var convertedData = Utils._convertData(data);
18662
18663    $.extend(true, this.defaults, convertedData);
18664  };
18665
18666  var defaults = new Defaults();
18667
18668  return defaults;
18669});
18670
18671S2.define('select2/options',[
18672  'require',
18673  'jquery',
18674  './defaults',
18675  './utils'
18676], function (require, $, Defaults, Utils) {
18677  function Options (options, $element) {
18678    this.options = options;
18679
18680    if ($element != null) {
18681      this.fromElement($element);
18682    }
18683
18684    if ($element != null) {
18685      this.options = Defaults.applyFromElement(this.options, $element);
18686    }
18687
18688    this.options = Defaults.apply(this.options);
18689
18690    if ($element && $element.is('input')) {
18691      var InputCompat = require(this.get('amdBase') + 'compat/inputData');
18692
18693      this.options.dataAdapter = Utils.Decorate(
18694        this.options.dataAdapter,
18695        InputCompat
18696      );
18697    }
18698  }
18699
18700  Options.prototype.fromElement = function ($e) {
18701    var excludedData = ['select2'];
18702
18703    if (this.options.multiple == null) {
18704      this.options.multiple = $e.prop('multiple');
18705    }
18706
18707    if (this.options.disabled == null) {
18708      this.options.disabled = $e.prop('disabled');
18709    }
18710
18711    if (this.options.dir == null) {
18712      if ($e.prop('dir')) {
18713        this.options.dir = $e.prop('dir');
18714      } else if ($e.closest('[dir]').prop('dir')) {
18715        this.options.dir = $e.closest('[dir]').prop('dir');
18716      } else {
18717        this.options.dir = 'ltr';
18718      }
18719    }
18720
18721    $e.prop('disabled', this.options.disabled);
18722    $e.prop('multiple', this.options.multiple);
18723
18724    if (Utils.GetData($e[0], 'select2Tags')) {
18725      if (this.options.debug && window.console && console.warn) {
18726        console.warn(
18727          'Select2: The `data-select2-tags` attribute has been changed to ' +
18728          'use the `data-data` and `data-tags="true"` attributes and will be ' +
18729          'removed in future versions of Select2.'
18730        );
18731      }
18732
18733      Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
18734      Utils.StoreData($e[0], 'tags', true);
18735    }
18736
18737    if (Utils.GetData($e[0], 'ajaxUrl')) {
18738      if (this.options.debug && window.console && console.warn) {
18739        console.warn(
18740          'Select2: The `data-ajax-url` attribute has been changed to ' +
18741          '`data-ajax--url` and support for the old attribute will be removed' +
18742          ' in future versions of Select2.'
18743        );
18744      }
18745
18746      $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
18747      Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
18748    }
18749
18750    var dataset = {};
18751
18752    function upperCaseLetter(_, letter) {
18753      return letter.toUpperCase();
18754    }
18755
18756    // Pre-load all of the attributes which are prefixed with `data-`
18757    for (var attr = 0; attr < $e[0].attributes.length; attr++) {
18758      var attributeName = $e[0].attributes[attr].name;
18759      var prefix = 'data-';
18760
18761      if (attributeName.substr(0, prefix.length) == prefix) {
18762        // Get the contents of the attribute after `data-`
18763        var dataName = attributeName.substring(prefix.length);
18764
18765        // Get the data contents from the consistent source
18766        // This is more than likely the jQuery data helper
18767        var dataValue = Utils.GetData($e[0], dataName);
18768
18769        // camelCase the attribute name to match the spec
18770        var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
18771
18772        // Store the data attribute contents into the dataset since
18773        dataset[camelDataName] = dataValue;
18774      }
18775    }
18776
18777    // Prefer the element's `dataset` attribute if it exists
18778    // jQuery 1.x does not correctly handle data attributes with multiple dashes
18779    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
18780      dataset = $.extend(true, {}, $e[0].dataset, dataset);
18781    }
18782
18783    // Prefer our internal data cache if it exists
18784    var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
18785
18786    data = Utils._convertData(data);
18787
18788    for (var key in data) {
18789      if ($.inArray(key, excludedData) > -1) {
18790        continue;
18791      }
18792
18793      if ($.isPlainObject(this.options[key])) {
18794        $.extend(this.options[key], data[key]);
18795      } else {
18796        this.options[key] = data[key];
18797      }
18798    }
18799
18800    return this;
18801  };
18802
18803  Options.prototype.get = function (key) {
18804    return this.options[key];
18805  };
18806
18807  Options.prototype.set = function (key, val) {
18808    this.options[key] = val;
18809  };
18810
18811  return Options;
18812});
18813
18814S2.define('select2/core',[
18815  'jquery',
18816  './options',
18817  './utils',
18818  './keys'
18819], function ($, Options, Utils, KEYS) {
18820  var Select2 = function ($element, options) {
18821    if (Utils.GetData($element[0], 'select2') != null) {
18822      Utils.GetData($element[0], 'select2').destroy();
18823    }
18824
18825    this.$element = $element;
18826
18827    this.id = this._generateId($element);
18828
18829    options = options || {};
18830
18831    this.options = new Options(options, $element);
18832
18833    Select2.__super__.constructor.call(this);
18834
18835    // Set up the tabindex
18836
18837    var tabindex = $element.attr('tabindex') || 0;
18838    Utils.StoreData($element[0], 'old-tabindex', tabindex);
18839    $element.attr('tabindex', '-1');
18840
18841    // Set up containers and adapters
18842
18843    var DataAdapter = this.options.get('dataAdapter');
18844    this.dataAdapter = new DataAdapter($element, this.options);
18845
18846    var $container = this.render();
18847
18848    this._placeContainer($container);
18849
18850    var SelectionAdapter = this.options.get('selectionAdapter');
18851    this.selection = new SelectionAdapter($element, this.options);
18852    this.$selection = this.selection.render();
18853
18854    this.selection.position(this.$selection, $container);
18855
18856    var DropdownAdapter = this.options.get('dropdownAdapter');
18857    this.dropdown = new DropdownAdapter($element, this.options);
18858    this.$dropdown = this.dropdown.render();
18859
18860    this.dropdown.position(this.$dropdown, $container);
18861
18862    var ResultsAdapter = this.options.get('resultsAdapter');
18863    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
18864    this.$results = this.results.render();
18865
18866    this.results.position(this.$results, this.$dropdown);
18867
18868    // Bind events
18869
18870    var self = this;
18871
18872    // Bind the container to all of the adapters
18873    this._bindAdapters();
18874
18875    // Register any DOM event handlers
18876    this._registerDomEvents();
18877
18878    // Register any internal event handlers
18879    this._registerDataEvents();
18880    this._registerSelectionEvents();
18881    this._registerDropdownEvents();
18882    this._registerResultsEvents();
18883    this._registerEvents();
18884
18885    // Set the initial state
18886    this.dataAdapter.current(function (initialData) {
18887      self.trigger('selection:update', {
18888        data: initialData
18889      });
18890    });
18891
18892    // Hide the original select
18893    $element.addClass('select2-hidden-accessible');
18894    $element.attr('aria-hidden', 'true');
18895
18896    // Synchronize any monitored attributes
18897    this._syncAttributes();
18898
18899    Utils.StoreData($element[0], 'select2', this);
18900
18901    // Ensure backwards compatibility with $element.data('select2').
18902    $element.data('select2', this);
18903  };
18904
18905  Utils.Extend(Select2, Utils.Observable);
18906
18907  Select2.prototype._generateId = function ($element) {
18908    var id = '';
18909
18910    if ($element.attr('id') != null) {
18911      id = $element.attr('id');
18912    } else if ($element.attr('name') != null) {
18913      id = $element.attr('name') + '-' + Utils.generateChars(2);
18914    } else {
18915      id = Utils.generateChars(4);
18916    }
18917
18918    id = id.replace(/(:|\.|\[|\]|,)/g, '');
18919    id = 'select2-' + id;
18920
18921    return id;
18922  };
18923
18924  Select2.prototype._placeContainer = function ($container) {
18925    $container.insertAfter(this.$element);
18926
18927    var width = this._resolveWidth(this.$element, this.options.get('width'));
18928
18929    if (width != null) {
18930      $container.css('width', width);
18931    }
18932  };
18933
18934  Select2.prototype._resolveWidth = function ($element, method) {
18935    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
18936
18937    if (method == 'resolve') {
18938      var styleWidth = this._resolveWidth($element, 'style');
18939
18940      if (styleWidth != null) {
18941        return styleWidth;
18942      }
18943
18944      return this._resolveWidth($element, 'element');
18945    }
18946
18947    if (method == 'element') {
18948      var elementWidth = $element.outerWidth(false);
18949
18950      if (elementWidth <= 0) {
18951        return 'auto';
18952      }
18953
18954      return elementWidth + 'px';
18955    }
18956
18957    if (method == 'style') {
18958      var style = $element.attr('style');
18959
18960      if (typeof(style) !== 'string') {
18961        return null;
18962      }
18963
18964      var attrs = style.split(';');
18965
18966      for (var i = 0, l = attrs.length; i < l; i = i + 1) {
18967        var attr = attrs[i].replace(/\s/g, '');
18968        var matches = attr.match(WIDTH);
18969
18970        if (matches !== null && matches.length >= 1) {
18971          return matches[1];
18972        }
18973      }
18974
18975      return null;
18976    }
18977
18978    if (method == 'computedstyle') {
18979      var computedStyle = window.getComputedStyle($element[0]);
18980
18981      return computedStyle.width;
18982    }
18983
18984    return method;
18985  };
18986
18987  Select2.prototype._bindAdapters = function () {
18988    this.dataAdapter.bind(this, this.$container);
18989    this.selection.bind(this, this.$container);
18990
18991    this.dropdown.bind(this, this.$container);
18992    this.results.bind(this, this.$container);
18993  };
18994
18995  Select2.prototype._registerDomEvents = function () {
18996    var self = this;
18997
18998    this.$element.on('change.select2', function () {
18999      self.dataAdapter.current(function (data) {
19000        self.trigger('selection:update', {
19001          data: data
19002        });
19003      });
19004    });
19005
19006    this.$element.on('focus.select2', function (evt) {
19007      self.trigger('focus', evt);
19008    });
19009
19010    this._syncA = Utils.bind(this._syncAttributes, this);
19011    this._syncS = Utils.bind(this._syncSubtree, this);
19012
19013    if (this.$element[0].attachEvent) {
19014      this.$element[0].attachEvent('onpropertychange', this._syncA);
19015    }
19016
19017    var observer = window.MutationObserver ||
19018      window.WebKitMutationObserver ||
19019      window.MozMutationObserver
19020    ;
19021
19022    if (observer != null) {
19023      this._observer = new observer(function (mutations) {
19024        self._syncA();
19025        self._syncS(null, mutations);
19026      });
19027      this._observer.observe(this.$element[0], {
19028        attributes: true,
19029        childList: true,
19030        subtree: false
19031      });
19032    } else if (this.$element[0].addEventListener) {
19033      this.$element[0].addEventListener(
19034        'DOMAttrModified',
19035        self._syncA,
19036        false
19037      );
19038      this.$element[0].addEventListener(
19039        'DOMNodeInserted',
19040        self._syncS,
19041        false
19042      );
19043      this.$element[0].addEventListener(
19044        'DOMNodeRemoved',
19045        self._syncS,
19046        false
19047      );
19048    }
19049  };
19050
19051  Select2.prototype._registerDataEvents = function () {
19052    var self = this;
19053
19054    this.dataAdapter.on('*', function (name, params) {
19055      self.trigger(name, params);
19056    });
19057  };
19058
19059  Select2.prototype._registerSelectionEvents = function () {
19060    var self = this;
19061    var nonRelayEvents = ['toggle', 'focus'];
19062
19063    this.selection.on('toggle', function () {
19064      self.toggleDropdown();
19065    });
19066
19067    this.selection.on('focus', function (params) {
19068      self.focus(params);
19069    });
19070
19071    this.selection.on('*', function (name, params) {
19072      if ($.inArray(name, nonRelayEvents) !== -1) {
19073        return;
19074      }
19075
19076      self.trigger(name, params);
19077    });
19078  };
19079
19080  Select2.prototype._registerDropdownEvents = function () {
19081    var self = this;
19082
19083    this.dropdown.on('*', fu
19083nction (name, params) {
19084      self.trigger(name, params);
19085    });
19086  };
19087
19088  Select2.prototype._registerResultsEvents = function () {
19089    var self = this;
19090
19091    this.results.on('*', function (name, params) {
19092      self.trigger(name, params);
19093    });
19094  };
19095
19096  Select2.prototype._registerEvents = function () {
19097    var self = this;
19098
19099    this.on('open', function () {
19100      self.$container.addClass('select2-container--open');
19101    });
19102
19103    this.on('close', function () {
19104      self.$container.removeClass('select2-container--open');
19105    });
19106
19107    this.on('enable', function () {
19108      self.$container.removeClass('select2-container--disabled');
19109    });
19110
19111    this.on('disable', function () {
19112      self.$container.addClass('select2-container--disabled');
19113    });
19114
19115    this.on('blur', function () {
19116      self.$container.removeClass('select2-container--focus');
19117    });
19118
19119    this.on('query', function (params) {
19120      if (!self.isOpen()) {
19121        self.trigger('open', {});
19122      }
19123
19124      this.dataAdapter.query(params, function (data) {
19125        self.trigger('results:all', {
19126          data: data,
19127          query: params
19128        });
19129      });
19130    });
19131
19132    this.on('query:append', function (params) {
19133      this.dataAdapter.query(params, function (data) {
19134        self.trigger('results:append', {
19135          data: data,
19136          query: params
19137        });
19138      });
19139    });
19140
19141    this.on('keypress', function (evt) {
19142      var key = evt.which;
19143
19144      if (self.isOpen()) {
19145        if (key === KEYS.ESC || key === KEYS.TAB ||
19146            (key === KEYS.UP && evt.altKey)) {
19147          self.close(evt);
19148
19149          evt.preventDefault();
19150        } else if (key === KEYS.ENTER) {
19151          self.trigger('results:select', {});
19152
19153          evt.preventDefault();
19154        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
19155          self.trigger('results:toggle', {});
19156
19157          evt.preventDefault();
19158        } else if (key === KEYS.UP) {
19159          self.trigger('results:previous', {});
19160
19161          evt.preventDefault();
19162        } else if (key === KEYS.DOWN) {
19163          self.trigger('results:next', {});
19164
19165          evt.preventDefault();
19166        }
19167      } else {
19168        if (key === KEYS.ENTER || key === KEYS.SPACE ||
19169            (key === KEYS.DOWN && evt.altKey)) {
19170          self.open();
19171
19172          evt.preventDefault();
19173        }
19174      }
19175    });
19176  };
19177
19178  Select2.prototype._syncAttributes = function () {
19179    this.options.set('disabled', this.$element.prop('disabled'));
19180
19181    if (this.isDisabled()) {
19182      if (this.isOpen()) {
19183        this.close();
19184      }
19185
19186      this.trigger('disable', {});
19187    } else {
19188      this.trigger('enable', {});
19189    }
19190  };
19191
19192  Select2.prototype._isChangeMutation = function (evt, mutations) {
19193    var changed = false;
19194    var self = this;
19195
19196    // Ignore any mutation events raised for elements that aren't options or
19197    // optgroups. This handles the case when the select element is destroyed
19198    if (
19199      evt && evt.target && (
19200        evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
19201      )
19202    ) {
19203      return;
19204    }
19205
19206    if (!mutations) {
19207      // If mutation events aren't supported, then we can only assume that the
19208      // change affected the selections
19209      changed = true;
19210    } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
19211      for (var n = 0; n < mutations.addedNodes.length; n++) {
19212        var node = mutations.addedNodes[n];
19213
19214        if (node.selected) {
19215          changed = true;
19216        }
19217      }
19218    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
19219      changed = true;
19220    } else if ($.isArray(mutations)) {
19221      $.each(mutations, function(evt, mutation) {
19222        if (self._isChangeMutation(evt, mutation)) {
19223          // We've found a change mutation.
19224          // Let's escape from the loop and continue
19225          changed = true;
19226          return false;
19227        }
19228      });
19229    }
19230    return changed;
19231  };
19232
19233  Select2.prototype._syncSubtree = function (evt, mutations) {
19234    var changed = this._isChangeMutation(evt, mutations);
19235    var self = this;
19236
19237    // Only re-pull the data if we think there is a change
19238    if (changed) {
19239      this.dataAdapter.current(function (currentData) {
19240        self.trigger('selection:update', {
19241          data: currentData
19242        });
19243      });
19244    }
19245  };
19246
19247  /**
19248   * Override the trigger method to automatically trigger pre-events when
19249   * there are events that can be prevented.
19250   */
19251  Select2.prototype.trigger = function (name, args) {
19252    var actualTrigger = Select2.__super__.trigger;
19253    var preTriggerMap = {
19254      'open': 'opening',
19255      'close': 'closing',
19256      'select': 'selecting',
19257      'unselect': 'unselecting',
19258      'clear': 'clearing'
19259    };
19260
19261    if (args === undefined) {
19262      args = {};
19263    }
19264
19265    if (name in preTriggerMap) {
19266      var preTriggerName = preTriggerMap[name];
19267      var preTriggerArgs = {
19268        prevented: false,
19269        name: name,
19270        args: args
19271      };
19272
19273      actualTrigger.call(this, preTriggerName, preTriggerArgs);
19274
19275      if (preTriggerArgs.prevented) {
19276        args.prevented = true;
19277
19278        return;
19279      }
19280    }
19281
19282    actualTrigger.call(this, name, args);
19283  };
19284
19285  Select2.prototype.toggleDropdown = function () {
19286    if (this.isDisabled()) {
19287      return;
19288    }
19289
19290    if (this.isOpen()) {
19291      this.close();
19292    } else {
19293      this.open();
19294    }
19295  };
19296
19297  Select2.prototype.open = function () {
19298    if (this.isOpen()) {
19299      return;
19300    }
19301
19302    if (this.isDisabled()) {
19303      return;
19304    }
19305
19306    this.trigger('query', {});
19307  };
19308
19309  Select2.prototype.close = function (evt) {
19310    if (!this.isOpen()) {
19311      return;
19312    }
19313
19314    this.trigger('close', { originalEvent : evt });
19315  };
19316
19317  /**
19318   * Helper method to abstract the "enabled" (not "disabled") state of this
19319   * object.
19320   *
19321   * @return {true} if the instance is not disabled.
19322   * @return {false} if the instance is disabled.
19323   */
19324  Select2.prototype.isEnabled = function () {
19325    return !this.isDisabled();
19326  };
19327
19328  /**
19329   * Helper method to abstract the "disabled" state of this object.
19330   *
19331   * @return {true} if the disabled option is true.
19332   * @return {false} if the disabled option is false.
19333   */
19334  Select2.prototype.isDisabled = function () {
19335    return this.options.get('disabled');
19336  };
19337
19338  Select2.prototype.isOpen = function () {
19339    return this.$container.hasClass('select2-container--open');
19340  };
19341
19342  Select2.prototype.hasFocus = function () {
19343    return this.$container.hasClass('select2-container--focus');
19344  };
19345
19346  Select2.prototype.focus = function (data) {
19347    // No need to re-trigger focus events if we are already focused
19348    if (this.hasFocus()) {
19349      return;
19350    }
19351
19352    this.$container.addClass('select2-container--focus');
19353    this.trigger('focus', {});
19354  };
19355
19356  Select2.prototype.enable = function (args) {
19357    if (this.options.get('debug') && window.console && console.warn) {
19358      console.warn(
19359        'Select2: The `select2("enable")` method has been deprecated and will' +
19360        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
19361        ' instead.'
19362      );
19363    }
19364
19365    if (args == null || args.length === 0) {
19366      args = [true];
19367    }
19368
19369    var disabled = !args[0];
19370
19371    this.$element.prop('disabled', disabled);
19372  };
19373
19374  Select2.prototype.data = function () {
19375    if (this.options.get('debug') &&
19376        arguments.length > 0 && window.console && console.warn) {
19377      console.warn(
19378        'Select2: Data can no longer be set using `select2("data")`. You ' +
19379        'should consider setting the value instead using `$element.val()`.'
19380      );
19381    }
19382
19383    var data = [];
19384
19385    this.dataAdapter.current(function (currentData) {
19386      data = currentData;
19387    });
19388
19389    return data;
19390  };
19391
19392  Select2.prototype.val = function (args) {
19393    if (this.options.get('debug') && window.console && console.warn) {
19394      console.warn(
19395        'Select2: The `select2("val")` method has been deprecated and will be' +
19396        ' removed in later Select2 versions. Use $element.val() instead.'
19397      );
19398    }
19399
19400    if (args == null || args.length === 0) {
19401      return this.$element.val();
19402    }
19403
19404    var newVal = args[0];
19405
19406    if ($.isArray(newVal)) {
19407      newVal = $.map(newVal, function (obj) {
19408        return obj.toString();
19409      });
19410    }
19411
19412    this.$element.val(newVal).trigger('input').trigger('change');
19413  };
19414
19415  Select2.prototype.destroy = function () {
19416    this.$container.remove();
19417
19418    if (this.$element[0].detachEvent) {
19419      this.$element[0].detachEvent('onpropertychange', this._syncA);
19420    }
19421
19422    if (this._observer != null) {
19423      this._observer.disconnect();
19424      this._observer = null;
19425    } else if (this.$element[0].removeEventListener) {
19426      this.$element[0]
19427        .removeEventListener('DOMAttrModified', this._syncA, false);
19428      this.$element[0]
19429        .removeEventListener('DOMNodeInserted', this._syncS, false);
19430      this.$element[0]
19431        .removeEventListener('DOMNodeRemoved', this._syncS, false);
19432    }
19433
19434    this._syncA = null;
19435    this._syncS = null;
19436
19437    this.$element.off('.select2');
19438    this.$element.attr('tabindex',
19439    Utils.GetData(this.$element[0], 'old-tabindex'));
19440
19441    this.$element.removeClass('select2-hidden-accessible');
19442    this.$element.attr('aria-hidden', 'false');
19443    Utils.RemoveData(this.$element[0]);
19444    this.$element.removeData('select2');
19445
19446    this.dataAdapter.destroy();
19447    this.selection.destroy();
19448    this.dropdown.destroy();
19449    this.results.destroy();
19450
19451    this.dataAdapter = null;
19452    this.selection = null;
19453    this.dropdown = null;
19454    this.results = null;
19455  };
19456
19457  Select2.prototype.render = function () {
19458    var $container = $(
19459      '<span class="select2 select2-container">' +
19460        '<span class="selection"></span>' +
19461        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
19462      '</span>'
19463    );
19464
19465    $container.attr('dir', this.options.get('dir'));
19466
19467    this.$container = $container;
19468
19469    this.$container.addClass('select2-container--' + this.options.get('theme'));
19470
19471    Utils.StoreData($container[0], 'element', this.$element);
19472
19473    return $container;
19474  };
19475
19476  return Select2;
19477});
19478
19479S2.define('jquery-mousewheel',[
19480  'jquery'
19481], function ($) {
19482  // Used to shim jQuery.mousewheel for non-full builds.
19483  return $;
19484});
19485
19486S2.define('jquery.select2',[
19487  'jquery',
19488  'jquery-mousewheel',
19489
19490  './select2/core',
19491  './select2/defaults',
19492  './select2/utils'
19493], function ($, _, Select2, Defaults, Utils) {
19494  if ($.fn.select2 == null) {
19495    // All methods that should return the element
19496    var thisMethods = ['open', 'close', 'destroy'];
19497
19498    $.fn.select2 = function (options) {
19499      options = options || {};
19500
19501      if (typeof options === 'object') {
19502        this.each(function () {
19503          var instanceOptions = $.extend(true, {}, options);
19504
19505          var instance = new Select2($(this), instanceOptions);
19506        });
19507
19508        return this;
19509      } else if (typeof options === 'string') {
19510        var ret;
19511        var args = Array.prototype.slice.call(arguments, 1);
19512
19513        this.each(function () {
19514          var instance = Utils.GetData(this, 'select2');
19515
19516          if (instance == null && window.console && console.error) {
19517            console.error(
19518              'The select2(\'' + options + '\') method was called on an ' +
19519              'element that is not using Select2.'
19520            );
19521          }
19522
19523          ret = instance[options].apply(instance, args);
19524        });
19525
19526        // Check if we should be returning `this`
19527        if ($.inArray(options, thisMethods) > -1) {
19528          return this;
19529        }
19530
19531        return ret;
19532      } else {
19533        throw new Error('Invalid arguments for Select2: ' + options);
19534      }
19535    };
19536  }
19537
19538  if ($.fn.select2.defaults == null) {
19539    $.fn.select2.defaults = Defaults;
19540  }
19541
19542  return Select2;
19543});
19544
19545  // Return the AMD loader configuration so it can be used outside of this file
19546  return {
19547    define: S2.define,
19548    require: S2.require
19549  };
19550}());
19551
19552  // Autoload the jQuery bindings
19553  // We know that all of the modules exist above this, so we're safe
19554  var select2 = S2.require('jquery.select2');
19555
19556  // Hold the AMD module references on the jQuery function that was just loaded
19557  // This allows Select2 to use the internal loader outside of this file, such
19558  // as in the language files.
19559  jQuery.fn.select2.amd = S2;
19560
19561  // Return the Select2 instance for anyone who is importing it.
19562  return select2;
19563}));
19564
19565var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
19566
19567var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
19568
19569/*! flatpickr v2.6.3, @license MIT */
19570function Flatpickr(element, config) {
19571	var self = this;
19572
19573	self._ = {};
19574	self._.afterDayAnim = afterDayAnim;
19575	self.changeMonth = changeMonth;
19576	self.changeYear = changeYear;
19577	self.clear = clear;
19578	self.close = close;
19579	self._createElement = createElement;
19580	self.destroy = destroy;
19581	self.isEnabled = isEnabled;
19582	self.jumpToDate = jumpToDate;
19583	self.open = open;
19584	self.redraw = redraw;
19585	self.set = set;
19586	self.setDate = setDate;
19587	self.toggle = toggle;
19588
19589	function init() {
19590		self.element = self.input = element;
19591		self.instanceConfig = config || {};
19592		self.parseDate = Flatpickr.prototype.parseDate.bind(self);
19593		self.formatDate = Flatpickr.prototype.formatDate.bind(self);
19594
19595		setupFormats();
19596		parseConfig();
19597		setupLocale();
19598		setupInputs();
19599		setupDates();
19600		setupHelperFunctions();
19601
19602		self.isOpen = false;
19603
19604		self.isMobile = !self.config.disableMobile && !self.config.inline && self.config.mode === "single" && !self.config.disable.length && !self.config.enable.length && !self.config.weekNumbers && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
19605
19606		if (!self.isMobile) build();
19607
19608		bindEvents();
19609
19610		if (self.selectedDates.length || self.config.noCalendar) {
19611			if (self.config.enableTime) {
19612				setHoursFromDate(self.config.noCalendar ? self.latestSelectedDateObj || self.config.minDate : null);
19613			}
19614			updateValue();
19615		}
19616
19617		if (self.config.weekNumbers) {
19618			self.calendarContainer.style.width = self.daysContainer.offsetWidth + self.weekWrapper.offsetWidth + "px";
19619		}
19620
19621		self.showTimeInput = self.selectedDates.length > 0 || self.config.noCalendar;
19622
19623		if (!self.isMobile) positionCalendar();
19624
19625		triggerEvent("Ready");
19626	}
19627
19628	/**
19629  * Binds a function to the current flatpickr instance
19630  * @param {Function} fn the function
19631  * @return {Function} the function bound to the instance
19632  */
19633	function bindToInstance(fn) {
19634		return fn.bind(self);
19635	}
19636
19637	/**
19638  * The handler for all events targeting the time inputs
19639  * @param {Event} e the event - "input", "wheel", "increment", etc
19640  */
19641	function updateTime(e) {
19642		if (self.config.noCalendar && !self.selectedDates.length)
19643			// picking time only
19644			self.selectedDates = [self.now];
19645
19646		timeWrapper(e);
19647
19648		if (!self.selectedDates.length) return;
19649
19650		if (!self.minDateHasTime || e.type !== "input" || e.target.value.length >= 2) {
19651			setHoursFromInputs();
19652			updateValue();
19653		} else {
19654			setTimeout(function () {
19655				setHoursFromInputs();
19656				updateValue();
19657			}, 1000);
19658		}
19659	}
19660
19661	/**
19662  * Syncs the selected date object time with user's time input
19663  */
19664	function setHoursFromInputs() {
19665		if (!self.config.enableTime) return;
19666
19667		var hours = (parseInt(self.hourElement.value, 10) || 0) % (self.amPM ? 12 : 24),
19668		    minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60,
19669		    seconds = self.config.enableSeconds ? (parseInt(self.secondElement.value, 10) || 0) % 60 : 0;
19670
19671		if (self.amPM !== undefined) hours = hours % 12 + 12 * (self.amPM.textContent === "PM");
19672
19673		if (self.minDateHasTime && compareDates(self.latestSelectedDateObj, self.config.minDate) === 0) {
19674
19675			hours = Math.max(hours, self.config.minDate.getHours());
19676			if (hours === self.config.minDate.getHours()) minutes = Math.max(minutes, self.config.minDate.getMinutes());
19677		}
19678
19679		if (self.maxDateHasTime && compareDates(self.latestSelectedDateObj, self.config.maxDate) === 0) {
19680			hours = Math.min(hours, self.config.maxDate.getHours());
19681			if (hours === self.config.maxDate.getHours()) minutes = Math.min(minutes, self.config.maxDate.getMinutes());
19682		}
19683
19684		setHours(hours, minutes, seconds);
19685	}
19686
19687	/**
19688  * Syncs time input values with a date
19689  * @param {Date} dateObj the date to sync with
19690  */
19691	function setHoursFromDate(dateObj) {
19692		var date = dateObj || self.latestSelectedDateObj;
19693
19694		if (date) setHours(date.getHours(), date.getMinutes(), date.getSeconds());
19695	}
19696
19697	/**
19698  * Sets the hours, minutes, and optionally seconds
19699  * of the latest selected date object and the
19700  * corresponding time inputs
19701  * @param {Number} hours the hour. whether its military
19702  *                 or am-pm gets inferred from config
19703  * @param {Number} minutes the minutes
19704  * @param {Number} seconds the seconds (optional)
19705  */
19706	function setHours(hours, minutes, seconds) {
19707		if (self.selectedDates.length) {
19708			self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);
19709		}
19710
19711		if (!self.config.enableTime || self.isMobile) return;
19712
19713		self.hourElement.value = self.pad(!self.config.time_24hr ? (12 + hours) % 12 + 12 * (hours % 12 === 0) : hours);
19714
19715		self.minuteElement.value = self.pad(minutes);
19716
19717		if (!self.config.time_24hr) self.amPM.textContent = hours >= 12 ? "PM" : "AM";
19718
19719		if (self.config.enableSeconds === true) self.secondElement.value = self.pad(seconds);
19720	}
19721
19722	/**
19723  * Handles the year input and incrementing events
19724  * @param {Event} event the keyup or increment event
19725  */
19726	function onYearInput(event) {
19727		var year = event.target.value;
19728		if (event.delta) year = (parseInt(year) + event.delta).toString();
19729
19730		if (year.length === 4 || event.key === "Enter") {
19731			self.currentYearElement.blur();
19732			if (!/[^\d]/.test(year)) changeYear(year);
19733		}
19734	}
19735
19736	/**
19737  * Essentially addEventListener + tracking
19738  * @param {Element} element the element to addEventListener to
19739  * @param {String} event the event name
19740  * @param {Function} handler the event handler
19741  */
19742	function bind(element, event, handler) {
19743		if (event instanceof Array) return event.forEach(function (ev) {
19744			return bind(element, ev, handler);
19745		});
19746
19747		if (element instanceof Array) return element.forEach(function (el) {
19748			return bind(el, event, handler);
19749		});
19750
19751		element.addEventListener(event, handler);
19752		self._handlers.push({ element: element, event: event, handler: handler });
19753	}
19754
19755	/**
19756  * A mousedown handler which mimics click.
19757  * Minimizes latency, since we don't need to wait for mouseup in most cases.
19758  * Also, avoids handling right clicks.
19759  *
19760  * @param {Function} handler the event handler
19761  */
19762	function onClick(handler) {
19763		return function (evt) {
19764			return evt.which === 1 && handler(evt);
19765		};
19766	}
19767
19768	/**
19769  * Adds all the necessary event listeners
19770  */
19771	function bindEvents() {
19772		self._handlers = [];
19773		self._animationLoop = [];
19774		if (self.config.wrap) {
19775			["open", "close", "toggle", "clear"].forEach(function (evt) {
19776				Array.prototype.forEach.call(self.element.querySelectorAll("[data-" + evt + "]"), function (el) {
19777					return bind(el, "mousedown", onClick(self[evt]));
19778				});
19779			});
19780		}
19781
19782		if (self.isMobile) return setupMobile();
19783
19784		self.debouncedResize = debounce(onResize, 50);
19785		self.triggerChange = function () {
19786			triggerEvent("Change");
19787		};
19788		self.debouncedChange = debounce(self.triggerChange, 300);
19789
19790		if (self.config.mode === "range" && self.daysContainer) bind(self.daysContainer, "mouseover", function (e) {
19791			return onMouseOver(e.target);
19792		});
19793
19794		bind(window.document.body, "keydown", onKeyDown);
19795
19796		if (!self.config.static) bind(self._input, "keydown", onKeyDown);
19797
19798		if (!self.config.inline && !self.config.static) bind(window, "resize", self.debouncedResize);
19799
19800		if (window.ontouchstart !== undefined) bind(window.document, "touchstart", documentClick);
19801
19802		bind(window.document, "mousedown", onClick(documentClick));
19803		bind(self._input, "blur", documentClick);
19804
19805		if (self.config.clickOpens === true) bind(self._input, "focus", self.open);
19806
19807		if (!self.config.noCalendar) {
19808			self.monthNav.addEventListener("wheel", function (e) {
19809				return e.preventDefault();
19810			});
19811			bind(self.monthNav, "wheel", debounce(onMonthNavScroll, 10));
19812			bind(self.monthNav, "mousedown", onClick(onMonthNavClick));
19813
19814			bind(self.monthNav, ["keyup", "increment"], onYearInput);
19815			bind(self.daysContainer, "mousedown", onClick(selectDate));
19816
19817			if (self.config.animate) {
19818				bind(self.daysContainer, ["webkitAnimationEnd", "animationend"], animateDays);
19819				bind(self.monthNav, ["webkitAnimationEnd", "animationend"], animateMonths);
19820			}
19821		}
19822
19823		if (self.config.enableTime) {
19824			var selText = function selText(e) {
19825				return e.target.select();
19826			};
19827			bind(self.timeContainer, ["wheel", "input", "increment"], updateTime);
19828			bind(self.timeContainer, "mousedown", onClick(timeIncrement));
19829
19830			bind(self.timeContainer, ["wheel", "increment"], self.debouncedChange);
19831			bind(self.timeContainer, "input", self.triggerChange);
19832
19833			bind([self.hourElement, self.minuteElement], "focus", selText);
19834
19835			if (self.secondElement !== undefined) bind(self.secondElement, "focus", function () {
19836				return self.secondElement.select();
19837			});
19838
19839			if (self.amPM !== undefined) {
19840				bind(self.amPM, "mousedown", onClick(function (e) {
19841					updateTime(e);
19842					self.triggerChange(e);
19843				}));
19844			}
19845		}
19846	}
19847
19848	function processPostDayAnimation() {
19849		for (var i = self._animationLoop.length; i--;) {
19850			self._animationLoop[i]();
19851			self._animationLoop.splice(i, 1);
19852		}
19853	}
19854
19855	/**
19856  * Removes the day container that slided out of view
19857  * @param {Event} e the animation event
19858  */
19859	function animateDays(e) {
19860		if (self.daysContainer.childNodes.length > 1) {
19861			switch (e.animationName) {
19862				case "fpSlideLeft":
19863					self.daysContainer.lastChild.classList.remove("slideLeftNew");
19864					self.daysContainer.removeChild(self.daysContainer.firstChild);
19865					self.days = self.daysContainer.firstChild;
19866					processPostDayAnimation();
19867
19868					break;
19869
19870				case "fpSlideRight":
19871					self.daysContainer.firstChild.classList.remove("slideRightNew");
19872					self.daysContainer.removeChild(self.daysContainer.lastChild);
19873					self.days = self.daysContainer.firstChild;
19874					processPostDayAnimation();
19875
19876					break;
19877
19878				default:
19879					break;
19880			}
19881		}
19882	}
19883
19884	/**
19885  * Removes the month element that animated out of view
19886  * @param {Event} e the animation event
19887  */
19888	function animateMonths(e) {
19889		switch (e.animationName) {
19890			case "fpSlideLeftNew":
19891			case "fpSlideRightNew":
19892				self.navigationCurrentMonth.classList.remove("slideLeftNew");
19893				self.navigationCurrentMonth.classList.remove("slideRightNew");
19894				var nav = self.navigationCurrentMonth;
19895
19896				while (nav.nextSibling && /curr/.test(nav.nextSibling.className)) {
19897					self.monthNav.removeChild(nav.nextSibling);
19898				}while (nav.previousSibling && /curr/.test(nav.previousSibling.className)) {
19899					self.monthNav.removeChild(nav.previousSibling);
19900				}self.oldCurMonth = null;
19901				break;
19902		}
19903	}
19904
19905	/**
19906  * Set the calendar view to a particular date.
19907  * @param {Date} jumpDate the date to set the view to
19908  */
19909	function jumpToDate(jumpDate) {
19910		jumpDate = jumpDate ? self.parseDate(jumpDate) : self.latestSelectedDateObj || (self.config.minDate > self.now ? self.config.minDate : self.config.maxDate && self.config.maxDate < self.now ? self.config.maxDate : self.now);
19911
19912		try {
19913			self.currentYear = jumpDate.getFullYear();
19914			self.currentMonth = jumpDate.getMonth();
19915		} catch (e) {
19916			/* istanbul ignore next */
19917			console.error(e.stack);
19918			/* istanbul ignore next */
19919			console.warn("Invalid date supplied: " + jumpDate);
19920		}
19921
19922		self.redraw();
19923	}
19924
19925	/**
19926  * The up/down arrow handler for time inputs
19927  * @param {Event} e the click event
19928  */
19929	function timeIncrement(e) {
19930		if (~e.target.className.indexOf("arrow")) incrementNumInput(e, e.target.classList.contains("arrowUp") ? 1 : -1);
19931	}
19932
19933	/**
19934  * Increments/decrements the value of input associ-
19935  * ated with the up/down arrow by dispatching an
19936  * "increment" event on the input.
19937  *
19938  * @param {Event} e the click event
19939  * @param {Number} delta the diff (usually 1 or -1)
19940  * @param {Element} inputElem the input element
19941  */
19942	function incrementNumInput(e, delta, inputElem) {
19943		var input = inputElem || e.target.parentNode.childNodes[0];
19944		var event = createEvent("increment");
19945		event.delta = delta;
19946		input.dispatchEvent(event);
19947	}
19948
19949	function createNumberInput(inputClassName) {
19950		var wrapper = createElement("div", "numInputWrapper"),
19951		    numInput = createElement("input", "numInput " + inputClassName),
19952		    arrowUp = createElement("span", "arrowUp"),
19953		    arrowDown = createElement("span", "arrowDown");
19954
19955		numInput.type = "text";
19956		numInput.pattern = "\\d*";
19957
19958		wrapper.appendChild(numInput);
19959		wrapper.appendChild(arrowUp);
19960		wrapper.appendChild(arrowDown);
19961
19962		return wrapper;
19963	}
19964
19965	function build() {
19966		var fragment = window.document.createDocumentFragment();
19967		self.calendarContainer = createElement("div", "flatpickr-calendar");
19968		self.calendarContainer.tabIndex = -1;
19969
19970		if (!self.config.noCalendar) {
19971			fragment.appendChild(buildMonthNav());
19972			self.innerContainer = createElement("div", "flatpickr-innerContainer");
19973
19974			if (self.config.weekNumbers) self.innerContainer.appendChild(buildWeeks());
19975
19976			self.rContainer = createElement("div", "flatpickr-rContainer");
19977			self.rContainer.appendChild(buildWeekdays());
19978
19979			if (!self.daysContainer) {
19980				self.daysContainer = createElement("div", "flatpickr-days");
19981				self.daysContainer.tabIndex = -1;
19982			}
19983
19984			buildDays();
19985			self.rContainer.appendChild(self.daysContainer);
19986
19987			self.innerContainer.appendChild(self.rContainer);
19988			fragment.appendChild(self.innerContainer);
19989		}
19990
19991		if (self.config.enableTime) fragment.appendChild(buildTime());
19992
19993		toggleClass(self.calendarContainer, "rangeMode", self.config.mode === "range");
19994		toggleClass(self.calendarContainer, "animate", self.config.animate);
19995
19996		self.calendarContainer.appendChild(fragment);
19997
19998		var customAppend = self.config.appendTo && self.config.appendTo.nodeType;
19999
20000		if (self.config.inline || self.config.static) {
20001			self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");
20002
20003			if (self.config.inline && !customAppend) {
20004				return self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);
20005			}
20006
20007			if (self.config.static) {
20008				var wrapper = createElement("div", "flatpickr-wrapper");
20009				self.element.parentNode.insertBefore(wrapper, self.element);
20010				wrapper.appendChild(self.element);
20011
20012				if (self.altInput) wrapper.appendChild(self.altInput);
20013
20014				wrapper.appendChild(self.calendarContainer);
20015				return;
20016			}
20017		}
20018
20019		(customAppend ? self.config.appendTo : window.document.body).appendChild(self.calendarContainer);
20020	}
20021
20022	function createDay(className, date, dayNumber, i) {
20023		var dateIsEnabled = isEnabled(date, true),
20024		    dayElement = createElement("span", "flatpickr-day " + className, date.getDate());
20025
20026		dayElement.dateObj = date;
20027		dayElement.$i = i;
20028		dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat));
20029
20030		if (compareDates(date, self.now) === 0) {
20031			self.todayDateElem = dayElement;
20032			dayElement.classList.add("today");
20033		}
20034
20035		if (dateIsEnabled) {
20036			dayElement.tabIndex = -1;
20037			if (isDateSelected(date)) {
20038				dayElement.classList.add("selected");
20039				self.selectedDateElem = dayElement;
20040				if (self.config.mode === "range") {
20041					toggleClass(dayElement, "startRange", compareDates(date, self.selectedDates[0]) === 0);
20042
20043					toggleClass(dayElement, "endRange", compareDates(date, self.selectedDates[1]) === 0);
20044				}
20045			}
20046		} else {
20047			dayElement.classList.add("disabled");
20048			if (self.selectedDates[0] && date > self.minRangeDate && date < self.selectedDates[0]) self.minRangeDate = date;else if (self.selectedDates[0] && date < self.maxRangeDate && date > self.selectedDates[0]) self.maxRangeDate = date;
20049		}
20050
20051		if (self.config.mode === "range") {
20052			if (isDateInRange(date) && !isDateSelected(date)) dayElement.classList.add("inRange");
20053
20054			if (self.selectedDates.length === 1 && (date < self.minRangeDate || date > self.maxRangeDate)) dayElement.classList.add("notAllowed");
20055		}
20056
20057		if (self.config.weekNumbers && className !== "prevMonthDay" && dayNumber % 7 === 1) {
20058			self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='disabled flatpickr-day'>" + self.config.getWeek(date) + "</span>");
20059		}
20060
20061		triggerEvent("DayCreate", dayElement);
20062
20063		return dayElement;
20064	}
20065
20066	function focusOnDay(currentIndex, offset) {
20067		var newIndex = currentIndex + offset || 0,
20068		    targetNode = currentIndex !== undefined ? self.days.childNodes[newIndex] : self.selectedDateElem || self.todayDateElem || self.days.childNodes[0],
20069		    focus = function focus() {
20070			targetNode = targetNode || self.days.childNodes[newIndex];
20071			targetNode.focus();
20072
20073			if (self.config.mode === "range") onMouseOver(targetNode);
20074		};
20075
20076		if (targetNode === undefined && offset !== 0) {
20077			if (offset > 0) {
20078				self.changeMonth(1);
20079				newIndex = newIndex % 42;
20080			} else if (offset < 0) {
20081				self.changeMonth(-1);
20082				newIndex += 42;
20083			}
20084
20085			return afterDayAnim(focus);
20086		}
20087
20088		focus();
20089	}
20090
20091	function afterDayAnim(fn) {
20092		if (self.config.animate === true) return self._animationLoop.push(fn);
20093		fn();
20094	}
20095
20096	function buildDays(delta) {
20097		var firstOfMonth = (new Date(self.currentYear, self.currentMonth, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7,
20098		    isRangeMode = self.config.mode === "range";
20099
20100		self.prevMonthDays = self.utils.getDaysinMonth((self.currentMonth - 1 + 12) % 12);
20101		self.selectedDateElem = undefined;
20102		self.todayDateElem = undefined;
20103
20104		var daysInMonth = self.utils.getDaysinMonth(),
20105		    days = window.document.createDocumentFragment();
20106
20107		var dayNumber = self.prevMonthDays + 1 - firstOfMonth,
20108		    dayIndex = 0;
20109
20110		if (self.config.weekNumbers && self.weekNumbers.firstChild) self.weekNumbers.textContent = "";
20111
20112		if (isRangeMode) {
20113			// const dateLimits = self.config.enable.length || self.config.disable.length || self.config.mixDate || self.config.maxDate;
20114			self.minRangeDate = new Date(self.currentYear, self.currentMonth - 1, dayNumber);
20115			self.maxRangeDate = new Date(self.currentYear, self.currentMonth + 1, (42 - firstOfMonth) % daysInMonth);
20116		}
20117
20118		// prepend days from the ending of previous month
20119		for (; dayNumber <= self.prevMonthDays; dayNumber++, dayIndex++) {
20120			days.appendChild(createDay("prevMonthDay", new Date(self.currentYear, self.currentMonth - 1, dayNumber), dayNumber, dayIndex));
20121		}
20122
20123		// Start at 1 since there is no 0th day
20124		for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {
20125			days.appendChild(createDay("", new Date(self.currentYear, self.currentMonth, dayNumber), dayNumber, dayIndex));
20126		}
20127
20128		// append days from the next month
20129		for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth; dayNum++, dayIndex++) {
20130			days.appendChild(createDay("nextMonthDay", new Date(self.currentYear, self.currentMonth + 1, dayNum % daysInMonth), dayNum, dayIndex));
20131		}
20132
20133		if (isRangeMode && self.selectedDates.length === 1 && days.childNodes[0]) {
20134			self._hidePrevMonthArrow = self._hidePrevMonthArrow || self.minRangeDate > days.childNodes[0].dateObj;
20135
20136			self._hideNextMonthArrow = self._hideNextMonthArrow || self.maxRangeDate < new Date(self.currentYear, self.currentMonth + 1, 1);
20137		} else updateNavigationCurrentMonth();
20138
20139		var dayContainer = createElement("div", "dayContainer");
20140		dayContainer.appendChild(days);
20141
20142		if (!self.config.animate || delta === undefined) clearNode(self.daysContainer);else {
20143			while (self.daysContainer.childNodes.length > 1) {
20144				self.daysContainer.removeChild(self.daysContainer.firstChild);
20145			}
20146		}
20147
20148		if (delta >= 0) self.daysContainer.appendChild(dayContainer);else self.daysContainer.insertBefore(dayContainer, self.daysContainer.firstChild);
20149
20150		self.days = self.daysContainer.firstChild;
20151		return self.daysContainer;
20152	}
20153
20154	function clearNode(node) {
20155		while (node.firstChild) {
20156			node.removeChild(node.firstChild);
20157		}
20158	}
20159
20160	function buildMonthNav() {
20161		var monthNavFragment = window.document.createDocumentFragment();
20162		self.monthNav = createElement("div", "flatpickr-month");
20163
20164		self.prevMonthNav = createElement("span", "flatpickr-prev-month");
20165		self.prevMonthNav.innerHTML = self.config.prevArrow;
20166
20167		self.currentMonthElement = createElement("span", "cur-month");
20168		self.currentMonthElement.title = self.l10n.scrollTitle;
20169
20170		var yearInput = createNumberInput("cur-year");
20171		self.currentYearElement = yearInput.childNodes[0];
20172		self.currentYearElement.title = self.l10n.scrollTitle;
20173
20174		if (self.config.minDate) self.currentYearElement.min = self.config.minDate.getFullYear();
20175
20176		if (self.config.maxDate) {
20177			self.currentYearElement.max = self.config.maxDate.getFullYear();
20178
20179			self.currentYearElement.disabled = self.config.minDate && self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
20180		}
20181
20182		self.nextMonthNav = createElement("span", "flatpickr-next-month");
20183		self.nextMonthNav.innerHTML = self.config.nextArrow;
20184
20185		self.navigationCurrentMonth = createElement("span", "flatpickr-current-month");
20186		self.navigationCurrentMonth.appendChild(self.currentMonthElement);
20187		self.navigationCurrentMonth.appendChild(yearInput);
20188
20189		monthNavFragment.appendChild(self.prevMonthNav);
20190		monthNavFragment.appendChild(self.navigationCurrentMonth);
20191		monthNavFragment.appendChild(self.nextMonthNav);
20192		self.monthNav.appendChild(monthNavFragment);
20193
20194		Object.defineProperty(self, "_hidePrevMonthArrow", {
20195			get: function get() {
20196				return this.__hidePrevMonthArrow;
20197			},
20198			set: function set(bool) {
20199				if (this.__hidePrevMonthArrow !== bool) self.prevMonthNav.style.display = bool ? "none" : "block";
20200				this.__hidePrevMonthArrow = bool;
20201			}
20202		});
20203
20204		Object.defineProperty(self, "_hideNextMonthArrow", {
20205			get: function get() {
20206				return this.__hideNextMonthArrow;
20207			},
20208			set: function set(bool) {
20209				if (this.__hideNextMonthArrow !== bool) self.nextMonthNav.style.display = bool ? "none" : "block";
20210				this.__hideNextMonthArrow = bool;
20211			}
20212		});
20213
20214		updateNavigationCurrentMonth();
20215
20216		return self.monthNav;
20217	}
20218
20219	function buildTime() {
20220		self.calendarContainer.classList.add("hasTime");
20221		if (self.config.noCalendar) self.calendarContainer.classList.add("noCalendar");
20222		self.timeContainer = createElement("div", "flatpickr-time");
20223		self.timeContainer.tabIndex = -1;
20224		var separator = createElement("span", "flatpickr-time-separator", ":");
20225
20226		var hourInput = createNumberInput("flatpickr-hour");
20227		self.hourElement = hourInput.childNodes[0];
20228
20229		var minuteInput = createNumberInput("flatpickr-minute");
20230		self.minuteElement = minuteInput.childNodes[0];
20231
20232		self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;
20233
20234		self.hourElement.value = self.pad(self.latestSelectedDateObj ? self.latestSelectedDateObj.getHours() : self.config.defaultHour);
20235
20236		self.minuteElement.value = self.pad(self.latestSelectedDateObj ? self.latestSelectedDateObj.getMinutes() : self.config.defaultMinute);
20237
20238		self.hourElement.step = self.config.hourIncrement;
20239		self.minuteElement.step = self.config.minuteIncrement;
20240
20241		self.hourElement.min = self.config.time_24hr ? 0 : 1;
20242		self.hourElement.max = self.config.time_24hr ? 23 : 12;
20243
20244		self.minuteElement.min = 0;
20245		self.minuteElement.max = 59;
20246
20247		self.hourElement.title = self.minuteElement.title = self.l10n.scrollTitle;
20248
20249		self.timeContainer.appendChild(hourInput);
20250		self.timeContainer.appendChild(separator);
20251		self.timeContainer.appendChild(minuteInput);
20252
20253		if (self.config.time_24hr) self.timeContainer.classList.add("time24hr");
20254
20255		if (self.config.enableSeconds) {
20256			self.timeContainer.classList.add("hasSeconds");
20257
20258			var secondInput = createNumberInput("flatpickr-second");
20259			self.secondElement = secondInput.childNodes[0];
20260
20261			self.secondElement.value = self.latestSelectedDateObj ? self.pad(self.latestSelectedDateObj.getSeconds()) : "00";
20262
20263			self.secondElement.step = self.minuteElement.step;
20264			self.secondElement.min = self.minuteElement.min;
20265			self.secondElement.max = self.minuteElement.max;
20266
20267			self.timeContainer.appendChild(createElement("span", "flatpickr-time-separator", ":"));
20268			self.timeContainer.appendChild(secondInput);
20269		}
20270
20271		if (!self.config.time_24hr) {
20272			// add self.amPM if appropriate
20273			self.amPM = createElement("span", "flatpickr-am-pm", ["AM", "PM"][self.hourElement.value > 11 | 0]);
20274			self.amPM.title = self.l10n.toggleTitle;
20275			self.amPM.tabIndex = -1;
20276			self.timeContainer.appendChild(self.amPM);
20277		}
20278
20279		return self.timeContainer;
20280	}
20281
20282	function buildWeekdays() {
20283		if (!self.weekdayContainer) self.weekdayContainer = createElement("div", "flatpickr-weekdays");
20284
20285		var firstDayOfWeek = self.l10n.firstDayOfWeek;
20286		var weekdays = self.l10n.weekdays.shorthand.slice();
20287
20288		if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
20289			weekdays = [].concat(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));
20290		}
20291
20292		self.weekdayContainer.innerHTML = "\n\t\t<span class=flatpickr-weekday>\n\t\t\t" + weekdays.join("</span><span class=flatpickr-weekday>") + "\n\t\t</span>\n\t\t";
20293
20294		return self.weekdayContainer;
20295	}
20296
20297	/* istanbul ignore next */
20298	function buildWeeks() {
20299		self.calendarContainer.classList.add("hasWeeks");
20300		self.weekWrapper = createElement("div", "flatpickr-weekwrapper");
20301		self.weekWrapper.appendChild(createElement("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
20302		self.weekNumbers = createElement("div", "flatpickr-weeks");
20303		self.weekWrapper.appendChild(self.weekNumbers);
20304
20305		return self.weekWrapper;
20306	}
20307
20308	function changeMonth(value, is_offset, animate) {
20309		is_offset = is_offset === undefined || is_offset;
20310		var delta = is_offset ? value : value - self.currentMonth;
20311		var skipAnimations = !self.config.animate || animate === false;
20312
20313		if (delta < 0 && self._hidePrevMonthArrow || delta > 0 && self._hideNextMonthArrow) return;
20314
20315		self.currentMonth += delta;
20316
20317		if (self.currentMonth < 0 || self.currentMonth > 11) {
20318			self.currentYear += self.currentMonth > 11 ? 1 : -1;
20319			self.currentMonth = (self.currentMonth + 12) % 12;
20320
20321			triggerEvent("YearChange");
20322		}
20323
20324		buildDays(!skipAnimations ? delta : undefined);
20325
20326		if (skipAnimations) {
20327			triggerEvent("MonthChange");
20328			return updateNavigationCurrentMonth();
20329		}
20330
20331		// remove possible remnants from clicking too fast
20332		var nav = self.navigationCurrentMonth;
20333		if (delta < 0) {
20334			while (nav.nextSibling && /curr/.test(nav.nextSibling.className)) {
20335				self.monthNav.removeChild(nav.nextSibling);
20336			}
20337		} else if (delta > 0) {
20338			while (nav.previousSibling && /curr/.test(nav.previousSibling.className)) {
20339				self.monthNav.removeChild(nav.previousSibling);
20340			}
20341		}
20342
20343		self.oldCurMonth = self.navigationCurrentMonth;
20344
20345		self.navigationCurrentMonth = self.monthNav.insertBefore(self.oldCurMonth.cloneNode(true), delta > 0 ? self.oldCurMonth.nextSibling : self.oldCurMonth);
20346
20347		if (delta > 0) {
20348			self.daysContainer.firstChild.classList.add("slideLeft");
20349			self.daysContainer.lastChild.classList.add("slideLeftNew");
20350
20351			self.oldCurMonth.classList.add("slideLeft");
20352			self.navigationCurrentMonth.classList.add("slideLeftNew");
20353		} else if (delta < 0) {
20354			self.daysContainer.firstChild.classList.add("slideRightNew");
20355			self.daysContainer.lastChild.classList.add("slideRight");
20356
20357			self.oldCurMonth.classList.add("slideRight");
20358			self.navigationCurrentMonth.classList.add("slideRightNew");
20359		}
20360
20361		self.currentMonthElement = self.navigationCurrentMonth.firstChild;
20362		self.currentYearElement = self.navigationCurrentMonth.lastChild.childNodes[0];
20363
20364		updateNavigationCurrentMonth();
20365		self.oldCurMonth.firstChild.textContent = self.utils.monthToStr(self.currentMonth - delta);
20366
20367		triggerEvent("MonthChange");
20368
20369		if (document.activeElement && document.activeElement.$i) {
20370			var index = document.activeElement.$i;
20371			afterDayAnim(function () {
20372				focusOnDay(index, 0);
20373			});
20374		}
20375	}
20376
20377	function clear(triggerChangeEvent) {
20378		self.input.value = "";
20379
20380		if (self.altInput) self.altInput.value = "";
20381
20382		if (self.mobileInput) self.mobileInput.value = "";
20383
20384		self.selectedDates = [];
20385		self.latestSelectedDateObj = undefined;
20386		self.showTimeInput = false;
20387
20388		self.redraw();
20389
20390		if (triggerChangeEvent !== false)
20391			// triggerChangeEvent is true (default) or an Event
20392			triggerEvent("Change");
20393	}
20394
20395	function close() {
20396		self.isOpen = false;
20397
20398		if (!self.isMobile) {
20399			self.calendarContainer.classList.remove("open");
20400			self._input.classList.remove("active");
20401		}
20402
20403		triggerEvent("Close");
20404	}
20405
20406	function destroy() {
20407		for (var i = self._handlers.length; i--;) {
20408			var h = self._handlers[i];
20409			h.element.removeEventListener(h.event, h.handler);
20410		}
20411
20412		self._handlers = [];
20413
20414		if (self.mobileInput) {
20415			if (self.mobileInput.parentNode) self.mobileInput.parentNode.removeChild(self.mobileInput);
20416			self.mobileInput = null;
20417		} else if (self.calendarContainer && self.calendarContainer.parentNode) self.calendarContainer.parentNode.removeChild(self.calendarContainer);
20418
20419		if (self.altInput) {
20420			self.input.type = "text";
20421			if (self.altInput.parentNode) self.altInput.parentNode.removeChild(self.altInput);
20422			delete self.altInput;
20423		}
20424
20425		if (self.input) {
20426			self.input.type = self.input._type;
20427			self.input.classList.remove("flatpickr-input");
20428			self.input.removeAttribute("readonly");
20429			self.input.value = "";
20430		}
20431
20432		["_showTimeInput", "latestSelectedDateObj", "_hideNextMonthArrow", "_hidePrevMonthArrow", "__hideNextMonthArrow", "__hidePrevMonthArrow", "isMobile", "isOpen", "selectedDateElem", "minDateHasTime", "maxDateHasTime", "days", "daysContainer", "_input", "_positionElement", "innerContainer", "rContainer", "monthNav", "todayDateElem", "calendarContainer", "weekdayContainer", "prevMonthNav", "nextMonthNav", "currentMonthElement", "currentYearElement", "navigationCurrentMonth", "selectedDateElem", "config"].forEach(function (k) {
20433			return delete self[k];
20434		});
20435	}
20436
20437	function isCalendarElem(elem) {
20438		if (self.config.appendTo && self.config.appendTo.contains(elem)) return true;
20439
20440		return self.calendarContainer.contains(elem);
20441	}
20442
20443	function documentClick(e) {
20444		if (self.isOpen && !self.config.inline) {
20445			var isCalendarElement = isCalendarElem(e.target);
20446			var isInput = e.target === self.input || e.target === self.altInput || self.element.contains(e.target) ||
20447			// web components
20448			e.path && e.path.indexOf && (~e.path.indexOf(self.input) || ~e.path.indexOf(self.altInput));
20449
20450			var lostFocus = e.type === "blur" ? isInput && e.relatedTarget && !isCalendarElem(e.relatedTarget) : !isInput && !isCalendarElement;
20451
20452			if (lostFocus) {
20453				e.preventDefault();
20454				self.close();
20455
20456				if (self.config.mode === "range" && self.selectedDates.length === 1) {
20457					self.clear(false);
20458					self.redraw();
20459				}
20460			}
20461		}
20462	}
20463
20464	function changeYear(newYear) {
20465		if (!newYear || self.currentYearElement.min && newYear < self.currentYearElement.min || self.currentYearElement.max && newYear > self.currentYearElement.max) return;
20466
20467		var newYearNum = parseInt(newYear, 10),
20468		    isNewYear = self.currentYear !== newYearNum;
20469
20470		self.currentYear = newYearNum || self.currentYear;
20471
20472		if (self.config.maxDate && self.currentYear === self.config.maxDate.getFullYear()) {
20473			self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
20474		} else if (self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) {
20475			self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
20476		}
20477
20478		if (isNewYear) {
20479			self.redraw();
20480			triggerEvent("YearChange");
20481		}
20482	}
20483
20484	function isEnabled(date, timeless) {
20485		if (self.config.minDate && compareDates(date, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0 || self.config.maxDate && compareDates(date, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0) return false;
20486
20487		if (!self.config.enable.length && !self.config.disable.length) return true;
20488
20489		var dateToCheck = self.parseDate(date, null, true); // timeless
20490
20491		var bool = self.config.enable.length > 0,
20492		    array = bool ? self.config.enable : self.config.disable;
20493
20494		for (var i = 0, d; i < array.length; i++) {
20495			d = array[i];
20496
20497			if (d instanceof Function && d(dateToCheck)) // disabled by function
20498				return bool;else if (d instanceof Date && d.getTime() === dateToCheck.getTime())
20499				// disabled by date
20500				return bool;else if (typeof d === "string" && self.parseDate(d, null, true).getTime() === dateToCheck.getTime())
20501				// disabled by date string
20502				return bool;else if ( // disabled by range
20503			(typeof d === "undefined" ? "undefined" : _typeof(d)) === "object" && d.from && d.to && dateToCheck >= d.from && dateToCheck <= d.to) return bool;
20504		}
20505
20506		return !bool;
20507	}
20508
20509	function onKeyDown(e) {
20510		var isInput = e.target === self._input;
20511		var calendarElem = isCalendarElem(e.target);
20512		var allowInput = self.config.allowInput;
20513		var allowKeydown = self.isOpen && (!allowInput || !isInput);
20514		var allowInlineKeydown = self.config.inline && isInput && !allowInput;
20515
20516		if (e.key === "Enter" && allowInput && isInput) {
20517			self.setDate(self._input.value, true, e.target === self.altInput ? self.config.altFormat : self.config.dateFormat);
20518			return e.target.blur();
20519		} else if (calendarElem || allowKeydown || allowInlineKeydown) {
20520			var isTimeObj = self.timeContainer && self.timeContainer.contains(e.target);
20521			switch (e.key) {
20522				case "Enter":
20523					if (isTimeObj) updateValue();else selectDate(e);
20524
20525					break;
20526
20527				case "Escape":
20528					// escape
20529					e.preventDefault();
20530					self.close();
20531					break;
20532
20533				case "ArrowLeft":
20534				case "ArrowRight":
20535					if (!isTimeObj) {
20536						e.preventDefault();
20537
20538						if (self.daysContainer) {
20539							var _delta = e.key === "ArrowRight" ? 1 : -1;
20540
20541							if (!e.ctrlKey) focusOnDay(e.target.$i, _delta);else changeMonth(_delta, true);
20542						} else if (self.config.enableTime && !isTimeObj) self.hourElement.focus();
20543					}
20544
20545					break;
20546
20547				case "ArrowUp":
20548				case "ArrowDown":
20549					e.preventDefault();
20550					var delta = e.key === "ArrowDown" ? 1 : -1;
20551
20552					if (self.daysContainer) {
20553						if (e.ctrlKey) {
20554							changeYear(self.currentYear - delta);
20555							focusOnDay(e.target.$i, 0);
20556						} else if (!isTimeObj) focusOnDay(e.target.$i, delta * 7);
20557					} else if (self.config.enableTime) {
20558						if (!isTimeObj) self.hourElement.focus();
20559						updateTime(e);
20560					}
20561
20562					break;
20563
20564				case "Tab":
20565					if (e.target === self.hourElement) {
20566						e.preventDefault();
20567						self.minuteElement.select();
20568					} else if (e.target === self.minuteElement && (self.secondElement || self.amPM)) {
20569						e.preventDefault();
20570						(self.secondElement || self.amPM).focus();
20571					} else if (e.target === self.secondElement) {
20572						e.preventDefault();
20573						self.amPM.focus();
20574					}
20575
20576					break;
20577
20578				case "a":
20579					if (e.target === self.amPM) {
20580						self.amPM.textContent = "AM";
20581						setHoursFromInputs();
20582						updateValue();
20583					}
20584					break;
20585
20586				case "p":
20587					if (e.target === self.amPM) {
20588						self.amPM.textContent = "PM";
20589						setHoursFromInputs();
20590						updateValue();
20591					}
20592					break;
20593
20594				default:
20595					break;
20596
20597			}
20598
20599			triggerEvent("KeyDown", e);
20600		}
20601	}
20602
20603	function onMouseOver(elem) {
20604		if (self.selectedDates.length !== 1 || !elem.classList.contains("flatpickr-day")) return;
20605
20606		var hoverDate = elem.dateObj,
20607		    initialDate = self.parseDate(self.selectedDates[0], null, true),
20608		    rangeStartDate = Math.min(hoverDate.getTime(), self.selectedDates[0].getTime()),
20609		    rangeEndDate = Math.max(hoverDate.getTime(), self.selectedDates[0].getTime()),
20610		    containsDisabled = false;
20611
20612		for (var t = rangeStartDate; t < rangeEndDate; t += self.utils.duration.DAY) {
20613			if (!isEnabled(new Date(t))) {
20614				containsDisabled = true;
20615				break;
20616			}
20617		}
20618
20619		var _loop = function _loop(timestamp, i) {
20620			var outOfRange = timestamp < self.minRangeDate.getTime() || timestamp > self.maxRangeDate.getTime(),
20621			    dayElem = self.days.childNodes[i];
20622
20623			if (outOfRange) {
20624				self.days.childNodes[i].classList.add("notAllowed");
20625				["inRange", "startRange", "endRange"].forEach(function (c) {
20626					dayElem.classList.remove(c);
20627				});
20628				return "continue";
20629			} else if (containsDisabled && !outOfRange) return "continue";
20630
20631			["startRange", "inRange", "endRange", "notAllowed"].forEach(function (c) {
20632				dayElem.classList.remove(c);
20633			});
20634
20635			var minRangeDate = Math.max(self.minRangeDate.getTime(), rangeStartDate),
20636			    maxRangeDate = Math.min(self.maxRangeDate.getTime(), rangeEndDate);
20637
20638			elem.classList.add(hoverDate < self.selectedDates[0] ? "startRange" : "endRange");
20639
20640			if (initialDate < hoverDate && timestamp === initialDate.getTime()) dayElem.classList.add("startRange");else if (initialDate > hoverDate && timestamp === initialDate.getTime()) dayElem.classList.add("endRange");
20641
20642			if (timestamp >= minRangeDate && timestamp <= maxRangeDate) dayElem.classList.add("inRange");
20643		};
20644
20645		for (var timestamp = self.days.childNodes[0].dateObj.getTime(), i = 0; i < 42; i++, timestamp += self.utils.duration.DAY) {
20646			var _ret = _loop(timestamp, i);
20647
20648			if (_ret === "continue") continue;
20649		}
20650	}
20651
20652	function onResize() {
20653		if (self.isOpen && !self.config.static && !self.config.inline) positionCalendar();
20654	}
20655
20656	function open(e) {
20657		if (self.isMobile) {
20658			if (e) {
20659				e.preventDefault();
20660				e.target.blur();
20661			}
20662
20663			setTimeout(function () {
20664				self.mobileInput.click();
20665			}, 0);
20666
20667			triggerEvent("Open");
20668			return;
20669		}
20670
20671		if (self.isOpen || self._input.disabled || self.config.inline) return;
20672
20673		self.isOpen = true;
20674		self.calendarContainer.classList.add("open");
20675		positionCalendar();
20676		self._input.classList.add("active");
20677
20678		triggerEvent("Open");
20679	}
20680
20681	function minMaxDateSetter(type) {
20682		return function (date) {
20683			var dateObj = self.config["_" + type + "Date"] = self.parseDate(date);
20684
20685			var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"];
20686			var isValidDate = date && dateObj instanceof Date;
20687
20688			if (isValidDate) {
20689				self[type + "DateHasTime"] = dateObj.getHours() || dateObj.getMinutes() || dateObj.getSeconds();
20690			}
20691
20692			if (self.selectedDates) {
20693				self.selectedDates = self.selectedDates.filter(function (d) {
20694					return isEnabled(d);
20695				});
20696				if (!self.selectedDates.length && type === "min") setHoursFromDate(dateObj);
20697				updateValue();
20698			}
20699
20700			if (self.daysContainer) {
20701				redraw();
20702
20703				if (isValidDate) self.currentYearElement[type] = dateObj.getFullYear();else self.currentYearElement.removeAttribute(type);
20704
20705				self.currentYearElement.disabled = inverseDateObj && dateObj && inverseDateObj.getFullYear() === dateObj.getFullYear();
20706			}
20707		};
20708	}
20709
20710	function parseConfig() {
20711		var boolOpts = ["utc", "wrap", "weekNumbers", "allowInput", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile"];
20712
20713		var hooks = ["onChange", "onClose", "onDayCreate", "onKeyDown", "onMonthChange", "onOpen", "onParseConfig", "onReady", "onValueUpdate", "onYearChange"];
20714
20715		self.config = Object.create(Flatpickr.defaultConfig);
20716
20717		var userConfig = _extends({}, self.instanceConfig, JSON.parse(JSON.stringify(self.element.dataset || {})));
20718
20719		self.config.parseDate = userConfig.parseDate;
20720		self.config.formatDate = userConfig.formatDate;
20721
20722		_extends(self.config, userConfig);
20723
20724		if (!userConfig.dateFormat && userConfig.enableTime) {
20725			self.config.dateFormat = self.config.noCalendar ? "H:i" + (self.config.enableSeconds ? ":S" : "") : Flatpickr.defaultConfig.dateFormat + " H:i" + (self.config.enableSeconds ? ":S" : "");
20726		}
20727
20728		if (userConfig.altInput && userConfig.enableTime && !userConfig.altFormat) {
20729			self.config.altFormat = self.config.noCalendar ? "h:i" + (self.config.enableSeconds ? ":S K" : " K") : Flatpickr.defaultConfig.altFormat + (" h:i" 
20729+ (self.config.enableSeconds ? ":S" : "") + " K");
20730		}
20731
20732		Object.defineProperty(self.config, "minDate", {
20733			get: function get() {
20734				return this._minDate;
20735			},
20736			set: minMaxDateSetter("min")
20737		});
20738
20739		Object.defineProperty(self.config, "maxDate", {
20740			get: function get() {
20741				return this._maxDate;
20742			},
20743			set: minMaxDateSetter("max")
20744		});
20745
20746		self.config.minDate = userConfig.minDate;
20747		self.config.maxDate = userConfig.maxDate;
20748
20749		for (var i = 0; i < boolOpts.length; i++) {
20750			self.config[boolOpts[i]] = self.config[boolOpts[i]] === true || self.config[boolOpts[i]] === "true";
20751		}for (var _i = hooks.length; _i--;) {
20752			if (self.config[hooks[_i]] !== undefined) {
20753				self.config[hooks[_i]] = arrayify(self.config[hooks[_i]] || []).map(bindToInstance);
20754			}
20755		}
20756
20757		for (var _i2 = 0; _i2 < self.config.plugins.length; _i2++) {
20758			var pluginConf = self.config.plugins[_i2](self) || {};
20759			for (var key in pluginConf) {
20760
20761				if (self.config[key] instanceof Array || ~hooks.indexOf(key)) {
20762					self.config[key] = arrayify(pluginConf[key]).map(bindToInstance).concat(self.config[key]);
20763				} else if (typeof userConfig[key] === "undefined") self.config[key] = pluginConf[key];
20764			}
20765		}
20766
20767		triggerEvent("ParseConfig");
20768	}
20769
20770	function setupLocale() {
20771		if (_typeof(self.config.locale) !== "object" && typeof Flatpickr.l10ns[self.config.locale] === "undefined") console.warn("flatpickr: invalid locale " + self.config.locale);
20772
20773		self.l10n = _extends(Object.create(Flatpickr.l10ns.default), _typeof(self.config.locale) === "object" ? self.config.locale : self.config.locale !== "default" ? Flatpickr.l10ns[self.config.locale] || {} : {});
20774	}
20775
20776	function positionCalendar() {
20777		if (self.calendarContainer === undefined) return;
20778
20779		var calendarHeight = self.calendarContainer.offsetHeight,
20780		    calendarWidth = self.calendarContainer.offsetWidth,
20781		    configPos = self.config.position,
20782		    inputBounds = self._positionElement.getBoundingClientRect(),
20783		    distanceFromBottom = window.innerHeight - inputBounds.bottom,
20784		    showOnTop = configPos === "above" || configPos !== "below" && distanceFromBottom < calendarHeight && inputBounds.top > calendarHeight;
20785
20786		var top = window.pageYOffset + inputBounds.top + (!showOnTop ? self._positionElement.offsetHeight + 2 : -calendarHeight - 2);
20787
20788		toggleClass(self.calendarContainer, "arrowTop", !showOnTop);
20789		toggleClass(self.calendarContainer, "arrowBottom", showOnTop);
20790
20791		if (self.config.inline) return;
20792
20793		var left = window.pageXOffset + inputBounds.left;
20794		var right = window.document.body.offsetWidth - inputBounds.right;
20795		var rightMost = left + calendarWidth > window.document.body.offsetWidth;
20796
20797		toggleClass(self.calendarContainer, "rightMost", rightMost);
20798
20799		if (self.config.static) return;
20800
20801		self.calendarContainer.style.top = top + "px";
20802
20803		if (!rightMost) {
20804			self.calendarContainer.style.left = left + "px";
20805			self.calendarContainer.style.right = "auto";
20806		} else {
20807			self.calendarContainer.style.left = "auto";
20808			self.calendarContainer.style.right = right + "px";
20809		}
20810	}
20811
20812	function redraw() {
20813		if (self.config.noCalendar || self.isMobile) return;
20814
20815		buildWeekdays();
20816		updateNavigationCurrentMonth();
20817		buildDays();
20818	}
20819
20820	function selectDate(e) {
20821		e.preventDefault();
20822		e.stopPropagation();
20823
20824		if (!e.target.classList.contains("flatpickr-day") || e.target.classList.contains("disabled") || e.target.classList.contains("notAllowed")) return;
20825
20826		var selectedDate = self.latestSelectedDateObj = new Date(e.target.dateObj.getTime());
20827
20828		var shouldChangeMonth = selectedDate.getMonth() !== self.currentMonth && self.config.mode !== "range";
20829
20830		self.selectedDateElem = e.target;
20831
20832		if (self.config.mode === "single") self.selectedDates = [selectedDate];else if (self.config.mode === "multiple") {
20833			var selectedIndex = isDateSelected(selectedDate);
20834			if (selectedIndex) self.selectedDates.splice(selectedIndex, 1);else self.selectedDates.push(selectedDate);
20835		} else if (self.config.mode === "range") {
20836			if (self.selectedDates.length === 2) self.clear();
20837
20838			self.selectedDates.push(selectedDate);
20839
20840			// unless selecting same date twice, sort ascendingly
20841			if (compareDates(selectedDate, self.selectedDates[0], true) !== 0) self.selectedDates.sort(function (a, b) {
20842				return a.getTime() - b.getTime();
20843			});
20844		}
20845
20846		setHoursFromInputs();
20847
20848		if (shouldChangeMonth) {
20849			var isNewYear = self.currentYear !== selectedDate.getFullYear();
20850			self.currentYear = selectedDate.getFullYear();
20851			self.currentMonth = selectedDate.getMonth();
20852
20853			if (isNewYear) triggerEvent("YearChange");
20854
20855			triggerEvent("MonthChange");
20856		}
20857
20858		buildDays();
20859
20860		if (self.minDateHasTime && self.config.enableTime && compareDates(selectedDate, self.config.minDate) === 0) setHoursFromDate(self.config.minDate);
20861
20862		updateValue();
20863
20864		if (self.config.enableTime) setTimeout(function () {
20865			return self.showTimeInput = true;
20866		}, 50);
20867
20868		if (self.config.mode === "range") {
20869			if (self.selectedDates.length === 1) {
20870				onMouseOver(e.target);
20871
20872				self._hidePrevMonthArrow = self._hidePrevMonthArrow || self.minRangeDate > self.days.childNodes[0].dateObj;
20873
20874				self._hideNextMonthArrow = self._hideNextMonthArrow || self.maxRangeDate < new Date(self.currentYear, self.currentMonth + 1, 1);
20875			} else updateNavigationCurrentMonth();
20876		}
20877
20878		triggerEvent("Change");
20879
20880		// maintain focus
20881		if (!shouldChangeMonth) focusOnDay(e.target.$i, 0);else afterDayAnim(function () {
20882			return self.selectedDateElem.focus();
20883		});
20884
20885		if (self.config.enableTime) setTimeout(function () {
20886			return self.hourElement.select();
20887		}, 451);
20888
20889		if (self.config.closeOnSelect) {
20890			var single = self.config.mode === "single" && !self.config.enableTime;
20891			var range = self.config.mode === "range" && self.selectedDates.length === 2 && !self.config.enableTime;
20892
20893			if (single || range) self.close();
20894		}
20895	}
20896
20897	function set(option, value) {
20898		self.config[option] = value;
20899		self.redraw();
20900		jumpToDate();
20901	}
20902
20903	function setSelectedDate(inputDate, format) {
20904		if (inputDate instanceof Array) self.selectedDates = inputDate.map(function (d) {
20905			return self.parseDate(d, format);
20906		});else if (inputDate instanceof Date || !isNaN(inputDate)) self.selectedDates = [self.parseDate(inputDate, format)];else if (inputDate && inputDate.substring) {
20907			switch (self.config.mode) {
20908				case "single":
20909					self.selectedDates = [self.parseDate(inputDate, format)];
20910					break;
20911
20912				case "multiple":
20913					self.selectedDates = inputDate.split("; ").map(function (date) {
20914						return self.parseDate(date, format);
20915					});
20916					break;
20917
20918				case "range":
20919					self.selectedDates = inputDate.split(self.l10n.rangeSeparator).map(function (date) {
20920						return self.parseDate(date, format);
20921					});
20922
20923					break;
20924
20925				default:
20926					break;
20927			}
20928		}
20929
20930		self.selectedDates = self.selectedDates.filter(function (d) {
20931			return d instanceof Date && isEnabled(d, false);
20932		});
20933
20934		self.selectedDates.sort(function (a, b) {
20935			return a.getTime() - b.getTime();
20936		});
20937	}
20938
20939	function setDate(date, triggerChange, format) {
20940		if (!date) return self.clear(triggerChange);
20941
20942		setSelectedDate(date, format);
20943
20944		self.showTimeInput = self.selectedDates.length > 0;
20945		self.latestSelectedDateObj = self.selectedDates[0];
20946
20947		self.redraw();
20948		jumpToDate();
20949
20950		setHoursFromDate();
20951		updateValue(triggerChange);
20952
20953		if (triggerChange) triggerEvent("Change");
20954	}
20955
20956	function setupDates() {
20957		function parseDateRules(arr) {
20958			for (var i = arr.length; i--;) {
20959				if (typeof arr[i] === "string" || +arr[i]) arr[i] = self.parseDate(arr[i], null, true);else if (arr[i] && arr[i].from && arr[i].to) {
20960					arr[i].from = self.parseDate(arr[i].from);
20961					arr[i].to = self.parseDate(arr[i].to);
20962				}
20963			}
20964
20965			return arr.filter(function (x) {
20966				return x;
20967			}); // remove falsy values
20968		}
20969
20970		self.selectedDates = [];
20971		self.now = new Date();
20972
20973		if (self.config.disable.length) self.config.disable = parseDateRules(self.config.disable);
20974
20975		if (self.config.enable.length) self.config.enable = parseDateRules(self.config.enable);
20976
20977		var preloadedDate = self.config.defaultDate || self.input.value;
20978		if (preloadedDate) setSelectedDate(preloadedDate, self.config.dateFormat);
20979
20980		var initialDate = self.selectedDates.length ? self.selectedDates[0] : self.config.minDate && self.config.minDate.getTime() > self.now ? self.config.minDate : self.config.maxDate && self.config.maxDate.getTime() < self.now ? self.config.maxDate : self.now;
20981
20982		self.currentYear = initialDate.getFullYear();
20983		self.currentMonth = initialDate.getMonth();
20984
20985		if (self.selectedDates.length) self.latestSelectedDateObj = self.selectedDates[0];
20986
20987		self.minDateHasTime = self.config.minDate && (self.config.minDate.getHours() || self.config.minDate.getMinutes() || self.config.minDate.getSeconds());
20988
20989		self.maxDateHasTime = self.config.maxDate && (self.config.maxDate.getHours() || self.config.maxDate.getMinutes() || self.config.maxDate.getSeconds());
20990
20991		Object.defineProperty(self, "latestSelectedDateObj", {
20992			get: function get() {
20993				return self._selectedDateObj || self.selectedDates[self.selectedDates.length - 1];
20994			},
20995			set: function set(date) {
20996				self._selectedDateObj = date;
20997			}
20998		});
20999
21000		if (!self.isMobile) {
21001			Object.defineProperty(self, "showTimeInput", {
21002				get: function get() {
21003					return self._showTimeInput;
21004				},
21005				set: function set(bool) {
21006					self._showTimeInput = bool;
21007					if (self.calendarContainer) toggleClass(self.calendarContainer, "showTimeInput", bool);
21008					positionCalendar();
21009				}
21010			});
21011		}
21012	}
21013
21014	function setupHelperFunctions() {
21015		self.utils = {
21016			duration: {
21017				DAY: 86400000
21018			},
21019			getDaysinMonth: function getDaysinMonth(month, yr) {
21020				month = typeof month === "undefined" ? self.currentMonth : month;
21021
21022				yr = typeof yr === "undefined" ? self.currentYear : yr;
21023
21024				if (month === 1 && (yr % 4 === 0 && yr % 100 !== 0 || yr % 400 === 0)) return 29;
21025
21026				return self.l10n.daysInMonth[month];
21027			},
21028			monthToStr: function monthToStr(monthNumber, shorthand) {
21029				shorthand = typeof shorthand === "undefined" ? self.config.shorthandCurrentMonth : shorthand;
21030
21031				return self.l10n.months[(shorthand ? "short" : "long") + "hand"][monthNumber];
21032			}
21033		};
21034	}
21035
21036	/* istanbul ignore next */
21037	function setupFormats() {
21038		["D", "F", "J", "M", "W", "l"].forEach(function (f) {
21039			self.formats[f] = Flatpickr.prototype.formats[f].bind(self);
21040		});
21041
21042		self.revFormat.F = Flatpickr.prototype.revFormat.F.bind(self);
21043		self.revFormat.M = Flatpickr.prototype.revFormat.M.bind(self);
21044	}
21045
21046	function setupInputs() {
21047		self.input = self.config.wrap ? self.element.querySelector("[data-input]") : self.element;
21048
21049		/* istanbul ignore next */
21050		if (!self.input) return console.warn("Error: invalid input element specified", self.input);
21051
21052		self.input._type = self.input.type;
21053		self.input.type = "text";
21054
21055		self.input.classList.add("flatpickr-input");
21056		self._input = self.input;
21057
21058		if (self.config.altInput) {
21059			// replicate self.element
21060			self.altInput = createElement(self.input.nodeName, self.input.className + " " + self.config.altInputClass);
21061			self._input = self.altInput;
21062			self.altInput.placeholder = self.input.placeholder;
21063			self.altInput.disabled = self.input.disabled;
21064			self.altInput.type = "text";
21065			self.input.type = "hidden";
21066
21067			if (!self.config.static && self.input.parentNode) self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
21068		}
21069
21070		if (!self.config.allowInput) self._input.setAttribute("readonly", "readonly");
21071
21072		self._positionElement = self.config.positionElement || self._input;
21073	}
21074
21075	function setupMobile() {
21076		var inputType = self.config.enableTime ? self.config.noCalendar ? "time" : "datetime-local" : "date";
21077
21078		self.mobileInput = createElement("input", self.input.className + " flatpickr-mobile");
21079		self.mobileInput.step = "any";
21080		self.mobileInput.tabIndex = 1;
21081		self.mobileInput.type = inputType;
21082		self.mobileInput.disabled = self.input.disabled;
21083		self.mobileInput.placeholder = self.input.placeholder;
21084
21085		self.mobileFormatStr = inputType === "datetime-local" ? "Y-m-d\\TH:i:S" : inputType === "date" ? "Y-m-d" : "H:i:S";
21086
21087		if (self.selectedDates.length) {
21088			self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);
21089		}
21090
21091		if (self.config.minDate) self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d");
21092
21093		if (self.config.maxDate) self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d");
21094
21095		self.input.type = "hidden";
21096		if (self.config.altInput) self.altInput.type = "hidden";
21097
21098		try {
21099			self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
21100		} catch (e) {
21101			//
21102		}
21103
21104		self.mobileInput.addEventListener("change", function (e) {
21105			self.setDate(e.target.value, false, self.mobileFormatStr);
21106			triggerEvent("Change");
21107			triggerEvent("Close");
21108		});
21109	}
21110
21111	function toggle() {
21112		if (self.isOpen) return self.close();
21113		self.open();
21114	}
21115
21116	function triggerEvent(event, data) {
21117		var hooks = self.config["on" + event];
21118
21119		if (hooks !== undefined && hooks.length > 0) {
21120			for (var i = 0; hooks[i] && i < hooks.length; i++) {
21121				hooks[i](self.selectedDates, self.input.value, self, data);
21122			}
21123		}
21124
21125		if (event === "Change") {
21126			self.input.dispatchEvent(createEvent("change"));
21127
21128			// many front-end frameworks bind to the input event
21129			self.input.dispatchEvent(createEvent("input"));
21130		}
21131	}
21132
21133	/**
21134  * Creates an Event, normalized across browsers
21135  * @param {String} name the event name, e.g. "click"
21136  * @return {Event} the created event
21137  */
21138	function createEvent(name) {
21139		if (self._supportsEvents) return new Event(name, { bubbles: true });
21140
21141		self._[name + "Event"] = document.createEvent("Event");
21142		self._[name + "Event"].initEvent(name, true, true);
21143		return self._[name + "Event"];
21144	}
21145
21146	function isDateSelected(date) {
21147		for (var i = 0; i < self.selectedDates.length; i++) {
21148			if (compareDates(self.selectedDates[i], date) === 0) return "" + i;
21149		}
21150
21151		return false;
21152	}
21153
21154	function isDateInRange(date) {
21155		if (self.config.mode !== "range" || self.selectedDates.length < 2) return false;
21156		return compareDates(date, self.selectedDates[0]) >= 0 && compareDates(date, self.selectedDates[1]) <= 0;
21157	}
21158
21159	function updateNavigationCurrentMonth() {
21160		if (self.config.noCalendar || self.isMobile || !self.monthNav) return;
21161
21162		self.currentMonthElement.textContent = self.utils.monthToStr(self.currentMonth) + " ";
21163		self.currentYearElement.value = self.currentYear;
21164
21165		self._hidePrevMonthArrow = self.config.minDate && (self.currentYear === self.config.minDate.getFullYear() ? self.currentMonth <= self.config.minDate.getMonth() : self.currentYear < self.config.minDate.getFullYear());
21166
21167		self._hideNextMonthArrow = self.config.maxDate && (self.currentYear === self.config.maxDate.getFullYear() ? self.currentMonth + 1 > self.config.maxDate.getMonth() : self.currentYear > self.config.maxDate.getFullYear());
21168	}
21169
21170	/**
21171  * Updates the values of inputs associated with the calendar
21172  * @return {void}
21173  */
21174	function updateValue(triggerChange) {
21175		if (!self.selectedDates.length) return self.clear(triggerChange);
21176
21177		if (self.isMobile) {
21178			self.mobileInput.value = self.selectedDates.length ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr) : "";
21179		}
21180
21181		var joinChar = self.config.mode !== "range" ? "; " : self.l10n.rangeSeparator;
21182
21183		self.input.value = self.selectedDates.map(function (dObj) {
21184			return self.formatDate(dObj, self.config.dateFormat);
21185		}).join(joinChar);
21186
21187		if (self.config.altInput) {
21188			self.altInput.value = self.selectedDates.map(function (dObj) {
21189				return self.formatDate(dObj, self.config.altFormat);
21190			}).join(joinChar);
21191		}
21192		triggerEvent("ValueUpdate");
21193	}
21194
21195	function mouseDelta(e) {
21196		return Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY));
21197	}
21198
21199	function onMonthNavScroll(e) {
21200		e.preventDefault();
21201		var isYear = self.currentYearElement.parentNode.contains(e.target);
21202
21203		if (e.target === self.currentMonthElement || isYear) {
21204
21205			var delta = mouseDelta(e);
21206
21207			if (isYear) {
21208				changeYear(self.currentYear + delta);
21209				e.target.value = self.currentYear;
21210			} else self.changeMonth(delta, true, false);
21211		}
21212	}
21213
21214	function onMonthNavClick(e) {
21215		var isPrevMonth = self.prevMonthNav.contains(e.target);
21216		var isNextMonth = self.nextMonthNav.contains(e.target);
21217
21218		if (isPrevMonth || isNextMonth) changeMonth(isPrevMonth ? -1 : 1);else if (e.target === self.currentYearElement) {
21219			e.preventDefault();
21220			self.currentYearElement.select();
21221		} else if (e.target.className === "arrowUp") self.changeYear(self.currentYear + 1);else if (e.target.className === "arrowDown") self.changeYear(self.currentYear - 1);
21222	}
21223
21224	/**
21225  * Creates an HTMLElement with given tag, class, and textual content
21226  * @param {String} tag the HTML tag
21227  * @param {String} className the new element's class name
21228  * @param {String} content The new element's text content
21229  * @return {HTMLElement} the created HTML element
21230  */
21231	function createElement(tag, className, content) {
21232		var e = window.document.createElement(tag);
21233		className = className || "";
21234		content = content || "";
21235
21236		e.className = className;
21237
21238		if (content !== undefined) e.textContent = content;
21239
21240		return e;
21241	}
21242
21243	function arrayify(obj) {
21244		if (obj instanceof Array) return obj;
21245		return [obj];
21246	}
21247
21248	function toggleClass(elem, className, bool) {
21249		if (bool) return elem.classList.add(className);
21250		elem.classList.remove(className);
21251	}
21252
21253	/* istanbul ignore next */
21254	function debounce(func, wait, immediate) {
21255		var timeout = void 0;
21256		return function () {
21257			var context = this,
21258			    args = arguments;
21259			clearTimeout(timeout);
21260			timeout = setTimeout(function () {
21261				timeout = null;
21262				if (!immediate) func.apply(context, args);
21263			}, wait);
21264			if (immediate && !timeout) func.apply(context, args);
21265		};
21266	}
21267
21268	/**
21269  * Compute the difference in dates, measured in ms
21270  * @param {Date} date1
21271  * @param {Date} date2
21272  * @param {Boolean} timeless whether to reset times of both dates to 00:00
21273  * @return {Number} the difference in ms
21274  */
21275	function compareDates(date1, date2, timeless) {
21276		if (!(date1 instanceof Date) || !(date2 instanceof Date)) return false;
21277
21278		if (timeless !== false) {
21279			return new Date(date1.getTime()).setHours(0, 0, 0, 0) - new Date(date2.getTime()).setHours(0, 0, 0, 0);
21280		}
21281
21282		return date1.getTime() - date2.getTime();
21283	}
21284
21285	function timeWrapper(e) {
21286		e.preventDefault();
21287
21288		var isKeyDown = e.type === "keydown",
21289		    isWheel = e.type === "wheel",
21290		    isIncrement = e.type === "increment",
21291		    input = e.target;
21292
21293		if (self.amPM && e.target === self.amPM) return e.target.textContent = ["AM", "PM"][e.target.textContent === "AM" | 0];
21294
21295		var min = Number(input.min),
21296		    max = Number(input.max),
21297		    step = Number(input.step),
21298		    curValue = parseInt(input.value, 10),
21299		    delta = e.delta || (!isKeyDown ? Math.max(-1, Math.min(1, e.wheelDelta || -e.deltaY)) || 0 : e.which === 38 ? 1 : -1);
21300
21301		var newValue = curValue + step * delta;
21302
21303		if (typeof input.value !== "undefined" && input.value.length === 2) {
21304			var isHourElem = input === self.hourElement,
21305			    isMinuteElem = input === self.minuteElement;
21306
21307			if (newValue < min) {
21308				newValue = max + newValue + !isHourElem + (isHourElem && !self.amPM);
21309
21310				if (isMinuteElem) incrementNumInput(null, -1, self.hourElement);
21311			} else if (newValue > max) {
21312				newValue = input === self.hourElement ? newValue - max - !self.amPM : min;
21313
21314				if (isMinuteElem) incrementNumInput(null, 1, self.hourElement);
21315			}
21316
21317			if (self.amPM && isHourElem && (step === 1 ? newValue + curValue === 23 : Math.abs(newValue - curValue) > step)) self.amPM.textContent = self.amPM.textContent === "PM" ? "AM" : "PM";
21318
21319			input.value = self.pad(newValue);
21320		}
21321	}
21322
21323	init();
21324	return self;
21325}
21326
21327/* istanbul ignore next */
21328Flatpickr.defaultConfig = {
21329	mode: "single",
21330
21331	position: "auto",
21332
21333	animate: window.navigator.userAgent.indexOf("MSIE") === -1,
21334
21335	/* if true, dates will be parsed, formatted, and displayed in UTC.
21336 preloading date strings w/ timezones is recommended but not necessary */
21337	utc: false,
21338
21339	// wrap: see https://chmln.github.io/flatpickr/examples/#flatpickr-external-elements
21340	wrap: false,
21341
21342	// enables week numbers
21343	weekNumbers: false,
21344
21345	// allow manual datetime input
21346	allowInput: false,
21347
21348	/*
21349 	clicking on input opens the date(time)picker.
21350 	disable if you wish to open the calendar manually with .open()
21351 */
21352	clickOpens: true,
21353
21354	/*
21355 	closes calendar after date selection,
21356 	unless 'mode' is 'multiple' or enableTime is true
21357 */
21358	closeOnSelect: true,
21359
21360	// display time picker in 24 hour mode
21361	time_24hr: false,
21362
21363	// enables the time picker functionality
21364	enableTime: false,
21365
21366	// noCalendar: true will hide the calendar. use for a time picker along w/ enableTime
21367	noCalendar: false,
21368
21369	// more date format chars at https://chmln.github.io/flatpickr/#dateformat
21370	dateFormat: "Y-m-d",
21371
21372	// date format used in aria-label for days
21373	ariaDateFormat: "F j, Y",
21374
21375	// altInput - see https://chmln.github.io/flatpickr/#altinput
21376	altInput: false,
21377
21378	// the created altInput element will have this class.
21379	altInputClass: "form-control input",
21380
21381	// same as dateFormat, but for altInput
21382	altFormat: "F j, Y", // defaults to e.g. June 10, 2016
21383
21384	// defaultDate - either a datestring or a date object. used for datetimepicker"s initial value
21385	defaultDate: null,
21386
21387	// the minimum date that user can pick (inclusive)
21388	minDate: null,
21389
21390	// the maximum date that user can pick (inclusive)
21391	maxDate: null,
21392
21393	// dateparser that transforms a given string to a date object
21394	parseDate: null,
21395
21396	// dateformatter that transforms a given date object to a string, according to passed format
21397	formatDate: null,
21398
21399	getWeek: function getWeek(givenDate) {
21400		var date = new Date(givenDate.getTime());
21401		var onejan = new Date(date.getFullYear(), 0, 1);
21402		return Math.ceil(((date - onejan) / 86400000 + onejan.getDay() + 1) / 7);
21403	},
21404
21405
21406	// see https://chmln.github.io/flatpickr/#disable
21407	enable: [],
21408
21409	// see https://chmln.github.io/flatpickr/#disable
21410	disable: [],
21411
21412	// display the short version of month names - e.g. Sep instead of September
21413	shorthandCurrentMonth: false,
21414
21415	// displays calendar inline. see https://chmln.github.io/flatpickr/#inline-calendar
21416	inline: false,
21417
21418	// position calendar inside wrapper and next to the input element
21419	// leave at false unless you know what you"re doing
21420	"static": false,
21421
21422	// DOM node to append the calendar to in *static* mode
21423	appendTo: null,
21424
21425	// code for previous/next icons. this is where you put your custom icon code e.g. fontawesome
21426	prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
21427	nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",
21428
21429	// enables seconds in the time picker
21430	enableSeconds: false,
21431
21432	// step size used when scrolling/incrementing the hour element
21433	hourIncrement: 1,
21434
21435	// step size used when scrolling/incrementing the minute element
21436	minuteIncrement: 5,
21437
21438	// initial value in the hour element
21439	defaultHour: 12,
21440
21441	// initial value in the minute element
21442	defaultMinute: 0,
21443
21444	// disable native mobile datetime input support
21445	disableMobile: false,
21446
21447	// default locale
21448	locale: "default",
21449
21450	plugins: [],
21451
21452	// called every time calendar is closed
21453	onClose: undefined, // function (dateObj, dateStr) {}
21454
21455	// onChange callback when user selects a date or time
21456	onChange: undefined, // function (dateObj, dateStr) {}
21457
21458	// called for every day element
21459	onDayCreate: undefined,
21460
21461	// called every time the month is changed
21462	onMonthChange: undefined,
21463
21464	// called every time calendar is opened
21465	onOpen: undefined, // function (dateObj, dateStr) {}
21466
21467	// called after the configuration has been parsed
21468	onParseConfig: undefined,
21469
21470	// called after calendar is ready
21471	onReady: undefined, // function (dateObj, dateStr) {}
21472
21473	// called after input value updated
21474	onValueUpdate: undefined,
21475
21476	// called every time the year is changed
21477	onYearChange: undefined,
21478
21479	onKeyDown: undefined
21480};
21481
21482/* istanbul ignore next */
21483Flatpickr.l10ns = {
21484	en: {
21485		weekdays: {
21486			shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
21487			longhand: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
21488		},
21489		months: {
21490			shorthand: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
21491			longhand: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
21491November", "December"]
21492		},
21493		daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
21494		firstDayOfWeek: 0,
21495		ordinal: function ordinal(nth) {
21496			var s = nth % 100;
21497			if (s > 3 && s < 21) return "th";
21498			switch (s % 10) {
21499				case 1:
21500					return "st";
21501				case 2:
21502					return "nd";
21503				case 3:
21504					return "rd";
21505				default:
21506					return "th";
21507			}
21508		},
21509		rangeSeparator: " to ",
21510		weekAbbreviation: "Wk",
21511		scrollTitle: "Scroll to increment",
21512		toggleTitle: "Click to toggle"
21513	}
21514};
21515
21516Flatpickr.l10ns.default = Object.create(Flatpickr.l10ns.en);
21517Flatpickr.localize = function (l10n) {
21518	return _extends(Flatpickr.l10ns.default, l10n || {});
21519};
21520Flatpickr.setDefaults = function (config) {
21521	return _extends(Flatpickr.defaultConfig, config || {});
21522};
21523
21524Flatpickr.prototype = {
21525	formats: {
21526		// get the date in UTC
21527		Z: function Z(date) {
21528			return date.toISOString();
21529		},
21530
21531		// weekday name, short, e.g. Thu
21532		D: function D(date) {
21533			return this.l10n.weekdays.shorthand[this.formats.w(date)];
21534		},
21535
21536		// full month name e.g. January
21537		F: function F(date) {
21538			return this.utils.monthToStr(this.formats.n(date) - 1, false);
21539		},
21540
21541		// padded hour 1-12
21542		G: function G(date) {
21543			return Flatpickr.prototype.pad(Flatpickr.prototype.formats.h(date));
21544		},
21545
21546		// hours with leading zero e.g. 03
21547		H: function H(date) {
21548			return Flatpickr.prototype.pad(date.getHours());
21549		},
21550
21551		// day (1-30) with ordinal suffix e.g. 1st, 2nd
21552		J: function J(date) {
21553			return date.getDate() + this.l10n.ordinal(date.getDate());
21554		},
21555
21556		// AM/PM
21557		K: function K(date) {
21558			return date.getHours() > 11 ? "PM" : "AM";
21559		},
21560
21561		// shorthand month e.g. Jan, Sep, Oct, etc
21562		M: function M(date) {
21563			return this.utils.monthToStr(date.getMonth(), true);
21564		},
21565
21566		// seconds 00-59
21567		S: function S(date) {
21568			return Flatpickr.prototype.pad(date.getSeconds());
21569		},
21570
21571		// unix timestamp
21572		U: function U(date) {
21573			return date.getTime() / 1000;
21574		},
21575
21576		W: function W(date) {
21577			return this.config.getWeek(date);
21578		},
21579
21580		// full year e.g. 2016
21581		Y: function Y(date) {
21582			return date.getFullYear();
21583		},
21584
21585		// day in month, padded (01-30)
21586		d: function d(date) {
21587			return Flatpickr.prototype.pad(date.getDate());
21588		},
21589
21590		// hour from 1-12 (am/pm)
21591		h: function h(date) {
21592			return date.getHours() % 12 ? date.getHours() % 12 : 12;
21593		},
21594
21595		// minutes, padded with leading zero e.g. 09
21596		i: function i(date) {
21597			return Flatpickr.prototype.pad(date.getMinutes());
21598		},
21599
21600		// day in month (1-30)
21601		j: function j(date) {
21602			return date.getDate();
21603		},
21604
21605		// weekday name, full, e.g. Thursday
21606		l: function l(date) {
21607			return this.l10n.weekdays.longhand[date.getDay()];
21608		},
21609
21610		// padded month number (01-12)
21611		m: function m(date) {
21612			return Flatpickr.prototype.pad(date.getMonth() + 1);
21613		},
21614
21615		// the month number (1-12)
21616		n: function n(date) {
21617			return date.getMonth() + 1;
21618		},
21619
21620		// seconds 0-59
21621		s: function s(date) {
21622			return date.getSeconds();
21623		},
21624
21625		// number of the day of the week
21626		w: function w(date) {
21627			return date.getDay();
21628		},
21629
21630		// last two digits of year e.g. 16 for 2016
21631		y: function y(date) {
21632			return String(date.getFullYear()).substring(2);
21633		}
21634	},
21635
21636	/**
21637  * Formats a given Date object into a string based on supplied format
21638  * @param {Date} dateObj the date object
21639  * @param {String} frmt a string composed of formatting tokens e.g. "Y-m-d"
21640  * @return {String} The textual representation of the date e.g. 2017-02-03
21641  */
21642	formatDate: function formatDate(dateObj, frmt) {
21643		var _this = this;
21644
21645		if (this.config !== undefined && this.config.formatDate !== undefined) return this.config.formatDate(dateObj, frmt);
21646
21647		return frmt.split("").map(function (c, i, arr) {
21648			return _this.formats[c] && arr[i - 1] !== "\\" ? _this.formats[c](dateObj) : c !== "\\" ? c : "";
21649		}).join("");
21650	},
21651
21652
21653	revFormat: {
21654		D: function D() {},
21655		F: function F(dateObj, monthName) {
21656			dateObj.setMonth(this.l10n.months.longhand.indexOf(monthName));
21657		},
21658		G: function G(dateObj, hour) {
21659			dateObj.setHours(parseFloat(hour));
21660		},
21661		H: function H(dateObj, hour) {
21662			dateObj.setHours(parseFloat(hour));
21663		},
21664		J: function J(dateObj, day) {
21665			dateObj.setDate(parseFloat(day));
21666		},
21667		K: function K(dateObj, amPM) {
21668			var hours = dateObj.getHours();
21669
21670			if (hours !== 12) dateObj.setHours(hours % 12 + 12 * /pm/i.test(amPM));
21671		},
21672		M: function M(dateObj, shortMonth) {
21673			dateObj.setMonth(this.l10n.months.shorthand.indexOf(shortMonth));
21674		},
21675		S: function S(dateObj, seconds) {
21676			dateObj.setSeconds(seconds);
21677		},
21678		U: function U(dateObj, unixSeconds) {
21679			return new Date(parseFloat(unixSeconds) * 1000);
21680		},
21681
21682		W: function W(dateObj, weekNumber) {
21683			weekNumber = parseInt(weekNumber);
21684			return new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0, 0);
21685		},
21686		Y: function Y(dateObj, year) {
21687			dateObj.setFullYear(year);
21688		},
21689		Z: function Z(dateObj, ISODate) {
21690			return new Date(ISODate);
21691		},
21692
21693		d: function d(dateObj, day) {
21694			dateObj.setDate(parseFloat(day));
21695		},
21696		h: function h(dateObj, hour) {
21697			dateObj.setHours(parseFloat(hour));
21698		},
21699		i: function i(dateObj, minutes) {
21700			dateObj.setMinutes(parseFloat(minutes));
21701		},
21702		j: function j(dateObj, day) {
21703			dateObj.setDate(parseFloat(day));
21704		},
21705		l: function l() {},
21706		m: function m(dateObj, month) {
21707			dateObj.setMonth(parseFloat(month) - 1);
21708		},
21709		n: function n(dateObj, month) {
21710			dateObj.setMonth(parseFloat(month) - 1);
21711		},
21712		s: function s(dateObj, seconds) {
21713			dateObj.setSeconds(parseFloat(seconds));
21714		},
21715		w: function w() {},
21716		y: function y(dateObj, year) {
21717			dateObj.setFullYear(2000 + parseFloat(year));
21718		}
21719	},
21720
21721	tokenRegex: {
21722		D: "(\\w+)",
21723		F: "(\\w+)",
21724		G: "(\\d\\d|\\d)",
21725		H: "(\\d\\d|\\d)",
21726		J: "(\\d\\d|\\d)\\w+",
21727		K: "(\\w+)",
21728		M: "(\\w+)",
21729		S: "(\\d\\d|\\d)",
21730		U: "(.+)",
21731		W: "(\\d\\d|\\d)",
21732		Y: "(\\d{4})",
21733		Z: "(.+)",
21734		d: "(\\d\\d|\\d)",
21735		h: "(\\d\\d|\\d)",
21736		i: "(\\d\\d|\\d)",
21737		j: "(\\d\\d|\\d)",
21738		l: "(\\w+)",
21739		m: "(\\d\\d|\\d)",
21740		n: "(\\d\\d|\\d)",
21741		s: "(\\d\\d|\\d)",
21742		w: "(\\d\\d|\\d)",
21743		y: "(\\d{2})"
21744	},
21745
21746	pad: function pad(number) {
21747		return ("0" + number).slice(-2);
21748	},
21749
21750	/**
21751  * Parses a date(+time) string into a Date object
21752  * @param {String} date the date string, e.g. 2017-02-03 14:45
21753  * @param {String} givenFormat the date format, e.g. Y-m-d H:i
21754  * @param {Boolean}
21754 timeless whether to reset the time of Date object
21755  * @return {Date} the parsed Date object
21756  */
21757	parseDate: function parseDate(date, givenFormat, timeless) {
21758		if (!date) return null;
21759
21760		var date_orig = date;
21761
21762		if (date instanceof Date) {
21763			date = new Date(date.getTime()); // create a copy
21764			date.fp_isUTC = date_orig.fp_isUTC;
21765		} else if (date.toFixed !== undefined) // timestamp
21766			date = new Date(date);else {
21767			// date string
21768			var format = givenFormat || (this.config || Flatpickr.defaultConfig).dateFormat;
21769			date = String(date).trim();
21770
21771			if (date === "today") {
21772				date = new Date();
21773				timeless = true;
21774			} else if (/Z$/.test(date) || /GMT$/.test(date)) // datestrings w/ timezone
21775				date = new Date(date);else if (this.config && this.config.parseDate) date = this.config.parseDate(date, format);else {
21776				var parsedDate = !this.config || !this.config.noCalendar ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0) : new Date(new Date().setHours(0, 0, 0, 0));
21777
21778				var matched = void 0;
21779
21780				for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
21781					var token = format[i];
21782					var isBackSlash = token === "\\";
21783					var escaped = format[i - 1] === "\\" || isBackSlash;
21784
21785					if (this.tokenRegex[token] && !escaped) {
21786						regexStr += this.tokenRegex[token];
21787						var match = new RegExp(regexStr).exec(date);
21788						if (match && (matched = true)) {
21789							parsedDate = this.revFormat[token](parsedDate, match[++matchIndex]) || parsedDate;
21790						}
21791					} else if (!isBackSlash) regexStr += "."; // don't really care
21792				}
21793
21794				date = matched ? parsedDate : null;
21795			}
21796		}
21797
21798		/* istanbul ignore next */
21799		if (!(date instanceof Date)) {
21800			console.warn("flatpickr: invalid date " + date_orig);
21801			console.info(this.element);
21802			return null;
21803		}
21804
21805		if (this.config && this.config.utc && !date.fp_isUTC) date = date.fp_toUTC();
21806
21807		if (timeless === true) date.setHours(0, 0, 0, 0);
21808
21809		return date;
21810	}
21811};
21812
21813/* istanbul ignore next */
21814function _flatpickr(nodeList, config) {
21815	var nodes = Array.prototype.slice.call(nodeList); // static list
21816	var instances = [];
21817	for (var i = 0; i < nodes.length; i++) {
21818		try {
21819			nodes[i]._flatpickr = new Flatpickr(nodes[i], config || {});
21820			instances.push(nodes[i]._flatpickr);
21821		} catch (e) {
21822			console.warn(e, e.stack);
21823		}
21824	}
21825
21826	return instances.length === 1 ? instances[0] : instances;
21827}
21828
21829/* istanbul ignore next */
21830if (typeof HTMLElement !== "undefined") {
21831	// browser env
21832	HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {
21833		return _flatpickr(this, config);
21834	};
21835
21836	HTMLElement.prototype.flatpickr = function (config) {
21837		return _flatpickr([this], config);
21838	};
21839}
21840
21841/* istanbul ignore next */
21842function flatpickr(selector, config) {
21843	return _flatpickr(window.document.querySelectorAll(selector), config);
21844}
21845
21846/* istanbul ignore next */
21847if (typeof jQuery !== "undefined") {
21848	jQuery.fn.flatpickr = function (config) {
21849		return _flatpickr(this, config);
21850	};
21851}
21852
21853Date.prototype.fp_incr = function (days) {
21854	return new Date(this.getFullYear(), this.getMonth(), this.getDate() + parseInt(days, 10));
21855};
21856
21857Date.prototype.fp_isUTC = false;
21858Date.prototype.fp_toUTC = function () {
21859	var newDate = new Date(this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds());
21860
21861	newDate.fp_isUTC = true;
21862	return newDate;
21863};
21864
21865if (typeof module !== "undefined") module.exports = Flatpickr;
21866/* French locals for flatpickr */
21867var Flatpickr = Flatpickr || { l10ns: {} };
21868Flatpickr.l10ns.fr = {};
21869
21870Flatpickr.l10ns.fr.firstDayOfWeek = 1;
21871
21872Flatpickr.l10ns.fr.weekdays = {
21873	shorthand: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"],
21874	longhand: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"]
21875};
21876
21877Flatpickr.l10ns.fr.months = {
21878	shorthand: ["Janv", "Févr", "Mars", "Avr", "Mai", "Juin", "Juil", "Août", "Sept", "Oct", "Nov", "Déc"],
21879	longhand: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
21880};
21881
21882Flatpickr.l10ns.fr.ordinal = function (nth) {
21883	if (nth > 1) return "ème";
21884
21885	return "er";
21886};
21887if (typeof module !== "undefined") module.exports = Flatpickr.l10ns;
21888
21889Flatpickr.l10ns.fr.rangeSeparator = " au ";
vendor: 5,764 bytes, lines 21890-22099
21890Flatpickr.l10ns.fr.weekAbbreviation = "Sem";
21891Flatpickr.l10ns.fr.scrollTitle = "Défiler pour augmenter la valeur";
21892Flatpickr.l10ns.fr.toggleTitle = "Cliquer pour basculer";
21893//! moment.js
21894//! version : 2.29.3
21895//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
21896//! license : MIT
21897//! momentjs.com
21898
21899;(function (global, factory) {
21900    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
21901    typeof define === 'function' && define.amd ? define(factory) :
21902    global.moment = factory()
21903}(this, (function () { 'use strict';
21904
21905    var hookCallback;
21906
21907    function hooks() {
21908        return hookCallback.apply(null, arguments);
21909    }
21910
21911    // This is done to register the method called with moment()
21912    // without creating circular dependencies.
21913    function setHookCallback(callback) {
21914        hookCallback = callback;
21915    }
21916
21917    function isArray(input) {
21918        return (
21919            input instanceof Array ||
21920            Object.prototype.toString.call(input) === '[object Array]'
21921        );
21922    }
21923
21924    function isObject(input) {
21925        // IE8 will treat undefined and null as object if it wasn't for
21926        // input != null
21927        return (
21928            input != null &&
21929            Object.prototype.toString.call(input) === '[object Object]'
21930        );
21931    }
21932
21933    function hasOwnProp(a, b) {
21934        return Object.prototype.hasOwnProperty.call(a, b);
21935    }
21936
21937    function isObjectEmpty(obj) {
21938        if (Object.getOwnPropertyNames) {
21939            return Object.getOwnPropertyNames(obj).length === 0;
21940        } else {
21941            var k;
21942            for (k in obj) {
21943                if (hasOwnProp(obj, k)) {
21944                    return false;
21945                }
21946            }
21947            return true;
21948        }
21949    }
21950
21951    function isUndefined(input) {
21952        return input === void 0;
21953    }
21954
21955    function isNumber(input) {
21956        return (
21957            typeof input === 'number' ||
21958            Object.prototype.toString.call(input) === '[object Number]'
21959        );
21960    }
21961
21962    function isDate(input) {
21963        return (
21964            input instanceof Date ||
21965            Object.prototype.toString.call(input) === '[object Date]'
21966        );
21967    }
21968
21969    function map(arr, fn) {
21970        var res = [],
21971            i,
21972            arrLen = arr.length;
21973        for (i = 0; i < arrLen; ++i) {
21974            res.push(fn(arr[i], i));
21975        }
21976        return res;
21977    }
21978
21979    function extend(a, b) {
21980        for (var i in b) {
21981            if (hasOwnProp(b, i)) {
21982                a[i] = b[i];
21983            }
21984        }
21985
21986        if (hasOwnProp(b, 'toString')) {
21987            a.toString = b.toString;
21988        }
21989
21990        if (hasOwnProp(b, 'valueOf')) {
21991            a.valueOf = b.valueOf;
21992        }
21993
21994        return a;
21995    }
21996
21997    function createUTC(input, format, locale, strict) {
21998        return createLocalOrUTC(input, format, locale, strict, true).utc();
21999    }
22000
22001    function defaultParsingFlags() {
22002        // We need to deep clone this object.
22003        return {
22004            empty: false,
22005            unusedTokens: [],
22006            unusedInput: [],
22007            overflow: -2,
22008            charsLeftOver: 0,
22009            nullInput: false,
22010            invalidEra: null,
22011            invalidMonth: null,
22012            invalidFormat: false,
22013            userInvalidated: false,
22014            iso: false,
22015            parsedDateParts: [],
22016            era: null,
22017            meridiem: null,
22018            rfc2822: false,
22019            weekdayMismatch: false,
22020        };
22021    }
22022
22023    function getParsingFlags(m) {
22024        if (m._pf == null) {
22025            m._pf = defaultParsingFlags();
22026        }
22027        return m._pf;
22028    }
22029
22030    var some;
22031    if (Array.prototype.some) {
22032        some = Array.prototype.some;
22033    } else {
22034        some = function (fun) {
22035            var t = Object(this),
22036                len = t.length >>> 0,
22037                i;
22038
22039            for (i = 0; i < len; i++) {
22040                if (i in t && fun.call(this, t[i], i, t)) {
22041                    return true;
22042                }
22043            }
22044
22045            return false;
22046        };
22047    }
22048
22049    function isValid(m) {
22050        if (m._isValid == null) {
22051            var flags = getParsingFlags(m),
22052                parsedParts = some.call(flags.parsedDateParts, function (i) {
22053                    return i != null;
22054                }),
22055                isNowValid =
22056                    !isNaN(m._d.getTime()) &&
22057                    flags.overflow < 0 &&
22058                    !flags.empty &&
22059                    !flags.invalidEra &&
22060                    !flags.invalidMonth &&
22061                    !flags.invalidWeekday &&
22062                    !flags.weekdayMismatch &&
22063                    !flags.nullInput &&
22064                    !flags.invalidFormat &&
22065                    !flags.userInvalidated &&
22066                    (!flags.meridiem || (flags.meridiem && parsedParts));
22067
22068            if (m._strict) {
22069                isNowValid =
22070                    isNowValid &&
22071                    flags.charsLeftOver === 0 &&
22072                    flags.unusedTokens.length === 0 &&
22073                    flags.bigHour === undefined;
22074            }
22075
22076            if (Object.isFrozen == null || !Object.isFrozen(m)) {
22077                m._isValid = isNowValid;
22078            } else {
22079                return isNowValid;
22080            }
22081        }
22082        return m._isValid;
22083    }
22084
22085    function createInvalid(flags) {
22086        var m = createUTC(NaN);
22087        if (flags != null) {
22088            extend(getParsingFlags(m), flags);
22089        } else {
22090            getParsingFlags(m).userInvalidated = true;
22091        }
22092
22093        return m;
22094    }
22095
22096    // Plugins that add properties should also add the key here (null value),
22097    // so we can properly clone ourselves.
22098    var momentProperties = (hooks.momentProperties = []),
22099        updateInProgress = false;
vendor: 7,422 bytes, lines 22100-22347
22100
22101    function copyConfig(to, from) {
22102        var i,
22103            prop,
22104            val,
22105            momentPropertiesLen = momentProperties.length;
22106
22107        if (!isUndefined(from._isAMomentObject)) {
22108            to._isAMomentObject = from._isAMomentObject;
22109        }
22110        if (!isUndefined(from._i)) {
22111            to._i = from._i;
22112        }
22113        if (!isUndefined(from._f)) {
22114            to._f = from._f;
22115        }
22116        if (!isUndefined(from._l)) {
22117            to._l = from._l;
22118        }
22119        if (!isUndefined(from._strict)) {
22120            to._strict = from._strict;
22121        }
22122        if (!isUndefined(from._tzm)) {
22123            to._tzm = from._tzm;
22124        }
22125        if (!isUndefined(from._isUTC)) {
22126            to._isUTC = from._isUTC;
22127        }
22128        if (!isUndefined(from._offset)) {
22129            to._offset = from._offset;
22130        }
22131        if (!isUndefined(from._pf)) {
22132            to._pf = getParsingFlags(from);
22133        }
22134        if (!isUndefined(from._locale)) {
22135            to._locale = from._locale;
22136        }
22137
22138        if (momentPropertiesLen > 0) {
22139            for (i = 0; i < momentPropertiesLen; i++) {
22140                prop = momentProperties[i];
22141                val = from[prop];
22142                if (!isUndefined(val)) {
22143                    to[prop] = val;
22144                }
22145            }
22146        }
22147
22148        return to;
22149    }
22150
22151    // Moment prototype object
22152    function Moment(config) {
22153        copyConfig(this, config);
22154        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
22155        if (!this.isValid()) {
22156            this._d = new Date(NaN);
22157        }
22158        // Prevent infinite loop in case updateOffset creates new moment
22159        // objects.
22160        if (updateInProgress === false) {
22161            updateInProgress = true;
22162            hooks.updateOffset(this);
22163            updateInProgress = false;
22164        }
22165    }
22166
22167    function isMoment(obj) {
22168        return (
22169            obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
22170        );
22171    }
22172
22173    function warn(msg) {
22174        if (
22175            hooks.suppressDeprecationWarnings === false &&
22176            typeof console !== 'undefined' &&
22177            console.warn
22178        ) {
22179            console.warn('Deprecation warning: ' + msg);
22180        }
22181    }
22182
22183    function deprecate(msg, fn) {
22184        var firstTime = true;
22185
22186        return extend(function () {
22187            if (hooks.deprecationHandler != null) {
22188                hooks.deprecationHandler(null, msg);
22189            }
22190            if (firstTime) {
22191                var args = [],
22192                    arg,
22193                    i,
22194                    key,
22195                    argLen = arguments.length;
22196                for (i = 0; i < argLen; i++) {
22197                    arg = '';
22198                    if (typeof arguments[i] === 'object') {
22199                        arg += '\n[' + i + '] ';
22200                        for (key in arguments[0]) {
22201                            if (hasOwnProp(arguments[0], key)) {
22202                                arg += key + ': ' + arguments[0][key] + ', ';
22203                            }
22204                        }
22205                        arg = arg.slice(0, -2); // Remove trailing comma and space
22206                    } else {
22207                        arg = arguments[i];
22208                    }
22209                    args.push(arg);
22210                }
22211                warn(
22212                    msg +
22213                        '\nArguments: ' +
22214                        Array.prototype.slice.call(args).join('') +
22215                        '\n' +
22216                        new Error().stack
22217                );
22218                firstTime = false;
22219            }
22220            return fn.apply(this, arguments);
22221        }, fn);
22222    }
22223
22224    var deprecations = {};
22225
22226    function deprecateSimple(name, msg) {
22227        if (hooks.deprecationHandler != null) {
22228            hooks.deprecationHandler(name, msg);
22229        }
22230        if (!deprecations[name]) {
22231            warn(msg);
22232            deprecations[name] = true;
22233        }
22234    }
22235
22236    hooks.suppressDeprecationWarnings = false;
22237    hooks.deprecationHandler = null;
22238
22239    function isFunction(input) {
22240        return (
22241            (typeof Function !== 'undefined' && input instanceof Function) ||
22242            Object.prototype.toString.call(input) === '[object Function]'
22243        );
22244    }
22245
22246    function set(config) {
22247        var prop, i;
22248        for (i in config) {
22249            if (hasOwnProp(config, i)) {
22250                prop = config[i];
22251                if (isFunction(prop)) {
22252                    this[i] = prop;
22253                } else {
22254                    this['_' + i] = prop;
22255                }
22256            }
22257        }
22258        this._config = config;
22259        // Lenient ordinal parsing accepts just a number in addition to
22260        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
22261        // TODO: Remove "ordinalParse" fallback in next major release.
22262        this._dayOfMonthOrdinalParseLenient = new RegExp(
22263            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
22264                '|' +
22265                /\d{1,2}/.source
22266        );
22267    }
22268
22269    function mergeConfigs(parentConfig, childConfig) {
22270        var res = extend({}, parentConfig),
22271            prop;
22272        for (prop in childConfig) {
22273            if (hasOwnProp(childConfig, prop)) {
22274                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
22275                    res[prop] = {};
22276                    extend(res[prop], parentConfig[prop]);
22277                    extend(res[prop], childConfig[prop]);
22278                } else if (childConfig[prop] != null) {
22279                    res[prop] = childConfig[prop];
22280                } else {
22281                    delete res[prop];
22282                }
22283            }
22284        }
22285        for (prop in parentConfig) {
22286            if (
22287                hasOwnProp(parentConfig, prop) &&
22288                !hasOwnProp(childConfig, prop) &&
22289                isObject(parentConfig[prop])
22290            ) {
22291                // make sure changes to properties don't modify parent config
22292                res[prop] = extend({}, res[prop]);
22293            }
22294        }
22295        return res;
22296    }
22297
22298    function Locale(config) {
22299        if (config != null) {
22300            this.set(config);
22301        }
22302    }
22303
22304    var keys;
22305
22306    if (Object.keys) {
22307        keys = Object.keys;
22308    } else {
22309        keys = function (obj) {
22310            var i,
22311                res = [];
22312            for (i in obj) {
22313                if (hasOwnProp(obj, i)) {
22314                    res.push(i);
22315                }
22316            }
22317            return res;
22318        };
22319    }
22320
22321    var defaultCalendar = {
22322        sameDay: '[Today at] LT',
22323        nextDay: '[Tomorrow at] LT',
22324        nextWeek: 'dddd [at] LT',
22325        lastDay: '[Yesterday at] LT',
22326        lastWeek: '[Last] dddd [at] LT',
22327        sameElse: 'L',
22328    };
22329
22330    function calendar(key, mom, now) {
22331        var output = this._calendar[key] || this._calendar['sameElse'];
22332        return isFunction(output) ? output.call(mom, now) : output;
22333    }
22334
22335    function zeroFill(number, targetLength, forceSign) {
22336        var absNumber = '' + Math.abs(number),
22337            zerosToFill = targetLength - absNumber.length,
22338            sign = number >= 0;
22339        return (
22340            (sign ? (forceSign ? '+' : '') : '-') +
22341            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
22342            absNumber
22343        );
22344    }
22345
22346    var formattingTokens =
22347           
vendor: 8,563 bytes, lines 22347-22651
22347 /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
22348        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
22349        formatFunctions = {},
22350        formatTokenFunctions = {};
22351
22352    // token:    'M'
22353    // padded:   ['MM', 2]
22354    // ordinal:  'Mo'
22355    // callback: function () { this.month() + 1 }
22356    function addFormatToken(token, padded, ordinal, callback) {
22357        var func = callback;
22358        if (typeof callback === 'string') {
22359            func = function () {
22360                return this[callback]();
22361            };
22362        }
22363        if (token) {
22364            formatTokenFunctions[token] = func;
22365        }
22366        if (padded) {
22367            formatTokenFunctions[padded[0]] = function () {
22368                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
22369            };
22370        }
22371        if (ordinal) {
22372            formatTokenFunctions[ordinal] = function () {
22373                return this.localeData().ordinal(
22374                    func.apply(this, arguments),
22375                    token
22376                );
22377            };
22378        }
22379    }
22380
22381    function removeFormattingTokens(input) {
22382        if (input.match(/\[[\s\S]/)) {
22383            return input.replace(/^\[|\]$/g, '');
22384        }
22385        return input.replace(/\\/g, '');
22386    }
22387
22388    function makeFormatFunction(format) {
22389        var array = format.match(formattingTokens),
22390            i,
22391            length;
22392
22393        for (i = 0, length = array.length; i < length; i++) {
22394            if (formatTokenFunctions[array[i]]) {
22395                array[i] = formatTokenFunctions[array[i]];
22396            } else {
22397                array[i] = removeFormattingTokens(array[i]);
22398            }
22399        }
22400
22401        return function (mom) {
22402            var output = '',
22403                i;
22404            for (i = 0; i < length; i++) {
22405                output += isFunction(array[i])
22406                    ? array[i].call(mom, format)
22407                    : array[i];
22408            }
22409            return output;
22410        };
22411    }
22412
22413    // format date using native date object
22414    function formatMoment(m, format) {
22415        if (!m.isValid()) {
22416            return m.localeData().invalidDate();
22417        }
22418
22419        format = expandFormat(format, m.localeData());
22420        formatFunctions[format] =
22421            formatFunctions[format] || makeFormatFunction(format);
22422
22423        return formatFunctions[format](m);
22424    }
22425
22426    function expandFormat(format, locale) {
22427        var i = 5;
22428
22429        function replaceLongDateFormatTokens(input) {
22430            return locale.longDateFormat(input) || input;
22431        }
22432
22433        localFormattingTokens.lastIndex = 0;
22434        while (i >= 0 && localFormattingTokens.test(format)) {
22435            format = format.replace(
22436                localFormattingTokens,
22437                replaceLongDateFormatTokens
22438            );
22439            localFormattingTokens.lastIndex = 0;
22440            i -= 1;
22441        }
22442
22443        return format;
22444    }
22445
22446    var defaultLongDateFormat = {
22447        LTS: 'h:mm:ss A',
22448        LT: 'h:mm A',
22449        L: 'MM/DD/YYYY',
22450        LL: 'MMMM D, YYYY',
22451        LLL: 'MMMM D, YYYY h:mm A',
22452        LLLL: 'dddd, MMMM D, YYYY h:mm A',
22453    };
22454
22455    function longDateFormat(key) {
22456        var format = this._longDateFormat[key],
22457            formatUpper = this._longDateFormat[key.toUpperCase()];
22458
22459        if (format || !formatUpper) {
22460            return format;
22461        }
22462
22463        this._longDateFormat[key] = formatUpper
22464            .match(formattingTokens)
22465            .map(function (tok) {
22466                if (
22467                    tok === 'MMMM' ||
22468                    tok === 'MM' ||
22469                    tok === 'DD' ||
22470                    tok === 'dddd'
22471                ) {
22472                    return tok.slice(1);
22473                }
22474                return tok;
22475            })
22476            .join('');
22477
22478        return this._longDateFormat[key];
22479    }
22480
22481    var defaultInvalidDate = 'Invalid date';
22482
22483    function invalidDate() {
22484        return this._invalidDate;
22485    }
22486
22487    var defaultOrdinal = '%d',
22488        defaultDayOfMonthOrdinalParse = /\d{1,2}/;
22489
22490    function ordinal(number) {
22491        return this._ordinal.replace('%d', number);
22492    }
22493
22494    var defaultRelativeTime = {
22495        future: 'in %s',
22496        past: '%s ago',
22497        s: 'a few seconds',
22498        ss: '%d seconds',
22499        m: 'a minute',
22500        mm: '%d minutes',
22501        h: 'an hour',
22502        hh: '%d hours',
22503        d: 'a day',
22504        dd: '%d days',
22505        w: 'a week',
22506        ww: '%d weeks',
22507        M: 'a month',
22508        MM: '%d months',
22509        y: 'a year',
22510        yy: '%d years',
22511    };
22512
22513    function relativeTime(number, withoutSuffix, string, isFuture) {
22514        var output = this._relativeTime[string];
22515        return isFunction(output)
22516            ? output(number, withoutSuffix, string, isFuture)
22517            : output.replace(/%d/i, number);
22518    }
22519
22520    function pastFuture(diff, output) {
22521        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
22522        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
22523    }
22524
22525    var aliases = {};
22526
22527    function addUnitAlias(unit, shorthand) {
22528        var lowerCase = unit.toLowerCase();
22529        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
22530    }
22531
22532    function normalizeUnits(units) {
22533        return typeof units === 'string'
22534            ? aliases[units] || aliases[units.toLowerCase()]
22535            : undefined;
22536    }
22537
22538    function normalizeObjectUnits(inputObject) {
22539        var normalizedInput = {},
22540            normalizedProp,
22541            prop;
22542
22543        for (prop in inputObject) {
22544            if (hasOwnProp(inputObject, prop)) {
22545                normalizedProp = normalizeUnits(prop);
22546                if (normalizedProp) {
22547                    normalizedInput[normalizedProp] = inputObject[prop];
22548                }
22549            }
22550        }
22551
22552        return normalizedInput;
22553    }
22554
22555    var priorities = {};
22556
22557    function addUnitPriority(unit, priority) {
22558        priorities[unit] = priority;
22559    }
22560
22561    function getPrioritizedUnits(unitsObj) {
22562        var units = [],
22563            u;
22564        for (u in unitsObj) {
22565            if (hasOwnProp(unitsObj, u)) {
22566                units.push({ unit: u, priority: priorities[u] });
22567            }
22568        }
22569        units.sort(function (a, b) {
22570            return a.priority - b.priority;
22571        });
22572        return units;
22573    }
22574
22575    function isLeapYear(year) {
22576        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
22577    }
22578
22579    function absFloor(number) {
22580        if (number < 0) {
22581            // -0 -> 0
22582            return Math.ceil(number) || 0;
22583        } else {
22584            return Math.floor(number);
22585        }
22586    }
22587
22588    function toInt(argumentForCoercion) {
22589        var coercedNumber = +argumentForCoercion,
22590            value = 0;
22591
22592        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
22593            value = absFloor(coercedNumber);
22594        }
22595
22596        return value;
22597    }
22598
22599    function makeGetSet(unit, keepTime) {
22600        return function (value) {
22601            if (value != null) {
22602                set$1(this, unit, value);
22603                hooks.updateOffset(this, keepTime);
22604                return this;
22605            } else {
22606                return get(this, unit);
22607            }
22608        };
22609    }
22610
22611    function get(mom, unit) {
22612        return mom.isValid()
22613            ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
22614            : NaN;
22615    }
22616
22617    function set$1(mom, unit, value) {
22618        if (mom.isValid() && !isNaN(value)) {
22619            if (
22620                unit === 'FullYear' &&
22621                isLeapYear(mom.year()) &&
22622                mom.month() === 1 &&
22623                mom.date() === 29
22624            ) {
22625                value = toInt(value);
22626                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
22627                    value,
22628                    mom.month(),
22629                    daysInMonth(value, mom.month())
22630                );
22631            } else {
22632                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
22633            }
22634        }
22635    }
22636
22637    // MOMENTS
22638
22639    function stringGet(units) {
22640        units = normalizeUnits(units);
22641        if (isFunction(this[units])) {
22642            return this[units]();
22643        }
22644        return this;
22645    }
22646
22647    function stringSet(units, value) {
22648        if (typeof units === 'object') {
22649            units = normalizeObjectUnits(units);
22650            var prioritized = getPrioritizedUnits(units),
22651                i
vendor: 5,547 bytes, lines 22651-22837
22651,
22652                prioritizedLen = prioritized.length;
22653            for (i = 0; i < prioritizedLen; i++) {
22654                this[prioritized[i].unit](units[prioritized[i].unit]);
22655            }
22656        } else {
22657            units = normalizeUnits(units);
22658            if (isFunction(this[units])) {
22659                return this[units](value);
22660            }
22661        }
22662        return this;
22663    }
22664
22665    var match1 = /\d/, //       0 - 9
22666        match2 = /\d\d/, //      00 - 99
22667        match3 = /\d{3}/, //     000 - 999
22668        match4 = /\d{4}/, //    0000 - 9999
22669        match6 = /[+-]?\d{6}/, // -999999 - 999999
22670        match1to2 = /\d\d?/, //       0 - 99
22671        match3to4 = /\d\d\d\d?/, //     999 - 9999
22672        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
22673        match1to3 = /\d{1,3}/, //       0 - 999
22674        match1to4 = /\d{1,4}/, //       0 - 9999
22675        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
22676        matchUnsigned = /\d+/, //       0 - inf
22677        matchSigned = /[+-]?\d+/, //    -inf - inf
22678        matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
22679        matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
22680        matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
22681        // any word (or two) characters or numbers including two/three word month in arabic.
22682        // includes scottish gaelic two word and hyphenated months
22683        matchWord =
22684            /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,
22685        regexes;
22686
22687    regexes = {};
22688
22689    function addRegexToken(token, regex, strictRegex) {
22690        regexes[token] = isFunction(regex)
22691            ? regex
22692            : function (isStrict, localeData) {
22693                  return isStrict && strictRegex ? strictRegex : regex;
22694              };
22695    }
22696
22697    function getParseRegexForToken(token, config) {
22698        if (!hasOwnProp(regexes, token)) {
22699            return new RegExp(unescapeFormat(token));
22700        }
22701
22702        return regexes[token](config._strict, config._locale);
22703    }
22704
22705    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
22706    function unescapeFormat(s) {
22707        return regexEscape(
22708            s
22709                .replace('\\', '')
22710                .replace(
22711                    /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,
22712                    function (matched, p1, p2, p3, p4) {
22713                        return p1 || p2 || p3 || p4;
22714                    }
22715                )
22716        );
22717    }
22718
22719    function regexEscape(s) {
22720        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
22721    }
22722
22723    var tokens = {};
22724
22725    function addParseToken(token, callback) {
22726        var i,
22727            func = callback,
22728            tokenLen;
22729        if (typeof token === 'string') {
22730            token = [token];
22731        }
22732        if (isNumber(callback)) {
22733            func = function (input, array) {
22734                array[callback] = toInt(input);
22735            };
22736        }
22737        tokenLen = token.length;
22738        for (i = 0; i < tokenLen; i++) {
22739            tokens[token[i]] = func;
22740        }
22741    }
22742
22743    function addWeekParseToken(token, callback) {
22744        addParseToken(token, function (input, array, config, token) {
22745            config._w = config._w || {};
22746            callback(input, config._w, config, token);
22747        });
22748    }
22749
22750    function addTimeToArrayFromToken(token, input, config) {
22751        if (input != null && hasOwnProp(tokens, token)) {
22752            tokens[token](input, config._a, config, token);
22753        }
22754    }
22755
22756    var YEAR = 0,
22757        MONTH = 1,
22758        DATE = 2,
22759        HOUR = 3,
22760        MINUTE = 4,
22761        SECOND = 5,
22762        MILLISECOND = 6,
22763        WEEK = 7,
22764        WEEKDAY = 8;
22765
22766    function mod(n, x) {
22767        return ((n % x) + x) % x;
22768    }
22769
22770    var indexOf;
22771
22772    if (Array.prototype.indexOf) {
22773        indexOf = Array.prototype.indexOf;
22774    } else {
22775        indexOf = function (o) {
22776            // I know
22777            var i;
22778            for (i = 0; i < this.length; ++i) {
22779                if (this[i] === o) {
22780                    return i;
22781                }
22782            }
22783            return -1;
22784        };
22785    }
22786
22787    function daysInMonth(year, month) {
22788        if (isNaN(year) || isNaN(month)) {
22789            return NaN;
22790        }
22791        var modMonth = mod(month, 12);
22792        year += (month - modMonth) / 12;
22793        return modMonth === 1
22794            ? isLeapYear(year)
22795                ? 29
22796                : 28
22797            : 31 - ((modMonth % 7) % 2);
22798    }
22799
22800    // FORMATTING
22801
22802    addFormatToken('M', ['MM', 2], 'Mo', function () {
22803        return this.month() + 1;
22804    });
22805
22806    addFormatToken('MMM', 0, 0, function (format) {
22807        return this.localeData().monthsShort(this, format);
22808    });
22809
22810    addFormatToken('MMMM', 0, 0, function (format) {
22811        return this.localeData().months(this, format);
22812    });
22813
22814    // ALIASES
22815
22816    addUnitAlias('month', 'M');
22817
22818    // PRIORITY
22819
22820    addUnitPriority('month', 8);
22821
22822    // PARSING
22823
22824    addRegexToken('M', match1to2);
22825    addRegexToken('MM', match1to2, match2);
22826    addRegexToken('MMM', function (isStrict, locale) {
22827        return locale.monthsShortRegex(isStrict);
22828    });
22829    addRegexToken('MMMM', function (isStrict, locale) {
22830        return locale.monthsRegex(isStrict);
22831    });
22832
22833    addParseToken(['M', 'MM'], function (input, array) {
22834        array[MONTH] = toInt(input) - 1;
22835    });
22836
22837    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
22838        var month = config._locale.monthsParse(input, token, config._strict);
22839        // if we didn't find a month name, mark the date as invalid.
22840        if (month != null) {
22841            array[MONTH] = month;
22842        } else {
22843            getParsingFlags(config).invalidMonth = input;
22844        }
22845    });
22846
22847    // LOCALES
22848
22849    var defaultLocaleMonths =
22850            'January_February_March_April_May_June_July_August_September_October_November_December'.split(
22851                '_'
22852            ),
22853        defaultLocaleMonthsShort =
22854            'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'
vendor: 13,773 bytes, lines 22854-23296
22854),
22855        MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
22856        defaultMonthsShortRegex = matchWord,
22857        defaultMonthsRegex = matchWord;
22858
22859    function localeMonths(m, format) {
22860        if (!m) {
22861            return isArray(this._months)
22862                ? this._months
22863                : this._months['standalone'];
22864        }
22865        return isArray(this._months)
22866            ? this._months[m.month()]
22867            : this._months[
22868                  (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
22869                      ? 'format'
22870                      : 'standalone'
22871              ][m.month()];
22872    }
22873
22874    function localeMonthsShort(m, format) {
22875        if (!m) {
22876            return isArray(this._monthsShort)
22877                ? this._monthsShort
22878                : this._monthsShort['standalone'];
22879        }
22880        return isArray(this._monthsShort)
22881            ? this._monthsShort[m.month()]
22882            : this._monthsShort[
22883                  MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
22884              ][m.month()];
22885    }
22886
22887    function handleStrictParse(monthName, format, strict) {
22888        var i,
22889            ii,
22890            mom,
22891            llc = monthName.toLocaleLowerCase();
22892        if (!this._monthsParse) {
22893            // this is not used
22894            this._monthsParse = [];
22895            this._longMonthsParse = [];
22896            this._shortMonthsParse = [];
22897            for (i = 0; i < 12; ++i) {
22898                mom = createUTC([2000, i]);
22899                this._shortMonthsParse[i] = this.monthsShort(
22900                    mom,
22901                    ''
22902                ).toLocaleLowerCase();
22903                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
22904            }
22905        }
22906
22907        if (strict) {
22908            if (format === 'MMM') {
22909                ii = indexOf.call(this._shortMonthsParse, llc);
22910                return ii !== -1 ? ii : null;
22911            } else {
22912                ii = indexOf.call(this._longMonthsParse, llc);
22913                return ii !== -1 ? ii : null;
22914            }
22915        } else {
22916            if (format === 'MMM') {
22917                ii = indexOf.call(this._shortMonthsParse, llc);
22918                if (ii !== -1) {
22919                    return ii;
22920                }
22921                ii = indexOf.call(this._longMonthsParse, llc);
22922                return ii !== -1 ? ii : null;
22923            } else {
22924                ii = indexOf.call(this._longMonthsParse, llc);
22925                if (ii !== -1) {
22926                    return ii;
22927                }
22928                ii = indexOf.call(this._shortMonthsParse, llc);
22929                return ii !== -1 ? ii : null;
22930            }
22931        }
22932    }
22933
22934    function localeMonthsParse(monthName, format, strict) {
22935        var i, mom, regex;
22936
22937        if (this._monthsParseExact) {
22938            return handleStrictParse.call(this, monthName, format, strict);
22939        }
22940
22941        if (!this._monthsParse) {
22942            this._monthsParse = [];
22943            this._longMonthsParse = [];
22944            this._shortMonthsParse = [];
22945        }
22946
22947        // TODO: add sorting
22948        // Sorting makes sure if one month (or abbr) is a prefix of another
22949        // see sorting in computeMonthsParse
22950        for (i = 0; i < 12; i++) {
22951            // make the regex if we don't have it already
22952            mom = createUTC([2000, i]);
22953            if (strict && !this._longMonthsParse[i]) {
22954                this._longMonthsParse[i] = new RegExp(
22955                    '^' + this.months(mom, '').replace('.', '') + '$',
22956                    'i'
22957                );
22958                this._shortMonthsParse[i] = new RegExp(
22959                    '^' + this.monthsShort(mom, '').replace('.', '') + '$',
22960                    'i'
22961                );
22962            }
22963            if (!strict && !this._monthsParse[i]) {
22964                regex =
22965                    '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
22966                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
22967            }
22968            // test the regex
22969            if (
22970                strict &&
22971                format === 'MMMM' &&
22972                this._longMonthsParse[i].test(monthName)
22973            ) {
22974                return i;
22975            } else if (
22976                strict &&
22977                format === 'MMM' &&
22978                this._shortMonthsParse[i].test(monthName)
22979            ) {
22980                return i;
22981            } else if (!strict && this._monthsParse[i].test(monthName)) {
22982                return i;
22983            }
22984        }
22985    }
22986
22987    // MOMENTS
22988
22989    function setMonth(mom, value) {
22990        var dayOfMonth;
22991
22992        if (!mom.isValid()) {
22993            // No op
22994            return mom;
22995        }
22996
22997        if (typeof value === 'string') {
22998            if (/^\d+$/.test(value)) {
22999                value = toInt(value);
23000            } else {
23001                value = mom.localeData().monthsParse(value);
23002                // TODO: Another silent failure?
23003                if (!isNumber(value)) {
23004                    return mom;
23005                }
23006            }
23007        }
23008
23009        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
23010        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
23011        return mom;
23012    }
23013
23014    function getSetMonth(value) {
23015        if (value != null) {
23016            setMonth(this, value);
23017            hooks.updateOffset(this, true);
23018            return this;
23019        } else {
23020            return get(this, 'Month');
23021        }
23022    }
23023
23024    function getDaysInMonth() {
23025        return daysInMonth(this.year(), this.month());
23026    }
23027
23028    function monthsShortRegex(isStrict) {
23029        if (this._monthsParseExact) {
23030            if (!hasOwnProp(this, '_monthsRegex')) {
23031                computeMonthsParse.call(this);
23032            }
23033            if (isStrict) {
23034                return this._monthsShortStrictRegex;
23035            } else {
23036                return this._monthsShortRegex;
23037            }
23038        } else {
23039            if (!hasOwnProp(this, '_monthsShortRegex')) {
23040                this._monthsShortRegex = defaultMonthsShortRegex;
23041            }
23042            return this._monthsShortStrictRegex && isStrict
23043                ? this._monthsShortStrictRegex
23044                : this._monthsShortRegex;
23045        }
23046    }
23047
23048    function monthsRegex(isStrict) {
23049        if (this._monthsParseExact) {
23050            if (!hasOwnProp(this, '_monthsRegex')) {
23051                computeMonthsParse.call(this);
23052            }
23053            if (isStrict) {
23054                return this._monthsStrictRegex;
23055            } else {
23056                return this._monthsRegex;
23057            }
23058        } else {
23059            if (!hasOwnProp(this, '_monthsRegex')) {
23060                this._monthsRegex = defaultMonthsRegex;
23061            }
23062            return this._monthsStrictRegex && isStrict
23063                ? this._monthsStrictRegex
23064                : this._monthsRegex;
23065        }
23066    }
23067
23068    function computeMonthsParse() {
23069        function cmpLenRev(a, b) {
23070            return b.length - a.length;
23071        }
23072
23073        var shortPieces = [],
23074            longPieces = [],
23075            mixedPieces = [],
23076            i,
23077            mom;
23078        for (i = 0; i < 12; i++) {
23079            // make the regex if we don't have it already
23080            mom = createUTC([2000, i]);
23081            shortPieces.push(this.monthsShort(mom, ''));
23082            longPieces.push(this.months(mom, ''));
23083            mixedPieces.push(this.months(mom, ''));
23084            mixedPieces.push(this.monthsShort(mom, ''));
23085        }
23086        // Sorting makes sure if one month (or abbr) is a prefix of another it
23087        // will match the longer piece.
23088        shortPieces.sort(cmpLenRev);
23089        longPieces.sort(cmpLenRev);
23090        mixedPieces.sort(cmpLenRev);
23091        for (i = 0; i < 12; i++) {
23092            shortPieces[i] = regexEscape(shortPieces[i]);
23093            longPieces[i] = regexEscape(longPieces[i]);
23094        }
23095        for (i = 0; i < 24; i++) {
23096            mixedPieces[i] = regexEscape(mixedPieces[i]);
23097        }
23098
23099        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
23100        this._monthsShortRegex = this._monthsRegex;
23101        this._monthsStrictRegex = new RegExp(
23102            '^(' + longPieces.join('|') + ')',
23103            'i'
23104        );
23105        this._monthsShortStrictRegex = new RegExp(
23106            '^(' + shortPieces.join('|') + ')',
23107            'i'
23108        );
23109    }
23110
23111    // FORMATTING
23112
23113    addFormatToken('Y', 0, 0, function () {
23114        var y = this.year();
23115        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
23116    });
23117
23118    addFormatToken(0, ['YY', 2], 0, function () {
23119        return this.year() % 100;
23120    });
23121
23122    addFormatToken(0, ['YYYY', 4], 0, 'year');
23123    addFormatToken(0, ['YYYYY', 5], 0, 'year');
23124    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
23125
23126    // ALIASES
23127
23128    addUnitAlias('year', 'y');
23129
23130    // PRIORITIES
23131
23132    addUnitPriority('year', 1);
23133
23134    // PARSING
23135
23136    addRegexToken('Y', matchSigned);
23137    addRegexToken('YY', match1to2, match2);
23138    addRegexToken('YYYY', match1to4, match4);
23139    addRegexToken('YYYYY', match1to6, match6);
23140    addRegexToken('YYYYYY', match1to6, match6);
23141
23142    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
23143    addParseToken('YYYY', function (input, array) {
23144        array[YEAR] =
23145            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
23146    });
23147    addParseToken('YY', function (input, array) {
23148        array[YEAR] = hooks.parseTwoDigitYear(input);
23149    });
23150    addParseToken('Y', function (input, array) {
23151        array[YEAR] = parseInt(input, 10);
23152    });
23153
23154    // HELPERS
23155
23156    function daysInYear(year) {
23157        return isLeapYear(year) ? 366 : 365;
23158    }
23159
23160    // HOOKS
23161
23162    hooks.parseTwoDigitYear = function (input) {
23163        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
23164    };
23165
23166    // MOMENTS
23167
23168    var getSetYear = makeGetSet('FullYear', true);
23169
23170    function getIsLeapYear() {
23171        return isLeapYear(this.year());
23172    }
23173
23174    function createDate(y, m, d, h, M, s, ms) {
23175        // can't just apply() to create a date:
23176        // https://stackoverflow.com/q/181348
23177        var date;
23178        // the date constructor remaps years 0-99 to 1900-1999
23179        if (y < 100 && y >= 0) {
23180            // preserve leap years using a full 400 year cycle, then reset
23181            date = new Date(y + 400, m, d, h, M, s, ms);
23182            if (isFinite(date.getFullYear())) {
23183                date.setFullYear(y);
23184            }
23185        } else {
23186            date = new Date(y, m, d, h, M, s, ms);
23187        }
23188
23189        return date;
23190    }
23191
23192    function createUTCDate(y) {
23193        var date, args;
23194        // the Date.UTC function remaps years 0-99 to 1900-1999
23195        if (y < 100 && y >= 0) {
23196            args = Array.prototype.slice.call(arguments);
23197            // preserve leap years using a full 400 year cycle, then reset
23198            args[0] = y + 400;
23199            date = new Date(Date.UTC.apply(null, args));
23200            if (isFinite(date.getUTCFullYear())) {
23201                date.setUTCFullYear(y);
23202            }
23203        } else {
23204            date = new Date(Date.UTC.apply(null, arguments));
23205        }
23206
23207        return date;
23208    }
23209
23210    // start-of-first-week - start-of-year
23211    function firstWeekOffset(year, dow, doy) {
23212        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
23213            fwd = 7 + dow - doy,
23214            // first-week day local weekday -- which local weekday is fwd
23215            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
23216
23217        return -fwdlw + fwd - 1;
23218    }
23219
23220    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
23221    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
23222        var localWeekday = (7 + weekday - dow) % 7,
23223            weekOffset = firstWeekOffset(year, dow, doy),
23224            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
23225            resYear,
23226            resDayOfYear;
23227
23228        if (dayOfYear <= 0) {
23229            resYear = year - 1;
23230            resDayOfYear = daysInYear(resYear) + dayOfYear;
23231        } else if (dayOfYear > daysInYear(year)) {
23232            resYear = year + 1;
23233            resDayOfYear = dayOfYear - daysInYear(year);
23234        } else {
23235            resYear = year;
23236            resDayOfYear = dayOfYear;
23237        }
23238
23239        return {
23240            year: resYear,
23241            dayOfYear: resDayOfYear,
23242        };
23243    }
23244
23245    function weekOfYear(mom, dow, doy) {
23246        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
23247            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
23248            resWeek,
23249            resYear;
23250
23251        if (week < 1) {
23252            resYear = mom.year() - 1;
23253            resWeek = week + weeksInYear(resYear, dow, doy);
23254        } else if (week > weeksInYear(mom.year(), dow, doy)) {
23255            resWeek = week - weeksInYear(mom.year(), dow, doy);
23256            resYear = mom.year() + 1;
23257        } else {
23258            resYear = mom.year();
23259            resWeek = week;
23260        }
23261
23262        return {
23263            week: resWeek,
23264            year: resYear,
23265        };
23266    }
23267
23268    function weeksInYear(year, dow, doy) {
23269        var weekOffset = firstWeekOffset(year, dow, doy),
23270            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
23271        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
23272    }
23273
23274    // FORMATTING
23275
23276    addFormatToken('w', ['ww', 2], 'wo', 'week');
23277    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
23278
23279    // ALIASES
23280
23281    addUnitAlias('week', 'w');
23282    addUnitAlias('isoWeek', 'W');
23283
23284    // PRIORITIES
23285
23286    addUnitPriority('week', 5);
23287    addUnitPriority('isoWeek', 5);
23288
23289    // PARSING
23290
23291    addRegexToken('w', match1to2);
23292    addRegexToken('ww', match1to2, match2);
23293    addRegexToken('W', match1to2);
23294    addRegexToken('WW', match1to2, match2);
23295
23296    addWeekParseToken(
vendor: 3,487 bytes, lines 23296-23427
23296
23297        ['w', 'ww', 'W', 'WW'],
23298        function (input, week, config, token) {
23299            week[token.substr(0, 1)] = toInt(input);
23300        }
23301    );
23302
23303    // HELPERS
23304
23305    // LOCALES
23306
23307    function localeWeek(mom) {
23308        return weekOfYear(mom, this._week.dow, this._week.doy).week;
23309    }
23310
23311    var defaultLocaleWeek = {
23312        dow: 0, // Sunday is the first day of the week.
23313        doy: 6, // The week that contains Jan 6th is the first week of the year.
23314    };
23315
23316    function localeFirstDayOfWeek() {
23317        return this._week.dow;
23318    }
23319
23320    function localeFirstDayOfYear() {
23321        return this._week.doy;
23322    }
23323
23324    // MOMENTS
23325
23326    function getSetWeek(input) {
23327        var week = this.localeData().week(this);
23328        return input == null ? week : this.add((input - week) * 7, 'd');
23329    }
23330
23331    function getSetISOWeek(input) {
23332        var week = weekOfYear(this, 1, 4).week;
23333        return input == null ? week : this.add((input - week) * 7, 'd');
23334    }
23335
23336    // FORMATTING
23337
23338    addFormatToken('d', 0, 'do', 'day');
23339
23340    addFormatToken('dd', 0, 0, function (format) {
23341        return this.localeData().weekdaysMin(this, format);
23342    });
23343
23344    addFormatToken('ddd', 0, 0, function (format) {
23345        return this.localeData().weekdaysShort(this, format);
23346    });
23347
23348    addFormatToken('dddd', 0, 0, function (format) {
23349        return this.localeData().weekdays(this, format);
23350    });
23351
23352    addFormatToken('e', 0, 0, 'weekday');
23353    addFormatToken('E', 0, 0, 'isoWeekday');
23354
23355    // ALIASES
23356
23357    addUnitAlias('day', 'd');
23358    addUnitAlias('weekday', 'e');
23359    addUnitAlias('isoWeekday', 'E');
23360
23361    // PRIORITY
23362    addUnitPriority('day', 11);
23363    addUnitPriority('weekday', 11);
23364    addUnitPriority('isoWeekday', 11);
23365
23366    // PARSING
23367
23368    addRegexToken('d', match1to2);
23369    addRegexToken('e', match1to2);
23370    addRegexToken('E', match1to2);
23371    addRegexToken('dd', function (isStrict, locale) {
23372        return locale.weekdaysMinRegex(isStrict);
23373    });
23374    addRegexToken('ddd', function (isStrict, locale) {
23375        return locale.weekdaysShortRegex(isStrict);
23376    });
23377    addRegexToken('dddd', function (isStrict, locale) {
23378        return locale.weekdaysRegex(isStrict);
23379    });
23380
23381    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
23382        var weekday = config._locale.weekdaysParse(input, token, config._strict);
23383        // if we didn't get a weekday name, mark the date as invalid
23384        if (weekday != null) {
23385            week.d = weekday;
23386        } else {
23387            getParsingFlags(config).invalidWeekday = input;
23388        }
23389    });
23390
23391    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
23392        week[token] = toInt(input);
23393    });
23394
23395    // HELPERS
23396
23397    function parseWeekday(input, locale) {
23398        if (typeof input !== 'string') {
23399            return input;
23400        }
23401
23402        if (!isNaN(input)) {
23403            return parseInt(input, 10);
23404        }
23405
23406        input = locale.weekdaysParse(input);
23407        if (typeof input === 'number') {
23408            return input;
23409        }
23410
23411        return null;
23412    }
23413
23414    function parseIsoWeekday(input, locale) {
23415        if (typeof input === 'string') {
23416            return locale.weekdaysParse(input) % 7 || 7;
23417        }
23418        return isNaN(input) ? null : input;
23419    }
23420
23421    // LOCALES
23422    function shiftWeekdays(ws, n) {
23423        return ws.slice(n, 7).concat(ws.slice(0, n));
23424    }
23425
23426    var defaultLocaleWeekdays =
23427            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'
vendor: 17,864 bytes, lines 23427-23975
23427),
23428        defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
23429        defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
23430        defaultWeekdaysRegex = matchWord,
23431        defaultWeekdaysShortRegex = matchWord,
23432        defaultWeekdaysMinRegex = matchWord;
23433
23434    function localeWeekdays(m, format) {
23435        var weekdays = isArray(this._weekdays)
23436            ? this._weekdays
23437            : this._weekdays[
23438                  m && m !== true && this._weekdays.isFormat.test(format)
23439                      ? 'format'
23440                      : 'standalone'
23441              ];
23442        return m === true
23443            ? shiftWeekdays(weekdays, this._week.dow)
23444            : m
23445            ? weekdays[m.day()]
23446            : weekdays;
23447    }
23448
23449    function localeWeekdaysShort(m) {
23450        return m === true
23451            ? shiftWeekdays(this._weekdaysShort, this._week.dow)
23452            : m
23453            ? this._weekdaysShort[m.day()]
23454            : this._weekdaysShort;
23455    }
23456
23457    function localeWeekdaysMin(m) {
23458        return m === true
23459            ? shiftWeekdays(this._weekdaysMin, this._week.dow)
23460            : m
23461            ? this._weekdaysMin[m.day()]
23462            : this._weekdaysMin;
23463    }
23464
23465    function handleStrictParse$1(weekdayName, format, strict) {
23466        var i,
23467            ii,
23468            mom,
23469            llc = weekdayName.toLocaleLowerCase();
23470        if (!this._weekdaysParse) {
23471            this._weekdaysParse = [];
23472            this._shortWeekdaysParse = [];
23473            this._minWeekdaysParse = [];
23474
23475            for (i = 0; i < 7; ++i) {
23476                mom = createUTC([2000, 1]).day(i);
23477                this._minWeekdaysParse[i] = this.weekdaysMin(
23478                    mom,
23479                    ''
23480                ).toLocaleLowerCase();
23481                this._shortWeekdaysParse[i] = this.weekdaysShort(
23482                    mom,
23483                    ''
23484                ).toLocaleLowerCase();
23485                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
23486            }
23487        }
23488
23489        if (strict) {
23490            if (format === 'dddd') {
23491                ii = indexOf.call(this._weekdaysParse, llc);
23492                return ii !== -1 ? ii : null;
23493            } else if (format === 'ddd') {
23494                ii = indexOf.call(this._shortWeekdaysParse, llc);
23495                return ii !== -1 ? ii : null;
23496            } else {
23497                ii = indexOf.call(this._minWeekdaysParse, llc);
23498                return ii !== -1 ? ii : null;
23499            }
23500        } else {
23501            if (format === 'dddd') {
23502                ii = indexOf.call(this._weekdaysParse, llc);
23503                if (ii !== -1) {
23504                    return ii;
23505                }
23506                ii = indexOf.call(this._shortWeekdaysParse, llc);
23507                if (ii !== -1) {
23508                    return ii;
23509                }
23510                ii = indexOf.call(this._minWeekdaysParse, llc);
23511                return ii !== -1 ? ii : null;
23512            } else if (format === 'ddd') {
23513                ii = indexOf.call(this._shortWeekdaysParse, llc);
23514                if (ii !== -1) {
23515                    return ii;
23516                }
23517                ii = indexOf.call(this._weekdaysParse, llc);
23518                if (ii !== -1) {
23519                    return ii;
23520                }
23521                ii = indexOf.call(this._minWeekdaysParse, llc);
23522                return ii !== -1 ? ii : null;
23523            } else {
23524                ii = indexOf.call(this._minWeekdaysParse, llc);
23525                if (ii !== -1) {
23526                    return ii;
23527                }
23528                ii = indexOf.call(this._weekdaysParse, llc);
23529                if (ii !== -1) {
23530                    return ii;
23531                }
23532                ii = indexOf.call(this._shortWeekdaysParse, llc);
23533                return ii !== -1 ? ii : null;
23534            }
23535        }
23536    }
23537
23538    function localeWeekdaysParse(weekdayName, format, strict) {
23539        var i, mom, regex;
23540
23541        if (this._weekdaysParseExact) {
23542            return handleStrictParse$1.call(this, weekdayName, format, strict);
23543        }
23544
23545        if (!this._weekdaysParse) {
23546            this._weekdaysParse = [];
23547            this._minWeekdaysParse = [];
23548            this._shortWeekdaysParse = [];
23549            this._fullWeekdaysParse = [];
23550        }
23551
23552        for (i = 0; i < 7; i++) {
23553            // make the regex if we don't have it already
23554
23555            mom = createUTC([2000, 1]).day(i);
23556            if (strict && !this._fullWeekdaysParse[i]) {
23557                this._fullWeekdaysParse[i] = new RegExp(
23558                    '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
23559                    'i'
23560                );
23561                this._shortWeekdaysParse[i] = new RegExp(
23562                    '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
23563                    'i'
23564                );
23565                this._minWeekdaysParse[i] = new RegExp(
23566                    '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
23567                    'i'
23568                );
23569            }
23570            if (!this._weekdaysParse[i]) {
23571                regex =
23572                    '^' +
23573                    this.weekdays(mom, '') +
23574                    '|^' +
23575                    this.weekdaysShort(mom, '') +
23576                    '|^' +
23577                    this.weekdaysMin(mom, '');
23578                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
23579            }
23580            // test the regex
23581            if (
23582                strict &&
23583                format === 'dddd' &&
23584                this._fullWeekdaysParse[i].test(weekdayName)
23585            ) {
23586                return i;
23587            } else if (
23588                strict &&
23589                format === 'ddd' &&
23590                this._shortWeekdaysParse[i].test(weekdayName)
23591            ) {
23592                return i;
23593            } else if (
23594                strict &&
23595                format === 'dd' &&
23596                this._minWeekdaysParse[i].test(weekdayName)
23597            ) {
23598                return i;
23599            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
23600                return i;
23601            }
23602        }
23603    }
23604
23605    // MOMENTS
23606
23607    function getSetDayOfWeek(input) {
23608        if (!this.isValid()) {
23609            return input != null ? this : NaN;
23610        }
23611        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
23612        if (input != null) {
23613            input = parseWeekday(input, this.localeData());
23614            return this.add(input - day, 'd');
23615        } else {
23616            return day;
23617        }
23618    }
23619
23620    function getSetLocaleDayOfWeek(input) {
23621        if (!this.isValid()) {
23622            return input != null ? this : NaN;
23623        }
23624        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
23625        return input == null ? weekday : this.add(input - weekday, 'd');
23626    }
23627
23628    function getSetISODayOfWeek(input) {
23629        if (!this.isValid()) {
23630            return input != null ? this : NaN;
23631        }
23632
23633        // behaves the same as moment#day except
23634        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
23635        // as a setter, sunday should belong to the previous week.
23636
23637        if (input != null) {
23638            var weekday = parseIsoWeekday(input, this.localeData());
23639            return this.day(this.day() % 7 ? weekday : weekday - 7);
23640        } else {
23641            return this.day() || 7;
23642        }
23643    }
23644
23645    function weekdaysRegex(isStrict) {
23646        if (this._weekdaysParseExact) {
23647            if (!hasOwnProp(this, '_weekdaysRegex')) {
23648                computeWeekdaysParse.call(this);
23649            }
23650            if (isStrict) {
23651                return this._weekdaysStrictRegex;
23652            } else {
23653                return this._weekdaysRegex;
23654            }
23655        } else {
23656            if (!hasOwnProp(this, '_weekdaysRegex')) {
23657                this._weekdaysRegex = defaultWeekdaysRegex;
23658            }
23659            return this._weekdaysStrictRegex && isStrict
23660                ? this._weekdaysStrictRegex
23661                : this._weekdaysRegex;
23662        }
23663    }
23664
23665    function weekdaysShortRegex(isStrict) {
23666        if (this._weekdaysParseExact) {
23667            if (!hasOwnProp(this, '_weekdaysRegex')) {
23668                computeWeekdaysParse.call(this);
23669            }
23670            if (isStrict) {
23671                return this._weekdaysShortStrictRegex;
23672            } else {
23673                return this._weekdaysShortRegex;
23674            }
23675        } else {
23676            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
23677                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
23678            }
23679            return this._weekdaysShortStrictRegex && isStrict
23680                ? this._weekdaysShortStrictRegex
23681                : this._weekdaysShortRegex;
23682        }
23683    }
23684
23685    function weekdaysMinRegex(isStrict) {
23686        if (this._weekdaysParseExact) {
23687            if (!hasOwnProp(this, '_weekdaysRegex')) {
23688                computeWeekdaysParse.call(this);
23689            }
23690            if (isStrict) {
23691                return this._weekdaysMinStrictRegex;
23692            } else {
23693                return this._weekdaysMinRegex;
23694            }
23695        } else {
23696            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
23697                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
23698            }
23699            return this._weekdaysMinStrictRegex && isStrict
23700                ? this._weekdaysMinStrictRegex
23701                : this._weekdaysMinRegex;
23702        }
23703    }
23704
23705    function computeWeekdaysParse() {
23706        function cmpLenRev(a, b) {
23707            return b.length - a.length;
23708        }
23709
23710        var minPieces = [],
23711            shortPieces = [],
23712            longPieces = [],
23713            mixedPieces = [],
23714            i,
23715            mom,
23716            minp,
23717            shortp,
23718            longp;
23719        for (i = 0; i < 7; i++) {
23720            // make the regex if we don't have it already
23721            mom = createUTC([2000, 1]).day(i);
23722            minp = regexEscape(this.weekdaysMin(mom, ''));
23723            shortp = regexEscape(this.weekdaysShort(mom, ''));
23724            longp = regexEscape(this.weekdays(mom, ''));
23725            minPieces.push(minp);
23726            shortPieces.push(shortp);
23727            longPieces.push(longp);
23728            mixedPieces.push(minp);
23729            mixedPieces.push(shortp);
23730            mixedPieces.push(longp);
23731        }
23732        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
23733        // will match the longer piece.
23734        minPieces.sort(cmpLenRev);
23735        shortPieces.sort(cmpLenRev);
23736        longPieces.sort(cmpLenRev);
23737        mixedPieces.sort(cmpLenRev);
23738
23739        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
23740        this._weekdaysShortRegex = this._weekdaysRegex;
23741        this._weekdaysMinRegex = this._weekdaysRegex;
23742
23743        this._weekdaysStrictRegex = new RegExp(
23744            '^(' + longPieces.join('|') + ')',
23745            'i'
23746        );
23747        this._weekdaysShortStrictRegex = new RegExp(
23748            '^(' + shortPieces.join('|') + ')',
23749            'i'
23750        );
23751        this._weekdaysMinStrictRegex = new RegExp(
23752            '^(' + minPieces.join('|') + ')',
23753            'i'
23754        );
23755    }
23756
23757    // FORMATTING
23758
23759    function hFormat() {
23760        return this.hours() % 12 || 12;
23761    }
23762
23763    function kFormat() {
23764        return this.hours() || 24;
23765    }
23766
23767    addFormatToken('H', ['HH', 2], 0, 'hour');
23768    addFormatToken('h', ['hh', 2], 0, hFormat);
23769    addFormatToken('k', ['kk', 2], 0, kFormat);
23770
23771    addFormatToken('hmm', 0, 0, function () {
23772        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
23773    });
23774
23775    addFormatToken('hmmss', 0, 0, function () {
23776        return (
23777            '' +
23778            hFormat.apply(this) +
23779            zeroFill(this.minutes(), 2) +
23780            zeroFill(this.seconds(), 2)
23781        );
23782    });
23783
23784    addFormatToken('Hmm', 0, 0, function () {
23785        return '' + this.hours() + zeroFill(this.minutes(), 2);
23786    });
23787
23788    addFormatToken('Hmmss', 0, 0, function () {
23789        return (
23790            '' +
23791            this.hours() +
23792            zeroFill(this.minutes(), 2) +
23793            zeroFill(this.seconds(), 2)
23794        );
23795    });
23796
23797    function meridiem(token, lowercase) {
23798        addFormatToken(token, 0, 0, function () {
23799            return this.localeData().meridiem(
23800                this.hours(),
23801                this.minutes(),
23802                lowercase
23803            );
23804        });
23805    }
23806
23807    meridiem('a', true);
23808    meridiem('A', false);
23809
23810    // ALIASES
23811
23812    addUnitAlias('hour', 'h');
23813
23814    // PRIORITY
23815    addUnitPriority('hour', 13);
23816
23817    // PARSING
23818
23819    function matchMeridiem(isStrict, locale) {
23820        return locale._meridiemParse;
23821    }
23822
23823    addRegexToken('a', matchMeridiem);
23824    addRegexToken('A', matchMeridiem);
23825    addRegexToken('H', match1to2);
23826    addRegexToken('h', match1to2);
23827    addRegexToken('k', match1to2);
23828    addRegexToken('HH', match1to2, match2);
23829    addRegexToken('hh', match1to2, match2);
23830    addRegexToken('kk', match1to2, match2);
23831
23832    addRegexToken('hmm', match3to4);
23833    addRegexToken('hmmss', match5to6);
23834    addRegexToken('Hmm', match3to4);
23835    addRegexToken('Hmmss', match5to6);
23836
23837    addParseToken(['H', 'HH'], HOUR);
23838    addParseToken(['k', 'kk'], function (input, array, config) {
23839        var kInput = toInt(input);
23840        array[HOUR] = kInput === 24 ? 0 : kInput;
23841    });
23842    addParseToken(['a', 'A'], function (input, array, config) {
23843        config._isPm = config._locale.isPM(input);
23844        config._meridiem = input;
23845    });
23846    addParseToken(['h', 'hh'], function (input, array, config) {
23847        array[HOUR] = toInt(input);
23848        getParsingFlags(config).bigHour = true;
23849    });
23850    addParseToken('hmm', function (input, array, config) {
23851        var pos = input.length - 2;
23852        array[HOUR] = toInt(input.substr(0, pos));
23853        array[MINUTE] = toInt(input.substr(pos));
23854        getParsingFlags(config).bigHour = true;
23855    });
23856    addParseToken('hmmss', function (input, array, config) {
23857        var pos1 = input.length - 4,
23858            pos2 = input.length - 2;
23859        array[HOUR] = toInt(input.substr(0, pos1));
23860        array[MINUTE] = toInt(input.substr(pos1, 2));
23861        array[SECOND] = toInt(input.substr(pos2));
23862        getParsingFlags(config).bigHour = true;
23863    });
23864    addParseToken('Hmm', function (input, array, config) {
23865        var pos = input.length - 2;
23866        array[HOUR] = toInt(input.substr(0, pos));
23867        array[MINUTE] = toInt(input.substr(pos));
23868    });
23869    addParseToken('Hmmss', function (input, array, config) {
23870        var pos1 = input.length - 4,
23871            pos2 = input.length - 2;
23872        array[HOUR] = toInt(input.substr(0, pos1));
23873        array[MINUTE] = toInt(input.substr(pos1, 2));
23874        array[SECOND] = toInt(input.substr(pos2));
23875    });
23876
23877    // LOCALES
23878
23879    function localeIsPM(input) {
23880        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
23881        // Using charAt should be more compatible.
23882        return (input + '').toLowerCase().charAt(0) === 'p';
23883    }
23884
23885    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
23886        // Setting the hour should keep the time, because the user explicitly
23887        // specified which hour they want. So trying to maintain the same hour (in
23888        // a new timezone) makes sense. Adding/subtracting hours does not follow
23889        // this rule.
23890        getSetHour = makeGetSet('Hours', true);
23891
23892    function localeMeridiem(hours, minutes, isLower) {
23893        if (hours > 11) {
23894            return isLower ? 'pm' : 'PM';
23895        } else {
23896            return isLower ? 'am' : 'AM';
23897        }
23898    }
23899
23900    var baseConfig = {
23901        calendar: defaultCalendar,
23902        longDateFormat: defaultLongDateFormat,
23903        invalidDate: defaultInvalidDate,
23904        ordinal: defaultOrdinal,
23905        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
23906        relativeTime: defaultRelativeTime,
23907
23908        months: defaultLocaleMonths,
23909        monthsShort: defaultLocaleMonthsShort,
23910
23911        week: defaultLocaleWeek,
23912
23913        weekdays: defaultLocaleWeekdays,
23914        weekdaysMin: defaultLocaleWeekdaysMin,
23915        weekdaysShort: defaultLocaleWeekdaysShort,
23916
23917        meridiemParse: defaultLocaleMeridiemParse,
23918    };
23919
23920    // internal storage for locale config files
23921    var locales = {},
23922        localeFamilies = {},
23923        globalLocale;
23924
23925    function commonPrefix(arr1, arr2) {
23926        var i,
23927            minl = Math.min(arr1.length, arr2.length);
23928        for (i = 0; i < minl; i += 1) {
23929            if (arr1[i] !== arr2[i]) {
23930                return i;
23931            }
23932        }
23933        return minl;
23934    }
23935
23936    function normalizeLocale(key) {
23937        return key ? key.toLowerCase().replace('_', '-') : key;
23938    }
23939
23940    // pick the locale from the array
23941    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
23942    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
23943    function chooseLocale(names) {
23944        var i = 0,
23945            j,
23946            next,
23947            locale,
23948            split;
23949
23950        while (i < names.length) {
23951            split = normalizeLocale(names[i]).split('-');
23952            j = split.length;
23953            next = normalizeLocale(names[i + 1]);
23954            next = next ? next.split('-') : null;
23955            while (j > 0) {
23956                locale = loadLocale(split.slice(0, j).join('-'));
23957                if (locale) {
23958                    return locale;
23959                }
23960                if (
23961                    next &&
23962                    next.length >= j &&
23963                    commonPrefix(split, next) >= j - 1
23964                ) {
23965                    //the next array item is better than a shallower substring of this one
23966                    break;
23967                }
23968                j--;
23969            }
23970            i++;
23971        }
23972        return globalLocale;
23973    }
23974
23975    function 
vendor: 10,067 bytes, lines 23975-24246
23975isLocaleNameSane(name) {
23976        // Prevent names that look like filesystem paths, i.e contain '/' or '\'
23977        return name.match('^[^/\\\\]*$') != null;
23978    }
23979
23980    function loadLocale(name) {
23981        var oldLocale = null,
23982            aliasedRequire;
23983        // TODO: Find a better way to register and load all the locales in Node
23984        if (
23985            locales[name] === undefined &&
23986            typeof module !== 'undefined' &&
23987            module &&
23988            module.exports &&
23989            isLocaleNameSane(name)
23990        ) {
23991            try {
23992                oldLocale = globalLocale._abbr;
23993                aliasedRequire = require;
23994                aliasedRequire('./locale/' + name);
23995                getSetGlobalLocale(oldLocale);
23996            } catch (e) {
23997                // mark as not found to avoid repeating expensive file require call causing high CPU
23998                // when trying to find en-US, en_US, en-us for every format call
23999                locales[name] = null; // null means not found
24000            }
24001        }
24002        return locales[name];
24003    }
24004
24005    // This function will load locale and then set the global locale.  If
24006    // no arguments are passed in, it will simply return the current global
24007    // locale key.
24008    function getSetGlobalLocale(key, values) {
24009        var data;
24010        if (key) {
24011            if (isUndefined(values)) {
24012                data = getLocale(key);
24013            } else {
24014                data = defineLocale(key, values);
24015            }
24016
24017            if (data) {
24018                // moment.duration._locale = moment._locale = data;
24019                globalLocale = data;
24020            } else {
24021                if (typeof console !== 'undefined' && console.warn) {
24022                    //warn user if arguments are passed but the locale could not be set
24023                    console.warn(
24024                        'Locale ' + key + ' not found. Did you forget to load it?'
24025                    );
24026                }
24027            }
24028        }
24029
24030        return globalLocale._abbr;
24031    }
24032
24033    function defineLocale(name, config) {
24034        if (config !== null) {
24035            var locale,
24036                parentConfig = baseConfig;
24037            config.abbr = name;
24038            if (locales[name] != null) {
24039                deprecateSimple(
24040                    'defineLocaleOverride',
24041                    'use moment.updateLocale(localeName, config) to change ' +
24042                        'an existing locale. moment.defineLocale(localeName, ' +
24043                        'config) should only be used for creating a new locale ' +
24044                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
24045                );
24046                parentConfig = locales[name]._config;
24047            } else if (config.parentLocale != null) {
24048                if (locales[config.parentLocale] != null) {
24049                    parentConfig = locales[config.parentLocale]._config;
24050                } else {
24051                    locale = loadLocale(config.parentLocale);
24052                    if (locale != null) {
24053                        parentConfig = locale._config;
24054                    } else {
24055                        if (!localeFamilies[config.parentLocale]) {
24056                            localeFamilies[config.parentLocale] = [];
24057                        }
24058                        localeFamilies[config.parentLocale].push({
24059                            name: name,
24060                            config: config,
24061                        });
24062                        return null;
24063                    }
24064                }
24065            }
24066            locales[name] = new Locale(mergeConfigs(parentConfig, config));
24067
24068            if (localeFamilies[name]) {
24069                localeFamilies[name].forEach(function (x) {
24070                    defineLocale(x.name, x.config);
24071                });
24072            }
24073
24074            // backwards compat for now: also set the locale
24075            // make sure we set the locale AFTER all child locales have been
24076            // created, so we won't end up with the child locale set.
24077            getSetGlobalLocale(name);
24078
24079            return locales[name];
24080        } else {
24081            // useful for testing
24082            delete locales[name];
24083            return null;
24084        }
24085    }
24086
24087    function updateLocale(name, config) {
24088        if (config != null) {
24089            var locale,
24090                tmpLocale,
24091                parentConfig = baseConfig;
24092
24093            if (locales[name] != null && locales[name].parentLocale != null) {
24094                // Update existing child locale in-place to avoid memory-leaks
24095                locales[name].set(mergeConfigs(locales[name]._config, config));
24096            } else {
24097                // MERGE
24098                tmpLocale = loadLocale(name);
24099                if (tmpLocale != null) {
24100                    parentConfig = tmpLocale._config;
24101                }
24102                config = mergeConfigs(parentConfig, config);
24103                if (tmpLocale == null) {
24104                    // updateLocale is called for creating a new locale
24105                    // Set abbr so it will have a name (getters return
24106                    // undefined otherwise).
24107                    config.abbr = name;
24108                }
24109                locale = new Locale(config);
24110                locale.parentLocale = locales[name];
24111                locales[name] = locale;
24112            }
24113
24114            // backwards compat for now: also set the locale
24115            getSetGlobalLocale(name);
24116        } else {
24117            // pass null for config to unupdate, useful for tests
24118            if (locales[name] != null) {
24119                if (locales[name].parentLocale != null) {
24120                    locales[name] = locales[name].parentLocale;
24121                    if (name === getSetGlobalLocale()) {
24122                        getSetGlobalLocale(name);
24123                    }
24124                } else if (locales[name] != null) {
24125                    delete locales[name];
24126                }
24127            }
24128        }
24129        return locales[name];
24130    }
24131
24132    // returns locale data
24133    function getLocale(key) {
24134        var locale;
24135
24136        if (key && key._locale && key._locale._abbr) {
24137            key = key._locale._abbr;
24138        }
24139
24140        if (!key) {
24141            return globalLocale;
24142        }
24143
24144        if (!isArray(key)) {
24145            //short-circuit everything else
24146            locale = loadLocale(key);
24147            if (locale) {
24148                return locale;
24149            }
24150            key = [key];
24151        }
24152
24153        return chooseLocale(key);
24154    }
24155
24156    function listLocales() {
24157        return keys(locales);
24158    }
24159
24160    function checkOverflow(m) {
24161        var overflow,
24162            a = m._a;
24163
24164        if (a && getParsingFlags(m).overflow === -2) {
24165            overflow =
24166                a[MONTH] < 0 || a[MONTH] > 11
24167                    ? MONTH
24168                    : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
24169                    ? DATE
24170                    : a[HOUR] < 0 ||
24171                      a[HOUR] > 24 ||
24172                      (a[HOUR] === 24 &&
24173                          (a[MINUTE] !== 0 ||
24174                              a[SECOND] !== 0 ||
24175                              a[MILLISECOND] !== 0))
24176                    ? HOUR
24177                    : a[MINUTE] < 0 || a[MINUTE] > 59
24178                    ? MINUTE
24179                    : a[SECOND] < 0 || a[SECOND] > 59
24180                    ? SECOND
24181                    : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
24182                    ? MILLISECOND
24183                    : -1;
24184
24185            if (
24186                getParsingFlags(m)._overflowDayOfYear &&
24187                (overflow < YEAR || overflow > DATE)
24188            ) {
24189                overflow = DATE;
24190            }
24191            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
24192                overflow = WEEK;
24193            }
24194            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
24195                overflow = WEEKDAY;
24196            }
24197
24198            getParsingFlags(m).overflow = overflow;
24199        }
24200
24201        return m;
24202    }
24203
24204    // iso 8601 regex
24205    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
24206    var extendedIsoRegex =
24207            /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
24208        basicIsoRegex =
24209            /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
24210        tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
24211        isoDates = [
24212            ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
24213            ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
24214            ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
24215            ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
24216            ['YYYY-DDD', /\d{4}-\d{3}/],
24217            ['YYYY-MM', /\d{4}-\d\d/, false],
24218            ['YYYYYYMMDD', /[+-]\d{10}/],
24219            ['YYYYMMDD', /\d{8}/],
24220            ['GGGG[W]WWE', /\d{4}W\d{3}/],
24221            ['GGGG[W]WW', /\d{4}W\d{2}/, false],
24222            ['YYYYDDD', /\d{7}/],
24223            ['YYYYMM', /\d{6}/, false],
24224            ['YYYY', /\d{4}/, false],
24225        ],
24226        // iso time formats and regexes
24227        isoTimes = [
24228            ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
24229            ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
24230            ['HH:mm:ss', /\d\d:\d\d:\d\d/],
24231            ['HH:mm', /\d\d:\d\d/],
24232            ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
24233            ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
24234            ['HHmmss', /\d\d\d\d\d\d/],
24235            ['HHmm', /\d\d\d\d/],
24236            ['HH', /\d\d/],
24237        ],
24238        aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
24239        // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
24240        rfc2822 =
24241            /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,
24242        obsOffsets = {
24243            UT: 0,
24244            GMT: 0,
24245            EDT: -4 * 60,
24246            EST: -5 * 60,
vendor: 24,421 bytes, lines 24247-25027
24247            CDT: -5 * 60,
24248            CST: -6 * 60,
24249            MDT: -6 * 60,
24250            MST: -7 * 60,
24251            PDT: -7 * 60,
24252            PST: -8 * 60,
24253        };
24254
24255    // date from iso format
24256    function configFromISO(config) {
24257        var i,
24258            l,
24259            string = config._i,
24260            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
24261            allowTime,
24262            dateFormat,
24263            timeFormat,
24264            tzFormat,
24265            isoDatesLen = isoDates.length,
24266            isoTimesLen = isoTimes.length;
24267
24268        if (match) {
24269            getParsingFlags(config).iso = true;
24270            for (i = 0, l = isoDatesLen; i < l; i++) {
24271                if (isoDates[i][1].exec(match[1])) {
24272                    dateFormat = isoDates[i][0];
24273                    allowTime = isoDates[i][2] !== false;
24274                    break;
24275                }
24276            }
24277            if (dateFormat == null) {
24278                config._isValid = false;
24279                return;
24280            }
24281            if (match[3]) {
24282                for (i = 0, l = isoTimesLen; i < l; i++) {
24283                    if (isoTimes[i][1].exec(match[3])) {
24284                        // match[2] should be 'T' or space
24285                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
24286                        break;
24287                    }
24288                }
24289                if (timeFormat == null) {
24290                    config._isValid = false;
24291                    return;
24292                }
24293            }
24294            if (!allowTime && timeFormat != null) {
24295                config._isValid = false;
24296                return;
24297            }
24298            if (match[4]) {
24299                if (tzRegex.exec(match[4])) {
24300                    tzFormat = 'Z';
24301                } else {
24302                    config._isValid = false;
24303                    return;
24304                }
24305            }
24306            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
24307            configFromStringAndFormat(config);
24308        } else {
24309            config._isValid = false;
24310        }
24311    }
24312
24313    function extractFromRFC2822Strings(
24314        yearStr,
24315        monthStr,
24316        dayStr,
24317        hourStr,
24318        minuteStr,
24319        secondStr
24320    ) {
24321        var result = [
24322            untruncateYear(yearStr),
24323            defaultLocaleMonthsShort.indexOf(monthStr),
24324            parseInt(dayStr, 10),
24325            parseInt(hourStr, 10),
24326            parseInt(minuteStr, 10),
24327        ];
24328
24329        if (secondStr) {
24330            result.push(parseInt(secondStr, 10));
24331        }
24332
24333        return result;
24334    }
24335
24336    function untruncateYear(yearStr) {
24337        var year = parseInt(yearStr, 10);
24338        if (year <= 49) {
24339            return 2000 + year;
24340        } else if (year <= 999) {
24341            return 1900 + year;
24342        }
24343        return year;
24344    }
24345
24346    function preprocessRFC2822(s) {
24347        // Remove comments and folding whitespace and replace multiple-spaces with a single space
24348        return s
24349            .replace(/\([^)]*\)|[\n\t]/g, ' ')
24350            .replace(/(\s\s+)/g, ' ')
24351            .replace(/^\s\s*/, '')
24352            .replace(/\s\s*$/, '');
24353    }
24354
24355    function checkWeekday(weekdayStr, parsedInput, config) {
24356        if (weekdayStr) {
24357            // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
24358            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
24359                weekdayActual = new Date(
24360                    parsedInput[0],
24361                    parsedInput[1],
24362                    parsedInput[2]
24363                ).getDay();
24364            if (weekdayProvided !== weekdayActual) {
24365                getParsingFlags(config).weekdayMismatch = true;
24366                config._isValid = false;
24367                return false;
24368            }
24369        }
24370        return true;
24371    }
24372
24373    function calculateOffset(obsOffset, militaryOffset, numOffset) {
24374        if (obsOffset) {
24375            return obsOffsets[obsOffset];
24376        } else if (militaryOffset) {
24377            // the only allowed military tz is Z
24378            return 0;
24379        } else {
24380            var hm = parseInt(numOffset, 10),
24381                m = hm % 100,
24382                h = (hm - m) / 100;
24383            return h * 60 + m;
24384        }
24385    }
24386
24387    // date and time from ref 2822 format
24388    function configFromRFC2822(config) {
24389        var match = rfc2822.exec(preprocessRFC2822(config._i)),
24390            parsedArray;
24391        if (match) {
24392            parsedArray = extractFromRFC2822Strings(
24393                match[4],
24394                match[3],
24395                match[2],
24396                match[5],
24397                match[6],
24398                match[7]
24399            );
24400            if (!checkWeekday(match[1], parsedArray, config)) {
24401                return;
24402            }
24403
24404            config._a = parsedArray;
24405            config._tzm = calculateOffset(match[8], match[9], match[10]);
24406
24407            config._d = createUTCDate.apply(null, config._a);
24408            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
24409
24410            getParsingFlags(config).rfc2822 = true;
24411        } else {
24412            config._isValid = false;
24413        }
24414    }
24415
24416    // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
24417    function configFromString(config) {
24418        var matched = aspNetJsonRegex.exec(config._i);
24419        if (matched !== null) {
24420            config._d = new Date(+matched[1]);
24421            return;
24422        }
24423
24424        configFromISO(config);
24425        if (config._isValid === false) {
24426            delete config._isValid;
24427        } else {
24428            return;
24429        }
24430
24431        configFromRFC2822(config);
24432        if (config._isValid === false) {
24433            delete config._isValid;
24434        } else {
24435            return;
24436        }
24437
24438        if (config._strict) {
24439            config._isValid = false;
24440        } else {
24441            // Final attempt, use Input Fallback
24442            hooks.createFromInputFallback(config);
24443        }
24444    }
24445
24446    hooks.createFromInputFallback = deprecate(
24447        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
24448            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
24449            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
24450        function (config) {
24451            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
24452        }
24453    );
24454
24455    // Pick the first defined of two or three arguments.
24456    function defaults(a, b, c) {
24457        if (a != null) {
24458            return a;
24459        }
24460        if (b != null) {
24461            return b;
24462        }
24463        return c;
24464    }
24465
24466    function currentDateArray(config) {
24467        // hooks is actually the exported moment object
24468        var nowValue = new Date(hooks.now());
24469        if (config._useUTC) {
24470            return [
24471                nowValue.getUTCFullYear(),
24472                nowValue.getUTCMonth(),
24473                nowValue.getUTCDate(),
24474            ];
24475        }
24476        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
24477    }
24478
24479    // convert an array to a date.
24480    // the array should mirror the parameters below
24481    // note: all values past the year are optional and will default to the lowest possible value.
24482    // [year, month, day , hour, minute, second, millisecond]
24483    function configFromArray(config) {
24484        var i,
24485            date,
24486            input = [],
24487            currentDate,
24488            expectedWeekday,
24489            yearToUse;
24490
24491        if (config._d) {
24492            return;
24493        }
24494
24495        currentDate = currentDateArray(config);
24496
24497        //compute day of the year from weeks and weekdays
24498        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
24499            dayOfYearFromWeekInfo(config);
24500        }
24501
24502        //if the day of the year is set, figure out what it is
24503        if (config._dayOfYear != null) {
24504            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
24505
24506            if (
24507                config._dayOfYear > daysInYear(yearToUse) ||
24508                config._dayOfYear === 0
24509            ) {
24510                getParsingFlags(config)._overflowDayOfYear = true;
24511            }
24512
24513            date = createUTCDate(yearToUse, 0, config._dayOfYear);
24514            config._a[MONTH] = date.getUTCMonth();
24515            config._a[DATE] = date.getUTCDate();
24516        }
24517
24518        // Default to current date.
24519        // * if no year, month, day of month are given, default to today
24520        // * if day of month is given, default month and year
24521        // * if month is given, default only year
24522        // * if year is given, don't default anything
24523        for (i = 0; i < 3 && config._a[i] == null; ++i) {
24524            config._a[i] = input[i] = currentDate[i];
24525        }
24526
24527        // Zero out whatever was not defaulted, including time
24528        for (; i < 7; i++) {
24529            config._a[i] = input[i] =
24530                config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
24531        }
24532
24533        // Check for 24:00:00.000
24534        if (
24535            config._a[HOUR] === 24 &&
24536            config._a[MINUTE] === 0 &&
24537            config._a[SECOND] === 0 &&
24538            config._a[MILLISECOND] === 0
24539        ) {
24540            config._nextDay = true;
24541            config._a[HOUR] = 0;
24542        }
24543
24544        config._d = (config._useUTC ? createUTCDate : createDate).apply(
24545            null,
24546            input
24547        );
24548        expectedWeekday = config._useUTC
24549            ? config._d.getUTCDay()
24550            : config._d.getDay();
24551
24552        // Apply timezone offset from input. The actual utcOffset can be changed
24553        // with parseZone.
24554        if (config._tzm != null) {
24555            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
24556        }
24557
24558        if (config._nextDay) {
24559            config._a[HOUR] = 24;
24560        }
24561
24562        // check for mismatching day of week
24563        if (
24564            config._w &&
24565            typeof config._w.d !== 'undefined' &&
24566            config._w.d !== expectedWeekday
24567        ) {
24568            getParsingFlags(config).weekdayMismatch = true;
24569        }
24570    }
24571
24572    function dayOfYearFromWeekInfo(config) {
24573        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
24574
24575        w = config._w;
24576        if (w.GG != null || w.W != null || w.E != null) {
24577            dow = 1;
24578            doy = 4;
24579
24580            // TODO: We need to take the current isoWeekYear, but that depends on
24581            // how we interpret now (local, utc, fixed offset). So create
24582            // a now version of current config (take local/utc/offset flags, and
24583            // create now).
24584            weekYear = defaults(
24585                w.GG,
24586                config._a[YEAR],
24587                weekOfYear(createLocal(), 1, 4).year
24588            );
24589            week = defaults(w.W, 1);
24590            weekday = defaults(w.E, 1);
24591            if (weekday < 1 || weekday > 7) {
24592                weekdayOverflow = true;
24593            }
24594        } else {
24595            dow = config._locale._week.dow;
24596            doy = config._locale._week.doy;
24597
24598            curWeek = weekOfYear(createLocal(), dow, doy);
24599
24600            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
24601
24602            // Default to current week.
24603            week = defaults(w.w, curWeek.week);
24604
24605            if (w.d != null) {
24606                // weekday -- low day numbers are considered next week
24607                weekday = w.d;
24608                if (weekday < 0 || weekday > 6) {
24609                    weekdayOverflow = true;
24610                }
24611            } else if (w.e != null) {
24612                // local weekday -- counting starts from beginning of week
24613                weekday = w.e + dow;
24614                if (w.e < 0 || w.e > 6) {
24615                    weekdayOverflow = true;
24616                }
24617            } else {
24618                // default to beginning of week
24619                weekday = dow;
24620            }
24621        }
24622        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
24623            getParsingFlags(config)._overflowWeeks = true;
24624        } else if (weekdayOverflow != null) {
24625            getParsingFlags(config)._overflowWeekday = true;
24626        } else {
24627            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
24628            config._a[YEAR] = temp.year;
24629            config._dayOfYear = temp.dayOfYear;
24630        }
24631    }
24632
24633    // constant that refers to the ISO standard
24634    hooks.ISO_8601 = function () {};
24635
24636    // constant that refers to the RFC 2822 form
24637    hooks.RFC_2822 = function () {};
24638
24639    // date from string and format string
24640    function configFromStringAndFormat(config) {
24641        // TODO: Move this to another part of the creation flow to prevent circular deps
24642        if (config._f === hooks.ISO_8601) {
24643            configFromISO(config);
24644            return;
24645        }
24646        if (config._f === hooks.RFC_2822) {
24647            configFromRFC2822(config);
24648            return;
24649        }
24650        config._a = [];
24651        getParsingFlags(config).empty = true;
24652
24653        // This array is used to make a Date, either with `new Date` or `Date.UTC`
24654        var string = '' + config._i,
24655            i,
24656            parsedInput,
24657            tokens,
24658            token,
24659            skipped,
24660            stringLength = string.length,
24661            totalParsedInputLength = 0,
24662            era,
24663            tokenLen;
24664
24665        tokens =
24666            expandFormat(config._f, config._locale).match(formattingTokens) || [];
24667        tokenLen = tokens.length;
24668        for (i = 0; i < tokenLen; i++) {
24669            token = tokens[i];
24670            parsedInput = (string.match(getParseRegexForToken(token, config)) ||
24671                [])[0];
24672            if (parsedInput) {
24673                skipped = string.substr(0, string.indexOf(parsedInput));
24674                if (skipped.length > 0) {
24675                    getParsingFlags(config).unusedInput.push(skipped);
24676                }
24677                string = string.slice(
24678                    string.indexOf(parsedInput) + parsedInput.length
24679                );
24680                totalParsedInputLength += parsedInput.length;
24681            }
24682            // don't parse if it's not a known token
24683            if (formatTokenFunctions[token]) {
24684                if (parsedInput) {
24685                    getParsingFlags(config).empty = false;
24686                } else {
24687                    getParsingFlags(config).unusedTokens.push(token);
24688                }
24689                addTimeToArrayFromToken(token, parsedInput, config);
24690            } else if (config._strict && !parsedInput) {
24691                getParsingFlags(config).unusedTokens.push(token);
24692            }
24693        }
24694
24695        // add remaining unparsed input length to the string
24696        getParsingFlags(config).charsLeftOver =
24697            stringLength - totalParsedInputLength;
24698        if (string.length > 0) {
24699            getParsingFlags(config).unusedInput.push(string);
24700        }
24701
24702        // clear _12h flag if hour is <= 12
24703        if (
24704            config._a[HOUR] <= 12 &&
24705            getParsingFlags(config).bigHour === true &&
24706            config._a[HOUR] > 0
24707        ) {
24708            getParsingFlags(config).bigHour = undefined;
24709        }
24710
24711        getParsingFlags(config).parsedDateParts = config._a.slice(0);
24712        getParsingFlags(config).meridiem = config._meridiem;
24713        // handle meridiem
24714        config._a[HOUR] = meridiemFixWrap(
24715            config._locale,
24716            config._a[HOUR],
24717            config._meridiem
24718        );
24719
24720        // handle era
24721        era = getParsingFlags(config).era;
24722        if (era !== null) {
24723            config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
24724        }
24725
24726        configFromArray(config);
24727        checkOverflow(config);
24728    }
24729
24730    function meridiemFixWrap(locale, hour, meridiem) {
24731        var isPm;
24732
24733        if (meridiem == null) {
24734            // nothing to do
24735            return hour;
24736        }
24737        if (locale.meridiemHour != null) {
24738            return locale.meridiemHour(hour, meridiem);
24739        } else if (locale.isPM != null) {
24740            // Fallback
24741            isPm = locale.isPM(meridiem);
24742            if (isPm && hour < 12) {
24743                hour += 12;
24744            }
24745            if (!isPm && hour === 12) {
24746                hour = 0;
24747            }
24748            return hour;
24749        } else {
24750            // this is not supposed to happen
24751            return hour;
24752        }
24753    }
24754
24755    // date from string and array of format strings
24756    function configFromStringAndArray(config) {
24757        var tempConfig,
24758            bestMoment,
24759            scoreToBeat,
24760            i,
24761            currentScore,
24762            validFormatFound,
24763            bestFormatIsValid = false,
24764            configfLen = config._f.length;
24765
24766        if (configfLen === 0) {
24767            getParsingFlags(config).invalidFormat = true;
24768            config._d = new Date(NaN);
24769            return;
24770        }
24771
24772        for (i = 0; i < configfLen; i++) {
24773            currentScore = 0;
24774            validFormatFound = false;
24775            tempConfig = copyConfig({}, config);
24776            if (config._useUTC != null) {
24777                tempConfig._useUTC = config._useUTC;
24778            }
24779            tempConfig._f = config._f[i];
24780            configFromStringAndFormat(tempConfig);
24781
24782            if (isValid(tempConfig)) {
24783                validFormatFound = true;
24784            }
24785
24786            // if there is any input that was not parsed add a penalty for that format
24787            currentScore += getParsingFlags(tempConfig).charsLeftOver;
24788
24789            //or tokens
24790            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
24791
24792            getParsingFlags(tempConfig).score = currentScore;
24793
24794            if (!bestFormatIsValid) {
24795                if (
24796                    scoreToBeat == null ||
24797                    currentScore < scoreToBeat ||
24798                    validFormatFound
24799                ) {
24800                    scoreToBeat = currentScore;
24801                    bestMoment = tempConfig;
24802                    if (validFormatFound) {
24803                        bestFormatIsValid = true;
24804                    }
24805                }
24806            } else {
24807                if (currentScore < scoreToBeat) {
24808                    scoreToBeat = currentScore;
24809                    bestMoment = tempConfig;
24810                }
24811            }
24812        }
24813
24814        extend(config, bestMoment || tempConfig);
24815    }
24816
24817    function configFromObject(config) {
24818        if (config._d) {
24819            return;
24820        }
24821
24822        var i = normalizeObjectUnits(config._i),
24823            dayOrDate = i.day === undefined ? i.date : i.day;
24824        config._a = map(
24825            [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
24826            function (obj) {
24827                return obj && parseInt(obj, 10);
24828            }
24829        );
24830
24831        configFromArray(config);
24832    }
24833
24834    function createFromConfig(config) {
24835        var res = new Moment(checkOverflow(prepareConfig(config)));
24836        if (res._nextDay) {
24837            // Adding is smart enough around DST
24838            res.add(1, 'd');
24839            res._nextDay = undefined;
24840        }
24841
24842        return res;
24843    }
24844
24845    function prepareConfig(config) {
24846        var input = config._i,
24847            format = config._f;
24848
24849        config._locale = config._locale || getLocale(config._l);
24850
24851        if (input === null || (format === undefined && input === '')) {
24852            return createInvalid({ nullInput: true });
24853        }
24854
24855        if (typeof input === 'string') {
24856            config._i = input = config._locale.preparse(input);
24857        }
24858
24859        if (isMoment(input)) {
24860            return new Moment(checkOverflow(input));
24861        } else if (isDate(input)) {
24862            config._d = input;
24863        } else if (isArray(format)) {
24864            configFromStringAndArray(config);
24865        } else if (format) {
24866            configFromStringAndFormat(config);
24867        } else {
24868            configFromInput(config);
24869        }
24870
24871        if (!isValid(config)) {
24872            config._d = null;
24873        }
24874
24875        return config;
24876    }
24877
24878    function configFromInput(config) {
24879        var input = config._i;
24880        if (isUndefined(input)) {
24881            config._d = new Date(hooks.now());
24882        } else if (isDate(input)) {
24883            config._d = new Date(input.valueOf());
24884        } else if (typeof input === 'string') {
24885            configFromString(config);
24886        } else if (isArray(input)) {
24887            config._a = map(input.slice(0), function (obj) {
24888                return parseInt(obj, 10);
24889            });
24890            configFromArray(config);
24891        } else if (isObject(input)) {
24892            configFromObject(config);
24893        } else if (isNumber(input)) {
24894            // from milliseconds
24895            config._d = new Date(input);
24896        } else {
24897            hooks.createFromInputFallback(config);
24898        }
24899    }
24900
24901    function createLocalOrUTC(input, format, locale, strict, isUTC) {
24902        var c = {};
24903
24904        if (format === true || format === false) {
24905            strict = format;
24906            format = undefined;
24907        }
24908
24909        if (locale === true || locale === false) {
24910            strict = locale;
24911            locale = undefined;
24912        }
24913
24914        if (
24915            (isObject(input) && isObjectEmpty(input)) ||
24916            (isArray(input) && input.length === 0)
24917        ) {
24918            input = undefined;
24919        }
24920        // object construction must be done this way.
24921        // https://github.com/moment/moment/issues/1423
24922        c._isAMomentObject = true;
24923        c._useUTC = c._isUTC = isUTC;
24924        c._l = locale;
24925        c._i = input;
24926        c._f = format;
24927        c._strict = strict;
24928
24929        return createFromConfig(c);
24930    }
24931
24932    function createLocal(input, format, locale, strict) {
24933        return createLocalOrUTC(input, format, locale, strict, false);
24934    }
24935
24936    var prototypeMin = deprecate(
24937            'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
24938            function () {
24939                var other = createLocal.apply(null, arguments);
24940                if (this.isValid() && other.isValid()) {
24941                    return other < this ? this : other;
24942                } else {
24943                    return createInvalid();
24944                }
24945            }
24946        ),
24947        prototypeMax = deprecate(
24948            'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
24949            function () {
24950                var other = createLocal.apply(null, arguments);
24951                if (this.isValid() && other.isValid()) {
24952                    return other > this ? this : other;
24953                } else {
24954                    return createInvalid();
24955                }
24956            }
24957        );
24958
24959    // Pick a moment m from moments so that m[fn](other) is true for all
24960    // other. This relies on the function fn to be transitive.
24961    //
24962    // moments should either be an array of moment objects or an array, whose
24963    // first element is an array of moment objects.
24964    function pickBy(fn, moments) {
24965        var res, i;
24966        if (moments.length === 1 && isArray(moments[0])) {
24967            moments = moments[0];
24968        }
24969        if (!moments.length) {
24970            return createLocal();
24971        }
24972        res = moments[0];
24973        for (i = 1; i < moments.length; ++i) {
24974            if (!moments[i].isValid() || moments[i][fn](res)) {
24975                res = moments[i];
24976            }
24977        }
24978        return res;
24979    }
24980
24981    // TODO: Use [].sort instead?
24982    function min() {
24983        var args = [].slice.call(arguments, 0);
24984
24985        return pickBy('isBefore', args);
24986    }
24987
24988    function max() {
24989        var args = [].slice.call(arguments, 0);
24990
24991        return pickBy('isAfter', args);
24992    }
24993
24994    var now = function () {
24995        return Date.now ? Date.now() : +new Date();
24996    };
24997
24998    var ordering = [
24999        'year',
25000        'quarter',
25001        'month',
25002        'week',
25003        'day',
25004        'hour',
25005        'minute',
25006        'second',
25007        'millisecond',
25008    ];
25009
25010    function isDurationValid(m) {
25011        var key,
25012            unitHasDecimal = false,
25013            i,
25014            orderLen = ordering.length;
25015        for (key in m) {
25016            if (
25017                hasOwnProp(m, key) &&
25018                !(
25019                    indexOf.call(ordering, key) !== -1 &&
25020                    (m[key] == null || !isNaN(m[key]))
25021                )
25022            ) {
25023                return false;
25024            }
25025        }
25026
25027        for (i = 0; i < orderLen
vendor: 10,251 bytes, lines 25027-25352
25027; ++i) {
25028            if (m[ordering[i]]) {
25029                if (unitHasDecimal) {
25030                    return false; // only allow non-integers for smallest unit
25031                }
25032                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
25033                    unitHasDecimal = true;
25034                }
25035            }
25036        }
25037
25038        return true;
25039    }
25040
25041    function isValid$1() {
25042        return this._isValid;
25043    }
25044
25045    function createInvalid$1() {
25046        return createDuration(NaN);
25047    }
25048
25049    function Duration(duration) {
25050        var normalizedInput = normalizeObjectUnits(duration),
25051            years = normalizedInput.year || 0,
25052            quarters = normalizedInput.quarter || 0,
25053            months = normalizedInput.month || 0,
25054            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
25055            days = normalizedInput.day || 0,
25056            hours = normalizedInput.hour || 0,
25057            minutes = normalizedInput.minute || 0,
25058            seconds = normalizedInput.second || 0,
25059            milliseconds = normalizedInput.millisecond || 0;
25060
25061        this._isValid = isDurationValid(normalizedInput);
25062
25063        // representation for dateAddRemove
25064        this._milliseconds =
25065            +milliseconds +
25066            seconds * 1e3 + // 1000
25067            minutes * 6e4 + // 1000 * 60
25068            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
25069        // Because of dateAddRemove treats 24 hours as different from a
25070        // day when working around DST, we need to store them separately
25071        this._days = +days + weeks * 7;
25072        // It is impossible to translate months into days without knowing
25073        // which months you are are talking about, so we have to store
25074        // it separately.
25075        this._months = +months + quarters * 3 + years * 12;
25076
25077        this._data = {};
25078
25079        this._locale = getLocale();
25080
25081        this._bubble();
25082    }
25083
25084    function isDuration(obj) {
25085        return obj instanceof Duration;
25086    }
25087
25088    function absRound(number) {
25089        if (number < 0) {
25090            return Math.round(-1 * number) * -1;
25091        } else {
25092            return Math.round(number);
25093        }
25094    }
25095
25096    // compare two arrays, return the number of differences
25097    function compareArrays(array1, array2, dontConvert) {
25098        var len = Math.min(array1.length, array2.length),
25099            lengthDiff = Math.abs(array1.length - array2.length),
25100            diffs = 0,
25101            i;
25102        for (i = 0; i < len; i++) {
25103            if (
25104                (dontConvert && array1[i] !== array2[i]) ||
25105                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
25106            ) {
25107                diffs++;
25108            }
25109        }
25110        return diffs + lengthDiff;
25111    }
25112
25113    // FORMATTING
25114
25115    function offset(token, separator) {
25116        addFormatToken(token, 0, 0, function () {
25117            var offset = this.utcOffset(),
25118                sign = '+';
25119            if (offset < 0) {
25120                offset = -offset;
25121                sign = '-';
25122            }
25123            return (
25124                sign +
25125                zeroFill(~~(offset / 60), 2) +
25126                separator +
25127                zeroFill(~~offset % 60, 2)
25128            );
25129        });
25130    }
25131
25132    offset('Z', ':');
25133    offset('ZZ', '');
25134
25135    // PARSING
25136
25137    addRegexToken('Z', matchShortOffset);
25138    addRegexToken('ZZ', matchShortOffset);
25139    addParseToken(['Z', 'ZZ'], function (input, array, config) {
25140        config._useUTC = true;
25141        config._tzm = offsetFromString(matchShortOffset, input);
25142    });
25143
25144    // HELPERS
25145
25146    // timezone chunker
25147    // '+10:00' > ['10',  '00']
25148    // '-1530'  > ['-15', '30']
25149    var chunkOffset = /([\+\-]|\d\d)/gi;
25150
25151    function offsetFromString(matcher, string) {
25152        var matches = (string || '').match(matcher),
25153            chunk,
25154            parts,
25155            minutes;
25156
25157        if (matches === null) {
25158            return null;
25159        }
25160
25161        chunk = matches[matches.length - 1] || [];
25162        parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
25163        minutes = +(parts[1] * 60) + toInt(parts[2]);
25164
25165        return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
25166    }
25167
25168    // Return a moment from input, that is local/utc/zone equivalent to model.
25169    function cloneWithOffset(input, model) {
25170        var res, diff;
25171        if (model._isUTC) {
25172            res = model.clone();
25173            diff =
25174                (isMoment(input) || isDate(input)
25175                    ? input.valueOf()
25176                    : createLocal(input).valueOf()) - res.valueOf();
25177            // Use low-level api, because this fn is low-level api.
25178            res._d.setTime(res._d.valueOf() + diff);
25179            hooks.updateOffset(res, false);
25180            return res;
25181        } else {
25182            return createLocal(input).local();
25183        }
25184    }
25185
25186    function getDateOffset(m) {
25187        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
25188        // https://github.com/moment/moment/pull/1871
25189        return -Math.round(m._d.getTimezoneOffset());
25190    }
25191
25192    // HOOKS
25193
25194    // This function will be called whenever a moment is mutated.
25195    // It is intended to keep the offset in sync with the timezone.
25196    hooks.updateOffset = function () {};
25197
25198    // MOMENTS
25199
25200    // keepLocalTime = true means only change the timezone, without
25201    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
25202    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
25203    // +0200, so we adjust the time as needed, to be valid.
25204    //
25205    // Keeping the time actually adds/subtracts (one hour)
25206    // from the actual represented time. That is why we call updateOffset
25207    // a second time. In case it wants us to change the offset again
25208    // _changeInProgress == true case, then we have to adjust, because
25209    // there is no such time in the given timezone.
25210    function getSetOffset(input, keepLocalTime, keepMinutes) {
25211        var offset = this._offset || 0,
25212            localAdjust;
25213        if (!this.isValid()) {
25214            return input != null ? this : NaN;
25215        }
25216        if (input != null) {
25217            if (typeof input === 'string') {
25218                input = offsetFromString(matchShortOffset, input);
25219                if (input === null) {
25220                    return this;
25221                }
25222            } else if (Math.abs(input) < 16 && !keepMinutes) {
25223                input = input * 60;
25224            }
25225            if (!this._isUTC && keepLocalTime) {
25226                localAdjust = getDateOffset(this);
25227            }
25228            this._offset = input;
25229            this._isUTC = true;
25230            if (localAdjust != null) {
25231                this.add(localAdjust, 'm');
25232            }
25233            if (offset !== input) {
25234                if (!keepLocalTime || this._changeInProgress) {
25235                    addSubtract(
25236                        this,
25237                        createDuration(input - offset, 'm'),
25238                        1,
25239                        false
25240                    );
25241                } else if (!this._changeInProgress) {
25242                    this._changeInProgress = true;
25243                    hooks.updateOffset(this, true);
25244                    this._changeInProgress = null;
25245                }
25246            }
25247            return this;
25248        } else {
25249            return this._isUTC ? offset : getDateOffset(this);
25250        }
25251    }
25252
25253    function getSetZone(input, keepLocalTime) {
25254        if (input != null) {
25255            if (typeof input !== 'string') {
25256                input = -input;
25257            }
25258
25259            this.utcOffset(input, keepLocalTime);
25260
25261            return this;
25262        } else {
25263            return -this.utcOffset();
25264        }
25265    }
25266
25267    function setOffsetToUTC(keepLocalTime) {
25268        return this.utcOffset(0, keepLocalTime);
25269    }
25270
25271    function setOffsetToLocal(keepLocalTime) {
25272        if (this._isUTC) {
25273            this.utcOffset(0, keepLocalTime);
25274            this._isUTC = false;
25275
25276            if (keepLocalTime) {
25277                this.subtract(getDateOffset(this), 'm');
25278            }
25279        }
25280        return this;
25281    }
25282
25283    function setOffsetToParsedOffset() {
25284        if (this._tzm != null) {
25285            this.utcOffset(this._tzm, false, true);
25286        } else if (typeof this._i === 'string') {
25287            var tZone = offsetFromString(matchOffset, this._i);
25288            if (tZone != null) {
25289                this.utcOffset(tZone);
25290            } else {
25291                this.utcOffset(0, true);
25292            }
25293        }
25294        return this;
25295    }
25296
25297    function hasAlignedHourOffset(input) {
25298        if (!this.isValid()) {
25299            return false;
25300        }
25301        input = input ? createLocal(input).utcOffset() : 0;
25302
25303        return (this.utcOffset() - input) % 60 === 0;
25304    }
25305
25306    function isDaylightSavingTime() {
25307        return (
25308            this.utcOffset() > this.clone().month(0).utcOffset() ||
25309            this.utcOffset() > this.clone().month(5).utcOffset()
25310        );
25311    }
25312
25313    function isDaylightSavingTimeShifted() {
25314        if (!isUndefined(this._isDSTShifted)) {
25315            return this._isDSTShifted;
25316        }
25317
25318        var c = {},
25319            other;
25320
25321        copyConfig(c, this);
25322        c = prepareConfig(c);
25323
25324        if (c._a) {
25325            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
25326            this._isDSTShifted =
25327                this.isValid() && compareArrays(c._a, other.toArray()) > 0;
25328        } else {
25329            this._isDSTShifted = false;
25330        }
25331
25332        return this._isDSTShifted;
25333    }
25334
25335    function isLocal() {
25336        return this.isValid() ? !this._isUTC : false;
25337    }
25338
25339    function isUtcOffset() {
25340        return this.isValid() ? this._isUTC : false;
25341    }
25342
25343    function isUtc() {
25344        return this.isValid() ? this._isUTC && this._offset === 0 : false;
25345    }
25346
25347    // ASP.NET json date format regex
25348    var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
25349        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
25350        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
25351        // and further modified to allow for strings containing both week and day
25352        isoRegex =
vendor: 9,021 bytes, lines 25352-25642
25352
25353            /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
25354
25355    function createDuration(input, key) {
25356        var duration = input,
25357            // matching against regexp is expensive, do it on demand
25358            match = null,
25359            sign,
25360            ret,
25361            diffRes;
25362
25363        if (isDuration(input)) {
25364            duration = {
25365                ms: input._milliseconds,
25366                d: input._days,
25367                M: input._months,
25368            };
25369        } else if (isNumber(input) || !isNaN(+input)) {
25370            duration = {};
25371            if (key) {
25372                duration[key] = +input;
25373            } else {
25374                duration.milliseconds = +input;
25375            }
25376        } else if ((match = aspNetRegex.exec(input))) {
25377            sign = match[1] === '-' ? -1 : 1;
25378            duration = {
25379                y: 0,
25380                d: toInt(match[DATE]) * sign,
25381                h: toInt(match[HOUR]) * sign,
25382                m: toInt(match[MINUTE]) * sign,
25383                s: toInt(match[SECOND]) * sign,
25384                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
25385            };
25386        } else if ((match = isoRegex.exec(input))) {
25387            sign = match[1] === '-' ? -1 : 1;
25388            duration = {
25389                y: parseIso(match[2], sign),
25390                M: parseIso(match[3], sign),
25391                w: parseIso(match[4], sign),
25392                d: parseIso(match[5], sign),
25393                h: parseIso(match[6], sign),
25394                m: parseIso(match[7], sign),
25395                s: parseIso(match[8], sign),
25396            };
25397        } else if (duration == null) {
25398            // checks for null or undefined
25399            duration = {};
25400        } else if (
25401            typeof duration === 'object' &&
25402            ('from' in duration || 'to' in duration)
25403        ) {
25404            diffRes = momentsDifference(
25405                createLocal(duration.from),
25406                createLocal(duration.to)
25407            );
25408
25409            duration = {};
25410            duration.ms = diffRes.milliseconds;
25411            duration.M = diffRes.months;
25412        }
25413
25414        ret = new Duration(duration);
25415
25416        if (isDuration(input) && hasOwnProp(input, '_locale')) {
25417            ret._locale = input._locale;
25418        }
25419
25420        if (isDuration(input) && hasOwnProp(input, '_isValid')) {
25421            ret._isValid = input._isValid;
25422        }
25423
25424        return ret;
25425    }
25426
25427    createDuration.fn = Duration.prototype;
25428    createDuration.invalid = createInvalid$1;
25429
25430    function parseIso(inp, sign) {
25431        // We'd normally use ~~inp for this, but unfortunately it also
25432        // converts floats to ints.
25433        // inp may be undefined, so careful calling replace on it.
25434        var res = inp && parseFloat(inp.replace(',', '.'));
25435        // apply sign while we're at it
25436        return (isNaN(res) ? 0 : res) * sign;
25437    }
25438
25439    function positiveMomentsDifference(base, other) {
25440        var res = {};
25441
25442        res.months =
25443            other.month() - base.month() + (other.year() - base.year()) * 12;
25444        if (base.clone().add(res.months, 'M').isAfter(other)) {
25445            --res.months;
25446        }
25447
25448        res.milliseconds = +other - +base.clone().add(res.months, 'M');
25449
25450        return res;
25451    }
25452
25453    function momentsDifference(base, other) {
25454        var res;
25455        if (!(base.isValid() && other.isValid())) {
25456            return { milliseconds: 0, months: 0 };
25457        }
25458
25459        other = cloneWithOffset(other, base);
25460        if (base.isBefore(other)) {
25461            res = positiveMomentsDifference(base, other);
25462        } else {
25463            res = positiveMomentsDifference(other, base);
25464            res.milliseconds = -res.milliseconds;
25465            res.months = -res.months;
25466        }
25467
25468        return res;
25469    }
25470
25471    // TODO: remove 'name' arg after deprecation is removed
25472    function createAdder(direction, name) {
25473        return function (val, period) {
25474            var dur, tmp;
25475            //invert the arguments, but complain about it
25476            if (period !== null && !isNaN(+period)) {
25477                deprecateSimple(
25478                    name,
25479                    'moment().' +
25480                        name +
25481                        '(period, number) is deprecated. Please use moment().' +
25482                        name +
25483                        '(number, period). ' +
25484                        'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
25485                );
25486                tmp = val;
25487                val = period;
25488                period = tmp;
25489            }
25490
25491            dur = createDuration(val, period);
25492            addSubtract(this, dur, direction);
25493            return this;
25494        };
25495    }
25496
25497    function addSubtract(mom, duration, isAdding, updateOffset) {
25498        var milliseconds = duration._milliseconds,
25499            days = absRound(duration._days),
25500            months = absRound(duration._months);
25501
25502        if (!mom.isValid()) {
25503            // No op
25504            return;
25505        }
25506
25507        updateOffset = updateOffset == null ? true : updateOffset;
25508
25509        if (months) {
25510            setMonth(mom, get(mom, 'Month') + months * isAdding);
25511        }
25512        if (days) {
25513            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
25514        }
25515        if (milliseconds) {
25516            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
25517        }
25518        if (updateOffset) {
25519            hooks.updateOffset(mom, days || months);
25520        }
25521    }
25522
25523    var add = createAdder(1, 'add'),
25524        subtract = createAdder(-1, 'subtract');
25525
25526    function isString(input) {
25527        return typeof input === 'string' || input instanceof String;
25528    }
25529
25530    // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
25531    function isMomentInput(input) {
25532        return (
25533            isMoment(input) ||
25534            isDate(input) ||
25535            isString(input) ||
25536            isNumber(input) ||
25537            isNumberOrStringArray(input) ||
25538            isMomentInputObject(input) ||
25539            input === null ||
25540            input === undefined
25541        );
25542    }
25543
25544    function isMomentInputObject(input) {
25545        var objectTest = isObject(input) && !isObjectEmpty(input),
25546            propertyTest = false,
25547            properties = [
25548                'years',
25549                'year',
25550                'y',
25551                'months',
25552                'month',
25553                'M',
25554                'days',
25555                'day',
25556                'd',
25557                'dates',
25558                'date',
25559                'D',
25560                'hours',
25561                'hour',
25562                'h',
25563                'minutes',
25564                'minute',
25565                'm',
25566                'seconds',
25567                'second',
25568                's',
25569                'milliseconds',
25570                'millisecond',
25571                'ms',
25572            ],
25573            i,
25574            property,
25575            propertyLen = properties.length;
25576
25577        for (i = 0; i < propertyLen; i += 1) {
25578            property = properties[i];
25579            propertyTest = propertyTest || hasOwnProp(input, property);
25580        }
25581
25582        return objectTest && propertyTest;
25583    }
25584
25585    function isNumberOrStringArray(input) {
25586        var arrayTest = isArray(input),
25587            dataTypeTest = false;
25588        if (arrayTest) {
25589            dataTypeTest =
25590                input.filter(function (item) {
25591                    return !isNumber(item) && isString(input);
25592                }).length === 0;
25593        }
25594        return arrayTest && dataTypeTest;
25595    }
25596
25597    function isCalendarSpec(input) {
25598        var objectTest = isObject(input) && !isObjectEmpty(input),
25599            propertyTest = false,
25600            properties = [
25601                'sameDay',
25602                'nextDay',
25603                'lastDay',
25604                'nextWeek',
25605                'lastWeek',
25606                'sameElse',
25607            ],
25608            i,
25609            property;
25610
25611        for (i = 0; i < properties.length; i += 1) {
25612            property = properties[i];
25613            propertyTest = propertyTest || hasOwnProp(input, property);
25614        }
25615
25616        return objectTest && propertyTest;
25617    }
25618
25619    function getCalendarFormat(myMoment, now) {
25620        var diff = myMoment.diff(now, 'days', true);
25621        return diff < -6
25622            ? 'sameElse'
25623            : diff < -1
25624            ? 'lastWeek'
25625            : diff < 0
25626            ? 'lastDay'
25627            : diff < 1
25628            ? 'sameDay'
25629            : diff < 2
25630            ? 'nextDay'
25631            : diff < 7
25632            ? 'nextWeek'
25633            : 'sameElse';
25634    }
25635
25636    function calendar$1(time, formats) {
25637        // Support for single parameter, formats only overload to the calendar function
25638        if (arguments.length === 1) {
25639            if (!arguments[0]) {
25640                time = undefined;
25641                formats = undefined;
25642            } else
vendor: 17,627 bytes, lines 25642-26200
25642 if (isMomentInput(arguments[0])) {
25643                time = arguments[0];
25644                formats = undefined;
25645            } else if (isCalendarSpec(arguments[0])) {
25646                formats = arguments[0];
25647                time = undefined;
25648            }
25649        }
25650        // We want to compare the start of today, vs this.
25651        // Getting start-of-today depends on whether we're local/utc/offset or not.
25652        var now = time || createLocal(),
25653            sod = cloneWithOffset(now, this).startOf('day'),
25654            format = hooks.calendarFormat(this, sod) || 'sameElse',
25655            output =
25656                formats &&
25657                (isFunction(formats[format])
25658                    ? formats[format].call(this, now)
25659                    : formats[format]);
25660
25661        return this.format(
25662            output || this.localeData().calendar(format, this, createLocal(now))
25663        );
25664    }
25665
25666    function clone() {
25667        return new Moment(this);
25668    }
25669
25670    function isAfter(input, units) {
25671        var localInput = isMoment(input) ? input : createLocal(input);
25672        if (!(this.isValid() && localInput.isValid())) {
25673            return false;
25674        }
25675        units = normalizeUnits(units) || 'millisecond';
25676        if (units === 'millisecond') {
25677            return this.valueOf() > localInput.valueOf();
25678        } else {
25679            return localInput.valueOf() < this.clone().startOf(units).valueOf();
25680        }
25681    }
25682
25683    function isBefore(input, units) {
25684        var localInput = isMoment(input) ? input : createLocal(input);
25685        if (!(this.isValid() && localInput.isValid())) {
25686            return false;
25687        }
25688        units = normalizeUnits(units) || 'millisecond';
25689        if (units === 'millisecond') {
25690            return this.valueOf() < localInput.valueOf();
25691        } else {
25692            return this.clone().endOf(units).valueOf() < localInput.valueOf();
25693        }
25694    }
25695
25696    function isBetween(from, to, units, inclusivity) {
25697        var localFrom = isMoment(from) ? from : createLocal(from),
25698            localTo = isMoment(to) ? to : createLocal(to);
25699        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
25700            return false;
25701        }
25702        inclusivity = inclusivity || '()';
25703        return (
25704            (inclusivity[0] === '('
25705                ? this.isAfter(localFrom, units)
25706                : !this.isBefore(localFrom, units)) &&
25707            (inclusivity[1] === ')'
25708                ? this.isBefore(localTo, units)
25709                : !this.isAfter(localTo, units))
25710        );
25711    }
25712
25713    function isSame(input, units) {
25714        var localInput = isMoment(input) ? input : createLocal(input),
25715            inputMs;
25716        if (!(this.isValid() && localInput.isValid())) {
25717            return false;
25718        }
25719        units = normalizeUnits(units) || 'millisecond';
25720        if (units === 'millisecond') {
25721            return this.valueOf() === localInput.valueOf();
25722        } else {
25723            inputMs = localInput.valueOf();
25724            return (
25725                this.clone().startOf(units).valueOf() <= inputMs &&
25726                inputMs <= this.clone().endOf(units).valueOf()
25727            );
25728        }
25729    }
25730
25731    function isSameOrAfter(input, units) {
25732        return this.isSame(input, units) || this.isAfter(input, units);
25733    }
25734
25735    function isSameOrBefore(input, units) {
25736        return this.isSame(input, units) || this.isBefore(input, units);
25737    }
25738
25739    function diff(input, units, asFloat) {
25740        var that, zoneDelta, output;
25741
25742        if (!this.isValid()) {
25743            return NaN;
25744        }
25745
25746        that = cloneWithOffset(input, this);
25747
25748        if (!that.isValid()) {
25749            return NaN;
25750        }
25751
25752        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
25753
25754        units = normalizeUnits(units);
25755
25756        switch (units) {
25757            case 'year':
25758                output = monthDiff(this, that) / 12;
25759                break;
25760            case 'month':
25761                output = monthDiff(this, that);
25762                break;
25763            case 'quarter':
25764                output = monthDiff(this, that) / 3;
25765                break;
25766            case 'second':
25767                output = (this - that) / 1e3;
25768                break; // 1000
25769            case 'minute':
25770                output = (this - that) / 6e4;
25771                break; // 1000 * 60
25772            case 'hour':
25773                output = (this - that) / 36e5;
25774                break; // 1000 * 60 * 60
25775            case 'day':
25776                output = (this - that - zoneDelta) / 864e5;
25777                break; // 1000 * 60 * 60 * 24, negate dst
25778            case 'week':
25779                output = (this - that - zoneDelta) / 6048e5;
25780                break; // 1000 * 60 * 60 * 24 * 7, negate dst
25781            default:
25782                output = this - that;
25783        }
25784
25785        return asFloat ? output : absFloor(output);
25786    }
25787
25788    function monthDiff(a, b) {
25789        if (a.date() < b.date()) {
25790            // end-of-month calculations work correct when the start month has more
25791            // days than the end month.
25792            return -monthDiff(b, a);
25793        }
25794        // difference in months
25795        var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
25796            // b is in (anchor - 1 month, anchor + 1 month)
25797            anchor = a.clone().add(wholeMonthDiff, 'months'),
25798            anchor2,
25799            adjust;
25800
25801        if (b - anchor < 0) {
25802            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
25803            // linear across the month
25804            adjust = (b - anchor) / (anchor - anchor2);
25805        } else {
25806            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
25807            // linear across the month
25808            adjust = (b - anchor) / (anchor2 - anchor);
25809        }
25810
25811        //check for negative zero, return zero if negative zero
25812        return -(wholeMonthDiff + adjust) || 0;
25813    }
25814
25815    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
25816    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
25817
25818    function toString() {
25819        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
25820    }
25821
25822    function toISOString(keepOffset) {
25823        if (!this.isValid()) {
25824            return null;
25825        }
25826        var utc = keepOffset !== true,
25827            m = utc ? this.clone().utc() : this;
25828        if (m.year() < 0 || m.year() > 9999) {
25829            return formatMoment(
25830                m,
25831                utc
25832                    ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
25833                    : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
25834            );
25835        }
25836        if (isFunction(Date.prototype.toISOString)) {
25837            // native implementation is ~50x faster, use it when we can
25838            if (utc) {
25839                return this.toDate().toISOString();
25840            } else {
25841                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
25842                    .toISOString()
25843                    .replace('Z', formatMoment(m, 'Z'));
25844            }
25845        }
25846        return formatMoment(
25847            m,
25848            utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
25849        );
25850    }
25851
25852    /**
25853     * Return a human readable representation of a moment that can
25854     * also be evaluated to get a new moment which is the same
25855     *
25856     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
25857     */
25858    function inspect() {
25859        if (!this.isValid()) {
25860            return 'moment.invalid(/* ' + this._i + ' */)';
25861        }
25862        var func = 'moment',
25863            zone = '',
25864            prefix,
25865            year,
25866            datetime,
25867            suffix;
25868        if (!this.isLocal()) {
25869            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
25870            zone = 'Z';
25871        }
25872        prefix = '[' + func + '("]';
25873        year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
25874        datetime = '-MM-DD[T]HH:mm:ss.SSS';
25875        suffix = zone + '[")]';
25876
25877        return this.format(prefix + year + datetime + suffix);
25878    }
25879
25880    function format(inputString) {
25881        if (!inputString) {
25882            inputString = this.isUtc()
25883                ? hooks.defaultFormatUtc
25884                : hooks.defaultFormat;
25885        }
25886        var output = formatMoment(this, inputString);
25887        return this.localeData().postformat(output);
25888    }
25889
25890    function from(time, withoutSuffix) {
25891        if (
25892            this.isValid() &&
25893            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
25894        ) {
25895            return createDuration({ to: this, from: time })
25896                .locale(this.locale())
25897                .humanize(!withoutSuffix);
25898        } else {
25899            return this.localeData().invalidDate();
25900        }
25901    }
25902
25903    function fromNow(withoutSuffix) {
25904        return this.from(createLocal(), withoutSuffix);
25905    }
25906
25907    function to(time, withoutSuffix) {
25908        if (
25909            this.isValid() &&
25910            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
25911        ) {
25912            return createDuration({ from: this, to: time })
25913                .locale(this.locale())
25914                .humanize(!withoutSuffix);
25915        } else {
25916            return this.localeData().invalidDate();
25917        }
25918    }
25919
25920    function toNow(withoutSuffix) {
25921        return this.to(createLocal(), withoutSuffix);
25922    }
25923
25924    // If passed a locale key, it will set the locale for this
25925    // instance.  Otherwise, it will return the locale configuration
25926    // variables for this instance.
25927    function locale(key) {
25928        var newLocaleData;
25929
25930        if (key === undefined) {
25931            return this._locale._abbr;
25932        } else {
25933            newLocaleData = getLocale(key);
25934            if (newLocaleData != null) {
25935                this._locale = newLocaleData;
25936            }
25937            return this;
25938        }
25939    }
25940
25941    var lang = deprecate(
25942        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
25943        function (key) {
25944            if (key === undefined) {
25945                return this.localeData();
25946            } else {
25947                return this.locale(key);
25948            }
25949        }
25950    );
25951
25952    function localeData() {
25953        return this._locale;
25954    }
25955
25956    var MS_PER_SECOND = 1000,
25957        MS_PER_MINUTE = 60 * MS_PER_SECOND,
25958        MS_PER_HOUR = 60 * MS_PER_MINUTE,
25959        MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
25960
25961    // actual modulo - handles negative numbers (for dates before 1970):
25962    function mod$1(dividend, divisor) {
25963        return ((dividend % divisor) + divisor) % divisor;
25964    }
25965
25966    function localStartOfDate(y, m, d) {
25967        // the date constructor remaps years 0-99 to 1900-1999
25968        if (y < 100 && y >= 0) {
25969            // preserve leap years using a full 400 year cycle, then reset
25970            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
25971        } else {
25972            return new Date(y, m, d).valueOf();
25973        }
25974    }
25975
25976    function utcStartOfDate(y, m, d) {
25977        // Date.UTC remaps years 0-99 to 1900-1999
25978        if (y < 100 && y >= 0) {
25979            // preserve leap years using a full 400 year cycle, then reset
25980            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
25981        } else {
25982            return Date.UTC(y, m, d);
25983        }
25984    }
25985
25986    function startOf(units) {
25987        var time, startOfDate;
25988        units = normalizeUnits(units);
25989        if (units === undefined || units === 'millisecond' || !this.isValid()) {
25990            return this;
25991        }
25992
25993        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
25994
25995        switch (units) {
25996            case 'year':
25997                time = startOfDate(this.year(), 0, 1);
25998                break;
25999            case 'quarter':
26000                time = startOfDate(
26001                    this.year(),
26002                    this.month() - (this.month() % 3),
26003                    1
26004                );
26005                break;
26006            case 'month':
26007                time = startOfDate(this.year(), this.month(), 1);
26008                break;
26009            case 'week':
26010                time = startOfDate(
26011                    this.year(),
26012                    this.month(),
26013                    this.date() - this.weekday()
26014                );
26015                break;
26016            case 'isoWeek':
26017                time = startOfDate(
26018                    this.year(),
26019                    this.month(),
26020                    this.date() - (this.isoWeekday() - 1)
26021                );
26022                break;
26023            case 'day':
26024            case 'date':
26025                time = startOfDate(this.year(), this.month(), this.date());
26026                break;
26027            case 'hour':
26028                time = this._d.valueOf();
26029                time -= mod$1(
26030                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
26031                    MS_PER_HOUR
26032                );
26033                break;
26034            case 'minute':
26035                time = this._d.valueOf();
26036                time -= mod$1(time, MS_PER_MINUTE);
26037                break;
26038            case 'second':
26039                time = this._d.valueOf();
26040                time -= mod$1(time, MS_PER_SECOND);
26041                break;
26042        }
26043
26044        this._d.setTime(time);
26045        hooks.updateOffset(this, true);
26046        return this;
26047    }
26048
26049    function endOf(units) {
26050        var time, startOfDate;
26051        units = normalizeUnits(units);
26052        if (units === undefined || units === 'millisecond' || !this.isValid()) {
26053            return this;
26054        }
26055
26056        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
26057
26058        switch (units) {
26059            case 'year':
26060                time = startOfDate(this.year() + 1, 0, 1) - 1;
26061                break;
26062            case 'quarter':
26063                time =
26064                    startOfDate(
26065                        this.year(),
26066                        this.month() - (this.month() % 3) + 3,
26067                        1
26068                    ) - 1;
26069                break;
26070            case 'month':
26071                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
26072                break;
26073            case 'week':
26074                time =
26075                    startOfDate(
26076                        this.year(),
26077                        this.month(),
26078                        this.date() - this.weekday() + 7
26079                    ) - 1;
26080                break;
26081            case 'isoWeek':
26082                time =
26083                    startOfDate(
26084                        this.year(),
26085                        this.month(),
26086                        this.date() - (this.isoWeekday() - 1) + 7
26087                    ) - 1;
26088                break;
26089            case 'day':
26090            case 'date':
26091                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
26092                break;
26093            case 'hour':
26094                time = this._d.valueOf();
26095                time +=
26096                    MS_PER_HOUR -
26097                    mod$1(
26098                        time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
26099                        MS_PER_HOUR
26100                    ) -
26101                    1;
26102                break;
26103            case 'minute':
26104                time = this._d.valueOf();
26105                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
26106                break;
26107            case 'second':
26108                time = this._d.valueOf();
26109                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
26110                break;
26111        }
26112
26113        this._d.setTime(time);
26114        hooks.updateOffset(this, true);
26115        return this;
26116    }
26117
26118    function valueOf() {
26119        return this._d.valueOf() - (this._offset || 0) * 60000;
26120    }
26121
26122    function unix() {
26123        return Math.floor(this.valueOf() / 1000);
26124    }
26125
26126    function toDate() {
26127        return new Date(this.valueOf());
26128    }
26129
26130    function toArray() {
26131        var m = this;
26132        return [
26133            m.year(),
26134            m.month(),
26135            m.date(),
26136            m.hour(),
26137            m.minute(),
26138            m.second(),
26139            m.millisecond(),
26140        ];
26141    }
26142
26143    function toObject() {
26144        var m = this;
26145        return {
26146            years: m.year(),
26147            months: m.month(),
26148            date: m.date(),
26149            hours: m.hours(),
26150            minutes: m.minutes(),
26151            seconds: m.seconds(),
26152            milliseconds: m.milliseconds(),
26153        };
26154    }
26155
26156    function toJSON() {
26157        // new Date(NaN).toJSON() === null
26158        return this.isValid() ? this.toISOString() : null;
26159    }
26160
26161    function isValid$2() {
26162        return isValid(this);
26163    }
26164
26165    function parsingFlags() {
26166        return extend({}, getParsingFlags(this));
26167    }
26168
26169    function invalidAt() {
26170        return getParsingFlags(this).overflow;
26171    }
26172
26173    function creationData() {
26174        return {
26175            input: this._i,
26176            format: this._f,
26177            locale: this._locale,
26178            isUTC: this._isUTC,
26179            strict: this._strict,
26180        };
26181    }
26182
26183    addFormatToken('N', 0, 0, 'eraAbbr');
26184    addFormatToken('NN', 0, 0, 'eraAbbr');
26185    addFormatToken('NNN', 0, 0, 'eraAbbr');
26186    addFormatToken('NNNN', 0, 0, 'eraName');
26187    addFormatToken('NNNNN', 0, 0, 'eraNarrow');
26188
26189    addFormatToken('y', ['y', 1], 'yo', 'eraYear');
26190    addFormatToken('y', ['yy', 2], 0, 'eraYear');
26191    addFormatToken('y', ['yyy', 3], 0, 'eraYear');
26192    addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
26193
26194    addRegexToken('N', matchEraAbbr);
26195    addRegexToken('NN', matchEraAbbr);
26196    addRegexToken('NNN', matchEraAbbr);
26197    addRegexToken('NNNN', matchEraName);
26198    addRegexToken('NNNNN', matchEraNarrow);
26199
26200    addParseToken(
vendor: 8,145 bytes, lines 26200-26475
26200
26201        ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
26202        function (input, array, config, token) {
26203            var era = config._locale.erasParse(input, token, config._strict);
26204            if (era) {
26205                getParsingFlags(config).era = era;
26206            } else {
26207                getParsingFlags(config).invalidEra = input;
26208            }
26209        }
26210    );
26211
26212    addRegexToken('y', matchUnsigned);
26213    addRegexToken('yy', matchUnsigned);
26214    addRegexToken('yyy', matchUnsigned);
26215    addRegexToken('yyyy', matchUnsigned);
26216    addRegexToken('yo', matchEraYearOrdinal);
26217
26218    addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
26219    addParseToken(['yo'], function (input, array, config, token) {
26220        var match;
26221        if (config._locale._eraYearOrdinalRegex) {
26222            match = input.match(config._locale._eraYearOrdinalRegex);
26223        }
26224
26225        if (config._locale.eraYearOrdinalParse) {
26226            array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
26227        } else {
26228            array[YEAR] = parseInt(input, 10);
26229        }
26230    });
26231
26232    function localeEras(m, format) {
26233        var i,
26234            l,
26235            date,
26236            eras = this._eras || getLocale('en')._eras;
26237        for (i = 0, l = eras.length; i < l; ++i) {
26238            switch (typeof eras[i].since) {
26239                case 'string':
26240                    // truncate time
26241                    date = hooks(eras[i].since).startOf('day');
26242                    eras[i].since = date.valueOf();
26243                    break;
26244            }
26245
26246            switch (typeof eras[i].until) {
26247                case 'undefined':
26248                    eras[i].until = +Infinity;
26249                    break;
26250                case 'string':
26251                    // truncate time
26252                    date = hooks(eras[i].until).startOf('day').valueOf();
26253                    eras[i].until = date.valueOf();
26254                    break;
26255            }
26256        }
26257        return eras;
26258    }
26259
26260    function localeErasParse(eraName, format, strict) {
26261        var i,
26262            l,
26263            eras = this.eras(),
26264            name,
26265            abbr,
26266            narrow;
26267        eraName = eraName.toUpperCase();
26268
26269        for (i = 0, l = eras.length; i < l; ++i) {
26270            name = eras[i].name.toUpperCase();
26271            abbr = eras[i].abbr.toUpperCase();
26272            narrow = eras[i].narrow.toUpperCase();
26273
26274            if (strict) {
26275                switch (format) {
26276                    case 'N':
26277                    case 'NN':
26278                    case 'NNN':
26279                        if (abbr === eraName) {
26280                            return eras[i];
26281                        }
26282                        break;
26283
26284                    case 'NNNN':
26285                        if (name === eraName) {
26286                            return eras[i];
26287                        }
26288                        break;
26289
26290                    case 'NNNNN':
26291                        if (narrow === eraName) {
26292                            return eras[i];
26293                        }
26294                        break;
26295                }
26296            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
26297                return eras[i];
26298            }
26299        }
26300    }
26301
26302    function localeErasConvertYear(era, year) {
26303        var dir = era.since <= era.until ? +1 : -1;
26304        if (year === undefined) {
26305            return hooks(era.since).year();
26306        } else {
26307            return hooks(era.since).year() + (year - era.offset) * dir;
26308        }
26309    }
26310
26311    function getEraName() {
26312        var i,
26313            l,
26314            val,
26315            eras = this.localeData().eras();
26316        for (i = 0, l = eras.length; i < l; ++i) {
26317            // truncate time
26318            val = this.clone().startOf('day').valueOf();
26319
26320            if (eras[i].since <= val && val <= eras[i].until) {
26321                return eras[i].name;
26322            }
26323            if (eras[i].until <= val && val <= eras[i].since) {
26324                return eras[i].name;
26325            }
26326        }
26327
26328        return '';
26329    }
26330
26331    function getEraNarrow() {
26332        var i,
26333            l,
26334            val,
26335            eras = this.localeData().eras();
26336        for (i = 0, l = eras.length; i < l; ++i) {
26337            // truncate time
26338            val = this.clone().startOf('day').valueOf();
26339
26340            if (eras[i].since <= val && val <= eras[i].until) {
26341                return eras[i].narrow;
26342            }
26343            if (eras[i].until <= val && val <= eras[i].since) {
26344                return eras[i].narrow;
26345            }
26346        }
26347
26348        return '';
26349    }
26350
26351    function getEraAbbr() {
26352        var i,
26353            l,
26354            val,
26355            eras = this.localeData().eras();
26356        for (i = 0, l = eras.length; i < l; ++i) {
26357            // truncate time
26358            val = this.clone().startOf('day').valueOf();
26359
26360            if (eras[i].since <= val && val <= eras[i].until) {
26361                return eras[i].abbr;
26362            }
26363            if (eras[i].until <= val && val <= eras[i].since) {
26364                return eras[i].abbr;
26365            }
26366        }
26367
26368        return '';
26369    }
26370
26371    function getEraYear() {
26372        var i,
26373            l,
26374            dir,
26375            val,
26376            eras = this.localeData().eras();
26377        for (i = 0, l = eras.length; i < l; ++i) {
26378            dir = eras[i].since <= eras[i].until ? +1 : -1;
26379
26380            // truncate time
26381            val = this.clone().startOf('day').valueOf();
26382
26383            if (
26384                (eras[i].since <= val && val <= eras[i].until) ||
26385                (eras[i].until <= val && val <= eras[i].since)
26386            ) {
26387                return (
26388                    (this.year() - hooks(eras[i].since).year()) * dir +
26389                    eras[i].offset
26390                );
26391            }
26392        }
26393
26394        return this.year();
26395    }
26396
26397    function erasNameRegex(isStrict) {
26398        if (!hasOwnProp(this, '_erasNameRegex')) {
26399            computeErasParse.call(this);
26400        }
26401        return isStrict ? this._erasNameRegex : this._erasRegex;
26402    }
26403
26404    function erasAbbrRegex(isStrict) {
26405        if (!hasOwnProp(this, '_erasAbbrRegex')) {
26406            computeErasParse.call(this);
26407        }
26408        return isStrict ? this._erasAbbrRegex : this._erasRegex;
26409    }
26410
26411    function erasNarrowRegex(isStrict) {
26412        if (!hasOwnProp(this, '_erasNarrowRegex')) {
26413            computeErasParse.call(this);
26414        }
26415        return isStrict ? this._erasNarrowRegex : this._erasRegex;
26416    }
26417
26418    function matchEraAbbr(isStrict, locale) {
26419        return locale.erasAbbrRegex(isStrict);
26420    }
26421
26422    function matchEraName(isStrict, locale) {
26423        return locale.erasNameRegex(isStrict);
26424    }
26425
26426    function matchEraNarrow(isStrict, locale) {
26427        return locale.erasNarrowRegex(isStrict);
26428    }
26429
26430    function matchEraYearOrdinal(isStrict, locale) {
26431        return locale._eraYearOrdinalRegex || matchUnsigned;
26432    }
26433
26434    function computeErasParse() {
26435        var abbrPieces = [],
26436            namePieces = [],
26437            narrowPieces = [],
26438            mixedPieces = [],
26439            i,
26440            l,
26441            eras = this.eras();
26442
26443        for (i = 0, l = eras.length; i < l; ++i) {
26444            namePieces.push(regexEscape(eras[i].name));
26445            abbrPieces.push(regexEscape(eras[i].abbr));
26446            narrowPieces.push(regexEscape(eras[i].narrow));
26447
26448            mixedPieces.push(regexEscape(eras[i].name));
26449            mixedPieces.push(regexEscape(eras[i].abbr));
26450            mixedPieces.push(regexEscape(eras[i].narrow));
26451        }
26452
26453        this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
26454        this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
26455        this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
26456        this._erasNarrowRegex = new RegExp(
26457            '^(' + narrowPieces.join('|') + ')',
26458            'i'
26459        );
26460    }
26461
26462    // FORMATTING
26463
26464    addFormatToken(0, ['gg', 2], 0, function () {
26465        return this.weekYear() % 100;
26466    });
26467
26468    addFormatToken(0, ['GG', 2], 0, function () {
26469        return this.isoWeekYear() % 100;
26470    });
26471
26472    function addWeekYearFormatToken(token, getter) {
26473        addFormatToken(0, [token, token.length], 0, getter);
26474    }
26475
26476    addWeekYearFormatToken('gggg', 'weekYear');
26477    addWeekYearFormatToken('ggggg', 'weekYear');
26478    addWeekYearFormatToken('GGGG', 'isoWeekYear');
26479    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
26480
26481    // ALIASES
26482
26483    addUnitAlias('weekYear', 'gg');
26484    addUnitAlias('isoWeekYear', 'GG');
26485
26486    // PRIORITY
26487
26488    addUnitPriority('weekYear', 1);
26489    addUnitPriority('isoWeekYear', 1);
26490
26491    // PARSING
26492
26493    addRegexToken('G', matchSigned);
26494    addRegexToken('g', matchSigned);
26495    addRegexToken('GG', match1to2, match2);
26496    addRegexToken('gg', match1to2, match2);
26497    addRegexToken('GGGG', match1to4, match4);
26498    addRegexToken('gggg', match1to4, match4);
26499    addRegexToken('GGGGG', match1to6, match6);
26500    addRegexToken('ggggg', match1to6, match6);
26501
26502    addWeekParseToken(
26503        ['gggg', 'ggggg', 'GGGG', 'GGGGG'],
26504        function (input, week, config, token) {
26505            week[token.substr(0, 2)] = toInt(input);
26506        }
26507    
vendor: 29,543 bytes, lines 26507-27530
26507);
26508
26509    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
26510        week[token] = hooks.parseTwoDigitYear(input);
26511    });
26512
26513    // MOMENTS
26514
26515    function getSetWeekYear(input) {
26516        return getSetWeekYearHelper.call(
26517            this,
26518            input,
26519            this.week(),
26520            this.weekday(),
26521            this.localeData()._week.dow,
26522            this.localeData()._week.doy
26523        );
26524    }
26525
26526    function getSetISOWeekYear(input) {
26527        return getSetWeekYearHelper.call(
26528            this,
26529            input,
26530            this.isoWeek(),
26531            this.isoWeekday(),
26532            1,
26533            4
26534        );
26535    }
26536
26537    function getISOWeeksInYear() {
26538        return weeksInYear(this.year(), 1, 4);
26539    }
26540
26541    function getISOWeeksInISOWeekYear() {
26542        return weeksInYear(this.isoWeekYear(), 1, 4);
26543    }
26544
26545    function getWeeksInYear() {
26546        var weekInfo = this.localeData()._week;
26547        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
26548    }
26549
26550    function getWeeksInWeekYear() {
26551        var weekInfo = this.localeData()._week;
26552        return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
26553    }
26554
26555    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
26556        var weeksTarget;
26557        if (input == null) {
26558            return weekOfYear(this, dow, doy).year;
26559        } else {
26560            weeksTarget = weeksInYear(input, dow, doy);
26561            if (week > weeksTarget) {
26562                week = weeksTarget;
26563            }
26564            return setWeekAll.call(this, input, week, weekday, dow, doy);
26565        }
26566    }
26567
26568    function setWeekAll(weekYear, week, weekday, dow, doy) {
26569        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
26570            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
26571
26572        this.year(date.getUTCFullYear());
26573        this.month(date.getUTCMonth());
26574        this.date(date.getUTCDate());
26575        return this;
26576    }
26577
26578    // FORMATTING
26579
26580    addFormatToken('Q', 0, 'Qo', 'quarter');
26581
26582    // ALIASES
26583
26584    addUnitAlias('quarter', 'Q');
26585
26586    // PRIORITY
26587
26588    addUnitPriority('quarter', 7);
26589
26590    // PARSING
26591
26592    addRegexToken('Q', match1);
26593    addParseToken('Q', function (input, array) {
26594        array[MONTH] = (toInt(input) - 1) * 3;
26595    });
26596
26597    // MOMENTS
26598
26599    function getSetQuarter(input) {
26600        return input == null
26601            ? Math.ceil((this.month() + 1) / 3)
26602            : this.month((input - 1) * 3 + (this.month() % 3));
26603    }
26604
26605    // FORMATTING
26606
26607    addFormatToken('D', ['DD', 2], 'Do', 'date');
26608
26609    // ALIASES
26610
26611    addUnitAlias('date', 'D');
26612
26613    // PRIORITY
26614    addUnitPriority('date', 9);
26615
26616    // PARSING
26617
26618    addRegexToken('D', match1to2);
26619    addRegexToken('DD', match1to2, match2);
26620    addRegexToken('Do', function (isStrict, locale) {
26621        // TODO: Remove "ordinalParse" fallback in next major release.
26622        return isStrict
26623            ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
26624            : locale._dayOfMonthOrdinalParseLenient;
26625    });
26626
26627    addParseToken(['D', 'DD'], DATE);
26628    addParseToken('Do', function (input, array) {
26629        array[DATE] = toInt(input.match(match1to2)[0]);
26630    });
26631
26632    // MOMENTS
26633
26634    var getSetDayOfMonth = makeGetSet('Date', true);
26635
26636    // FORMATTING
26637
26638    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
26639
26640    // ALIASES
26641
26642    addUnitAlias('dayOfYear', 'DDD');
26643
26644    // PRIORITY
26645    addUnitPriority('dayOfYear', 4);
26646
26647    // PARSING
26648
26649    addRegexToken('DDD', match1to3);
26650    addRegexToken('DDDD', match3);
26651    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
26652        config._dayOfYear = toInt(input);
26653    });
26654
26655    // HELPERS
26656
26657    // MOMENTS
26658
26659    function getSetDayOfYear(input) {
26660        var dayOfYear =
26661            Math.round(
26662                (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
26663            ) + 1;
26664        return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
26665    }
26666
26667    // FORMATTING
26668
26669    addFormatToken('m', ['mm', 2], 0, 'minute');
26670
26671    // ALIASES
26672
26673    addUnitAlias('minute', 'm');
26674
26675    // PRIORITY
26676
26677    addUnitPriority('minute', 14);
26678
26679    // PARSING
26680
26681    addRegexToken('m', match1to2);
26682    addRegexToken('mm', match1to2, match2);
26683    addParseToken(['m', 'mm'], MINUTE);
26684
26685    // MOMENTS
26686
26687    var getSetMinute = makeGetSet('Minutes', false);
26688
26689    // FORMATTING
26690
26691    addFormatToken('s', ['ss', 2], 0, 'second');
26692
26693    // ALIASES
26694
26695    addUnitAlias('second', 's');
26696
26697    // PRIORITY
26698
26699    addUnitPriority('second', 15);
26700
26701    // PARSING
26702
26703    addRegexToken('s', match1to2);
26704    addRegexToken('ss', match1to2, match2);
26705    addParseToken(['s', 'ss'], SECOND);
26706
26707    // MOMENTS
26708
26709    var getSetSecond = makeGetSet('Seconds', false);
26710
26711    // FORMATTING
26712
26713    addFormatToken('S', 0, 0, function () {
26714        return ~~(this.millisecond() / 100);
26715    });
26716
26717    addFormatToken(0, ['SS', 2], 0, function () {
26718        return ~~(this.millisecond() / 10);
26719    });
26720
26721    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
26722    addFormatToken(0, ['SSSS', 4], 0, function () {
26723        return this.millisecond() * 10;
26724    });
26725    addFormatToken(0, ['SSSSS', 5], 0, function () {
26726        return this.millisecond() * 100;
26727    });
26728    addFormatToken(0, ['SSSSSS', 6], 0, function () {
26729        return this.millisecond() * 1000;
26730    });
26731    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
26732        return this.millisecond() * 10000;
26733    });
26734    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
26735        return this.millisecond() * 100000;
26736    });
26737    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
26738        return this.millisecond() * 1000000;
26739    });
26740
26741    // ALIASES
26742
26743    addUnitAlias('millisecond', 'ms');
26744
26745    // PRIORITY
26746
26747    addUnitPriority('millisecond', 16);
26748
26749    // PARSING
26750
26751    addRegexToken('S', match1to3, match1);
26752    addRegexToken('SS', match1to3, match2);
26753    addRegexToken('SSS', match1to3, match3);
26754
26755    var token, getSetMillisecond;
26756    for (token = 'SSSS'; token.length <= 9; token += 'S') {
26757        addRegexToken(token, matchUnsigned);
26758    }
26759
26760    function parseMs(input, array) {
26761        array[MILLISECOND] = toInt(('0.' + input) * 1000);
26762    }
26763
26764    for (token = 'S'; token.length <= 9; token += 'S') {
26765        addParseToken(token, parseMs);
26766    }
26767
26768    getSetMillisecond = makeGetSet('Milliseconds', false);
26769
26770    // FORMATTING
26771
26772    addFormatToken('z', 0, 0, 'zoneAbbr');
26773    addFormatToken('zz', 0, 0, 'zoneName');
26774
26775    // MOMENTS
26776
26777    function getZoneAbbr() {
26778        return this._isUTC ? 'UTC' : '';
26779    }
26780
26781    function getZoneName() {
26782        return this._isUTC ? 'Coordinated Universal Time' : '';
26783    }
26784
26785    var proto = Moment.prototype;
26786
26787    proto.add = add;
26788    proto.calendar = calendar$1;
26789    proto.clone = clone;
26790    proto.diff = diff;
26791    proto.endOf = endOf;
26792    proto.format = format;
26793    proto.from = from;
26794    proto.fromNow = fromNow;
26795    proto.to = to;
26796    proto.toNow = toNow;
26797    proto.get = stringGet;
26798    proto.invalidAt = invalidAt;
26799    proto.isAfter = isAfter;
26800    proto.isBefore = isBefore;
26801    proto.isBetween = isBetween;
26802    proto.isSame = isSame;
26803    proto.isSameOrAfter = isSameOrAfter;
26804    proto.isSameOrBefore = isSameOrBefore;
26805    proto.isValid = isValid$2;
26806    proto.lang = lang;
26807    proto.locale = locale;
26808    proto.localeData = localeData;
26809    proto.max = prototypeMax;
26810    proto.min = prototypeMin;
26811    proto.parsingFlags = parsingFlags;
26812    proto.set = stringSet;
26813    proto.startOf = startOf;
26814    proto.subtract = subtract;
26815    proto.toArray = toArray;
26816    proto.toObject = toObject;
26817    proto.toDate = toDate;
26818    proto.toISOString = toISOString;
26819    proto.inspect = inspect;
26820    if (typeof Symbol !== 'undefined' && Symbol.for != null) {
26821        proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
26822            return 'Moment<' + this.format() + '>';
26823        };
26824    }
26825    proto.toJSON = toJSON;
26826    proto.toString = toString;
26827    proto.unix = unix;
26828    proto.valueOf = valueOf;
26829    proto.creationData = creationData;
26830    proto.eraName = getEraName;
26831    proto.eraNarrow = getEraNarrow;
26832    proto.eraAbbr = getEraAbbr;
26833    proto.eraYear = getEraYear;
26834    proto.year = getSetYear;
26835    proto.isLeapYear = getIsLeapYear;
26836    proto.weekYear = getSetWeekYear;
26837    proto.isoWeekYear = getSetISOWeekYear;
26838    proto.quarter = proto.quarters = getSetQuarter;
26839    proto.month = getSetMonth;
26840    proto.daysInMonth = getDaysInMonth;
26841    proto.week = proto.weeks = getSetWeek;
26842    proto.isoWeek = proto.isoWeeks = getSetISOWeek;
26843    proto.weeksInYear = getWeeksInYear;
26844    proto.weeksInWeekYear = getWeeksInWeekYear;
26845    proto.isoWeeksInYear = getISOWeeksInYear;
26846    proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
26847    proto.date = getSetDayOfMonth;
26848    proto.day = proto.days = getSetDayOfWeek;
26849    proto.weekday = getSetLocaleDayOfWeek;
26850    proto.isoWeekday = getSetISODayOfWeek;
26851    proto.dayOfYear = getSetDayOfYear;
26852    proto.hour = proto.hours = getSetHour;
26853    proto.minute = proto.minutes = getSetMinute;
26854    proto.second = proto.seconds = getSetSecond;
26855    proto.millisecond = proto.milliseconds = getSetMillisecond;
26856    proto.utcOffset = getSetOffset;
26857    proto.utc = setOffsetToUTC;
26858    proto.local = setOffsetToLocal;
26859    proto.parseZone = setOffsetToParsedOffset;
26860    proto.hasAlignedHourOffset = hasAlignedHourOffset;
26861    proto.isDST = isDaylightSavingTime;
26862    proto.isLocal = isLocal;
26863    proto.isUtcOffset = isUtcOffset;
26864    proto.isUtc = isUtc;
26865    proto.isUTC = isUtc;
26866    proto.zoneAbbr = getZoneAbbr;
26867    proto.zoneName = getZoneName;
26868    proto.dates = deprecate(
26869        'dates accessor is deprecated. Use date instead.',
26870        getSetDayOfMonth
26871    );
26872    proto.months = deprecate(
26873        'months accessor is deprecated. Use month instead',
26874        getSetMonth
26875    );
26876    proto.years = deprecate(
26877        'years accessor is deprecated. Use year instead',
26878        getSetYear
26879    );
26880    proto.zone = deprecate(
26881        'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
26882        getSetZone
26883    );
26884    proto.isDSTShifted = deprecate(
26885        'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
26886        isDaylightSavingTimeShifted
26887    );
26888
26889    function createUnix(input) {
26890        return createLocal(input * 1000);
26891    }
26892
26893    function createInZone() {
26894        return createLocal.apply(null, arguments).parseZone();
26895    }
26896
26897    function preParsePostFormat(string) {
26898        return string;
26899    }
26900
26901    var proto$1 = Locale.prototype;
26902
26903    proto$1.calendar = calendar;
26904    proto$1.longDateFormat = longDateFormat;
26905    proto$1.invalidDate = invalidDate;
26906    proto$1.ordinal = ordinal;
26907    proto$1.preparse = preParsePostFormat;
26908    proto$1.postformat = preParsePostFormat;
26909    proto$1.relativeTime = relativeTime;
26910    proto$1.pastFuture = pastFuture;
26911    proto$1.set = set;
26912    proto$1.eras = localeEras;
26913    proto$1.erasParse = localeErasParse;
26914    proto$1.erasConvertYear = localeErasConvertYear;
26915    proto$1.erasAbbrRegex = erasAbbrRegex;
26916    proto$1.erasNameRegex = erasNameRegex;
26917    proto$1.erasNarrowRegex = erasNarrowRegex;
26918
26919    proto$1.months = localeMonths;
26920    proto$1.monthsShort = localeMonthsShort;
26921    proto$1.monthsParse = localeMonthsParse;
26922    proto$1.monthsRegex = monthsRegex;
26923    proto$1.monthsShortRegex = monthsShortRegex;
26924    proto$1.week = localeWeek;
26925    proto$1.firstDayOfYear = localeFirstDayOfYear;
26926    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
26927
26928    proto$1.weekdays = localeWeekdays;
26929    proto$1.weekdaysMin = localeWeekdaysMin;
26930    proto$1.weekdaysShort = localeWeekdaysShort;
26931    proto$1.weekdaysParse = localeWeekdaysParse;
26932
26933    proto$1.weekdaysRegex = weekdaysRegex;
26934    proto$1.weekdaysShortRegex = weekdaysShortRegex;
26935    proto$1.weekdaysMinRegex = weekdaysMinRegex;
26936
26937    proto$1.isPM = localeIsPM;
26938    proto$1.meridiem = localeMeridiem;
26939
26940    function get$1(format, index, field, setter) {
26941        var locale = getLocale(),
26942            utc = createUTC().set(setter, index);
26943        return locale[field](utc, format);
26944    }
26945
26946    function listMonthsImpl(format, index, field) {
26947        if (isNumber(format)) {
26948            index = format;
26949            format = undefined;
26950        }
26951
26952        format = format || '';
26953
26954        if (index != null) {
26955            return get$1(format, index, field, 'month');
26956        }
26957
26958        var i,
26959            out = [];
26960        for (i = 0; i < 12; i++) {
26961            out[i] = get$1(format, i, field, 'month');
26962        }
26963        return out;
26964    }
26965
26966    // ()
26967    // (5)
26968    // (fmt, 5)
26969    // (fmt)
26970    // (true)
26971    // (true, 5)
26972    // (true, fmt, 5)
26973    // (true, fmt)
26974    function listWeekdaysImpl(localeSorted, format, index, field) {
26975        if (typeof localeSorted === 'boolean') {
26976            if (isNumber(format)) {
26977                index = format;
26978                format = undefined;
26979            }
26980
26981            format = format || '';
26982        } else {
26983            format = localeSorted;
26984            index = format;
26985            localeSorted = false;
26986
26987            if (isNumber(format)) {
26988                index = format;
26989                format = undefined;
26990            }
26991
26992            format = format || '';
26993        }
26994
26995        var locale = getLocale(),
26996            shift = localeSorted ? locale._week.dow : 0,
26997            i,
26998            out = [];
26999
27000        if (index != null) {
27001            return get$1(format, (index + shift) % 7, field, 'day');
27002        }
27003
27004        for (i = 0; i < 7; i++) {
27005            out[i] = get$1(format, (i + shift) % 7, field, 'day');
27006        }
27007        return out;
27008    }
27009
27010    function listMonths(format, index) {
27011        return listMonthsImpl(format, index, 'months');
27012    }
27013
27014    function listMonthsShort(format, index) {
27015        return listMonthsImpl(format, index, 'monthsShort');
27016    }
27017
27018    function listWeekdays(localeSorted, format, index) {
27019        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
27020    }
27021
27022    function listWeekdaysShort(localeSorted, format, index) {
27023        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
27024    }
27025
27026    function listWeekdaysMin(localeSorted, format, index) {
27027        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
27028    }
27029
27030    getSetGlobalLocale('en', {
27031        eras: [
27032            {
27033                since: '0001-01-01',
27034                until: +Infinity,
27035                offset: 1,
27036                name: 'Anno Domini',
27037                narrow: 'AD',
27038                abbr: 'AD',
27039            },
27040            {
27041                since: '0000-12-31',
27042                until: -Infinity,
27043                offset: 1,
27044                name: 'Before Christ',
27045                narrow: 'BC',
27046                abbr: 'BC',
27047            },
27048        ],
27049        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
27050        ordinal: function (number) {
27051            var b = number % 10,
27052                output =
27053                    toInt((number % 100) / 10) === 1
27054                        ? 'th'
27055                        : b === 1
27056                        ? 'st'
27057                        : b === 2
27058                        ? 'nd'
27059                        : b === 3
27060                        ? 'rd'
27061                        : 'th';
27062            return number + output;
27063        },
27064    });
27065
27066    // Side effect imports
27067
27068    hooks.lang = deprecate(
27069        'moment.lang is deprecated. Use moment.locale instead.',
27070        getSetGlobalLocale
27071    );
27072    hooks.langData = deprecate(
27073        'moment.langData is deprecated. Use moment.localeData instead.',
27074        getLocale
27075    );
27076
27077    var mathAbs = Math.abs;
27078
27079    function abs() {
27080        var data = this._data;
27081
27082        this._milliseconds = mathAbs(this._milliseconds);
27083        this._days = mathAbs(this._days);
27084        this._months = mathAbs(this._months);
27085
27086        data.milliseconds = mathAbs(data.milliseconds);
27087        data.seconds = mathAbs(data.seconds);
27088        data.minutes = mathAbs(data.minutes);
27089        data.hours = mathAbs(data.hours);
27090        data.months = mathAbs(data.months);
27091        data.years = mathAbs(data.years);
27092
27093        return this;
27094    }
27095
27096    function addSubtract$1(duration, input, value, direction) {
27097        var other = createDuration(input, value);
27098
27099        duration._milliseconds += direction * other._milliseconds;
27100        duration._days += direction * other._days;
27101        duration._months += direction * other._months;
27102
27103        return duration._bubble();
27104    }
27105
27106    // supports only 2.0-style add(1, 's') or add(duration)
27107    function add$1(input, value) {
27108        return addSubtract$1(this, input, value, 1);
27109    }
27110
27111    // supports only 2.0-style subtract(1, 's') or subtract(duration)
27112    function subtract$1(input, value) {
27113        return addSubtract$1(this, input, value, -1);
27114    }
27115
27116    function absCeil(number) {
27117        if (number < 0) {
27118            return Math.floor(number);
27119        } else {
27120            return Math.ceil(number);
27121        }
27122    }
27123
27124    function bubble() {
27125        var milliseconds = this._milliseconds,
27126            days = this._days,
27127            months = this._months,
27128            data = this._data,
27129            seconds,
27130            minutes,
27131            hours,
27132            years,
27133            monthsFromDays;
27134
27135        // if we have a mix of positive and negative values, bubble down first
27136        // check: https://github.com/moment/moment/issues/2166
27137        if (
27138            !(
27139                (milliseconds >= 0 && days >= 0 && months >= 0) ||
27140                (milliseconds <= 0 && days <= 0 && months <= 0)
27141            )
27142        ) {
27143            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
27144            days = 0;
27145            months = 0;
27146        }
27147
27148        // The following code bubbles up values, see the tests for
27149        // examples of what that means.
27150        data.milliseconds = milliseconds % 1000;
27151
27152        seconds = absFloor(milliseconds / 1000);
27153        data.seconds = seconds % 60;
27154
27155        minutes = absFloor(seconds / 60);
27156        data.minutes = minutes % 60;
27157
27158        hours = absFloor(minutes / 60);
27159        data.hours = hours % 24;
27160
27161        days += absFloor(hours / 24);
27162
27163        // convert days to months
27164        monthsFromDays = absFloor(daysToMonths(days));
27165        months += monthsFromDays;
27166        days -= absCeil(monthsToDays(monthsFromDays));
27167
27168        // 12 months -> 1 year
27169        years = absFloor(months / 12);
27170        months %= 12;
27171
27172        data.days = days;
27173        data.months = months;
27174        data.years = years;
27175
27176        return this;
27177    }
27178
27179    function daysToMonths(days) {
27180        // 400 years have 146097 days (taking into account leap year rules)
27181        // 400 years have 12 months === 4800
27182        return (days * 4800) / 146097;
27183    }
27184
27185    function monthsToDays(months) {
27186        // the reverse of daysToMonths
27187        return (months * 146097) / 4800;
27188    }
27189
27190    function as(units) {
27191        if (!this.isValid()) {
27192            return NaN;
27193        }
27194        var days,
27195            months,
27196            milliseconds = this._milliseconds;
27197
27198        units = normalizeUnits(units);
27199
27200        if (units === 'month' || units === 'quarter' || units === 'year') {
27201            days = this._days + milliseconds / 864e5;
27202            months = this._months + daysToMonths(days);
27203            switch (units) {
27204                case 'month':
27205                    return months;
27206                case 'quarter':
27207                    return months / 3;
27208                case 'year':
27209                    return months / 12;
27210            }
27211        } else {
27212            // handle milliseconds separately because of floating point math errors (issue #1867)
27213            days = this._days + Math.round(monthsToDays(this._months));
27214            switch (units) {
27215                case 'week':
27216                    return days / 7 + milliseconds / 6048e5;
27217                case 'day':
27218                    return days + milliseconds / 864e5;
27219                case 'hour':
27220                    return days * 24 + milliseconds / 36e5;
27221                case 'minute':
27222                    return days * 1440 + milliseconds / 6e4;
27223                case 'second':
27224                    return days * 86400 + milliseconds / 1000;
27225                // Math.floor prevents floating point math errors here
27226                case 'millisecond':
27227                    return Math.floor(days * 864e5) + milliseconds;
27228                default:
27229                    throw new Error('Unknown unit ' + units);
27230            }
27231        }
27232    }
27233
27234    // TODO: Use this.as('ms')?
27235    function valueOf$1() {
27236        if (!this.isValid()) {
27237            return NaN;
27238        }
27239        return (
27240            this._milliseconds +
27241            this._days * 864e5 +
27242            (this._months % 12) * 2592e6 +
27243            toInt(this._months / 12) * 31536e6
27244        );
27245    }
27246
27247    function makeAs(alias) {
27248        return function () {
27249            return this.as(alias);
27250        };
27251    }
27252
27253    var asMilliseconds = makeAs('ms'),
27254        asSeconds = makeAs('s'),
27255        asMinutes = makeAs('m'),
27256        asHours = makeAs('h'),
27257        asDays = makeAs('d'),
27258        asWeeks = makeAs('w'),
27259        asMonths = makeAs('M'),
27260        asQuarters = makeAs('Q'),
27261        asYears = makeAs('y');
27262
27263    function clone$1() {
27264        return createDuration(this);
27265    }
27266
27267    function get$2(units) {
27268        units = normalizeUnits(units);
27269        return this.isValid() ? this[units + 's']() : NaN;
27270    }
27271
27272    function makeGetter(name) {
27273        return function () {
27274            return this.isValid() ? this._data[name] : NaN;
27275        };
27276    }
27277
27278    var milliseconds = makeGetter('milliseconds'),
27279        seconds = makeGetter('seconds'),
27280        minutes = makeGetter('minutes'),
27281        hours = makeGetter('hours'),
27282        days = makeGetter('days'),
27283        months = makeGetter('months'),
27284        years = makeGetter('years');
27285
27286    function weeks() {
27287        return absFloor(this.days() / 7);
27288    }
27289
27290    var round = Math.round,
27291        thresholds = {
27292            ss: 44, // a few seconds to seconds
27293            s: 45, // seconds to minute
27294            m: 45, // minutes to hour
27295            h: 22, // hours to day
27296            d: 26, // days to month/week
27297            w: null, // weeks to month
27298            M: 11, // months to year
27299        };
27300
27301    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
27302    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
27303        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
27304    }
27305
27306    function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
27307        var duration = createDuration(posNegDuration).abs(),
27308            seconds = round(duration.as('s')),
27309            minutes = round(duration.as('m')),
27310            hours = round(duration.as('h')),
27311            days = round(duration.as('d')),
27312            months = round(duration.as('M')),
27313            weeks = round(duration.as('w')),
27314            years = round(duration.as('y')),
27315            a =
27316                (seconds <= thresholds.ss && ['s', seconds]) ||
27317                (seconds < thresholds.s && ['ss', seconds]) ||
27318                (minutes <= 1 && ['m']) ||
27319                (minutes < thresholds.m && ['mm', minutes]) ||
27320                (hours <= 1 && ['h']) ||
27321                (hours < thresholds.h && ['hh', hours]) ||
27322                (days <= 1 && ['d']) ||
27323                (days < thresholds.d && ['dd', days]);
27324
27325        if (thresholds.w != null) {
27326            a =
27327                a ||
27328                (weeks <= 1 && ['w']) ||
27329                (weeks < thresholds.w && ['ww', weeks]);
27330        }
27331        a = a ||
27332            (months <= 1 && ['M']) ||
27333            (months < thresholds.M && ['MM', months]) ||
27334            (years <= 1 && ['y']) || ['yy', years];
27335
27336        a[2] = withoutSuffix;
27337        a[3] = +posNegDuration > 0;
27338        a[4] = locale;
27339        return substituteTimeAgo.apply(null, a);
27340    }
27341
27342    // This function allows you to set the rounding function for relative time strings
27343    function getSetRelativeTimeRounding(roundingFunction) {
27344        if (roundingFunction === undefined) {
27345            return round;
27346        }
27347        if (typeof roundingFunction === 'function') {
27348            round = roundingFunction;
27349            return true;
27350        }
27351        return false;
27352    }
27353
27354    // This function allows you to set a threshold for relative time strings
27355    function getSetRelativeTimeThreshold(threshold, limit) {
27356        if (thresholds[threshold] === undefined) {
27357            return false;
27358        }
27359        if (limit === undefined) {
27360            return thresholds[threshold];
27361        }
27362        thresholds[threshold] = limit;
27363        if (threshold === 's') {
27364            thresholds.ss = limit - 1;
27365        }
27366        return true;
27367    }
27368
27369    function humanize(argWithSuffix, argThresholds) {
27370        if (!this.isValid()) {
27371            return this.localeData().invalidDate();
27372        }
27373
27374        var withSuffix = false,
27375            th = thresholds,
27376            locale,
27377            output;
27378
27379        if (typeof argWithSuffix === 'object') {
27380            argThresholds = argWithSuffix;
27381            argWithSuffix = false;
27382        }
27383        if (typeof argWithSuffix === 'boolean') {
27384            withSuffix = argWithSuffix;
27385        }
27386        if (typeof argThresholds === 'object') {
27387            th = Object.assign({}, thresholds, argThresholds);
27388            if (argThresholds.s != null && argThresholds.ss == null) {
27389                th.ss = argThresholds.s - 1;
27390            }
27391        }
27392
27393        locale = this.localeData();
27394        output = relativeTime$1(this, !withSuffix, th, locale);
27395
27396        if (withSuffix) {
27397            output = locale.pastFuture(+this, output);
27398        }
27399
27400        return locale.postformat(output);
27401    }
27402
27403    var abs$1 = Math.abs;
27404
27405    function sign(x) {
27406        return (x > 0) - (x < 0) || +x;
27407    }
27408
27409    function toISOString$1() {
27410        // for ISO strings we do not use the normal bubbling rules:
27411        //  * milliseconds bubble up until they become hours
27412        //  * days do not bubble at all
27413        //  * months bubble up until they become years
27414        // This is because there is no context-free conversion between hours and days
27415        // (think of clock changes)
27416        // and also not between days and months (28-31 days per month)
27417        if (!this.isValid()) {
27418            return this.localeData().invalidDate();
27419        }
27420
27421        var seconds = abs$1(this._milliseconds) / 1000,
27422            days = abs$1(this._days),
27423            months = abs$1(this._months),
27424            minutes,
27425            hours,
27426            years,
27427            s,
27428            total = this.asSeconds(),
27429            totalSign,
27430            ymSign,
27431            daysSign,
27432            hmsSign;
27433
27434        if (!total) {
27435            // this is the same as C#'s (Noda) and python (isodate)...
27436            // but not other JS (goog.date)
27437            return 'P0D';
27438        }
27439
27440        // 3600 seconds -> 60 minutes -> 1 hour
27441        minutes = absFloor(seconds / 60);
27442        hours = absFloor(minutes / 60);
27443        seconds %= 60;
27444        minutes %= 60;
27445
27446        // 12 months -> 1 year
27447        years = absFloor(months / 12);
27448        months %= 12;
27449
27450        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
27451        s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
27452
27453        totalSign = total < 0 ? '-' : '';
27454        ymSign = sign(this._months) !== sign(total) ? '-' : '';
27455        daysSign = sign(this._days) !== sign(total) ? '-' : '';
27456        hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
27457
27458        return (
27459            totalSign +
27460            'P' +
27461            (years ? ymSign + years + 'Y' : '') +
27462            (months ? ymSign + months + 'M' : '') +
27463            (days ? daysSign + days + 'D' : '') +
27464            (hours || minutes || seconds ? 'T' : '') +
27465            (hours ? hmsSign + hours + 'H' : '') +
27466            (minutes ? hmsSign + minutes + 'M' : '') +
27467            (seconds ? hmsSign + s + 'S' : '')
27468        );
27469    }
27470
27471    var proto$2 = Duration.prototype;
27472
27473    proto$2.isValid = isValid$1;
27474    proto$2.abs = abs;
27475    proto$2.add = add$1;
27476    proto$2.subtract = subtract$1;
27477    proto$2.as = as;
27478    proto$2.asMilliseconds = asMilliseconds;
27479    proto$2.asSeconds = asSeconds;
27480    proto$2.asMinutes = asMinutes;
27481    proto$2.asHours = asHours;
27482    proto$2.asDays = asDays;
27483    proto$2.asWeeks = asWeeks;
27484    proto$2.asMonths = asMonths;
27485    proto$2.asQuarters = asQuarters;
27486    proto$2.asYears = asYears;
27487    proto$2.valueOf = valueOf$1;
27488    proto$2._bubble = bubble;
27489    proto$2.clone = clone$1;
27490    proto$2.get = get$2;
27491    proto$2.milliseconds = milliseconds;
27492    proto$2.seconds = seconds;
27493    proto$2.minutes = minutes;
27494    proto$2.hours = hours;
27495    proto$2.days = days;
27496    proto$2.weeks = weeks;
27497    proto$2.months = months;
27498    proto$2.years = years;
27499    proto$2.humanize = humanize;
27500    proto$2.toISOString = toISOString$1;
27501    proto$2.toString = toISOString$1;
27502    proto$2.toJSON = toISOString$1;
27503    proto$2.locale = locale;
27504    proto$2.localeData = localeData;
27505
27506    proto$2.toIsoString = deprecate(
27507        'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
27508        toISOString$1
27509    );
27510    proto$2.lang = lang;
27511
27512    // FORMATTING
27513
27514    addFormatToken('X', 0, 0, 'unix');
27515    addFormatToken('x', 0, 0, 'valueOf');
27516
27517    // PARSING
27518
27519    addRegexToken('x', matchSigned);
27520    addRegexToken('X', matchTimestamp);
27521    addParseToken('X', function (input, array, config) {
27522        config._d = new Date(parseFloat(input) * 1000);
27523    });
27524    addParseToken('x', function (input, array, config) {
27525        config._d = new Date(toInt(input));
27526    });
27527
27528    //! moment.js
27529
27530    hooks.version = '2.2
vendor: 5,148 bytes, lines 27530-27719
275309.3';
27531
27532    setHookCallback(createLocal);
27533
27534    hooks.fn = proto;
27535    hooks.min = min;
27536    hooks.max = max;
27537    hooks.now = now;
27538    hooks.utc = createUTC;
27539    hooks.unix = createUnix;
27540    hooks.months = listMonths;
27541    hooks.isDate = isDate;
27542    hooks.locale = getSetGlobalLocale;
27543    hooks.invalid = createInvalid;
27544    hooks.duration = createDuration;
27545    hooks.isMoment = isMoment;
27546    hooks.weekdays = listWeekdays;
27547    hooks.parseZone = createInZone;
27548    hooks.localeData = getLocale;
27549    hooks.isDuration = isDuration;
27550    hooks.monthsShort = listMonthsShort;
27551    hooks.weekdaysMin = listWeekdaysMin;
27552    hooks.defineLocale = defineLocale;
27553    hooks.updateLocale = updateLocale;
27554    hooks.locales = listLocales;
27555    hooks.weekdaysShort = listWeekdaysShort;
27556    hooks.normalizeUnits = normalizeUnits;
27557    hooks.relativeTimeRounding = getSetRelativeTimeRounding;
27558    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
27559    hooks.calendarFormat = getCalendarFormat;
27560    hooks.prototype = proto;
27561
27562    // currently HTML5 input type only supports 24-hour formats
27563    hooks.HTML5_FMT = {
27564        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
27565        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
27566        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
27567        DATE: 'YYYY-MM-DD', // <input type="date" />
27568        TIME: 'HH:mm', // <input type="time" />
27569        TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
27570        TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
27571        WEEK: 'GGGG-[W]WW', // <input type="week" />
27572        MONTH: 'YYYY-MM', // <input type="month" />
27573    };
27574
27575    return hooks;
27576
27577})));
27578
27579/**
27580 * EvEmitter v1.1.0
27581 * Lil' event emitter
27582 * MIT License
27583 */
27584
27585/* jshint unused: true, undef: true, strict: true */
27586
27587( function( global, factory ) {
27588  // universal module definition
27589  /* jshint strict: false */ /* globals define, module, window */
27590  if ( typeof define == 'function' && define.amd ) {
27591    // AMD - RequireJS
27592    define( factory );
27593  } else if ( typeof module == 'object' && module.exports ) {
27594    // CommonJS - Browserify, Webpack
27595    module.exports = factory();
27596  } else {
27597    // Browser globals
27598    global.EvEmitter = factory();
27599  }
27600
27601}( typeof window != 'undefined' ? window : this, function() {
27602
27603"use strict";
27604
27605function EvEmitter() {}
27606
27607var proto = EvEmitter.prototype;
27608
27609proto.on = function( eventName, listener ) {
27610  if ( !eventName || !listener ) {
27611    return;
27612  }
27613  // set events hash
27614  var events = this._events = this._events || {};
27615  // set listeners array
27616  var listeners = events[ eventName ] = events[ eventName ] || [];
27617  // only add once
27618  if ( listeners.indexOf( listener ) == -1 ) {
27619    listeners.push( listener );
27620  }
27621
27622  return this;
27623};
27624
27625proto.once = function( eventName, listener ) {
27626  if ( !eventName || !listener ) {
27627    return;
27628  }
27629  // add event
27630  this.on( eventName, listener );
27631  // set once flag
27632  // set onceEvents hash
27633  var onceEvents = this._onceEvents = this._onceEvents || {};
27634  // set onceListeners object
27635  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
27636  // set flag
27637  onceListeners[ listener ] = true;
27638
27639  return this;
27640};
27641
27642proto.off = function( eventName, listener ) {
27643  var listeners = this._events && this._events[ eventName ];
27644  if ( !listeners || !listeners.length ) {
27645    return;
27646  }
27647  var index = listeners.indexOf( listener );
27648  if ( index != -1 ) {
27649    listeners.splice( index, 1 );
27650  }
27651
27652  return this;
27653};
27654
27655proto.emitEvent = function( eventName, args ) {
27656  var listeners = this._events && this._events[ eventName ];
27657  if ( !listeners || !listeners.length ) {
27658    return;
27659  }
27660  // copy over to avoid interference if .off() in listener
27661  listeners = listeners.slice(0);
27662  args = args || [];
27663  // once stuff
27664  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
27665
27666  for ( var i=0; i < listeners.length; i++ ) {
27667    var listener = listeners[i]
27668    var isOnce = onceListeners && onceListeners[ listener ];
27669    if ( isOnce ) {
27670      // remove listener
27671      // remove before trigger to prevent recursion
27672      this.off( eventName, listener );
27673      // unset once flag
27674      delete onceListeners[ listener ];
27675    }
27676    // trigger listener
27677    listener.apply( this, args );
27678  }
27679
27680  return this;
27681};
27682
27683proto.allOff = function() {
27684  delete this._events;
27685  delete this._onceEvents;
27686};
27687
27688return EvEmitter;
27689
27690}));
27691
27692/**
27693 * matchesSelector v2.0.2
27694 * matchesSelector( element, '.selector' )
27695 * MIT license
27696 */
27697
27698/*jshint browser: true, strict: true, undef: true, unused: true */
27699
27700( function( window, factory ) {
27701  /*global define: false, module: false */
27702  'use strict';
27703  // universal module definition
27704  if ( typeof define == 'function' && define.amd ) {
27705    // AMD
27706    define( factory );
27707  } else if ( typeof module == 'object' && module.exports ) {
27708    // CommonJS
27709    module.exports = factory();
27710  } else {
27711    // browser global
27712    window.matchesSelector = factory();
27713  }
27714
27715}( window, function factory() {
27716  'use strict';
27717
27718  var matchesMethod = ( function() {
27719    var ElemProto = window.Element.prototype;
27720    // check for the standard method name first
27721    if ( ElemProto.matches ) {
27722      return 'matches';
27723    }
27724    // check un-prefixed
27725    if ( ElemProto.matchesSelector ) {
27726      return 'matchesSelector';
27727    }
27728    // check vendor prefixes
27729    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
27730
27731    for ( var i=0; i < prefixes.length; i++ ) {
27732      var prefix = prefixes[i];
27733      var method = prefix + 'MatchesSelector';
27734      if ( ElemProto[ method ] ) {
27735        return method;
27736      }
27737    }
27738  })();
27739
27740  return function matchesSelector( elem, selector ) {
27741    return elem[ matchesMethod ]( selector );
27742  };
27743
27744}));
27745
27746/**
27747 * @license
27748 * Lodash <https://lodash.com/>
27749 * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
27750 * Released under MIT license <https://lodash.com/license>
27751 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
27752 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
27753 */
27754;(function() {
27755
27756  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
27757  var undefined
vendor: 12,195 bytes, lines 27757-28060
27757;
27758
27759  /** Used as the semantic version number. */
27760  var VERSION = '4.17.21';
27761
27762  /** Used as the size to enable large array optimizations. */
27763  var LARGE_ARRAY_SIZE = 200;
27764
27765  /** Error message constants. */
27766  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
27767      FUNC_ERROR_TEXT = 'Expected a function',
27768      INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
27769
27770  /** Used to stand-in for `undefined` hash values. */
27771  var HASH_UNDEFINED = '__lodash_hash_undefined__';
27772
27773  /** Used as the maximum memoize cache size. */
27774  var MAX_MEMOIZE_SIZE = 500;
27775
27776  /** Used as the internal argument placeholder. */
27777  var PLACEHOLDER = '__lodash_placeholder__';
27778
27779  /** Used to compose bitmasks for cloning. */
27780  var CLONE_DEEP_FLAG = 1,
27781      CLONE_FLAT_FLAG = 2,
27782      CLONE_SYMBOLS_FLAG = 4;
27783
27784  /** Used to compose bitmasks for value comparisons. */
27785  var COMPARE_PARTIAL_FLAG = 1,
27786      COMPARE_UNORDERED_FLAG = 2;
27787
27788  /** Used to compose bitmasks for function metadata. */
27789  var WRAP_BIND_FLAG = 1,
27790      WRAP_BIND_KEY_FLAG = 2,
27791      WRAP_CURRY_BOUND_FLAG = 4,
27792      WRAP_CURRY_FLAG = 8,
27793      WRAP_CURRY_RIGHT_FLAG = 16,
27794      WRAP_PARTIAL_FLAG = 32,
27795      WRAP_PARTIAL_RIGHT_FLAG = 64,
27796      WRAP_ARY_FLAG = 128,
27797      WRAP_REARG_FLAG = 256,
27798      WRAP_FLIP_FLAG = 512;
27799
27800  /** Used as default options for `_.truncate`. */
27801  var DEFAULT_TRUNC_LENGTH = 30,
27802      DEFAULT_TRUNC_OMISSION = '...';
27803
27804  /** Used to detect hot functions by number of calls within a span of milliseconds. */
27805  var HOT_COUNT = 800,
27806      HOT_SPAN = 16;
27807
27808  /** Used to indicate the type of lazy iteratees. */
27809  var LAZY_FILTER_FLAG = 1,
27810      LAZY_MAP_FLAG = 2,
27811      LAZY_WHILE_FLAG = 3;
27812
27813  /** Used as references for various `Number` constants. */
27814  var INFINITY = 1 / 0,
27815      MAX_SAFE_INTEGER = 9007199254740991,
27816      MAX_INTEGER = 1.7976931348623157e+308,
27817      NAN = 0 / 0;
27818
27819  /** Used as references for the maximum length and index of an array. */
27820  var MAX_ARRAY_LENGTH = 4294967295,
27821      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
27822      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
27823
27824  /** Used to associate wrap methods with their bit flags. */
27825  var wrapFlags = [
27826    ['ary', WRAP_ARY_FLAG],
27827    ['bind', WRAP_BIND_FLAG],
27828    ['bindKey', WRAP_BIND_KEY_FLAG],
27829    ['curry', WRAP_CURRY_FLAG],
27830    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
27831    ['flip', WRAP_FLIP_FLAG],
27832    ['partial', WRAP_PARTIAL_FLAG],
27833    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
27834    ['rearg', WRAP_REARG_FLAG]
27835  ];
27836
27837  /** `Object#toString` result references. */
27838  var argsTag = '[object Arguments]',
27839      arrayTag = '[object Array]',
27840      asyncTag = '[object AsyncFunction]',
27841      boolTag = '[object Boolean]',
27842      dateTag = '[object Date]',
27843      domExcTag = '[object DOMException]',
27844      errorTag = '[object Error]',
27845      funcTag = '[object Function]',
27846      genTag = '[object GeneratorFunction]',
27847      mapTag = '[object Map]',
27848      numberTag = '[object Number]',
27849      nullTag = '[object Null]',
27850      objectTag = '[object Object]',
27851      promiseTag = '[object Promise]',
27852      proxyTag = '[object Proxy]',
27853      regexpTag = '[object RegExp]',
27854      setTag = '[object Set]',
27855      stringTag = '[object String]',
27856      symbolTag = '[object Symbol]',
27857      undefinedTag = '[object Undefined]',
27858      weakMapTag = '[object WeakMap]',
27859      weakSetTag = '[object WeakSet]';
27860
27861  var arrayBufferTag = '[object ArrayBuffer]',
27862      dataViewTag = '[object DataView]',
27863      float32Tag = '[object Float32Array]',
27864      float64Tag = '[object Float64Array]',
27865      int8Tag = '[object Int8Array]',
27866      int16Tag = '[object Int16Array]',
27867      int32Tag = '[object Int32Array]',
27868      uint8Tag = '[object Uint8Array]',
27869      uint8ClampedTag = '[object Uint8ClampedArray]',
27870      uint16Tag = '[object Uint16Array]',
27871      uint32Tag = '[object Uint32Array]';
27872
27873  /** Used to match empty string literals in compiled template source. */
27874  var reEmptyStringLeading = /\b__p \+= '';/g,
27875      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
27876      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
27877
27878  /** Used to match HTML entities and HTML characters. */
27879  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
27880      reUnescapedHtml = /[&<>"']/g,
27881      reHasEscapedHtml = RegExp(reEscapedHtml.source),
27882      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
27883
27884  /** Used to match template delimiters. */
27885  var reEscape = /<%-([\s\S]+?)%>/g,
27886      reEvaluate = /<%([\s\S]+?)%>/g,
27887      reInterpolate = /<%=([\s\S]+?)%>/g;
27888
27889  /** Used to match property names within property paths. */
27890  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
27891      reIsPlainProp = /^\w*$/,
27892      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
27893
27894  /**
27895   * Used to match `RegExp`
27896   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
27897   */
27898  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
27899      reHasRegExpChar = RegExp(reRegExpChar.source);
27900
27901  /** Used to match leading whitespace. */
27902  var reTrimStart = /^\s+/;
27903
27904  /** Used to match a single whitespace character. */
27905  var reWhitespace = /\s/;
27906
27907  /** Used to match wrap detail comments. */
27908  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
27909      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
27910      reSplitDetails = /,? & /;
27911
27912  /** Used to match words composed of alphanumeric characters. */
27913  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
27914
27915  /**
27916   * Used to validate the `validate` option in `_.template` variable.
27917   *
27918   * Forbids characters which could potentially change the meaning of the function argument definition:
27919   * - "()," (modification of function parameters)
27920   * - "=" (default value)
27921   * - "[]{}" (destructuring of function parameters)
27922   * - "/" (beginning of a comment)
27923   * - whitespace
27924   */
27925  var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
27926
27927  /** Used to match backslashes in property paths. */
27928  var reEscapeChar = /\\(\\)?/g;
27929
27930  /**
27931   * Used to match
27932   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
27933   */
27934  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
27935
27936  /** Used to match `RegExp` flags from their coerced string values. */
27937  var reFlags = /\w*$/;
27938
27939  /** Used to detect bad signed hexadecimal string values. */
27940  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
27941
27942  /** Used to detect binary string values. */
27943  var reIsBinary = /^0b[01]+$/i;
27944
27945  /** Used to detect host constructors (Safari). */
27946  var reIsHostCtor = /^\[object .+?Constructor\]$/;
27947
27948  /** Used to detect octal string values. */
27949  var reIsOctal = /^0o[0-7]+$/i;
27950
27951  /** Used to detect unsigned integer values. */
27952  var reIsUint = /^(?:0|[1-9]\d*)$/;
27953
27954  /** Used to match Latin Unicode letters (excluding mathematical operators). */
27955  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
27956
27957  /** Used to ensure capturing order of template delimiters. */
27958  var reNoMatch = /($^)/;
27959
27960  /** Used to match unescaped characters in compiled string literals. */
27961  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
27962
27963  /** Used to compose unicode character classes. */
27964  var rsAstralRange = '\\ud800-\\udfff',
27965      rsComboMarksRange = '\\u0300-\\u036f',
27966      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
27967      rsComboSymbolsRange = '\\u20d0-\\u20ff',
27968      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
27969      rsDingbatRange = '\\u2700-\\u27bf',
27970      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
27971      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
27972      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
27973      rsPunctuationRange = '\\u2000-\\u206f',
27974      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',
27975      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
27976      rsVarRange = '\\ufe0e\\ufe0f',
27977      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
27978
27979  /** Used to compose unicode capture groups. */
27980  var rsApos = "['\u2019]",
27981      rsAstral = '[' + rsAstralRange + ']',
27982      rsBreak = '[' + rsBreakRange + ']',
27983      rsCombo = '[' + rsComboRange + ']',
27984      rsDigits = '\\d+',
27985      rsDingbat = '[' + rsDingbatRange + ']',
27986      rsLower = '[' + rsLowerRange + ']',
27987      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
27988      rsFitz = '\\ud83c[\\udffb-\\udfff]',
27989      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
27990      rsNonAstral = '[^' + rsAstralRange + ']',
27991      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
27992      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
27993      rsUpper = '[' + rsUpperRange + ']',
27994      rsZWJ = '\\u200d';
27995
27996  /** Used to compose unicode regexes. */
27997  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
27998      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
27999      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
28000      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
28001      reOptMod = rsModifier + '?',
28002      rsOptVar = '[' + rsVarRange + ']?',
28003      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
28004      rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
28005      rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
28006      rsSeq = rsOptVar + reOptMod + rsOptJoin,
28007      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
28008      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
28009
28010  /** Used to match apostrophes. */
28011  var reApos = RegExp(rsApos, 'g');
28012
28013  /**
28014   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
28015   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
28016   */
28017  var reComboMark = RegExp(rsCombo, 'g');
28018
28019  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
28020  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
28021
28022  /** Used to match complex or compound words. */
28023  var reUnicodeWord = RegExp([
28024    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
28025    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
28026    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
28027    rsUpper + '+' + rsOptContrUpper,
28028    rsOrdUpper,
28029    rsOrdLower,
28030    rsDigits,
28031    rsEmoji
28032  ].join('|'), 'g');
28033
28034  /** 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/). */
28035  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
28036
28037  /** Used to detect strings that need a more robust regexp to match words. */
28038  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 ]/;
28039
28040  /** Used to assign default `context` object properties. */
28041  var contextProps = [
28042    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
28043    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
28044    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
28045    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
28046    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
28047  ];
28048
28049  /** Used to make template sourceURLs easier to identify. */
28050  var templateCounter = -1;
28051
28052  /** Used to identify `toStringTag` values of typed arrays. */
28053  var typedArrayTags = {};
28054  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
28055  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
28056  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
28057  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
28058  typedArrayTags[uint32Tag] = true;
28059  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
28060  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
vendor: 5,923 bytes, lines 28061-28195
28061  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
28062  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
28063  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
28064  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
28065  typedArrayTags[setTag] = typedArrayTags[stringTag] =
28066  typedArrayTags[weakMapTag] = false;
28067
28068  /** Used to identify `toStringTag` values supported by `_.clone`. */
28069  var cloneableTags = {};
28070  cloneableTags[argsTag] = cloneableTags[arrayTag] =
28071  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
28072  cloneableTags[boolTag] = cloneableTags[dateTag] =
28073  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
28074  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
28075  cloneableTags[int32Tag] = cloneableTags[mapTag] =
28076  cloneableTags[numberTag] = cloneableTags[objectTag] =
28077  cloneableTags[regexpTag] = cloneableTags[setTag] =
28078  cloneableTags[stringTag] = cloneableTags[symbolTag] =
28079  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
28080  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
28081  cloneableTags[errorTag] = cloneableTags[funcTag] =
28082  cloneableTags[weakMapTag] = false;
28083
28084  /** Used to map Latin Unicode letters to basic Latin letters. */
28085  var deburredLetters = {
28086    // Latin-1 Supplement block.
28087    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
28088    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
28089    '\xc7': 'C',  '\xe7': 'c',
28090    '\xd0': 'D',  '\xf0': 'd',
28091    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
28092    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
28093    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
28094    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
28095    '\xd1': 'N',  '\xf1': 'n',
28096    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
28097    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
28098    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
28099    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
28100    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
28101    '\xc6': 'Ae', '\xe6': 'ae',
28102    '\xde': 'Th', '\xfe': 'th',
28103    '\xdf': 'ss',
28104    // Latin Extended-A block.
28105    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
28106    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
28107    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
28108    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
28109    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
28110    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
28111    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
28112    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
28113    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
28114    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
28115    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
28116    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
28117    '\u0134': 'J',  '\u0135': 'j',
28118    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
28119    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
28120    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
28121    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
28122    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
28123    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
28124    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
28125    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
28126    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
28127    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
28128    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
28129    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
28130    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
28131    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
28132    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
28133    '\u0174': 'W',  '\u0175': 'w',
28134    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
28135    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
28136    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
28137    '\u0132': 'IJ', '\u0133': 'ij',
28138    '\u0152': 'Oe', '\u0153': 'oe',
28139    '\u0149': "'n", '\u017f': 's'
28140  };
28141
28142  /** Used to map characters to HTML entities. */
28143  var htmlEscapes = {
28144    '&': '&amp;',
28145    '<': '&lt;',
28146    '>': '&gt;',
28147    '"': '&quot;',
28148    "'": '&#39;'
28149  };
28150
28151  /** Used to map HTML entities to characters. */
28152  var htmlUnescapes = {
28153    '&amp;': '&',
28154    '&lt;': '<',
28155    '&gt;': '>',
28156    '&quot;': '"',
28157    '&#39;': "'"
28158  };
28159
28160  /** Used to escape characters for inclusion in compiled string literals. */
28161  var stringEscapes = {
28162    '\\': '\\',
28163    "'": "'",
28164    '\n': 'n',
28165    '\r': 'r',
28166    '\u2028': 'u2028',
28167    '\u2029': 'u2029'
28168  };
28169
28170  /** Built-in method references without a dependency on `root`. */
28171  var freeParseFloat = parseFloat,
28172      freeParseInt = parseInt;
28173
28174  /** Detect free variable `global` from Node.js. */
28175  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
28176
28177  /** Detect free variable `self`. */
28178  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
28179
28180  /** Used as a reference to the global object. */
28181  var root = freeGlobal || freeSelf || Function('return this')();
28182
28183  /** Detect free variable `exports`. */
28184  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
28185
28186  /** Detect free variable `module`. */
28187  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
28188
28189  /** Detect the popular CommonJS extension `module.exports`. */
28190  var moduleExports = freeModule && freeModule.exports === freeExports;
28191
28192  /** Detect free variable `process` from Node.js. */
28193  var freeProcess = moduleExports && freeGlobal.process;
28194
28195  /** Used to access faster Node.js helpers. */
vendor: 8,860 bytes, lines 28196-28489
28196  var nodeUtil = (function() {
28197    try {
28198      // Use `util.types` for Node.js 10+.
28199      var types = freeModule && freeModule.require && freeModule.require('util').types;
28200
28201      if (types) {
28202        return types;
28203      }
28204
28205      // Legacy `process.binding('util')` for Node.js < 10.
28206      return freeProcess && freeProcess.binding && freeProcess.binding('util');
28207    } catch (e) {}
28208  }());
28209
28210  /* Node.js helper references. */
28211  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
28212      nodeIsDate = nodeUtil && nodeUtil.isDate,
28213      nodeIsMap = nodeUtil && nodeUtil.isMap,
28214      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
28215      nodeIsSet = nodeUtil && nodeUtil.isSet,
28216      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
28217
28218  /*--------------------------------------------------------------------------*/
28219
28220  /**
28221   * A faster alternative to `Function#apply`, this function invokes `func`
28222   * with the `this` binding of `thisArg` and the arguments of `args`.
28223   *
28224   * @private
28225   * @param {Function} func The function to invoke.
28226   * @param {*} thisArg The `this` binding of `func`.
28227   * @param {Array} args The arguments to invoke `func` with.
28228   * @returns {*} Returns the result of `func`.
28229   */
28230  function apply(func, thisArg, args) {
28231    switch (args.length) {
28232      case 0: return func.call(thisArg);
28233      case 1: return func.call(thisArg, args[0]);
28234      case 2: return func.call(thisArg, args[0], args[1]);
28235      case 3: return func.call(thisArg, args[0], args[1], args[2]);
28236    }
28237    return func.apply(thisArg, args);
28238  }
28239
28240  /**
28241   * A specialized version of `baseAggregator` for arrays.
28242   *
28243   * @private
28244   * @param {Array} [array] The array to iterate over.
28245   * @param {Function} setter The function to set `accumulator` values.
28246   * @param {Function} iteratee The iteratee to transform keys.
28247   * @param {Object} accumulator The initial aggregated object.
28248   * @returns {Function} Returns `accumulator`.
28249   */
28250  function arrayAggregator(array, setter, iteratee, accumulator) {
28251    var index = -1,
28252        length = array == null ? 0 : array.length;
28253
28254    while (++index < length) {
28255      var value = array[index];
28256      setter(accumulator, value, iteratee(value), array);
28257    }
28258    return accumulator;
28259  }
28260
28261  /**
28262   * A specialized version of `_.forEach` for arrays without support for
28263   * iteratee shorthands.
28264   *
28265   * @private
28266   * @param {Array} [array] The array to iterate over.
28267   * @param {Function} iteratee The function invoked per iteration.
28268   * @returns {Array} Returns `array`.
28269   */
28270  function arrayEach(array, iteratee) {
28271    var index = -1,
28272        length = array == null ? 0 : array.length;
28273
28274    while (++index < length) {
28275      if (iteratee(array[index], index, array) === false) {
28276        break;
28277      }
28278    }
28279    return array;
28280  }
28281
28282  /**
28283   * A specialized version of `_.forEachRight` for arrays without support for
28284   * iteratee shorthands.
28285   *
28286   * @private
28287   * @param {Array} [array] The array to iterate over.
28288   * @param {Function} iteratee The function invoked per iteration.
28289   * @returns {Array} Returns `array`.
28290   */
28291  function arrayEachRight(array, iteratee) {
28292    var length = array == null ? 0 : array.length;
28293
28294    while (length--) {
28295      if (iteratee(array[length], length, array) === false) {
28296        break;
28297      }
28298    }
28299    return array;
28300  }
28301
28302  /**
28303   * A specialized version of `_.every` for arrays without support for
28304   * iteratee shorthands.
28305   *
28306   * @private
28307   * @param {Array} [array] The array to iterate over.
28308   * @param {Function} predicate The function invoked per iteration.
28309   * @returns {boolean} Returns `true` if all elements pass the predicate check,
28310   *  else `false`.
28311   */
28312  function arrayEvery(array, predicate) {
28313    var index = -1,
28314        length = array == null ? 0 : array.length;
28315
28316    while (++index < length) {
28317      if (!predicate(array[index], index, array)) {
28318        return false;
28319      }
28320    }
28321    return true;
28322  }
28323
28324  /**
28325   * A specialized version of `_.filter` for arrays without support for
28326   * iteratee shorthands.
28327   *
28328   * @private
28329   * @param {Array} [array] The array to iterate over.
28330   * @param {Function} predicate The function invoked per iteration.
28331   * @returns {Array} Returns the new filtered array.
28332   */
28333  function arrayFilter(array, predicate) {
28334    var index = -1,
28335        length = array == null ? 0 : array.length,
28336        resIndex = 0,
28337        result = [];
28338
28339    while (++index < length) {
28340      var value = array[index];
28341      if (predicate(value, index, array)) {
28342        result[resIndex++] = value;
28343      }
28344    }
28345    return result;
28346  }
28347
28348  /**
28349   * A specialized version of `_.includes` for arrays without support for
28350   * specifying an index to search from.
28351   *
28352   * @private
28353   * @param {Array} [array] The array to inspect.
28354   * @param {*} target The value to search for.
28355   * @returns {boolean} Returns `true` if `target` is found, else `false`.
28356   */
28357  function arrayIncludes(array, value) {
28358    var length = array == null ? 0 : array.length;
28359    return !!length && baseIndexOf(array, value, 0) > -1;
28360  }
28361
28362  /**
28363   * This function is like `arrayIncludes` except that it accepts a comparator.
28364   *
28365   * @private
28366   * @param {Array} [array] The array to inspect.
28367   * @param {*} target The value to search for.
28368   * @param {Function} comparator The comparator invoked per element.
28369   * @returns {boolean} Returns `true` if `target` is found, else `false`.
28370   */
28371  function arrayIncludesWith(array, value, comparator) {
28372    var index = -1,
28373        length = array == null ? 0 : array.length;
28374
28375    while (++index < length) {
28376      if (comparator(value, array[index])) {
28377        return true;
28378      }
28379    }
28380    return false;
28381  }
28382
28383  /**
28384   * A specialized version of `_.map` for arrays without support for iteratee
28385   * shorthands.
28386   *
28387   * @private
28388   * @param {Array} [array] The array to iterate over.
28389   * @param {Function} iteratee The function invoked per iteration.
28390   * @returns {Array} Returns the new mapped array.
28391   */
28392  function arrayMap(array, iteratee) {
28393    var index = -1,
28394        length = array == null ? 0 : array.length,
28395        result = Array(length);
28396
28397    while (++index < length) {
28398      result[index] = iteratee(array[index], index, array);
28399    }
28400    return result;
28401  }
28402
28403  /**
28404   * Appends the elements of `values` to `array`.
28405   *
28406   * @private
28407   * @param {Array} array The array to modify.
28408   * @param {Array} values The values to append.
28409   * @returns {Array} Returns `array`.
28410   */
28411  function arrayPush(array, values) {
28412    var index = -1,
28413        length = values.length,
28414        offset = array.length;
28415
28416    while (++index < length) {
28417      array[offset + index] = values[index];
28418    }
28419    return array;
28420  }
28421
28422  /**
28423   * A specialized version of `_.reduce` for arrays without support for
28424   * iteratee shorthands.
28425   *
28426   * @private
28427   * @param {Array} [array] The array to iterate over.
28428   * @param {Function} iteratee The function invoked per iteration.
28429   * @param {*} [accumulator] The initial value.
28430   * @param {boolean} [initAccum] Specify using the first element of `array` as
28431   *  the initial value.
28432   * @returns {*} Returns the accumulated value.
28433   */
28434  function arrayReduce(array, iteratee, accumulator, initAccum) {
28435    var index = -1,
28436        length = array == null ? 0 : array.length;
28437
28438    if (initAccum && length) {
28439      accumulator = array[++index];
28440    }
28441    while (++index < length) {
28442      accumulator = iteratee(accumulator, array[index], index, array);
28443    }
28444    return accumulator;
28445  }
28446
28447  /**
28448   * A specialized version of `_.reduceRight` for arrays without support for
28449   * iteratee shorthands.
28450   *
28451   * @private
28452   * @param {Array} [array] The array to iterate over.
28453   * @param {Function} iteratee The function invoked per iteration.
28454   * @param {*} [accumulator] The initial value.
28455   * @param {boolean} [initAccum] Specify using the last element of `array` as
28456   *  the initial value.
28457   * @returns {*} Returns the accumulated value.
28458   */
28459  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
28460    var length = array == null ? 0 : array.length;
28461    if (initAccum && length) {
28462      accumulator = array[--length];
28463    }
28464    while (length--) {
28465      accumulator = iteratee(accumulator, array[length], length, array);
28466    }
28467    return accumulator;
28468  }
28469
28470  /**
28471   * A specialized version of `_.some` for arrays without support for iteratee
28472   * shorthands.
28473   *
28474   * @private
28475   * @param {Array} [array] The array to iterate over.
28476   * @param {Function} predicate The function invoked per iteration.
28477   * @returns {boolean} Returns `true` if any element passes the predicate check,
28478   *  else `false`.
28479   */
28480  function arraySome(array, predicate) {
28481    var index = -1,
28482        length = array == null ? 0 : array.length;
28483
28484    while (++index < length) {
28485      if (predicate(array[index], index, array)) {
28486        return true;
28487      }
28488    }
28489    return false;
vendor: 12,899 bytes, lines 28490-28927
28490  }
28491
28492  /**
28493   * Gets the size of an ASCII `string`.
28494   *
28495   * @private
28496   * @param {string} string The string inspect.
28497   * @returns {number} Returns the string size.
28498   */
28499  var asciiSize = baseProperty('length');
28500
28501  /**
28502   * Converts an ASCII `string` to an array.
28503   *
28504   * @private
28505   * @param {string} string The string to convert.
28506   * @returns {Array} Returns the converted array.
28507   */
28508  function asciiToArray(string) {
28509    return string.split('');
28510  }
28511
28512  /**
28513   * Splits an ASCII `string` into an array of its words.
28514   *
28515   * @private
28516   * @param {string} The string to inspect.
28517   * @returns {Array} Returns the words of `string`.
28518   */
28519  function asciiWords(string) {
28520    return string.match(reAsciiWord) || [];
28521  }
28522
28523  /**
28524   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
28525   * without support for iteratee shorthands, which iterates over `collection`
28526   * using `eachFunc`.
28527   *
28528   * @private
28529   * @param {Array|Object} collection The collection to inspect.
28530   * @param {Function} predicate The function invoked per iteration.
28531   * @param {Function} eachFunc The function to iterate over `collection`.
28532   * @returns {*} Returns the found element or its key, else `undefined`.
28533   */
28534  function baseFindKey(collection, predicate, eachFunc) {
28535    var result;
28536    eachFunc(collection, function(value, key, collection) {
28537      if (predicate(value, key, collection)) {
28538        result = key;
28539        return false;
28540      }
28541    });
28542    return result;
28543  }
28544
28545  /**
28546   * The base implementation of `_.findIndex` and `_.findLastIndex` without
28547   * support for iteratee shorthands.
28548   *
28549   * @private
28550   * @param {Array} array The array to inspect.
28551   * @param {Function} predicate The function invoked per iteration.
28552   * @param {number} fromIndex The index to search from.
28553   * @param {boolean} [fromRight] Specify iterating from right to left.
28554   * @returns {number} Returns the index of the matched value, else `-1`.
28555   */
28556  function baseFindIndex(array, predicate, fromIndex, fromRight) {
28557    var length = array.length,
28558        index = fromIndex + (fromRight ? 1 : -1);
28559
28560    while ((fromRight ? index-- : ++index < length)) {
28561      if (predicate(array[index], index, array)) {
28562        return index;
28563      }
28564    }
28565    return -1;
28566  }
28567
28568  /**
28569   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
28570   *
28571   * @private
28572   * @param {Array} array The array to inspect.
28573   * @param {*} value The value to search for.
28574   * @param {number} fromIndex The index to search from.
28575   * @returns {number} Returns the index of the matched value, else `-1`.
28576   */
28577  function baseIndexOf(array, value, fromIndex) {
28578    return value === value
28579      ? strictIndexOf(array, value, fromIndex)
28580      : baseFindIndex(array, baseIsNaN, fromIndex);
28581  }
28582
28583  /**
28584   * This function is like `baseIndexOf` except that it accepts a comparator.
28585   *
28586   * @private
28587   * @param {Array} array The array to inspect.
28588   * @param {*} value The value to search for.
28589   * @param {number} fromIndex The index to search from.
28590   * @param {Function} comparator The comparator invoked per element.
28591   * @returns {number} Returns the index of the matched value, else `-1`.
28592   */
28593  function baseIndexOfWith(array, value, fromIndex, comparator) {
28594    var index = fromIndex - 1,
28595        length = array.length;
28596
28597    while (++index < length) {
28598      if (comparator(array[index], value)) {
28599        return index;
28600      }
28601    }
28602    return -1;
28603  }
28604
28605  /**
28606   * The base implementation of `_.isNaN` without support for number objects.
28607   *
28608   * @private
28609   * @param {*} value The value to check.
28610   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
28611   */
28612  function baseIsNaN(value) {
28613    return value !== value;
28614  }
28615
28616  /**
28617   * The base implementation of `_.mean` and `_.meanBy` without support for
28618   * iteratee shorthands.
28619   *
28620   * @private
28621   * @param {Array} array The array to iterate over.
28622   * @param {Function} iteratee The function invoked per iteration.
28623   * @returns {number} Returns the mean.
28624   */
28625  function baseMean(array, iteratee) {
28626    var length = array == null ? 0 : array.length;
28627    return length ? (baseSum(array, iteratee) / length) : NAN;
28628  }
28629
28630  /**
28631   * The base implementation of `_.property` without support for deep paths.
28632   *
28633   * @private
28634   * @param {string} key The key of the property to get.
28635   * @returns {Function} Returns the new accessor function.
28636   */
28637  function baseProperty(key) {
28638    return function(object) {
28639      return object == null ? undefined : object[key];
28640    };
28641  }
28642
28643  /**
28644   * The base implementation of `_.propertyOf` without support for deep paths.
28645   *
28646   * @private
28647   * @param {Object} object The object to query.
28648   * @returns {Function} Returns the new accessor function.
28649   */
28650  function basePropertyOf(object) {
28651    return function(key) {
28652      return object == null ? undefined : object[key];
28653    };
28654  }
28655
28656  /**
28657   * The base implementation of `_.reduce` and `_.reduceRight`, without support
28658   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
28659   *
28660   * @private
28661   * @param {Array|Object} collection The collection to iterate over.
28662   * @param {Function} iteratee The function invoked per iteration.
28663   * @param {*} accumulator The initial value.
28664   * @param {boolean} initAccum Specify using the first or last element of
28665   *  `collection` as the initial value.
28666   * @param {Function} eachFunc The function to iterate over `collection`.
28667   * @returns {*} Returns the accumulated value.
28668   */
28669  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
28670    eachFunc(collection, function(value, index, collection) {
28671      accumulator = initAccum
28672        ? (initAccum = false, value)
28673        : iteratee(accumulator, value, index, collection);
28674    });
28675    return accumulator;
28676  }
28677
28678  /**
28679   * The base implementation of `_.sortBy` which uses `comparer` to define the
28680   * sort order of `array` and replaces criteria objects with their corresponding
28681   * values.
28682   *
28683   * @private
28684   * @param {Array} array The array to sort.
28685   * @param {Function} comparer The function to define sort order.
28686   * @returns {Array} Returns `array`.
28687   */
28688  function baseSortBy(array, comparer) {
28689    var length = array.length;
28690
28691    array.sort(comparer);
28692    while (length--) {
28693      array[length] = array[length].value;
28694    }
28695    return array;
28696  }
28697
28698  /**
28699   * The base implementation of `_.sum` and `_.sumBy` without support for
28700   * iteratee shorthands.
28701   *
28702   * @private
28703   * @param {Array} array The array to iterate over.
28704   * @param {Function} iteratee The function invoked per iteration.
28705   * @returns {number} Returns the sum.
28706   */
28707  function baseSum(array, iteratee) {
28708    var result,
28709        index = -1,
28710        length = array.length;
28711
28712    while (++index < length) {
28713      var current = iteratee(array[index]);
28714      if (current !== undefined) {
28715        result = result === undefined ? current : (result + current);
28716      }
28717    }
28718    return result;
28719  }
28720
28721  /**
28722   * The base implementation of `_.times` without support for iteratee shorthands
28723   * or max array length checks.
28724   *
28725   * @private
28726   * @param {number} n The number of times to invoke `iteratee`.
28727   * @param {Function} iteratee The function invoked per iteration.
28728   * @returns {Array} Returns the array of results.
28729   */
28730  function baseTimes(n, iteratee) {
28731    var index = -1,
28732        result = Array(n);
28733
28734    while (++index < n) {
28735      result[index] = iteratee(index);
28736    }
28737    return result;
28738  }
28739
28740  /**
28741   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
28742   * of key-value pairs for `object` corresponding to the property names of `props`.
28743   *
28744   * @private
28745   * @param {Object} object The object to query.
28746   * @param {Array} props The property names to get values for.
28747   * @returns {Object} Returns the key-value pairs.
28748   */
28749  function baseToPairs(object, props) {
28750    return arrayMap(props, function(key) {
28751      return [key, object[key]];
28752    });
28753  }
28754
28755  /**
28756   * The base implementation of `_.trim`.
28757   *
28758   * @private
28759   * @param {string} string The string to trim.
28760   * @returns {string} Returns the trimmed string.
28761   */
28762  function baseTrim(string) {
28763    return string
28764      ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
28765      : string;
28766  }
28767
28768  /**
28769   * The base implementation of `_.unary` without support for storing metadata.
28770   *
28771   * @private
28772   * @param {Function} func The function to cap arguments for.
28773   * @returns {Function} Returns the new capped function.
28774   */
28775  function baseUnary(func) {
28776    return function(value) {
28777      return func(value);
28778    };
28779  }
28780
28781  /**
28782   * The base implementation of `_.values` and `_.valuesIn` which creates an
28783   * array of `object` property values corresponding to the property names
28784   * of `props`.
28785   *
28786   * @private
28787   * @param {Object} object The object to query.
28788   * @param {Array} props The property names to get values for.
28789   * @returns {Object} Returns the array of property values.
28790   */
28791  function baseValues(object, props) {
28792    return arrayMap(props, function(key) {
28793      return object[key];
28794    });
28795  }
28796
28797  /**
28798   * Checks if a `cache` value for `key` exists.
28799   *
28800   * @private
28801   * @param {Object} cache The cache to query.
28802   * @param {string} key The key of the entry to check.
28803   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
28804   */
28805  function cacheHas(cache, key) {
28806    return cache.has(key);
28807  }
28808
28809  /**
28810   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
28811   * that is not found in the character symbols.
28812   *
28813   * @private
28814   * @param {Array} strSymbols The string symbols to inspect.
28815   * @param {Array} chrSymbols The character symbols to find.
28816   * @returns {number} Returns the index of the first unmatched string symbol.
28817   */
28818  function charsStartIndex(strSymbols, chrSymbols) {
28819    var index = -1,
28820        length = strSymbols.length;
28821
28822    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
28823    return index;
28824  }
28825
28826  /**
28827   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
28828   * that is not found in the character symbols.
28829   *
28830   * @private
28831   * @param {Array} strSymbols The string symbols to inspect.
28832   * @param {Array} chrSymbols The character symbols to find.
28833   * @returns {number} Returns the index of the last unmatched string symbol.
28834   */
28835  function charsEndIndex(strSymbols, chrSymbols) {
28836    var index = strSymbols.length;
28837
28838    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
28839    return index;
28840  }
28841
28842  /**
28843   * Gets the number of `placeholder` occurrences in `array`.
28844   *
28845   * @private
28846   * @param {Array} array The array to inspect.
28847   * @param {*} placeholder The placeholder to search for.
28848   * @returns {number} Returns the placeholder count.
28849   */
28850  function countHolders(array, placeholder) {
28851    var length = array.length,
28852        result = 0;
28853
28854    while (length--) {
28855      if (array[length] === placeholder) {
28856        ++result;
28857      }
28858    }
28859    return result;
28860  }
28861
28862  /**
28863   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
28864   * letters to basic Latin letters.
28865   *
28866   * @private
28867   * @param {string} letter The matched letter to deburr.
28868   * @returns {string} Returns the deburred letter.
28869   */
28870  var deburrLetter = basePropertyOf(deburredLetters);
28871
28872  /**
28873   * Used by `_.escape` to convert characters to HTML entities.
28874   *
28875   * @private
28876   * @param {string} chr The matched character to escape.
28877   * @returns {string} Returns the escaped character.
28878   */
28879  var escapeHtmlChar = basePropertyOf(htmlEscapes);
28880
28881  /**
28882   * Used by `_.template` to escape characters for inclusion in compiled string literals.
28883   *
28884   * @private
28885   * @param {string} chr The matched character to escape.
28886   * @returns {string} Returns the escaped character.
28887   */
28888  function escapeStringChar(chr) {
28889    return '\\' + stringEscapes[chr];
28890  }
28891
28892  /**
28893   * Gets the value at `key` of `object`.
28894   *
28895   * @private
28896   * @param {Object} [object] The object to query.
28897   * @param {string} key The key of the property to get.
28898   * @returns {*} Returns the property value.
28899   */
28900  function getValue(object, key) {
28901    return object == null ? undefined : object[key];
28902  }
28903
28904  /**
28905   * Checks if `string` contains Unicode symbols.
28906   *
28907   * @private
28908   * @param {string} string The string to inspect.
28909   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
28910   */
28911  function hasUnicode(string) {
28912    return reHasUnicode.test(string);
28913  }
28914
28915  /**
28916   * Checks if `string` contains a word composed of Unicode symbols.
28917   *
28918   * @private
28919   * @param {string} string The string to inspect.
28920   * @returns {boolean} Returns `true` if a word is found, else `false`.
28921   */
28922  function hasUnicodeWord(string) {
28923    return reHasUnicodeWord.test(string);
28924  }
28925
28926  /**
28927   * Converts `iterator` to an array.
vendor: 8,214 bytes, lines 28928-29237
28928   *
28929   * @private
28930   * @param {Object} iterator The iterator to convert.
28931   * @returns {Array} Returns the converted array.
28932   */
28933  function iteratorToArray(iterator) {
28934    var data,
28935        result = [];
28936
28937    while (!(data = iterator.next()).done) {
28938      result.push(data.value);
28939    }
28940    return result;
28941  }
28942
28943  /**
28944   * Converts `map` to its key-value pairs.
28945   *
28946   * @private
28947   * @param {Object} map The map to convert.
28948   * @returns {Array} Returns the key-value pairs.
28949   */
28950  function mapToArray(map) {
28951    var index = -1,
28952        result = Array(map.size);
28953
28954    map.forEach(function(value, key) {
28955      result[++index] = [key, value];
28956    });
28957    return result;
28958  }
28959
28960  /**
28961   * Creates a unary function that invokes `func` with its argument transformed.
28962   *
28963   * @private
28964   * @param {Function} func The function to wrap.
28965   * @param {Function} transform The argument transform.
28966   * @returns {Function} Returns the new function.
28967   */
28968  function overArg(func, transform) {
28969    return function(arg) {
28970      return func(transform(arg));
28971    };
28972  }
28973
28974  /**
28975   * Replaces all `placeholder` elements in `array` with an internal placeholder
28976   * and returns an array of their indexes.
28977   *
28978   * @private
28979   * @param {Array} array The array to modify.
28980   * @param {*} placeholder The placeholder to replace.
28981   * @returns {Array} Returns the new array of placeholder indexes.
28982   */
28983  function replaceHolders(array, placeholder) {
28984    var index = -1,
28985        length = array.length,
28986        resIndex = 0,
28987        result = [];
28988
28989    while (++index < length) {
28990      var value = array[index];
28991      if (value === placeholder || value === PLACEHOLDER) {
28992        array[index] = PLACEHOLDER;
28993        result[resIndex++] = index;
28994      }
28995    }
28996    return result;
28997  }
28998
28999  /**
29000   * Converts `set` to an array of its values.
29001   *
29002   * @private
29003   * @param {Object} set The set to convert.
29004   * @returns {Array} Returns the values.
29005   */
29006  function setToArray(set) {
29007    var index = -1,
29008        result = Array(set.size);
29009
29010    set.forEach(function(value) {
29011      result[++index] = value;
29012    });
29013    return result;
29014  }
29015
29016  /**
29017   * Converts `set` to its value-value pairs.
29018   *
29019   * @private
29020   * @param {Object} set The set to convert.
29021   * @returns {Array} Returns the value-value pairs.
29022   */
29023  function setToPairs(set) {
29024    var index = -1,
29025        result = Array(set.size);
29026
29027    set.forEach(function(value) {
29028      result[++index] = [value, value];
29029    });
29030    return result;
29031  }
29032
29033  /**
29034   * A specialized version of `_.indexOf` which performs strict equality
29035   * comparisons of values, i.e. `===`.
29036   *
29037   * @private
29038   * @param {Array} array The array to inspect.
29039   * @param {*} value The value to search for.
29040   * @param {number} fromIndex The index to search from.
29041   * @returns {number} Returns the index of the matched value, else `-1`.
29042   */
29043  function strictIndexOf(array, value, fromIndex) {
29044    var index = fromIndex - 1,
29045        length = array.length;
29046
29047    while (++index < length) {
29048      if (array[index] === value) {
29049        return index;
29050      }
29051    }
29052    return -1;
29053  }
29054
29055  /**
29056   * A specialized version of `_.lastIndexOf` which performs strict equality
29057   * comparisons of values, i.e. `===`.
29058   *
29059   * @private
29060   * @param {Array} array The array to inspect.
29061   * @param {*} value The value to search for.
29062   * @param {number} fromIndex The index to search from.
29063   * @returns {number} Returns the index of the matched value, else `-1`.
29064   */
29065  function strictLastIndexOf(array, value, fromIndex) {
29066    var index = fromIndex + 1;
29067    while (index--) {
29068      if (array[index] === value) {
29069        return index;
29070      }
29071    }
29072    return index;
29073  }
29074
29075  /**
29076   * Gets the number of symbols in `string`.
29077   *
29078   * @private
29079   * @param {string} string The string to inspect.
29080   * @returns {number} Returns the string size.
29081   */
29082  function stringSize(string) {
29083    return hasUnicode(string)
29084      ? unicodeSize(string)
29085      : asciiSize(string);
29086  }
29087
29088  /**
29089   * Converts `string` to an array.
29090   *
29091   * @private
29092   * @param {string} string The string to convert.
29093   * @returns {Array} Returns the converted array.
29094   */
29095  function stringToArray(string) {
29096    return hasUnicode(string)
29097      ? unicodeToArray(string)
29098      : asciiToArray(string);
29099  }
29100
29101  /**
29102   * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
29103   * character of `string`.
29104   *
29105   * @private
29106   * @param {string} string The string to inspect.
29107   * @returns {number} Returns the index of the last non-whitespace character.
29108   */
29109  function trimmedEndIndex(string) {
29110    var index = string.length;
29111
29112    while (index-- && reWhitespace.test(string.charAt(index))) {}
29113    return index;
29114  }
29115
29116  /**
29117   * Used by `_.unescape` to convert HTML entities to characters.
29118   *
29119   * @private
29120   * @param {string} chr The matched character to unescape.
29121   * @returns {string} Returns the unescaped character.
29122   */
29123  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
29124
29125  /**
29126   * Gets the size of a Unicode `string`.
29127   *
29128   * @private
29129   * @param {string} string The string inspect.
29130   * @returns {number} Returns the string size.
29131   */
29132  function unicodeSize(string) {
29133    var result = reUnicode.lastIndex = 0;
29134    while (reUnicode.test(string)) {
29135      ++result;
29136    }
29137    return result;
29138  }
29139
29140  /**
29141   * Converts a Unicode `string` to an array.
29142   *
29143   * @private
29144   * @param {string} string The string to convert.
29145   * @returns {Array} Returns the converted array.
29146   */
29147  function unicodeToArray(string) {
29148    return string.match(reUnicode) || [];
29149  }
29150
29151  /**
29152   * Splits a Unicode `string` into an array of its words.
29153   *
29154   * @private
29155   * @param {string} The string to inspect.
29156   * @returns {Array} Returns the words of `string`.
29157   */
29158  function unicodeWords(string) {
29159    return string.match(reUnicodeWord) || [];
29160  }
29161
29162  /*--------------------------------------------------------------------------*/
29163
29164  /**
29165   * Create a new pristine `lodash` function using the `context` object.
29166   *
29167   * @static
29168   * @memberOf _
29169   * @since 1.1.0
29170   * @category Util
29171   * @param {Object} [context=root] The context object.
29172   * @returns {Function} Returns a new `lodash` function.
29173   * @example
29174   *
29175   * _.mixin({ 'foo': _.constant('foo') });
29176   *
29177   * var lodash = _.runInContext();
29178   * lodash.mixin({ 'bar': lodash.constant('bar') });
29179   *
29180   * _.isFunction(_.foo);
29181   * // => true
29182   * _.isFunction(_.bar);
29183   * // => false
29184   *
29185   * lodash.isFunction(lodash.foo);
29186   * // => false
29187   * lodash.isFunction(lodash.bar);
29188   * // => true
29189   *
29190   * // Create a suped-up `defer` in Node.js.
29191   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
29192   */
29193  var runInContext = (function runInContext(context) {
29194    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
29195
29196    /** Built-in constructor references. */
29197    var Array = context.Array,
29198        Date = context.Date,
29199        Error = context.Error,
29200        Function = context.Function,
29201        Math = context.Math,
29202        Object = context.Object,
29203        RegExp = context.RegExp,
29204        String = context.String,
29205        TypeError = context.TypeError;
29206
29207    /** Used for built-in method references. */
29208    var arrayProto = Array.prototype,
29209        funcProto = Function.prototype,
29210        objectProto = Object.prototype;
29211
29212    /** Used to detect overreaching core-js shims. */
29213    var coreJsData = context['__core-js_shared__'];
29214
29215    /** Used to resolve the decompiled source of functions. */
29216    var funcToString = funcProto.toString;
29217
29218    /** Used to check objects for own properties. */
29219    var hasOwnProperty = objectProto.hasOwnProperty;
29220
29221    /** Used to generate unique IDs. */
29222    var idCounter = 0;
29223
29224    /** Used to detect methods masquerading as native. */
29225    var maskSrcKey = (function() {
29226      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
29227      return uid ? ('Symbol(src)_1.' + uid) : '';
29228    }());
29229
29230    /**
29231     * Used to resolve the
29232     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
29233     * of values.
29234     */
29235    var nativeObjectToString = objectProto.toString;
29236
29237    /** Used to infer the `Object` constructor. */
vendor: 25,659 bytes, lines 29238-30035
29238    var objectCtorString = funcToString.call(Object);
29239
29240    /** Used to restore the original `_` reference in `_.noConflict`. */
29241    var oldDash = root._;
29242
29243    /** Used to detect if a method is native. */
29244    var reIsNative = RegExp('^' +
29245      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
29246      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
29247    );
29248
29249    /** Built-in value references. */
29250    var Buffer = moduleExports ? context.Buffer : undefined,
29251        Symbol = context.Symbol,
29252        Uint8Array = context.Uint8Array,
29253        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
29254        getPrototype = overArg(Object.getPrototypeOf, Object),
29255        objectCreate = Object.create,
29256        propertyIsEnumerable = objectProto.propertyIsEnumerable,
29257        splice = arrayProto.splice,
29258        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
29259        symIterator = Symbol ? Symbol.iterator : undefined,
29260        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
29261
29262    var defineProperty = (function() {
29263      try {
29264        var func = getNative(Object, 'defineProperty');
29265        func({}, '', {});
29266        return func;
29267      } catch (e) {}
29268    }());
29269
29270    /** Mocked built-ins. */
29271    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
29272        ctxNow = Date && Date.now !== root.Date.now && Date.now,
29273        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
29274
29275    /* Built-in method references for those with the same name as other `lodash` methods. */
29276    var nativeCeil = Math.ceil,
29277        nativeFloor = Math.floor,
29278        nativeGetSymbols = Object.getOwnPropertySymbols,
29279        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
29280        nativeIsFinite = context.isFinite,
29281        nativeJoin = arrayProto.join,
29282        nativeKeys = overArg(Object.keys, Object),
29283        nativeMax = Math.max,
29284        nativeMin = Math.min,
29285        nativeNow = Date.now,
29286        nativeParseInt = context.parseInt,
29287        nativeRandom = Math.random,
29288        nativeReverse = arrayProto.reverse;
29289
29290    /* Built-in method references that are verified to be native. */
29291    var DataView = getNative(context, 'DataView'),
29292        Map = getNative(context, 'Map'),
29293        Promise = getNative(context, 'Promise'),
29294        Set = getNative(context, 'Set'),
29295        WeakMap = getNative(context, 'WeakMap'),
29296        nativeCreate = getNative(Object, 'create');
29297
29298    /** Used to store function metadata. */
29299    var metaMap = WeakMap && new WeakMap;
29300
29301    /** Used to lookup unminified function names. */
29302    var realNames = {};
29303
29304    /** Used to detect maps, sets, and weakmaps. */
29305    var dataViewCtorString = toSource(DataView),
29306        mapCtorString = toSource(Map),
29307        promiseCtorString = toSource(Promise),
29308        setCtorString = toSource(Set),
29309        weakMapCtorString = toSource(WeakMap);
29310
29311    /** Used to convert symbols to primitives and strings. */
29312    var symbolProto = Symbol ? Symbol.prototype : undefined,
29313        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
29314        symbolToString = symbolProto ? symbolProto.toString : undefined;
29315
29316    /*------------------------------------------------------------------------*/
29317
29318    /**
29319     * Creates a `lodash` object which wraps `value` to enable implicit method
29320     * chain sequences. Methods that operate on and return arrays, collections,
29321     * and functions can be chained together. Methods that retrieve a single value
29322     * or may return a primitive value will automatically end the chain sequence
29323     * and return the unwrapped value. Otherwise, the value must be unwrapped
29324     * with `_#value`.
29325     *
29326     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
29327     * enabled using `_.chain`.
29328     *
29329     * The execution of chained methods is lazy, that is, it's deferred until
29330     * `_#value` is implicitly or explicitly called.
29331     *
29332     * Lazy evaluation allows several methods to support shortcut fusion.
29333     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
29334     * the creation of intermediate arrays and can greatly reduce the number of
29335     * iteratee executions. Sections of a chain sequence qualify for shortcut
29336     * fusion if the section is applied to an array and iteratees accept only
29337     * one argument. The heuristic for whether a section qualifies for shortcut
29338     * fusion is subject to change.
29339     *
29340     * Chaining is supported in custom builds as long as the `_#value` method is
29341     * directly or indirectly included in the build.
29342     *
29343     * In addition to lodash methods, wrappers have `Array` and `String` methods.
29344     *
29345     * The wrapper `Array` methods are:
29346     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
29347     *
29348     * The wrapper `String` methods are:
29349     * `replace` and `split`
29350     *
29351     * The wrapper methods that support shortcut fusion are:
29352     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
29353     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
29354     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
29355     *
29356     * The chainable wrapper methods are:
29357     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
29358     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
29359     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
29360     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
29361     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
29362     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
29363     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
29364     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
29365     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
29366     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
29367     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
29368     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
29369     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
29370     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
29371     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
29372     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
29373     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
29374     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
29375     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
29376     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
29377     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
29378     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
29379     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
29380     * `zipObject`, `zipObjectDeep`, and `zipWith`
29381     *
29382     * The wrapper methods that are **not** chainable by default are:
29383     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
29384     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
29385     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
29386     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
29387     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
29388     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
29389     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
29390     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
29391     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
29392     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
29393     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
29394     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
29395     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
29396     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
29397     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
29398     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
29399     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
29400     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
29401     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
29402     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
29403     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
29404     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
29405     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
29406     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
29407     * `upperFirst`, `value`, and `words`
29408     *
29409     * @name _
29410     * @constructor
29411     * @category Seq
29412     * @param {*} value The value to wrap in a `lodash` instance.
29413     * @returns {Object} Returns the new `lodash` wrapper instance.
29414     * @example
29415     *
29416     * function square(n) {
29417     *   return n * n;
29418     * }
29419     *
29420     * var wrapped = _([1, 2, 3]);
29421     *
29422     * // Returns an unwrapped value.
29423     * wrapped.reduce(_.add);
29424     * // => 6
29425     *
29426     * // Returns a wrapped value.
29427     * var squares = wrapped.map(square);
29428     *
29429     * _.isArray(squares);
29430     * // => false
29431     *
29432     * _.isArray(squares.value());
29433     * // => true
29434     */
29435    function lodash(value) {
29436      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
29437        if (value instanceof LodashWrapper) {
29438          return value;
29439        }
29440        if (hasOwnProperty.call(value, '__wrapped__')) {
29441          return wrapperClone(value);
29442        }
29443      }
29444      return new LodashWrapper(value);
29445    }
29446
29447    /**
29448     * The base implementation of `_.create` without support for assigning
29449     * properties to the created object.
29450     *
29451     * @private
29452     * @param {Object} proto The object to inherit from.
29453     * @returns {Object} Returns the new object.
29454     */
29455    var baseCreate = (function() {
29456      function object() {}
29457      return function(proto) {
29458        if (!isObject(proto)) {
29459          return {};
29460        }
29461        if (objectCreate) {
29462          return objectCreate(proto);
29463        }
29464        object.prototype = proto;
29465        var result = new object;
29466        object.prototype = undefined;
29467        return result;
29468      };
29469    }());
29470
29471    /**
29472     * The function whose prototype chain sequence wrappers inherit from.
29473     *
29474     * @private
29475     */
29476    function baseLodash() {
29477      // No operation performed.
29478    }
29479
29480    /**
29481     * The base constructor for creating `lodash` wrapper objects.
29482     *
29483     * @private
29484     * @param {*} value The value to wrap.
29485     * @param {boolean} [chainAll] Enable explicit method chain sequences.
29486     */
29487    function LodashWrapper(value, chainAll) {
29488      this.__wrapped__ = value;
29489      this.__actions__ = [];
29490      this.__chain__ = !!chainAll;
29491      this.__index__ = 0;
29492      this.__values__ = undefined;
29493    }
29494
29495    /**
29496     * By default, the template delimiters used by lodash are like those in
29497     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
29498     * following template settings to use alternative delimiters.
29499     *
29500     * @static
29501     * @memberOf _
29502     * @type {Object}
29503     */
29504    lodash.templateSettings = {
29505
29506      /**
29507       * Used to detect `data` property values to be HTML-escaped.
29508       *
29509       * @memberOf _.templateSettings
29510       * @type {RegExp}
29511       */
29512      'escape': reEscape,
29513
29514      /**
29515       * Used to detect code to be evaluated.
29516       *
29517       * @memberOf _.templateSettings
29518       * @type {RegExp}
29519       */
29520      'evaluate': reEvaluate,
29521
29522      /**
29523       * Used to detect `data` property values to inject.
29524       *
29525       * @memberOf _.templateSettings
29526       * @type {RegExp}
29527       */
29528      'interpolate': reInterpolate,
29529
29530      /**
29531       * Used to reference the data object in the template text.
29532       *
29533       * @memberOf _.templateSettings
29534       * @type {string}
29535       */
29536      'variable': '',
29537
29538      /**
29539       * Used to import variables into the compiled template.
29540       *
29541       * @memberOf _.templateSettings
29542       * @type {Object}
29543       */
29544      'imports': {
29545
29546        /**
29547         * A reference to the `lodash` function.
29548         *
29549         * @memberOf _.templateSettings.imports
29550         * @type {Function}
29551         */
29552        '_': lodash
29553      }
29554    };
29555
29556    // Ensure wrappers are instances of `baseLodash`.
29557    lodash.prototype = baseLodash.prototype;
29558    lodash.prototype.constructor = lodash;
29559
29560    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
29561    LodashWrapper.prototype.constructor = LodashWrapper;
29562
29563    /*------------------------------------------------------------------------*/
29564
29565    /**
29566     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
29567     *
29568     * @private
29569     * @constructor
29570     * @param {*} value The value to wrap.
29571     */
29572    function LazyWrapper(value) {
29573      this.__wrapped__ = value;
29574      this.__actions__ = [];
29575      this.__dir__ = 1;
29576      this.__filtered__ = false;
29577      this.__iteratees__ = [];
29578      this.__takeCount__ = MAX_ARRAY_LENGTH;
29579      this.__views__ = [];
29580    }
29581
29582    /**
29583     * Creates a clone of the lazy wrapper object.
29584     *
29585     * @private
29586     * @name clone
29587     * @memberOf LazyWrapper
29588     * @returns {Object} Returns the cloned `LazyWrapper` object.
29589     */
29590    function lazyClone() {
29591      var result = new LazyWrapper(this.__wrapped__);
29592      result.__actions__ = copyArray(this.__actions__);
29593      result.__dir__ = this.__dir__;
29594      result.__filtered__ = this.__filtered__;
29595      result.__iteratees__ = copyArray(this.__iteratees__);
29596      result.__takeCount__ = this.__takeCount__;
29597      result.__views__ = copyArray(this.__views__);
29598      return result;
29599    }
29600
29601    /**
29602     * Reverses the direction of lazy iteration.
29603     *
29604     * @private
29605     * @name reverse
29606     * @memberOf LazyWrapper
29607     * @returns {Object} Returns the new reversed `LazyWrapper` object.
29608     */
29609    function lazyReverse() {
29610      if (this.__filtered__) {
29611        var result = new LazyWrapper(this);
29612        result.__dir__ = -1;
29613        result.__filtered__ = true;
29614      } else {
29615        result = this.clone();
29616        result.__dir__ *= -1;
29617      }
29618      return result;
29619    }
29620
29621    /**
29622     * Extracts the unwrapped value from its lazy wrapper.
29623     *
29624     * @private
29625     * @name value
29626     * @memberOf LazyWrapper
29627     * @returns {*} Returns the unwrapped value.
29628     */
29629    function lazyValue() {
29630      var array = this.__wrapped__.value(),
29631          dir = this.__dir__,
29632          isArr = isArray(array),
29633          isRight = dir < 0,
29634          arrLength = isArr ? array.length : 0,
29635          view = getView(0, arrLength, this.__views__),
29636          start = view.start,
29637          end = view.end,
29638          length = end - start,
29639          index = isRight ? end : (start - 1),
29640          iteratees = this.__iteratees__,
29641          iterLength = iteratees.length,
29642          resIndex = 0,
29643          takeCount = nativeMin(length, this.__takeCount__);
29644
29645      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
29646        return baseWrapperValue(array, this.__actions__);
29647      }
29648      var result = [];
29649
29650      outer:
29651      while (length-- && resIndex < takeCount) {
29652        index += dir;
29653
29654        var iterIndex = -1,
29655            value = array[index];
29656
29657        while (++iterIndex < iterLength) {
29658          var data = iteratees[iterIndex],
29659              iteratee = data.iteratee,
29660              type = data.type,
29661              computed = iteratee(value);
29662
29663          if (type == LAZY_MAP_FLAG) {
29664            value = computed;
29665          } else if (!computed) {
29666            if (type == LAZY_FILTER_FLAG) {
29667              continue outer;
29668            } else {
29669              break outer;
29670            }
29671          }
29672        }
29673        result[resIndex++] = value;
29674      }
29675      return result;
29676    }
29677
29678    // Ensure `LazyWrapper` is an instance of `baseLodash`.
29679    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
29680    LazyWrapper.prototype.constructor = LazyWrapper;
29681
29682    /*------------------------------------------------------------------------*/
29683
29684    /**
29685     * Creates a hash object.
29686     *
29687     * @private
29688     * @constructor
29689     * @param {Array} [entries] The key-value pairs to cache.
29690     */
29691    function Hash(entries) {
29692      var index = -1,
29693          length = entries == null ? 0 : entries.length;
29694
29695      this.clear();
29696      while (++index < length) {
29697        var entry = entries[index];
29698        this.set(entry[0], entry[1]);
29699      }
29700    }
29701
29702    /**
29703     * Removes all key-value entries from the hash.
29704     *
29705     * @private
29706     * @name clear
29707     * @memberOf Hash
29708     */
29709    function hashClear() {
29710      this.__data__ = nativeCreate ? nativeCreate(null) : {};
29711      this.size = 0;
29712    }
29713
29714    /**
29715     * Removes `key` and its value from the hash.
29716     *
29717     * @private
29718     * @name delete
29719     * @memberOf Hash
29720     * @param {Object} hash The hash to modify.
29721     * @param {string} key The key of the value to remove.
29722     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
29723     */
29724    function hashDelete(key) {
29725      var result = this.has(key) && delete this.__data__[key];
29726      this.size -= result ? 1 : 0;
29727      return result;
29728    }
29729
29730    /**
29731     * Gets the hash value for `key`.
29732     *
29733     * @private
29734     * @name get
29735     * @memberOf Hash
29736     * @param {string} key The key of the value to get.
29737     * @returns {*} Returns the entry value.
29738     */
29739    function hashGet(key) {
29740      var data = this.__data__;
29741      if (nativeCreate) {
29742        var result = data[key];
29743        return result === HASH_UNDEFINED ? undefined : result;
29744      }
29745      return hasOwnProperty.call(data, key) ? data[key] : undefined;
29746    }
29747
29748    /**
29749     * Checks if a hash value for `key` exists.
29750     *
29751     * @private
29752     * @name has
29753     * @memberOf Hash
29754     * @param {string} key The key of the entry to check.
29755     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
29756     */
29757    function hashHas(key) {
29758      var data = this.__data__;
29759      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
29760    }
29761
29762    /**
29763     * Sets the hash `key` to `value`.
29764     *
29765     * @private
29766     * @name set
29767     * @memberOf Hash
29768     * @param {string} key The key of the value to set.
29769     * @param {*} value The value to set.
29770     * @returns {Object} Returns the hash instance.
29771     */
29772    function hashSet(key, value) {
29773      var data = this.__data__;
29774      this.size += this.has(key) ? 0 : 1;
29775      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
29776      return this;
29777    }
29778
29779    // Add methods to `Hash`.
29780    Hash.prototype.clear = hashClear;
29781    Hash.prototype['delete'] = hashDelete;
29782    Hash.prototype.get = hashGet;
29783    Hash.prototype.has = hashHas;
29784    Hash.prototype.set = hashSet;
29785
29786    /*------------------------------------------------------------------------*/
29787
29788    /**
29789     * Creates an list cache object.
29790     *
29791     * @private
29792     * @constructor
29793     * @param {Array} [entries] The key-value pairs to cache.
29794     */
29795    function ListCache(entries) {
29796      var index = -1,
29797          length = entries == null ? 0 : entries.length;
29798
29799      this.clear();
29800      while (++index < length) {
29801        var entry = entries[index];
29802        this.set(entry[0], entry[1]);
29803      }
29804    }
29805
29806    /**
29807     * Removes all key-value entries from the list cache.
29808     *
29809     * @private
29810     * @name clear
29811     * @memberOf ListCache
29812     */
29813    function listCacheClear() {
29814      this.__data__ = [];
29815      this.size = 0;
29816    }
29817
29818    /**
29819     * Removes `key` and its value from the list cache.
29820     *
29821     * @private
29822     * @name delete
29823     * @memberOf ListCache
29824     * @param {string} key The key of the value to remove.
29825     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
29826     */
29827    function listCacheDelete(key) {
29828      var data = this.__data__,
29829          index = assocIndexOf(data, key);
29830
29831      if (index < 0) {
29832        return false;
29833      }
29834      var lastIndex = data.length - 1;
29835      if (index == lastIndex) {
29836        data.pop();
29837      } else {
29838        splice.call(data, index, 1);
29839      }
29840      --this.size;
29841      return true;
29842    }
29843
29844    /**
29845     * Gets the list cache value for `key`.
29846     *
29847     * @private
29848     * @name get
29849     * @memberOf ListCache
29850     * @param {string} key The key of the value to get.
29851     * @returns {*} Returns the entry value.
29852     */
29853    function listCacheGet(key) {
29854      var data = this.__data__,
29855          index = assocIndexOf(data, key);
29856
29857      return index < 0 ? undefined : data[index][1];
29858    }
29859
29860    /**
29861     * Checks if a list cache value for `key` exists.
29862     *
29863     * @private
29864     * @name has
29865     * @memberOf ListCache
29866     * @param {string} key The key of the entry to check.
29867     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
29868     */
29869    function listCacheHas(key) {
29870      return assocIndexOf(this.__data__, key) > -1;
29871    }
29872
29873    /**
29874     * Sets the list cache `key` to `value`.
29875     *
29876     * @private
29877     * @name set
29878     * @memberOf ListCache
29879     * @param {string} key The key of the value to set.
29880     * @param {*} value The value to set.
29881     * @returns {Object} Returns the list cache instance.
29882     */
29883    function listCacheSet(key, value) {
29884      var data = this.__data__,
29885          index = assocIndexOf(data, key);
29886
29887      if (index < 0) {
29888        ++this.size;
29889        data.push([key, value]);
29890      } else {
29891        data[index][1] = value;
29892      }
29893      return this;
29894    }
29895
29896    // Add methods to `ListCache`.
29897    ListCache.prototype.clear = listCacheClear;
29898    ListCache.prototype['delete'] = listCacheDelete;
29899    ListCache.prototype.get = listCacheGet;
29900    ListCache.prototype.has = listCacheHas;
29901    ListCache.prototype.set = listCacheSet;
29902
29903    /*------------------------------------------------------------------------*/
29904
29905    /**
29906     * Creates a map cache object to store key-value pairs.
29907     *
29908     * @private
29909     * @constructor
29910     * @param {Array} [entries] The key-value pairs to cache.
29911     */
29912    function MapCache(entries) {
29913      var index = -1,
29914          length = entries == null ? 0 : entries.length;
29915
29916      this.clear();
29917      while (++index < length) {
29918        var entry = entries[index];
29919        this.set(entry[0], entry[1]);
29920      }
29921    }
29922
29923    /**
29924     * Removes all key-value entries from the map.
29925     *
29926     * @private
29927     * @name clear
29928     * @memberOf MapCache
29929     */
29930    function mapCacheClear() {
29931      this.size = 0;
29932      this.__data__ = {
29933        'hash': new Hash,
29934        'map': new (Map || ListCache),
29935        'string': new Hash
29936      };
29937    }
29938
29939    /**
29940     * Removes `key` and its value from the map.
29941     *
29942     * @private
29943     * @name delete
29944     * @memberOf MapCache
29945     * @param {string} key The key of the value to remove.
29946     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
29947     */
29948    function mapCacheDelete(key) {
29949      var result = getMapData(this, key)['delete'](key);
29950      this.size -= result ? 1 : 0;
29951      return result;
29952    }
29953
29954    /**
29955     * Gets the map value for `key`.
29956     *
29957     * @private
29958     * @name get
29959     * @memberOf MapCache
29960     * @param {string} key The key of the value to get.
29961     * @returns {*} Returns the entry value.
29962     */
29963    function mapCacheGet(key) {
29964      return getMapData(this, key).get(key);
29965    }
29966
29967    /**
29968     * Checks if a map value for `key` exists.
29969     *
29970     * @private
29971     * @name has
29972     * @memberOf MapCache
29973     * @param {string} key The key of the entry to check.
29974     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
29975     */
29976    function mapCacheHas(key) {
29977      return getMapData(this, key).has(key);
29978    }
29979
29980    /**
29981     * Sets the map `key` to `value`.
29982     *
29983     * @private
29984     * @name set
29985     * @memberOf MapCache
29986     * @param {string} key The key of the value to set.
29987     * @param {*} value The value to set.
29988     * @returns {Object} Returns the map cache instance.
29989     */
29990    function mapCacheSet(key, value) {
29991      var data = getMapData(this, key),
29992          size = data.size;
29993
29994      data.set(key, value);
29995      this.size += data.size == size ? 0 : 1;
29996      return this;
29997    }
29998
29999    // Add methods to `MapCache`.
30000    MapCache.prototype.clear = mapCacheClear;
30001    MapCache.prototype['delete'] = mapCacheDelete;
30002    MapCache.prototype.get = mapCacheGet;
30003    MapCache.prototype.has = mapCacheHas;
30004    MapCache.prototype.set = mapCacheSet;
30005
30006    /*------------------------------------------------------------------------*/
30007
30008    /**
30009     *
30010     * Creates an array cache object to store unique values.
30011     *
30012     * @private
30013     * @constructor
30014     * @param {Array} [values] The values to cache.
30015     */
30016    function SetCache(values) {
30017      var index = -1,
30018          length = values == null ? 0 : values.length;
30019
30020      this.__data__ = new MapCache;
30021      while (++index < length) {
30022        this.add(values[index]);
30023      }
30024    }
30025
30026    /**
30027     * Adds `value` to the array cache.
30028     *
30029     * @private
30030     * @name add
30031     * @memberOf SetCache
30032     * @alias push
30033     * @param {*} value The value to cache.
30034     * @returns {Object} Returns the cache instance.
30035     */
vendor: 3,741 bytes, lines 30036-30172
30036    function setCacheAdd(value) {
30037      this.__data__.set(value, HASH_UNDEFINED);
30038      return this;
30039    }
30040
30041    /**
30042     * Checks if `value` is in the array cache.
30043     *
30044     * @private
30045     * @name has
30046     * @memberOf SetCache
30047     * @param {*} value The value to search for.
30048     * @returns {number} Returns `true` if `value` is found, else `false`.
30049     */
30050    function setCacheHas(value) {
30051      return this.__data__.has(value);
30052    }
30053
30054    // Add methods to `SetCache`.
30055    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
30056    SetCache.prototype.has = setCacheHas;
30057
30058    /*------------------------------------------------------------------------*/
30059
30060    /**
30061     * Creates a stack cache object to store key-value pairs.
30062     *
30063     * @private
30064     * @constructor
30065     * @param {Array} [entries] The key-value pairs to cache.
30066     */
30067    function Stack(entries) {
30068      var data = this.__data__ = new ListCache(entries);
30069      this.size = data.size;
30070    }
30071
30072    /**
30073     * Removes all key-value entries from the stack.
30074     *
30075     * @private
30076     * @name clear
30077     * @memberOf Stack
30078     */
30079    function stackClear() {
30080      this.__data__ = new ListCache;
30081      this.size = 0;
30082    }
30083
30084    /**
30085     * Removes `key` and its value from the stack.
30086     *
30087     * @private
30088     * @name delete
30089     * @memberOf Stack
30090     * @param {string} key The key of the value to remove.
30091     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
30092     */
30093    function stackDelete(key) {
30094      var data = this.__data__,
30095          result = data['delete'](key);
30096
30097      this.size = data.size;
30098      return result;
30099    }
30100
30101    /**
30102     * Gets the stack value for `key`.
30103     *
30104     * @private
30105     * @name get
30106     * @memberOf Stack
30107     * @param {string} key The key of the value to get.
30108     * @returns {*} Returns the entry value.
30109     */
30110    function stackGet(key) {
30111      return this.__data__.get(key);
30112    }
30113
30114    /**
30115     * Checks if a stack value for `key` exists.
30116     *
30117     * @private
30118     * @name has
30119     * @memberOf Stack
30120     * @param {string} key The key of the entry to check.
30121     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
30122     */
30123    function stackHas(key) {
30124      return this.__data__.has(key);
30125    }
30126
30127    /**
30128     * Sets the stack `key` to `value`.
30129     *
30130     * @private
30131     * @name set
30132     * @memberOf Stack
30133     * @param {string} key The key of the value to set.
30134     * @param {*} value The value to set.
30135     * @returns {Object} Returns the stack cache instance.
30136     */
30137    function stackSet(key, value) {
30138      var data = this.__data__;
30139      if (data instanceof ListCache) {
30140        var pairs = data.__data__;
30141        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
30142          pairs.push([key, value]);
30143          this.size = ++data.size;
30144          return this;
30145        }
30146        data = this.__data__ = new MapCache(pairs);
30147      }
30148      data.set(key, value);
30149      this.size = data.size;
30150      return this;
30151    }
30152
30153    // Add methods to `Stack`.
30154    Stack.prototype.clear = stackClear;
30155    Stack.prototype['delete'] = stackDelete;
30156    Stack.prototype.get = stackGet;
30157    Stack.prototype.has = stackHas;
30158    Stack.prototype.set = stackSet;
30159
30160    /*------------------------------------------------------------------------*/
30161
30162    /**
30163     * Creates an array of the enumerable property names of the array-like `value`.
30164     *
30165     * @private
30166     * @param {*} value The value to query.
30167     * @param {boolean} inherited Specify returning inherited property names.
30168     * @returns {Array} Returns the array of property names.
30169     */
30170    function arrayLikeKeys(value, inherited) {
30171      var isArr = isArray(value),
30172          isArg = !isArr && isArguments(value),
vendor: 111,524 bytes, lines 30173-33466
30173          isBuff = !isArr && !isArg && isBuffer(value),
30174          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
30175          skipIndexes = isArr || isArg || isBuff || isType,
30176          result = skipIndexes ? baseTimes(value.length, String) : [],
30177          length = result.length;
30178
30179      for (var key in value) {
30180        if ((inherited || hasOwnProperty.call(value, key)) &&
30181            !(skipIndexes && (
30182               // Safari 9 has enumerable `arguments.length` in strict mode.
30183               key == 'length' ||
30184               // Node.js 0.10 has enumerable non-index properties on buffers.
30185               (isBuff && (key == 'offset' || key == 'parent')) ||
30186               // PhantomJS 2 has enumerable non-index properties on typed arrays.
30187               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
30188               // Skip index properties.
30189               isIndex(key, length)
30190            ))) {
30191          result.push(key);
30192        }
30193      }
30194      return result;
30195    }
30196
30197    /**
30198     * A specialized version of `_.sample` for arrays.
30199     *
30200     * @private
30201     * @param {Array} array The array to sample.
30202     * @returns {*} Returns the random element.
30203     */
30204    function arraySample(array) {
30205      var length = array.length;
30206      return length ? array[baseRandom(0, length - 1)] : undefined;
30207    }
30208
30209    /**
30210     * A specialized version of `_.sampleSize` for arrays.
30211     *
30212     * @private
30213     * @param {Array} array The array to sample.
30214     * @param {number} n The number of elements to sample.
30215     * @returns {Array} Returns the random elements.
30216     */
30217    function arraySampleSize(array, n) {
30218      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
30219    }
30220
30221    /**
30222     * A specialized version of `_.shuffle` for arrays.
30223     *
30224     * @private
30225     * @param {Array} array The array to shuffle.
30226     * @returns {Array} Returns the new shuffled array.
30227     */
30228    function arrayShuffle(array) {
30229      return shuffleSelf(copyArray(array));
30230    }
30231
30232    /**
30233     * This function is like `assignValue` except that it doesn't assign
30234     * `undefined` values.
30235     *
30236     * @private
30237     * @param {Object} object The object to modify.
30238     * @param {string} key The key of the property to assign.
30239     * @param {*} value The value to assign.
30240     */
30241    function assignMergeValue(object, key, value) {
30242      if ((value !== undefined && !eq(object[key], value)) ||
30243          (value === undefined && !(key in object))) {
30244        baseAssignValue(object, key, value);
30245      }
30246    }
30247
30248    /**
30249     * Assigns `value` to `key` of `object` if the existing value is not equivalent
30250     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
30251     * for equality comparisons.
30252     *
30253     * @private
30254     * @param {Object} object The object to modify.
30255     * @param {string} key The key of the property to assign.
30256     * @param {*} value The value to assign.
30257     */
30258    function assignValue(object, key, value) {
30259      var objValue = object[key];
30260      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
30261          (value === undefined && !(key in object))) {
30262        baseAssignValue(object, key, value);
30263      }
30264    }
30265
30266    /**
30267     * Gets the index at which the `key` is found in `array` of key-value pairs.
30268     *
30269     * @private
30270     * @param {Array} array The array to inspect.
30271     * @param {*} key The key to search for.
30272     * @returns {number} Returns the index of the matched value, else `-1`.
30273     */
30274    function assocIndexOf(array, key) {
30275      var length = array.length;
30276      while (length--) {
30277        if (eq(array[length][0], key)) {
30278          return length;
30279        }
30280      }
30281      return -1;
30282    }
30283
30284    /**
30285     * Aggregates elements of `collection` on `accumulator` with keys transformed
30286     * by `iteratee` and values set by `setter`.
30287     *
30288     * @private
30289     * @param {Array|Object} collection The collection to iterate over.
30290     * @param {Function} setter The function to set `accumulator` values.
30291     * @param {Function} iteratee The iteratee to transform keys.
30292     * @param {Object} accumulator The initial aggregated object.
30293     * @returns {Function} Returns `accumulator`.
30294     */
30295    function baseAggregator(collection, setter, iteratee, accumulator) {
30296      baseEach(collection, function(value, key, collection) {
30297        setter(accumulator, value, iteratee(value), collection);
30298      });
30299      return accumulator;
30300    }
30301
30302    /**
30303     * The base implementation of `_.assign` without support for multiple sources
30304     * or `customizer` functions.
30305     *
30306     * @private
30307     * @param {Object} object The destination object.
30308     * @param {Object} source The source object.
30309     * @returns {Object} Returns `object`.
30310     */
30311    function baseAssign(object, source) {
30312      return object && copyObject(source, keys(source), object);
30313    }
30314
30315    /**
30316     * The base implementation of `_.assignIn` without support for multiple sources
30317     * or `customizer` functions.
30318     *
30319     * @private
30320     * @param {Object} object The destination object.
30321     * @param {Object} source The source object.
30322     * @returns {Object} Returns `object`.
30323     */
30324    function baseAssignIn(object, source) {
30325      return object && copyObject(source, keysIn(source), object);
30326    }
30327
30328    /**
30329     * The base implementation of `assignValue` and `assignMergeValue` without
30330     * value checks.
30331     *
30332     * @private
30333     * @param {Object} object The object to modify.
30334     * @param {string} key The key of the property to assign.
30335     * @param {*} value The value to assign.
30336     */
30337    function baseAssignValue(object, key, value) {
30338      if (key == '__proto__' && defineProperty) {
30339        defineProperty(object, key, {
30340          'configurable': true,
30341          'enumerable': true,
30342          'value': value,
30343          'writable': true
30344        });
30345      } else {
30346        object[key] = value;
30347      }
30348    }
30349
30350    /**
30351     * The base implementation of `_.at` without support for individual paths.
30352     *
30353     * @private
30354     * @param {Object} object The object to iterate over.
30355     * @param {string[]} paths The property paths to pick.
30356     * @returns {Array} Returns the picked elements.
30357     */
30358    function baseAt(object, paths) {
30359      var index = -1,
30360          length = paths.length,
30361          result = Array(length),
30362          skip = object == null;
30363
30364      while (++index < length) {
30365        result[index] = skip ? undefined : get(object, paths[index]);
30366      }
30367      return result;
30368    }
30369
30370    /**
30371     * The base implementation of `_.clamp` which doesn't coerce arguments.
30372     *
30373     * @private
30374     * @param {number} number The number to clamp.
30375     * @param {number} [lower] The lower bound.
30376     * @param {number} upper The upper bound.
30377     * @returns {number} Returns the clamped number.
30378     */
30379    function baseClamp(number, lower, upper) {
30380      if (number === number) {
30381        if (upper !== undefined) {
30382          number = number <= upper ? number : upper;
30383        }
30384        if (lower !== undefined) {
30385          number = number >= lower ? number : lower;
30386        }
30387      }
30388      return number;
30389    }
30390
30391    /**
30392     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
30393     * traversed objects.
30394     *
30395     * @private
30396     * @param {*} value The value to clone.
30397     * @param {boolean} bitmask The bitmask flags.
30398     *  1 - Deep clone
30399     *  2 - Flatten inherited properties
30400     *  4 - Clone symbols
30401     * @param {Function} [customizer] The function to customize cloning.
30402     * @param {string} [key] The key of `value`.
30403     * @param {Object} [object] The parent object of `value`.
30404     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
30405     * @returns {*} Returns the cloned value.
30406     */
30407    function baseClone(value, bitmask, customizer, key, object, stack) {
30408      var result,
30409          isDeep = bitmask & CLONE_DEEP_FLAG,
30410          isFlat = bitmask & CLONE_FLAT_FLAG,
30411          isFull = bitmask & CLONE_SYMBOLS_FLAG;
30412
30413      if (customizer) {
30414        result = object ? customizer(value, key, object, stack) : customizer(value);
30415      }
30416      if (result !== undefined) {
30417        return result;
30418      }
30419      if (!isObject(value)) {
30420        return value;
30421      }
30422      var isArr = isArray(value);
30423      if (isArr) {
30424        result = initCloneArray(value);
30425        if (!isDeep) {
30426          return copyArray(value, result);
30427        }
30428      } else {
30429        var tag = getTag(value),
30430            isFunc = tag == funcTag || tag == genTag;
30431
30432        if (isBuffer(value)) {
30433          return cloneBuffer(value, isDeep);
30434        }
30435        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
30436          result = (isFlat || isFunc) ? {} : initCloneObject(value);
30437          if (!isDeep) {
30438            return isFlat
30439              ? copySymbolsIn(value, baseAssignIn(result, value))
30440              : copySymbols(value, baseAssign(result, value));
30441          }
30442        } else {
30443          if (!cloneableTags[tag]) {
30444            return object ? value : {};
30445          }
30446          result = initCloneByTag(value, tag, isDeep);
30447        }
30448      }
30449      // Check for circular references and return its corresponding clone.
30450      stack || (stack = new Stack);
30451      var stacked = stack.get(value);
30452      if (stacked) {
30453        return stacked;
30454      }
30455      stack.set(value, result);
30456
30457      if (isSet(value)) {
30458        value.forEach(function(subValue) {
30459          result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
30460        });
30461      } else if (isMap(value)) {
30462        value.forEach(function(subValue, key) {
30463          result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
30464        });
30465      }
30466
30467      var keysFunc = isFull
30468        ? (isFlat ? getAllKeysIn : getAllKeys)
30469        : (isFlat ? keysIn : keys);
30470
30471      var props = isArr ? undefined : keysFunc(value);
30472      arrayEach(props || value, function(subValue, key) {
30473        if (props) {
30474          key = subValue;
30475          subValue = value[key];
30476        }
30477        // Recursively populate clone (susceptible to call stack limits).
30478        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
30479      });
30480      return result;
30481    }
30482
30483    /**
30484     * The base implementation of `_.conforms` which doesn't clone `source`.
30485     *
30486     * @private
30487     * @param {Object} source The object of property predicates to conform to.
30488     * @returns {Function} Returns the new spec function.
30489     */
30490    function baseConforms(source) {
30491      var props = keys(source);
30492      return function(object) {
30493        return baseConformsTo(object, source, props);
30494      };
30495    }
30496
30497    /**
30498     * The base implementation of `_.conformsTo` which accepts `props` to check.
30499     *
30500     * @private
30501     * @param {Object} object The object to inspect.
30502     * @param {Object} source The object of property predicates to conform to.
30503     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
30504     */
30505    function baseConformsTo(object, source, props) {
30506      var length = props.length;
30507      if (object == null) {
30508        return !length;
30509      }
30510      object = Object(object);
30511      while (length--) {
30512        var key = props[length],
30513            predicate = source[key],
30514            value = object[key];
30515
30516        if ((value === undefined && !(key in object)) || !predicate(value)) {
30517          return false;
30518        }
30519      }
30520      return true;
30521    }
30522
30523    /**
30524     * The base implementation of `_.delay` and `_.defer` which accepts `args`
30525     * to provide to `func`.
30526     *
30527     * @private
30528     * @param {Function} func The function to delay.
30529     * @param {number} wait The number of milliseconds to delay invocation.
30530     * @param {Array} args The arguments to provide to `func`.
30531     * @returns {number|Object} Returns the timer id or timeout object.
30532     */
30533    function baseDelay(func, wait, args) {
30534      if (typeof func != 'function') {
30535        throw new TypeError(FUNC_ERROR_TEXT);
30536      }
30537      return setTimeout(function() { func.apply(undefined, args); }, wait);
30538    }
30539
30540    /**
30541     * The base implementation of methods like `_.difference` without support
30542     * for excluding multiple arrays or iteratee shorthands.
30543     *
30544     * @private
30545     * @param {Array} array The array to inspect.
30546     * @param {Array} values The values to exclude.
30547     * @param {Function} [iteratee] The iteratee invoked per element.
30548     * @param {Function} [comparator] The comparator invoked per element.
30549     * @returns {Array} Returns the new array of filtered values.
30550     */
30551    function baseDifference(array, values, iteratee, comparator) {
30552      var index = -1,
30553          includes = arrayIncludes,
30554          isCommon = true,
30555          length = array.length,
30556          result = [],
30557          valuesLength = values.length;
30558
30559      if (!length) {
30560        return result;
30561      }
30562      if (iteratee) {
30563        values = arrayMap(values, baseUnary(iteratee));
30564      }
30565      if (comparator) {
30566        includes = arrayIncludesWith;
30567        isCommon = false;
30568      }
30569      else if (values.length >= LARGE_ARRAY_SIZE) {
30570        includes = cacheHas;
30571        isCommon = false;
30572        values = new SetCache(values);
30573      }
30574      outer:
30575      while (++index < length) {
30576        var value = array[index],
30577            computed = iteratee == null ? value : iteratee(value);
30578
30579        value = (comparator || value !== 0) ? value : 0;
30580        if (isCommon && computed === computed) {
30581          var valuesIndex = valuesLength;
30582          while (valuesIndex--) {
30583            if (values[valuesIndex] === computed) {
30584              continue outer;
30585            }
30586          }
30587          result.push(value);
30588        }
30589        else if (!includes(values, computed, comparator)) {
30590          result.push(value);
30591        }
30592      }
30593      return result;
30594    }
30595
30596    /**
30597     * The base implementation of `_.forEach` without support for iteratee shorthands.
30598     *
30599     * @private
30600     * @param {Array|Object} collection The collection to iterate over.
30601     * @param {Function} iteratee The function invoked per iteration.
30602     * @returns {Array|Object} Returns `collection`.
30603     */
30604    var baseEach = createBaseEach(baseForOwn);
30605
30606    /**
30607     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
30608     *
30609     * @private
30610     * @param {Array|Object} collection The collection to iterate over.
30611     * @param {Function} iteratee The function invoked per iteration.
30612     * @returns {Array|Object} Returns `collection`.
30613     */
30614    var baseEachRight = createBaseEach(baseForOwnRight, true);
30615
30616    /**
30617     * The base implementation of `_.every` without support for iteratee shorthands.
30618     *
30619     * @private
30620     * @param {Array|Object} collection The collection to iterate over.
30621     * @param {Function} predicate The function invoked per iteration.
30622     * @returns {boolean} Returns `true` if all elements pass the predicate check,
30623     *  else `false`
30624     */
30625    function baseEvery(collection, predicate) {
30626      var result = true;
30627      baseEach(collection, function(value, index, collection) {
30628        result = !!predicate(value, index, collection);
30629        return result;
30630      });
30631      return result;
30632    }
30633
30634    /**
30635     * The base implementation of methods like `_.max` and `_.min` which accepts a
30636     * `comparator` to determine the extremum value.
30637     *
30638     * @private
30639     * @param {Array} array The array to iterate over.
30640     * @param {Function} iteratee The iteratee invoked per iteration.
30641     * @param {Function} comparator The comparator used to compare values.
30642     * @returns {*} Returns the extremum value.
30643     */
30644    function baseExtremum(array, iteratee, comparator) {
30645      var index = -1,
30646          length = array.length;
30647
30648      while (++index < length) {
30649        var value = array[index],
30650            current = iteratee(value);
30651
30652        if (current != null && (computed === undefined
30653              ? (current === current && !isSymbol(current))
30654              : comparator(current, computed)
30655            )) {
30656          var computed = current,
30657              result = value;
30658        }
30659      }
30660      return result;
30661    }
30662
30663    /**
30664     * The base implementation of `_.fill` without an iteratee call guard.
30665     *
30666     * @private
30667     * @param {Array} array The array to fill.
30668     * @param {*} value The value to fill `array` with.
30669     * @param {number} [start=0] The start position.
30670     * @param {number} [end=array.length] The end position.
30671     * @returns {Array} Returns `array`.
30672     */
30673    function baseFill(array, value, start, end) {
30674      var length = array.length;
30675
30676      start = toInteger(start);
30677      if (start < 0) {
30678        start = -start > length ? 0 : (length + start);
30679      }
30680      end = (end === undefined || end > length) ? length : toInteger(end);
30681      if (end < 0) {
30682        end += length;
30683      }
30684      end = start > end ? 0 : toLength(end);
30685      while (start < end) {
30686        array[start++] = value;
30687      }
30688      return array;
30689    }
30690
30691    /**
30692     * The base implementation of `_.filter` without support for iteratee shorthands.
30693     *
30694     * @private
30695     * @param {Array|Object} collection The collection to iterate over.
30696     * @param {Function} predicate The function invoked per iteration.
30697     * @returns {Array} Returns the new filtered array.
30698     */
30699    function baseFilter(collection, predicate) {
30700      var result = [];
30701      baseEach(collection, function(value, index, collection) {
30702        if (predicate(value, index, collection)) {
30703          result.push(value);
30704        }
30705      });
30706      return result;
30707    }
30708
30709    /**
30710     * The base implementation of `_.flatten` with support for restricting flattening.
30711     *
30712     * @private
30713     * @param {Array} array The array to flatten.
30714     * @param {number} depth The maximum recursion depth.
30715     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
30716     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
30717     * @param {Array} [result=[]] The initial result value.
30718     * @returns {Array} Returns the new flattened array.
30719     */
30720    function baseFlatten(array, depth, predicate, isStrict, result) {
30721      var index = -1,
30722          length = array.length;
30723
30724      predicate || (predicate = isFlattenable);
30725      result || (result = []);
30726
30727      while (++index < length) {
30728        var value = array[index];
30729        if (depth > 0 && predicate(value)) {
30730          if (depth > 1) {
30731            // Recursively flatten arrays (susceptible to call stack limits).
30732            baseFlatten(value, depth - 1, predicate, isStrict, result);
30733          } else {
30734            arrayPush(result, value);
30735          }
30736        } else if (!isStrict) {
30737          result[result.length] = value;
30738        }
30739      }
30740      return result;
30741    }
30742
30743    /**
30744     * The base implementation of `baseForOwn` which iterates over `object`
30745     * properties returned by `keysFunc` and invokes `iteratee` for each property.
30746     * Iteratee functions may exit iteration early by explicitly returning `false`.
30747     *
30748     * @private
30749     * @param {Object} object The object to iterate over.
30750     * @param {Function} iteratee The function invoked per iteration.
30751     * @param {Function} keysFunc The function to get the keys of `object`.
30752     * @returns {Object} Returns `object`.
30753     */
30754    var baseFor = createBaseFor();
30755
30756    /**
30757     * This function is like `baseFor` except that it iterates over properties
30758     * in the opposite order.
30759     *
30760     * @private
30761     * @param {Object} object The object to iterate over.
30762     * @param {Function} iteratee The function invoked per iteration.
30763     * @param {Function} keysFunc The function to get the keys of `object`.
30764     * @returns {Object} Returns `object`.
30765     */
30766    var baseForRight = createBaseFor(true);
30767
30768    /**
30769     * The base implementation of `_.forOwn` without support for iteratee shorthands.
30770     *
30771     * @private
30772     * @param {Object} object The object to iterate over.
30773     * @param {Function} iteratee The function invoked per iteration.
30774     * @returns {Object} Returns `object`.
30775     */
30776    function baseForOwn(object, iteratee) {
30777      return object && baseFor(object, iteratee, keys);
30778    }
30779
30780    /**
30781     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
30782     *
30783     * @private
30784     * @param {Object} object The object to iterate over.
30785     * @param {Function} iteratee The function invoked per iteration.
30786     * @returns {Object} Returns `object`.
30787     */
30788    function baseForOwnRight(object, iteratee) {
30789      return object && baseForRight(object, iteratee, keys);
30790    }
30791
30792    /**
30793     * The base implementation of `_.functions` which creates an array of
30794     * `object` function property names filtered from `props`.
30795     *
30796     * @private
30797     * @param {Object} object The object to inspect.
30798     * @param {Array} props The property names to filter.
30799     * @returns {Array} Returns the function names.
30800     */
30801    function baseFunctions(object, props) {
30802      return arrayFilter(props, function(key) {
30803        return isFunction(object[key]);
30804      });
30805    }
30806
30807    /**
30808     * The base implementation of `_.get` without support for default values.
30809     *
30810     * @private
30811     * @param {Object} object The object to query.
30812     * @param {Array|string} path The path of the property to get.
30813     * @returns {*} Returns the resolved value.
30814     */
30815    function baseGet(object, path) {
30816      path = castPath(path, object);
30817
30818      var index = 0,
30819          length = path.length;
30820
30821      while (object != null && index < length) {
30822        object = object[toKey(path[index++])];
30823      }
30824      return (index && index == length) ? object : undefined;
30825    }
30826
30827    /**
30828     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
30829     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
30830     * symbols of `object`.
30831     *
30832     * @private
30833     * @param {Object} object The object to query.
30834     * @param {Function} keysFunc The function to get the keys of `object`.
30835     * @param {Function} symbolsFunc The function to get the symbols of `object`.
30836     * @returns {Array} Returns the array of property names and symbols.
30837     */
30838    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
30839      var result = keysFunc(object);
30840      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
30841    }
30842
30843    /**
30844     * The base implementation of `getTag` without fallbacks for buggy environments.
30845     *
30846     * @private
30847     * @param {*} value The value to query.
30848     * @returns {string} Returns the `toStringTag`.
30849     */
30850    function baseGetTag(value) {
30851      if (value == null) {
30852        return value === undefined ? undefinedTag : nullTag;
30853      }
30854      return (symToStringTag && symToStringTag in Object(value))
30855        ? getRawTag(value)
30856        : objectToString(value);
30857    }
30858
30859    /**
30860     * The base implementation of `_.gt` which doesn't coerce arguments.
30861     *
30862     * @private
30863     * @param {*} value The value to compare.
30864     * @param {*} other The other value to compare.
30865     * @returns {boolean} Returns `true` if `value` is greater than `other`,
30866     *  else `false`.
30867     */
30868    function baseGt(value, other) {
30869      return value > other;
30870    }
30871
30872    /**
30873     * The base implementation of `_.has` without support for deep paths.
30874     *
30875     * @private
30876     * @param {Object} [object] The object to query.
30877     * @param {Array|string} key The key to check.
30878     * @returns {boolean} Returns `true` if `key` exists, else `false`.
30879     */
30880    function baseHas(object, key) {
30881      return object != null && hasOwnProperty.call(object, key);
30882    }
30883
30884    /**
30885     * The base implementation of `_.hasIn` without support for deep paths.
30886     *
30887     * @private
30888     * @param {Object} [object] The object to query.
30889     * @param {Array|string} key The key to check.
30890     * @returns {boolean} Returns `true` if `key` exists, else `false`.
30891     */
30892    function baseHasIn(object, key) {
30893      return object != null && key in Object(object);
30894    }
30895
30896    /**
30897     * The base implementation of `_.inRange` which doesn't coerce arguments.
30898     *
30899     * @private
30900     * @param {number} number The number to check.
30901     * @param {number} start The start of the range.
30902     * @param {number} end The end of the range.
30903     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
30904     */
30905    function baseInRange(number, start, end) {
30906      return number >= nativeMin(start, end) && number < nativeMax(start, end);
30907    }
30908
30909    /**
30910     * The base implementation of methods like `_.intersection`, without support
30911     * for iteratee shorthands, that accepts an array of arrays to inspect.
30912     *
30913     * @private
30914     * @param {Array} arrays The arrays to inspect.
30915     * @param {Function} [iteratee] The iteratee invoked per element.
30916     * @param {Function} [comparator] The comparator invoked per element.
30917     * @returns {Array} Returns the new array of shared values.
30918     */
30919    function baseIntersection(arrays, iteratee, comparator) {
30920      var includes = comparator ? arrayIncludesWith : arrayIncludes,
30921          length = arrays[0].length,
30922          othLength = arrays.length,
30923          othIndex = othLength,
30924          caches = Array(othLength),
30925          maxLength = Infinity,
30926          result = [];
30927
30928      while (othIndex--) {
30929        var array = arrays[othIndex];
30930        if (othIndex && iteratee) {
30931          array = arrayMap(array, baseUnary(iteratee));
30932        }
30933        maxLength = nativeMin(array.length, maxLength);
30934        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
30935          ? new SetCache(othIndex && array)
30936          : undefined;
30937      }
30938      array = arrays[0];
30939
30940      var index = -1,
30941          seen = caches[0];
30942
30943      outer:
30944      while (++index < length && result.length < maxLength) {
30945        var value = array[index],
30946            computed = iteratee ? iteratee(value) : value;
30947
30948        value = (comparator || value !== 0) ? value : 0;
30949        if (!(seen
30950              ? cacheHas(seen, computed)
30951              : includes(result, computed, comparator)
30952            )) {
30953          othIndex = othLength;
30954          while (--othIndex) {
30955            var cache = caches[othIndex];
30956            if (!(cache
30957                  ? cacheHas(cache, computed)
30958                  : includes(arrays[othIndex], computed, comparator))
30959                ) {
30960              continue outer;
30961            }
30962          }
30963          if (seen) {
30964            seen.push(computed);
30965          }
30966          result.push(value);
30967        }
30968      }
30969      return result;
30970    }
30971
30972    /**
30973     * The base implementation of `_.invert` and `_.invertBy` which inverts
30974     * `object` with values transformed by `iteratee` and set by `setter`.
30975     *
30976     * @private
30977     * @param {Object} object The object to iterate over.
30978     * @param {Function} setter The function to set `accumulator` values.
30979     * @param {Function} iteratee The iteratee to transform values.
30980     * @param {Object} accumulator The initial inverted object.
30981     * @returns {Function} Returns `accumulator`.
30982     */
30983    function baseInverter(object, setter, iteratee, accumulator) {
30984      baseForOwn(object, function(value, key, object) {
30985        setter(accumulator, iteratee(value), key, object);
30986      });
30987      return accumulator;
30988    }
30989
30990    /**
30991     * The base implementation of `_.invoke` without support for individual
30992     * method arguments.
30993     *
30994     * @private
30995     * @param {Object} object The object to query.
30996     * @param {Array|string} path The path of the method to invoke.
30997     * @param {Array} args The arguments to invoke the method with.
30998     * @returns {*} Returns the result of the invoked method.
30999     */
31000    function baseInvoke(object, path, args) {
31001      path = castPath(path, object);
31002      object = parent(object, path);
31003      var func = object == null ? object : object[toKey(last(path))];
31004      return func == null ? undefined : apply(func, object, args);
31005    }
31006
31007    /**
31008     * The base implementation of `_.isArguments`.
31009     *
31010     * @private
31011     * @param {*} value The value to check.
31012     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
31013     */
31014    function baseIsArguments(value) {
31015      return isObjectLike(value) && baseGetTag(value) == argsTag;
31016    }
31017
31018    /**
31019     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
31020     *
31021     * @private
31022     * @param {*} value The value to check.
31023     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
31024     */
31025    function baseIsArrayBuffer(value) {
31026      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
31027    }
31028
31029    /**
31030     * The base implementation of `_.isDate` without Node.js optimizations.
31031     *
31032     * @private
31033     * @param {*} value The value to check.
31034     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
31035     */
31036    function baseIsDate(value) {
31037      return isObjectLike(value) && baseGetTag(value) == dateTag;
31038    }
31039
31040    /**
31041     * The base implementation of `_.isEqual` which supports partial comparisons
31042     * and tracks traversed objects.
31043     *
31044     * @private
31045     * @param {*} value The value to compare.
31046     * @param {*} other The other value to compare.
31047     * @param {boolean} bitmask The bitmask flags.
31048     *  1 - Unordered comparison
31049     *  2 - Partial comparison
31050     * @param {Function} [customizer] The function to customize comparisons.
31051     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
31052     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
31053     */
31054    function baseIsEqual(value, other, bitmask, customizer, stack) {
31055      if (value === other) {
31056        return true;
31057      }
31058      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
31059        return value !== value && other !== other;
31060      }
31061      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
31062    }
31063
31064    /**
31065     * A specialized version of `baseIsEqual` for arrays and objects which performs
31066     * deep comparisons and tracks traversed objects enabling objects with circular
31067     * references to be compared.
31068     *
31069     * @private
31070     * @param {Object} object The object to compare.
31071     * @param {Object} other The other object to compare.
31072     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
31073     * @param {Function} customizer The function to customize comparisons.
31074     * @param {Function} equalFunc The function to determine equivalents of values.
31075     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
31076     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
31077     */
31078    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
31079      var objIsArr = isArray(object),
31080          othIsArr = isArray(other),
31081          objTag = objIsArr ? arrayTag : getTag(object),
31082          othTag = othIsArr ? arrayTag : getTag(other);
31083
31084      objTag = objTag == argsTag ? objectTag : objTag;
31085      othTag = othTag == argsTag ? objectTag : othTag;
31086
31087      var objIsObj = objTag == objectTag,
31088          othIsObj = othTag == objectTag,
31089          isSameTag = objTag == othTag;
31090
31091      if (isSameTag && isBuffer(object)) {
31092        if (!isBuffer(other)) {
31093          return false;
31094        }
31095        objIsArr = true;
31096        objIsObj = false;
31097      }
31098      if (isSameTag && !objIsObj) {
31099        stack || (stack = new Stack);
31100        return (objIsArr || isTypedArray(object))
31101          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
31102          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
31103      }
31104      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
31105        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
31106            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
31107
31108        if (objIsWrapped || othIsWrapped) {
31109          var objUnwrapped = objIsWrapped ? object.value() : object,
31110              othUnwrapped = othIsWrapped ? other.value() : other;
31111
31112          stack || (stack = new Stack);
31113          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
31114        }
31115      }
31116      if (!isSameTag) {
31117        return false;
31118      }
31119      stack || (stack = new Stack);
31120      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
31121    }
31122
31123    /**
31124     * The base implementation of `_.isMap` without Node.js optimizations.
31125     *
31126     * @private
31127     * @param {*} value The value to check.
31128     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
31129     */
31130    function baseIsMap(value) {
31131      return isObjectLike(value) && getTag(value) == mapTag;
31132    }
31133
31134    /**
31135     * The base implementation of `_.isMatch` without support for iteratee shorthands.
31136     *
31137     * @private
31138     * @param {Object} object The object to inspect.
31139     * @param {Object} source The object of property values to match.
31140     * @param {Array} matchData The property names, values, and compare flags to match.
31141     * @param {Function} [customizer] The function to customize comparisons.
31142     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
31143     */
31144    function baseIsMatch(object, source, matchData, customizer) {
31145      var index = matchData.length,
31146          length = index,
31147          noCustomizer = !customizer;
31148
31149      if (object == null) {
31150        return !length;
31151      }
31152      object = Object(object);
31153      while (index--) {
31154        var data = matchData[index];
31155        if ((noCustomizer && data[2])
31156              ? data[1] !== object[data[0]]
31157              : !(data[0] in object)
31158            ) {
31159          return false;
31160        }
31161      }
31162      while (++index < length) {
31163        data = matchData[index];
31164        var key = data[0],
31165            objValue = object[key],
31166            srcValue = data[1];
31167
31168        if (noCustomizer && data[2]) {
31169          if (objValue === undefined && !(key in object)) {
31170            return false;
31171          }
31172        } else {
31173          var stack = new Stack;
31174          if (customizer) {
31175            var result = customizer(objValue, srcValue, key, object, source, stack);
31176          }
31177          if (!(result === undefined
31178                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
31179                : result
31180              )) {
31181            return false;
31182          }
31183        }
31184      }
31185      return true;
31186    }
31187
31188    /**
31189     * The base implementation of `_.isNative` without bad shim checks.
31190     *
31191     * @private
31192     * @param {*} value The value to check.
31193     * @returns {boolean} Returns `true` if `value` is a native function,
31194     *  else `false`.
31195     */
31196    function baseIsNative(value) {
31197      if (!isObject(value) || isMasked(value)) {
31198        return false;
31199      }
31200      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
31201      return pattern.test(toSource(value));
31202    }
31203
31204    /**
31205     * The base implementation of `_.isRegExp` without Node.js optimizations.
31206     *
31207     * @private
31208     * @param {*} value The value to check.
31209     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
31210     */
31211    function baseIsRegExp(value) {
31212      return isObjectLike(value) && baseGetTag(value) == regexpTag;
31213    }
31214
31215    /**
31216     * The base implementation of `_.isSet` without Node.js optimizations.
31217     *
31218     * @private
31219     * @param {*} value The value to check.
31220     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
31221     */
31222    function baseIsSet(value) {
31223      return isObjectLike(value) && getTag(value) == setTag;
31224    }
31225
31226    /**
31227     * The base implementation of `_.isTypedArray` without Node.js optimizations.
31228     *
31229     * @private
31230     * @param {*} value The value to check.
31231     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
31232     */
31233    function baseIsTypedArray(value) {
31234      return isObjectLike(value) &&
31235        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
31236    }
31237
31238    /**
31239     * The base implementation of `_.iteratee`.
31240     *
31241     * @private
31242     * @param {*} [value=_.identity] The value to convert to an iteratee.
31243     * @returns {Function} Returns the iteratee.
31244     */
31245    function baseIteratee(value) {
31246      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
31247      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
31248      if (typeof value == 'function') {
31249        return value;
31250      }
31251      if (value == null) {
31252        return identity;
31253      }
31254      if (typeof value == 'object') {
31255        return isArray(value)
31256          ? baseMatchesProperty(value[0], value[1])
31257          : baseMatches(value);
31258      }
31259      return property(value);
31260    }
31261
31262    /**
31263     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
31264     *
31265     * @private
31266     * @param {Object} object The object to query.
31267     * @returns {Array} Returns the array of property names.
31268     */
31269    function baseKeys(object) {
31270      if (!isPrototype(object)) {
31271        return nativeKeys(object);
31272      }
31273      var result = [];
31274      for (var key in Object(object)) {
31275        if (hasOwnProperty.call(object, key) && key != 'constructor') {
31276          result.push(key);
31277        }
31278      }
31279      return result;
31280    }
31281
31282    /**
31283     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
31284     *
31285     * @private
31286     * @param {Object} object The object to query.
31287     * @returns {Array} Returns the array of property names.
31288     */
31289    function baseKeysIn(object) {
31290      if (!isObject(object)) {
31291        return nativeKeysIn(object);
31292      }
31293      var isProto = isPrototype(object),
31294          result = [];
31295
31296      for (var key in object) {
31297        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
31298          result.push(key);
31299        }
31300      }
31301      return result;
31302    }
31303
31304    /**
31305     * The base implementation of `_.lt` which doesn't coerce arguments.
31306     *
31307     * @private
31308     * @param {*} value The value to compare.
31309     * @param {*} other The other value to compare.
31310     * @returns {boolean} Returns `true` if `value` is less than `other`,
31311     *  else `false`.
31312     */
31313    function baseLt(value, other) {
31314      return value < other;
31315    }
31316
31317    /**
31318     * The base implementation of `_.map` without support for iteratee shorthands.
31319     *
31320     * @private
31321     * @param {Array|Object} collection The collection to iterate over.
31322     * @param {Function} iteratee The function invoked per iteration.
31323     * @returns {Array} Returns the new mapped array.
31324     */
31325    function baseMap(collection, iteratee) {
31326      var index = -1,
31327          result = isArrayLike(collection) ? Array(collection.length) : [];
31328
31329      baseEach(collection, function(value, key, collection) {
31330        result[++index] = iteratee(value, key, collection);
31331      });
31332      return result;
31333    }
31334
31335    /**
31336     * The base implementation of `_.matches` which doesn't clone `source`.
31337     *
31338     * @private
31339     * @param {Object} source The object of property values to match.
31340     * @returns {Function} Returns the new spec function.
31341     */
31342    function baseMatches(source) {
31343      var matchData = getMatchData(source);
31344      if (matchData.length == 1 && matchData[0][2]) {
31345        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
31346      }
31347      return function(object) {
31348        return object === source || baseIsMatch(object, source, matchData);
31349      };
31350    }
31351
31352    /**
31353     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
31354     *
31355     * @private
31356     * @param {string} path The path of the property to get.
31357     * @param {*} srcValue The value to match.
31358     * @returns {Function} Returns the new spec function.
31359     */
31360    function baseMatchesProperty(path, srcValue) {
31361      if (isKey(path) && isStrictComparable(srcValue)) {
31362        return matchesStrictComparable(toKey(path), srcValue);
31363      }
31364      return function(object) {
31365        var objValue = get(object, path);
31366        return (objValue === undefined && objValue === srcValue)
31367          ? hasIn(object, path)
31368          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
31369      };
31370    }
31371
31372    /**
31373     * The base implementation of `_.merge` without support for multiple sources.
31374     *
31375     * @private
31376     * @param {Object} object The destination object.
31377     * @param {Object} source The source object.
31378     * @param {number} srcIndex The index of `source`.
31379     * @param {Function} [customizer] The function to customize merged values.
31380     * @param {Object} [stack] Tracks traversed source values and their merged
31381     *  counterparts.
31382     */
31383    function baseMerge(object, source, srcIndex, customizer, stack) {
31384      if (object === source) {
31385        return;
31386      }
31387      baseFor(source, function(srcValue, key) {
31388        stack || (stack = new Stack);
31389        if (isObject(srcValue)) {
31390          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
31391        }
31392        else {
31393          var newValue = customizer
31394            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
31395            : undefined;
31396
31397          if (newValue === undefined) {
31398            newValue = srcValue;
31399          }
31400          assignMergeValue(object, key, newValue);
31401        }
31402      }, keysIn);
31403    }
31404
31405    /**
31406     * A specialized version of `baseMerge` for arrays and objects which performs
31407     * deep merges and tracks traversed objects enabling objects with circular
31408     * references to be merged.
31409     *
31410     * @private
31411     * @param {Object} object The destination object.
31412     * @param {Object} source The source object.
31413     * @param {string} key The key of the value to merge.
31414     * @param {number} srcIndex The index of `source`.
31415     * @param {Function} mergeFunc The function to merge values.
31416     * @param {Function} [customizer] The function to customize assigned values.
31417     * @param {Object} [stack] Tracks traversed source values and their merged
31418     *  counterparts.
31419     */
31420    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
31421      var objValue = safeGet(object, key),
31422          srcValue = safeGet(source, key),
31423          stacked = stack.get(srcValue);
31424
31425      if (stacked) {
31426        assignMergeValue(object, key, stacked);
31427        return;
31428      }
31429      var newValue = customizer
31430        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
31431        : undefined;
31432
31433      var isCommon = newValue === undefined;
31434
31435      if (isCommon) {
31436        var isArr = isArray(srcValue),
31437            isBuff = !isArr && isBuffer(srcValue),
31438            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
31439
31440        newValue = srcValue;
31441        if (isArr || isBuff || isTyped) {
31442          if (isArray(objValue)) {
31443            newValue = objValue;
31444          }
31445          else if (isArrayLikeObject(objValue)) {
31446            newValue = copyArray(objValue);
31447          }
31448          else if (isBuff) {
31449            isCommon = false;
31450            newValue = cloneBuffer(srcValue, true);
31451          }
31452          else if (isTyped) {
31453            isCommon = false;
31454            newValue = cloneTypedArray(srcValue, true);
31455          }
31456          else {
31457            newValue = [];
31458          }
31459        }
31460        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
31461          newValue = objValue;
31462          if (isArguments(objValue)) {
31463            newValue = toPlainObject(objValue);
31464          }
31465          else if (!isObject(objValue) || isFunction(objValue)) {
31466            newValue = initCloneObject(srcValue);
31467          }
31468        }
31469        else {
31470          isCommon = false;
31471        }
31472      }
31473      if (isCommon) {
31474        // Recursively merge objects and arrays (susceptible to call stack limits).
31475        stack.set(srcValue, newValue);
31476        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
31477        stack['delete'](srcValue);
31478      }
31479      assignMergeValue(object, key, newValue);
31480    }
31481
31482    /**
31483     * The base implementation of `_.nth` which doesn't coerce arguments.
31484     *
31485     * @private
31486     * @param {Array} array The array to query.
31487     * @param {number} n The index of the element to return.
31488     * @returns {*} Returns the nth element of `array`.
31489     */
31490    function baseNth(array, n) {
31491      var length = array.length;
31492      if (!length) {
31493        return;
31494      }
31495      n += n < 0 ? length : 0;
31496      return isIndex(n, length) ? array[n] : undefined;
31497    }
31498
31499    /**
31500     * The base implementation of `_.orderBy` without param guards.
31501     *
31502     * @private
31503     * @param {Array|Object} collection The collection to iterate over.
31504     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
31505     * @param {string[]} orders The sort orders of `iteratees`.
31506     * @returns {Array} Returns the new sorted array.
31507     */
31508    function baseOrderBy(collection, iteratees, orders) {
31509      if (iteratees.length) {
31510        iteratees = arrayMap(iteratees, function(iteratee) {
31511          if (isArray(iteratee)) {
31512            return function(value) {
31513              return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
31514            }
31515          }
31516          return iteratee;
31517        });
31518      } else {
31519        iteratees = [identity];
31520      }
31521
31522      var index = -1;
31523      iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
31524
31525      var result = baseMap(collection, function(value, key, collection) {
31526        var criteria = arrayMap(iteratees, function(iteratee) {
31527          return iteratee(value);
31528        });
31529        return { 'criteria': criteria, 'index': ++index, 'value': value };
31530      });
31531
31532      return baseSortBy(result, function(object, other) {
31533        return compareMultiple(object, other, orders);
31534      });
31535    }
31536
31537    /**
31538     * The base implementation of `_.pick` without support for individual
31539     * property identifiers.
31540     *
31541     * @private
31542     * @param {Object} object The source object.
31543     * @param {string[]} paths The property paths to pick.
31544     * @returns {Object} Returns the new object.
31545     */
31546    function basePick(object, paths) {
31547      return basePickBy(object, paths, function(value, path) {
31548        return hasIn(object, path);
31549      });
31550    }
31551
31552    /**
31553     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
31554     *
31555     * @private
31556     * @param {Object} object The source object.
31557     * @param {string[]} paths The property paths to pick.
31558     * @param {Function} predicate The function invoked per property.
31559     * @returns {Object} Returns the new object.
31560     */
31561    function basePickBy(object, paths, predicate) {
31562      var index = -1,
31563          length = paths.length,
31564          result = {};
31565
31566      while (++index < length) {
31567        var path = paths[index],
31568            value = baseGet(object, path);
31569
31570        if (predicate(value, path)) {
31571          baseSet(result, castPath(path, object), value);
31572        }
31573      }
31574      return result;
31575    }
31576
31577    /**
31578     * A specialized version of `baseProperty` which supports deep paths.
31579     *
31580     * @private
31581     * @param {Array|string} path The path of the property to get.
31582     * @returns {Function} Returns the new accessor function.
31583     */
31584    function basePropertyDeep(path) {
31585      return function(object) {
31586        return baseGet(object, path);
31587      };
31588    }
31589
31590    /**
31591     * The base implementation of `_.pullAllBy` without support for iteratee
31592     * shorthands.
31593     *
31594     * @private
31595     * @param {Array} array The array to modify.
31596     * @param {Array} values The values to remove.
31597     * @param {Function} [iteratee] The iteratee invoked per element.
31598     * @param {Function} [comparator] The comparator invoked per element.
31599     * @returns {Array} Returns `array`.
31600     */
31601    function basePullAll(array, values, iteratee, comparator) {
31602      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
31603          index = -1,
31604          length = values.length,
31605          seen = array;
31606
31607      if (array === values) {
31608        values = copyArray(values);
31609      }
31610      if (iteratee) {
31611        seen = arrayMap(array, baseUnary(iteratee));
31612      }
31613      while (++index < length) {
31614        var fromIndex = 0,
31615            value = values[index],
31616            computed = iteratee ? iteratee(value) : value;
31617
31618        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
31619          if (seen !== array) {
31620            splice.call(seen, fromIndex, 1);
31621          }
31622          splice.call(array, fromIndex, 1);
31623        }
31624      }
31625      return array;
31626    }
31627
31628    /**
31629     * The base implementation of `_.pullAt` without support for individual
31630     * indexes or capturing the removed elements.
31631     *
31632     * @private
31633     * @param {Array} array The array to modify.
31634     * @param {number[]} indexes The indexes of elements to remove.
31635     * @returns {Array} Returns `array`.
31636     */
31637    function basePullAt(array, indexes) {
31638      var length = array ? indexes.length : 0,
31639          lastIndex = length - 1;
31640
31641      while (length--) {
31642        var index = indexes[length];
31643        if (length == lastIndex || index !== previous) {
31644          var previous = index;
31645          if (isIndex(index)) {
31646            splice.call(array, index, 1);
31647          } else {
31648            baseUnset(array, index);
31649          }
31650        }
31651      }
31652      return array;
31653    }
31654
31655    /**
31656     * The base implementation of `_.random` without support for returning
31657     * floating-point numbers.
31658     *
31659     * @private
31660     * @param {number} lower The lower bound.
31661     * @param {number} upper The upper bound.
31662     * @returns {number} Returns the random number.
31663     */
31664    function baseRandom(lower, upper) {
31665      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
31666    }
31667
31668    /**
31669     * The base implementation of `_.range` and `_.rangeRight` which doesn't
31670     * coerce arguments.
31671     *
31672     * @private
31673     * @param {number} start The start of the range.
31674     * @param {number} end The end of the range.
31675     * @param {number} step The value to increment or decrement by.
31676     * @param {boolean} [fromRight] Specify iterating from right to left.
31677     * @returns {Array} Returns the range of numbers.
31678     */
31679    function baseRange(start, end, step, fromRight) {
31680      var index = -1,
31681          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
31682          result = Array(length);
31683
31684      while (length--) {
31685        result[fromRight ? length : ++index] = start;
31686        start += step;
31687      }
31688      return result;
31689    }
31690
31691    /**
31692     * The base implementation of `_.repeat` which doesn't coerce arguments.
31693     *
31694     * @private
31695     * @param {string} string The string to repeat.
31696     * @param {number} n The number of times to repeat the string.
31697     * @returns {string} Returns the repeated string.
31698     */
31699    function baseRepeat(string, n) {
31700      var result = '';
31701      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
31702        return result;
31703      }
31704      // Leverage the exponentiation by squaring algorithm for a faster repeat.
31705      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
31706      do {
31707        if (n % 2) {
31708          result += string;
31709        }
31710        n = nativeFloor(n / 2);
31711        if (n) {
31712          string += string;
31713        }
31714      } while (n);
31715
31716      return result;
31717    }
31718
31719    /**
31720     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
31721     *
31722     * @private
31723     * @param {Function} func The function to apply a rest parameter to.
31724     * @param {number} [start=func.length-1] The start position of the rest parameter.
31725     * @returns {Function} Returns the new function.
31726     */
31727    function baseRest(func, start) {
31728      return setToString(overRest(func, start, identity), func + '');
31729    }
31730
31731    /**
31732     * The base implementation of `_.sample`.
31733     *
31734     * @private
31735     * @param {Array|Object} collection The collection to sample.
31736     * @returns {*} Returns the random element.
31737     */
31738    function baseSample(collection) {
31739      return arraySample(values(collection));
31740    }
31741
31742    /**
31743     * The base implementation of `_.sampleSize` without param guards.
31744     *
31745     * @private
31746     * @param {Array|Object} collection The collection to sample.
31747     * @param {number} n The number of elements to sample.
31748     * @returns {Array} Returns the random elements.
31749     */
31750    function baseSampleSize(collection, n) {
31751      var array = values(collection);
31752      return shuffleSelf(array, baseClamp(n, 0, array.length));
31753    }
31754
31755    /**
31756     * The base implementation of `_.set`.
31757     *
31758     * @private
31759     * @param {Object} object The object to modify.
31760     * @param {Array|string} path The path of the property to set.
31761     * @param {*} value The value to set.
31762     * @param {Function} [customizer] The function to customize path creation.
31763     * @returns {Object} Returns `object`.
31764     */
31765    function baseSet(object, path, value, customizer) {
31766      if (!isObject(object)) {
31767        return object;
31768      }
31769      path = castPath(path, object);
31770
31771      var index = -1,
31772          length = path.length,
31773          lastIndex = length - 1,
31774          nested = object;
31775
31776      while (nested != null && ++index < length) {
31777        var key = toKey(path[index]),
31778            newValue = value;
31779
31780        if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
31781          return object;
31782        }
31783
31784        if (index != lastIndex) {
31785          var objValue = nested[key];
31786          newValue = customizer ? customizer(objValue, key, nested) : undefined;
31787          if (newValue === undefined) {
31788            newValue = isObject(objValue)
31789              ? objValue
31790              : (isIndex(path[index + 1]) ? [] : {});
31791          }
31792        }
31793        assignValue(nested, key, newValue);
31794        nested = nested[key];
31795      }
31796      return object;
31797    }
31798
31799    /**
31800     * The base implementation of `setData` without support for hot loop shorting.
31801     *
31802     * @private
31803     * @param {Function} func The function to associate metadata with.
31804     * @param {*} data The metadata.
31805     * @returns {Function} Returns `func`.
31806     */
31807    var baseSetData = !metaMap ? identity : function(func, data) {
31808      metaMap.set(func, data);
31809      return func;
31810    };
31811
31812    /**
31813     * The base implementation of `setToString` without support for hot loop shorting.
31814     *
31815     * @private
31816     * @param {Function} func The function to modify.
31817     * @param {Function} string The `toString` result.
31818     * @returns {Function} Returns `func`.
31819     */
31820    var baseSetToString = !defineProperty ? identity : function(func, string) {
31821      return defineProperty(func, 'toString', {
31822        'configurable': true,
31823        'enumerable': false,
31824        'value': constant(string),
31825        'writable': true
31826      });
31827    };
31828
31829    /**
31830     * The base implementation of `_.shuffle`.
31831     *
31832     * @private
31833     * @param {Array|Object} collection The collection to shuffle.
31834     * @returns {Array} Returns the new shuffled array.
31835     */
31836    function baseShuffle(collection) {
31837      return shuffleSelf(values(collection));
31838    }
31839
31840    /**
31841     * The base implementation of `_.slice` without an iteratee call guard.
31842     *
31843     * @private
31844     * @param {Array} array The array to slice.
31845     * @param {number} [start=0] The start position.
31846     * @param {number} [end=array.length] The end position.
31847     * @returns {Array} Returns the slice of `array`.
31848     */
31849    function baseSlice(array, start, end) {
31850      var index = -1,
31851          length = array.length;
31852
31853      if (start < 0) {
31854        start = -start > length ? 0 : (length + start);
31855      }
31856      end = end > length ? length : end;
31857      if (end < 0) {
31858        end += length;
31859      }
31860      length = start > end ? 0 : ((end - start) >>> 0);
31861      start >>>= 0;
31862
31863      var result = Array(length);
31864      while (++index < length) {
31865        result[index] = array[index + start];
31866      }
31867      return result;
31868    }
31869
31870    /**
31871     * The base implementation of `_.some` without support for iteratee shorthands.
31872     *
31873     * @private
31874     * @param {Array|Object} collection The collection to iterate over.
31875     * @param {Function} predicate The function invoked per iteration.
31876     * @returns {boolean} Returns `true` if any element passes the predicate check,
31877     *  else `false`.
31878     */
31879    function baseSome(collection, predicate) {
31880      var result;
31881
31882      baseEach(collection, function(value, index, collection) {
31883        result = predicate(value, index, collection);
31884        return !result;
31885      });
31886      return !!result;
31887    }
31888
31889    /**
31890     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
31891     * performs a binary search of `array` to determine the index at which `value`
31892     * should be inserted into `array` in order to maintain its sort order.
31893     *
31894     * @private
31895     * @param {Array} array The sorted array to inspect.
31896     * @param {*} value The value to evaluate.
31897     * @param {boolean} [retHighest] Specify returning the highest qualified index.
31898     * @returns {number} Returns the index at which `value` should be inserted
31899     *  into `array`.
31900     */
31901    function baseSortedIndex(array, value, retHighest) {
31902      var low = 0,
31903          high = array == null ? low : array.length;
31904
31905      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
31906        while (low < high) {
31907          var mid = (low + high) >>> 1,
31908              computed = array[mid];
31909
31910          if (computed !== null && !isSymbol(computed) &&
31911              (retHighest ? (computed <= value) : (computed < value))) {
31912            low = mid + 1;
31913          } else {
31914            high = mid;
31915          }
31916        }
31917        return high;
31918      }
31919      return baseSortedIndexBy(array, value, identity, retHighest);
31920    }
31921
31922    /**
31923     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
31924     * which invokes `iteratee` for `value` and each element of `array` to compute
31925     * their sort ranking. The iteratee is invoked with one argument; (value).
31926     *
31927     * @private
31928     * @param {Array} array The sorted array to inspect.
31929     * @param {*} value The value to evaluate.
31930     * @param {Function} iteratee The iteratee invoked per element.
31931     * @param {boolean} [retHighest] Specify returning the highest qualified index.
31932     * @returns {number} Returns the index at which `value` should be inserted
31933     *  into `array`.
31934     */
31935    function baseSortedIndexBy(array, value, iteratee, retHighest) {
31936      var low = 0,
31937          high = array == null ? 0 : array.length;
31938      if (high === 0) {
31939        return 0;
31940      }
31941
31942      value = iteratee(value);
31943      var valIsNaN = value !== value,
31944          valIsNull = value === null,
31945          valIsSymbol = isSymbol(value),
31946          valIsUndefined = value === undefined;
31947
31948      while (low < high) {
31949        var mid = nativeFloor((low + high) / 2),
31950            computed = iteratee(array[mid]),
31951            othIsDefined = computed !== undefined,
31952            othIsNull = computed === null,
31953            othIsReflexive = computed === computed,
31954            othIsSymbol = isSymbol(computed);
31955
31956        if (valIsNaN) {
31957          var setLow = retHighest || othIsReflexive;
31958        } else if (valIsUndefined) {
31959          setLow = othIsReflexive && (retHighest || othIsDefined);
31960        } else if (valIsNull) {
31961          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
31962        } else if (valIsSymbol) {
31963          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
31964        } else if (othIsNull || othIsSymbol) {
31965          setLow = false;
31966        } else {
31967          setLow = retHighest ? (computed <= value) : (computed < value);
31968        }
31969        if (setLow) {
31970          low = mid + 1;
31971        } else {
31972          high = mid;
31973        }
31974      }
31975      return nativeMin(high, MAX_ARRAY_INDEX);
31976    }
31977
31978    /**
31979     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
31980     * support for iteratee shorthands.
31981     *
31982     * @private
31983     * @param {Array} array The array to inspect.
31984     * @param {Function} [iteratee] The iteratee invoked per element.
31985     * @returns {Array} Returns the new duplicate free array.
31986     */
31987    function baseSortedUniq(array, iteratee) {
31988      var index = -1,
31989          length = array.length,
31990          resIndex = 0,
31991          result = [];
31992
31993      while (++index < length) {
31994        var value = array[index],
31995            computed = iteratee ? iteratee(value) : value;
31996
31997        if (!index || !eq(computed, seen)) {
31998          var seen = computed;
31999          result[resIndex++] = value === 0 ? 0 : value;
32000        }
32001      }
32002      return result;
32003    }
32004
32005    /**
32006     * The base implementation of `_.toNumber` which doesn't ensure correct
32007     * conversions of binary, hexadecimal, or octal string values.
32008     *
32009     * @private
32010     * @param {*} value The value to process.
32011     * @returns {number} Returns the number.
32012     */
32013    function baseToNumber(value) {
32014      if (typeof value == 'number') {
32015        return value;
32016      }
32017      if (isSymbol(value)) {
32018        return NAN;
32019      }
32020      return +value;
32021    }
32022
32023    /**
32024     * The base implementation of `_.toString` which doesn't convert nullish
32025     * values to empty strings.
32026     *
32027     * @private
32028     * @param {*} value The value to process.
32029     * @returns {string} Returns the string.
32030     */
32031    function baseToString(value) {
32032      // Exit early for strings to avoid a performance hit in some environments.
32033      if (typeof value == 'string') {
32034        return value;
32035      }
32036      if (isArray(value)) {
32037        // Recursively convert values (susceptible to call stack limits).
32038        return arrayMap(value, baseToString) + '';
32039      }
32040      if (isSymbol(value)) {
32041        return symbolToString ? symbolToString.call(value) : '';
32042      }
32043      var result = (value + '');
32044      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
32045    }
32046
32047    /**
32048     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
32049     *
32050     * @private
32051     * @param {Array} array The array to inspect.
32052     * @param {Function} [iteratee] The iteratee invoked per element.
32053     * @param {Function} [comparator] The comparator invoked per element.
32054     * @returns {Array} Returns the new duplicate free array.
32055     */
32056    function baseUniq(array, iteratee, comparator) {
32057      var index = -1,
32058          includes = arrayIncludes,
32059          length = array.length,
32060          isCommon = true,
32061          result = [],
32062          seen = result;
32063
32064      if (comparator) {
32065        isCommon = false;
32066        includes = arrayIncludesWith;
32067      }
32068      else if (length >= LARGE_ARRAY_SIZE) {
32069        var set = iteratee ? null : createSet(array);
32070        if (set) {
32071          return setToArray(set);
32072        }
32073        isCommon = false;
32074        includes = cacheHas;
32075        seen = new SetCache;
32076      }
32077      else {
32078        seen = iteratee ? [] : result;
32079      }
32080      outer:
32081      while (++index < length) {
32082        var value = array[index],
32083            computed = iteratee ? iteratee(value) : value;
32084
32085        value = (comparator || value !== 0) ? value : 0;
32086        if (isCommon && computed === computed) {
32087          var seenIndex = seen.length;
32088          while (seenIndex--) {
32089            if (seen[seenIndex] === computed) {
32090              continue outer;
32091            }
32092          }
32093          if (iteratee) {
32094            seen.push(computed);
32095          }
32096          result.push(value);
32097        }
32098        else if (!includes(seen, computed, comparator)) {
32099          if (seen !== result) {
32100            seen.push(computed);
32101          }
32102          result.push(value);
32103        }
32104      }
32105      return result;
32106    }
32107
32108    /**
32109     * The base implementation of `_.unset`.
32110     *
32111     * @private
32112     * @param {Object} object The object to modify.
32113     * @param {Array|string} path The property path to unset.
32114     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
32115     */
32116    function baseUnset(object, path) {
32117      path = castPath(path, object);
32118      object = parent(object, path);
32119      return object == null || delete object[toKey(last(path))];
32120    }
32121
32122    /**
32123     * The base implementation of `_.update`.
32124     *
32125     * @private
32126     * @param {Object} object The object to modify.
32127     * @param {Array|string} path The path of the property to update.
32128     * @param {Function} updater The function to produce the updated value.
32129     * @param {Function} [customizer] The function to customize path creation.
32130     * @returns {Object} Returns `object`.
32131     */
32132    function baseUpdate(object, path, updater, customizer) {
32133      return baseSet(object, path, updater(baseGet(object, path)), customizer);
32134    }
32135
32136    /**
32137     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
32138     * without support for iteratee shorthands.
32139     *
32140     * @private
32141     * @param {Array} array The array to query.
32142     * @param {Function} predicate The function invoked per iteration.
32143     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
32144     * @param {boolean} [fromRight] Specify iterating from right to left.
32145     * @returns {Array} Returns the slice of `array`.
32146     */
32147    function baseWhile(array, predicate, isDrop, fromRight) {
32148      var length = array.length,
32149          index = fromRight ? length : -1;
32150
32151      while ((fromRight ? index-- : ++index < length) &&
32152        predicate(array[index], index, array)) {}
32153
32154      return isDrop
32155        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
32156        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
32157    }
32158
32159    /**
32160     * The base implementation of `wrapperValue` which returns the result of
32161     * performing a sequence of actions on the unwrapped `value`, where each
32162     * successive action is supplied the return value of the previous.
32163     *
32164     * @private
32165     * @param {*} value The unwrapped value.
32166     * @param {Array} actions Actions to perform to resolve the unwrapped value.
32167     * @returns {*} Returns the resolved value.
32168     */
32169    function baseWrapperValue(value, actions) {
32170      var result = value;
32171      if (result instanceof LazyWrapper) {
32172        result = result.value();
32173      }
32174      return arrayReduce(actions, function(result, action) {
32175        return action.func.apply(action.thisArg, arrayPush([result], action.args));
32176      }, result);
32177    }
32178
32179    /**
32180     * The base implementation of methods like `_.xor`, without support for
32181     * iteratee shorthands, that accepts an array of arrays to inspect.
32182     *
32183     * @private
32184     * @param {Array} arrays The arrays to inspect.
32185     * @param {Function} [iteratee] The iteratee invoked per element.
32186     * @param {Function} [comparator] The comparator invoked per element.
32187     * @returns {Array} Returns the new array of values.
32188     */
32189    function baseXor(arrays, iteratee, comparator) {
32190      var length = arrays.length;
32191      if (length < 2) {
32192        return length ? baseUniq(arrays[0]) : [];
32193      }
32194      var index = -1,
32195          result = Array(length);
32196
32197      while (++index < length) {
32198        var array = arrays[index],
32199            othIndex = -1;
32200
32201        while (++othIndex < length) {
32202          if (othIndex != index) {
32203            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
32204          }
32205        }
32206      }
32207      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
32208    }
32209
32210    /**
32211     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
32212     *
32213     * @private
32214     * @param {Array} props The property identifiers.
32215     * @param {Array} values The property values.
32216     * @param {Function} assignFunc The function to assign values.
32217     * @returns {Object} Returns the new object.
32218     */
32219    function baseZipObject(props, values, assignFunc) {
32220      var index = -1,
32221          length = props.length,
32222          valsLength = values.length,
32223          result = {};
32224
32225      while (++index < length) {
32226        var value = index < valsLength ? values[index] : undefined;
32227        assignFunc(result, props[index], value);
32228      }
32229      return result;
32230    }
32231
32232    /**
32233     * Casts `value` to an empty array if it's not an array like object.
32234     *
32235     * @private
32236     * @param {*} value The value to inspect.
32237     * @returns {Array|Object} Returns the cast array-like object.
32238     */
32239    function castArrayLikeObject(value) {
32240      return isArrayLikeObject(value) ? value : [];
32241    }
32242
32243    /**
32244     * Casts `value` to `identity` if it's not a function.
32245     *
32246     * @private
32247     * @param {*} value The value to inspect.
32248     * @returns {Function} Returns cast function.
32249     */
32250    function castFunction(value) {
32251      return typeof value == 'function' ? value : identity;
32252    }
32253
32254    /**
32255     * Casts `value` to a path array if it's not one.
32256     *
32257     * @private
32258     * @param {*} value The value to inspect.
32259     * @param {Object} [object] The object to query keys on.
32260     * @returns {Array} Returns the cast property path array.
32261     */
32262    function castPath(value, object) {
32263      if (isArray(value)) {
32264        return value;
32265      }
32266      return isKey(value, object) ? [value] : stringToPath(toString(value));
32267    }
32268
32269    /**
32270     * A `baseRest` alias which can be replaced with `identity` by module
32271     * replacement plugins.
32272     *
32273     * @private
32274     * @type {Function}
32275     * @param {Function} func The function to apply a rest parameter to.
32276     * @returns {Function} Returns the new function.
32277     */
32278    var castRest = baseRest;
32279
32280    /**
32281     * Casts `array` to a slice if it's needed.
32282     *
32283     * @private
32284     * @param {Array} array The array to inspect.
32285     * @param {number} start The start position.
32286     * @param {number} [end=array.length] The end position.
32287     * @returns {Array} Returns the cast slice.
32288     */
32289    function castSlice(array, start, end) {
32290      var length = array.length;
32291      end = end === undefined ? length : end;
32292      return (!start && end >= length) ? array : baseSlice(array, start, end);
32293    }
32294
32295    /**
32296     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
32297     *
32298     * @private
32299     * @param {number|Object} id The timer id or timeout object of the timer to clear.
32300     */
32301    var clearTimeout = ctxClearTimeout || function(id) {
32302      return root.clearTimeout(id);
32303    };
32304
32305    /**
32306     * Creates a clone of  `buffer`.
32307     *
32308     * @private
32309     * @param {Buffer} buffer The buffer to clone.
32310     * @param {boolean} [isDeep] Specify a deep clone.
32311     * @returns {Buffer} Returns the cloned buffer.
32312     */
32313    function cloneBuffer(buffer, isDeep) {
32314      if (isDeep) {
32315        return buffer.slice();
32316      }
32317      var length = buffer.length,
32318          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
32319
32320      buffer.copy(result);
32321      return result;
32322    }
32323
32324    /**
32325     * Creates a clone of `arrayBuffer`.
32326     *
32327     * @private
32328     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
32329     * @returns {ArrayBuffer} Returns the cloned array buffer.
32330     */
32331    function cloneArrayBuffer(arrayBuffer) {
32332      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
32333      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
32334      return result;
32335    }
32336
32337    /**
32338     * Creates a clone of `dataView`.
32339     *
32340     * @private
32341     * @param {Object} dataView The data view to clone.
32342     * @param {boolean} [isDeep] Specify a deep clone.
32343     * @returns {Object} Returns the cloned data view.
32344     */
32345    function cloneDataView(dataView, isDeep) {
32346      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
32347      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
32348    }
32349
32350    /**
32351     * Creates a clone of `regexp`.
32352     *
32353     * @private
32354     * @param {Object} regexp The regexp to clone.
32355     * @returns {Object} Returns the cloned regexp.
32356     */
32357    function cloneRegExp(regexp) {
32358      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
32359      result.lastIndex = regexp.lastIndex;
32360      return result;
32361    }
32362
32363    /**
32364     * Creates a clone of the `symbol` object.
32365     *
32366     * @private
32367     * @param {Object} symbol The symbol object to clone.
32368     * @returns {Object} Returns the cloned symbol object.
32369     */
32370    function cloneSymbol(symbol) {
32371      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
32372    }
32373
32374    /**
32375     * Creates a clone of `typedArray`.
32376     *
32377     * @private
32378     * @param {Object} typedArray The typed array to clone.
32379     * @param {boolean} [isDeep] Specify a deep clone.
32380     * @returns {Object} Returns the cloned typed array.
32381     */
32382    function cloneTypedArray(typedArray, isDeep) {
32383      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
32384      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
32385    }
32386
32387    /**
32388     * Compares values to sort them in ascending order.
32389     *
32390     * @private
32391     * @param {*} value The value to compare.
32392     * @param {*} other The other value to compare.
32393     * @returns {number} Returns the sort order indicator for `value`.
32394     */
32395    function compareAscending(value, other) {
32396      if (value !== other) {
32397        var valIsDefined = value !== undefined,
32398            valIsNull = value === null,
32399            valIsReflexive = value === value,
32400            valIsSymbol = isSymbol(value);
32401
32402        var othIsDefined = other !== undefined,
32403            othIsNull = other === null,
32404            othIsReflexive = other === other,
32405            othIsSymbol = isSymbol(other);
32406
32407        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
32408            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
32409            (valIsNull && othIsDefined && othIsReflexive) ||
32410            (!valIsDefined && othIsReflexive) ||
32411            !valIsReflexive) {
32412          return 1;
32413        }
32414        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
32415            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
32416            (othIsNull && valIsDefined && valIsReflexive) ||
32417            (!othIsDefined && valIsReflexive) ||
32418            !othIsReflexive) {
32419          return -1;
32420        }
32421      }
32422      return 0;
32423    }
32424
32425    /**
32426     * Used by `_.orderBy` to compare multiple properties of a value to another
32427     * and stable sort them.
32428     *
32429     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
32430     * specify an order of "desc" for descending or "asc" for ascending sort order
32431     * of corresponding values.
32432     *
32433     * @private
32434     * @param {Object} object The object to compare.
32435     * @param {Object} other The other object to compare.
32436     * @param {boolean[]|string[]} orders The order to sort by for each property.
32437     * @returns {number} Returns the sort order indicator for `object`.
32438     */
32439    function compareMultiple(object, other, orders) {
32440      var index = -1,
32441          objCriteria = object.criteria,
32442          othCriteria = other.criteria,
32443          length = objCriteria.length,
32444          ordersLength = orders.length;
32445
32446      while (++index < length) {
32447        var result = compareAscending(objCriteria[index], othCriteria[index]);
32448        if (result) {
32449          if (index >= ordersLength) {
32450            return result;
32451          }
32452          var order = orders[index];
32453          return result * (order == 'desc' ? -1 : 1);
32454        }
32455      }
32456      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
32457      // that causes it, under certain circumstances, to provide the same value for
32458      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
32459      // for more details.
32460      //
32461      // This also ensures a stable sort in V8 and other engines.
32462      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
32463      return object.index - other.index;
32464    }
32465
32466    /**
32467     * Creates an array that is the composition of partially applied arguments,
32468     * placeholders, and provided arguments into a single array of arguments.
32469     *
32470     * @private
32471     * @param {Array} args The provided arguments.
32472     * @param {Array} partials The arguments to prepend to those provided.
32473     * @param {Array} holders The `partials` placeholder indexes.
32474     * @params {boolean} [isCurried] Specify composing for a curried function.
32475     * @returns {Array} Returns the new array of composed arguments.
32476     */
32477    function composeArgs(args, partials, holders, isCurried) {
32478      var argsIndex = -1,
32479          argsLength = args.length,
32480          holdersLength = holders.length,
32481          leftIndex = -1,
32482          leftLength = partials.length,
32483          rangeLength = nativeMax(argsLength - holdersLength, 0),
32484          result = Array(leftLength + rangeLength),
32485          isUncurried = !isCurried;
32486
32487      while (++leftIndex < leftLength) {
32488        result[leftIndex] = partials[leftIndex];
32489      }
32490      while (++argsIndex < holdersLength) {
32491        if (isUncurried || argsIndex < argsLength) {
32492          result[holders[argsIndex]] = args[argsIndex];
32493        }
32494      }
32495      while (rangeLength--) {
32496        result[leftIndex++] = args[argsIndex++];
32497      }
32498      return result;
32499    }
32500
32501    /**
32502     * This function is like `composeArgs` except that the arguments composition
32503     * is tailored for `_.partialRight`.
32504     *
32505     * @private
32506     * @param {Array} args The provided arguments.
32507     * @param {Array} partials The arguments to append to those provided.
32508     * @param {Array} holders The `partials` placeholder indexes.
32509     * @params {boolean} [isCurried] Specify composing for a curried function.
32510     * @returns {Array} Returns the new array of composed arguments.
32511     */
32512    function composeArgsRight(args, partials, holders, isCurried) {
32513      var argsIndex = -1,
32514          argsLength = args.length,
32515          holdersIndex = -1,
32516          holdersLength = holders.length,
32517          rightIndex = -1,
32518          rightLength = partials.length,
32519          rangeLength = nativeMax(argsLength - holdersLength, 0),
32520          result = Array(rangeLength + rightLength),
32521          isUncurried = !isCurried;
32522
32523      while (++argsIndex < rangeLength) {
32524        result[argsIndex] = args[argsIndex];
32525      }
32526      var offset = argsIndex;
32527      while (++rightIndex < rightLength) {
32528        result[offset + rightIndex] = partials[rightIndex];
32529      }
32530      while (++holdersIndex < holdersLength) {
32531        if (isUncurried || argsIndex < argsLength) {
32532          result[offset + holders[holdersIndex]] = args[argsIndex++];
32533        }
32534      }
32535      return result;
32536    }
32537
32538    /**
32539     * Copies the values of `source` to `array`.
32540     *
32541     * @private
32542     * @param {Array} source The array to copy values from.
32543     * @param {Array} [array=[]] The array to copy values to.
32544     * @returns {Array} Returns `array`.
32545     */
32546    function copyArray(source, array) {
32547      var index = -1,
32548          length = source.length;
32549
32550      array || (array = Array(length));
32551      while (++index < length) {
32552        array[index] = source[index];
32553      }
32554      return array;
32555    }
32556
32557    /**
32558     * Copies properties of `source` to `object`.
32559     *
32560     * @private
32561     * @param {Object} source The object to copy properties from.
32562     * @param {Array} props The property identifiers to copy.
32563     * @param {Object} [object={}] The object to copy properties to.
32564     * @param {Function} [customizer] The function to customize copied values.
32565     * @returns {Object} Returns `object`.
32566     */
32567    function copyObject(source, props, object, customizer) {
32568      var isNew = !object;
32569      object || (object = {});
32570
32571      var index = -1,
32572          length = props.length;
32573
32574      while (++index < length) {
32575        var key = props[index];
32576
32577        var newValue = customizer
32578          ? customizer(object[key], source[key], key, object, source)
32579          : undefined;
32580
32581        if (newValue === undefined) {
32582          newValue = source[key];
32583        }
32584        if (isNew) {
32585          baseAssignValue(object, key, newValue);
32586        } else {
32587          assignValue(object, key, newValue);
32588        }
32589      }
32590      return object;
32591    }
32592
32593    /**
32594     * Copies own symbols of `source` to `object`.
32595     *
32596     * @private
32597     * @param {Object} source The object to copy symbols from.
32598     * @param {Object} [object={}] The object to copy symbols to.
32599     * @returns {Object} Returns `object`.
32600     */
32601    function copySymbols(source, object) {
32602      return copyObject(source, getSymbols(source), object);
32603    }
32604
32605    /**
32606     * Copies own and inherited symbols of `source` to `object`.
32607     *
32608     * @private
32609     * @param {Object} source The object to copy symbols from.
32610     * @param {Object} [object={}] The object to copy symbols to.
32611     * @returns {Object} Returns `object`.
32612     */
32613    function copySymbolsIn(source, object) {
32614      return copyObject(source, getSymbolsIn(source), object);
32615    }
32616
32617    /**
32618     * Creates a function like `_.groupBy`.
32619     *
32620     * @private
32621     * @param {Function} setter The function to set accumulator values.
32622     * @param {Function} [initializer] The accumulator object initializer.
32623     * @returns {Function} Returns the new aggregator function.
32624     */
32625    function createAggregator(setter, initializer) {
32626      return function(collection, iteratee) {
32627        var func = isArray(collection) ? arrayAggregator : baseAggregator,
32628            accumulator = initializer ? initializer() : {};
32629
32630        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
32631      };
32632    }
32633
32634    /**
32635     * Creates a function like `_.assign`.
32636     *
32637     * @private
32638     * @param {Function} assigner The function to assign values.
32639     * @returns {Function} Returns the new assigner function.
32640     */
32641    function createAssigner(assigner) {
32642      return baseRest(function(object, sources) {
32643        var index = -1,
32644            length = sources.length,
32645            customizer = length > 1 ? sources[length - 1] : undefined,
32646            guard = length > 2 ? sources[2] : undefined;
32647
32648        customizer = (assigner.length > 3 && typeof customizer == 'function')
32649          ? (length--, customizer)
32650          : undefined;
32651
32652        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
32653          customizer = length < 3 ? undefined : customizer;
32654          length = 1;
32655        }
32656        object = Object(object);
32657        while (++index < length) {
32658          var source = sources[index];
32659          if (source) {
32660            assigner(object, source, index, customizer);
32661          }
32662        }
32663        return object;
32664      });
32665    }
32666
32667    /**
32668     * Creates a `baseEach` or `baseEachRight` function.
32669     *
32670     * @private
32671     * @param {Function} eachFunc The function to iterate over a collection.
32672     * @param {boolean} [fromRight] Specify iterating from right to left.
32673     * @returns {Function} Returns the new base function.
32674     */
32675    function createBaseEach(eachFunc, fromRight) {
32676      return function(collection, iteratee) {
32677        if (collection == null) {
32678          return collection;
32679        }
32680        if (!isArrayLike(collection)) {
32681          return eachFunc(collection, iteratee);
32682        }
32683        var length = collection.length,
32684            index = fromRight ? length : -1,
32685            iterable = Object(collection);
32686
32687        while ((fromRight ? index-- : ++index < length)) {
32688          if (iteratee(iterable[index], index, iterable) === false) {
32689            break;
32690          }
32691        }
32692        return collection;
32693      };
32694    }
32695
32696    /**
32697     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
32698     *
32699     * @private
32700     * @param {boolean} [fromRight] Specify iterating from right to left.
32701     * @returns {Function} Returns the new base function.
32702     */
32703    function createBaseFor(fromRight) {
32704      return function(object, iteratee, keysFunc) {
32705        var index = -1,
32706            iterable = Object(object),
32707            props = keysFunc(object),
32708            length = props.length;
32709
32710        while (length--) {
32711          var key = props[fromRight ? length : ++index];
32712          if (iteratee(iterable[key], key, iterable) === false) {
32713            break;
32714          }
32715        }
32716        return object;
32717      };
32718    }
32719
32720    /**
32721     * Creates a function that wraps `func` to invoke it with the optional `this`
32722     * binding of `thisArg`.
32723     *
32724     * @private
32725     * @param {Function} func The function to wrap.
32726     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
32727     * @param {*} [thisArg] The `this` binding of `func`.
32728     * @returns {Function} Returns the new wrapped function.
32729     */
32730    function createBind(func, bitmask, thisArg) {
32731      var isBind = bitmask & WRAP_BIND_FLAG,
32732          Ctor = createCtor(func);
32733
32734      function wrapper() {
32735        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
32736        return fn.apply(isBind ? thisArg : this, arguments);
32737      }
32738      return wrapper;
32739    }
32740
32741    /**
32742     * Creates a function like `_.lowerFirst`.
32743     *
32744     * @private
32745     * @param {string} methodName The name of the `String` case method to use.
32746     * @returns {Function} Returns the new case function.
32747     */
32748    function createCaseFirst(methodName) {
32749      return function(string) {
32750        string = toString(string);
32751
32752        var strSymbols = hasUnicode(string)
32753          ? stringToArray(string)
32754          : undefined;
32755
32756        var chr = strSymbols
32757          ? strSymbols[0]
32758          : string.charAt(0);
32759
32760        var trailing = strSymbols
32761          ? castSlice(strSymbols, 1).join('')
32762          : string.slice(1);
32763
32764        return chr[methodName]() + trailing;
32765      };
32766    }
32767
32768    /**
32769     * Creates a function like `_.camelCase`.
32770     *
32771     * @private
32772     * @param {Function} callback The function to combine each word.
32773     * @returns {Function} Returns the new compounder function.
32774     */
32775    function createCompounder(callback) {
32776      return function(string) {
32777        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
32778      };
32779    }
32780
32781    /**
32782     * Creates a function that produces an instance of `Ctor` regardless of
32783     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
32784     *
32785     * @private
32786     * @param {Function} Ctor The constructor to wrap.
32787     * @returns {Function} Returns the new wrapped function.
32788     */
32789    function createCtor(Ctor) {
32790      return function() {
32791        // Use a `switch` statement to work with class constructors. See
32792        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
32793        // for more details.
32794        var args = arguments;
32795        switch (args.length) {
32796          case 0: return new Ctor;
32797          case 1: return new Ctor(args[0]);
32798          case 2: return new Ctor(args[0], args[1]);
32799          case 3: return new Ctor(args[0], args[1], args[2]);
32800          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
32801          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
32802          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
32803          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
32804        }
32805        var thisBinding = baseCreate(Ctor.prototype),
32806            result = Ctor.apply(thisBinding, args);
32807
32808        // Mimic the constructor's `return` behavior.
32809        // See https://es5.github.io/#x13.2.2 for more details.
32810        return isObject(result) ? result : thisBinding;
32811      };
32812    }
32813
32814    /**
32815     * Creates a function that wraps `func` to enable currying.
32816     *
32817     * @private
32818     * @param {Function} func The function to wrap.
32819     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
32820     * @param {number} arity The arity of `func`.
32821     * @returns {Function} Returns the new wrapped function.
32822     */
32823    function createCurry(func, bitmask, arity) {
32824      var Ctor = createCtor(func);
32825
32826      function wrapper() {
32827        var length = arguments.length,
32828            args = Array(length),
32829            index = length,
32830            placeholder = getHolder(wrapper);
32831
32832        while (index--) {
32833          args[index] = arguments[index];
32834        }
32835        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
32836          ? []
32837          : replaceHolders(args, placeholder);
32838
32839        length -= holders.length;
32840        if (length < arity) {
32841          return createRecurry(
32842            func, bitmask, createHybrid, wrapper.placeholder, undefined,
32843            args, holders, undefined, undefined, arity - length);
32844        }
32845        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
32846        return apply(fn, this, args);
32847      }
32848      return wrapper;
32849    }
32850
32851    /**
32852     * Creates a `_.find` or `_.findLast` function.
32853     *
32854     * @private
32855     * @param {Function} findIndexFunc The function to find the collection index.
32856     * @returns {Function} Returns the new find function.
32857     */
32858    function createFind(findIndexFunc) {
32859      return function(collection, predicate, fromIndex) {
32860        var iterable = Object(collection);
32861        if (!isArrayLike(collection)) {
32862          var iteratee = getIteratee(predicate, 3);
32863          collection = keys(collection);
32864          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
32865        }
32866        var index = findIndexFunc(collection, predicate, fromIndex);
32867        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
32868      };
32869    }
32870
32871    /**
32872     * Creates a `_.flow` or `_.flowRight` function.
32873     *
32874     * @private
32875     * @param {boolean} [fromRight] Specify iterating from right to left.
32876     * @returns {Function} Returns the new flow function.
32877     */
32878    function createFlow(fromRight) {
32879      return flatRest(function(funcs) {
32880        var length = funcs.length,
32881            index = length,
32882            prereq = LodashWrapper.prototype.thru;
32883
32884        if (fromRight) {
32885          funcs.reverse();
32886        }
32887        while (index--) {
32888          var func = funcs[index];
32889          if (typeof func != 'function') {
32890            throw new TypeError(FUNC_ERROR_TEXT);
32891          }
32892          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
32893            var wrapper = new LodashWrapper([], true);
32894          }
32895        }
32896        index = wrapper ? index : length;
32897        while (++index < length) {
32898          func = funcs[index];
32899
32900          var funcName = getFuncName(func),
32901              data = funcName == 'wrapper' ? getData(func) : undefined;
32902
32903          if (data && isLaziable(data[0]) &&
32904                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
32905                !data[4].length && data[9] == 1
32906              ) {
32907            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
32908          } else {
32909            wrapper = (func.length == 1 && isLaziable(func))
32910              ? wrapper[funcName]()
32911              : wrapper.thru(func);
32912          }
32913        }
32914        return function() {
32915          var args = arguments,
32916              value = args[0];
32917
32918          if (wrapper && args.length == 1 && isArray(value)) {
32919            return wrapper.plant(value).value();
32920          }
32921          var index = 0,
32922              result = length ? funcs[index].apply(this, args) : value;
32923
32924          while (++index < length) {
32925            result = funcs[index].call(this, result);
32926          }
32927          return result;
32928        };
32929      });
32930    }
32931
32932    /**
32933     * Creates a function that wraps `func` to invoke it with optional `this`
32934     * binding of `thisArg`, partial application, and currying.
32935     *
32936     * @private
32937     * @param {Function|string} func The function or method name to wrap.
32938     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
32939     * @param {*} [thisArg] The `this` binding of `func`.
32940     * @param {Array} [partials] The arguments to prepend to those provided to
32941     *  the new function.
32942     * @param {Array} [holders] The `partials` placeholder indexes.
32943     * @param {Array} [partialsRight] The arguments to append to those provided
32944     *  to the new function.
32945     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
32946     * @param {Array} [argPos] The argument positions of the new function.
32947     * @param {number} [ary] The arity cap of `func`.
32948     * @param {number} [arity] The arity of `func`.
32949     * @returns {Function} Returns the new wrapped function.
32950     */
32951    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
32952      var isAry = bitmask & WRAP_ARY_FLAG,
32953          isBind = bitmask & WRAP_BIND_FLAG,
32954          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
32955          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
32956          isFlip = bitmask & WRAP_FLIP_FLAG,
32957          Ctor = isBindKey ? undefined : createCtor(func);
32958
32959      function wrapper() {
32960        var length = arguments.length,
32961            args = Array(length),
32962            index = length;
32963
32964        while (index--) {
32965          args[index] = arguments[index];
32966        }
32967        if (isCurried) {
32968          var placeholder = getHolder(wrapper),
32969              holdersCount = countHolders(args, placeholder);
32970        }
32971        if (partials) {
32972          args = composeArgs(args, partials, holders, isCurried);
32973        }
32974        if (partialsRight) {
32975          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
32976        }
32977        length -= holdersCount;
32978        if (isCurried && length < arity) {
32979          var newHolders = replaceHolders(args, placeholder);
32980          return createRecurry(
32981            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
32982            args, newHolders, argPos, ary, arity - length
32983          );
32984        }
32985        var thisBinding = isBind ? thisArg : this,
32986            fn = isBindKey ? thisBinding[func] : func;
32987
32988        length = args.length;
32989        if (argPos) {
32990          args = reorder(args, argPos);
32991        } else if (isFlip && length > 1) {
32992          args.reverse();
32993        }
32994        if (isAry && ary < length) {
32995          args.length = ary;
32996        }
32997        if (this && this !== root && this instanceof wrapper) {
32998          fn = Ctor || createCtor(fn);
32999        }
33000        return fn.apply(thisBinding, args);
33001      }
33002      return wrapper;
33003    }
33004
33005    /**
33006     * Creates a function like `_.invertBy`.
33007     *
33008     * @private
33009     * @param {Function} setter The function to set accumulator values.
33010     * @param {Function} toIteratee The function to resolve iteratees.
33011     * @returns {Function} Returns the new inverter function.
33012     */
33013    function createInverter(setter, toIteratee) {
33014      return function(object, iteratee) {
33015        return baseInverter(object, setter, toIteratee(iteratee), {});
33016      };
33017    }
33018
33019    /**
33020     * Creates a function that performs a mathematical operation on two values.
33021     *
33022     * @private
33023     * @param {Function} operator The function to perform the operation.
33024     * @param {number} [defaultValue] The value used for `undefined` arguments.
33025     * @returns {Function} Returns the new mathematical operation function.
33026     */
33027    function createMathOperation(operator, defaultValue) {
33028      return function(value, other) {
33029        var result;
33030        if (value === undefined && other === undefined) {
33031          return defaultValue;
33032        }
33033        if (value !== undefined) {
33034          result = value;
33035        }
33036        if (other !== undefined) {
33037          if (result === undefined) {
33038            return other;
33039          }
33040          if (typeof value == 'string' || typeof other == 'string') {
33041            value = baseToString(value);
33042            other = baseToString(other);
33043          } else {
33044            value = baseToNumber(value);
33045            other = baseToNumber(other);
33046          }
33047          result = operator(value, other);
33048        }
33049        return result;
33050      };
33051    }
33052
33053    /**
33054     * Creates a function like `_.over`.
33055     *
33056     * @private
33057     * @param {Function} arrayFunc The function to iterate over iteratees.
33058     * @returns {Function} Returns the new over function.
33059     */
33060    function createOver(arrayFunc) {
33061      return flatRest(function(iteratees) {
33062        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
33063        return baseRest(function(args) {
33064          var thisArg = this;
33065          return arrayFunc(iteratees, function(iteratee) {
33066            return apply(iteratee, thisArg, args);
33067          });
33068        });
33069      });
33070    }
33071
33072    /**
33073     * Creates the padding for `string` based on `length`. The `chars` string
33074     * is truncated if the number of characters exceeds `length`.
33075     *
33076     * @private
33077     * @param {number} length The padding length.
33078     * @param {string} [chars=' '] The string used as padding.
33079     * @returns {string} Returns the padding for `string`.
33080     */
33081    function createPadding(length, chars) {
33082      chars = chars === undefined ? ' ' : baseToString(chars);
33083
33084      var charsLength = chars.length;
33085      if (charsLength < 2) {
33086        return charsLength ? baseRepeat(chars, length) : chars;
33087      }
33088      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
33089      return hasUnicode(chars)
33090        ? castSlice(stringToArray(result), 0, length).join('')
33091        : result.slice(0, length);
33092    }
33093
33094    /**
33095     * Creates a function that wraps `func` to invoke it with the `this` binding
33096     * of `thisArg` and `partials` prepended to the arguments it receives.
33097     *
33098     * @private
33099     * @param {Function} func The function to wrap.
33100     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
33101     * @param {*} thisArg The `this` binding of `func`.
33102     * @param {Array} partials The arguments to prepend to those provided to
33103     *  the new function.
33104     * @returns {Function} Returns the new wrapped function.
33105     */
33106    function createPartial(func, bitmask, thisArg, partials) {
33107      var isBind = bitmask & WRAP_BIND_FLAG,
33108          Ctor = createCtor(func);
33109
33110      function wrapper() {
33111        var argsIndex = -1,
33112            argsLength = arguments.length,
33113            leftIndex = -1,
33114            leftLength = partials.length,
33115            args = Array(leftLength + argsLength),
33116            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
33117
33118        while (++leftIndex < leftLength) {
33119          args[leftIndex] = partials[leftIndex];
33120        }
33121        while (argsLength--) {
33122          args[leftIndex++] = arguments[++argsIndex];
33123        }
33124        return apply(fn, isBind ? thisArg : this, args);
33125      }
33126      return wrapper;
33127    }
33128
33129    /**
33130     * Creates a `_.range` or `_.rangeRight` function.
33131     *
33132     * @private
33133     * @param {boolean} [fromRight] Specify iterating from right to left.
33134     * @returns {Function} Returns the new range function.
33135     */
33136    function createRange(fromRight) {
33137      return function(start, end, step) {
33138        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
33139          end = step = undefined;
33140        }
33141        // Ensure the sign of `-0` is preserved.
33142        start = toFinite(start);
33143        if (end === undefined) {
33144          end = start;
33145          start = 0;
33146        } else {
33147          end = toFinite(end);
33148        }
33149        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
33150        return baseRange(start, end, step, fromRight);
33151      };
33152    }
33153
33154    /**
33155     * Creates a function that performs a relational operation on two values.
33156     *
33157     * @private
33158     * @param {Function} operator The function to perform the operation.
33159     * @returns {Function} Returns the new relational operation function.
33160     */
33161    function createRelationalOperation(operator) {
33162      return function(value, other) {
33163        if (!(typeof value == 'string' && typeof other == 'string')) {
33164          value = toNumber(value);
33165          other = toNumber(other);
33166        }
33167        return operator(value, other);
33168      };
33169    }
33170
33171    /**
33172     * Creates a function that wraps `func` to continue currying.
33173     *
33174     * @private
33175     * @param {Function} func The function to wrap.
33176     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
33177     * @param {Function} wrapFunc The function to create the `func` wrapper.
33178     * @param {*} placeholder The placeholder value.
33179     * @param {*} [thisArg] The `this` binding of `func`.
33180     * @param {Array} [partials] The arguments to prepend to those provided to
33181     *  the new function.
33182     * @param {Array} [holders] The `partials` placeholder indexes.
33183     * @param {Array} [argPos] The argument positions of the new function.
33184     * @param {number} [ary] The arity cap of `func`.
33185     * @param {number} [arity] The arity of `func`.
33186     * @returns {Function} Returns the new wrapped function.
33187     */
33188    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
33189      var isCurry = bitmask & WRAP_CURRY_FLAG,
33190          newHolders = isCurry ? holders : undefined,
33191          newHoldersRight = isCurry ? undefined : holders,
33192          newPartials = isCurry ? partials : undefined,
33193          newPartialsRight = isCurry ? undefined : partials;
33194
33195      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
33196      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
33197
33198      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
33199        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
33200      }
33201      var newData = [
33202        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
33203        newHoldersRight, argPos, ary, arity
33204      ];
33205
33206      var result = wrapFunc.apply(undefined, newData);
33207      if (isLaziable(func)) {
33208        setData(result, newData);
33209      }
33210      result.placeholder = placeholder;
33211      return setWrapToString(result, func, bitmask);
33212    }
33213
33214    /**
33215     * Creates a function like `_.round`.
33216     *
33217     * @private
33218     * @param {string} methodName The name of the `Math` method to use when rounding.
33219     * @returns {Function} Returns the new round function.
33220     */
33221    function createRound(methodName) {
33222      var func = Math[methodName];
33223      return function(number, precision) {
33224        number = toNumber(number);
33225        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
33226        if (precision && nativeIsFinite(number)) {
33227          // Shift with exponential notation to avoid floating-point issues.
33228          // See [MDN](https://mdn.io/round#Examples) for more details.
33229          var pair = (toString(number) + 'e').split('e'),
33230              value = func(pair[0] + 'e' + (+pair[1] + precision));
33231
33232          pair = (toString(value) + 'e').split('e');
33233          return +(pair[0] + 'e' + (+pair[1] - precision));
33234        }
33235        return func(number);
33236      };
33237    }
33238
33239    /**
33240     * Creates a set object of `values`.
33241     *
33242     * @private
33243     * @param {Array} values The values to add to the set.
33244     * @returns {Object} Returns the new set.
33245     */
33246    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
33247      return new Set(values);
33248    };
33249
33250    /**
33251     * Creates a `_.toPairs` or `_.toPairsIn` function.
33252     *
33253     * @private
33254     * @param {Function} keysFunc The function to get the keys of a given object.
33255     * @returns {Function} Returns the new pairs function.
33256     */
33257    function createToPairs(keysFunc) {
33258      return function(object) {
33259        var tag = getTag(object);
33260        if (tag == mapTag) {
33261          return mapToArray(object);
33262        }
33263        if (tag == setTag) {
33264          return setToPairs(object);
33265        }
33266        return baseToPairs(object, keysFunc(object));
33267      };
33268    }
33269
33270    /**
33271     * Creates a function that either curries or invokes `func` with optional
33272     * `this` binding and partially applied arguments.
33273     *
33274     * @private
33275     * @param {Function|string} func The function or method name to wrap.
33276     * @param {number} bitmask The bitmask flags.
33277     *    1 - `_.bind`
33278     *    2 - `_.bindKey`
33279     *    4 - `_.curry` or `_.curryRight` of a bound function
33280     *    8 - `_.curry`
33281     *   16 - `_.curryRight`
33282     *   32 - `_.partial`
33283     *   64 - `_.partialRight`
33284     *  128 - `_.rearg`
33285     *  256 - `_.ary`
33286     *  512 - `_.flip`
33287     * @param {*} [thisArg] The `this` binding of `func`.
33288     * @param {Array} [partials] The arguments to be partially applied.
33289     * @param {Array} [holders] The `partials` placeholder indexes.
33290     * @param {Array} [argPos] The argument positions of the new function.
33291     * @param {number} [ary] The arity cap of `func`.
33292     * @param {number} [arity] The arity of `func`.
33293     * @returns {Function} Returns the new wrapped function.
33294     */
33295    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
33296      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
33297      if (!isBindKey && typeof func != 'function') {
33298        throw new TypeError(FUNC_ERROR_TEXT);
33299      }
33300      var length = partials ? partials.length : 0;
33301      if (!length) {
33302        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
33303        partials = holders = undefined;
33304      }
33305      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
33306      arity = arity === undefined ? arity : toInteger(arity);
33307      length -= holders ? holders.length : 0;
33308
33309      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
33310        var partialsRight = partials,
33311            holdersRight = holders;
33312
33313        partials = holders = undefined;
33314      }
33315      var data = isBindKey ? undefined : getData(func);
33316
33317      var newData = [
33318        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
33319        argPos, ary, arity
33320      ];
33321
33322      if (data) {
33323        mergeData(newData, data);
33324      }
33325      func = newData[0];
33326      bitmask = newData[1];
33327      thisArg = newData[2];
33328      partials = newData[3];
33329      holders = newData[4];
33330      arity = newData[9] = newData[9] === undefined
33331        ? (isBindKey ? 0 : func.length)
33332        : nativeMax(newData[9] - length, 0);
33333
33334      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
33335        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
33336      }
33337      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
33338        var result = createBind(func, bitmask, thisArg);
33339      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
33340        result = createCurry(func, bitmask, arity);
33341      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
33342        result = createPartial(func, bitmask, thisArg, partials);
33343      } else {
33344        result = createHybrid.apply(undefined, newData);
33345      }
33346      var setter = data ? baseSetData : setData;
33347      return setWrapToString(setter(result, newData), func, bitmask);
33348    }
33349
33350    /**
33351     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
33352     * of source objects to the destination object for all destination properties
33353     * that resolve to `undefined`.
33354     *
33355     * @private
33356     * @param {*} objValue The destination value.
33357     * @param {*} srcValue The source value.
33358     * @param {string} key The key of the property to assign.
33359     * @param {Object} object The parent object of `objValue`.
33360     * @returns {*} Returns the value to assign.
33361     */
33362    function customDefaultsAssignIn(objValue, srcValue, key, object) {
33363      if (objValue === undefined ||
33364          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
33365        return srcValue;
33366      }
33367      return objValue;
33368    }
33369
33370    /**
33371     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
33372     * objects into destination objects that are passed thru.
33373     *
33374     * @private
33375     * @param {*} objValue The destination value.
33376     * @param {*} srcValue The source value.
33377     * @param {string} key The key of the property to merge.
33378     * @param {Object} object The parent object of `objValue`.
33379     * @param {Object} source The parent object of `srcValue`.
33380     * @param {Object} [stack] Tracks traversed source values and their merged
33381     *  counterparts.
33382     * @returns {*} Returns the value to assign.
33383     */
33384    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
33385      if (isObject(objValue) && isObject(srcValue)) {
33386        // Recursively merge objects and arrays (susceptible to call stack limits).
33387        stack.set(srcValue, objValue);
33388        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
33389        stack['delete'](srcValue);
33390      }
33391      return objValue;
33392    }
33393
33394    /**
33395     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
33396     * objects.
33397     *
33398     * @private
33399     * @param {*} value The value to inspect.
33400     * @param {string} key The key of the property to inspect.
33401     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
33402     */
33403    function customOmitClone(value) {
33404      return isPlainObject(value) ? undefined : value;
33405    }
33406
33407    /**
33408     * A specialized version of `baseIsEqualDeep` for arrays with support for
33409     * partial deep comparisons.
33410     *
33411     * @private
33412     * @param {Array} array The array to compare.
33413     * @param {Array} other The other array to compare.
33414     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
33415     * @param {Function} customizer The function to customize comparisons.
33416     * @param {Function} equalFunc The function to determine equivalents of values.
33417     * @param {Object} stack Tracks traversed `array` and `other` objects.
33418     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
33419     */
33420    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
33421      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
33422          arrLength = array.length,
33423          othLength = other.length;
33424
33425      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
33426        return false;
33427      }
33428      // Check that cyclic values are equal.
33429      var arrStacked = stack.get(array);
33430      var othStacked = stack.get(other);
33431      if (arrStacked && othStacked) {
33432        return arrStacked == other && othStacked == array;
33433      }
33434      var index = -1,
33435          result = true,
33436          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
33437
33438      stack.set(array, other);
33439      stack.set(other, array);
33440
33441      // Ignore non-index properties.
33442      while (++index < arrLength) {
33443        var arrValue = array[index],
33444            othValue = other[index];
33445
33446        if (customizer) {
33447          var compared = isPartial
33448            ? customizer(othValue, arrValue, index, other, array, stack)
33449            : customizer(arrValue, othValue, index, array, other, stack);
33450        }
33451        if (compared !== undefined) {
33452          if (compared) {
33453            continue;
33454          }
33455          result = false;
33456          break;
33457        }
33458        // Recursively compare arrays (susceptible to call stack limits).
33459        if (seen) {
33460          if (!arraySome(other, function(othValue, othIndex) {
33461                if (!cacheHas(seen, othIndex) &&
33462                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
33463                  return seen.push(othIndex);
33464                }
33465              })) {
33466            result = false;
vendor: 4,179 bytes, lines 33467-33578
33467            break;
33468          }
33469        } else if (!(
33470              arrValue === othValue ||
33471                equalFunc(arrValue, othValue, bitmask, customizer, stack)
33472            )) {
33473          result = false;
33474          break;
33475        }
33476      }
33477      stack['delete'](array);
33478      stack['delete'](other);
33479      return result;
33480    }
33481
33482    /**
33483     * A specialized version of `baseIsEqualDeep` for comparing objects of
33484     * the same `toStringTag`.
33485     *
33486     * **Note:** This function only supports comparing values with tags of
33487     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
33488     *
33489     * @private
33490     * @param {Object} object The object to compare.
33491     * @param {Object} other The other object to compare.
33492     * @param {string} tag The `toStringTag` of the objects to compare.
33493     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
33494     * @param {Function} customizer The function to customize comparisons.
33495     * @param {Function} equalFunc The function to determine equivalents of values.
33496     * @param {Object} stack Tracks traversed `object` and `other` objects.
33497     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
33498     */
33499    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
33500      switch (tag) {
33501        case dataViewTag:
33502          if ((object.byteLength != other.byteLength) ||
33503              (object.byteOffset != other.byteOffset)) {
33504            return false;
33505          }
33506          object = object.buffer;
33507          other = other.buffer;
33508
33509        case arrayBufferTag:
33510          if ((object.byteLength != other.byteLength) ||
33511              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
33512            return false;
33513          }
33514          return true;
33515
33516        case boolTag:
33517        case dateTag:
33518        case numberTag:
33519          // Coerce booleans to `1` or `0` and dates to milliseconds.
33520          // Invalid dates are coerced to `NaN`.
33521          return eq(+object, +other);
33522
33523        case errorTag:
33524          return object.name == other.name && object.message == other.message;
33525
33526        case regexpTag:
33527        case stringTag:
33528          // Coerce regexes to strings and treat strings, primitives and objects,
33529          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
33530          // for more details.
33531          return object == (other + '');
33532
33533        case mapTag:
33534          var convert = mapToArray;
33535
33536        case setTag:
33537          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
33538          convert || (convert = setToArray);
33539
33540          if (object.size != other.size && !isPartial) {
33541            return false;
33542          }
33543          // Assume cyclic values are equal.
33544          var stacked = stack.get(object);
33545          if (stacked) {
33546            return stacked == other;
33547          }
33548          bitmask |= COMPARE_UNORDERED_FLAG;
33549
33550          // Recursively compare objects (susceptible to call stack limits).
33551          stack.set(object, other);
33552          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
33553          stack['delete'](object);
33554          return result;
33555
33556        case symbolTag:
33557          if (symbolValueOf) {
33558            return symbolValueOf.call(object) == symbolValueOf.call(other);
33559          }
33560      }
33561      return false;
33562    }
33563
33564    /**
33565     * A specialized version of `baseIsEqualDeep` for objects with support for
33566     * partial deep comparisons.
33567     *
33568     * @private
33569     * @param {Object} object The object to compare.
33570     * @param {Object} other The other object to compare.
33571     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
33572     * @param {Function} customizer The function to customize comparisons.
33573     * @param {Function} equalFunc The function to determine equivalents of values.
33574     * @param {Object} stack Tracks traversed `object` and `other` objects.
33575     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
33576     */
33577    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
33578      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
vendor: 9,614 bytes, lines 33579-33886
33579          objProps = getAllKeys(object),
33580          objLength = objProps.length,
33581          othProps = getAllKeys(other),
33582          othLength = othProps.length;
33583
33584      if (objLength != othLength && !isPartial) {
33585        return false;
33586      }
33587      var index = objLength;
33588      while (index--) {
33589        var key = objProps[index];
33590        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
33591          return false;
33592        }
33593      }
33594      // Check that cyclic values are equal.
33595      var objStacked = stack.get(object);
33596      var othStacked = stack.get(other);
33597      if (objStacked && othStacked) {
33598        return objStacked == other && othStacked == object;
33599      }
33600      var result = true;
33601      stack.set(object, other);
33602      stack.set(other, object);
33603
33604      var skipCtor = isPartial;
33605      while (++index < objLength) {
33606        key = objProps[index];
33607        var objValue = object[key],
33608            othValue = other[key];
33609
33610        if (customizer) {
33611          var compared = isPartial
33612            ? customizer(othValue, objValue, key, other, object, stack)
33613            : customizer(objValue, othValue, key, object, other, stack);
33614        }
33615        // Recursively compare objects (susceptible to call stack limits).
33616        if (!(compared === undefined
33617              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
33618              : compared
33619            )) {
33620          result = false;
33621          break;
33622        }
33623        skipCtor || (skipCtor = key == 'constructor');
33624      }
33625      if (result && !skipCtor) {
33626        var objCtor = object.constructor,
33627            othCtor = other.constructor;
33628
33629        // Non `Object` object instances with different constructors are not equal.
33630        if (objCtor != othCtor &&
33631            ('constructor' in object && 'constructor' in other) &&
33632            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
33633              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
33634          result = false;
33635        }
33636      }
33637      stack['delete'](object);
33638      stack['delete'](other);
33639      return result;
33640    }
33641
33642    /**
33643     * A specialized version of `baseRest` which flattens the rest array.
33644     *
33645     * @private
33646     * @param {Function} func The function to apply a rest parameter to.
33647     * @returns {Function} Returns the new function.
33648     */
33649    function flatRest(func) {
33650      return setToString(overRest(func, undefined, flatten), func + '');
33651    }
33652
33653    /**
33654     * Creates an array of own enumerable property names and symbols of `object`.
33655     *
33656     * @private
33657     * @param {Object} object The object to query.
33658     * @returns {Array} Returns the array of property names and symbols.
33659     */
33660    function getAllKeys(object) {
33661      return baseGetAllKeys(object, keys, getSymbols);
33662    }
33663
33664    /**
33665     * Creates an array of own and inherited enumerable property names and
33666     * symbols of `object`.
33667     *
33668     * @private
33669     * @param {Object} object The object to query.
33670     * @returns {Array} Returns the array of property names and symbols.
33671     */
33672    function getAllKeysIn(object) {
33673      return baseGetAllKeys(object, keysIn, getSymbolsIn);
33674    }
33675
33676    /**
33677     * Gets metadata for `func`.
33678     *
33679     * @private
33680     * @param {Function} func The function to query.
33681     * @returns {*} Returns the metadata for `func`.
33682     */
33683    var getData = !metaMap ? noop : function(func) {
33684      return metaMap.get(func);
33685    };
33686
33687    /**
33688     * Gets the name of `func`.
33689     *
33690     * @private
33691     * @param {Function} func The function to query.
33692     * @returns {string} Returns the function name.
33693     */
33694    function getFuncName(func) {
33695      var result = (func.name + ''),
33696          array = realNames[result],
33697          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
33698
33699      while (length--) {
33700        var data = array[length],
33701            otherFunc = data.func;
33702        if (otherFunc == null || otherFunc == func) {
33703          return data.name;
33704        }
33705      }
33706      return result;
33707    }
33708
33709    /**
33710     * Gets the argument placeholder value for `func`.
33711     *
33712     * @private
33713     * @param {Function} func The function to inspect.
33714     * @returns {*} Returns the placeholder value.
33715     */
33716    function getHolder(func) {
33717      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
33718      return object.placeholder;
33719    }
33720
33721    /**
33722     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
33723     * this function returns the custom method, otherwise it returns `baseIteratee`.
33724     * If arguments are provided, the chosen function is invoked with them and
33725     * its result is returned.
33726     *
33727     * @private
33728     * @param {*} [value] The value to convert to an iteratee.
33729     * @param {number} [arity] The arity of the created iteratee.
33730     * @returns {Function} Returns the chosen function or its result.
33731     */
33732    function getIteratee() {
33733      var result = lodash.iteratee || iteratee;
33734      result = result === iteratee ? baseIteratee : result;
33735      return arguments.length ? result(arguments[0], arguments[1]) : result;
33736    }
33737
33738    /**
33739     * Gets the data for `map`.
33740     *
33741     * @private
33742     * @param {Object} map The map to query.
33743     * @param {string} key The reference key.
33744     * @returns {*} Returns the map data.
33745     */
33746    function getMapData(map, key) {
33747      var data = map.__data__;
33748      return isKeyable(key)
33749        ? data[typeof key == 'string' ? 'string' : 'hash']
33750        : data.map;
33751    }
33752
33753    /**
33754     * Gets the property names, values, and compare flags of `object`.
33755     *
33756     * @private
33757     * @param {Object} object The object to query.
33758     * @returns {Array} Returns the match data of `object`.
33759     */
33760    function getMatchData(object) {
33761      var result = keys(object),
33762          length = result.length;
33763
33764      while (length--) {
33765        var key = result[length],
33766            value = object[key];
33767
33768        result[length] = [key, value, isStrictComparable(value)];
33769      }
33770      return result;
33771    }
33772
33773    /**
33774     * Gets the native function at `key` of `object`.
33775     *
33776     * @private
33777     * @param {Object} object The object to query.
33778     * @param {string} key The key of the method to get.
33779     * @returns {*} Returns the function if it's native, else `undefined`.
33780     */
33781    function getNative(object, key) {
33782      var value = getValue(object, key);
33783      return baseIsNative(value) ? value : undefined;
33784    }
33785
33786    /**
33787     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
33788     *
33789     * @private
33790     * @param {*} value The value to query.
33791     * @returns {string} Returns the raw `toStringTag`.
33792     */
33793    function getRawTag(value) {
33794      var isOwn = hasOwnProperty.call(value, symToStringTag),
33795          tag = value[symToStringTag];
33796
33797      try {
33798        value[symToStringTag] = undefined;
33799        var unmasked = true;
33800      } catch (e) {}
33801
33802      var result = nativeObjectToString.call(value);
33803      if (unmasked) {
33804        if (isOwn) {
33805          value[symToStringTag] = tag;
33806        } else {
33807          delete value[symToStringTag];
33808        }
33809      }
33810      return result;
33811    }
33812
33813    /**
33814     * Creates an array of the own enumerable symbols of `object`.
33815     *
33816     * @private
33817     * @param {Object} object The object to query.
33818     * @returns {Array} Returns the array of symbols.
33819     */
33820    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
33821      if (object == null) {
33822        return [];
33823      }
33824      object = Object(object);
33825      return arrayFilter(nativeGetSymbols(object), function(symbol) {
33826        return propertyIsEnumerable.call(object, symbol);
33827      });
33828    };
33829
33830    /**
33831     * Creates an array of the own and inherited enumerable symbols of `object`.
33832     *
33833     * @private
33834     * @param {Object} object The object to query.
33835     * @returns {Array} Returns the array of symbols.
33836     */
33837    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
33838      var result = [];
33839      while (object) {
33840        arrayPush(result, getSymbols(object));
33841        object = getPrototype(object);
33842      }
33843      return result;
33844    };
33845
33846    /**
33847     * Gets the `toStringTag` of `value`.
33848     *
33849     * @private
33850     * @param {*} value The value to query.
33851     * @returns {string} Returns the `toStringTag`.
33852     */
33853    var getTag = baseGetTag;
33854
33855    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
33856    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
33857        (Map && getTag(new Map) != mapTag) ||
33858        (Promise && getTag(Promise.resolve()) != promiseTag) ||
33859        (Set && getTag(new Set) != setTag) ||
33860        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
33861      getTag = function(value) {
33862        var result = baseGetTag(value),
33863            Ctor = result == objectTag ? value.constructor : undefined,
33864            ctorString = Ctor ? toSource(Ctor) : '';
33865
33866        if (ctorString) {
33867          switch (ctorString) {
33868            case dataViewCtorString: return dataViewTag;
33869            case mapCtorString: return mapTag;
33870            case promiseCtorString: return promiseTag;
33871            case setCtorString: return setTag;
33872            case weakMapCtorString: return weakMapTag;
33873          }
33874        }
33875        return result;
33876      };
33877    }
33878
33879    /**
33880     * Gets the view, applying any `transforms` to the `start` and `end` positions.
33881     *
33882     * @private
33883     * @param {number} start The start of the view.
33884     * @param {number} end The end of the view.
33885     * @param {Array} transforms The transformations to apply to the view.
33886     * @returns {Object}
vendor: 6,432 bytes, lines 33886-34091
33886 Returns an object containing the `start` and `end`
33887     *  positions of the view.
33888     */
33889    function getView(start, end, transforms) {
33890      var index = -1,
33891          length = transforms.length;
33892
33893      while (++index < length) {
33894        var data = transforms[index],
33895            size = data.size;
33896
33897        switch (data.type) {
33898          case 'drop':      start += size; break;
33899          case 'dropRight': end -= size; break;
33900          case 'take':      end = nativeMin(end, start + size); break;
33901          case 'takeRight': start = nativeMax(start, end - size); break;
33902        }
33903      }
33904      return { 'start': start, 'end': end };
33905    }
33906
33907    /**
33908     * Extracts wrapper details from the `source` body comment.
33909     *
33910     * @private
33911     * @param {string} source The source to inspect.
33912     * @returns {Array} Returns the wrapper details.
33913     */
33914    function getWrapDetails(source) {
33915      var match = source.match(reWrapDetails);
33916      return match ? match[1].split(reSplitDetails) : [];
33917    }
33918
33919    /**
33920     * Checks if `path` exists on `object`.
33921     *
33922     * @private
33923     * @param {Object} object The object to query.
33924     * @param {Array|string} path The path to check.
33925     * @param {Function} hasFunc The function to check properties.
33926     * @returns {boolean} Returns `true` if `path` exists, else `false`.
33927     */
33928    function hasPath(object, path, hasFunc) {
33929      path = castPath(path, object);
33930
33931      var index = -1,
33932          length = path.length,
33933          result = false;
33934
33935      while (++index < length) {
33936        var key = toKey(path[index]);
33937        if (!(result = object != null && hasFunc(object, key))) {
33938          break;
33939        }
33940        object = object[key];
33941      }
33942      if (result || ++index != length) {
33943        return result;
33944      }
33945      length = object == null ? 0 : object.length;
33946      return !!length && isLength(length) && isIndex(key, length) &&
33947        (isArray(object) || isArguments(object));
33948    }
33949
33950    /**
33951     * Initializes an array clone.
33952     *
33953     * @private
33954     * @param {Array} array The array to clone.
33955     * @returns {Array} Returns the initialized clone.
33956     */
33957    function initCloneArray(array) {
33958      var length = array.length,
33959          result = new array.constructor(length);
33960
33961      // Add properties assigned by `RegExp#exec`.
33962      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
33963        result.index = array.index;
33964        result.input = array.input;
33965      }
33966      return result;
33967    }
33968
33969    /**
33970     * Initializes an object clone.
33971     *
33972     * @private
33973     * @param {Object} object The object to clone.
33974     * @returns {Object} Returns the initialized clone.
33975     */
33976    function initCloneObject(object) {
33977      return (typeof object.constructor == 'function' && !isPrototype(object))
33978        ? baseCreate(getPrototype(object))
33979        : {};
33980    }
33981
33982    /**
33983     * Initializes an object clone based on its `toStringTag`.
33984     *
33985     * **Note:** This function only supports cloning values with tags of
33986     * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
33987     *
33988     * @private
33989     * @param {Object} object The object to clone.
33990     * @param {string} tag The `toStringTag` of the object to clone.
33991     * @param {boolean} [isDeep] Specify a deep clone.
33992     * @returns {Object} Returns the initialized clone.
33993     */
33994    function initCloneByTag(object, tag, isDeep) {
33995      var Ctor = object.constructor;
33996      switch (tag) {
33997        case arrayBufferTag:
33998          return cloneArrayBuffer(object);
33999
34000        case boolTag:
34001        case dateTag:
34002          return new Ctor(+object);
34003
34004        case dataViewTag:
34005          return cloneDataView(object, isDeep);
34006
34007        case float32Tag: case float64Tag:
34008        case int8Tag: case int16Tag: case int32Tag:
34009        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
34010          return cloneTypedArray(object, isDeep);
34011
34012        case mapTag:
34013          return new Ctor;
34014
34015        case numberTag:
34016        case stringTag:
34017          return new Ctor(object);
34018
34019        case regexpTag:
34020          return cloneRegExp(object);
34021
34022        case setTag:
34023          return new Ctor;
34024
34025        case symbolTag:
34026          return cloneSymbol(object);
34027      }
34028    }
34029
34030    /**
34031     * Inserts wrapper `details` in a comment at the top of the `source` body.
34032     *
34033     * @private
34034     * @param {string} source The source to modify.
34035     * @returns {Array} details The details to insert.
34036     * @returns {string} Returns the modified source.
34037     */
34038    function insertWrapDetails(source, details) {
34039      var length = details.length;
34040      if (!length) {
34041        return source;
34042      }
34043      var lastIndex = length - 1;
34044      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
34045      details = details.join(length > 2 ? ', ' : ' ');
34046      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
34047    }
34048
34049    /**
34050     * Checks if `value` is a flattenable `arguments` object or array.
34051     *
34052     * @private
34053     * @param {*} value The value to check.
34054     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
34055     */
34056    function isFlattenable(value) {
34057      return isArray(value) || isArguments(value) ||
34058        !!(spreadableSymbol && value && value[spreadableSymbol]);
34059    }
34060
34061    /**
34062     * Checks if `value` is a valid array-like index.
34063     *
34064     * @private
34065     * @param {*} value The value to check.
34066     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
34067     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
34068     */
34069    function isIndex(value, length) {
34070      var type = typeof value;
34071      length = length == null ? MAX_SAFE_INTEGER : length;
34072
34073      return !!length &&
34074        (type == 'number' ||
34075          (type != 'symbol' && reIsUint.test(value))) &&
34076            (value > -1 && value % 1 == 0 && value < length);
34077    }
34078
34079    /**
34080     * Checks if the given arguments are from an iteratee call.
34081     *
34082     * @private
34083     * @param {*} value The potential iteratee value argument.
34084     * @param {*} index The potential iteratee index or key argument.
34085     * @param {*} object The potential iteratee object argument.
34086     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
34087     *  else `false`.
34088     */
34089    function isIterateeCall(value, index, object) {
34090      if (!isObject(object)) {
34091        return false;
vendor: 14,387 bytes, lines 34092-34538
34092      }
34093      var type = typeof index;
34094      if (type == 'number'
34095            ? (isArrayLike(object) && isIndex(index, object.length))
34096            : (type == 'string' && index in object)
34097          ) {
34098        return eq(object[index], value);
34099      }
34100      return false;
34101    }
34102
34103    /**
34104     * Checks if `value` is a property name and not a property path.
34105     *
34106     * @private
34107     * @param {*} value The value to check.
34108     * @param {Object} [object] The object to query keys on.
34109     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
34110     */
34111    function isKey(value, object) {
34112      if (isArray(value)) {
34113        return false;
34114      }
34115      var type = typeof value;
34116      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
34117          value == null || isSymbol(value)) {
34118        return true;
34119      }
34120      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
34121        (object != null && value in Object(object));
34122    }
34123
34124    /**
34125     * Checks if `value` is suitable for use as unique object key.
34126     *
34127     * @private
34128     * @param {*} value The value to check.
34129     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
34130     */
34131    function isKeyable(value) {
34132      var type = typeof value;
34133      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
34134        ? (value !== '__proto__')
34135        : (value === null);
34136    }
34137
34138    /**
34139     * Checks if `func` has a lazy counterpart.
34140     *
34141     * @private
34142     * @param {Function} func The function to check.
34143     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
34144     *  else `false`.
34145     */
34146    function isLaziable(func) {
34147      var funcName = getFuncName(func),
34148          other = lodash[funcName];
34149
34150      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
34151        return false;
34152      }
34153      if (func === other) {
34154        return true;
34155      }
34156      var data = getData(other);
34157      return !!data && func === data[0];
34158    }
34159
34160    /**
34161     * Checks if `func` has its source masked.
34162     *
34163     * @private
34164     * @param {Function} func The function to check.
34165     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
34166     */
34167    function isMasked(func) {
34168      return !!maskSrcKey && (maskSrcKey in func);
34169    }
34170
34171    /**
34172     * Checks if `func` is capable of being masked.
34173     *
34174     * @private
34175     * @param {*} value The value to check.
34176     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
34177     */
34178    var isMaskable = coreJsData ? isFunction : stubFalse;
34179
34180    /**
34181     * Checks if `value` is likely a prototype object.
34182     *
34183     * @private
34184     * @param {*} value The value to check.
34185     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
34186     */
34187    function isPrototype(value) {
34188      var Ctor = value && value.constructor,
34189          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
34190
34191      return value === proto;
34192    }
34193
34194    /**
34195     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
34196     *
34197     * @private
34198     * @param {*} value The value to check.
34199     * @returns {boolean} Returns `true` if `value` if suitable for strict
34200     *  equality comparisons, else `false`.
34201     */
34202    function isStrictComparable(value) {
34203      return value === value && !isObject(value);
34204    }
34205
34206    /**
34207     * A specialized version of `matchesProperty` for source values suitable
34208     * for strict equality comparisons, i.e. `===`.
34209     *
34210     * @private
34211     * @param {string} key The key of the property to get.
34212     * @param {*} srcValue The value to match.
34213     * @returns {Function} Returns the new spec function.
34214     */
34215    function matchesStrictComparable(key, srcValue) {
34216      return function(object) {
34217        if (object == null) {
34218          return false;
34219        }
34220        return object[key] === srcValue &&
34221          (srcValue !== undefined || (key in Object(object)));
34222      };
34223    }
34224
34225    /**
34226     * A specialized version of `_.memoize` which clears the memoized function's
34227     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
34228     *
34229     * @private
34230     * @param {Function} func The function to have its output memoized.
34231     * @returns {Function} Returns the new memoized function.
34232     */
34233    function memoizeCapped(func) {
34234      var result = memoize(func, function(key) {
34235        if (cache.size === MAX_MEMOIZE_SIZE) {
34236          cache.clear();
34237        }
34238        return key;
34239      });
34240
34241      var cache = result.cache;
34242      return result;
34243    }
34244
34245    /**
34246     * Merges the function metadata of `source` into `data`.
34247     *
34248     * Merging metadata reduces the number of wrappers used to invoke a function.
34249     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
34250     * may be applied regardless of execution order. Methods like `_.ary` and
34251     * `_.rearg` modify function arguments, making the order in which they are
34252     * executed important, preventing the merging of metadata. However, we make
34253     * an exception for a safe combined case where curried functions have `_.ary`
34254     * and or `_.rearg` applied.
34255     *
34256     * @private
34257     * @param {Array} data The destination metadata.
34258     * @param {Array} source The source metadata.
34259     * @returns {Array} Returns `data`.
34260     */
34261    function mergeData(data, source) {
34262      var bitmask = data[1],
34263          srcBitmask = source[1],
34264          newBitmask = bitmask | srcBitmask,
34265          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
34266
34267      var isCombo =
34268        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
34269        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
34270        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
34271
34272      // Exit early if metadata can't be merged.
34273      if (!(isCommon || isCombo)) {
34274        return data;
34275      }
34276      // Use source `thisArg` if available.
34277      if (srcBitmask & WRAP_BIND_FLAG) {
34278        data[2] = source[2];
34279        // Set when currying a bound function.
34280        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
34281      }
34282      // Compose partial arguments.
34283      var value = source[3];
34284      if (value) {
34285        var partials = data[3];
34286        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
34287        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
34288      }
34289      // Compose partial right arguments.
34290      value = source[5];
34291      if (value) {
34292        partials = data[5];
34293        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
34294        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
34295      }
34296      // Use source `argPos` if available.
34297      value = source[7];
34298      if (value) {
34299        data[7] = value;
34300      }
34301      // Use source `ary` if it's smaller.
34302      if (srcBitmask & WRAP_ARY_FLAG) {
34303        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
34304      }
34305      // Use source `arity` if one is not provided.
34306      if (data[9] == null) {
34307        data[9] = source[9];
34308      }
34309      // Use source `func` and merge bitmasks.
34310      data[0] = source[0];
34311      data[1] = newBitmask;
34312
34313      return data;
34314    }
34315
34316    /**
34317     * This function is like
34318     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
34319     * except that it includes inherited enumerable properties.
34320     *
34321     * @private
34322     * @param {Object} object The object to query.
34323     * @returns {Array} Returns the array of property names.
34324     */
34325    function nativeKeysIn(object) {
34326      var result = [];
34327      if (object != null) {
34328        for (var key in Object(object)) {
34329          result.push(key);
34330        }
34331      }
34332      return result;
34333    }
34334
34335    /**
34336     * Converts `value` to a string using `Object.prototype.toString`.
34337     *
34338     * @private
34339     * @param {*} value The value to convert.
34340     * @returns {string} Returns the converted string.
34341     */
34342    function objectToString(value) {
34343      return nativeObjectToString.call(value);
34344    }
34345
34346    /**
34347     * A specialized version of `baseRest` which transforms the rest array.
34348     *
34349     * @private
34350     * @param {Function} func The function to apply a rest parameter to.
34351     * @param {number} [start=func.length-1] The start position of the rest parameter.
34352     * @param {Function} transform The rest array transform.
34353     * @returns {Function} Returns the new function.
34354     */
34355    function overRest(func, start, transform) {
34356      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
34357      return function() {
34358        var args = arguments,
34359            index = -1,
34360            length = nativeMax(args.length - start, 0),
34361            array = Array(length);
34362
34363        while (++index < length) {
34364          array[index] = args[start + index];
34365        }
34366        index = -1;
34367        var otherArgs = Array(start + 1);
34368        while (++index < start) {
34369          otherArgs[index] = args[index];
34370        }
34371        otherArgs[start] = transform(array);
34372        return apply(func, this, otherArgs);
34373      };
34374    }
34375
34376    /**
34377     * Gets the parent value at `path` of `object`.
34378     *
34379     * @private
34380     * @param {Object} object The object to query.
34381     * @param {Array} path The path to get the parent value of.
34382     * @returns {*} Returns the parent value.
34383     */
34384    function parent(object, path) {
34385      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
34386    }
34387
34388    /**
34389     * Reorder `array` according to the specified indexes where the element at
34390     * the first index is assigned as the first element, the element at
34391     * the second index is assigned as the second element, and so on.
34392     *
34393     * @private
34394     * @param {Array} array The array to reorder.
34395     * @param {Array} indexes The arranged array indexes.
34396     * @returns {Array} Returns `array`.
34397     */
34398    function reorder(array, indexes) {
34399      var arrLength = array.length,
34400          length = nativeMin(indexes.length, arrLength),
34401          oldArray = copyArray(array);
34402
34403      while (length--) {
34404        var index = indexes[length];
34405        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
34406      }
34407      return array;
34408    }
34409
34410    /**
34411     * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
34412     *
34413     * @private
34414     * @param {Object} object The object to query.
34415     * @param {string} key The key of the property to get.
34416     * @returns {*} Returns the property value.
34417     */
34418    function safeGet(object, key) {
34419      if (key === 'constructor' && typeof object[key] === 'function') {
34420        return;
34421      }
34422
34423      if (key == '__proto__') {
34424        return;
34425      }
34426
34427      return object[key];
34428    }
34429
34430    /**
34431     * Sets metadata for `func`.
34432     *
34433     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
34434     * period of time, it will trip its breaker and transition to an identity
34435     * function to avoid garbage collection pauses in V8. See
34436     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
34437     * for more details.
34438     *
34439     * @private
34440     * @param {Function} func The function to associate metadata with.
34441     * @param {*} data The metadata.
34442     * @returns {Function} Returns `func`.
34443     */
34444    var setData = shortOut(baseSetData);
34445
34446    /**
34447     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
34448     *
34449     * @private
34450     * @param {Function} func The function to delay.
34451     * @param {number} wait The number of milliseconds to delay invocation.
34452     * @returns {number|Object} Returns the timer id or timeout object.
34453     */
34454    var setTimeout = ctxSetTimeout || function(func, wait) {
34455      return root.setTimeout(func, wait);
34456    };
34457
34458    /**
34459     * Sets the `toString` method of `func` to return `string`.
34460     *
34461     * @private
34462     * @param {Function} func The function to modify.
34463     * @param {Function} string The `toString` result.
34464     * @returns {Function} Returns `func`.
34465     */
34466    var setToString = shortOut(baseSetToString);
34467
34468    /**
34469     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
34470     * with wrapper details in a comment at the top of the source body.
34471     *
34472     * @private
34473     * @param {Function} wrapper The function to modify.
34474     * @param {Function} reference The reference function.
34475     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
34476     * @returns {Function} Returns `wrapper`.
34477     */
34478    function setWrapToString(wrapper, reference, bitmask) {
34479      var source = (reference + '');
34480      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
34481    }
34482
34483    /**
34484     * Creates a function that'll short out and invoke `identity` instead
34485     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
34486     * milliseconds.
34487     *
34488     * @private
34489     * @param {Function} func The function to restrict.
34490     * @returns {Function} Returns the new shortable function.
34491     */
34492    function shortOut(func) {
34493      var count = 0,
34494          lastCalled = 0;
34495
34496      return function() {
34497        var stamp = nativeNow(),
34498            remaining = HOT_SPAN - (stamp - lastCalled);
34499
34500        lastCalled = stamp;
34501        if (remaining > 0) {
34502          if (++count >= HOT_COUNT) {
34503            return arguments[0];
34504          }
34505        } else {
34506          count = 0;
34507        }
34508        return func.apply(undefined, arguments);
34509      };
34510    }
34511
34512    /**
34513     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
34514     *
34515     * @private
34516     * @param {Array} array The array to shuffle.
34517     * @param {number} [size=array.length] The size of `array`.
34518     * @returns {Array} Returns `array`.
34519     */
34520    function shuffleSelf(array, size) {
34521      var index = -1,
34522          length = array.length,
34523          lastIndex = length - 1;
34524
34525      size = size === undefined ? length : size;
34526      while (++index < size) {
34527        var rand = baseRandom(index, lastIndex),
34528            value = array[rand];
34529
34530        array[rand] = array[index];
34531        array[index] = value;
34532      }
34533      array.length = size;
34534      return array;
34535    }
34536
34537    /**
34538     * Converts `string` to a property path array.
vendor: 1,775 bytes, lines 34539-34599
34539     *
34540     * @private
34541     * @param {string} string The string to convert.
34542     * @returns {Array} Returns the property path array.
34543     */
34544    var stringToPath = memoizeCapped(function(string) {
34545      var result = [];
34546      if (string.charCodeAt(0) === 46 /* . */) {
34547        result.push('');
34548      }
34549      string.replace(rePropName, function(match, number, quote, subString) {
34550        result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
34551      });
34552      return result;
34553    });
34554
34555    /**
34556     * Converts `value` to a string key if it's not a string or symbol.
34557     *
34558     * @private
34559     * @param {*} value The value to inspect.
34560     * @returns {string|symbol} Returns the key.
34561     */
34562    function toKey(value) {
34563      if (typeof value == 'string' || isSymbol(value)) {
34564        return value;
34565      }
34566      var result = (value + '');
34567      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
34568    }
34569
34570    /**
34571     * Converts `func` to its source code.
34572     *
34573     * @private
34574     * @param {Function} func The function to convert.
34575     * @returns {string} Returns the source code.
34576     */
34577    function toSource(func) {
34578      if (func != null) {
34579        try {
34580          return funcToString.call(func);
34581        } catch (e) {}
34582        try {
34583          return (func + '');
34584        } catch (e) {}
34585      }
34586      return '';
34587    }
34588
34589    /**
34590     * Updates wrapper `details` based on `bitmask` flags.
34591     *
34592     * @private
34593     * @returns {Array} details The details to modify.
34594     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
34595     * @returns {Array} Returns `details`.
34596     */
34597    function updateWrapDetails(details, bitmask) {
34598      arrayEach(wrapFlags, function(pair) {
34599        var value = '_.' + pair[0];
vendor: 80,381 bytes, lines 34600-37183
34600        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
34601          details.push(value);
34602        }
34603      });
34604      return details.sort();
34605    }
34606
34607    /**
34608     * Creates a clone of `wrapper`.
34609     *
34610     * @private
34611     * @param {Object} wrapper The wrapper to clone.
34612     * @returns {Object} Returns the cloned wrapper.
34613     */
34614    function wrapperClone(wrapper) {
34615      if (wrapper instanceof LazyWrapper) {
34616        return wrapper.clone();
34617      }
34618      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
34619      result.__actions__ = copyArray(wrapper.__actions__);
34620      result.__index__  = wrapper.__index__;
34621      result.__values__ = wrapper.__values__;
34622      return result;
34623    }
34624
34625    /*------------------------------------------------------------------------*/
34626
34627    /**
34628     * Creates an array of elements split into groups the length of `size`.
34629     * If `array` can't be split evenly, the final chunk will be the remaining
34630     * elements.
34631     *
34632     * @static
34633     * @memberOf _
34634     * @since 3.0.0
34635     * @category Array
34636     * @param {Array} array The array to process.
34637     * @param {number} [size=1] The length of each chunk
34638     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
34639     * @returns {Array} Returns the new array of chunks.
34640     * @example
34641     *
34642     * _.chunk(['a', 'b', 'c', 'd'], 2);
34643     * // => [['a', 'b'], ['c', 'd']]
34644     *
34645     * _.chunk(['a', 'b', 'c', 'd'], 3);
34646     * // => [['a', 'b', 'c'], ['d']]
34647     */
34648    function chunk(array, size, guard) {
34649      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
34650        size = 1;
34651      } else {
34652        size = nativeMax(toInteger(size), 0);
34653      }
34654      var length = array == null ? 0 : array.length;
34655      if (!length || size < 1) {
34656        return [];
34657      }
34658      var index = 0,
34659          resIndex = 0,
34660          result = Array(nativeCeil(length / size));
34661
34662      while (index < length) {
34663        result[resIndex++] = baseSlice(array, index, (index += size));
34664      }
34665      return result;
34666    }
34667
34668    /**
34669     * Creates an array with all falsey values removed. The values `false`, `null`,
34670     * `0`, `""`, `undefined`, and `NaN` are falsey.
34671     *
34672     * @static
34673     * @memberOf _
34674     * @since 0.1.0
34675     * @category Array
34676     * @param {Array} array The array to compact.
34677     * @returns {Array} Returns the new array of filtered values.
34678     * @example
34679     *
34680     * _.compact([0, 1, false, 2, '', 3]);
34681     * // => [1, 2, 3]
34682     */
34683    function compact(array) {
34684      var index = -1,
34685          length = array == null ? 0 : array.length,
34686          resIndex = 0,
34687          result = [];
34688
34689      while (++index < length) {
34690        var value = array[index];
34691        if (value) {
34692          result[resIndex++] = value;
34693        }
34694      }
34695      return result;
34696    }
34697
34698    /**
34699     * Creates a new array concatenating `array` with any additional arrays
34700     * and/or values.
34701     *
34702     * @static
34703     * @memberOf _
34704     * @since 4.0.0
34705     * @category Array
34706     * @param {Array} array The array to concatenate.
34707     * @param {...*} [values] The values to concatenate.
34708     * @returns {Array} Returns the new concatenated array.
34709     * @example
34710     *
34711     * var array = [1];
34712     * var other = _.concat(array, 2, [3], [[4]]);
34713     *
34714     * console.log(other);
34715     * // => [1, 2, 3, [4]]
34716     *
34717     * console.log(array);
34718     * // => [1]
34719     */
34720    function concat() {
34721      var length = arguments.length;
34722      if (!length) {
34723        return [];
34724      }
34725      var args = Array(length - 1),
34726          array = arguments[0],
34727          index = length;
34728
34729      while (index--) {
34730        args[index - 1] = arguments[index];
34731      }
34732      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
34733    }
34734
34735    /**
34736     * Creates an array of `array` values not included in the other given arrays
34737     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
34738     * for equality comparisons. The order and references of result values are
34739     * determined by the first array.
34740     *
34741     * **Note:** Unlike `_.pullAll`, this method returns a new array.
34742     *
34743     * @static
34744     * @memberOf _
34745     * @since 0.1.0
34746     * @category Array
34747     * @param {Array} array The array to inspect.
34748     * @param {...Array} [values] The values to exclude.
34749     * @returns {Array} Returns the new array of filtered values.
34750     * @see _.without, _.xor
34751     * @example
34752     *
34753     * _.difference([2, 1], [2, 3]);
34754     * // => [1]
34755     */
34756    var difference = baseRest(function(array, values) {
34757      return isArrayLikeObject(array)
34758        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
34759        : [];
34760    });
34761
34762    /**
34763     * This method is like `_.difference` except that it accepts `iteratee` which
34764     * is invoked for each element of `array` and `values` to generate the criterion
34765     * by which they're compared. The order and references of result values are
34766     * determined by the first array. The iteratee is invoked with one argument:
34767     * (value).
34768     *
34769     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
34770     *
34771     * @static
34772     * @memberOf _
34773     * @since 4.0.0
34774     * @category Array
34775     * @param {Array} array The array to inspect.
34776     * @param {...Array} [values] The values to exclude.
34777     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
34778     * @returns {Array} Returns the new array of filtered values.
34779     * @example
34780     *
34781     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
34782     * // => [1.2]
34783     *
34784     * // The `_.property` iteratee shorthand.
34785     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
34786     * // => [{ 'x': 2 }]
34787     */
34788    var differenceBy = baseRest(function(array, values) {
34789      var iteratee = last(values);
34790      if (isArrayLikeObject(iteratee)) {
34791        iteratee = undefined;
34792      }
34793      return isArrayLikeObject(array)
34794        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
34795        : [];
34796    });
34797
34798    /**
34799     * This method is like `_.difference` except that it accepts `comparator`
34800     * which is invoked to compare elements of `array` to `values`. The order and
34801     * references of result values are determined by the first array. The comparator
34802     * is invoked with two arguments: (arrVal, othVal).
34803     *
34804     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
34805     *
34806     * @static
34807     * @memberOf _
34808     * @since 4.0.0
34809     * @category Array
34810     * @param {Array} array The array to inspect.
34811     * @param {...Array} [values] The values to exclude.
34812     * @param {Function} [comparator] The comparator invoked per element.
34813     * @returns {Array} Returns the new array of filtered values.
34814     * @example
34815     *
34816     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
34817     *
34818     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
34819     * // => [{ 'x': 2, 'y': 1 }]
34820     */
34821    var differenceWith = baseRest(function(array, values) {
34822      var comparator = last(values);
34823      if (isArrayLikeObject(comparator)) {
34824        comparator = undefined;
34825      }
34826      return isArrayLikeObject(array)
34827        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
34828        : [];
34829    });
34830
34831    /**
34832     * Creates a slice of `array` with `n` elements dropped from the beginning.
34833     *
34834     * @static
34835     * @memberOf _
34836     * @since 0.5.0
34837     * @category Array
34838     * @param {Array} array The array to query.
34839     * @param {number} [n=1] The number of elements to drop.
34840     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
34841     * @returns {Array} Returns the slice of `array`.
34842     * @example
34843     *
34844     * _.drop([1, 2, 3]);
34845     * // => [2, 3]
34846     *
34847     * _.drop([1, 2, 3], 2);
34848     * // => [3]
34849     *
34850     * _.drop([1, 2, 3], 5);
34851     * // => []
34852     *
34853     * _.drop([1, 2, 3], 0);
34854     * // => [1, 2, 3]
34855     */
34856    function drop(array, n, guard) {
34857      var length = array == null ? 0 : array.length;
34858      if (!length) {
34859        return [];
34860      }
34861      n = (guard || n === undefined) ? 1 : toInteger(n);
34862      return baseSlice(array, n < 0 ? 0 : n, length);
34863    }
34864
34865    /**
34866     * Creates a slice of `array` with `n` elements dropped from the end.
34867     *
34868     * @static
34869     * @memberOf _
34870     * @since 3.0.0
34871     * @category Array
34872     * @param {Array} array The array to query.
34873     * @param {number} [n=1] The number of elements to drop.
34874     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
34875     * @returns {Array} Returns the slice of `array`.
34876     * @example
34877     *
34878     * _.dropRight([1, 2, 3]);
34879     * // => [1, 2]
34880     *
34881     * _.dropRight([1, 2, 3], 2);
34882     * // => [1]
34883     *
34884     * _.dropRight([1, 2, 3], 5);
34885     * // => []
34886     *
34887     * _.dropRight([1, 2, 3], 0);
34888     * // => [1, 2, 3]
34889     */
34890    function dropRight(array, n, guard) {
34891      var length = array == null ? 0 : array.length;
34892      if (!length) {
34893        return [];
34894      }
34895      n = (guard || n === undefined) ? 1 : toInteger(n);
34896      n = length - n;
34897      return baseSlice(array, 0, n < 0 ? 0 : n);
34898    }
34899
34900    /**
34901     * Creates a slice of `array` excluding elements dropped from the end.
34902     * Elements are dropped until `predicate` returns falsey. The predicate is
34903     * invoked with three arguments: (value, index, array).
34904     *
34905     * @static
34906     * @memberOf _
34907     * @since 3.0.0
34908     * @category Array
34909     * @param {Array} array The array to query.
34910     * @param {Function} [predicate=_.identity] The function invoked per iteration.
34911     * @returns {Array} Returns the slice of `array`.
34912     * @example
34913     *
34914     * var users = [
34915     *   { 'user': 'barney',  'active': true },
34916     *   { 'user': 'fred',    'active': false },
34917     *   { 'user': 'pebbles', 'active': false }
34918     * ];
34919     *
34920     * _.dropRightWhile(users, function(o) { return !o.active; });
34921     * // => objects for ['barney']
34922     *
34923     * // The `_.matches` iteratee shorthand.
34924     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
34925     * // => objects for ['barney', 'fred']
34926     *
34927     * // The `_.matchesProperty` iteratee shorthand.
34928     * _.dropRightWhile(users, ['active', false]);
34929     * // => objects for ['barney']
34930     *
34931     * // The `_.property` iteratee shorthand.
34932     * _.dropRightWhile(users, 'active');
34933     * // => objects for ['barney', 'fred', 'pebbles']
34934     */
34935    function dropRightWhile(array, predicate) {
34936      return (array && array.length)
34937        ? baseWhile(array, getIteratee(predicate, 3), true, true)
34938        : [];
34939    }
34940
34941    /**
34942     * Creates a slice of `array` excluding elements dropped from the beginning.
34943     * Elements are dropped until `predicate` returns falsey. The predicate is
34944     * invoked with three arguments: (value, index, array).
34945     *
34946     * @static
34947     * @memberOf _
34948     * @since 3.0.0
34949     * @category Array
34950     * @param {Array} array The array to query.
34951     * @param {Function} [predicate=_.identity] The function invoked per iteration.
34952     * @returns {Array} Returns the slice of `array`.
34953     * @example
34954     *
34955     * var users = [
34956     *   { 'user': 'barney',  'active': false },
34957     *   { 'user': 'fred',    'active': false },
34958     *   { 'user': 'pebbles', 'active': true }
34959     * ];
34960     *
34961     * _.dropWhile(users, function(o) { return !o.active; });
34962     * // => objects for ['pebbles']
34963     *
34964     * // The `_.matches` iteratee shorthand.
34965     * _.dropWhile(users, { 'user': 'barney', 'active': false });
34966     * // => objects for ['fred', 'pebbles']
34967     *
34968     * // The `_.matchesProperty` iteratee shorthand.
34969     * _.dropWhile(users, ['active', false]);
34970     * // => objects for ['pebbles']
34971     *
34972     * // The `_.property` iteratee shorthand.
34973     * _.dropWhile(users, 'active');
34974     * // => objects for ['barney', 'fred', 'pebbles']
34975     */
34976    function dropWhile(array, predicate) {
34977      return (array && array.length)
34978        ? baseWhile(array, getIteratee(predicate, 3), true)
34979        : [];
34980    }
34981
34982    /**
34983     * Fills elements of `array` with `value` from `start` up to, but not
34984     * including, `end`.
34985     *
34986     * **Note:** This method mutates `array`.
34987     *
34988     * @static
34989     * @memberOf _
34990     * @since 3.2.0
34991     * @category Array
34992     * @param {Array} array The array to fill.
34993     * @param {*} value The value to fill `array` with.
34994     * @param {number} [start=0] The start position.
34995     * @param {number} [end=array.length] The end position.
34996     * @returns {Array} Returns `array`.
34997     * @example
34998     *
34999     * var array = [1, 2, 3];
35000     *
35001     * _.fill(array, 'a');
35002     * console.log(array);
35003     * // => ['a', 'a', 'a']
35004     *
35005     * _.fill(Array(3), 2);
35006     * // => [2, 2, 2]
35007     *
35008     * _.fill([4, 6, 8, 10], '*', 1, 3);
35009     * // => [4, '*', '*', 10]
35010     */
35011    function fill(array, value, start, end) {
35012      var length = array == null ? 0 : array.length;
35013      if (!length) {
35014        return [];
35015      }
35016      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
35017        start = 0;
35018        end = length;
35019      }
35020      return baseFill(array, value, start, end);
35021    }
35022
35023    /**
35024     * This method is like `_.find` except that it returns the index of the first
35025     * element `predicate` returns truthy for instead of the element itself.
35026     *
35027     * @static
35028     * @memberOf _
35029     * @since 1.1.0
35030     * @category Array
35031     * @param {Array} array The array to inspect.
35032     * @param {Function} [predicate=_.identity] The function invoked per iteration.
35033     * @param {number} [fromIndex=0] The index to search from.
35034     * @returns {number} Returns the index of the found element, else `-1`.
35035     * @example
35036     *
35037     * var users = [
35038     *   { 'user': 'barney',  'active': false },
35039     *   { 'user': 'fred',    'active': false },
35040     *   { 'user': 'pebbles', 'active': true }
35041     * ];
35042     *
35043     * _.findIndex(users, function(o) { return o.user == 'barney'; });
35044     * // => 0
35045     *
35046     * // The `_.matches` iteratee shorthand.
35047     * _.findIndex(users, { 'user': 'fred', 'active': false });
35048     * // => 1
35049     *
35050     * // The `_.matchesProperty` iteratee shorthand.
35051     * _.findIndex(users, ['active', false]);
35052     * // => 0
35053     *
35054     * // The `_.property` iteratee shorthand.
35055     * _.findIndex(users, 'active');
35056     * // => 2
35057     */
35058    function findIndex(array, predicate, fromIndex) {
35059      var length = array == null ? 0 : array.length;
35060      if (!length) {
35061        return -1;
35062      }
35063      var index = fromIndex == null ? 0 : toInteger(fromIndex);
35064      if (index < 0) {
35065        index = nativeMax(length + index, 0);
35066      }
35067      return baseFindIndex(array, getIteratee(predicate, 3), index);
35068    }
35069
35070    /**
35071     * This method is like `_.findIndex` except that it iterates over elements
35072     * of `collection` from right to left.
35073     *
35074     * @static
35075     * @memberOf _
35076     * @since 2.0.0
35077     * @category Array
35078     * @param {Array} array The array to inspect.
35079     * @param {Function} [predicate=_.identity] The function invoked per iteration.
35080     * @param {number} [fromIndex=array.length-1] The index to search from.
35081     * @returns {number} Returns the index of the found element, else `-1`.
35082     * @example
35083     *
35084     * var users = [
35085     *   { 'user': 'barney',  'active': true },
35086     *   { 'user': 'fred',    'active': false },
35087     *   { 'user': 'pebbles', 'active': false }
35088     * ];
35089     *
35090     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
35091     * // => 2
35092     *
35093     * // The `_.matches` iteratee shorthand.
35094     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
35095     * // => 0
35096     *
35097     * // The `_.matchesProperty` iteratee shorthand.
35098     * _.findLastIndex(users, ['active', false]);
35099     * // => 2
35100     *
35101     * // The `_.property` iteratee shorthand.
35102     * _.findLastIndex(users, 'active');
35103     * // => 0
35104     */
35105    function findLastIndex(array, predicate, fromIndex) {
35106      var length = array == null ? 0 : array.length;
35107      if (!length) {
35108        return -1;
35109      }
35110      var index = length - 1;
35111      if (fromIndex !== undefined) {
35112        index = toInteger(fromIndex);
35113        index = fromIndex < 0
35114          ? nativeMax(length + index, 0)
35115          : nativeMin(index, length - 1);
35116      }
35117      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
35118    }
35119
35120    /**
35121     * Flattens `array` a single level deep.
35122     *
35123     * @static
35124     * @memberOf _
35125     * @since 0.1.0
35126     * @category Array
35127     * @param {Array} array The array to flatten.
35128     * @returns {Array} Returns the new flattened array.
35129     * @example
35130     *
35131     * _.flatten([1, [2, [3, [4]], 5]]);
35132     * // => [1, 2, [3, [4]], 5]
35133     */
35134    function flatten(array) {
35135      var length = array == null ? 0 : array.length;
35136      return length ? baseFlatten(array, 1) : [];
35137    }
35138
35139    /**
35140     * Recursively flattens `array`.
35141     *
35142     * @static
35143     * @memberOf _
35144     * @since 3.0.0
35145     * @category Array
35146     * @param {Array} array The array to flatten.
35147     * @returns {Array} Returns the new flattened array.
35148     * @example
35149     *
35150     * _.flattenDeep([1, [2, [3, [4]], 5]]);
35151     * // => [1, 2, 3, 4, 5]
35152     */
35153    function flattenDeep(array) {
35154      var length = array == null ? 0 : array.length;
35155      return length ? baseFlatten(array, INFINITY) : [];
35156    }
35157
35158    /**
35159     * Recursively flatten `array` up to `depth` times.
35160     *
35161     * @static
35162     * @memberOf _
35163     * @since 4.4.0
35164     * @category Array
35165     * @param {Array} array The array to flatten.
35166     * @param {number} [depth=1] The maximum recursion depth.
35167     * @returns {Array} Returns the new flattened array.
35168     * @example
35169     *
35170     * var array = [1, [2, [3, [4]], 5]];
35171     *
35172     * _.flattenDepth(array, 1);
35173     * // => [1, 2, [3, [4]], 5]
35174     *
35175     * _.flattenDepth(array, 2);
35176     * // => [1, 2, 3, [4], 5]
35177     */
35178    function flattenDepth(array, depth) {
35179      var length = array == null ? 0 : array.length;
35180      if (!length) {
35181        return [];
35182      }
35183      depth = depth === undefined ? 1 : toInteger(depth);
35184      return baseFlatten(array, depth);
35185    }
35186
35187    /**
35188     * The inverse of `_.toPairs`; this method returns an object composed
35189     * from key-value `pairs`.
35190     *
35191     * @static
35192     * @memberOf _
35193     * @since 4.0.0
35194     * @category Array
35195     * @param {Array} pairs The key-value pairs.
35196     * @returns {Object} Returns the new object.
35197     * @example
35198     *
35199     * _.fromPairs([['a', 1], ['b', 2]]);
35200     * // => { 'a': 1, 'b': 2 }
35201     */
35202    function fromPairs(pairs) {
35203      var index = -1,
35204          length = pairs == null ? 0 : pairs.length,
35205          result = {};
35206
35207      while (++index < length) {
35208        var pair = pairs[index];
35209        result[pair[0]] = pair[1];
35210      }
35211      return result;
35212    }
35213
35214    /**
35215     * Gets the first element of `array`.
35216     *
35217     * @static
35218     * @memberOf _
35219     * @since 0.1.0
35220     * @alias first
35221     * @category Array
35222     * @param {Array} array The array to query.
35223     * @returns {*} Returns the first element of `array`.
35224     * @example
35225     *
35226     * _.head([1, 2, 3]);
35227     * // => 1
35228     *
35229     * _.head([]);
35230     * // => undefined
35231     */
35232    function head(array) {
35233      return (array && array.length) ? array[0] : undefined;
35234    }
35235
35236    /**
35237     * Gets the index at which the first occurrence of `value` is found in `array`
35238     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
35239     * for equality comparisons. If `fromIndex` is negative, it's used as the
35240     * offset from the end of `array`.
35241     *
35242     * @static
35243     * @memberOf _
35244     * @since 0.1.0
35245     * @category Array
35246     * @param {Array} array The array to inspect.
35247     * @param {*} value The value to search for.
35248     * @param {number} [fromIndex=0] The index to search from.
35249     * @returns {number} Returns the index of the matched value, else `-1`.
35250     * @example
35251     *
35252     * _.indexOf([1, 2, 1, 2], 2);
35253     * // => 1
35254     *
35255     * // Search from the `fromIndex`.
35256     * _.indexOf([1, 2, 1, 2], 2, 2);
35257     * // => 3
35258     */
35259    function indexOf(array, value, fromIndex) {
35260      var length = array == null ? 0 : array.length;
35261      if (!length) {
35262        return -1;
35263      }
35264      var index = fromIndex == null ? 0 : toInteger(fromIndex);
35265      if (index < 0) {
35266        index = nativeMax(length + index, 0);
35267      }
35268      return baseIndexOf(array, value, index);
35269    }
35270
35271    /**
35272     * Gets all but the last element of `array`.
35273     *
35274     * @static
35275     * @memberOf _
35276     * @since 0.1.0
35277     * @category Array
35278     * @param {Array} array The array to query.
35279     * @returns {Array} Returns the slice of `array`.
35280     * @example
35281     *
35282     * _.initial([1, 2, 3]);
35283     * // => [1, 2]
35284     */
35285    function initial(array) {
35286      var length = array == null ? 0 : array.length;
35287      return length ? baseSlice(array, 0, -1) : [];
35288    }
35289
35290    /**
35291     * Creates an array of unique values that are included in all given arrays
35292     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
35293     * for equality comparisons. The order and references of result values are
35294     * determined by the first array.
35295     *
35296     * @static
35297     * @memberOf _
35298     * @since 0.1.0
35299     * @category Array
35300     * @param {...Array} [arrays] The arrays to inspect.
35301     * @returns {Array} Returns the new array of intersecting values.
35302     * @example
35303     *
35304     * _.intersection([2, 1], [2, 3]);
35305     * // => [2]
35306     */
35307    var intersection = baseRest(function(arrays) {
35308      var mapped = arrayMap(arrays, castArrayLikeObject);
35309      return (mapped.length && mapped[0] === arrays[0])
35310        ? baseIntersection(mapped)
35311        : [];
35312    });
35313
35314    /**
35315     * This method is like `_.intersection` except that it accepts `iteratee`
35316     * which is invoked for each element of each `arrays` to generate the criterion
35317     * by which they're compared. The order and references of result values are
35318     * determined by the first array. The iteratee is invoked with one argument:
35319     * (value).
35320     *
35321     * @static
35322     * @memberOf _
35323     * @since 4.0.0
35324     * @category Array
35325     * @param {...Array} [arrays] The arrays to inspect.
35326     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
35327     * @returns {Array} Returns the new array of intersecting values.
35328     * @example
35329     *
35330     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
35331     * // => [2.1]
35332     *
35333     * // The `_.property` iteratee shorthand.
35334     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
35335     * // => [{ 'x': 1 }]
35336     */
35337    var intersectionBy = baseRest(function(arrays) {
35338      var iteratee = last(arrays),
35339          mapped = arrayMap(arrays, castArrayLikeObject);
35340
35341      if (iteratee === last(mapped)) {
35342        iteratee = undefined;
35343      } else {
35344        mapped.pop();
35345      }
35346      return (mapped.length && mapped[0] === arrays[0])
35347        ? baseIntersection(mapped, getIteratee(iteratee, 2))
35348        : [];
35349    });
35350
35351    /**
35352     * This method is like `_.intersection` except that it accepts `comparator`
35353     * which is invoked to compare elements of `arrays`. The order and references
35354     * of result values are determined by the first array. The comparator is
35355     * invoked with two arguments: (arrVal, othVal).
35356     *
35357     * @static
35358     * @memberOf _
35359     * @since 4.0.0
35360     * @category Array
35361     * @param {...Array} [arrays] The arrays to inspect.
35362     * @param {Function} [comparator] The comparator invoked per element.
35363     * @returns {Array} Returns the new array of intersecting values.
35364     * @example
35365     *
35366     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
35367     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
35368     *
35369     * _.intersectionWith(objects, others, _.isEqual);
35370     * // => [{ 'x': 1, 'y': 2 }]
35371     */
35372    var intersectionWith = baseRest(function(arrays) {
35373      var comparator = last(arrays),
35374          mapped = arrayMap(arrays, castArrayLikeObject);
35375
35376      comparator = typeof comparator == 'function' ? comparator : undefined;
35377      if (comparator) {
35378        mapped.pop();
35379      }
35380      return (mapped.length && mapped[0] === arrays[0])
35381        ? baseIntersection(mapped, undefined, comparator)
35382        : [];
35383    });
35384
35385    /**
35386     * Converts all elements in `array` into a string separated by `separator`.
35387     *
35388     * @static
35389     * @memberOf _
35390     * @since 4.0.0
35391     * @category Array
35392     * @param {Array} array The array to convert.
35393     * @param {string} [separator=','] The element separator.
35394     * @returns {string} Returns the joined string.
35395     * @example
35396     *
35397     * _.join(['a', 'b', 'c'], '~');
35398     * // => 'a~b~c'
35399     */
35400    function join(array, separator) {
35401      return array == null ? '' : nativeJoin.call(array, separator);
35402    }
35403
35404    /**
35405     * Gets the last element of `array`.
35406     *
35407     * @static
35408     * @memberOf _
35409     * @since 0.1.0
35410     * @category Array
35411     * @param {Array} array The array to query.
35412     * @returns {*} Returns the last element of `array`.
35413     * @example
35414     *
35415     * _.last([1, 2, 3]);
35416     * // => 3
35417     */
35418    function last(array) {
35419      var length = array == null ? 0 : array.length;
35420      return length ? array[length - 1] : undefined;
35421    }
35422
35423    /**
35424     * This method is like `_.indexOf` except that it iterates over elements of
35425     * `array` from right to left.
35426     *
35427     * @static
35428     * @memberOf _
35429     * @since 0.1.0
35430     * @category Array
35431     * @param {Array} array The array to inspect.
35432     * @param {*} value The value to search for.
35433     * @param {number} [fromIndex=array.length-1] The index to search from.
35434     * @returns {number} Returns the index of the matched value, else `-1`.
35435     * @example
35436     *
35437     * _.lastIndexOf([1, 2, 1, 2], 2);
35438     * // => 3
35439     *
35440     * // Search from the `fromIndex`.
35441     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
35442     * // => 1
35443     */
35444    function lastIndexOf(array, value, fromIndex) {
35445      var length = array == null ? 0 : array.length;
35446      if (!length) {
35447        return -1;
35448      }
35449      var index = length;
35450      if (fromIndex !== undefined) {
35451        index = toInteger(fromIndex);
35452        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
35453      }
35454      return value === value
35455        ? strictLastIndexOf(array, value, index)
35456        : baseFindIndex(array, baseIsNaN, index, true);
35457    }
35458
35459    /**
35460     * Gets the element at index `n` of `array`. If `n` is negative, the nth
35461     * element from the end is returned.
35462     *
35463     * @static
35464     * @memberOf _
35465     * @since 4.11.0
35466     * @category Array
35467     * @param {Array} array The array to query.
35468     * @param {number} [n=0] The index of the element to return.
35469     * @returns {*} Returns the nth element of `array`.
35470     * @example
35471     *
35472     * var array = ['a', 'b', 'c', 'd'];
35473     *
35474     * _.nth(array, 1);
35475     * // => 'b'
35476     *
35477     * _.nth(array, -2);
35478     * // => 'c';
35479     */
35480    function nth(array, n) {
35481      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
35482    }
35483
35484    /**
35485     * Removes all given values from `array` using
35486     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
35487     * for equality comparisons.
35488     *
35489     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
35490     * to remove elements from an array by predicate.
35491     *
35492     * @static
35493     * @memberOf _
35494     * @since 2.0.0
35495     * @category Array
35496     * @param {Array} array The array to modify.
35497     * @param {...*} [values] The values to remove.
35498     * @returns {Array} Returns `array`.
35499     * @example
35500     *
35501     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
35502     *
35503     * _.pull(array, 'a', 'c');
35504     * console.log(array);
35505     * // => ['b', 'b']
35506     */
35507    var pull = baseRest(pullAll);
35508
35509    /**
35510     * This method is like `_.pull` except that it accepts an array of values to remove.
35511     *
35512     * **Note:** Unlike `_.difference`, this method mutates `array`.
35513     *
35514     * @static
35515     * @memberOf _
35516     * @since 4.0.0
35517     * @category Array
35518     * @param {Array} array The array to modify.
35519     * @param {Array} values The values to remove.
35520     * @returns {Array} Returns `array`.
35521     * @example
35522     *
35523     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
35524     *
35525     * _.pullAll(array, ['a', 'c']);
35526     * console.log(array);
35527     * // => ['b', 'b']
35528     */
35529    function pullAll(array, values) {
35530      return (array && array.length && values && values.length)
35531        ? basePullAll(array, values)
35532        : array;
35533    }
35534
35535    /**
35536     * This method is like `_.pullAll` except that it accepts `iteratee` which is
35537     * invoked for each element of `array` and `values` to generate the criterion
35538     * by which they're compared. The iteratee is invoked with one argument: (value).
35539     *
35540     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
35541     *
35542     * @static
35543     * @memberOf _
35544     * @since 4.0.0
35545     * @category Array
35546     * @param {Array} array The array to modify.
35547     * @param {Array} values The values to remove.
35548     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
35549     * @returns {Array} Returns `array`.
35550     * @example
35551     *
35552     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
35553     *
35554     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
35555     * console.log(array);
35556     * // => [{ 'x': 2 }]
35557     */
35558    function pullAllBy(array, values, iteratee) {
35559      return (array && array.length && values && values.length)
35560        ? basePullAll(array, values, getIteratee(iteratee, 2))
35561        : array;
35562    }
35563
35564    /**
35565     * This method is like `_.pullAll` except that it accepts `comparator` which
35566     * is invoked to compare elements of `array` to `values`. The comparator is
35567     * invoked with two arguments: (arrVal, othVal).
35568     *
35569     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
35570     *
35571     * @static
35572     * @memberOf _
35573     * @since 4.6.0
35574     * @category Array
35575     * @param {Array} array The array to modify.
35576     * @param {Array} values The values to remove.
35577     * @param {Function} [comparator] The comparator invoked per element.
35578     * @returns {Array} Returns `array`.
35579     * @example
35580     *
35581     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
35582     *
35583     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
35584     * console.log(array);
35585     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
35586     */
35587    function pullAllWith(array, values, comparator) {
35588      return (array && array.length && values && values.length)
35589        ? basePullAll(array, values, undefined, comparator)
35590        : array;
35591    }
35592
35593    /**
35594     * Removes elements from `array` corresponding to `indexes` and returns an
35595     * array of removed elements.
35596     *
35597     * **Note:** Unlike `_.at`, this method mutates `array`.
35598     *
35599     * @static
35600     * @memberOf _
35601     * @since 3.0.0
35602     * @category Array
35603     * @param {Array} array The array to modify.
35604     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
35605     * @returns {Array} Returns the new array of removed elements.
35606     * @example
35607     *
35608     * var array = ['a', 'b', 'c', 'd'];
35609     * var pulled = _.pullAt(array, [1, 3]);
35610     *
35611     * console.log(array);
35612     * // => ['a', 'c']
35613     *
35614     * console.log(pulled);
35615     * // => ['b', 'd']
35616     */
35617    var pullAt = flatRest(function(array, indexes) {
35618      var length = array == null ? 0 : array.length,
35619          result = baseAt(array, indexes);
35620
35621      basePullAt(array, arrayMap(indexes, function(index) {
35622        return isIndex(index, length) ? +index : index;
35623      }).sort(compareAscending));
35624
35625      return result;
35626    });
35627
35628    /**
35629     * Removes all elements from `array` that `predicate` returns truthy for
35630     * and returns an array of the removed elements. The predicate is invoked
35631     * with three arguments: (value, index, array).
35632     *
35633     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
35634     * to pull elements from an array by value.
35635     *
35636     * @static
35637     * @memberOf _
35638     * @since 2.0.0
35639     * @category Array
35640     * @param {Array} array The array to modify.
35641     * @param {Function} [predicate=_.identity] The function invoked per iteration.
35642     * @returns {Array} Returns the new array of removed elements.
35643     * @example
35644     *
35645     * var array = [1, 2, 3, 4];
35646     * var evens = _.remove(array, function(n) {
35647     *   return n % 2 == 0;
35648     * });
35649     *
35650     * console.log(array);
35651     * // => [1, 3]
35652     *
35653     * console.log(evens);
35654     * // => [2, 4]
35655     */
35656    function remove(array, predicate) {
35657      var result = [];
35658      if (!(array && array.length)) {
35659        return result;
35660      }
35661      var index = -1,
35662          indexes = [],
35663          length = array.length;
35664
35665      predicate = getIteratee(predicate, 3);
35666      while (++index < length) {
35667        var value = array[index];
35668        if (predicate(value, index, array)) {
35669          result.push(value);
35670          indexes.push(index);
35671        }
35672      }
35673      basePullAt(array, indexes);
35674      return result;
35675    }
35676
35677    /**
35678     * Reverses `array` so that the first element becomes the last, the second
35679     * element becomes the second to last, and so on.
35680     *
35681     * **Note:** This method mutates `array` and is based on
35682     * [`Array#reverse`](https://mdn.io/Array/reverse).
35683     *
35684     * @static
35685     * @memberOf _
35686     * @since 4.0.0
35687     * @category Array
35688     * @param {Array} array The array to modify.
35689     * @returns {Array} Returns `array`.
35690     * @example
35691     *
35692     * var array = [1, 2, 3];
35693     *
35694     * _.reverse(array);
35695     * // => [3, 2, 1]
35696     *
35697     * console.log(array);
35698     * // => [3, 2, 1]
35699     */
35700    function reverse(array) {
35701      return array == null ? array : nativeReverse.call(array);
35702    }
35703
35704    /**
35705     * Creates a slice of `array` from `start` up to, but not including, `end`.
35706     *
35707     * **Note:** This method is used instead of
35708     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
35709     * returned.
35710     *
35711     * @static
35712     * @memberOf _
35713     * @since 3.0.0
35714     * @category Array
35715     * @param {Array} array The array to slice.
35716     * @param {number} [start=0] The start position.
35717     * @param {number} [end=array.length] The end position.
35718     * @returns {Array} Returns the slice of `array`.
35719     */
35720    function slice(array, start, end) {
35721      var length = array == null ? 0 : array.length;
35722      if (!length) {
35723        return [];
35724      }
35725      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
35726        start = 0;
35727        end = length;
35728      }
35729      else {
35730        start = start == null ? 0 : toInteger(start);
35731        end = end === undefined ? length : toInteger(end);
35732      }
35733      return baseSlice(array, start, end);
35734    }
35735
35736    /**
35737     * Uses a binary search to determine the lowest index at which `value`
35738     * should be inserted into `array` in order to maintain its sort order.
35739     *
35740     * @static
35741     * @memberOf _
35742     * @since 0.1.0
35743     * @category Array
35744     * @param {Array} array The sorted array to inspect.
35745     * @param {*} value The value to evaluate.
35746     * @returns {number} Returns the index at which `value` should be inserted
35747     *  into `array`.
35748     * @example
35749     *
35750     * _.sortedIndex([30, 50], 40);
35751     * // => 1
35752     */
35753    function sortedIndex(array, value) {
35754      return baseSortedIndex(array, value);
35755    }
35756
35757    /**
35758     * This method is like `_.sortedIndex` except that it accepts `iteratee`
35759     * which is invoked for `value` and each element of `array` to compute their
35760     * sort ranking. The iteratee is invoked with one argument: (value).
35761     *
35762     * @static
35763     * @memberOf _
35764     * @since 4.0.0
35765     * @category Array
35766     * @param {Array} array The sorted array to inspect.
35767     * @param {*} value The value to evaluate.
35768     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
35769     * @returns {number} Returns the index at which `value` should be inserted
35770     *  into `array`.
35771     * @example
35772     *
35773     * var objects = [{ 'x': 4 }, { 'x': 5 }];
35774     *
35775     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
35776     * // => 0
35777     *
35778     * // The `_.property` iteratee shorthand.
35779     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
35780     * // => 0
35781     */
35782    function sortedIndexBy(array, value, iteratee) {
35783      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
35784    }
35785
35786    /**
35787     * This method is like `_.indexOf` except that it performs a binary
35788     * search on a sorted `array`.
35789     *
35790     * @static
35791     * @memberOf _
35792     * @since 4.0.0
35793     * @category Array
35794     * @param {Array} array The array to inspect.
35795     * @param {*} value The value to search for.
35796     * @returns {number} Returns the index of the matched value, else `-1`.
35797     * @example
35798     *
35799     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
35800     * // => 1
35801     */
35802    function sortedIndexOf(array, value) {
35803      var length = array == null ? 0 : array.length;
35804      if (length) {
35805        var index = baseSortedIndex(array, value);
35806        if (index < length && eq(array[index], value)) {
35807          return index;
35808        }
35809      }
35810      return -1;
35811    }
35812
35813    /**
35814     * This method is like `_.sortedIndex` except that it returns the highest
35815     * index at which `value` should be inserted into `array` in order to
35816     * maintain its sort order.
35817     *
35818     * @static
35819     * @memberOf _
35820     * @since 3.0.0
35821     * @category Array
35822     * @param {Array} array The sorted array to inspect.
35823     * @param {*} value The value to evaluate.
35824     * @returns {number} Returns the index at which `value` should be inserted
35825     *  into `array`.
35826     * @example
35827     *
35828     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
35829     * // => 4
35830     */
35831    function sortedLastIndex(array, value) {
35832      return baseSortedIndex(array, value, true);
35833    }
35834
35835    /**
35836     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
35837     * which is invoked for `value` and each element of `array` to compute their
35838     * sort ranking. The iteratee is invoked with one argument: (value).
35839     *
35840     * @static
35841     * @memberOf _
35842     * @since 4.0.0
35843     * @category Array
35844     * @param {Array} array The sorted array to inspect.
35845     * @param {*} value The value to evaluate.
35846     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
35847     * @returns {number} Returns the index at which `value` should be inserted
35848     *  into `array`.
35849     * @example
35850     *
35851     * var objects = [{ 'x': 4 }, { 'x': 5 }];
35852     *
35853     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
35854     * // => 1
35855     *
35856     * // The `_.property` iteratee shorthand.
35857     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
35858     * // => 1
35859     */
35860    function sortedLastIndexBy(array, value, iteratee) {
35861      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
35862    }
35863
35864    /**
35865     * This method is like `_.lastIndexOf` except that it performs a binary
35866     * search on a sorted `array`.
35867     *
35868     * @static
35869     * @memberOf _
35870     * @since 4.0.0
35871     * @category Array
35872     * @param {Array} array The array to inspect.
35873     * @param {*} value The value to search for.
35874     * @returns {number} Returns the index of the matched value, else `-1`.
35875     * @example
35876     *
35877     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
35878     * // => 3
35879     */
35880    function sortedLastIndexOf(array, value) {
35881      var length = array == null ? 0 : array.length;
35882      if (length) {
35883        var index = baseSortedIndex(array, value, true) - 1;
35884        if (eq(array[index], value)) {
35885          return index;
35886        }
35887      }
35888      return -1;
35889    }
35890
35891    /**
35892     * This method is like `_.uniq` except that it's designed and optimized
35893     * for sorted arrays.
35894     *
35895     * @static
35896     * @memberOf _
35897     * @since 4.0.0
35898     * @category Array
35899     * @param {Array} array The array to inspect.
35900     * @returns {Array} Returns the new duplicate free array.
35901     * @example
35902     *
35903     * _.sortedUniq([1, 1, 2]);
35904     * // => [1, 2]
35905     */
35906    function sortedUniq(array) {
35907      return (array && array.length)
35908        ? baseSortedUniq(array)
35909        : [];
35910    }
35911
35912    /**
35913     * This method is like `_.uniqBy` except that it's designed and optimized
35914     * for sorted arrays.
35915     *
35916     * @static
35917     * @memberOf _
35918     * @since 4.0.0
35919     * @category Array
35920     * @param {Array} array The array to inspect.
35921     * @param {Function} [iteratee] The iteratee invoked per element.
35922     * @returns {Array} Returns the new duplicate free array.
35923     * @example
35924     *
35925     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
35926     * // => [1.1, 2.3]
35927     */
35928    function sortedUniqBy(array, iteratee) {
35929      return (array && array.length)
35930        ? baseSortedUniq(array, getIteratee(iteratee, 2))
35931        : [];
35932    }
35933
35934    /**
35935     * Gets all but the first element of `array`.
35936     *
35937     * @static
35938     * @memberOf _
35939     * @since 4.0.0
35940     * @category Array
35941     * @param {Array} array The array to query.
35942     * @returns {Array} Returns the slice of `array`.
35943     * @example
35944     *
35945     * _.tail([1, 2, 3]);
35946     * // => [2, 3]
35947     */
35948    function tail(array) {
35949      var length = array == null ? 0 : array.length;
35950      return length ? baseSlice(array, 1, length) : [];
35951    }
35952
35953    /**
35954     * Creates a slice of `array` with `n` elements taken from the beginning.
35955     *
35956     * @static
35957     * @memberOf _
35958     * @since 0.1.0
35959     * @category Array
35960     * @param {Array} array The array to query.
35961     * @param {number} [n=1] The number of elements to take.
35962     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35963     * @returns {Array} Returns the slice of `array`.
35964     * @example
35965     *
35966     * _.take([1, 2, 3]);
35967     * // => [1]
35968     *
35969     * _.take([1, 2, 3], 2);
35970     * // => [1, 2]
35971     *
35972     * _.take([1, 2, 3], 5);
35973     * // => [1, 2, 3]
35974     *
35975     * _.take([1, 2, 3], 0);
35976     * // => []
35977     */
35978    function take(array, n, guard) {
35979      if (!(array && array.length)) {
35980        return [];
35981      }
35982      n = (guard || n === undefined) ? 1 : toInteger(n);
35983      return baseSlice(array, 0, n < 0 ? 0 : n);
35984    }
35985
35986    /**
35987     * Creates a slice of `array` with `n` elements taken from the end.
35988     *
35989     * @static
35990     * @memberOf _
35991     * @since 3.0.0
35992     * @category Array
35993     * @param {Array} array The array to query.
35994     * @param {number} [n=1] The number of elements to take.
35995     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35996     * @returns {Array} Returns the slice of `array`.
35997     * @example
35998     *
35999     * _.takeRight([1, 2, 3]);
36000     * // => [3]
36001     *
36002     * _.takeRight([1, 2, 3], 2);
36003     * // => [2, 3]
36004     *
36005     * _.takeRight([1, 2, 3], 5);
36006     * // => [1, 2, 3]
36007     *
36008     * _.takeRight([1, 2, 3], 0);
36009     * // => []
36010     */
36011    function takeRight(array, n, guard) {
36012      var length = array == null ? 0 : array.length;
36013      if (!length) {
36014        return [];
36015      }
36016      n = (guard || n === undefined) ? 1 : toInteger(n);
36017      n = length - n;
36018      return baseSlice(array, n < 0 ? 0 : n, length);
36019    }
36020
36021    /**
36022     * Creates a slice of `array` with elements taken from the end. Elements are
36023     * taken until `predicate` returns falsey. The predicate is invoked with
36024     * three arguments: (value, index, array).
36025     *
36026     * @static
36027     * @memberOf _
36028     * @since 3.0.0
36029     * @category Array
36030     * @param {Array} array The array to query.
36031     * @param {Function} [predicate=_.identity] The function invoked per iteration.
36032     * @returns {Array} Returns the slice of `array`.
36033     * @example
36034     *
36035     * var users = [
36036     *   { 'user': 'barney',  'active': true },
36037     *   { 'user': 'fred',    'active': false },
36038     *   { 'user': 'pebbles', 'active': false }
36039     * ];
36040     *
36041     * _.takeRightWhile(users, function(o) { return !o.active; });
36042     * // => objects for ['fred', 'pebbles']
36043     *
36044     * // The `_.matches` iteratee shorthand.
36045     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
36046     * // => objects for ['pebbles']
36047     *
36048     * // The `_.matchesProperty` iteratee shorthand.
36049     * _.takeRightWhile(users, ['active', false]);
36050     * // => objects for ['fred', 'pebbles']
36051     *
36052     * // The `_.property` iteratee shorthand.
36053     * _.takeRightWhile(users, 'active');
36054     * // => []
36055     */
36056    function takeRightWhile(array, predicate) {
36057      return (array && array.length)
36058        ? baseWhile(array, getIteratee(predicate, 3), false, true)
36059        : [];
36060    }
36061
36062    /**
36063     * Creates a slice of `array` with elements taken from the beginning. Elements
36064     * are taken until `predicate` returns falsey. The predicate is invoked with
36065     * three arguments: (value, index, array).
36066     *
36067     * @static
36068     * @memberOf _
36069     * @since 3.0.0
36070     * @category Array
36071     * @param {Array} array The array to query.
36072     * @param {Function} [predicate=_.identity] The function invoked per iteration.
36073     * @returns {Array} Returns the slice of `array`.
36074     * @example
36075     *
36076     * var users = [
36077     *   { 'user': 'barney',  'active': false },
36078     *   { 'user': 'fred',    'active': false },
36079     *   { 'user': 'pebbles', 'active': true }
36080     * ];
36081     *
36082     * _.takeWhile(users, function(o) { return !o.active; });
36083     * // => objects for ['barney', 'fred']
36084     *
36085     * // The `_.matches` iteratee shorthand.
36086     * _.takeWhile(users, { 'user': 'barney', 'active': false });
36087     * // => objects for ['barney']
36088     *
36089     * // The `_.matchesProperty` iteratee shorthand.
36090     * _.takeWhile(users, ['active', false]);
36091     * // => objects for ['barney', 'fred']
36092     *
36093     * // The `_.property` iteratee shorthand.
36094     * _.takeWhile(users, 'active');
36095     * // => []
36096     */
36097    function takeWhile(array, predicate) {
36098      return (array && array.length)
36099        ? baseWhile(array, getIteratee(predicate, 3))
36100        : [];
36101    }
36102
36103    /**
36104     * Creates an array of unique values, in order, from all given arrays using
36105     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
36106     * for equality comparisons.
36107     *
36108     * @static
36109     * @memberOf _
36110     * @since 0.1.0
36111     * @category Array
36112     * @param {...Array} [arrays] The arrays to inspect.
36113     * @returns {Array} Returns the new array of combined values.
36114     * @example
36115     *
36116     * _.union([2], [1, 2]);
36117     * // => [2, 1]
36118     */
36119    var union = baseRest(function(arrays) {
36120      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
36121    });
36122
36123    /**
36124     * This method is like `_.union` except that it accepts `iteratee` which is
36125     * invoked for each element of each `arrays` to generate the criterion by
36126     * which uniqueness is computed. Result values are chosen from the first
36127     * array in which the value occurs. The iteratee is invoked with one argument:
36128     * (value).
36129     *
36130     * @static
36131     * @memberOf _
36132     * @since 4.0.0
36133     * @category Array
36134     * @param {...Array} [arrays] The arrays to inspect.
36135     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
36136     * @returns {Array} Returns the new array of combined values.
36137     * @example
36138     *
36139     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
36140     * // => [2.1, 1.2]
36141     *
36142     * // The `_.property` iteratee shorthand.
36143     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
36144     * // => [{ 'x': 1 }, { 'x': 2 }]
36145     */
36146    var unionBy = baseRest(function(arrays) {
36147      var iteratee = last(arrays);
36148      if (isArrayLikeObject(iteratee)) {
36149        iteratee = undefined;
36150      }
36151      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
36152    });
36153
36154    /**
36155     * This method is like `_.union` except that it accepts `comparator` which
36156     * is invoked to compare elements of `arrays`. Result values are chosen from
36157     * the first array in which the value occurs. The comparator is invoked
36158     * with two arguments: (arrVal, othVal).
36159     *
36160     * @static
36161     * @memberOf _
36162     * @since 4.0.0
36163     * @category Array
36164     * @param {...Array} [arrays] The arrays to inspect.
36165     * @param {Function} [comparator] The comparator invoked per element.
36166     * @returns {Array} Returns the new array of combined values.
36167     * @example
36168     *
36169     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
36170     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
36171     *
36172     * _.unionWith(objects, others, _.isEqual);
36173     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
36174     */
36175    var unionWith = baseRest(function(arrays) {
36176      var comparator = last(arrays);
36177      comparator = typeof comparator == 'function' ? comparator : undefined;
36178      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
36179    });
36180
36181    /**
36182     * Creates a duplicate-free version of an array, using
36183     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
36184     * for equality comparisons, in which only the first occurrence of each element
36185     * is kept. The order of result values is determined by the order they occur
36186     * in the array.
36187     *
36188     * @static
36189     * @memberOf _
36190     * @since 0.1.0
36191     * @category Array
36192     * @param {Array} array The array to inspect.
36193     * @returns {Array} Returns the new duplicate free array.
36194     * @example
36195     *
36196     * _.uniq([2, 1, 2]);
36197     * // => [2, 1]
36198     */
36199    function uniq(array) {
36200      return (array && array.length) ? baseUniq(array) : [];
36201    }
36202
36203    /**
36204     * This method is like `_.uniq` except that it accepts `iteratee` which is
36205     * invoked for each element in `array` to generate the criterion by which
36206     * uniqueness is computed. The order of result values is determined by the
36207     * order they occur in the array. The iteratee is invoked with one argument:
36208     * (value).
36209     *
36210     * @static
36211     * @memberOf _
36212     * @since 4.0.0
36213     * @category Array
36214     * @param {Array} array The array to inspect.
36215     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
36216     * @returns {Array} Returns the new duplicate free array.
36217     * @example
36218     *
36219     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
36220     * // => [2.1, 1.2]
36221     *
36222     * // The `_.property` iteratee shorthand.
36223     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
36224     * // => [{ 'x': 1 }, { 'x': 2 }]
36225     */
36226    function uniqBy(array, iteratee) {
36227      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
36228    }
36229
36230    /**
36231     * This method is like `_.uniq` except that it accepts `comparator` which
36232     * is invoked to compare elements of `array`. The order of result values is
36233     * determined by the order they occur in the array.The comparator is invoked
36234     * with two arguments: (arrVal, othVal).
36235     *
36236     * @static
36237     * @memberOf _
36238     * @since 4.0.0
36239     * @category Array
36240     * @param {Array} array The array to inspect.
36241     * @param {Function} [comparator] The comparator invoked per element.
36242     * @returns {Array} Returns the new duplicate free array.
36243     * @example
36244     *
36245     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
36246     *
36247     * _.uniqWith(objects, _.isEqual);
36248     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
36249     */
36250    function uniqWith(array, comparator) {
36251      comparator = typeof comparator == 'function' ? comparator : undefined;
36252      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
36253    }
36254
36255    /**
36256     * This method is like `_.zip` except that it accepts an array of grouped
36257     * elements and creates an array regrouping the elements to their pre-zip
36258     * configuration.
36259     *
36260     * @static
36261     * @memberOf _
36262     * @since 1.2.0
36263     * @category Array
36264     * @param {Array} array The array of grouped elements to process.
36265     * @returns {Array} Returns the new array of regrouped elements.
36266     * @example
36267     *
36268     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
36269     * // => [['a', 1, true], ['b', 2, false]]
36270     *
36271     * _.unzip(zipped);
36272     * // => [['a', 'b'], [1, 2], [true, false]]
36273     */
36274    function unzip(array) {
36275      if (!(array && array.length)) {
36276        return [];
36277      }
36278      var length = 0;
36279      array = arrayFilter(array, function(group) {
36280        if (isArrayLikeObject(group)) {
36281          length = nativeMax(group.length, length);
36282          return true;
36283        }
36284      });
36285      return baseTimes(length, function(index) {
36286        return arrayMap(array, baseProperty(index));
36287      });
36288    }
36289
36290    /**
36291     * This method is like `_.unzip` except that it accepts `iteratee` to specify
36292     * how regrouped values should be combined. The iteratee is invoked with the
36293     * elements of each group: (...group).
36294     *
36295     * @static
36296     * @memberOf _
36297     * @since 3.8.0
36298     * @category Array
36299     * @param {Array} array The array of grouped elements to process.
36300     * @param {Function} [iteratee=_.identity] The function to combine
36301     *  regrouped values.
36302     * @returns {Array} Returns the new array of regrouped elements.
36303     * @example
36304     *
36305     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
36306     * // => [[1, 10, 100], [2, 20, 200]]
36307     *
36308     * _.unzipWith(zipped, _.add);
36309     * // => [3, 30, 300]
36310     */
36311    function unzipWith(array, iteratee) {
36312      if (!(array && array.length)) {
36313        return [];
36314      }
36315      var result = unzip(array);
36316      if (iteratee == null) {
36317        return result;
36318      }
36319      return arrayMap(result, function(group) {
36320        return apply(iteratee, undefined, group);
36321      });
36322    }
36323
36324    /**
36325     * Creates an array excluding all given values using
36326     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
36327     * for equality comparisons.
36328     *
36329     * **Note:** Unlike `_.pull`, this method returns a new array.
36330     *
36331     * @static
36332     * @memberOf _
36333     * @since 0.1.0
36334     * @category Array
36335     * @param {Array} array The array to inspect.
36336     * @param {...*} [values] The values to exclude.
36337     * @returns {Array} Returns the new array of filtered values.
36338     * @see _.difference, _.xor
36339     * @example
36340     *
36341     * _.without([2, 1, 2, 3], 1, 2);
36342     * // => [3]
36343     */
36344    var without = baseRest(function(array, values) {
36345      return isArrayLikeObject(array)
36346        ? baseDifference(array, values)
36347        : [];
36348    });
36349
36350    /**
36351     * Creates an array of unique values that is the
36352     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
36353     * of the given arrays. The order of result values is determined by the order
36354     * they occur in the arrays.
36355     *
36356     * @static
36357     * @memberOf _
36358     * @since 2.4.0
36359     * @category Array
36360     * @param {...Array} [arrays] The arrays to inspect.
36361     * @returns {Array} Returns the new array of filtered values.
36362     * @see _.difference, _.without
36363     * @example
36364     *
36365     * _.xor([2, 1], [2, 3]);
36366     * // => [1, 3]
36367     */
36368    var xor = baseRest(function(arrays) {
36369      return baseXor(arrayFilter(arrays, isArrayLikeObject));
36370    });
36371
36372    /**
36373     * This method is like `_.xor` except that it accepts `iteratee` which is
36374     * invoked for each element of each `arrays` to generate the criterion by
36375     * which by which they're compared. The order of result values is determined
36376     * by the order they occur in the arrays. The iteratee is invoked with one
36377     * argument: (value).
36378     *
36379     * @static
36380     * @memberOf _
36381     * @since 4.0.0
36382     * @category Array
36383     * @param {...Array} [arrays] The arrays to inspect.
36384     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
36385     * @returns {Array} Returns the new array of filtered values.
36386     * @example
36387     *
36388     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
36389     * // => [1.2, 3.4]
36390     *
36391     * // The `_.property` iteratee shorthand.
36392     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
36393     * // => [{ 'x': 2 }]
36394     */
36395    var xorBy = baseRest(function(arrays) {
36396      var iteratee = last(arrays);
36397      if (isArrayLikeObject(iteratee)) {
36398        iteratee = undefined;
36399      }
36400      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
36401    });
36402
36403    /**
36404     * This method is like `_.xor` except that it accepts `comparator` which is
36405     * invoked to compare elements of `arrays`. The order of result values is
36406     * determined by the order they occur in the arrays. The comparator is invoked
36407     * with two arguments: (arrVal, othVal).
36408     *
36409     * @static
36410     * @memberOf _
36411     * @since 4.0.0
36412     * @category Array
36413     * @param {...Array} [arrays] The arrays to inspect.
36414     * @param {Function} [comparator] The comparator invoked per element.
36415     * @returns {Array} Returns the new array of filtered values.
36416     * @example
36417     *
36418     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
36419     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
36420     *
36421     * _.xorWith(objects, others, _.isEqual);
36422     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
36423     */
36424    var xorWith = baseRest(function(arrays) {
36425      var comparator = last(arrays);
36426      comparator = typeof comparator == 'function' ? comparator : undefined;
36427      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
36428    });
36429
36430    /**
36431     * Creates an array of grouped elements, the first of which contains the
36432     * first elements of the given arrays, the second of which contains the
36433     * second elements of the given arrays, and so on.
36434     *
36435     * @static
36436     * @memberOf _
36437     * @since 0.1.0
36438     * @category Array
36439     * @param {...Array} [arrays] The arrays to process.
36440     * @returns {Array} Returns the new array of grouped elements.
36441     * @example
36442     *
36443     * _.zip(['a', 'b'], [1, 2], [true, false]);
36444     * // => [['a', 1, true], ['b', 2, false]]
36445     */
36446    var zip = baseRest(unzip);
36447
36448    /**
36449     * This method is like `_.fromPairs` except that it accepts two arrays,
36450     * one of property identifiers and one of corresponding values.
36451     *
36452     * @static
36453     * @memberOf _
36454     * @since 0.4.0
36455     * @category Array
36456     * @param {Array} [props=[]] The property identifiers.
36457     * @param {Array} [values=[]] The property values.
36458     * @returns {Object} Returns the new object.
36459     * @example
36460     *
36461     * _.zipObject(['a', 'b'], [1, 2]);
36462     * // => { 'a': 1, 'b': 2 }
36463     */
36464    function zipObject(props, values) {
36465      return baseZipObject(props || [], values || [], assignValue);
36466    }
36467
36468    /**
36469     * This method is like `_.zipObject` except that it supports property paths.
36470     *
36471     * @static
36472     * @memberOf _
36473     * @since 4.1.0
36474     * @category Array
36475     * @param {Array} [props=[]] The property identifiers.
36476     * @param {Array} [values=[]] The property values.
36477     * @returns {Object} Returns the new object.
36478     * @example
36479     *
36480     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
36481     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
36482     */
36483    function zipObjectDeep(props, values) {
36484      return baseZipObject(props || [], values || [], baseSet);
36485    }
36486
36487    /**
36488     * This method is like `_.zip` except that it accepts `iteratee` to specify
36489     * how grouped values should be combined. The iteratee is invoked with the
36490     * elements of each group: (...group).
36491     *
36492     * @static
36493     * @memberOf _
36494     * @since 3.8.0
36495     * @category Array
36496     * @param {...Array} [arrays] The arrays to process.
36497     * @param {Function} [iteratee=_.identity] The function to combine
36498     *  grouped values.
36499     * @returns {Array} Returns the new array of grouped elements.
36500     * @example
36501     *
36502     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
36503     *   return a + b + c;
36504     * });
36505     * // => [111, 222]
36506     */
36507    var zipWith = baseRest(function(arrays) {
36508      var length = arrays.length,
36509          iteratee = length > 1 ? arrays[length - 1] : undefined;
36510
36511      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
36512      return unzipWith(arrays, iteratee);
36513    });
36514
36515    /*------------------------------------------------------------------------*/
36516
36517    /**
36518     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
36519     * chain sequences enabled. The result of such sequences must be unwrapped
36520     * with `_#value`.
36521     *
36522     * @static
36523     * @memberOf _
36524     * @since 1.3.0
36525     * @category Seq
36526     * @param {*} value The value to wrap.
36527     * @returns {Object} Returns the new `lodash` wrapper instance.
36528     * @example
36529     *
36530     * var users = [
36531     *   { 'user': 'barney',  'age': 36 },
36532     *   { 'user': 'fred',    'age': 40 },
36533     *   { 'user': 'pebbles', 'age': 1 }
36534     * ];
36535     *
36536     * var youngest = _
36537     *   .chain(users)
36538     *   .sortBy('age')
36539     *   .map(function(o) {
36540     *     return o.user + ' is ' + o.age;
36541     *   })
36542     *   .head()
36543     *   .value();
36544     * // => 'pebbles is 1'
36545     */
36546    function chain(value) {
36547      var result = lodash(value);
36548      result.__chain__ = true;
36549      return result;
36550    }
36551
36552    /**
36553     * This method invokes `interceptor` and returns `value`. The interceptor
36554     * is invoked with one argument; (value). The purpose of this method is to
36555     * "tap into" a method chain sequence in order to modify intermediate results.
36556     *
36557     * @static
36558     * @memberOf _
36559     * @since 0.1.0
36560     * @category Seq
36561     * @param {*} value The value to provide to `interceptor`.
36562     * @param {Function} interceptor The function to invoke.
36563     * @returns {*} Returns `value`.
36564     * @example
36565     *
36566     * _([1, 2, 3])
36567     *  .tap(function(array) {
36568     *    // Mutate input array.
36569     *    array.pop();
36570     *  })
36571     *  .reverse()
36572     *  .value();
36573     * // => [2, 1]
36574     */
36575    function tap(value, interceptor) {
36576      interceptor(value);
36577      return value;
36578    }
36579
36580    /**
36581     * This method is like `_.tap` except that it returns the result of `interceptor`.
36582     * The purpose of this method is to "pass thru" values replacing intermediate
36583     * results in a method chain sequence.
36584     *
36585     * @static
36586     * @memberOf _
36587     * @since 3.0.0
36588     * @category Seq
36589     * @param {*} value The value to provide to `interceptor`.
36590     * @param {Function} interceptor The function to invoke.
36591     * @returns {*} Returns the result of `interceptor`.
36592     * @example
36593     *
36594     * _('  abc  ')
36595     *  .chain()
36596     *  .trim()
36597     *  .thru(function(value) {
36598     *    return [value];
36599     *  })
36600     *  .value();
36601     * // => ['abc']
36602     */
36603    function thru(value, interceptor) {
36604      return interceptor(value);
36605    }
36606
36607    /**
36608     * This method is the wrapper version of `_.at`.
36609     *
36610     * @name at
36611     * @memberOf _
36612     * @since 1.0.0
36613     * @category Seq
36614     * @param {...(string|string[])} [paths] The property paths to pick.
36615     * @returns {Object} Returns the new `lodash` wrapper instance.
36616     * @example
36617     *
36618     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
36619     *
36620     * _(object).at(['a[0].b.c', 'a[1]']).value();
36621     * // => [3, 4]
36622     */
36623    var wrapperAt = flatRest(function(paths) {
36624      var length = paths.length,
36625          start = length ? paths[0] : 0,
36626          value = this.__wrapped__,
36627          interceptor = function(object) { return baseAt(object, paths); };
36628
36629      if (length > 1 || this.__actions__.length ||
36630          !(value instanceof LazyWrapper) || !isIndex(start)) {
36631        return this.thru(interceptor);
36632      }
36633      value = value.slice(start, +start + (length ? 1 : 0));
36634      value.__actions__.push({
36635        'func': thru,
36636        'args': [interceptor],
36637        'thisArg': undefined
36638      });
36639      return new LodashWrapper(value, this.__chain__).thru(function(array) {
36640        if (length && !array.length) {
36641          array.push(undefined);
36642        }
36643        return array;
36644      });
36645    });
36646
36647    /**
36648     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
36649     *
36650     * @name chain
36651     * @memberOf _
36652     * @since 0.1.0
36653     * @category Seq
36654     * @returns {Object} Returns the new `lodash` wrapper instance.
36655     * @example
36656     *
36657     * var users = [
36658     *   { 'user': 'barney', 'age': 36 },
36659     *   { 'user': 'fred',   'age': 40 }
36660     * ];
36661     *
36662     * // A sequence without explicit chaining.
36663     * _(users).head();
36664     * // => { 'user': 'barney', 'age': 36 }
36665     *
36666     * // A sequence with explicit chaining.
36667     * _(users)
36668     *   .chain()
36669     *   .head()
36670     *   .pick('user')
36671     *   .value();
36672     * // => { 'user': 'barney' }
36673     */
36674    function wrapperChain() {
36675      return chain(this);
36676    }
36677
36678    /**
36679     * Executes the chain sequence and returns the wrapped result.
36680     *
36681     * @name commit
36682     * @memberOf _
36683     * @since 3.2.0
36684     * @category Seq
36685     * @returns {Object} Returns the new `lodash` wrapper instance.
36686     * @example
36687     *
36688     * var array = [1, 2];
36689     * var wrapped = _(array).push(3);
36690     *
36691     * console.log(array);
36692     * // => [1, 2]
36693     *
36694     * wrapped = wrapped.commit();
36695     * console.log(array);
36696     * // => [1, 2, 3]
36697     *
36698     * wrapped.last();
36699     * // => 3
36700     *
36701     * console.log(array);
36702     * // => [1, 2, 3]
36703     */
36704    function wrapperCommit() {
36705      return new LodashWrapper(this.value(), this.__chain__);
36706    }
36707
36708    /**
36709     * Gets the next value on a wrapped object following the
36710     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
36711     *
36712     * @name next
36713     * @memberOf _
36714     * @since 4.0.0
36715     * @category Seq
36716     * @returns {Object} Returns the next iterator value.
36717     * @example
36718     *
36719     * var wrapped = _([1, 2]);
36720     *
36721     * wrapped.next();
36722     * // => { 'done': false, 'value': 1 }
36723     *
36724     * wrapped.next();
36725     * // => { 'done': false, 'value': 2 }
36726     *
36727     * wrapped.next();
36728     * // => { 'done': true, 'value': undefined }
36729     */
36730    function wrapperNext() {
36731      if (this.__values__ === undefined) {
36732        this.__values__ = toArray(this.value());
36733      }
36734      var done = this.__index__ >= this.__values__.length,
36735          value = done ? undefined : this.__values__[this.__index__++];
36736
36737      return { 'done': done, 'value': value };
36738    }
36739
36740    /**
36741     * Enables the wrapper to be iterable.
36742     *
36743     * @name Symbol.iterator
36744     * @memberOf _
36745     * @since 4.0.0
36746     * @category Seq
36747     * @returns {Object} Returns the wrapper object.
36748     * @example
36749     *
36750     * var wrapped = _([1, 2]);
36751     *
36752     * wrapped[Symbol.iterator]() === wrapped;
36753     * // => true
36754     *
36755     * Array.from(wrapped);
36756     * // => [1, 2]
36757     */
36758    function wrapperToIterator() {
36759      return this;
36760    }
36761
36762    /**
36763     * Creates a clone of the chain sequence planting `value` as the wrapped value.
36764     *
36765     * @name plant
36766     * @memberOf _
36767     * @since 3.2.0
36768     * @category Seq
36769     * @param {*} value The value to plant.
36770     * @returns {Object} Returns the new `lodash` wrapper instance.
36771     * @example
36772     *
36773     * function square(n) {
36774     *   return n * n;
36775     * }
36776     *
36777     * var wrapped = _([1, 2]).map(square);
36778     * var other = wrapped.plant([3, 4]);
36779     *
36780     * other.value();
36781     * // => [9, 16]
36782     *
36783     * wrapped.value();
36784     * // => [1, 4]
36785     */
36786    function wrapperPlant(value) {
36787      var result,
36788          parent = this;
36789
36790      while (parent instanceof baseLodash) {
36791        var clone = wrapperClone(parent);
36792        clone.__index__ = 0;
36793        clone.__values__ = undefined;
36794        if (result) {
36795          previous.__wrapped__ = clone;
36796        } else {
36797          result = clone;
36798        }
36799        var previous = clone;
36800        parent = parent.__wrapped__;
36801      }
36802      previous.__wrapped__ = value;
36803      return result;
36804    }
36805
36806    /**
36807     * This method is the wrapper version of `_.reverse`.
36808     *
36809     * **Note:** This method mutates the wrapped array.
36810     *
36811     * @name reverse
36812     * @memberOf _
36813     * @since 0.1.0
36814     * @category Seq
36815     * @returns {Object} Returns the new `lodash` wrapper instance.
36816     * @example
36817     *
36818     * var array = [1, 2, 3];
36819     *
36820     * _(array).reverse().value()
36821     * // => [3, 2, 1]
36822     *
36823     * console.log(array);
36824     * // => [3, 2, 1]
36825     */
36826    function wrapperReverse() {
36827      var value = this.__wrapped__;
36828      if (value instanceof LazyWrapper) {
36829        var wrapped = value;
36830        if (this.__actions__.length) {
36831          wrapped = new LazyWrapper(this);
36832        }
36833        wrapped = wrapped.reverse();
36834        wrapped.__actions__.push({
36835          'func': thru,
36836          'args': [reverse],
36837          'thisArg': undefined
36838        });
36839        return new LodashWrapper(wrapped, this.__chain__);
36840      }
36841      return this.thru(reverse);
36842    }
36843
36844    /**
36845     * Executes the chain sequence to resolve the unwrapped value.
36846     *
36847     * @name value
36848     * @memberOf _
36849     * @since 0.1.0
36850     * @alias toJSON, valueOf
36851     * @category Seq
36852     * @returns {*} Returns the resolved unwrapped value.
36853     * @example
36854     *
36855     * _([1, 2, 3]).value();
36856     * // => [1, 2, 3]
36857     */
36858    function wrapperValue() {
36859      return baseWrapperValue(this.__wrapped__, this.__actions__);
36860    }
36861
36862    /*------------------------------------------------------------------------*/
36863
36864    /**
36865     * Creates an object composed of keys generated from the results of running
36866     * each element of `collection` thru `iteratee`. The corresponding value of
36867     * each key is the number of times the key was returned by `iteratee`. The
36868     * iteratee is invoked with one argument: (value).
36869     *
36870     * @static
36871     * @memberOf _
36872     * @since 0.5.0
36873     * @category Collection
36874     * @param {Array|Object} collection The collection to iterate over.
36875     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
36876     * @returns {Object} Returns the composed aggregate object.
36877     * @example
36878     *
36879     * _.countBy([6.1, 4.2, 6.3], Math.floor);
36880     * // => { '4': 1, '6': 2 }
36881     *
36882     * // The `_.property` iteratee shorthand.
36883     * _.countBy(['one', 'two', 'three'], 'length');
36884     * // => { '3': 2, '5': 1 }
36885     */
36886    var countBy = createAggregator(function(result, value, key) {
36887      if (hasOwnProperty.call(result, key)) {
36888        ++result[key];
36889      } else {
36890        baseAssignValue(result, key, 1);
36891      }
36892    });
36893
36894    /**
36895     * Checks if `predicate` returns truthy for **all** elements of `collection`.
36896     * Iteration is stopped once `predicate` returns falsey. The predicate is
36897     * invoked with three arguments: (value, index|key, collection).
36898     *
36899     * **Note:** This method returns `true` for
36900     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
36901     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
36902     * elements of empty collections.
36903     *
36904     * @static
36905     * @memberOf _
36906     * @since 0.1.0
36907     * @category Collection
36908     * @param {Array|Object} collection The collection to iterate over.
36909     * @param {Function} [predicate=_.identity] The function invoked per iteration.
36910     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
36911     * @returns {boolean} Returns `true` if all elements pass the predicate check,
36912     *  else `false`.
36913     * @example
36914     *
36915     * _.every([true, 1, null, 'yes'], Boolean);
36916     * // => false
36917     *
36918     * var users = [
36919     *   { 'user': 'barney', 'age': 36, 'active': false },
36920     *   { 'user': 'fred',   'age': 40, 'active': false }
36921     * ];
36922     *
36923     * // The `_.matches` iteratee shorthand.
36924     * _.every(users, { 'user': 'barney', 'active': false });
36925     * // => false
36926     *
36927     * // The `_.matchesProperty` iteratee shorthand.
36928     * _.every(users, ['active', false]);
36929     * // => true
36930     *
36931     * // The `_.property` iteratee shorthand.
36932     * _.every(users, 'active');
36933     * // => false
36934     */
36935    function every(collection, predicate, guard) {
36936      var func = isArray(collection) ? arrayEvery : baseEvery;
36937      if (guard && isIterateeCall(collection, predicate, guard)) {
36938        predicate = undefined;
36939      }
36940      return func(collection, getIteratee(predicate, 3));
36941    }
36942
36943    /**
36944     * Iterates over elements of `collection`, returning an array of all elements
36945     * `predicate` returns truthy for. The predicate is invoked with three
36946     * arguments: (value, index|key, collection).
36947     *
36948     * **Note:** Unlike `_.remove`, this method returns a new array.
36949     *
36950     * @static
36951     * @memberOf _
36952     * @since 0.1.0
36953     * @category Collection
36954     * @param {Array|Object} collection The collection to iterate over.
36955     * @param {Function} [predicate=_.identity] The function invoked per iteration.
36956     * @returns {Array} Returns the new filtered array.
36957     * @see _.reject
36958     * @example
36959     *
36960     * var users = [
36961     *   { 'user': 'barney', 'age': 36, 'active': true },
36962     *   { 'user': 'fred',   'age': 40, 'active': false }
36963     * ];
36964     *
36965     * _.filter(users, function(o) { return !o.active; });
36966     * // => objects for ['fred']
36967     *
36968     * // The `_.matches` iteratee shorthand.
36969     * _.filter(users, { 'age': 36, 'active': true });
36970     * // => objects for ['barney']
36971     *
36972     * // The `_.matchesProperty` iteratee shorthand.
36973     * _.filter(users, ['active', false]);
36974     * // => objects for ['fred']
36975     *
36976     * // The `_.property` iteratee shorthand.
36977     * _.filter(users, 'active');
36978     * // => objects for ['barney']
36979     *
36980     * // Combining several predicates using `_.overEvery` or `_.overSome`.
36981     * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
36982     * // => objects for ['fred', 'barney']
36983     */
36984    function filter(collection, predicate) {
36985      var func = isArray(collection) ? arrayFilter : baseFilter;
36986      return func(collection, getIteratee(predicate, 3));
36987    }
36988
36989    /**
36990     * Iterates over elements of `collection`, returning the first element
36991     * `predicate` returns truthy for. The predicate is invoked with three
36992     * arguments: (value, index|key, collection).
36993     *
36994     * @static
36995     * @memberOf _
36996     * @since 0.1.0
36997     * @category Collection
36998     * @param {Array|Object} collection The collection to inspect.
36999     * @param {Function} [predicate=_.identity] The function invoked per iteration.
37000     * @param {number} [fromIndex=0] The index to search from.
37001     * @returns {*} Returns the matched element, else `undefined`.
37002     * @example
37003     *
37004     * var users = [
37005     *   { 'user': 'barney',  'age': 36, 'active': true },
37006     *   { 'user': 'fred',    'age': 40, 'active': false },
37007     *   { 'user': 'pebbles', 'age': 1,  'active': true }
37008     * ];
37009     *
37010     * _.find(users, function(o) { return o.age < 40; });
37011     * // => object for 'barney'
37012     *
37013     * // The `_.matches` iteratee shorthand.
37014     * _.find(users, { 'age': 1, 'active': true });
37015     * // => object for 'pebbles'
37016     *
37017     * // The `_.matchesProperty` iteratee shorthand.
37018     * _.find(users, ['active', false]);
37019     * // => object for 'fred'
37020     *
37021     * // The `_.property` iteratee shorthand.
37022     * _.find(users, 'active');
37023     * // => object for 'barney'
37024     */
37025    var find = createFind(findIndex);
37026
37027    /**
37028     * This method is like `_.find` except that it iterates over elements of
37029     * `collection` from right to left.
37030     *
37031     * @static
37032     * @memberOf _
37033     * @since 2.0.0
37034     * @category Collection
37035     * @param {Array|Object} collection The collection to inspect.
37036     * @param {Function} [predicate=_.identity] The function invoked per iteration.
37037     * @param {number} [fromIndex=collection.length-1] The index to search from.
37038     * @returns {*} Returns the matched element, else `undefined`.
37039     * @example
37040     *
37041     * _.findLast([1, 2, 3, 4], function(n) {
37042     *   return n % 2 == 1;
37043     * });
37044     * // => 3
37045     */
37046    var findLast = createFind(findLastIndex);
37047
37048    /**
37049     * Creates a flattened array of values by running each element in `collection`
37050     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
37051     * with three arguments: (value, index|key, collection).
37052     *
37053     * @static
37054     * @memberOf _
37055     * @since 4.0.0
37056     * @category Collection
37057     * @param {Array|Object} collection The collection to iterate over.
37058     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37059     * @returns {Array} Returns the new flattened array.
37060     * @example
37061     *
37062     * function duplicate(n) {
37063     *   return [n, n];
37064     * }
37065     *
37066     * _.flatMap([1, 2], duplicate);
37067     * // => [1, 1, 2, 2]
37068     */
37069    function flatMap(collection, iteratee) {
37070      return baseFlatten(map(collection, iteratee), 1);
37071    }
37072
37073    /**
37074     * This method is like `_.flatMap` except that it recursively flattens the
37075     * mapped results.
37076     *
37077     * @static
37078     * @memberOf _
37079     * @since 4.7.0
37080     * @category Collection
37081     * @param {Array|Object} collection The collection to iterate over.
37082     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37083     * @returns {Array} Returns the new flattened array.
37084     * @example
37085     *
37086     * function duplicate(n) {
37087     *   return [[[n, n]]];
37088     * }
37089     *
37090     * _.flatMapDeep([1, 2], duplicate);
37091     * // => [1, 1, 2, 2]
37092     */
37093    function flatMapDeep(collection, iteratee) {
37094      return baseFlatten(map(collection, iteratee), INFINITY);
37095    }
37096
37097    /**
37098     * This method is like `_.flatMap` except that it recursively flattens the
37099     * mapped results up to `depth` times.
37100     *
37101     * @static
37102     * @memberOf _
37103     * @since 4.7.0
37104     * @category Collection
37105     * @param {Array|Object} collection The collection to iterate over.
37106     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37107     * @param {number} [depth=1] The maximum recursion depth.
37108     * @returns {Array} Returns the new flattened array.
37109     * @example
37110     *
37111     * function duplicate(n) {
37112     *   return [[[n, n]]];
37113     * }
37114     *
37115     * _.flatMapDepth([1, 2], duplicate, 2);
37116     * // => [[1, 1], [2, 2]]
37117     */
37118    function flatMapDepth(collection, iteratee, depth) {
37119      depth = depth === undefined ? 1 : toInteger(depth);
37120      return baseFlatten(map(collection, iteratee), depth);
37121    }
37122
37123    /**
37124     * Iterates over elements of `collection` and invokes `iteratee` for each element.
37125     * The iteratee is invoked with three arguments: (value, index|key, collection).
37126     * Iteratee functions may exit iteration early by explicitly returning `false`.
37127     *
37128     * **Note:** As with other "Collections" methods, objects with a "length"
37129     * property are iterated like arrays. To avoid this behavior use `_.forIn`
37130     * or `_.forOwn` for object iteration.
37131     *
37132     * @static
37133     * @memberOf _
37134     * @since 0.1.0
37135     * @alias each
37136     * @category Collection
37137     * @param {Array|Object} collection The collection to iterate over.
37138     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37139     * @returns {Array|Object} Returns `collection`.
37140     * @see _.forEachRight
37141     * @example
37142     *
37143     * _.forEach([1, 2], function(value) {
37144     *   console.log(value);
37145     * });
37146     * // => Logs `1` then `2`.
37147     *
37148     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
37149     *   console.log(key);
37150     * });
37151     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
37152     */
37153    function forEach(collection, iteratee) {
37154      var func = isArray(collection) ? arrayEach : baseEach;
37155      return func(collection, getIteratee(iteratee, 3));
37156    }
37157
37158    /**
37159     * This method is like `_.forEach` except that it iterates over elements of
37160     * `collection` from right to left.
37161     *
37162     * @static
37163     * @memberOf _
37164     * @since 2.0.0
37165     * @alias eachRight
37166     * @category Collection
37167     * @param {Array|Object} collection The collection to iterate over.
37168     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37169     * @returns {Array|Object} Returns `collection`.
37170     * @see _.forEach
37171     * @example
37172     *
37173     * _.forEachRight([1, 2], function(value) {
37174     *   console.log(value);
37175     * });
37176     * // => Logs `2` then `1`.
37177     */
37178    function forEachRight(collection, iteratee) {
37179      var func = isArray(collection) ? arrayEachRight : baseEachRight;
37180      return func(collection, getIteratee(iteratee, 3));
37181    }
37182
37183    /**
vendor: 4,136 bytes, lines 37184-37291
37184     * Creates an object composed of keys generated from the results of running
37185     * each element of `collection` thru `iteratee`. The order of grouped values
37186     * is determined by the order they occur in `collection`. The corresponding
37187     * value of each key is an array of elements responsible for generating the
37188     * key. The iteratee is invoked with one argument: (value).
37189     *
37190     * @static
37191     * @memberOf _
37192     * @since 0.1.0
37193     * @category Collection
37194     * @param {Array|Object} collection The collection to iterate over.
37195     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
37196     * @returns {Object} Returns the composed aggregate object.
37197     * @example
37198     *
37199     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
37200     * // => { '4': [4.2], '6': [6.1, 6.3] }
37201     *
37202     * // The `_.property` iteratee shorthand.
37203     * _.groupBy(['one', 'two', 'three'], 'length');
37204     * // => { '3': ['one', 'two'], '5': ['three'] }
37205     */
37206    var groupBy = createAggregator(function(result, value, key) {
37207      if (hasOwnProperty.call(result, key)) {
37208        result[key].push(value);
37209      } else {
37210        baseAssignValue(result, key, [value]);
37211      }
37212    });
37213
37214    /**
37215     * Checks if `value` is in `collection`. If `collection` is a string, it's
37216     * checked for a substring of `value`, otherwise
37217     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
37218     * is used for equality comparisons. If `fromIndex` is negative, it's used as
37219     * the offset from the end of `collection`.
37220     *
37221     * @static
37222     * @memberOf _
37223     * @since 0.1.0
37224     * @category Collection
37225     * @param {Array|Object|string} collection The collection to inspect.
37226     * @param {*} value The value to search for.
37227     * @param {number} [fromIndex=0] The index to search from.
37228     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
37229     * @returns {boolean} Returns `true` if `value` is found, else `false`.
37230     * @example
37231     *
37232     * _.includes([1, 2, 3], 1);
37233     * // => true
37234     *
37235     * _.includes([1, 2, 3], 1, 2);
37236     * // => false
37237     *
37238     * _.includes({ 'a': 1, 'b': 2 }, 1);
37239     * // => true
37240     *
37241     * _.includes('abcd', 'bc');
37242     * // => true
37243     */
37244    function includes(collection, value, fromIndex, guard) {
37245      collection = isArrayLike(collection) ? collection : values(collection);
37246      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
37247
37248      var length = collection.length;
37249      if (fromIndex < 0) {
37250        fromIndex = nativeMax(length + fromIndex, 0);
37251      }
37252      return isString(collection)
37253        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
37254        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
37255    }
37256
37257    /**
37258     * Invokes the method at `path` of each element in `collection`, returning
37259     * an array of the results of each invoked method. Any additional arguments
37260     * are provided to each invoked method. If `path` is a function, it's invoked
37261     * for, and `this` bound to, each element in `collection`.
37262     *
37263     * @static
37264     * @memberOf _
37265     * @since 4.0.0
37266     * @category Collection
37267     * @param {Array|Object} collection The collection to iterate over.
37268     * @param {Array|Function|string} path The path of the method to invoke or
37269     *  the function invoked per iteration.
37270     * @param {...*} [args] The arguments to invoke each method with.
37271     * @returns {Array} Returns the array of results.
37272     * @example
37273     *
37274     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
37275     * // => [[1, 5, 7], [1, 2, 3]]
37276     *
37277     * _.invokeMap([123, 456], String.prototype.split, '');
37278     * // => [['1', '2', '3'], ['4', '5', '6']]
37279     */
37280    var invokeMap = baseRest(function(collection, path, args) {
37281      var index = -1,
37282          isFunc = typeof path == 'function',
37283          result = isArrayLike(collection) ? Array(collection.length) : [];
37284
37285      baseEach(collection, function(value) {
37286        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
37287      });
37288      return result;
37289    });
37290
37291    /**
vendor: 68,500 bytes, lines 37292-39406
37292     * Creates an object composed of keys generated from the results of running
37293     * each element of `collection` thru `iteratee`. The corresponding value of
37294     * each key is the last element responsible for generating the key. The
37295     * iteratee is invoked with one argument: (value).
37296     *
37297     * @static
37298     * @memberOf _
37299     * @since 4.0.0
37300     * @category Collection
37301     * @param {Array|Object} collection The collection to iterate over.
37302     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
37303     * @returns {Object} Returns the composed aggregate object.
37304     * @example
37305     *
37306     * var array = [
37307     *   { 'dir': 'left', 'code': 97 },
37308     *   { 'dir': 'right', 'code': 100 }
37309     * ];
37310     *
37311     * _.keyBy(array, function(o) {
37312     *   return String.fromCharCode(o.code);
37313     * });
37314     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
37315     *
37316     * _.keyBy(array, 'dir');
37317     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
37318     */
37319    var keyBy = createAggregator(function(result, value, key) {
37320      baseAssignValue(result, key, value);
37321    });
37322
37323    /**
37324     * Creates an array of values by running each element in `collection` thru
37325     * `iteratee`. The iteratee is invoked with three arguments:
37326     * (value, index|key, collection).
37327     *
37328     * Many lodash methods are guarded to work as iteratees for methods like
37329     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
37330     *
37331     * The guarded methods are:
37332     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
37333     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
37334     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
37335     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
37336     *
37337     * @static
37338     * @memberOf _
37339     * @since 0.1.0
37340     * @category Collection
37341     * @param {Array|Object} collection The collection to iterate over.
37342     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37343     * @returns {Array} Returns the new mapped array.
37344     * @example
37345     *
37346     * function square(n) {
37347     *   return n * n;
37348     * }
37349     *
37350     * _.map([4, 8], square);
37351     * // => [16, 64]
37352     *
37353     * _.map({ 'a': 4, 'b': 8 }, square);
37354     * // => [16, 64] (iteration order is not guaranteed)
37355     *
37356     * var users = [
37357     *   { 'user': 'barney' },
37358     *   { 'user': 'fred' }
37359     * ];
37360     *
37361     * // The `_.property` iteratee shorthand.
37362     * _.map(users, 'user');
37363     * // => ['barney', 'fred']
37364     */
37365    function map(collection, iteratee) {
37366      var func = isArray(collection) ? arrayMap : baseMap;
37367      return func(collection, getIteratee(iteratee, 3));
37368    }
37369
37370    /**
37371     * This method is like `_.sortBy` except that it allows specifying the sort
37372     * orders of the iteratees to sort by. If `orders` is unspecified, all values
37373     * are sorted in ascending order. Otherwise, specify an order of "desc" for
37374     * descending or "asc" for ascending sort order of corresponding values.
37375     *
37376     * @static
37377     * @memberOf _
37378     * @since 4.0.0
37379     * @category Collection
37380     * @param {Array|Object} collection The collection to iterate over.
37381     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
37382     *  The iteratees to sort by.
37383     * @param {string[]} [orders] The sort orders of `iteratees`.
37384     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
37385     * @returns {Array} Returns the new sorted array.
37386     * @example
37387     *
37388     * var users = [
37389     *   { 'user': 'fred',   'age': 48 },
37390     *   { 'user': 'barney', 'age': 34 },
37391     *   { 'user': 'fred',   'age': 40 },
37392     *   { 'user': 'barney', 'age': 36 }
37393     * ];
37394     *
37395     * // Sort by `user` in ascending order and by `age` in descending order.
37396     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
37397     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
37398     */
37399    function orderBy(collection, iteratees, orders, guard) {
37400      if (collection == null) {
37401        return [];
37402      }
37403      if (!isArray(iteratees)) {
37404        iteratees = iteratees == null ? [] : [iteratees];
37405      }
37406      orders = guard ? undefined : orders;
37407      if (!isArray(orders)) {
37408        orders = orders == null ? [] : [orders];
37409      }
37410      return baseOrderBy(collection, iteratees, orders);
37411    }
37412
37413    /**
37414     * Creates an array of elements split into two groups, the first of which
37415     * contains elements `predicate` returns truthy for, the second of which
37416     * contains elements `predicate` returns falsey for. The predicate is
37417     * invoked with one argument: (value).
37418     *
37419     * @static
37420     * @memberOf _
37421     * @since 3.0.0
37422     * @category Collection
37423     * @param {Array|Object} collection The collection to iterate over.
37424     * @param {Function} [predicate=_.identity] The function invoked per iteration.
37425     * @returns {Array} Returns the array of grouped elements.
37426     * @example
37427     *
37428     * var users = [
37429     *   { 'user': 'barney',  'age': 36, 'active': false },
37430     *   { 'user': 'fred',    'age': 40, 'active': true },
37431     *   { 'user': 'pebbles', 'age': 1,  'active': false }
37432     * ];
37433     *
37434     * _.partition(users, function(o) { return o.active; });
37435     * // => objects for [['fred'], ['barney', 'pebbles']]
37436     *
37437     * // The `_.matches` iteratee shorthand.
37438     * _.partition(users, { 'age': 1, 'active': false });
37439     * // => objects for [['pebbles'], ['barney', 'fred']]
37440     *
37441     * // The `_.matchesProperty` iteratee shorthand.
37442     * _.partition(users, ['active', false]);
37443     * // => objects for [['barney', 'pebbles'], ['fred']]
37444     *
37445     * // The `_.property` iteratee shorthand.
37446     * _.partition(users, 'active');
37447     * // => objects for [['fred'], ['barney', 'pebbles']]
37448     */
37449    var partition = createAggregator(function(result, value, key) {
37450      result[key ? 0 : 1].push(value);
37451    }, function() { return [[], []]; });
37452
37453    /**
37454     * Reduces `collection` to a value which is the accumulated result of running
37455     * each element in `collection` thru `iteratee`, where each successive
37456     * invocation is supplied the return value of the previous. If `accumulator`
37457     * is not given, the first element of `collection` is used as the initial
37458     * value. The iteratee is invoked with four arguments:
37459     * (accumulator, value, index|key, collection).
37460     *
37461     * Many lodash methods are guarded to work as iteratees for methods like
37462     * `_.reduce`, `_.reduceRight`, and `_.transform`.
37463     *
37464     * The guarded methods are:
37465     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
37466     * and `sortBy`
37467     *
37468     * @static
37469     * @memberOf _
37470     * @since 0.1.0
37471     * @category Collection
37472     * @param {Array|Object} collection The collection to iterate over.
37473     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37474     * @param {*} [accumulator] The initial value.
37475     * @returns {*} Returns the accumulated value.
37476     * @see _.reduceRight
37477     * @example
37478     *
37479     * _.reduce([1, 2], function(sum, n) {
37480     *   return sum + n;
37481     * }, 0);
37482     * // => 3
37483     *
37484     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
37485     *   (result[value] || (result[value] = [])).push(key);
37486     *   return result;
37487     * }, {});
37488     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
37489     */
37490    function reduce(collection, iteratee, accumulator) {
37491      var func = isArray(collection) ? arrayReduce : baseReduce,
37492          initAccum = arguments.length < 3;
37493
37494      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
37495    }
37496
37497    /**
37498     * This method is like `_.reduce` except that it iterates over elements of
37499     * `collection` from right to left.
37500     *
37501     * @static
37502     * @memberOf _
37503     * @since 0.1.0
37504     * @category Collection
37505     * @param {Array|Object} collection The collection to iterate over.
37506     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
37507     * @param {*} [accumulator] The initial value.
37508     * @returns {*} Returns the accumulated value.
37509     * @see _.reduce
37510     * @example
37511     *
37512     * var array = [[0, 1], [2, 3], [4, 5]];
37513     *
37514     * _.reduceRight(array, function(flattened, other) {
37515     *   return flattened.concat(other);
37516     * }, []);
37517     * // => [4, 5, 2, 3, 0, 1]
37518     */
37519    function reduceRight(collection, iteratee, accumulator) {
37520      var func = isArray(collection) ? arrayReduceRight : baseReduce,
37521          initAccum = arguments.length < 3;
37522
37523      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
37524    }
37525
37526    /**
37527     * The opposite of `_.filter`; this method returns the elements of `collection`
37528     * that `predicate` does **not** return truthy for.
37529     *
37530     * @static
37531     * @memberOf _
37532     * @since 0.1.0
37533     * @category Collection
37534     * @param {Array|Object} collection The collection to iterate over.
37535     * @param {Function} [predicate=_.identity] The function invoked per iteration.
37536     * @returns {Array} Returns the new filtered array.
37537     * @see _.filter
37538     * @example
37539     *
37540     * var users = [
37541     *   { 'user': 'barney', 'age': 36, 'active': false },
37542     *   { 'user': 'fred',   'age': 40, 'active': true }
37543     * ];
37544     *
37545     * _.reject(users, function(o) { return !o.active; });
37546     * // => objects for ['fred']
37547     *
37548     * // The `_.matches` iteratee shorthand.
37549     * _.reject(users, { 'age': 40, 'active': true });
37550     * // => objects for ['barney']
37551     *
37552     * // The `_.matchesProperty` iteratee shorthand.
37553     * _.reject(users, ['active', false]);
37554     * // => objects for ['fred']
37555     *
37556     * // The `_.property` iteratee shorthand.
37557     * _.reject(users, 'active');
37558     * // => objects for ['barney']
37559     */
37560    function reject(collection, predicate) {
37561      var func = isArray(collection) ? arrayFilter : baseFilter;
37562      return func(collection, negate(getIteratee(predicate, 3)));
37563    }
37564
37565    /**
37566     * Gets a random element from `collection`.
37567     *
37568     * @static
37569     * @memberOf _
37570     * @since 2.0.0
37571     * @category Collection
37572     * @param {Array|Object} collection The collection to sample.
37573     * @returns {*} Returns the random element.
37574     * @example
37575     *
37576     * _.sample([1, 2, 3, 4]);
37577     * // => 2
37578     */
37579    function sample(collection) {
37580      var func = isArray(collection) ? arraySample : baseSample;
37581      return func(collection);
37582    }
37583
37584    /**
37585     * Gets `n` random elements at unique keys from `collection` up to the
37586     * size of `collection`.
37587     *
37588     * @static
37589     * @memberOf _
37590     * @since 4.0.0
37591     * @category Collection
37592     * @param {Array|Object} collection The collection to sample.
37593     * @param {number} [n=1] The number of elements to sample.
37594     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37595     * @returns {Array} Returns the random elements.
37596     * @example
37597     *
37598     * _.sampleSize([1, 2, 3], 2);
37599     * // => [3, 1]
37600     *
37601     * _.sampleSize([1, 2, 3], 4);
37602     * // => [2, 3, 1]
37603     */
37604    function sampleSize(collection, n, guard) {
37605      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
37606        n = 1;
37607      } else {
37608        n = toInteger(n);
37609      }
37610      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
37611      return func(collection, n);
37612    }
37613
37614    /**
37615     * Creates an array of shuffled values, using a version of the
37616     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
37617     *
37618     * @static
37619     * @memberOf _
37620     * @since 0.1.0
37621     * @category Collection
37622     * @param {Array|Object} collection The collection to shuffle.
37623     * @returns {Array} Returns the new shuffled array.
37624     * @example
37625     *
37626     * _.shuffle([1, 2, 3, 4]);
37627     * // => [4, 1, 3, 2]
37628     */
37629    function shuffle(collection) {
37630      var func = isArray(collection) ? arrayShuffle : baseShuffle;
37631      return func(collection);
37632    }
37633
37634    /**
37635     * Gets the size of `collection` by returning its length for array-like
37636     * values or the number of own enumerable string keyed properties for objects.
37637     *
37638     * @static
37639     * @memberOf _
37640     * @since 0.1.0
37641     * @category Collection
37642     * @param {Array|Object|string} collection The collection to inspect.
37643     * @returns {number} Returns the collection size.
37644     * @example
37645     *
37646     * _.size([1, 2, 3]);
37647     * // => 3
37648     *
37649     * _.size({ 'a': 1, 'b': 2 });
37650     * // => 2
37651     *
37652     * _.size('pebbles');
37653     * // => 7
37654     */
37655    function size(collection) {
37656      if (collection == null) {
37657        return 0;
37658      }
37659      if (isArrayLike(collection)) {
37660        return isString(collection) ? stringSize(collection) : collection.length;
37661      }
37662      var tag = getTag(collection);
37663      if (tag == mapTag || tag == setTag) {
37664        return collection.size;
37665      }
37666      return baseKeys(collection).length;
37667    }
37668
37669    /**
37670     * Checks if `predicate` returns truthy for **any** element of `collection`.
37671     * Iteration is stopped once `predicate` returns truthy. The predicate is
37672     * invoked with three arguments: (value, index|key, collection).
37673     *
37674     * @static
37675     * @memberOf _
37676     * @since 0.1.0
37677     * @category Collection
37678     * @param {Array|Object} collection The collection to iterate over.
37679     * @param {Function} [predicate=_.identity] The function invoked per iteration.
37680     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37681     * @returns {boolean} Returns `true` if any element passes the predicate check,
37682     *  else `false`.
37683     * @example
37684     *
37685     * _.some([null, 0, 'yes', false], Boolean);
37686     * // => true
37687     *
37688     * var users = [
37689     *   { 'user': 'barney', 'active': true },
37690     *   { 'user': 'fred',   'active': false }
37691     * ];
37692     *
37693     * // The `_.matches` iteratee shorthand.
37694     * _.some(users, { 'user': 'barney', 'active': false });
37695     * // => false
37696     *
37697     * // The `_.matchesProperty` iteratee shorthand.
37698     * _.some(users, ['active', false]);
37699     * // => true
37700     *
37701     * // The `_.property` iteratee shorthand.
37702     * _.some(users, 'active');
37703     * // => true
37704     */
37705    function some(collection, predicate, guard) {
37706      var func = isArray(collection) ? arraySome : baseSome;
37707      if (guard && isIterateeCall(collection, predicate, guard)) {
37708        predicate = undefined;
37709      }
37710      return func(collection, getIteratee(predicate, 3));
37711    }
37712
37713    /**
37714     * Creates an array of elements, sorted in ascending order by the results of
37715     * running each element in a collection thru each iteratee. This method
37716     * performs a stable sort, that is, it preserves the original sort order of
37717     * equal elements. The iteratees are invoked with one argument: (value).
37718     *
37719     * @static
37720     * @memberOf _
37721     * @since 0.1.0
37722     * @category Collection
37723     * @param {Array|Object} collection The collection to iterate over.
37724     * @param {...(Function|Function[])} [iteratees=[_.identity]]
37725     *  The iteratees to sort by.
37726     * @returns {Array} Returns the new sorted array.
37727     * @example
37728     *
37729     * var users = [
37730     *   { 'user': 'fred',   'age': 48 },
37731     *   { 'user': 'barney', 'age': 36 },
37732     *   { 'user': 'fred',   'age': 30 },
37733     *   { 'user': 'barney', 'age': 34 }
37734     * ];
37735     *
37736     * _.sortBy(users, [function(o) { return o.user; }]);
37737     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
37738     *
37739     * _.sortBy(users, ['user', 'age']);
37740     * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
37741     */
37742    var sortBy = baseRest(function(collection, iteratees) {
37743      if (collection == null) {
37744        return [];
37745      }
37746      var length = iteratees.length;
37747      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
37748        iteratees = [];
37749      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
37750        iteratees = [iteratees[0]];
37751      }
37752      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
37753    });
37754
37755    /*------------------------------------------------------------------------*/
37756
37757    /**
37758     * Gets the timestamp of the number of milliseconds that have elapsed since
37759     * the Unix epoch (1 January 1970 00:00:00 UTC).
37760     *
37761     * @static
37762     * @memberOf _
37763     * @since 2.4.0
37764     * @category Date
37765     * @returns {number} Returns the timestamp.
37766     * @example
37767     *
37768     * _.defer(function(stamp) {
37769     *   console.log(_.now() - stamp);
37770     * }, _.now());
37771     * // => Logs the number of milliseconds it took for the deferred invocation.
37772     */
37773    var now = ctxNow || function() {
37774      return root.Date.now();
37775    };
37776
37777    /*------------------------------------------------------------------------*/
37778
37779    /**
37780     * The opposite of `_.before`; this method creates a function that invokes
37781     * `func` once it's called `n` or more times.
37782     *
37783     * @static
37784     * @memberOf _
37785     * @since 0.1.0
37786     * @category Function
37787     * @param {number} n The number of calls before `func` is invoked.
37788     * @param {Function} func The function to restrict.
37789     * @returns {Function} Returns the new restricted function.
37790     * @example
37791     *
37792     * var saves = ['profile', 'settings'];
37793     *
37794     * var done = _.after(saves.length, function() {
37795     *   console.log('done saving!');
37796     * });
37797     *
37798     * _.forEach(saves, function(type) {
37799     *   asyncSave({ 'type': type, 'complete': done });
37800     * });
37801     * // => Logs 'done saving!' after the two async saves have completed.
37802     */
37803    function after(n, func) {
37804      if (typeof func != 'function') {
37805        throw new TypeError(FUNC_ERROR_TEXT);
37806      }
37807      n = toInteger(n);
37808      return function() {
37809        if (--n < 1) {
37810          return func.apply(this, arguments);
37811        }
37812      };
37813    }
37814
37815    /**
37816     * Creates a function that invokes `func`, with up to `n` arguments,
37817     * ignoring any additional arguments.
37818     *
37819     * @static
37820     * @memberOf _
37821     * @since 3.0.0
37822     * @category Function
37823     * @param {Function} func The function to cap arguments for.
37824     * @param {number} [n=func.length] The arity cap.
37825     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37826     * @returns {Function} Returns the new capped function.
37827     * @example
37828     *
37829     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
37830     * // => [6, 8, 10]
37831     */
37832    function ary(func, n, guard) {
37833      n = guard ? undefined : n;
37834      n = (func && n == null) ? func.length : n;
37835      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
37836    }
37837
37838    /**
37839     * Creates a function that invokes `func`, with the `this` binding and arguments
37840     * of the created function, while it's called less than `n` times. Subsequent
37841     * calls to the created function return the result of the last `func` invocation.
37842     *
37843     * @static
37844     * @memberOf _
37845     * @since 3.0.0
37846     * @category Function
37847     * @param {number} n The number of calls at which `func` is no longer invoked.
37848     * @param {Function} func The function to restrict.
37849     * @returns {Function} Returns the new restricted function.
37850     * @example
37851     *
37852     * jQuery(element).on('click', _.before(5, addContactToList));
37853     * // => Allows adding up to 4 contacts to the list.
37854     */
37855    function before(n, func) {
37856      var result;
37857      if (typeof func != 'function') {
37858        throw new TypeError(FUNC_ERROR_TEXT);
37859      }
37860      n = toInteger(n);
37861      return function() {
37862        if (--n > 0) {
37863          result = func.apply(this, arguments);
37864        }
37865        if (n <= 1) {
37866          func = undefined;
37867        }
37868        return result;
37869      };
37870    }
37871
37872    /**
37873     * Creates a function that invokes `func` with the `this` binding of `thisArg`
37874     * and `partials` prepended to the arguments it receives.
37875     *
37876     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
37877     * may be used as a placeholder for partially applied arguments.
37878     *
37879     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
37880     * property of bound functions.
37881     *
37882     * @static
37883     * @memberOf _
37884     * @since 0.1.0
37885     * @category Function
37886     * @param {Function} func The function to bind.
37887     * @param {*} thisArg The `this` binding of `func`.
37888     * @param {...*} [partials] The arguments to be partially applied.
37889     * @returns {Function} Returns the new bound function.
37890     * @example
37891     *
37892     * function greet(greeting, punctuation) {
37893     *   return greeting + ' ' + this.user + punctuation;
37894     * }
37895     *
37896     * var object = { 'user': 'fred' };
37897     *
37898     * var bound = _.bind(greet, object, 'hi');
37899     * bound('!');
37900     * // => 'hi fred!'
37901     *
37902     * // Bound with placeholders.
37903     * var bound = _.bind(greet, object, _, '!');
37904     * bound('hi');
37905     * // => 'hi fred!'
37906     */
37907    var bind = baseRest(function(func, thisArg, partials) {
37908      var bitmask = WRAP_BIND_FLAG;
37909      if (partials.length) {
37910        var holders = replaceHolders(partials, getHolder(bind));
37911        bitmask |= WRAP_PARTIAL_FLAG;
37912      }
37913      return createWrap(func, bitmask, thisArg, partials, holders);
37914    });
37915
37916    /**
37917     * Creates a function that invokes the method at `object[key]` with `partials`
37918     * prepended to the arguments it receives.
37919     *
37920     * This method differs from `_.bind` by allowing bound functions to reference
37921     * methods that may be redefined or don't yet exist. See
37922     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
37923     * for more details.
37924     *
37925     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
37926     * builds, may be used as a placeholder for partially applied arguments.
37927     *
37928     * @static
37929     * @memberOf _
37930     * @since 0.10.0
37931     * @category Function
37932     * @param {Object} object The object to invoke the method on.
37933     * @param {string} key The key of the method.
37934     * @param {...*} [partials] The arguments to be partially applied.
37935     * @returns {Function} Returns the new bound function.
37936     * @example
37937     *
37938     * var object = {
37939     *   'user': 'fred',
37940     *   'greet': function(greeting, punctuation) {
37941     *     return greeting + ' ' + this.user + punctuation;
37942     *   }
37943     * };
37944     *
37945     * var bound = _.bindKey(object, 'greet', 'hi');
37946     * bound('!');
37947     * // => 'hi fred!'
37948     *
37949     * object.greet = function(greeting, punctuation) {
37950     *   return greeting + 'ya ' + this.user + punctuation;
37951     * };
37952     *
37953     * bound('!');
37954     * // => 'hiya fred!'
37955     *
37956     * // Bound with placeholders.
37957     * var bound = _.bindKey(object, 'greet', _, '!');
37958     * bound('hi');
37959     * // => 'hiya fred!'
37960     */
37961    var bindKey = baseRest(function(object, key, partials) {
37962      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
37963      if (partials.length) {
37964        var holders = replaceHolders(partials, getHolder(bindKey));
37965        bitmask |= WRAP_PARTIAL_FLAG;
37966      }
37967      return createWrap(key, bitmask, object, partials, holders);
37968    });
37969
37970    /**
37971     * Creates a function that accepts arguments of `func` and either invokes
37972     * `func` returning its result, if at least `arity` number of arguments have
37973     * been provided, or returns a function that accepts the remaining `func`
37974     * arguments, and so on. The arity of `func` may be specified if `func.length`
37975     * is not sufficient.
37976     *
37977     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
37978     * may be used as a placeholder for provided arguments.
37979     *
37980     * **Note:** This method doesn't set the "length" property of curried functions.
37981     *
37982     * @static
37983     * @memberOf _
37984     * @since 2.0.0
37985     * @category Function
37986     * @param {Function} func The function to curry.
37987     * @param {number} [arity=func.length] The arity of `func`.
37988     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37989     * @returns {Function} Returns the new curried function.
37990     * @example
37991     *
37992     * var abc = function(a, b, c) {
37993     *   return [a, b, c];
37994     * };
37995     *
37996     * var curried = _.curry(abc);
37997     *
37998     * curried(1)(2)(3);
37999     * // => [1, 2, 3]
38000     *
38001     * curried(1, 2)(3);
38002     * // => [1, 2, 3]
38003     *
38004     * curried(1, 2, 3);
38005     * // => [1, 2, 3]
38006     *
38007     * // Curried with placeholders.
38008     * curried(1)(_, 3)(2);
38009     * // => [1, 2, 3]
38010     */
38011    function curry(func, arity, guard) {
38012      arity = guard ? undefined : arity;
38013      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
38014      result.placeholder = curry.placeholder;
38015      return result;
38016    }
38017
38018    /**
38019     * This method is like `_.curry` except that arguments are applied to `func`
38020     * in the manner of `_.partialRight` instead of `_.partial`.
38021     *
38022     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
38023     * builds, may be used as a placeholder for provided arguments.
38024     *
38025     * **Note:** This method doesn't set the "length" property of curried functions.
38026     *
38027     * @static
38028     * @memberOf _
38029     * @since 3.0.0
38030     * @category Function
38031     * @param {Function} func The function to curry.
38032     * @param {number} [arity=func.length] The arity of `func`.
38033     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
38034     * @returns {Function} Returns the new curried function.
38035     * @example
38036     *
38037     * var abc = function(a, b, c) {
38038     *   return [a, b, c];
38039     * };
38040     *
38041     * var curried = _.curryRight(abc);
38042     *
38043     * curried(3)(2)(1);
38044     * // => [1, 2, 3]
38045     *
38046     * curried(2, 3)(1);
38047     * // => [1, 2, 3]
38048     *
38049     * curried(1, 2, 3);
38050     * // => [1, 2, 3]
38051     *
38052     * // Curried with placeholders.
38053     * curried(3)(1, _)(2);
38054     * // => [1, 2, 3]
38055     */
38056    function curryRight(func, arity, guard) {
38057      arity = guard ? undefined : arity;
38058      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
38059      result.placeholder = curryRight.placeholder;
38060      return result;
38061    }
38062
38063    /**
38064     * Creates a debounced function that delays invoking `func` until after `wait`
38065     * milliseconds have elapsed since the last time the debounced function was
38066     * invoked. The debounced function comes with a `cancel` method to cancel
38067     * delayed `func` invocations and a `flush` method to immediately invoke them.
38068     * Provide `options` to indicate whether `func` should be invoked on the
38069     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
38070     * with the last arguments provided to the debounced function. Subsequent
38071     * calls to the debounced function return the result of the last `func`
38072     * invocation.
38073     *
38074     * **Note:** If `leading` and `trailing` options are `true`, `func` is
38075     * invoked on the trailing edge of the timeout only if the debounced function
38076     * is invoked more than once during the `wait` timeout.
38077     *
38078     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
38079     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
38080     *
38081     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
38082     * for details over the differences between `_.debounce` and `_.throttle`.
38083     *
38084     * @static
38085     * @memberOf _
38086     * @since 0.1.0
38087     * @category Function
38088     * @param {Function} func The function to debounce.
38089     * @param {number} [wait=0] The number of milliseconds to delay.
38090     * @param {Object} [options={}] The options object.
38091     * @param {boolean} [options.leading=false]
38092     *  Specify invoking on the leading edge of the timeout.
38093     * @param {number} [options.maxWait]
38094     *  The maximum time `func` is allowed to be delayed before it's invoked.
38095     * @param {boolean} [options.trailing=true]
38096     *  Specify invoking on the trailing edge of the timeout.
38097     * @returns {Function} Returns the new debounced function.
38098     * @example
38099     *
38100     * // Avoid costly calculations while the window size is in flux.
38101     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
38102     *
38103     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
38104     * jQuery(element).on('click', _.debounce(sendMail, 300, {
38105     *   'leading': true,
38106     *   'trailing': false
38107     * }));
38108     *
38109     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
38110     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
38111     * var source = new EventSource('/stream');
38112     * jQuery(source).on('message', debounced);
38113     *
38114     * // Cancel the trailing debounced invocation.
38115     * jQuery(window).on('popstate', debounced.cancel);
38116     */
38117    function debounce(func, wait, options) {
38118      var lastArgs,
38119          lastThis,
38120          maxWait,
38121          result,
38122          timerId,
38123          lastCallTime,
38124          lastInvokeTime = 0,
38125          leading = false,
38126          maxing = false,
38127          trailing = true;
38128
38129      if (typeof func != 'function') {
38130        throw new TypeError(FUNC_ERROR_TEXT);
38131      }
38132      wait = toNumber(wait) || 0;
38133      if (isObject(options)) {
38134        leading = !!options.leading;
38135        maxing = 'maxWait' in options;
38136        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
38137        trailing = 'trailing' in options ? !!options.trailing : trailing;
38138      }
38139
38140      function invokeFunc(time) {
38141        var args = lastArgs,
38142            thisArg = lastThis;
38143
38144        lastArgs = lastThis = undefined;
38145        lastInvokeTime = time;
38146        result = func.apply(thisArg, args);
38147        return result;
38148      }
38149
38150      function leadingEdge(time) {
38151        // Reset any `maxWait` timer.
38152        lastInvokeTime = time;
38153        // Start the timer for the trailing edge.
38154        timerId = setTimeout(timerExpired, wait);
38155        // Invoke the leading edge.
38156        return leading ? invokeFunc(time) : result;
38157      }
38158
38159      function remainingWait(time) {
38160        var timeSinceLastCall = time - lastCallTime,
38161            timeSinceLastInvoke = time - lastInvokeTime,
38162            timeWaiting = wait - timeSinceLastCall;
38163
38164        return maxing
38165          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
38166          : timeWaiting;
38167      }
38168
38169      function shouldInvoke(time) {
38170        var timeSinceLastCall = time - lastCallTime,
38171            timeSinceLastInvoke = time - lastInvokeTime;
38172
38173        // Either this is the first call, activity has stopped and we're at the
38174        // trailing edge, the system time has gone backwards and we're treating
38175        // it as the trailing edge, or we've hit the `maxWait` limit.
38176        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
38177          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
38178      }
38179
38180      function timerExpired() {
38181        var time = now();
38182        if (shouldInvoke(time)) {
38183          return trailingEdge(time);
38184        }
38185        // Restart the timer.
38186        timerId = setTimeout(timerExpired, remainingWait(time));
38187      }
38188
38189      function trailingEdge(time) {
38190        timerId = undefined;
38191
38192        // Only invoke if we have `lastArgs` which means `func` has been
38193        // debounced at least once.
38194        if (trailing && lastArgs) {
38195          return invokeFunc(time);
38196        }
38197        lastArgs = lastThis = undefined;
38198        return result;
38199      }
38200
38201      function cancel() {
38202        if (timerId !== undefined) {
38203          clearTimeout(timerId);
38204        }
38205        lastInvokeTime = 0;
38206        lastArgs = lastCallTime = lastThis = timerId = undefined;
38207      }
38208
38209      function flush() {
38210        return timerId === undefined ? result : trailingEdge(now());
38211      }
38212
38213      function debounced() {
38214        var time = now(),
38215            isInvoking = shouldInvoke(time);
38216
38217        lastArgs = arguments;
38218        lastThis = this;
38219        lastCallTime = time;
38220
38221        if (isInvoking) {
38222          if (timerId === undefined) {
38223            return leadingEdge(lastCallTime);
38224          }
38225          if (maxing) {
38226            // Handle invocations in a tight loop.
38227            clearTimeout(timerId);
38228            timerId = setTimeout(timerExpired, wait);
38229            return invokeFunc(lastCallTime);
38230          }
38231        }
38232        if (timerId === undefined) {
38233          timerId = setTimeout(timerExpired, wait);
38234        }
38235        return result;
38236      }
38237      debounced.cancel = cancel;
38238      debounced.flush = flush;
38239      return debounced;
38240    }
38241
38242    /**
38243     * Defers invoking the `func` until the current call stack has cleared. Any
38244     * additional arguments are provided to `func` when it's invoked.
38245     *
38246     * @static
38247     * @memberOf _
38248     * @since 0.1.0
38249     * @category Function
38250     * @param {Function} func The function to defer.
38251     * @param {...*} [args] The arguments to invoke `func` with.
38252     * @returns {number} Returns the timer id.
38253     * @example
38254     *
38255     * _.defer(function(text) {
38256     *   console.log(text);
38257     * }, 'deferred');
38258     * // => Logs 'deferred' after one millisecond.
38259     */
38260    var defer = baseRest(function(func, args) {
38261      return baseDelay(func, 1, args);
38262    });
38263
38264    /**
38265     * Invokes `func` after `wait` milliseconds. Any additional arguments are
38266     * provided to `func` when it's invoked.
38267     *
38268     * @static
38269     * @memberOf _
38270     * @since 0.1.0
38271     * @category Function
38272     * @param {Function} func The function to delay.
38273     * @param {number} wait The number of milliseconds to delay invocation.
38274     * @param {...*} [args] The arguments to invoke `func` with.
38275     * @returns {number} Returns the timer id.
38276     * @example
38277     *
38278     * _.delay(function(text) {
38279     *   console.log(text);
38280     * }, 1000, 'later');
38281     * // => Logs 'later' after one second.
38282     */
38283    var delay = baseRest(function(func, wait, args) {
38284      return baseDelay(func, toNumber(wait) || 0, args);
38285    });
38286
38287    /**
38288     * Creates a function that invokes `func` with arguments reversed.
38289     *
38290     * @static
38291     * @memberOf _
38292     * @since 4.0.0
38293     * @category Function
38294     * @param {Function} func The function to flip arguments for.
38295     * @returns {Function} Returns the new flipped function.
38296     * @example
38297     *
38298     * var flipped = _.flip(function() {
38299     *   return _.toArray(arguments);
38300     * });
38301     *
38302     * flipped('a', 'b', 'c', 'd');
38303     * // => ['d', 'c', 'b', 'a']
38304     */
38305    function flip(func) {
38306      return createWrap(func, WRAP_FLIP_FLAG);
38307    }
38308
38309    /**
38310     * Creates a function that memoizes the result of `func`. If `resolver` is
38311     * provided, it determines the cache key for storing the result based on the
38312     * arguments provided to the memoized function. By default, the first argument
38313     * provided to the memoized function is used as the map cache key. The `func`
38314     * is invoked with the `this` binding of the memoized function.
38315     *
38316     * **Note:** The cache is exposed as the `cache` property on the memoized
38317     * function. Its creation may be customized by replacing the `_.memoize.Cache`
38318     * constructor with one whose instances implement the
38319     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
38320     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
38321     *
38322     * @static
38323     * @memberOf _
38324     * @since 0.1.0
38325     * @category Function
38326     * @param {Function} func The function to have its output memoized.
38327     * @param {Function} [resolver] The function to resolve the cache key.
38328     * @returns {Function} Returns the new memoized function.
38329     * @example
38330     *
38331     * var object = { 'a': 1, 'b': 2 };
38332     * var other = { 'c': 3, 'd': 4 };
38333     *
38334     * var values = _.memoize(_.values);
38335     * values(object);
38336     * // => [1, 2]
38337     *
38338     * values(other);
38339     * // => [3, 4]
38340     *
38341     * object.a = 2;
38342     * values(object);
38343     * // => [1, 2]
38344     *
38345     * // Modify the result cache.
38346     * values.cache.set(object, ['a', 'b']);
38347     * values(object);
38348     * // => ['a', 'b']
38349     *
38350     * // Replace `_.memoize.Cache`.
38351     * _.memoize.Cache = WeakMap;
38352     */
38353    function memoize(func, resolver) {
38354      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
38355        throw new TypeError(FUNC_ERROR_TEXT);
38356      }
38357      var memoized = function() {
38358        var args = arguments,
38359            key = resolver ? resolver.apply(this, args) : args[0],
38360            cache = memoized.cache;
38361
38362        if (cache.has(key)) {
38363          return cache.get(key);
38364        }
38365        var result = func.apply(this, args);
38366        memoized.cache = cache.set(key, result) || cache;
38367        return result;
38368      };
38369      memoized.cache = new (memoize.Cache || MapCache);
38370      return memoized;
38371    }
38372
38373    // Expose `MapCache`.
38374    memoize.Cache = MapCache;
38375
38376    /**
38377     * Creates a function that negates the result of the predicate `func`. The
38378     * `func` predicate is invoked with the `this` binding and arguments of the
38379     * created function.
38380     *
38381     * @static
38382     * @memberOf _
38383     * @since 3.0.0
38384     * @category Function
38385     * @param {Function} predicate The predicate to negate.
38386     * @returns {Function} Returns the new negated function.
38387     * @example
38388     *
38389     * function isEven(n) {
38390     *   return n % 2 == 0;
38391     * }
38392     *
38393     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
38394     * // => [1, 3, 5]
38395     */
38396    function negate(predicate) {
38397      if (typeof predicate != 'function') {
38398        throw new TypeError(FUNC_ERROR_TEXT);
38399      }
38400      return function() {
38401        var args = arguments;
38402        switch (args.length) {
38403          case 0: return !predicate.call(this);
38404          case 1: return !predicate.call(this, args[0]);
38405          case 2: return !predicate.call(this, args[0], args[1]);
38406          case 3: return !predicate.call(this, args[0], args[1], args[2]);
38407        }
38408        return !predicate.apply(this, args);
38409      };
38410    }
38411
38412    /**
38413     * Creates a function that is restricted to invoking `func` once. Repeat calls
38414     * to the function return the value of the first invocation. The `func` is
38415     * invoked with the `this` binding and arguments of the created function.
38416     *
38417     * @static
38418     * @memberOf _
38419     * @since 0.1.0
38420     * @category Function
38421     * @param {Function} func The function to restrict.
38422     * @returns {Function} Returns the new restricted function.
38423     * @example
38424     *
38425     * var initialize = _.once(createApplication);
38426     * initialize();
38427     * initialize();
38428     * // => `createApplication` is invoked once
38429     */
38430    function once(func) {
38431      return before(2, func);
38432    }
38433
38434    /**
38435     * Creates a function that invokes `func` with its arguments transformed.
38436     *
38437     * @static
38438     * @since 4.0.0
38439     * @memberOf _
38440     * @category Function
38441     * @param {Function} func The function to wrap.
38442     * @param {...(Function|Function[])} [transforms=[_.identity]]
38443     *  The argument transforms.
38444     * @returns {Function} Returns the new function.
38445     * @example
38446     *
38447     * function doubled(n) {
38448     *   return n * 2;
38449     * }
38450     *
38451     * function square(n) {
38452     *   return n * n;
38453     * }
38454     *
38455     * var func = _.overArgs(function(x, y) {
38456     *   return [x, y];
38457     * }, [square, doubled]);
38458     *
38459     * func(9, 3);
38460     * // => [81, 6]
38461     *
38462     * func(10, 5);
38463     * // => [100, 10]
38464     */
38465    var overArgs = castRest(function(func, transforms) {
38466      transforms = (transforms.length == 1 && isArray(transforms[0]))
38467        ? arrayMap(transforms[0], baseUnary(getIteratee()))
38468        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
38469
38470      var funcsLength = transforms.length;
38471      return baseRest(function(args) {
38472        var index = -1,
38473            length = nativeMin(args.length, funcsLength);
38474
38475        while (++index < length) {
38476          args[index] = transforms[index].call(this, args[index]);
38477        }
38478        return apply(func, this, args);
38479      });
38480    });
38481
38482    /**
38483     * Creates a function that invokes `func` with `partials` prepended to the
38484     * arguments it receives. This method is like `_.bind` except it does **not**
38485     * alter the `this` binding.
38486     *
38487     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
38488     * builds, may be used as a placeholder for partially applied arguments.
38489     *
38490     * **Note:** This method doesn't set the "length" property of partially
38491     * applied functions.
38492     *
38493     * @static
38494     * @memberOf _
38495     * @since 0.2.0
38496     * @category Function
38497     * @param {Function} func The function to partially apply arguments to.
38498     * @param {...*} [partials] The arguments to be partially applied.
38499     * @returns {Function} Returns the new partially applied function.
38500     * @example
38501     *
38502     * function greet(greeting, name) {
38503     *   return greeting + ' ' + name;
38504     * }
38505     *
38506     * var sayHelloTo = _.partial(greet, 'hello');
38507     * sayHelloTo('fred');
38508     * // => 'hello fred'
38509     *
38510     * // Partially applied with placeholders.
38511     * var greetFred = _.partial(greet, _, 'fred');
38512     * greetFred('hi');
38513     * // => 'hi fred'
38514     */
38515    var partial = baseRest(function(func, partials) {
38516      var holders = replaceHolders(partials, getHolder(partial));
38517      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
38518    });
38519
38520    /**
38521     * This method is like `_.partial` except that partially applied arguments
38522     * are appended to the arguments it receives.
38523     *
38524     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
38525     * builds, may be used as a placeholder for partially applied arguments.
38526     *
38527     * **Note:** This method doesn't set the "length" property of partially
38528     * applied functions.
38529     *
38530     * @static
38531     * @memberOf _
38532     * @since 1.0.0
38533     * @category Function
38534     * @param {Function} func The function to partially apply arguments to.
38535     * @param {...*} [partials] The arguments to be partially applied.
38536     * @returns {Function} Returns the new partially applied function.
38537     * @example
38538     *
38539     * function greet(greeting, name) {
38540     *   return greeting + ' ' + name;
38541     * }
38542     *
38543     * var greetFred = _.partialRight(greet, 'fred');
38544     * greetFred('hi');
38545     * // => 'hi fred'
38546     *
38547     * // Partially applied with placeholders.
38548     * var sayHelloTo = _.partialRight(greet, 'hello', _);
38549     * sayHelloTo('fred');
38550     * // => 'hello fred'
38551     */
38552    var partialRight = baseRest(function(func, partials) {
38553      var holders = replaceHolders(partials, getHolder(partialRight));
38554      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
38555    });
38556
38557    /**
38558     * Creates a function that invokes `func` with arguments arranged according
38559     * to the specified `indexes` where the argument value at the first index is
38560     * provided as the first argument, the argument value at the second index is
38561     * provided as the second argument, and so on.
38562     *
38563     * @static
38564     * @memberOf _
38565     * @since 3.0.0
38566     * @category Function
38567     * @param {Function} func The function to rearrange arguments for.
38568     * @param {...(number|number[])} indexes The arranged argument indexes.
38569     * @returns {Function} Returns the new function.
38570     * @example
38571     *
38572     * var rearged = _.rearg(function(a, b, c) {
38573     *   return [a, b, c];
38574     * }, [2, 0, 1]);
38575     *
38576     * rearged('b', 'c', 'a')
38577     * // => ['a', 'b', 'c']
38578     */
38579    var rearg = flatRest(function(func, indexes) {
38580      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
38581    });
38582
38583    /**
38584     * Creates a function that invokes `func` with the `this` binding of the
38585     * created function and arguments from `start` and beyond provided as
38586     * an array.
38587     *
38588     * **Note:** This method is based on the
38589     * [rest parameter](https://mdn.io/rest_parameters).
38590     *
38591     * @static
38592     * @memberOf _
38593     * @since 4.0.0
38594     * @category Function
38595     * @param {Function} func The function to apply a rest parameter to.
38596     * @param {number} [start=func.length-1] The start position of the rest parameter.
38597     * @returns {Function} Returns the new function.
38598     * @example
38599     *
38600     * var say = _.rest(function(what, names) {
38601     *   return what + ' ' + _.initial(names).join(', ') +
38602     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
38603     * });
38604     *
38605     * say('hello', 'fred', 'barney', 'pebbles');
38606     * // => 'hello fred, barney, & pebbles'
38607     */
38608    function rest(func, start) {
38609      if (typeof func != 'function') {
38610        throw new TypeError(FUNC_ERROR_TEXT);
38611      }
38612      start = start === undefined ? start : toInteger(start);
38613      return baseRest(func, start);
38614    }
38615
38616    /**
38617     * Creates a function that invokes `func` with the `this` binding of the
38618     * create function and an array of arguments much like
38619     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
38620     *
38621     * **Note:** This method is based on the
38622     * [spread operator](https://mdn.io/spread_operator).
38623     *
38624     * @static
38625     * @memberOf _
38626     * @since 3.2.0
38627     * @category Function
38628     * @param {Function} func The function to spread arguments over.
38629     * @param {number} [start=0] The start position of the spread.
38630     * @returns {Function} Returns the new function.
38631     * @example
38632     *
38633     * var say = _.spread(function(who, what) {
38634     *   return who + ' says ' + what;
38635     * });
38636     *
38637     * say(['fred', 'hello']);
38638     * // => 'fred says hello'
38639     *
38640     * var numbers = Promise.all([
38641     *   Promise.resolve(40),
38642     *   Promise.resolve(36)
38643     * ]);
38644     *
38645     * numbers.then(_.spread(function(x, y) {
38646     *   return x + y;
38647     * }));
38648     * // => a Promise of 76
38649     */
38650    function spread(func, start) {
38651      if (typeof func != 'function') {
38652        throw new TypeError(FUNC_ERROR_TEXT);
38653      }
38654      start = start == null ? 0 : nativeMax(toInteger(start), 0);
38655      return baseRest(function(args) {
38656        var array = args[start],
38657            otherArgs = castSlice(args, 0, start);
38658
38659        if (array) {
38660          arrayPush(otherArgs, array);
38661        }
38662        return apply(func, this, otherArgs);
38663      });
38664    }
38665
38666    /**
38667     * Creates a throttled function that only invokes `func` at most once per
38668     * every `wait` milliseconds. The throttled function comes with a `cancel`
38669     * method to cancel delayed `func` invocations and a `flush` method to
38670     * immediately invoke them. Provide `options` to indicate whether `func`
38671     * should be invoked on the leading and/or trailing edge of the `wait`
38672     * timeout. The `func` is invoked with the last arguments provided to the
38673     * throttled function. Subsequent calls to the throttled function return the
38674     * result of the last `func` invocation.
38675     *
38676     * **Note:** If `leading` and `trailing` options are `true`, `func` is
38677     * invoked on the trailing edge of the timeout only if the throttled function
38678     * is invoked more than once during the `wait` timeout.
38679     *
38680     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
38681     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
38682     *
38683     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
38684     * for details over the differences between `_.throttle` and `_.debounce`.
38685     *
38686     * @static
38687     * @memberOf _
38688     * @since 0.1.0
38689     * @category Function
38690     * @param {Function} func The function to throttle.
38691     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
38692     * @param {Object} [options={}] The options object.
38693     * @param {boolean} [options.leading=true]
38694     *  Specify invoking on the leading edge of the timeout.
38695     * @param {boolean} [options.trailing=true]
38696     *  Specify invoking on the trailing edge of the timeout.
38697     * @returns {Function} Returns the new throttled function.
38698     * @example
38699     *
38700     * // Avoid excessively updating the position while scrolling.
38701     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
38702     *
38703     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
38704     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
38705     * jQuery(element).on('click', throttled);
38706     *
38707     * // Cancel the trailing throttled invocation.
38708     * jQuery(window).on('popstate', throttled.cancel);
38709     */
38710    function throttle(func, wait, options) {
38711      var leading = true,
38712          trailing = true;
38713
38714      if (typeof func != 'function') {
38715        throw new TypeError(FUNC_ERROR_TEXT);
38716      }
38717      if (isObject(options)) {
38718        leading = 'leading' in options ? !!options.leading : leading;
38719        trailing = 'trailing' in options ? !!options.trailing : trailing;
38720      }
38721      return debounce(func, wait, {
38722        'leading': leading,
38723        'maxWait': wait,
38724        'trailing': trailing
38725      });
38726    }
38727
38728    /**
38729     * Creates a function that accepts up to one argument, ignoring any
38730     * additional arguments.
38731     *
38732     * @static
38733     * @memberOf _
38734     * @since 4.0.0
38735     * @category Function
38736     * @param {Function} func The function to cap arguments for.
38737     * @returns {Function} Returns the new capped function.
38738     * @example
38739     *
38740     * _.map(['6', '8', '10'], _.unary(parseInt));
38741     * // => [6, 8, 10]
38742     */
38743    function unary(func) {
38744      return ary(func, 1);
38745    }
38746
38747    /**
38748     * Creates a function that provides `value` to `wrapper` as its first
38749     * argument. Any additional arguments provided to the function are appended
38750     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
38751     * binding of the created function.
38752     *
38753     * @static
38754     * @memberOf _
38755     * @since 0.1.0
38756     * @category Function
38757     * @param {*} value The value to wrap.
38758     * @param {Function} [wrapper=identity] The wrapper function.
38759     * @returns {Function} Returns the new function.
38760     * @example
38761     *
38762     * var p = _.wrap(_.escape, function(func, text) {
38763     *   return '<p>' + func(text) + '</p>';
38764     * });
38765     *
38766     * p('fred, barney, & pebbles');
38767     * // => '<p>fred, barney, &amp; pebbles</p>'
38768     */
38769    function wrap(value, wrapper) {
38770      return partial(castFunction(wrapper), value);
38771    }
38772
38773    /*------------------------------------------------------------------------*/
38774
38775    /**
38776     * Casts `value` as an array if it's not one.
38777     *
38778     * @static
38779     * @memberOf _
38780     * @since 4.4.0
38781     * @category Lang
38782     * @param {*} value The value to inspect.
38783     * @returns {Array} Returns the cast array.
38784     * @example
38785     *
38786     * _.castArray(1);
38787     * // => [1]
38788     *
38789     * _.castArray({ 'a': 1 });
38790     * // => [{ 'a': 1 }]
38791     *
38792     * _.castArray('abc');
38793     * // => ['abc']
38794     *
38795     * _.castArray(null);
38796     * // => [null]
38797     *
38798     * _.castArray(undefined);
38799     * // => [undefined]
38800     *
38801     * _.castArray();
38802     * // => []
38803     *
38804     * var array = [1, 2, 3];
38805     * console.log(_.castArray(array) === array);
38806     * // => true
38807     */
38808    function castArray() {
38809      if (!arguments.length) {
38810        return [];
38811      }
38812      var value = arguments[0];
38813      return isArray(value) ? value : [value];
38814    }
38815
38816    /**
38817     * Creates a shallow clone of `value`.
38818     *
38819     * **Note:** This method is loosely based on the
38820     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
38821     * and supports cloning arrays, array buffers, booleans, date objects, maps,
38822     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
38823     * arrays. The own enumerable properties of `arguments` objects are cloned
38824     * as plain objects. An empty object is returned for uncloneable values such
38825     * as error objects, functions, DOM nodes, and WeakMaps.
38826     *
38827     * @static
38828     * @memberOf _
38829     * @since 0.1.0
38830     * @category Lang
38831     * @param {*} value The value to clone.
38832     * @returns {*} Returns the cloned value.
38833     * @see _.cloneDeep
38834     * @example
38835     *
38836     * var objects = [{ 'a': 1 }, { 'b': 2 }];
38837     *
38838     * var shallow = _.clone(objects);
38839     * console.log(shallow[0] === objects[0]);
38840     * // => true
38841     */
38842    function clone(value) {
38843      return baseClone(value, CLONE_SYMBOLS_FLAG);
38844    }
38845
38846    /**
38847     * This method is like `_.clone` except that it accepts `customizer` which
38848     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
38849     * cloning is handled by the method instead. The `customizer` is invoked with
38850     * up to four arguments; (value [, index|key, object, stack]).
38851     *
38852     * @static
38853     * @memberOf _
38854     * @since 4.0.0
38855     * @category Lang
38856     * @param {*} value The value to clone.
38857     * @param {Function} [customizer] The function to customize cloning.
38858     * @returns {*} Returns the cloned value.
38859     * @see _.cloneDeepWith
38860     * @example
38861     *
38862     * function customizer(value) {
38863     *   if (_.isElement(value)) {
38864     *     return value.cloneNode(false);
38865     *   }
38866     * }
38867     *
38868     * var el = _.cloneWith(document.body, customizer);
38869     *
38870     * console.log(el === document.body);
38871     * // => false
38872     * console.log(el.nodeName);
38873     * // => 'BODY'
38874     * console.log(el.childNodes.length);
38875     * // => 0
38876     */
38877    function cloneWith(value, customizer) {
38878      customizer = typeof customizer == 'function' ? customizer : undefined;
38879      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
38880    }
38881
38882    /**
38883     * This method is like `_.clone` except that it recursively clones `value`.
38884     *
38885     * @static
38886     * @memberOf _
38887     * @since 1.0.0
38888     * @category Lang
38889     * @param {*} value The value to recursively clone.
38890     * @returns {*} Returns the deep cloned value.
38891     * @see _.clone
38892     * @example
38893     *
38894     * var objects = [{ 'a': 1 }, { 'b': 2 }];
38895     *
38896     * var deep = _.cloneDeep(objects);
38897     * console.log(deep[0] === objects[0]);
38898     * // => false
38899     */
38900    function cloneDeep(value) {
38901      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
38902    }
38903
38904    /**
38905     * This method is like `_.cloneWith` except that it recursively clones `value`.
38906     *
38907     * @static
38908     * @memberOf _
38909     * @since 4.0.0
38910     * @category Lang
38911     * @param {*} value The value to recursively clone.
38912     * @param {Function} [customizer] The function to customize cloning.
38913     * @returns {*} Returns the deep cloned value.
38914     * @see _.cloneWith
38915     * @example
38916     *
38917     * function customizer(value) {
38918     *   if (_.isElement(value)) {
38919     *     return value.cloneNode(true);
38920     *   }
38921     * }
38922     *
38923     * var el = _.cloneDeepWith(document.body, customizer);
38924     *
38925     * console.log(el === document.body);
38926     * // => false
38927     * console.log(el.nodeName);
38928     * // => 'BODY'
38929     * console.log(el.childNodes.length);
38930     * // => 20
38931     */
38932    function cloneDeepWith(value, customizer) {
38933      customizer = typeof customizer == 'function' ? customizer : undefined;
38934      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
38935    }
38936
38937    /**
38938     * Checks if `object` conforms to `source` by invoking the predicate
38939     * properties of `source` with the corresponding property values of `object`.
38940     *
38941     * **Note:** This method is equivalent to `_.conforms` when `source` is
38942     * partially applied.
38943     *
38944     * @static
38945     * @memberOf _
38946     * @since 4.14.0
38947     * @category Lang
38948     * @param {Object} object The object to inspect.
38949     * @param {Object} source The object of property predicates to conform to.
38950     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
38951     * @example
38952     *
38953     * var object = { 'a': 1, 'b': 2 };
38954     *
38955     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
38956     * // => true
38957     *
38958     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
38959     * // => false
38960     */
38961    function conformsTo(object, source) {
38962      return source == null || baseConformsTo(object, source, keys(source));
38963    }
38964
38965    /**
38966     * Performs a
38967     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
38968     * comparison between two values to determine if they are equivalent.
38969     *
38970     * @static
38971     * @memberOf _
38972     * @since 4.0.0
38973     * @category Lang
38974     * @param {*} value The value to compare.
38975     * @param {*} other The other value to compare.
38976     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
38977     * @example
38978     *
38979     * var object = { 'a': 1 };
38980     * var other = { 'a': 1 };
38981     *
38982     * _.eq(object, object);
38983     * // => true
38984     *
38985     * _.eq(object, other);
38986     * // => false
38987     *
38988     * _.eq('a', 'a');
38989     * // => true
38990     *
38991     * _.eq('a', Object('a'));
38992     * // => false
38993     *
38994     * _.eq(NaN, NaN);
38995     * // => true
38996     */
38997    function eq(value, other) {
38998      return value === other || (value !== value && other !== other);
38999    }
39000
39001    /**
39002     * Checks if `value` is greater than `other`.
39003     *
39004     * @static
39005     * @memberOf _
39006     * @since 3.9.0
39007     * @category Lang
39008     * @param {*} value The value to compare.
39009     * @param {*} other The other value to compare.
39010     * @returns {boolean} Returns `true` if `value` is greater than `other`,
39011     *  else `false`.
39012     * @see _.lt
39013     * @example
39014     *
39015     * _.gt(3, 1);
39016     * // => true
39017     *
39018     * _.gt(3, 3);
39019     * // => false
39020     *
39021     * _.gt(1, 3);
39022     * // => false
39023     */
39024    var gt = createRelationalOperation(baseGt);
39025
39026    /**
39027     * Checks if `value` is greater than or equal to `other`.
39028     *
39029     * @static
39030     * @memberOf _
39031     * @since 3.9.0
39032     * @category Lang
39033     * @param {*} value The value to compare.
39034     * @param {*} other The other value to compare.
39035     * @returns {boolean} Returns `true` if `value` is greater than or equal to
39036     *  `other`, else `false`.
39037     * @see _.lte
39038     * @example
39039     *
39040     * _.gte(3, 1);
39041     * // => true
39042     *
39043     * _.gte(3, 3);
39044     * // => true
39045     *
39046     * _.gte(1, 3);
39047     * // => false
39048     */
39049    var gte = createRelationalOperation(function(value, other) {
39050      return value >= other;
39051    });
39052
39053    /**
39054     * Checks if `value` is likely an `arguments` object.
39055     *
39056     * @static
39057     * @memberOf _
39058     * @since 0.1.0
39059     * @category Lang
39060     * @param {*} value The value to check.
39061     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
39062     *  else `false`.
39063     * @example
39064     *
39065     * _.isArguments(function() { return arguments; }());
39066     * // => true
39067     *
39068     * _.isArguments([1, 2, 3]);
39069     * // => false
39070     */
39071    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
39072      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
39073        !propertyIsEnumerable.call(value, 'callee');
39074    };
39075
39076    /**
39077     * Checks if `value` is classified as an `Array` object.
39078     *
39079     * @static
39080     * @memberOf _
39081     * @since 0.1.0
39082     * @category Lang
39083     * @param {*} value The value to check.
39084     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
39085     * @example
39086     *
39087     * _.isArray([1, 2, 3]);
39088     * // => true
39089     *
39090     * _.isArray(document.body.children);
39091     * // => false
39092     *
39093     * _.isArray('abc');
39094     * // => false
39095     *
39096     * _.isArray(_.noop);
39097     * // => false
39098     */
39099    var isArray = Array.isArray;
39100
39101    /**
39102     * Checks if `value` is classified as an `ArrayBuffer` object.
39103     *
39104     * @static
39105     * @memberOf _
39106     * @since 4.3.0
39107     * @category Lang
39108     * @param {*} value The value to check.
39109     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
39110     * @example
39111     *
39112     * _.isArrayBuffer(new ArrayBuffer(2));
39113     * // => true
39114     *
39115     * _.isArrayBuffer(new Array(2));
39116     * // => false
39117     */
39118    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
39119
39120    /**
39121     * Checks if `value` is array-like. A value is considered array-like if it's
39122     * not a function and has a `value.length` that's an integer greater than or
39123     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
39124     *
39125     * @static
39126     * @memberOf _
39127     * @since 4.0.0
39128     * @category Lang
39129     * @param {*} value The value to check.
39130     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
39131     * @example
39132     *
39133     * _.isArrayLike([1, 2, 3]);
39134     * // => true
39135     *
39136     * _.isArrayLike(document.body.children);
39137     * // => true
39138     *
39139     * _.isArrayLike('abc');
39140     * // => true
39141     *
39142     * _.isArrayLike(_.noop);
39143     * // => false
39144     */
39145    function isArrayLike(value) {
39146      return value != null && isLength(value.length) && !isFunction(value);
39147    }
39148
39149    /**
39150     * This method is like `_.isArrayLike` except that it also checks if `value`
39151     * is an object.
39152     *
39153     * @static
39154     * @memberOf _
39155     * @since 4.0.0
39156     * @category Lang
39157     * @param {*} value The value to check.
39158     * @returns {boolean} Returns `true` if `value` is an array-like object,
39159     *  else `false`.
39160     * @example
39161     *
39162     * _.isArrayLikeObject([1, 2, 3]);
39163     * // => true
39164     *
39165     * _.isArrayLikeObject(document.body.children);
39166     * // => true
39167     *
39168     * _.isArrayLikeObject('abc');
39169     * // => false
39170     *
39171     * _.isArrayLikeObject(_.noop);
39172     * // => false
39173     */
39174    function isArrayLikeObject(value) {
39175      return isObjectLike(value) && isArrayLike(value);
39176    }
39177
39178    /**
39179     * Checks if `value` is classified as a boolean primitive or object.
39180     *
39181     * @static
39182     * @memberOf _
39183     * @since 0.1.0
39184     * @category Lang
39185     * @param {*} value The value to check.
39186     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
39187     * @example
39188     *
39189     * _.isBoolean(false);
39190     * // => true
39191     *
39192     * _.isBoolean(null);
39193     * // => false
39194     */
39195    function isBoolean(value) {
39196      return value === true || value === false ||
39197        (isObjectLike(value) && baseGetTag(value) == boolTag);
39198    }
39199
39200    /**
39201     * Checks if `value` is a buffer.
39202     *
39203     * @static
39204     * @memberOf _
39205     * @since 4.3.0
39206     * @category Lang
39207     * @param {*} value The value to check.
39208     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
39209     * @example
39210     *
39211     * _.isBuffer(new Buffer(2));
39212     * // => true
39213     *
39214     * _.isBuffer(new Uint8Array(2));
39215     * // => false
39216     */
39217    var isBuffer = nativeIsBuffer || stubFalse;
39218
39219    /**
39220     * Checks if `value` is classified as a `Date` object.
39221     *
39222     * @static
39223     * @memberOf _
39224     * @since 0.1.0
39225     * @category Lang
39226     * @param {*} value The value to check.
39227     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
39228     * @example
39229     *
39230     * _.isDate(new Date);
39231     * // => true
39232     *
39233     * _.isDate('Mon April 23 2012');
39234     * // => false
39235     */
39236    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
39237
39238    /**
39239     * Checks if `value` is likely a DOM element.
39240     *
39241     * @static
39242     * @memberOf _
39243     * @since 0.1.0
39244     * @category Lang
39245     * @param {*} value The value to check.
39246     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
39247     * @example
39248     *
39249     * _.isElement(document.body);
39250     * // => true
39251     *
39252     * _.isElement('<body>');
39253     * // => false
39254     */
39255    function isElement(value) {
39256      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
39257    }
39258
39259    /**
39260     * Checks if `value` is an empty object, collection, map, or set.
39261     *
39262     * Objects are considered empty if they have no own enumerable string keyed
39263     * properties.
39264     *
39265     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
39266     * jQuery-like collections are considered empty if they have a `length` of `0`.
39267     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
39268     *
39269     * @static
39270     * @memberOf _
39271     * @since 0.1.0
39272     * @category Lang
39273     * @param {*} value The value to check.
39274     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
39275     * @example
39276     *
39277     * _.isEmpty(null);
39278     * // => true
39279     *
39280     * _.isEmpty(true);
39281     * // => true
39282     *
39283     * _.isEmpty(1);
39284     * // => true
39285     *
39286     * _.isEmpty([1, 2, 3]);
39287     * // => false
39288     *
39289     * _.isEmpty({ 'a': 1 });
39290     * // => false
39291     */
39292    function isEmpty(value) {
39293      if (value == null) {
39294        return true;
39295      }
39296      if (isArrayLike(value) &&
39297          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
39298            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
39299        return !value.length;
39300      }
39301      var tag = getTag(value);
39302      if (tag == mapTag || tag == setTag) {
39303        return !value.size;
39304      }
39305      if (isPrototype(value)) {
39306        return !baseKeys(value).length;
39307      }
39308      for (var key in value) {
39309        if (hasOwnProperty.call(value, key)) {
39310          return false;
39311        }
39312      }
39313      return true;
39314    }
39315
39316    /**
39317     * Performs a deep comparison between two values to determine if they are
39318     * equivalent.
39319     *
39320     * **Note:** This method supports comparing arrays, array buffers, booleans,
39321     * date objects, error objects, maps, numbers, `Object` objects, regexes,
39322     * sets, strings, symbols, and typed arrays. `Object` objects are compared
39323     * by their own, not inherited, enumerable properties. Functions and DOM
39324     * nodes are compared by strict equality, i.e. `===`.
39325     *
39326     * @static
39327     * @memberOf _
39328     * @since 0.1.0
39329     * @category Lang
39330     * @param {*} value The value to compare.
39331     * @param {*} other The other value to compare.
39332     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
39333     * @example
39334     *
39335     * var object = { 'a': 1 };
39336     * var other = { 'a': 1 };
39337     *
39338     * _.isEqual(object, other);
39339     * // => true
39340     *
39341     * object === other;
39342     * // => false
39343     */
39344    function isEqual(value, other) {
39345      return baseIsEqual(value, other);
39346    }
39347
39348    /**
39349     * This method is like `_.isEqual` except that it accepts `customizer` which
39350     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
39351     * are handled by the method instead. The `customizer` is invoked with up to
39352     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
39353     *
39354     * @static
39355     * @memberOf _
39356     * @since 4.0.0
39357     * @category Lang
39358     * @param {*} value The value to compare.
39359     * @param {*} other The other value to compare.
39360     * @param {Function} [customizer] The function to customize comparisons.
39361     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
39362     * @example
39363     *
39364     * function isGreeting(value) {
39365     *   return /^h(?:i|ello)$/.test(value);
39366     * }
39367     *
39368     * function customizer(objValue, othValue) {
39369     *   if (isGreeting(objValue) && isGreeting(othValue)) {
39370     *     return true;
39371     *   }
39372     * }
39373     *
39374     * var array = ['hello', 'goodbye'];
39375     * var other = ['hi', 'goodbye'];
39376     *
39377     * _.isEqualWith(array, other, customizer);
39378     * // => true
39379     */
39380    function isEqualWith(value, other, customizer) {
39381      customizer = typeof customizer == 'function' ? customizer : undefined;
39382      var result = customizer ? customizer(value, other) : undefined;
39383      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
39384    }
39385
39386    /**
39387     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
39388     * `SyntaxError`, `TypeError`, or `URIError` object.
39389     *
39390     * @static
39391     * @memberOf _
39392     * @since 3.0.0
39393     * @category Lang
39394     * @param {*} value The value to check.
39395     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
39396     * @example
39397     *
39398     * _.isError(new Error);
39399     * // => true
39400     *
39401     * _.isError(Error);
39402     * // => false
39403     */
39404    function isError(value) {
39405      if (!isObjectLike(value)) {
39406        return false;
vendor: 6,607 bytes, lines 39407-39644
39407      }
39408      var tag = baseGetTag(value);
39409      return tag == errorTag || tag == domExcTag ||
39410        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
39411    }
39412
39413    /**
39414     * Checks if `value` is a finite primitive number.
39415     *
39416     * **Note:** This method is based on
39417     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
39418     *
39419     * @static
39420     * @memberOf _
39421     * @since 0.1.0
39422     * @category Lang
39423     * @param {*} value The value to check.
39424     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
39425     * @example
39426     *
39427     * _.isFinite(3);
39428     * // => true
39429     *
39430     * _.isFinite(Number.MIN_VALUE);
39431     * // => true
39432     *
39433     * _.isFinite(Infinity);
39434     * // => false
39435     *
39436     * _.isFinite('3');
39437     * // => false
39438     */
39439    function isFinite(value) {
39440      return typeof value == 'number' && nativeIsFinite(value);
39441    }
39442
39443    /**
39444     * Checks if `value` is classified as a `Function` object.
39445     *
39446     * @static
39447     * @memberOf _
39448     * @since 0.1.0
39449     * @category Lang
39450     * @param {*} value The value to check.
39451     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
39452     * @example
39453     *
39454     * _.isFunction(_);
39455     * // => true
39456     *
39457     * _.isFunction(/abc/);
39458     * // => false
39459     */
39460    function isFunction(value) {
39461      if (!isObject(value)) {
39462        return false;
39463      }
39464      // The use of `Object#toString` avoids issues with the `typeof` operator
39465      // in Safari 9 which returns 'object' for typed arrays and other constructors.
39466      var tag = baseGetTag(value);
39467      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
39468    }
39469
39470    /**
39471     * Checks if `value` is an integer.
39472     *
39473     * **Note:** This method is based on
39474     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
39475     *
39476     * @static
39477     * @memberOf _
39478     * @since 4.0.0
39479     * @category Lang
39480     * @param {*} value The value to check.
39481     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
39482     * @example
39483     *
39484     * _.isInteger(3);
39485     * // => true
39486     *
39487     * _.isInteger(Number.MIN_VALUE);
39488     * // => false
39489     *
39490     * _.isInteger(Infinity);
39491     * // => false
39492     *
39493     * _.isInteger('3');
39494     * // => false
39495     */
39496    function isInteger(value) {
39497      return typeof value == 'number' && value == toInteger(value);
39498    }
39499
39500    /**
39501     * Checks if `value` is a valid array-like length.
39502     *
39503     * **Note:** This method is loosely based on
39504     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
39505     *
39506     * @static
39507     * @memberOf _
39508     * @since 4.0.0
39509     * @category Lang
39510     * @param {*} value The value to check.
39511     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
39512     * @example
39513     *
39514     * _.isLength(3);
39515     * // => true
39516     *
39517     * _.isLength(Number.MIN_VALUE);
39518     * // => false
39519     *
39520     * _.isLength(Infinity);
39521     * // => false
39522     *
39523     * _.isLength('3');
39524     * // => false
39525     */
39526    function isLength(value) {
39527      return typeof value == 'number' &&
39528        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
39529    }
39530
39531    /**
39532     * Checks if `value` is the
39533     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
39534     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
39535     *
39536     * @static
39537     * @memberOf _
39538     * @since 0.1.0
39539     * @category Lang
39540     * @param {*} value The value to check.
39541     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
39542     * @example
39543     *
39544     * _.isObject({});
39545     * // => true
39546     *
39547     * _.isObject([1, 2, 3]);
39548     * // => true
39549     *
39550     * _.isObject(_.noop);
39551     * // => true
39552     *
39553     * _.isObject(null);
39554     * // => false
39555     */
39556    function isObject(value) {
39557      var type = typeof value;
39558      return value != null && (type == 'object' || type == 'function');
39559    }
39560
39561    /**
39562     * Checks if `value` is object-like. A value is object-like if it's not `null`
39563     * and has a `typeof` result of "object".
39564     *
39565     * @static
39566     * @memberOf _
39567     * @since 4.0.0
39568     * @category Lang
39569     * @param {*} value The value to check.
39570     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
39571     * @example
39572     *
39573     * _.isObjectLike({});
39574     * // => true
39575     *
39576     * _.isObjectLike([1, 2, 3]);
39577     * // => true
39578     *
39579     * _.isObjectLike(_.noop);
39580     * // => false
39581     *
39582     * _.isObjectLike(null);
39583     * // => false
39584     */
39585    function isObjectLike(value) {
39586      return value != null && typeof value == 'object';
39587    }
39588
39589    /**
39590     * Checks if `value` is classified as a `Map` object.
39591     *
39592     * @static
39593     * @memberOf _
39594     * @since 4.3.0
39595     * @category Lang
39596     * @param {*} value The value to check.
39597     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
39598     * @example
39599     *
39600     * _.isMap(new Map);
39601     * // => true
39602     *
39603     * _.isMap(new WeakMap);
39604     * // => false
39605     */
39606    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
39607
39608    /**
39609     * Performs a partial deep comparison between `object` and `source` to
39610     * determine if `object` contains equivalent property values.
39611     *
39612     * **Note:** This method is equivalent to `_.matches` when `source` is
39613     * partially applied.
39614     *
39615     * Partial comparisons will match empty array and empty object `source`
39616     * values against any array or object value, respectively. See `_.isEqual`
39617     * for a list of supported value comparisons.
39618     *
39619     * @static
39620     * @memberOf _
39621     * @since 3.0.0
39622     * @category Lang
39623     * @param {Object} object The object to inspect.
39624     * @param {Object} source The object of property values to match.
39625     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
39626     * @example
39627     *
39628     * var object = { 'a': 1, 'b': 2 };
39629     *
39630     * _.isMatch(object, { 'b': 2 });
39631     * // => true
39632     *
39633     * _.isMatch(object, { 'b': 1 });
39634     * // => false
39635     */
39636    function isMatch(object, source) {
39637      return object === source || baseIsMatch(object, source, getMatchData(source));
39638    }
39639
39640    /**
39641     * This method is like `_.isMatch` except that it accepts `customizer` which
39642     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
39643     * are handled by the method instead. The `customizer` is invoked with five
39644     * arguments: (objValue, srcValue, index|key, object, source).
vendor: 12,241 bytes, lines 39645-40110
39645     *
39646     * @static
39647     * @memberOf _
39648     * @since 4.0.0
39649     * @category Lang
39650     * @param {Object} object The object to inspect.
39651     * @param {Object} source The object of property values to match.
39652     * @param {Function} [customizer] The function to customize comparisons.
39653     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
39654     * @example
39655     *
39656     * function isGreeting(value) {
39657     *   return /^h(?:i|ello)$/.test(value);
39658     * }
39659     *
39660     * function customizer(objValue, srcValue) {
39661     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
39662     *     return true;
39663     *   }
39664     * }
39665     *
39666     * var object = { 'greeting': 'hello' };
39667     * var source = { 'greeting': 'hi' };
39668     *
39669     * _.isMatchWith(object, source, customizer);
39670     * // => true
39671     */
39672    function isMatchWith(object, source, customizer) {
39673      customizer = typeof customizer == 'function' ? customizer : undefined;
39674      return baseIsMatch(object, source, getMatchData(source), customizer);
39675    }
39676
39677    /**
39678     * Checks if `value` is `NaN`.
39679     *
39680     * **Note:** This method is based on
39681     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
39682     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
39683     * `undefined` and other non-number values.
39684     *
39685     * @static
39686     * @memberOf _
39687     * @since 0.1.0
39688     * @category Lang
39689     * @param {*} value The value to check.
39690     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
39691     * @example
39692     *
39693     * _.isNaN(NaN);
39694     * // => true
39695     *
39696     * _.isNaN(new Number(NaN));
39697     * // => true
39698     *
39699     * isNaN(undefined);
39700     * // => true
39701     *
39702     * _.isNaN(undefined);
39703     * // => false
39704     */
39705    function isNaN(value) {
39706      // An `NaN` primitive is the only value that is not equal to itself.
39707      // Perform the `toStringTag` check first to avoid errors with some
39708      // ActiveX objects in IE.
39709      return isNumber(value) && value != +value;
39710    }
39711
39712    /**
39713     * Checks if `value` is a pristine native function.
39714     *
39715     * **Note:** This method can't reliably detect native functions in the presence
39716     * of the core-js package because core-js circumvents this kind of detection.
39717     * Despite multiple requests, the core-js maintainer has made it clear: any
39718     * attempt to fix the detection will be obstructed. As a result, we're left
39719     * with little choice but to throw an error. Unfortunately, this also affects
39720     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
39721     * which rely on core-js.
39722     *
39723     * @static
39724     * @memberOf _
39725     * @since 3.0.0
39726     * @category Lang
39727     * @param {*} value The value to check.
39728     * @returns {boolean} Returns `true` if `value` is a native function,
39729     *  else `false`.
39730     * @example
39731     *
39732     * _.isNative(Array.prototype.push);
39733     * // => true
39734     *
39735     * _.isNative(_);
39736     * // => false
39737     */
39738    function isNative(value) {
39739      if (isMaskable(value)) {
39740        throw new Error(CORE_ERROR_TEXT);
39741      }
39742      return baseIsNative(value);
39743    }
39744
39745    /**
39746     * Checks if `value` is `null`.
39747     *
39748     * @static
39749     * @memberOf _
39750     * @since 0.1.0
39751     * @category Lang
39752     * @param {*} value The value to check.
39753     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
39754     * @example
39755     *
39756     * _.isNull(null);
39757     * // => true
39758     *
39759     * _.isNull(void 0);
39760     * // => false
39761     */
39762    function isNull(value) {
39763      return value === null;
39764    }
39765
39766    /**
39767     * Checks if `value` is `null` or `undefined`.
39768     *
39769     * @static
39770     * @memberOf _
39771     * @since 4.0.0
39772     * @category Lang
39773     * @param {*} value The value to check.
39774     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
39775     * @example
39776     *
39777     * _.isNil(null);
39778     * // => true
39779     *
39780     * _.isNil(void 0);
39781     * // => true
39782     *
39783     * _.isNil(NaN);
39784     * // => false
39785     */
39786    function isNil(value) {
39787      return value == null;
39788    }
39789
39790    /**
39791     * Checks if `value` is classified as a `Number` primitive or object.
39792     *
39793     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
39794     * classified as numbers, use the `_.isFinite` method.
39795     *
39796     * @static
39797     * @memberOf _
39798     * @since 0.1.0
39799     * @category Lang
39800     * @param {*} value The value to check.
39801     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
39802     * @example
39803     *
39804     * _.isNumber(3);
39805     * // => true
39806     *
39807     * _.isNumber(Number.MIN_VALUE);
39808     * // => true
39809     *
39810     * _.isNumber(Infinity);
39811     * // => true
39812     *
39813     * _.isNumber('3');
39814     * // => false
39815     */
39816    function isNumber(value) {
39817      return typeof value == 'number' ||
39818        (isObjectLike(value) && baseGetTag(value) == numberTag);
39819    }
39820
39821    /**
39822     * Checks if `value` is a plain object, that is, an object created by the
39823     * `Object` constructor or one with a `[[Prototype]]` of `null`.
39824     *
39825     * @static
39826     * @memberOf _
39827     * @since 0.8.0
39828     * @category Lang
39829     * @param {*} value The value to check.
39830     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
39831     * @example
39832     *
39833     * function Foo() {
39834     *   this.a = 1;
39835     * }
39836     *
39837     * _.isPlainObject(new Foo);
39838     * // => false
39839     *
39840     * _.isPlainObject([1, 2, 3]);
39841     * // => false
39842     *
39843     * _.isPlainObject({ 'x': 0, 'y': 0 });
39844     * // => true
39845     *
39846     * _.isPlainObject(Object.create(null));
39847     * // => true
39848     */
39849    function isPlainObject(value) {
39850      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
39851        return false;
39852      }
39853      var proto = getPrototype(value);
39854      if (proto === null) {
39855        return true;
39856      }
39857      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
39858      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
39859        funcToString.call(Ctor) == objectCtorString;
39860    }
39861
39862    /**
39863     * Checks if `value` is classified as a `RegExp` object.
39864     *
39865     * @static
39866     * @memberOf _
39867     * @since 0.1.0
39868     * @category Lang
39869     * @param {*} value The value to check.
39870     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
39871     * @example
39872     *
39873     * _.isRegExp(/abc/);
39874     * // => true
39875     *
39876     * _.isRegExp('/abc/');
39877     * // => false
39878     */
39879    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
39880
39881    /**
39882     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
39883     * double precision number which isn't the result of a rounded unsafe integer.
39884     *
39885     * **Note:** This method is based on
39886     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
39887     *
39888     * @static
39889     * @memberOf _
39890     * @since 4.0.0
39891     * @category Lang
39892     * @param {*} value The value to check.
39893     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
39894     * @example
39895     *
39896     * _.isSafeInteger(3);
39897     * // => true
39898     *
39899     * _.isSafeInteger(Number.MIN_VALUE);
39900     * // => false
39901     *
39902     * _.isSafeInteger(Infinity);
39903     * // => false
39904     *
39905     * _.isSafeInteger('3');
39906     * // => false
39907     */
39908    function isSafeInteger(value) {
39909      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
39910    }
39911
39912    /**
39913     * Checks if `value` is classified as a `Set` object.
39914     *
39915     * @static
39916     * @memberOf _
39917     * @since 4.3.0
39918     * @category Lang
39919     * @param {*} value The value to check.
39920     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
39921     * @example
39922     *
39923     * _.isSet(new Set);
39924     * // => true
39925     *
39926     * _.isSet(new WeakSet);
39927     * // => false
39928     */
39929    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
39930
39931    /**
39932     * Checks if `value` is classified as a `String` primitive or object.
39933     *
39934     * @static
39935     * @since 0.1.0
39936     * @memberOf _
39937     * @category Lang
39938     * @param {*} value The value to check.
39939     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
39940     * @example
39941     *
39942     * _.isString('abc');
39943     * // => true
39944     *
39945     * _.isString(1);
39946     * // => false
39947     */
39948    function isString(value) {
39949      return typeof value == 'string' ||
39950        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
39951    }
39952
39953    /**
39954     * Checks if `value` is classified as a `Symbol` primitive or object.
39955     *
39956     * @static
39957     * @memberOf _
39958     * @since 4.0.0
39959     * @category Lang
39960     * @param {*} value The value to check.
39961     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
39962     * @example
39963     *
39964     * _.isSymbol(Symbol.iterator);
39965     * // => true
39966     *
39967     * _.isSymbol('abc');
39968     * // => false
39969     */
39970    function isSymbol(value) {
39971      return typeof value == 'symbol' ||
39972        (isObjectLike(value) && baseGetTag(value) == symbolTag);
39973    }
39974
39975    /**
39976     * Checks if `value` is classified as a typed array.
39977     *
39978     * @static
39979     * @memberOf _
39980     * @since 3.0.0
39981     * @category Lang
39982     * @param {*} value The value to check.
39983     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
39984     * @example
39985     *
39986     * _.isTypedArray(new Uint8Array);
39987     * // => true
39988     *
39989     * _.isTypedArray([]);
39990     * // => false
39991     */
39992    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
39993
39994    /**
39995     * Checks if `value` is `undefined`.
39996     *
39997     * @static
39998     * @since 0.1.0
39999     * @memberOf _
40000     * @category Lang
40001     * @param {*} value The value to check.
40002     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
40003     * @example
40004     *
40005     * _.isUndefined(void 0);
40006     * // => true
40007     *
40008     * _.isUndefined(null);
40009     * // => false
40010     */
40011    function isUndefined(value) {
40012      return value === undefined;
40013    }
40014
40015    /**
40016     * Checks if `value` is classified as a `WeakMap` object.
40017     *
40018     * @static
40019     * @memberOf _
40020     * @since 4.3.0
40021     * @category Lang
40022     * @param {*} value The value to check.
40023     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
40024     * @example
40025     *
40026     * _.isWeakMap(new WeakMap);
40027     * // => true
40028     *
40029     * _.isWeakMap(new Map);
40030     * // => false
40031     */
40032    function isWeakMap(value) {
40033      return isObjectLike(value) && getTag(value) == weakMapTag;
40034    }
40035
40036    /**
40037     * Checks if `value` is classified as a `WeakSet` object.
40038     *
40039     * @static
40040     * @memberOf _
40041     * @since 4.3.0
40042     * @category Lang
40043     * @param {*} value The value to check.
40044     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
40045     * @example
40046     *
40047     * _.isWeakSet(new WeakSet);
40048     * // => true
40049     *
40050     * _.isWeakSet(new Set);
40051     * // => false
40052     */
40053    function isWeakSet(value) {
40054      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
40055    }
40056
40057    /**
40058     * Checks if `value` is less than `other`.
40059     *
40060     * @static
40061     * @memberOf _
40062     * @since 3.9.0
40063     * @category Lang
40064     * @param {*} value The value to compare.
40065     * @param {*} other The other value to compare.
40066     * @returns {boolean} Returns `true` if `value` is less than `other`,
40067     *  else `false`.
40068     * @see _.gt
40069     * @example
40070     *
40071     * _.lt(1, 3);
40072     * // => true
40073     *
40074     * _.lt(3, 3);
40075     * // => false
40076     *
40077     * _.lt(3, 1);
40078     * // => false
40079     */
40080    var lt = createRelationalOperation(baseLt);
40081
40082    /**
40083     * Checks if `value` is less than or equal to `other`.
40084     *
40085     * @static
40086     * @memberOf _
40087     * @since 3.9.0
40088     * @category Lang
40089     * @param {*} value The value to compare.
40090     * @param {*} other The other value to compare.
40091     * @returns {boolean} Returns `true` if `value` is less than or equal to
40092     *  `other`, else `false`.
40093     * @see _.gte
40094     * @example
40095     *
40096     * _.lte(1, 3);
40097     * // => true
40098     *
40099     * _.lte(3, 3);
40100     * // => true
40101     *
40102     * _.lte(3, 1);
40103     * // => false
40104     */
40105    var lte = createRelationalOperation(function(value, other) {
40106      return value <= other;
40107    });
40108
40109    /**
40110     * Converts `value` to an array.
vendor: 11,756 bytes, lines 40111-40540
40111     *
40112     * @static
40113     * @since 0.1.0
40114     * @memberOf _
40115     * @category Lang
40116     * @param {*} value The value to convert.
40117     * @returns {Array} Returns the converted array.
40118     * @example
40119     *
40120     * _.toArray({ 'a': 1, 'b': 2 });
40121     * // => [1, 2]
40122     *
40123     * _.toArray('abc');
40124     * // => ['a', 'b', 'c']
40125     *
40126     * _.toArray(1);
40127     * // => []
40128     *
40129     * _.toArray(null);
40130     * // => []
40131     */
40132    function toArray(value) {
40133      if (!value) {
40134        return [];
40135      }
40136      if (isArrayLike(value)) {
40137        return isString(value) ? stringToArray(value) : copyArray(value);
40138      }
40139      if (symIterator && value[symIterator]) {
40140        return iteratorToArray(value[symIterator]());
40141      }
40142      var tag = getTag(value),
40143          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
40144
40145      return func(value);
40146    }
40147
40148    /**
40149     * Converts `value` to a finite number.
40150     *
40151     * @static
40152     * @memberOf _
40153     * @since 4.12.0
40154     * @category Lang
40155     * @param {*} value The value to convert.
40156     * @returns {number} Returns the converted number.
40157     * @example
40158     *
40159     * _.toFinite(3.2);
40160     * // => 3.2
40161     *
40162     * _.toFinite(Number.MIN_VALUE);
40163     * // => 5e-324
40164     *
40165     * _.toFinite(Infinity);
40166     * // => 1.7976931348623157e+308
40167     *
40168     * _.toFinite('3.2');
40169     * // => 3.2
40170     */
40171    function toFinite(value) {
40172      if (!value) {
40173        return value === 0 ? value : 0;
40174      }
40175      value = toNumber(value);
40176      if (value === INFINITY || value === -INFINITY) {
40177        var sign = (value < 0 ? -1 : 1);
40178        return sign * MAX_INTEGER;
40179      }
40180      return value === value ? value : 0;
40181    }
40182
40183    /**
40184     * Converts `value` to an integer.
40185     *
40186     * **Note:** This method is loosely based on
40187     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
40188     *
40189     * @static
40190     * @memberOf _
40191     * @since 4.0.0
40192     * @category Lang
40193     * @param {*} value The value to convert.
40194     * @returns {number} Returns the converted integer.
40195     * @example
40196     *
40197     * _.toInteger(3.2);
40198     * // => 3
40199     *
40200     * _.toInteger(Number.MIN_VALUE);
40201     * // => 0
40202     *
40203     * _.toInteger(Infinity);
40204     * // => 1.7976931348623157e+308
40205     *
40206     * _.toInteger('3.2');
40207     * // => 3
40208     */
40209    function toInteger(value) {
40210      var result = toFinite(value),
40211          remainder = result % 1;
40212
40213      return result === result ? (remainder ? result - remainder : result) : 0;
40214    }
40215
40216    /**
40217     * Converts `value` to an integer suitable for use as the length of an
40218     * array-like object.
40219     *
40220     * **Note:** This method is based on
40221     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
40222     *
40223     * @static
40224     * @memberOf _
40225     * @since 4.0.0
40226     * @category Lang
40227     * @param {*} value The value to convert.
40228     * @returns {number} Returns the converted integer.
40229     * @example
40230     *
40231     * _.toLength(3.2);
40232     * // => 3
40233     *
40234     * _.toLength(Number.MIN_VALUE);
40235     * // => 0
40236     *
40237     * _.toLength(Infinity);
40238     * // => 4294967295
40239     *
40240     * _.toLength('3.2');
40241     * // => 3
40242     */
40243    function toLength(value) {
40244      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
40245    }
40246
40247    /**
40248     * Converts `value` to a number.
40249     *
40250     * @static
40251     * @memberOf _
40252     * @since 4.0.0
40253     * @category Lang
40254     * @param {*} value The value to process.
40255     * @returns {number} Returns the number.
40256     * @example
40257     *
40258     * _.toNumber(3.2);
40259     * // => 3.2
40260     *
40261     * _.toNumber(Number.MIN_VALUE);
40262     * // => 5e-324
40263     *
40264     * _.toNumber(Infinity);
40265     * // => Infinity
40266     *
40267     * _.toNumber('3.2');
40268     * // => 3.2
40269     */
40270    function toNumber(value) {
40271      if (typeof value == 'number') {
40272        return value;
40273      }
40274      if (isSymbol(value)) {
40275        return NAN;
40276      }
40277      if (isObject(value)) {
40278        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
40279        value = isObject(other) ? (other + '') : other;
40280      }
40281      if (typeof value != 'string') {
40282        return value === 0 ? value : +value;
40283      }
40284      value = baseTrim(value);
40285      var isBinary = reIsBinary.test(value);
40286      return (isBinary || reIsOctal.test(value))
40287        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
40288        : (reIsBadHex.test(value) ? NAN : +value);
40289    }
40290
40291    /**
40292     * Converts `value` to a plain object flattening inherited enumerable string
40293     * keyed properties of `value` to own properties of the plain object.
40294     *
40295     * @static
40296     * @memberOf _
40297     * @since 3.0.0
40298     * @category Lang
40299     * @param {*} value The value to convert.
40300     * @returns {Object} Returns the converted plain object.
40301     * @example
40302     *
40303     * function Foo() {
40304     *   this.b = 2;
40305     * }
40306     *
40307     * Foo.prototype.c = 3;
40308     *
40309     * _.assign({ 'a': 1 }, new Foo);
40310     * // => { 'a': 1, 'b': 2 }
40311     *
40312     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
40313     * // => { 'a': 1, 'b': 2, 'c': 3 }
40314     */
40315    function toPlainObject(value) {
40316      return copyObject(value, keysIn(value));
40317    }
40318
40319    /**
40320     * Converts `value` to a safe integer. A safe integer can be compared and
40321     * represented correctly.
40322     *
40323     * @static
40324     * @memberOf _
40325     * @since 4.0.0
40326     * @category Lang
40327     * @param {*} value The value to convert.
40328     * @returns {number} Returns the converted integer.
40329     * @example
40330     *
40331     * _.toSafeInteger(3.2);
40332     * // => 3
40333     *
40334     * _.toSafeInteger(Number.MIN_VALUE);
40335     * // => 0
40336     *
40337     * _.toSafeInteger(Infinity);
40338     * // => 9007199254740991
40339     *
40340     * _.toSafeInteger('3.2');
40341     * // => 3
40342     */
40343    function toSafeInteger(value) {
40344      return value
40345        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
40346        : (value === 0 ? value : 0);
40347    }
40348
40349    /**
40350     * Converts `value` to a string. An empty string is returned for `null`
40351     * and `undefined` values. The sign of `-0` is preserved.
40352     *
40353     * @static
40354     * @memberOf _
40355     * @since 4.0.0
40356     * @category Lang
40357     * @param {*} value The value to convert.
40358     * @returns {string} Returns the converted string.
40359     * @example
40360     *
40361     * _.toString(null);
40362     * // => ''
40363     *
40364     * _.toString(-0);
40365     * // => '-0'
40366     *
40367     * _.toString([1, 2, 3]);
40368     * // => '1,2,3'
40369     */
40370    function toString(value) {
40371      return value == null ? '' : baseToString(value);
40372    }
40373
40374    /*------------------------------------------------------------------------*/
40375
40376    /**
40377     * Assigns own enumerable string keyed properties of source objects to the
40378     * destination object. Source objects are applied from left to right.
40379     * Subsequent sources overwrite property assignments of previous sources.
40380     *
40381     * **Note:** This method mutates `object` and is loosely based on
40382     * [`Object.assign`](https://mdn.io/Object/assign).
40383     *
40384     * @static
40385     * @memberOf _
40386     * @since 0.10.0
40387     * @category Object
40388     * @param {Object} object The destination object.
40389     * @param {...Object} [sources] The source objects.
40390     * @returns {Object} Returns `object`.
40391     * @see _.assignIn
40392     * @example
40393     *
40394     * function Foo() {
40395     *   this.a = 1;
40396     * }
40397     *
40398     * function Bar() {
40399     *   this.c = 3;
40400     * }
40401     *
40402     * Foo.prototype.b = 2;
40403     * Bar.prototype.d = 4;
40404     *
40405     * _.assign({ 'a': 0 }, new Foo, new Bar);
40406     * // => { 'a': 1, 'c': 3 }
40407     */
40408    var assign = createAssigner(function(object, source) {
40409      if (isPrototype(source) || isArrayLike(source)) {
40410        copyObject(source, keys(source), object);
40411        return;
40412      }
40413      for (var key in source) {
40414        if (hasOwnProperty.call(source, key)) {
40415          assignValue(object, key, source[key]);
40416        }
40417      }
40418    });
40419
40420    /**
40421     * This method is like `_.assign` except that it iterates over own and
40422     * inherited source properties.
40423     *
40424     * **Note:** This method mutates `object`.
40425     *
40426     * @static
40427     * @memberOf _
40428     * @since 4.0.0
40429     * @alias extend
40430     * @category Object
40431     * @param {Object} object The destination object.
40432     * @param {...Object} [sources] The source objects.
40433     * @returns {Object} Returns `object`.
40434     * @see _.assign
40435     * @example
40436     *
40437     * function Foo() {
40438     *   this.a = 1;
40439     * }
40440     *
40441     * function Bar() {
40442     *   this.c = 3;
40443     * }
40444     *
40445     * Foo.prototype.b = 2;
40446     * Bar.prototype.d = 4;
40447     *
40448     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
40449     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
40450     */
40451    var assignIn = createAssigner(function(object, source) {
40452      copyObject(source, keysIn(source), object);
40453    });
40454
40455    /**
40456     * This method is like `_.assignIn` except that it accepts `customizer`
40457     * which is invoked to produce the assigned values. If `customizer` returns
40458     * `undefined`, assignment is handled by the method instead. The `customizer`
40459     * is invoked with five arguments: (objValue, srcValue, key, object, source).
40460     *
40461     * **Note:** This method mutates `object`.
40462     *
40463     * @static
40464     * @memberOf _
40465     * @since 4.0.0
40466     * @alias extendWith
40467     * @category Object
40468     * @param {Object} object The destination object.
40469     * @param {...Object} sources The source objects.
40470     * @param {Function} [customizer] The function to customize assigned values.
40471     * @returns {Object} Returns `object`.
40472     * @see _.assignWith
40473     * @example
40474     *
40475     * function customizer(objValue, srcValue) {
40476     *   return _.isUndefined(objValue) ? srcValue : objValue;
40477     * }
40478     *
40479     * var defaults = _.partialRight(_.assignInWith, customizer);
40480     *
40481     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
40482     * // => { 'a': 1, 'b': 2 }
40483     */
40484    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
40485      copyObject(source, keysIn(source), object, customizer);
40486    });
40487
40488    /**
40489     * This method is like `_.assign` except that it accepts `customizer`
40490     * which is invoked to produce the assigned values. If `customizer` returns
40491     * `undefined`, assignment is handled by the method instead. The `customizer`
40492     * is invoked with five arguments: (objValue, srcValue, key, object, source).
40493     *
40494     * **Note:** This method mutates `object`.
40495     *
40496     * @static
40497     * @memberOf _
40498     * @since 4.0.0
40499     * @category Object
40500     * @param {Object} object The destination object.
40501     * @param {...Object} sources The source objects.
40502     * @param {Function} [customizer] The function to customize assigned values.
40503     * @returns {Object} Returns `object`.
40504     * @see _.assignInWith
40505     * @example
40506     *
40507     * function customizer(objValue, srcValue) {
40508     *   return _.isUndefined(objValue) ? srcValue : objValue;
40509     * }
40510     *
40511     * var defaults = _.partialRight(_.assignWith, customizer);
40512     *
40513     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
40514     * // => { 'a': 1, 'b': 2 }
40515     */
40516    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
40517      copyObject(source, keys(source), object, customizer);
40518    });
40519
40520    /**
40521     * Creates an array of values corresponding to `paths` of `object`.
40522     *
40523     * @static
40524     * @memberOf _
40525     * @since 1.0.0
40526     * @category Object
40527     * @param {Object} object The object to iterate over.
40528     * @param {...(string|string[])} [paths] The property paths to pick.
40529     * @returns {Array} Returns the picked values.
40530     * @example
40531     *
40532     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
40533     *
40534     * _.at(object, ['a[0].b.c', 'a[1]']);
40535     * // => [3, 4]
40536     */
40537    var at = flatRest(baseAt);
40538
40539    /**
40540     * Creates an object that inherits from the `prototype` object. If a
vendor: 13,619 bytes, lines 40541-41005
40541     * `properties` object is given, its own enumerable string keyed properties
40542     * are assigned to the created object.
40543     *
40544     * @static
40545     * @memberOf _
40546     * @since 2.3.0
40547     * @category Object
40548     * @param {Object} prototype The object to inherit from.
40549     * @param {Object} [properties] The properties to assign to the object.
40550     * @returns {Object} Returns the new object.
40551     * @example
40552     *
40553     * function Shape() {
40554     *   this.x = 0;
40555     *   this.y = 0;
40556     * }
40557     *
40558     * function Circle() {
40559     *   Shape.call(this);
40560     * }
40561     *
40562     * Circle.prototype = _.create(Shape.prototype, {
40563     *   'constructor': Circle
40564     * });
40565     *
40566     * var circle = new Circle;
40567     * circle instanceof Circle;
40568     * // => true
40569     *
40570     * circle instanceof Shape;
40571     * // => true
40572     */
40573    function create(prototype, properties) {
40574      var result = baseCreate(prototype);
40575      return properties == null ? result : baseAssign(result, properties);
40576    }
40577
40578    /**
40579     * Assigns own and inherited enumerable string keyed properties of source
40580     * objects to the destination object for all destination properties that
40581     * resolve to `undefined`. Source objects are applied from left to right.
40582     * Once a property is set, additional values of the same property are ignored.
40583     *
40584     * **Note:** This method mutates `object`.
40585     *
40586     * @static
40587     * @since 0.1.0
40588     * @memberOf _
40589     * @category Object
40590     * @param {Object} object The destination object.
40591     * @param {...Object} [sources] The source objects.
40592     * @returns {Object} Returns `object`.
40593     * @see _.defaultsDeep
40594     * @example
40595     *
40596     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
40597     * // => { 'a': 1, 'b': 2 }
40598     */
40599    var defaults = baseRest(function(object, sources) {
40600      object = Object(object);
40601
40602      var index = -1;
40603      var length = sources.length;
40604      var guard = length > 2 ? sources[2] : undefined;
40605
40606      if (guard && isIterateeCall(sources[0], sources[1], guard)) {
40607        length = 1;
40608      }
40609
40610      while (++index < length) {
40611        var source = sources[index];
40612        var props = keysIn(source);
40613        var propsIndex = -1;
40614        var propsLength = props.length;
40615
40616        while (++propsIndex < propsLength) {
40617          var key = props[propsIndex];
40618          var value = object[key];
40619
40620          if (value === undefined ||
40621              (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
40622            object[key] = source[key];
40623          }
40624        }
40625      }
40626
40627      return object;
40628    });
40629
40630    /**
40631     * This method is like `_.defaults` except that it recursively assigns
40632     * default properties.
40633     *
40634     * **Note:** This method mutates `object`.
40635     *
40636     * @static
40637     * @memberOf _
40638     * @since 3.10.0
40639     * @category Object
40640     * @param {Object} object The destination object.
40641     * @param {...Object} [sources] The source objects.
40642     * @returns {Object} Returns `object`.
40643     * @see _.defaults
40644     * @example
40645     *
40646     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
40647     * // => { 'a': { 'b': 2, 'c': 3 } }
40648     */
40649    var defaultsDeep = baseRest(function(args) {
40650      args.push(undefined, customDefaultsMerge);
40651      return apply(mergeWith, undefined, args);
40652    });
40653
40654    /**
40655     * This method is like `_.find` except that it returns the key of the first
40656     * element `predicate` returns truthy for instead of the element itself.
40657     *
40658     * @static
40659     * @memberOf _
40660     * @since 1.1.0
40661     * @category Object
40662     * @param {Object} object The object to inspect.
40663     * @param {Function} [predicate=_.identity] The function invoked per iteration.
40664     * @returns {string|undefined} Returns the key of the matched element,
40665     *  else `undefined`.
40666     * @example
40667     *
40668     * var users = {
40669     *   'barney':  { 'age': 36, 'active': true },
40670     *   'fred':    { 'age': 40, 'active': false },
40671     *   'pebbles': { 'age': 1,  'active': true }
40672     * };
40673     *
40674     * _.findKey(users, function(o) { return o.age < 40; });
40675     * // => 'barney' (iteration order is not guaranteed)
40676     *
40677     * // The `_.matches` iteratee shorthand.
40678     * _.findKey(users, { 'age': 1, 'active': true });
40679     * // => 'pebbles'
40680     *
40681     * // The `_.matchesProperty` iteratee shorthand.
40682     * _.findKey(users, ['active', false]);
40683     * // => 'fred'
40684     *
40685     * // The `_.property` iteratee shorthand.
40686     * _.findKey(users, 'active');
40687     * // => 'barney'
40688     */
40689    function findKey(object, predicate) {
40690      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
40691    }
40692
40693    /**
40694     * This method is like `_.findKey` except that it iterates over elements of
40695     * a collection in the opposite order.
40696     *
40697     * @static
40698     * @memberOf _
40699     * @since 2.0.0
40700     * @category Object
40701     * @param {Object} object The object to inspect.
40702     * @param {Function} [predicate=_.identity] The function invoked per iteration.
40703     * @returns {string|undefined} Returns the key of the matched element,
40704     *  else `undefined`.
40705     * @example
40706     *
40707     * var users = {
40708     *   'barney':  { 'age': 36, 'active': true },
40709     *   'fred':    { 'age': 40, 'active': false },
40710     *   'pebbles': { 'age': 1,  'active': true }
40711     * };
40712     *
40713     * _.findLastKey(users, function(o) { return o.age < 40; });
40714     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
40715     *
40716     * // The `_.matches` iteratee shorthand.
40717     * _.findLastKey(users, { 'age': 36, 'active': true });
40718     * // => 'barney'
40719     *
40720     * // The `_.matchesProperty` iteratee shorthand.
40721     * _.findLastKey(users, ['active', false]);
40722     * // => 'fred'
40723     *
40724     * // The `_.property` iteratee shorthand.
40725     * _.findLastKey(users, 'active');
40726     * // => 'pebbles'
40727     */
40728    function findLastKey(object, predicate) {
40729      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
40730    }
40731
40732    /**
40733     * Iterates over own and inherited enumerable string keyed properties of an
40734     * object and invokes `iteratee` for each property. The iteratee is invoked
40735     * with three arguments: (value, key, object). Iteratee functions may exit
40736     * iteration early by explicitly returning `false`.
40737     *
40738     * @static
40739     * @memberOf _
40740     * @since 0.3.0
40741     * @category Object
40742     * @param {Object} object The object to iterate over.
40743     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
40744     * @returns {Object} Returns `object`.
40745     * @see _.forInRight
40746     * @example
40747     *
40748     * function Foo() {
40749     *   this.a = 1;
40750     *   this.b = 2;
40751     * }
40752     *
40753     * Foo.prototype.c = 3;
40754     *
40755     * _.forIn(new Foo, function(value, key) {
40756     *   console.log(key);
40757     * });
40758     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
40759     */
40760    function forIn(object, iteratee) {
40761      return object == null
40762        ? object
40763        : baseFor(object, getIteratee(iteratee, 3), keysIn);
40764    }
40765
40766    /**
40767     * This method is like `_.forIn` except that it iterates over properties of
40768     * `object` in the opposite order.
40769     *
40770     * @static
40771     * @memberOf _
40772     * @since 2.0.0
40773     * @category Object
40774     * @param {Object} object The object to iterate over.
40775     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
40776     * @returns {Object} Returns `object`.
40777     * @see _.forIn
40778     * @example
40779     *
40780     * function Foo() {
40781     *   this.a = 1;
40782     *   this.b = 2;
40783     * }
40784     *
40785     * Foo.prototype.c = 3;
40786     *
40787     * _.forInRight(new Foo, function(value, key) {
40788     *   console.log(key);
40789     * });
40790     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
40791     */
40792    function forInRight(object, iteratee) {
40793      return object == null
40794        ? object
40795        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
40796    }
40797
40798    /**
40799     * Iterates over own enumerable string keyed properties of an object and
40800     * invokes `iteratee` for each property. The iteratee is invoked with three
40801     * arguments: (value, key, object). Iteratee functions may exit iteration
40802     * early by explicitly returning `false`.
40803     *
40804     * @static
40805     * @memberOf _
40806     * @since 0.3.0
40807     * @category Object
40808     * @param {Object} object The object to iterate over.
40809     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
40810     * @returns {Object} Returns `object`.
40811     * @see _.forOwnRight
40812     * @example
40813     *
40814     * function Foo() {
40815     *   this.a = 1;
40816     *   this.b = 2;
40817     * }
40818     *
40819     * Foo.prototype.c = 3;
40820     *
40821     * _.forOwn(new Foo, function(value, key) {
40822     *   console.log(key);
40823     * });
40824     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
40825     */
40826    function forOwn(object, iteratee) {
40827      return object && baseForOwn(object, getIteratee(iteratee, 3));
40828    }
40829
40830    /**
40831     * This method is like `_.forOwn` except that it iterates over properties of
40832     * `object` in the opposite order.
40833     *
40834     * @static
40835     * @memberOf _
40836     * @since 2.0.0
40837     * @category Object
40838     * @param {Object} object The object to iterate over.
40839     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
40840     * @returns {Object} Returns `object`.
40841     * @see _.forOwn
40842     * @example
40843     *
40844     * function Foo() {
40845     *   this.a = 1;
40846     *   this.b = 2;
40847     * }
40848     *
40849     * Foo.prototype.c = 3;
40850     *
40851     * _.forOwnRight(new Foo, function(value, key) {
40852     *   console.log(key);
40853     * });
40854     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
40855     */
40856    function forOwnRight(object, iteratee) {
40857      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
40858    }
40859
40860    /**
40861     * Creates an array of function property names from own enumerable properties
40862     * of `object`.
40863     *
40864     * @static
40865     * @since 0.1.0
40866     * @memberOf _
40867     * @category Object
40868     * @param {Object} object The object to inspect.
40869     * @returns {Array} Returns the function names.
40870     * @see _.functionsIn
40871     * @example
40872     *
40873     * function Foo() {
40874     *   this.a = _.constant('a');
40875     *   this.b = _.constant('b');
40876     * }
40877     *
40878     * Foo.prototype.c = _.constant('c');
40879     *
40880     * _.functions(new Foo);
40881     * // => ['a', 'b']
40882     */
40883    function functions(object) {
40884      return object == null ? [] : baseFunctions(object, keys(object));
40885    }
40886
40887    /**
40888     * Creates an array of function property names from own and inherited
40889     * enumerable properties of `object`.
40890     *
40891     * @static
40892     * @memberOf _
40893     * @since 4.0.0
40894     * @category Object
40895     * @param {Object} object The object to inspect.
40896     * @returns {Array} Returns the function names.
40897     * @see _.functions
40898     * @example
40899     *
40900     * function Foo() {
40901     *   this.a = _.constant('a');
40902     *   this.b = _.constant('b');
40903     * }
40904     *
40905     * Foo.prototype.c = _.constant('c');
40906     *
40907     * _.functionsIn(new Foo);
40908     * // => ['a', 'b', 'c']
40909     */
40910    function functionsIn(object) {
40911      return object == null ? [] : baseFunctions(object, keysIn(object));
40912    }
40913
40914    /**
40915     * Gets the value at `path` of `object`. If the resolved value is
40916     * `undefined`, the `defaultValue` is returned in its place.
40917     *
40918     * @static
40919     * @memberOf _
40920     * @since 3.7.0
40921     * @category Object
40922     * @param {Object} object The object to query.
40923     * @param {Array|string} path The path of the property to get.
40924     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
40925     * @returns {*} Returns the resolved value.
40926     * @example
40927     *
40928     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
40929     *
40930     * _.get(object, 'a[0].b.c');
40931     * // => 3
40932     *
40933     * _.get(object, ['a', '0', 'b', 'c']);
40934     * // => 3
40935     *
40936     * _.get(object, 'a.b.c', 'default');
40937     * // => 'default'
40938     */
40939    function get(object, path, defaultValue) {
40940      var result = object == null ? undefined : baseGet(object, path);
40941      return result === undefined ? defaultValue : result;
40942    }
40943
40944    /**
40945     * Checks if `path` is a direct property of `object`.
40946     *
40947     * @static
40948     * @since 0.1.0
40949     * @memberOf _
40950     * @category Object
40951     * @param {Object} object The object to query.
40952     * @param {Array|string} path The path to check.
40953     * @returns {boolean} Returns `true` if `path` exists, else `false`.
40954     * @example
40955     *
40956     * var object = { 'a': { 'b': 2 } };
40957     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
40958     *
40959     * _.has(object, 'a');
40960     * // => true
40961     *
40962     * _.has(object, 'a.b');
40963     * // => true
40964     *
40965     * _.has(object, ['a', 'b']);
40966     * // => true
40967     *
40968     * _.has(other, 'a');
40969     * // => false
40970     */
40971    function has(object, path) {
40972      return object != null && hasPath(object, path, baseHas);
40973    }
40974
40975    /**
40976     * Checks if `path` is a direct or inherited property of `object`.
40977     *
40978     * @static
40979     * @memberOf _
40980     * @since 4.0.0
40981     * @category Object
40982     * @param {Object} object The object to query.
40983     * @param {Array|string} path The path to check.
40984     * @returns {boolean} Returns `true` if `path` exists, else `false`.
40985     * @example
40986     *
40987     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
40988     *
40989     * _.hasIn(object, 'a');
40990     * // => true
40991     *
40992     * _.hasIn(object, 'a.b');
40993     * // => true
40994     *
40995     * _.hasIn(object, ['a', 'b']);
40996     * // => true
40997     *
40998     * _.hasIn(object, 'b');
40999     * // => false
41000     */
41001    function hasIn(object, path) {
41002      return object != null && hasPath(object, path, baseHasIn);
41003    }
41004
41005    /**
vendor: 11,848 bytes, lines 41006-41376
41006     * Creates an object composed of the inverted keys and values of `object`.
41007     * If `object` contains duplicate values, subsequent values overwrite
41008     * property assignments of previous values.
41009     *
41010     * @static
41011     * @memberOf _
41012     * @since 0.7.0
41013     * @category Object
41014     * @param {Object} object The object to invert.
41015     * @returns {Object} Returns the new inverted object.
41016     * @example
41017     *
41018     * var object = { 'a': 1, 'b': 2, 'c': 1 };
41019     *
41020     * _.invert(object);
41021     * // => { '1': 'c', '2': 'b' }
41022     */
41023    var invert = createInverter(function(result, value, key) {
41024      if (value != null &&
41025          typeof value.toString != 'function') {
41026        value = nativeObjectToString.call(value);
41027      }
41028
41029      result[value] = key;
41030    }, constant(identity));
41031
41032    /**
41033     * This method is like `_.invert` except that the inverted object is generated
41034     * from the results of running each element of `object` thru `iteratee`. The
41035     * corresponding inverted value of each inverted key is an array of keys
41036     * responsible for generating the inverted value. The iteratee is invoked
41037     * with one argument: (value).
41038     *
41039     * @static
41040     * @memberOf _
41041     * @since 4.1.0
41042     * @category Object
41043     * @param {Object} object The object to invert.
41044     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
41045     * @returns {Object} Returns the new inverted object.
41046     * @example
41047     *
41048     * var object = { 'a': 1, 'b': 2, 'c': 1 };
41049     *
41050     * _.invertBy(object);
41051     * // => { '1': ['a', 'c'], '2': ['b'] }
41052     *
41053     * _.invertBy(object, function(value) {
41054     *   return 'group' + value;
41055     * });
41056     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
41057     */
41058    var invertBy = createInverter(function(result, value, key) {
41059      if (value != null &&
41060          typeof value.toString != 'function') {
41061        value = nativeObjectToString.call(value);
41062      }
41063
41064      if (hasOwnProperty.call(result, value)) {
41065        result[value].push(key);
41066      } else {
41067        result[value] = [key];
41068      }
41069    }, getIteratee);
41070
41071    /**
41072     * Invokes the method at `path` of `object`.
41073     *
41074     * @static
41075     * @memberOf _
41076     * @since 4.0.0
41077     * @category Object
41078     * @param {Object} object The object to query.
41079     * @param {Array|string} path The path of the method to invoke.
41080     * @param {...*} [args] The arguments to invoke the method with.
41081     * @returns {*} Returns the result of the invoked method.
41082     * @example
41083     *
41084     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
41085     *
41086     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
41087     * // => [2, 3]
41088     */
41089    var invoke = baseRest(baseInvoke);
41090
41091    /**
41092     * Creates an array of the own enumerable property names of `object`.
41093     *
41094     * **Note:** Non-object values are coerced to objects. See the
41095     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
41096     * for more details.
41097     *
41098     * @static
41099     * @since 0.1.0
41100     * @memberOf _
41101     * @category Object
41102     * @param {Object} object The object to query.
41103     * @returns {Array} Returns the array of property names.
41104     * @example
41105     *
41106     * function Foo() {
41107     *   this.a = 1;
41108     *   this.b = 2;
41109     * }
41110     *
41111     * Foo.prototype.c = 3;
41112     *
41113     * _.keys(new Foo);
41114     * // => ['a', 'b'] (iteration order is not guaranteed)
41115     *
41116     * _.keys('hi');
41117     * // => ['0', '1']
41118     */
41119    function keys(object) {
41120      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
41121    }
41122
41123    /**
41124     * Creates an array of the own and inherited enumerable property names of `object`.
41125     *
41126     * **Note:** Non-object values are coerced to objects.
41127     *
41128     * @static
41129     * @memberOf _
41130     * @since 3.0.0
41131     * @category Object
41132     * @param {Object} object The object to query.
41133     * @returns {Array} Returns the array of property names.
41134     * @example
41135     *
41136     * function Foo() {
41137     *   this.a = 1;
41138     *   this.b = 2;
41139     * }
41140     *
41141     * Foo.prototype.c = 3;
41142     *
41143     * _.keysIn(new Foo);
41144     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
41145     */
41146    function keysIn(object) {
41147      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
41148    }
41149
41150    /**
41151     * The opposite of `_.mapValues`; this method creates an object with the
41152     * same values as `object` and keys generated by running each own enumerable
41153     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
41154     * with three arguments: (value, key, object).
41155     *
41156     * @static
41157     * @memberOf _
41158     * @since 3.8.0
41159     * @category Object
41160     * @param {Object} object The object to iterate over.
41161     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
41162     * @returns {Object} Returns the new mapped object.
41163     * @see _.mapValues
41164     * @example
41165     *
41166     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
41167     *   return key + value;
41168     * });
41169     * // => { 'a1': 1, 'b2': 2 }
41170     */
41171    function mapKeys(object, iteratee) {
41172      var result = {};
41173      iteratee = getIteratee(iteratee, 3);
41174
41175      baseForOwn(object, function(value, key, object) {
41176        baseAssignValue(result, iteratee(value, key, object), value);
41177      });
41178      return result;
41179    }
41180
41181    /**
41182     * Creates an object with the same keys as `object` and values generated
41183     * by running each own enumerable string keyed property of `object` thru
41184     * `iteratee`. The iteratee is invoked with three arguments:
41185     * (value, key, object).
41186     *
41187     * @static
41188     * @memberOf _
41189     * @since 2.4.0
41190     * @category Object
41191     * @param {Object} object The object to iterate over.
41192     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
41193     * @returns {Object} Returns the new mapped object.
41194     * @see _.mapKeys
41195     * @example
41196     *
41197     * var users = {
41198     *   'fred':    { 'user': 'fred',    'age': 40 },
41199     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
41200     * };
41201     *
41202     * _.mapValues(users, function(o) { return o.age; });
41203     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
41204     *
41205     * // The `_.property` iteratee shorthand.
41206     * _.mapValues(users, 'age');
41207     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
41208     */
41209    function mapValues(object, iteratee) {
41210      var result = {};
41211      iteratee = getIteratee(iteratee, 3);
41212
41213      baseForOwn(object, function(value, key, object) {
41214        baseAssignValue(result, key, iteratee(value, key, object));
41215      });
41216      return result;
41217    }
41218
41219    /**
41220     * This method is like `_.assign` except that it recursively merges own and
41221     * inherited enumerable string keyed properties of source objects into the
41222     * destination object. Source properties that resolve to `undefined` are
41223     * skipped if a destination value exists. Array and plain object properties
41224     * are merged recursively. Other objects and value types are overridden by
41225     * assignment. Source objects are applied from left to right. Subsequent
41226     * sources overwrite property assignments of previous sources.
41227     *
41228     * **Note:** This method mutates `object`.
41229     *
41230     * @static
41231     * @memberOf _
41232     * @since 0.5.0
41233     * @category Object
41234     * @param {Object} object The destination object.
41235     * @param {...Object} [sources] The source objects.
41236     * @returns {Object} Returns `object`.
41237     * @example
41238     *
41239     * var object = {
41240     *   'a': [{ 'b': 2 }, { 'd': 4 }]
41241     * };
41242     *
41243     * var other = {
41244     *   'a': [{ 'c': 3 }, { 'e': 5 }]
41245     * };
41246     *
41247     * _.merge(object, other);
41248     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
41249     */
41250    var merge = createAssigner(function(object, source, srcIndex) {
41251      baseMerge(object, source, srcIndex);
41252    });
41253
41254    /**
41255     * This method is like `_.merge` except that it accepts `customizer` which
41256     * is invoked to produce the merged values of the destination and source
41257     * properties. If `customizer` returns `undefined`, merging is handled by the
41258     * method instead. The `customizer` is invoked with six arguments:
41259     * (objValue, srcValue, key, object, source, stack).
41260     *
41261     * **Note:** This method mutates `object`.
41262     *
41263     * @static
41264     * @memberOf _
41265     * @since 4.0.0
41266     * @category Object
41267     * @param {Object} object The destination object.
41268     * @param {...Object} sources The source objects.
41269     * @param {Function} customizer The function to customize assigned values.
41270     * @returns {Object} Returns `object`.
41271     * @example
41272     *
41273     * function customizer(objValue, srcValue) {
41274     *   if (_.isArray(objValue)) {
41275     *     return objValue.concat(srcValue);
41276     *   }
41277     * }
41278     *
41279     * var object = { 'a': [1], 'b': [2] };
41280     * var other = { 'a': [3], 'b': [4] };
41281     *
41282     * _.mergeWith(object, other, customizer);
41283     * // => { 'a': [1, 3], 'b': [2, 4] }
41284     */
41285    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
41286      baseMerge(object, source, srcIndex, customizer);
41287    });
41288
41289    /**
41290     * The opposite of `_.pick`; this method creates an object composed of the
41291     * own and inherited enumerable property paths of `object` that are not omitted.
41292     *
41293     * **Note:** This method is considerably slower than `_.pick`.
41294     *
41295     * @static
41296     * @since 0.1.0
41297     * @memberOf _
41298     * @category Object
41299     * @param {Object} object The source object.
41300     * @param {...(string|string[])} [paths] The property paths to omit.
41301     * @returns {Object} Returns the new object.
41302     * @example
41303     *
41304     * var object = { 'a': 1, 'b': '2', 'c': 3 };
41305     *
41306     * _.omit(object, ['a', 'c']);
41307     * // => { 'b': '2' }
41308     */
41309    var omit = flatRest(function(object, paths) {
41310      var result = {};
41311      if (object == null) {
41312        return result;
41313      }
41314      var isDeep = false;
41315      paths = arrayMap(paths, function(path) {
41316        path = castPath(path, object);
41317        isDeep || (isDeep = path.length > 1);
41318        return path;
41319      });
41320      copyObject(object, getAllKeysIn(object), result);
41321      if (isDeep) {
41322        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
41323      }
41324      var length = paths.length;
41325      while (length--) {
41326        baseUnset(result, paths[length]);
41327      }
41328      return result;
41329    });
41330
41331    /**
41332     * The opposite of `_.pickBy`; this method creates an object composed of
41333     * the own and inherited enumerable string keyed properties of `object` that
41334     * `predicate` doesn't return truthy for. The predicate is invoked with two
41335     * arguments: (value, key).
41336     *
41337     * @static
41338     * @memberOf _
41339     * @since 4.0.0
41340     * @category Object
41341     * @param {Object} object The source object.
41342     * @param {Function} [predicate=_.identity] The function invoked per property.
41343     * @returns {Object} Returns the new object.
41344     * @example
41345     *
41346     * var object = { 'a': 1, 'b': '2', 'c': 3 };
41347     *
41348     * _.omitBy(object, _.isNumber);
41349     * // => { 'b': '2' }
41350     */
41351    function omitBy(object, predicate) {
41352      return pickBy(object, negate(getIteratee(predicate)));
41353    }
41354
41355    /**
41356     * Creates an object composed of the picked `object` properties.
41357     *
41358     * @static
41359     * @since 0.1.0
41360     * @memberOf _
41361     * @category Object
41362     * @param {Object} object The source object.
41363     * @param {...(string|string[])} [paths] The property paths to pick.
41364     * @returns {Object} Returns the new object.
41365     * @example
41366     *
41367     * var object = { 'a': 1, 'b': '2', 'c': 3 };
41368     *
41369     * _.pick(object, ['a', 'c']);
41370     * // => { 'a': 1, 'c': 3 }
41371     */
41372    var pick = flatRest(function(object, paths) {
41373      return object == null ? {} : basePick(object, paths);
41374    });
41375
41376    /**
vendor: 11,160 bytes, lines 41377-41715
41377     * Creates an object composed of the `object` properties `predicate` returns
41378     * truthy for. The predicate is invoked with two arguments: (value, key).
41379     *
41380     * @static
41381     * @memberOf _
41382     * @since 4.0.0
41383     * @category Object
41384     * @param {Object} object The source object.
41385     * @param {Function} [predicate=_.identity] The function invoked per property.
41386     * @returns {Object} Returns the new object.
41387     * @example
41388     *
41389     * var object = { 'a': 1, 'b': '2', 'c': 3 };
41390     *
41391     * _.pickBy(object, _.isNumber);
41392     * // => { 'a': 1, 'c': 3 }
41393     */
41394    function pickBy(object, predicate) {
41395      if (object == null) {
41396        return {};
41397      }
41398      var props = arrayMap(getAllKeysIn(object), function(prop) {
41399        return [prop];
41400      });
41401      predicate = getIteratee(predicate);
41402      return basePickBy(object, props, function(value, path) {
41403        return predicate(value, path[0]);
41404      });
41405    }
41406
41407    /**
41408     * This method is like `_.get` except that if the resolved value is a
41409     * function it's invoked with the `this` binding of its parent object and
41410     * its result is returned.
41411     *
41412     * @static
41413     * @since 0.1.0
41414     * @memberOf _
41415     * @category Object
41416     * @param {Object} object The object to query.
41417     * @param {Array|string} path The path of the property to resolve.
41418     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
41419     * @returns {*} Returns the resolved value.
41420     * @example
41421     *
41422     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
41423     *
41424     * _.result(object, 'a[0].b.c1');
41425     * // => 3
41426     *
41427     * _.result(object, 'a[0].b.c2');
41428     * // => 4
41429     *
41430     * _.result(object, 'a[0].b.c3', 'default');
41431     * // => 'default'
41432     *
41433     * _.result(object, 'a[0].b.c3', _.constant('default'));
41434     * // => 'default'
41435     */
41436    function result(object, path, defaultValue) {
41437      path = castPath(path, object);
41438
41439      var index = -1,
41440          length = path.length;
41441
41442      // Ensure the loop is entered when path is empty.
41443      if (!length) {
41444        length = 1;
41445        object = undefined;
41446      }
41447      while (++index < length) {
41448        var value = object == null ? undefined : object[toKey(path[index])];
41449        if (value === undefined) {
41450          index = length;
41451          value = defaultValue;
41452        }
41453        object = isFunction(value) ? value.call(object) : value;
41454      }
41455      return object;
41456    }
41457
41458    /**
41459     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
41460     * it's created. Arrays are created for missing index properties while objects
41461     * are created for all other missing properties. Use `_.setWith` to customize
41462     * `path` creation.
41463     *
41464     * **Note:** This method mutates `object`.
41465     *
41466     * @static
41467     * @memberOf _
41468     * @since 3.7.0
41469     * @category Object
41470     * @param {Object} object The object to modify.
41471     * @param {Array|string} path The path of the property to set.
41472     * @param {*} value The value to set.
41473     * @returns {Object} Returns `object`.
41474     * @example
41475     *
41476     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
41477     *
41478     * _.set(object, 'a[0].b.c', 4);
41479     * console.log(object.a[0].b.c);
41480     * // => 4
41481     *
41482     * _.set(object, ['x', '0', 'y', 'z'], 5);
41483     * console.log(object.x[0].y.z);
41484     * // => 5
41485     */
41486    function set(object, path, value) {
41487      return object == null ? object : baseSet(object, path, value);
41488    }
41489
41490    /**
41491     * This method is like `_.set` except that it accepts `customizer` which is
41492     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
41493     * path creation is handled by the method instead. The `customizer` is invoked
41494     * with three arguments: (nsValue, key, nsObject).
41495     *
41496     * **Note:** This method mutates `object`.
41497     *
41498     * @static
41499     * @memberOf _
41500     * @since 4.0.0
41501     * @category Object
41502     * @param {Object} object The object to modify.
41503     * @param {Array|string} path The path of the property to set.
41504     * @param {*} value The value to set.
41505     * @param {Function} [customizer] The function to customize assigned values.
41506     * @returns {Object} Returns `object`.
41507     * @example
41508     *
41509     * var object = {};
41510     *
41511     * _.setWith(object, '[0][1]', 'a', Object);
41512     * // => { '0': { '1': 'a' } }
41513     */
41514    function setWith(object, path, value, customizer) {
41515      customizer = typeof customizer == 'function' ? customizer : undefined;
41516      return object == null ? object : baseSet(object, path, value, customizer);
41517    }
41518
41519    /**
41520     * Creates an array of own enumerable string keyed-value pairs for `object`
41521     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
41522     * entries are returned.
41523     *
41524     * @static
41525     * @memberOf _
41526     * @since 4.0.0
41527     * @alias entries
41528     * @category Object
41529     * @param {Object} object The object to query.
41530     * @returns {Array} Returns the key-value pairs.
41531     * @example
41532     *
41533     * function Foo() {
41534     *   this.a = 1;
41535     *   this.b = 2;
41536     * }
41537     *
41538     * Foo.prototype.c = 3;
41539     *
41540     * _.toPairs(new Foo);
41541     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
41542     */
41543    var toPairs = createToPairs(keys);
41544
41545    /**
41546     * Creates an array of own and inherited enumerable string keyed-value pairs
41547     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
41548     * or set, its entries are returned.
41549     *
41550     * @static
41551     * @memberOf _
41552     * @since 4.0.0
41553     * @alias entriesIn
41554     * @category Object
41555     * @param {Object} object The object to query.
41556     * @returns {Array} Returns the key-value pairs.
41557     * @example
41558     *
41559     * function Foo() {
41560     *   this.a = 1;
41561     *   this.b = 2;
41562     * }
41563     *
41564     * Foo.prototype.c = 3;
41565     *
41566     * _.toPairsIn(new Foo);
41567     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
41568     */
41569    var toPairsIn = createToPairs(keysIn);
41570
41571    /**
41572     * An alternative to `_.reduce`; this method transforms `object` to a new
41573     * `accumulator` object which is the result of running each of its own
41574     * enumerable string keyed properties thru `iteratee`, with each invocation
41575     * potentially mutating the `accumulator` object. If `accumulator` is not
41576     * provided, a new object with the same `[[Prototype]]` will be used. The
41577     * iteratee is invoked with four arguments: (accumulator, value, key, object).
41578     * Iteratee functions may exit iteration early by explicitly returning `false`.
41579     *
41580     * @static
41581     * @memberOf _
41582     * @since 1.3.0
41583     * @category Object
41584     * @param {Object} object The object to iterate over.
41585     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
41586     * @param {*} [accumulator] The custom accumulator value.
41587     * @returns {*} Returns the accumulated value.
41588     * @example
41589     *
41590     * _.transform([2, 3, 4], function(result, n) {
41591     *   result.push(n *= n);
41592     *   return n % 2 == 0;
41593     * }, []);
41594     * // => [4, 9]
41595     *
41596     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
41597     *   (result[value] || (result[value] = [])).push(key);
41598     * }, {});
41599     * // => { '1': ['a', 'c'], '2': ['b'] }
41600     */
41601    function transform(object, iteratee, accumulator) {
41602      var isArr = isArray(object),
41603          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
41604
41605      iteratee = getIteratee(iteratee, 4);
41606      if (accumulator == null) {
41607        var Ctor = object && object.constructor;
41608        if (isArrLike) {
41609          accumulator = isArr ? new Ctor : [];
41610        }
41611        else if (isObject(object)) {
41612          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
41613        }
41614        else {
41615          accumulator = {};
41616        }
41617      }
41618      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
41619        return iteratee(accumulator, value, index, object);
41620      });
41621      return accumulator;
41622    }
41623
41624    /**
41625     * Removes the property at `path` of `object`.
41626     *
41627     * **Note:** This method mutates `object`.
41628     *
41629     * @static
41630     * @memberOf _
41631     * @since 4.0.0
41632     * @category Object
41633     * @param {Object} object The object to modify.
41634     * @param {Array|string} path The path of the property to unset.
41635     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
41636     * @example
41637     *
41638     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
41639     * _.unset(object, 'a[0].b.c');
41640     * // => true
41641     *
41642     * console.log(object);
41643     * // => { 'a': [{ 'b': {} }] };
41644     *
41645     * _.unset(object, ['a', '0', 'b', 'c']);
41646     * // => true
41647     *
41648     * console.log(object);
41649     * // => { 'a': [{ 'b': {} }] };
41650     */
41651    function unset(object, path) {
41652      return object == null ? true : baseUnset(object, path);
41653    }
41654
41655    /**
41656     * This method is like `_.set` except that accepts `updater` to produce the
41657     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
41658     * is invoked with one argument: (value).
41659     *
41660     * **Note:** This method mutates `object`.
41661     *
41662     * @static
41663     * @memberOf _
41664     * @since 4.6.0
41665     * @category Object
41666     * @param {Object} object The object to modify.
41667     * @param {Array|string} path The path of the property to set.
41668     * @param {Function} updater The function to produce the updated value.
41669     * @returns {Object} Returns `object`.
41670     * @example
41671     *
41672     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
41673     *
41674     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
41675     * console.log(object.a[0].b.c);
41676     * // => 9
41677     *
41678     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
41679     * console.log(object.x[0].y.z);
41680     * // => 0
41681     */
41682    function update(object, path, updater) {
41683      return object == null ? object : baseUpdate(object, path, castFunction(updater));
41684    }
41685
41686    /**
41687     * This method is like `_.update` except that it accepts `customizer` which is
41688     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
41689     * path creation is handled by the method instead. The `customizer` is invoked
41690     * with three arguments: (nsValue, key, nsObject).
41691     *
41692     * **Note:** This method mutates `object`.
41693     *
41694     * @static
41695     * @memberOf _
41696     * @since 4.6.0
41697     * @category Object
41698     * @param {Object} object The object to modify.
41699     * @param {Array|string} path The path of the property to set.
41700     * @param {Function} updater The function to produce the updated value.
41701     * @param {Function} [customizer] The function to customize assigned values.
41702     * @returns {Object} Returns `object`.
41703     * @example
41704     *
41705     * var object = {};
41706     *
41707     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
41708     * // => { '0': { '1': 'a' } }
41709     */
41710    function updateWith(object, path, updater, customizer) {
41711      customizer = typeof customizer == 'function' ? customizer : undefined;
41712      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
41713    }
41714
41715    /**
vendor: 1,263 bytes, lines 41716-41765
41716     * Creates an array of the own enumerable string keyed property values of `object`.
41717     *
41718     * **Note:** Non-object values are coerced to objects.
41719     *
41720     * @static
41721     * @since 0.1.0
41722     * @memberOf _
41723     * @category Object
41724     * @param {Object} object The object to query.
41725     * @returns {Array} Returns the array of property values.
41726     * @example
41727     *
41728     * function Foo() {
41729     *   this.a = 1;
41730     *   this.b = 2;
41731     * }
41732     *
41733     * Foo.prototype.c = 3;
41734     *
41735     * _.values(new Foo);
41736     * // => [1, 2] (iteration order is not guaranteed)
41737     *
41738     * _.values('hi');
41739     * // => ['h', 'i']
41740     */
41741    function values(object) {
41742      return object == null ? [] : baseValues(object, keys(object));
41743    }
41744
41745    /**
41746     * Creates an array of the own and inherited enumerable string keyed property
41747     * values of `object`.
41748     *
41749     * **Note:** Non-object values are coerced to objects.
41750     *
41751     * @static
41752     * @memberOf _
41753     * @since 3.0.0
41754     * @category Object
41755     * @param {Object} object The object to query.
41756     * @returns {Array} Returns the array of property values.
41757     * @example
41758     *
41759     * function Foo() {
41760     *   this.a = 1;
41761     *   this.b = 2;
41762     * }
41763     *
41764     * Foo.prototype.c = 3;
41765     *
vendor: 9,679 bytes, lines 41766-42086
41766     * _.valuesIn(new Foo);
41767     * // => [1, 2, 3] (iteration order is not guaranteed)
41768     */
41769    function valuesIn(object) {
41770      return object == null ? [] : baseValues(object, keysIn(object));
41771    }
41772
41773    /*------------------------------------------------------------------------*/
41774
41775    /**
41776     * Clamps `number` within the inclusive `lower` and `upper` bounds.
41777     *
41778     * @static
41779     * @memberOf _
41780     * @since 4.0.0
41781     * @category Number
41782     * @param {number} number The number to clamp.
41783     * @param {number} [lower] The lower bound.
41784     * @param {number} upper The upper bound.
41785     * @returns {number} Returns the clamped number.
41786     * @example
41787     *
41788     * _.clamp(-10, -5, 5);
41789     * // => -5
41790     *
41791     * _.clamp(10, -5, 5);
41792     * // => 5
41793     */
41794    function clamp(number, lower, upper) {
41795      if (upper === undefined) {
41796        upper = lower;
41797        lower = undefined;
41798      }
41799      if (upper !== undefined) {
41800        upper = toNumber(upper);
41801        upper = upper === upper ? upper : 0;
41802      }
41803      if (lower !== undefined) {
41804        lower = toNumber(lower);
41805        lower = lower === lower ? lower : 0;
41806      }
41807      return baseClamp(toNumber(number), lower, upper);
41808    }
41809
41810    /**
41811     * Checks if `n` is between `start` and up to, but not including, `end`. If
41812     * `end` is not specified, it's set to `start` with `start` then set to `0`.
41813     * If `start` is greater than `end` the params are swapped to support
41814     * negative ranges.
41815     *
41816     * @static
41817     * @memberOf _
41818     * @since 3.3.0
41819     * @category Number
41820     * @param {number} number The number to check.
41821     * @param {number} [start=0] The start of the range.
41822     * @param {number} end The end of the range.
41823     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
41824     * @see _.range, _.rangeRight
41825     * @example
41826     *
41827     * _.inRange(3, 2, 4);
41828     * // => true
41829     *
41830     * _.inRange(4, 8);
41831     * // => true
41832     *
41833     * _.inRange(4, 2);
41834     * // => false
41835     *
41836     * _.inRange(2, 2);
41837     * // => false
41838     *
41839     * _.inRange(1.2, 2);
41840     * // => true
41841     *
41842     * _.inRange(5.2, 4);
41843     * // => false
41844     *
41845     * _.inRange(-3, -2, -6);
41846     * // => true
41847     */
41848    function inRange(number, start, end) {
41849      start = toFinite(start);
41850      if (end === undefined) {
41851        end = start;
41852        start = 0;
41853      } else {
41854        end = toFinite(end);
41855      }
41856      number = toNumber(number);
41857      return baseInRange(number, start, end);
41858    }
41859
41860    /**
41861     * Produces a random number between the inclusive `lower` and `upper` bounds.
41862     * If only one argument is provided a number between `0` and the given number
41863     * is returned. If `floating` is `true`, or either `lower` or `upper` are
41864     * floats, a floating-point number is returned instead of an integer.
41865     *
41866     * **Note:** JavaScript follows the IEEE-754 standard for resolving
41867     * floating-point values which can produce unexpected results.
41868     *
41869     * @static
41870     * @memberOf _
41871     * @since 0.7.0
41872     * @category Number
41873     * @param {number} [lower=0] The lower bound.
41874     * @param {number} [upper=1] The upper bound.
41875     * @param {boolean} [floating] Specify returning a floating-point number.
41876     * @returns {number} Returns the random number.
41877     * @example
41878     *
41879     * _.random(0, 5);
41880     * // => an integer between 0 and 5
41881     *
41882     * _.random(5);
41883     * // => also an integer between 0 and 5
41884     *
41885     * _.random(5, true);
41886     * // => a floating-point number between 0 and 5
41887     *
41888     * _.random(1.2, 5.2);
41889     * // => a floating-point number between 1.2 and 5.2
41890     */
41891    function random(lower, upper, floating) {
41892      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
41893        upper = floating = undefined;
41894      }
41895      if (floating === undefined) {
41896        if (typeof upper == 'boolean') {
41897          floating = upper;
41898          upper = undefined;
41899        }
41900        else if (typeof lower == 'boolean') {
41901          floating = lower;
41902          lower = undefined;
41903        }
41904      }
41905      if (lower === undefined && upper === undefined) {
41906        lower = 0;
41907        upper = 1;
41908      }
41909      else {
41910        lower = toFinite(lower);
41911        if (upper === undefined) {
41912          upper = lower;
41913          lower = 0;
41914        } else {
41915          upper = toFinite(upper);
41916        }
41917      }
41918      if (lower > upper) {
41919        var temp = lower;
41920        lower = upper;
41921        upper = temp;
41922      }
41923      if (floating || lower % 1 || upper % 1) {
41924        var rand = nativeRandom();
41925        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
41926      }
41927      return baseRandom(lower, upper);
41928    }
41929
41930    /*------------------------------------------------------------------------*/
41931
41932    /**
41933     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
41934     *
41935     * @static
41936     * @memberOf _
41937     * @since 3.0.0
41938     * @category String
41939     * @param {string} [string=''] The string to convert.
41940     * @returns {string} Returns the camel cased string.
41941     * @example
41942     *
41943     * _.camelCase('Foo Bar');
41944     * // => 'fooBar'
41945     *
41946     * _.camelCase('--foo-bar--');
41947     * // => 'fooBar'
41948     *
41949     * _.camelCase('__FOO_BAR__');
41950     * // => 'fooBar'
41951     */
41952    var camelCase = createCompounder(function(result, word, index) {
41953      word = word.toLowerCase();
41954      return result + (index ? capitalize(word) : word);
41955    });
41956
41957    /**
41958     * Converts the first character of `string` to upper case and the remaining
41959     * to lower case.
41960     *
41961     * @static
41962     * @memberOf _
41963     * @since 3.0.0
41964     * @category String
41965     * @param {string} [string=''] The string to capitalize.
41966     * @returns {string} Returns the capitalized string.
41967     * @example
41968     *
41969     * _.capitalize('FRED');
41970     * // => 'Fred'
41971     */
41972    function capitalize(string) {
41973      return upperFirst(toString(string).toLowerCase());
41974    }
41975
41976    /**
41977     * Deburrs `string` by converting
41978     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
41979     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
41980     * letters to basic Latin letters and removing
41981     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
41982     *
41983     * @static
41984     * @memberOf _
41985     * @since 3.0.0
41986     * @category String
41987     * @param {string} [string=''] The string to deburr.
41988     * @returns {string} Returns the deburred string.
41989     * @example
41990     *
41991     * _.deburr('déjà vu');
41992     * // => 'deja vu'
41993     */
41994    function deburr(string) {
41995      string = toString(string);
41996      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
41997    }
41998
41999    /**
42000     * Checks if `string` ends with the given target string.
42001     *
42002     * @static
42003     * @memberOf _
42004     * @since 3.0.0
42005     * @category String
42006     * @param {string} [string=''] The string to inspect.
42007     * @param {string} [target] The string to search for.
42008     * @param {number} [position=string.length] The position to search up to.
42009     * @returns {boolean} Returns `true` if `string` ends with `target`,
42010     *  else `false`.
42011     * @example
42012     *
42013     * _.endsWith('abc', 'c');
42014     * // => true
42015     *
42016     * _.endsWith('abc', 'b');
42017     * // => false
42018     *
42019     * _.endsWith('abc', 'b', 2);
42020     * // => true
42021     */
42022    function endsWith(string, target, position) {
42023      string = toString(string);
42024      target = baseToString(target);
42025
42026      var length = string.length;
42027      position = position === undefined
42028        ? length
42029        : baseClamp(toInteger(position), 0, length);
42030
42031      var end = position;
42032      position -= target.length;
42033      return position >= 0 && string.slice(position, end) == target;
42034    }
42035
42036    /**
42037     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
42038     * corresponding HTML entities.
42039     *
42040     * **Note:** No other characters are escaped. To escape additional
42041     * characters use a third-party library like [_he_](https://mths.be/he).
42042     *
42043     * Though the ">" character is escaped for symmetry, characters like
42044     * ">" and "/" don't need escaping in HTML and have no special meaning
42045     * unless they're part of a tag or unquoted attribute value. See
42046     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
42047     * (under "semi-related fun fact") for more details.
42048     *
42049     * When working with HTML you should always
42050     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
42051     * XSS vectors.
42052     *
42053     * @static
42054     * @since 0.1.0
42055     * @memberOf _
42056     * @category String
42057     * @param {string} [string=''] The string to escape.
42058     * @returns {string} Returns the escaped string.
42059     * @example
42060     *
42061     * _.escape('fred, barney, & pebbles');
42062     * // => 'fred, barney, &amp; pebbles'
42063     */
42064    function escape(string) {
42065      string = toString(string);
42066      return (string && reHasUnescapedHtml.test(string))
42067        ? string.replace(reUnescapedHtml, escapeHtmlChar)
42068        : string;
42069    }
42070
42071    /**
42072     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
42073     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
42074     *
42075     * @static
42076     * @memberOf _
42077     * @since 3.0.0
42078     * @category String
42079     * @param {string} [string=''] The string to escape.
42080     * @returns {string} Returns the escaped string.
42081     * @example
42082     *
42083     * _.escapeRegExp('[lodash](https://lodash.com/)');
42084     * // => '\[lodash\]\(https://lodash\.com/\)'
42085     */
42086    function escapeRegExp(string) {
vendor: 4,658 bytes, lines 42087-42256
42087      string = toString(string);
42088      return (string && reHasRegExpChar.test(string))
42089        ? string.replace(reRegExpChar, '\\$&')
42090        : string;
42091    }
42092
42093    /**
42094     * Converts `string` to
42095     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
42096     *
42097     * @static
42098     * @memberOf _
42099     * @since 3.0.0
42100     * @category String
42101     * @param {string} [string=''] The string to convert.
42102     * @returns {string} Returns the kebab cased string.
42103     * @example
42104     *
42105     * _.kebabCase('Foo Bar');
42106     * // => 'foo-bar'
42107     *
42108     * _.kebabCase('fooBar');
42109     * // => 'foo-bar'
42110     *
42111     * _.kebabCase('__FOO_BAR__');
42112     * // => 'foo-bar'
42113     */
42114    var kebabCase = createCompounder(function(result, word, index) {
42115      return result + (index ? '-' : '') + word.toLowerCase();
42116    });
42117
42118    /**
42119     * Converts `string`, as space separated words, to lower case.
42120     *
42121     * @static
42122     * @memberOf _
42123     * @since 4.0.0
42124     * @category String
42125     * @param {string} [string=''] The string to convert.
42126     * @returns {string} Returns the lower cased string.
42127     * @example
42128     *
42129     * _.lowerCase('--Foo-Bar--');
42130     * // => 'foo bar'
42131     *
42132     * _.lowerCase('fooBar');
42133     * // => 'foo bar'
42134     *
42135     * _.lowerCase('__FOO_BAR__');
42136     * // => 'foo bar'
42137     */
42138    var lowerCase = createCompounder(function(result, word, index) {
42139      return result + (index ? ' ' : '') + word.toLowerCase();
42140    });
42141
42142    /**
42143     * Converts the first character of `string` to lower case.
42144     *
42145     * @static
42146     * @memberOf _
42147     * @since 4.0.0
42148     * @category String
42149     * @param {string} [string=''] The string to convert.
42150     * @returns {string} Returns the converted string.
42151     * @example
42152     *
42153     * _.lowerFirst('Fred');
42154     * // => 'fred'
42155     *
42156     * _.lowerFirst('FRED');
42157     * // => 'fRED'
42158     */
42159    var lowerFirst = createCaseFirst('toLowerCase');
42160
42161    /**
42162     * Pads `string` on the left and right sides if it's shorter than `length`.
42163     * Padding characters are truncated if they can't be evenly divided by `length`.
42164     *
42165     * @static
42166     * @memberOf _
42167     * @since 3.0.0
42168     * @category String
42169     * @param {string} [string=''] The string to pad.
42170     * @param {number} [length=0] The padding length.
42171     * @param {string} [chars=' '] The string used as padding.
42172     * @returns {string} Returns the padded string.
42173     * @example
42174     *
42175     * _.pad('abc', 8);
42176     * // => '  abc   '
42177     *
42178     * _.pad('abc', 8, '_-');
42179     * // => '_-abc_-_'
42180     *
42181     * _.pad('abc', 3);
42182     * // => 'abc'
42183     */
42184    function pad(string, length, chars) {
42185      string = toString(string);
42186      length = toInteger(length);
42187
42188      var strLength = length ? stringSize(string) : 0;
42189      if (!length || strLength >= length) {
42190        return string;
42191      }
42192      var mid = (length - strLength) / 2;
42193      return (
42194        createPadding(nativeFloor(mid), chars) +
42195        string +
42196        createPadding(nativeCeil(mid), chars)
42197      );
42198    }
42199
42200    /**
42201     * Pads `string` on the right side if it's shorter than `length`. Padding
42202     * characters are truncated if they exceed `length`.
42203     *
42204     * @static
42205     * @memberOf _
42206     * @since 4.0.0
42207     * @category String
42208     * @param {string} [string=''] The string to pad.
42209     * @param {number} [length=0] The padding length.
42210     * @param {string} [chars=' '] The string used as padding.
42211     * @returns {string} Returns the padded string.
42212     * @example
42213     *
42214     * _.padEnd('abc', 6);
42215     * // => 'abc   '
42216     *
42217     * _.padEnd('abc', 6, '_-');
42218     * // => 'abc_-_'
42219     *
42220     * _.padEnd('abc', 3);
42221     * // => 'abc'
42222     */
42223    function padEnd(string, length, chars) {
42224      string = toString(string);
42225      length = toInteger(length);
42226
42227      var strLength = length ? stringSize(string) : 0;
42228      return (length && strLength < length)
42229        ? (string + createPadding(length - strLength, chars))
42230        : string;
42231    }
42232
42233    /**
42234     * Pads `string` on the left side if it's shorter than `length`. Padding
42235     * characters are truncated if they exceed `length`.
42236     *
42237     * @static
42238     * @memberOf _
42239     * @since 4.0.0
42240     * @category String
42241     * @param {string} [string=''] The string to pad.
42242     * @param {number} [length=0] The padding length.
42243     * @param {string} [chars=' '] The string used as padding.
42244     * @returns {string} Returns the padded string.
42245     * @example
42246     *
42247     * _.padStart('abc', 6);
42248     * // => '   abc'
42249     *
42250     * _.padStart('abc', 6, '_-');
42251     * // => '_-_abc'
42252     *
42253     * _.padStart('abc', 3);
42254     * // => 'abc'
42255     */
42256    function padStart(string, length, chars) {
vendor: 29,827 bytes, lines 42257-43154
42257      string = toString(string);
42258      length = toInteger(length);
42259
42260      var strLength = length ? stringSize(string) : 0;
42261      return (length && strLength < length)
42262        ? (createPadding(length - strLength, chars) + string)
42263        : string;
42264    }
42265
42266    /**
42267     * Converts `string` to an integer of the specified radix. If `radix` is
42268     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
42269     * hexadecimal, in which case a `radix` of `16` is used.
42270     *
42271     * **Note:** This method aligns with the
42272     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
42273     *
42274     * @static
42275     * @memberOf _
42276     * @since 1.1.0
42277     * @category String
42278     * @param {string} string The string to convert.
42279     * @param {number} [radix=10] The radix to interpret `value` by.
42280     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
42281     * @returns {number} Returns the converted integer.
42282     * @example
42283     *
42284     * _.parseInt('08');
42285     * // => 8
42286     *
42287     * _.map(['6', '08', '10'], _.parseInt);
42288     * // => [6, 8, 10]
42289     */
42290    function parseInt(string, radix, guard) {
42291      if (guard || radix == null) {
42292        radix = 0;
42293      } else if (radix) {
42294        radix = +radix;
42295      }
42296      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
42297    }
42298
42299    /**
42300     * Repeats the given string `n` times.
42301     *
42302     * @static
42303     * @memberOf _
42304     * @since 3.0.0
42305     * @category String
42306     * @param {string} [string=''] The string to repeat.
42307     * @param {number} [n=1] The number of times to repeat the string.
42308     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
42309     * @returns {string} Returns the repeated string.
42310     * @example
42311     *
42312     * _.repeat('*', 3);
42313     * // => '***'
42314     *
42315     * _.repeat('abc', 2);
42316     * // => 'abcabc'
42317     *
42318     * _.repeat('abc', 0);
42319     * // => ''
42320     */
42321    function repeat(string, n, guard) {
42322      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
42323        n = 1;
42324      } else {
42325        n = toInteger(n);
42326      }
42327      return baseRepeat(toString(string), n);
42328    }
42329
42330    /**
42331     * Replaces matches for `pattern` in `string` with `replacement`.
42332     *
42333     * **Note:** This method is based on
42334     * [`String#replace`](https://mdn.io/String/replace).
42335     *
42336     * @static
42337     * @memberOf _
42338     * @since 4.0.0
42339     * @category String
42340     * @param {string} [string=''] The string to modify.
42341     * @param {RegExp|string} pattern The pattern to replace.
42342     * @param {Function|string} replacement The match replacement.
42343     * @returns {string} Returns the modified string.
42344     * @example
42345     *
42346     * _.replace('Hi Fred', 'Fred', 'Barney');
42347     * // => 'Hi Barney'
42348     */
42349    function replace() {
42350      var args = arguments,
42351          string = toString(args[0]);
42352
42353      return args.length < 3 ? string : string.replace(args[1], args[2]);
42354    }
42355
42356    /**
42357     * Converts `string` to
42358     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
42359     *
42360     * @static
42361     * @memberOf _
42362     * @since 3.0.0
42363     * @category String
42364     * @param {string} [string=''] The string to convert.
42365     * @returns {string} Returns the snake cased string.
42366     * @example
42367     *
42368     * _.snakeCase('Foo Bar');
42369     * // => 'foo_bar'
42370     *
42371     * _.snakeCase('fooBar');
42372     * // => 'foo_bar'
42373     *
42374     * _.snakeCase('--FOO-BAR--');
42375     * // => 'foo_bar'
42376     */
42377    var snakeCase = createCompounder(function(result, word, index) {
42378      return result + (index ? '_' : '') + word.toLowerCase();
42379    });
42380
42381    /**
42382     * Splits `string` by `separator`.
42383     *
42384     * **Note:** This method is based on
42385     * [`String#split`](https://mdn.io/String/split).
42386     *
42387     * @static
42388     * @memberOf _
42389     * @since 4.0.0
42390     * @category String
42391     * @param {string} [string=''] The string to split.
42392     * @param {RegExp|string} separator The separator pattern to split by.
42393     * @param {number} [limit] The length to truncate results to.
42394     * @returns {Array} Returns the string segments.
42395     * @example
42396     *
42397     * _.split('a-b-c', '-', 2);
42398     * // => ['a', 'b']
42399     */
42400    function split(string, separator, limit) {
42401      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
42402        separator = limit = undefined;
42403      }
42404      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
42405      if (!limit) {
42406        return [];
42407      }
42408      string = toString(string);
42409      if (string && (
42410            typeof separator == 'string' ||
42411            (separator != null && !isRegExp(separator))
42412          )) {
42413        separator = baseToString(separator);
42414        if (!separator && hasUnicode(string)) {
42415          return castSlice(stringToArray(string), 0, limit);
42416        }
42417      }
42418      return string.split(separator, limit);
42419    }
42420
42421    /**
42422     * Converts `string` to
42423     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
42424     *
42425     * @static
42426     * @memberOf _
42427     * @since 3.1.0
42428     * @category String
42429     * @param {string} [string=''] The string to convert.
42430     * @returns {string} Returns the start cased string.
42431     * @example
42432     *
42433     * _.startCase('--foo-bar--');
42434     * // => 'Foo Bar'
42435     *
42436     * _.startCase('fooBar');
42437     * // => 'Foo Bar'
42438     *
42439     * _.startCase('__FOO_BAR__');
42440     * // => 'FOO BAR'
42441     */
42442    var startCase = createCompounder(function(result, word, index) {
42443      return result + (index ? ' ' : '') + upperFirst(word);
42444    });
42445
42446    /**
42447     * Checks if `string` starts with the given target string.
42448     *
42449     * @static
42450     * @memberOf _
42451     * @since 3.0.0
42452     * @category String
42453     * @param {string} [string=''] The string to inspect.
42454     * @param {string} [target] The string to search for.
42455     * @param {number} [position=0] The position to search from.
42456     * @returns {boolean} Returns `true` if `string` starts with `target`,
42457     *  else `false`.
42458     * @example
42459     *
42460     * _.startsWith('abc', 'a');
42461     * // => true
42462     *
42463     * _.startsWith('abc', 'b');
42464     * // => false
42465     *
42466     * _.startsWith('abc', 'b', 1);
42467     * // => true
42468     */
42469    function startsWith(string, target, position) {
42470      string = toString(string);
42471      position = position == null
42472        ? 0
42473        : baseClamp(toInteger(position), 0, string.length);
42474
42475      target = baseToString(target);
42476      return string.slice(position, position + target.length) == target;
42477    }
42478
42479    /**
42480     * Creates a compiled template function that can interpolate data properties
42481     * in "interpolate" delimiters, HTML-escape interpolated data properties in
42482     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
42483     * properties may be accessed as free variables in the template. If a setting
42484     * object is given, it takes precedence over `_.templateSettings` values.
42485     *
42486     * **Note:** In the development build `_.template` utilizes
42487     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
42488     * for easier debugging.
42489     *
42490     * For more information on precompiling templates see
42491     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
42492     *
42493     * For more information on Chrome extension sandboxes see
42494     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
42495     *
42496     * @static
42497     * @since 0.1.0
42498     * @memberOf _
42499     * @category String
42500     * @param {string} [string=''] The template string.
42501     * @param {Object} [options={}] The options object.
42502     * @param {RegExp} [options.escape=_.templateSettings.escape]
42503     *  The HTML "escape" delimiter.
42504     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
42505     *  The "evaluate" delimiter.
42506     * @param {Object} [options.imports=_.templateSettings.imports]
42507     *  An object to import into the template as free variables.
42508     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
42509     *  The "interpolate" delimiter.
42510     * @param {string} [options.sourceURL='lodash.templateSources[n]']
42511     *  The sourceURL of the compiled template.
42512     * @param {string} [options.variable='obj']
42513     *  The data object variable name.
42514     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
42515     * @returns {Function} Returns the compiled template function.
42516     * @example
42517     *
42518     * // Use the "interpolate" delimiter to create a compiled template.
42519     * var compiled = _.template('hello <%= user %>!');
42520     * compiled({ 'user': 'fred' });
42521     * // => 'hello fred!'
42522     *
42523     * // Use the HTML "escape" delimiter to escape data property values.
42524     * var compiled = _.template('<b><%- value %></b>');
42525     * compiled({ 'value': '<script>' });
42526     * // => '<b>&lt;script&gt;</b>'
42527     *
42528     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
42529     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
42530     * compiled({ 'users': ['fred', 'barney'] });
42531     * // => '<li>fred</li><li>barney</li>'
42532     *
42533     * // Use the internal `print` function in "evaluate" delimiters.
42534     * var compiled = _.template('<% print("hello " + user); %>!');
42535     * compiled({ 'user': 'barney' });
42536     * // => 'hello barney!'
42537     *
42538     * // Use the ES template literal delimiter as an "interpolate" delimiter.
42539     * // Disable support by replacing the "interpolate" delimiter.
42540     * var compiled = _.template('hello ${ user }!');
42541     * compiled({ 'user': 'pebbles' });
42542     * // => 'hello pebbles!'
42543     *
42544     * // Use backslashes to treat delimiters as plain text.
42545     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
42546     * compiled({ 'value': 'ignored' });
42547     * // => '<%- value %>'
42548     *
42549     * // Use the `imports` option to import `jQuery` as `jq`.
42550     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
42551     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
42552     * compiled({ 'users': ['fred', 'barney'] });
42553     * // => '<li>fred</li><li>barney</li>'
42554     *
42555     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
42556     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
42557     * compiled(data);
42558     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
42559     *
42560     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
42561     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
42562     * compiled.source;
42563     * // => function(data) {
42564     * //   var __t, __p = '';
42565     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
42566     * //   return __p;
42567     * // }
42568     *
42569     * // Use custom template delimiters.
42570     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
42571     * var compiled = _.template('hello {{ user }}!');
42572     * compiled({ 'user': 'mustache' });
42573     * // => 'hello mustache!'
42574     *
42575     * // Use the `source` property to inline compiled templates for meaningful
42576     * // line numbers in error messages and stack traces.
42577     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
42578     *   var JST = {\
42579     *     "main": ' + _.template(mainText).source + '\
42580     *   };\
42581     * ');
42582     */
42583    function template(string, options, guard) {
42584      // Based on John Resig's `tmpl` implementation
42585      // (http://ejohn.org/blog/javascript-micro-templating/)
42586      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
42587      var settings = lodash.templateSettings;
42588
42589      if (guard && isIterateeCall(string, options, guard)) {
42590        options = undefined;
42591      }
42592      string = toString(string);
42593      options = assignInWith({}, options, settings, customDefaultsAssignIn);
42594
42595      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
42596          importsKeys = keys(imports),
42597          importsValues = baseValues(imports, importsKeys);
42598
42599      var isEscaping,
42600          isEvaluating,
42601          index = 0,
42602          interpolate = options.interpolate || reNoMatch,
42603          source = "__p += '";
42604
42605      // Compile the regexp to match each delimiter.
42606      var reDelimiters = RegExp(
42607        (options.escape || reNoMatch).source + '|' +
42608        interpolate.source + '|' +
42609        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
42610        (options.evaluate || reNoMatch).source + '|$'
42611      , 'g');
42612
42613      // Use a sourceURL for easier debugging.
42614      // The sourceURL gets injected into the source that's eval-ed, so be careful
42615      // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
42616      // and escape the comment, thus injecting code that gets evaled.
42617      var sourceURL = '//# sourceURL=' +
42618        (hasOwnProperty.call(options, 'sourceURL')
42619          ? (options.sourceURL + '').replace(/\s/g, ' ')
42620          : ('lodash.templateSources[' + (++templateCounter) + ']')
42621        ) + '\n';
42622
42623      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
42624        interpolateValue || (interpolateValue = esTemplateValue);
42625
42626        // Escape characters that can't be included in string literals.
42627        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
42628
42629        // Replace delimiters with snippets.
42630        if (escapeValue) {
42631          isEscaping = true;
42632          source += "' +\n__e(" + escapeValue + ") +\n'";
42633        }
42634        if (evaluateValue) {
42635          isEvaluating = true;
42636          source += "';\n" + evaluateValue + ";\n__p += '";
42637        }
42638        if (interpolateValue) {
42639          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
42640        }
42641        index = offset + match.length;
42642
42643        // The JS engine embedded in Adobe products needs `match` returned in
42644        // order to produce the correct `offset` value.
42645        return match;
42646      });
42647
42648      source += "';\n";
42649
42650      // If `variable` is not specified wrap a with-statement around the generated
42651      // code to add the data object to the top of the scope chain.
42652      var variable = hasOwnProperty.call(options, 'variable') && options.variable;
42653      if (!variable) {
42654        source = 'with (obj) {\n' + source + '\n}\n';
42655      }
42656      // Throw an error if a forbidden character was found in `variable`, to prevent
42657      // potential command injection attacks.
42658      else if (reForbiddenIdentifierChars.test(variable)) {
42659        throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
42660      }
42661
42662      // Cleanup code by stripping empty strings.
42663      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
42664        .replace(reEmptyStringMiddle, '$1')
42665        .replace(reEmptyStringTrailing, '$1;');
42666
42667      // Frame code as the function body.
42668      source = 'function(' + (variable || 'obj') + ') {\n' +
42669        (variable
42670          ? ''
42671          : 'obj || (obj = {});\n'
42672        ) +
42673        "var __t, __p = ''" +
42674        (isEscaping
42675           ? ', __e = _.escape'
42676           : ''
42677        ) +
42678        (isEvaluating
42679          ? ', __j = Array.prototype.join;\n' +
42680            "function print() { __p += __j.call(arguments, '') }\n"
42681          : ';\n'
42682        ) +
42683        source +
42684        'return __p\n}';
42685
42686      var result = attempt(function() {
42687        return Function(importsKeys, sourceURL + 'return ' + source)
42688          .apply(undefined, importsValues);
42689      });
42690
42691      // Provide the compiled function's source by its `toString` method or
42692      // the `source` property as a convenience for inlining compiled templates.
42693      result.source = source;
42694      if (isError(result)) {
42695        throw result;
42696      }
42697      return result;
42698    }
42699
42700    /**
42701     * Converts `string`, as a whole, to lower case just like
42702     * [String#toLowerCase](https://mdn.io/toLowerCase).
42703     *
42704     * @static
42705     * @memberOf _
42706     * @since 4.0.0
42707     * @category String
42708     * @param {string} [string=''] The string to convert.
42709     * @returns {string} Returns the lower cased string.
42710     * @example
42711     *
42712     * _.toLower('--Foo-Bar--');
42713     * // => '--foo-bar--'
42714     *
42715     * _.toLower('fooBar');
42716     * // => 'foobar'
42717     *
42718     * _.toLower('__FOO_BAR__');
42719     * // => '__foo_bar__'
42720     */
42721    function toLower(value) {
42722      return toString(value).toLowerCase();
42723    }
42724
42725    /**
42726     * Converts `string`, as a whole, to upper case just like
42727     * [String#toUpperCase](https://mdn.io/toUpperCase).
42728     *
42729     * @static
42730     * @memberOf _
42731     * @since 4.0.0
42732     * @category String
42733     * @param {string} [string=''] The string to convert.
42734     * @returns {string} Returns the upper cased string.
42735     * @example
42736     *
42737     * _.toUpper('--foo-bar--');
42738     * // => '--FOO-BAR--'
42739     *
42740     * _.toUpper('fooBar');
42741     * // => 'FOOBAR'
42742     *
42743     * _.toUpper('__foo_bar__');
42744     * // => '__FOO_BAR__'
42745     */
42746    function toUpper(value) {
42747      return toString(value).toUpperCase();
42748    }
42749
42750    /**
42751     * Removes leading and trailing whitespace or specified characters from `string`.
42752     *
42753     * @static
42754     * @memberOf _
42755     * @since 3.0.0
42756     * @category String
42757     * @param {string} [string=''] The string to trim.
42758     * @param {string} [chars=whitespace] The characters to trim.
42759     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
42760     * @returns {string} Returns the trimmed string.
42761     * @example
42762     *
42763     * _.trim('  abc  ');
42764     * // => 'abc'
42765     *
42766     * _.trim('-_-abc-_-', '_-');
42767     * // => 'abc'
42768     *
42769     * _.map(['  foo  ', '  bar  '], _.trim);
42770     * // => ['foo', 'bar']
42771     */
42772    function trim(string, chars, guard) {
42773      string = toString(string);
42774      if (string && (guard || chars === undefined)) {
42775        return baseTrim(string);
42776      }
42777      if (!string || !(chars = baseToString(chars))) {
42778        return string;
42779      }
42780      var strSymbols = stringToArray(string),
42781          chrSymbols = stringToArray(chars),
42782          start = charsStartIndex(strSymbols, chrSymbols),
42783          end = charsEndIndex(strSymbols, chrSymbols) + 1;
42784
42785      return castSlice(strSymbols, start, end).join('');
42786    }
42787
42788    /**
42789     * Removes trailing whitespace or specified characters from `string`.
42790     *
42791     * @static
42792     * @memberOf _
42793     * @since 4.0.0
42794     * @category String
42795     * @param {string} [string=''] The string to trim.
42796     * @param {string} [chars=whitespace] The characters to trim.
42797     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
42798     * @returns {string} Returns the trimmed string.
42799     * @example
42800     *
42801     * _.trimEnd('  abc  ');
42802     * // => '  abc'
42803     *
42804     * _.trimEnd('-_-abc-_-', '_-');
42805     * // => '-_-abc'
42806     */
42807    function trimEnd(string, chars, guard) {
42808      string = toString(string);
42809      if (string && (guard || chars === undefined)) {
42810        return string.slice(0, trimmedEndIndex(string) + 1);
42811      }
42812      if (!string || !(chars = baseToString(chars))) {
42813        return string;
42814      }
42815      var strSymbols = stringToArray(string),
42816          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
42817
42818      return castSlice(strSymbols, 0, end).join('');
42819    }
42820
42821    /**
42822     * Removes leading whitespace or specified characters from `string`.
42823     *
42824     * @static
42825     * @memberOf _
42826     * @since 4.0.0
42827     * @category String
42828     * @param {string} [string=''] The string to trim.
42829     * @param {string} [chars=whitespace] The characters to trim.
42830     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
42831     * @returns {string} Returns the trimmed string.
42832     * @example
42833     *
42834     * _.trimStart('  abc  ');
42835     * // => 'abc  '
42836     *
42837     * _.trimStart('-_-abc-_-', '_-');
42838     * // => 'abc-_-'
42839     */
42840    function trimStart(string, chars, guard) {
42841      string = toString(string);
42842      if (string && (guard || chars === undefined)) {
42843        return string.replace(reTrimStart, '');
42844      }
42845      if (!string || !(chars = baseToString(chars))) {
42846        return string;
42847      }
42848      var strSymbols = stringToArray(string),
42849          start = charsStartIndex(strSymbols, stringToArray(chars));
42850
42851      return castSlice(strSymbols, start).join('');
42852    }
42853
42854    /**
42855     * Truncates `string` if it's longer than the given maximum string length.
42856     * The last characters of the truncated string are replaced with the omission
42857     * string which defaults to "...".
42858     *
42859     * @static
42860     * @memberOf _
42861     * @since 4.0.0
42862     * @category String
42863     * @param {string} [string=''] The string to truncate.
42864     * @param {Object} [options={}] The options object.
42865     * @param {number} [options.length=30] The maximum string length.
42866     * @param {string} [options.omission='...'] The string to indicate text is omitted.
42867     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
42868     * @returns {string} Returns the truncated string.
42869     * @example
42870     *
42871     * _.truncate('hi-diddly-ho there, neighborino');
42872     * // => 'hi-diddly-ho there, neighbo...'
42873     *
42874     * _.truncate('hi-diddly-ho there, neighborino', {
42875     *   'length': 24,
42876     *   'separator': ' '
42877     * });
42878     * // => 'hi-diddly-ho there,...'
42879     *
42880     * _.truncate('hi-diddly-ho there, neighborino', {
42881     *   'length': 24,
42882     *   'separator': /,? +/
42883     * });
42884     * // => 'hi-diddly-ho there...'
42885     *
42886     * _.truncate('hi-diddly-ho there, neighborino', {
42887     *   'omission': ' [...]'
42888     * });
42889     * // => 'hi-diddly-ho there, neig [...]'
42890     */
42891    function truncate(string, options) {
42892      var length = DEFAULT_TRUNC_LENGTH,
42893          omission = DEFAULT_TRUNC_OMISSION;
42894
42895      if (isObject(options)) {
42896        var separator = 'separator' in options ? options.separator : separator;
42897        length = 'length' in options ? toInteger(options.length) : length;
42898        omission = 'omission' in options ? baseToString(options.omission) : omission;
42899      }
42900      string = toString(string);
42901
42902      var strLength = string.length;
42903      if (hasUnicode(string)) {
42904        var strSymbols = stringToArray(string);
42905        strLength = strSymbols.length;
42906      }
42907      if (length >= strLength) {
42908        return string;
42909      }
42910      var end = length - stringSize(omission);
42911      if (end < 1) {
42912        return omission;
42913      }
42914      var result = strSymbols
42915        ? castSlice(strSymbols, 0, end).join('')
42916        : string.slice(0, end);
42917
42918      if (separator === undefined) {
42919        return result + omission;
42920      }
42921      if (strSymbols) {
42922        end += (result.length - end);
42923      }
42924      if (isRegExp(separator)) {
42925        if (string.slice(end).search(separator)) {
42926          var match,
42927              substring = result;
42928
42929          if (!separator.global) {
42930            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
42931          }
42932          separator.lastIndex = 0;
42933          while ((match = separator.exec(substring))) {
42934            var newEnd = match.index;
42935          }
42936          result = result.slice(0, newEnd === undefined ? end : newEnd);
42937        }
42938      } else if (string.indexOf(baseToString(separator), end) != end) {
42939        var index = result.lastIndexOf(separator);
42940        if (index > -1) {
42941          result = result.slice(0, index);
42942        }
42943      }
42944      return result + omission;
42945    }
42946
42947    /**
42948     * The inverse of `_.escape`; this method converts the HTML entities
42949     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
42950     * their corresponding characters.
42951     *
42952     * **Note:** No other HTML entities are unescaped. To unescape additional
42953     * HTML entities use a third-party library like [_he_](https://mths.be/he).
42954     *
42955     * @static
42956     * @memberOf _
42957     * @since 0.6.0
42958     * @category String
42959     * @param {string} [string=''] The string to unescape.
42960     * @returns {string} Returns the unescaped string.
42961     * @example
42962     *
42963     * _.unescape('fred, barney, &amp; pebbles');
42964     * // => 'fred, barney, & pebbles'
42965     */
42966    function unescape(string) {
42967      string = toString(string);
42968      return (string && reHasEscapedHtml.test(string))
42969        ? string.replace(reEscapedHtml, unescapeHtmlChar)
42970        : string;
42971    }
42972
42973    /**
42974     * Converts `string`, as space separated words, to upper case.
42975     *
42976     * @static
42977     * @memberOf _
42978     * @since 4.0.0
42979     * @category String
42980     * @param {string} [string=''] The string to convert.
42981     * @returns {string} Returns the upper cased string.
42982     * @example
42983     *
42984     * _.upperCase('--foo-bar');
42985     * // => 'FOO BAR'
42986     *
42987     * _.upperCase('fooBar');
42988     * // => 'FOO BAR'
42989     *
42990     * _.upperCase('__foo_bar__');
42991     * // => 'FOO BAR'
42992     */
42993    var upperCase = createCompounder(function(result, word, index) {
42994      return result + (index ? ' ' : '') + word.toUpperCase();
42995    });
42996
42997    /**
42998     * Converts the first character of `string` to upper case.
42999     *
43000     * @static
43001     * @memberOf _
43002     * @since 4.0.0
43003     * @category String
43004     * @param {string} [string=''] The string to convert.
43005     * @returns {string} Returns the converted string.
43006     * @example
43007     *
43008     * _.upperFirst('fred');
43009     * // => 'Fred'
43010     *
43011     * _.upperFirst('FRED');
43012     * // => 'FRED'
43013     */
43014    var upperFirst = createCaseFirst('toUpperCase');
43015
43016    /**
43017     * Splits `string` into an array of its words.
43018     *
43019     * @static
43020     * @memberOf _
43021     * @since 3.0.0
43022     * @category String
43023     * @param {string} [string=''] The string to inspect.
43024     * @param {RegExp|string} [pattern] The pattern to match words.
43025     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
43026     * @returns {Array} Returns the words of `string`.
43027     * @example
43028     *
43029     * _.words('fred, barney, & pebbles');
43030     * // => ['fred', 'barney', 'pebbles']
43031     *
43032     * _.words('fred, barney, & pebbles', /[^, ]+/g);
43033     * // => ['fred', 'barney', '&', 'pebbles']
43034     */
43035    function words(string, pattern, guard) {
43036      string = toString(string);
43037      pattern = guard ? undefined : pattern;
43038
43039      if (pattern === undefined) {
43040        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
43041      }
43042      return string.match(pattern) || [];
43043    }
43044
43045    /*------------------------------------------------------------------------*/
43046
43047    /**
43048     * Attempts to invoke `func`, returning either the result or the caught error
43049     * object. Any additional arguments are provided to `func` when it's invoked.
43050     *
43051     * @static
43052     * @memberOf _
43053     * @since 3.0.0
43054     * @category Util
43055     * @param {Function} func The function to attempt.
43056     * @param {...*} [args] The arguments to invoke `func` with.
43057     * @returns {*} Returns the `func` result or error object.
43058     * @example
43059     *
43060     * // Avoid throwing errors for invalid selectors.
43061     * var elements = _.attempt(function(selector) {
43062     *   return document.querySelectorAll(selector);
43063     * }, '>_>');
43064     *
43065     * if (_.isError(elements)) {
43066     *   elements = [];
43067     * }
43068     */
43069    var attempt = baseRest(function(func, args) {
43070      try {
43071        return apply(func, undefined, args);
43072      } catch (e) {
43073        return isError(e) ? e : new Error(e);
43074      }
43075    });
43076
43077    /**
43078     * Binds methods of an object to the object itself, overwriting the existing
43079     * method.
43080     *
43081     * **Note:** This method doesn't set the "length" property of bound functions.
43082     *
43083     * @static
43084     * @since 0.1.0
43085     * @memberOf _
43086     * @category Util
43087     * @param {Object} object The object to bind and assign the bound methods to.
43088     * @param {...(string|string[])} methodNames The object method names to bind.
43089     * @returns {Object} Returns `object`.
43090     * @example
43091     *
43092     * var view = {
43093     *   'label': 'docs',
43094     *   'click': function() {
43095     *     console.log('clicked ' + this.label);
43096     *   }
43097     * };
43098     *
43099     * _.bindAll(view, ['click']);
43100     * jQuery(element).on('click', view.click);
43101     * // => Logs 'clicked docs' when clicked.
43102     */
43103    var bindAll = flatRest(function(object, methodNames) {
43104      arrayEach(methodNames, function(key) {
43105        key = toKey(key);
43106        baseAssignValue(object, key, bind(object[key], object));
43107      });
43108      return object;
43109    });
43110
43111    /**
43112     * Creates a function that iterates over `pairs` and invokes the corresponding
43113     * function of the first predicate to return truthy. The predicate-function
43114     * pairs are invoked with the `this` binding and arguments of the created
43115     * function.
43116     *
43117     * @static
43118     * @memberOf _
43119     * @since 4.0.0
43120     * @category Util
43121     * @param {Array} pairs The predicate-function pairs.
43122     * @returns {Function} Returns the new composite function.
43123     * @example
43124     *
43125     * var func = _.cond([
43126     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
43127     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
43128     *   [_.stubTrue,                      _.constant('no match')]
43129     * ]);
43130     *
43131     * func({ 'a': 1, 'b': 2 });
43132     * // => 'matches A'
43133     *
43134     * func({ 'a': 0, 'b': 1 });
43135     * // => 'matches B'
43136     *
43137     * func({ 'a': '1', 'b': '2' });
43138     * // => 'no match'
43139     */
43140    function cond(pairs) {
43141      var length = pairs == null ? 0 : pairs.length,
43142          toIteratee = getIteratee();
43143
43144      pairs = !length ? [] : arrayMap(pairs, function(pair) {
43145        if (typeof pair[1] != 'function') {
43146          throw new TypeError(FUNC_ERROR_TEXT);
43147        }
43148        return [toIteratee(pair[0]), pair[1]];
43149      });
43150
43151      return baseRest(function(args) {
43152        var index = -1;
43153        while (++index < length) {
43154          var pair = pairs[index];
vendor: 10,296 bytes, lines 43155-43487
43155          if (apply(pair[0], this, args)) {
43156            return apply(pair[1], this, args);
43157          }
43158        }
43159      });
43160    }
43161
43162    /**
43163     * Creates a function that invokes the predicate properties of `source` with
43164     * the corresponding property values of a given object, returning `true` if
43165     * all predicates return truthy, else `false`.
43166     *
43167     * **Note:** The created function is equivalent to `_.conformsTo` with
43168     * `source` partially applied.
43169     *
43170     * @static
43171     * @memberOf _
43172     * @since 4.0.0
43173     * @category Util
43174     * @param {Object} source The object of property predicates to conform to.
43175     * @returns {Function} Returns the new spec function.
43176     * @example
43177     *
43178     * var objects = [
43179     *   { 'a': 2, 'b': 1 },
43180     *   { 'a': 1, 'b': 2 }
43181     * ];
43182     *
43183     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
43184     * // => [{ 'a': 1, 'b': 2 }]
43185     */
43186    function conforms(source) {
43187      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
43188    }
43189
43190    /**
43191     * Creates a function that returns `value`.
43192     *
43193     * @static
43194     * @memberOf _
43195     * @since 2.4.0
43196     * @category Util
43197     * @param {*} value The value to return from the new function.
43198     * @returns {Function} Returns the new constant function.
43199     * @example
43200     *
43201     * var objects = _.times(2, _.constant({ 'a': 1 }));
43202     *
43203     * console.log(objects);
43204     * // => [{ 'a': 1 }, { 'a': 1 }]
43205     *
43206     * console.log(objects[0] === objects[1]);
43207     * // => true
43208     */
43209    function constant(value) {
43210      return function() {
43211        return value;
43212      };
43213    }
43214
43215    /**
43216     * Checks `value` to determine whether a default value should be returned in
43217     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
43218     * or `undefined`.
43219     *
43220     * @static
43221     * @memberOf _
43222     * @since 4.14.0
43223     * @category Util
43224     * @param {*} value The value to check.
43225     * @param {*} defaultValue The default value.
43226     * @returns {*} Returns the resolved value.
43227     * @example
43228     *
43229     * _.defaultTo(1, 10);
43230     * // => 1
43231     *
43232     * _.defaultTo(undefined, 10);
43233     * // => 10
43234     */
43235    function defaultTo(value, defaultValue) {
43236      return (value == null || value !== value) ? defaultValue : value;
43237    }
43238
43239    /**
43240     * Creates a function that returns the result of invoking the given functions
43241     * with the `this` binding of the created function, where each successive
43242     * invocation is supplied the return value of the previous.
43243     *
43244     * @static
43245     * @memberOf _
43246     * @since 3.0.0
43247     * @category Util
43248     * @param {...(Function|Function[])} [funcs] The functions to invoke.
43249     * @returns {Function} Returns the new composite function.
43250     * @see _.flowRight
43251     * @example
43252     *
43253     * function square(n) {
43254     *   return n * n;
43255     * }
43256     *
43257     * var addSquare = _.flow([_.add, square]);
43258     * addSquare(1, 2);
43259     * // => 9
43260     */
43261    var flow = createFlow();
43262
43263    /**
43264     * This method is like `_.flow` except that it creates a function that
43265     * invokes the given functions from right to left.
43266     *
43267     * @static
43268     * @since 3.0.0
43269     * @memberOf _
43270     * @category Util
43271     * @param {...(Function|Function[])} [funcs] The functions to invoke.
43272     * @returns {Function} Returns the new composite function.
43273     * @see _.flow
43274     * @example
43275     *
43276     * function square(n) {
43277     *   return n * n;
43278     * }
43279     *
43280     * var addSquare = _.flowRight([square, _.add]);
43281     * addSquare(1, 2);
43282     * // => 9
43283     */
43284    var flowRight = createFlow(true);
43285
43286    /**
43287     * This method returns the first argument it receives.
43288     *
43289     * @static
43290     * @since 0.1.0
43291     * @memberOf _
43292     * @category Util
43293     * @param {*} value Any value.
43294     * @returns {*} Returns `value`.
43295     * @example
43296     *
43297     * var object = { 'a': 1 };
43298     *
43299     * console.log(_.identity(object) === object);
43300     * // => true
43301     */
43302    function identity(value) {
43303      return value;
43304    }
43305
43306    /**
43307     * Creates a function that invokes `func` with the arguments of the created
43308     * function. If `func` is a property name, the created function returns the
43309     * property value for a given element. If `func` is an array or object, the
43310     * created function returns `true` for elements that contain the equivalent
43311     * source properties, otherwise it returns `false`.
43312     *
43313     * @static
43314     * @since 4.0.0
43315     * @memberOf _
43316     * @category Util
43317     * @param {*} [func=_.identity] The value to convert to a callback.
43318     * @returns {Function} Returns the callback.
43319     * @example
43320     *
43321     * var users = [
43322     *   { 'user': 'barney', 'age': 36, 'active': true },
43323     *   { 'user': 'fred',   'age': 40, 'active': false }
43324     * ];
43325     *
43326     * // The `_.matches` iteratee shorthand.
43327     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
43328     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
43329     *
43330     * // The `_.matchesProperty` iteratee shorthand.
43331     * _.filter(users, _.iteratee(['user', 'fred']));
43332     * // => [{ 'user': 'fred', 'age': 40 }]
43333     *
43334     * // The `_.property` iteratee shorthand.
43335     * _.map(users, _.iteratee('user'));
43336     * // => ['barney', 'fred']
43337     *
43338     * // Create custom iteratee shorthands.
43339     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
43340     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
43341     *     return func.test(string);
43342     *   };
43343     * });
43344     *
43345     * _.filter(['abc', 'def'], /ef/);
43346     * // => ['def']
43347     */
43348    function iteratee(func) {
43349      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
43350    }
43351
43352    /**
43353     * Creates a function that performs a partial deep comparison between a given
43354     * object and `source`, returning `true` if the given object has equivalent
43355     * property values, else `false`.
43356     *
43357     * **Note:** The created function is equivalent to `_.isMatch` with `source`
43358     * partially applied.
43359     *
43360     * Partial comparisons will match empty array and empty object `source`
43361     * values against any array or object value, respectively. See `_.isEqual`
43362     * for a list of supported value comparisons.
43363     *
43364     * **Note:** Multiple values can be checked by combining several matchers
43365     * using `_.overSome`
43366     *
43367     * @static
43368     * @memberOf _
43369     * @since 3.0.0
43370     * @category Util
43371     * @param {Object} source The object of property values to match.
43372     * @returns {Function} Returns the new spec function.
43373     * @example
43374     *
43375     * var objects = [
43376     *   { 'a': 1, 'b': 2, 'c': 3 },
43377     *   { 'a': 4, 'b': 5, 'c': 6 }
43378     * ];
43379     *
43380     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
43381     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
43382     *
43383     * // Checking for several possible values
43384     * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
43385     * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
43386     */
43387    function matches(source) {
43388      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
43389    }
43390
43391    /**
43392     * Creates a function that performs a partial deep comparison between the
43393     * value at `path` of a given object to `srcValue`, returning `true` if the
43394     * object value is equivalent, else `false`.
43395     *
43396     * **Note:** Partial comparisons will match empty array and empty object
43397     * `srcValue` values against any array or object value, respectively. See
43398     * `_.isEqual` for a list of supported value comparisons.
43399     *
43400     * **Note:** Multiple values can be checked by combining several matchers
43401     * using `_.overSome`
43402     *
43403     * @static
43404     * @memberOf _
43405     * @since 3.2.0
43406     * @category Util
43407     * @param {Array|string} path The path of the property to get.
43408     * @param {*} srcValue The value to match.
43409     * @returns {Function} Returns the new spec function.
43410     * @example
43411     *
43412     * var objects = [
43413     *   { 'a': 1, 'b': 2, 'c': 3 },
43414     *   { 'a': 4, 'b': 5, 'c': 6 }
43415     * ];
43416     *
43417     * _.find(objects, _.matchesProperty('a', 4));
43418     * // => { 'a': 4, 'b': 5, 'c': 6 }
43419     *
43420     * // Checking for several possible values
43421     * _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
43422     * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
43423     */
43424    function matchesProperty(path, srcValue) {
43425      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
43426    }
43427
43428    /**
43429     * Creates a function that invokes the method at `path` of a given object.
43430     * Any additional arguments are provided to the invoked method.
43431     *
43432     * @static
43433     * @memberOf _
43434     * @since 3.7.0
43435     * @category Util
43436     * @param {Array|string} path The path of the method to invoke.
43437     * @param {...*} [args] The arguments to invoke the method with.
43438     * @returns {Function} Returns the new invoker function.
43439     * @example
43440     *
43441     * var objects = [
43442     *   { 'a': { 'b': _.constant(2) } },
43443     *   { 'a': { 'b': _.constant(1) } }
43444     * ];
43445     *
43446     * _.map(objects, _.method('a.b'));
43447     * // => [2, 1]
43448     *
43449     * _.map(objects, _.method(['a', 'b']));
43450     * // => [2, 1]
43451     */
43452    var method = baseRest(function(path, args) {
43453      return function(object) {
43454        return baseInvoke(object, path, args);
43455      };
43456    });
43457
43458    /**
43459     * The opposite of `_.method`; this method creates a function that invokes
43460     * the method at a given path of `object`. Any additional arguments are
43461     * provided to the invoked method.
43462     *
43463     * @static
43464     * @memberOf _
43465     * @since 3.7.0
43466     * @category Util
43467     * @param {Object} object The object to query.
43468     * @param {...*} [args] The arguments to invoke the method with.
43469     * @returns {Function} Returns the new invoker function.
43470     * @example
43471     *
43472     * var array = _.times(3, _.constant),
43473     *     object = { 'a': array, 'b': array, 'c': array };
43474     *
43475     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
43476     * // => [2, 0]
43477     *
43478     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
43479     * // => [2, 0]
43480     */
43481    var methodOf = baseRest(function(object, args) {
43482      return function(path) {
43483        return baseInvoke(object, path, args);
43484      };
43485    });
43486
43487    /**
vendor: 10,734 bytes, lines 43488-43875
43488     * Adds all own enumerable string keyed function properties of a source
43489     * object to the destination object. If `object` is a function, then methods
43490     * are added to its prototype as well.
43491     *
43492     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
43493     * avoid conflicts caused by modifying the original.
43494     *
43495     * @static
43496     * @since 0.1.0
43497     * @memberOf _
43498     * @category Util
43499     * @param {Function|Object} [object=lodash] The destination object.
43500     * @param {Object} source The object of functions to add.
43501     * @param {Object} [options={}] The options object.
43502     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
43503     * @returns {Function|Object} Returns `object`.
43504     * @example
43505     *
43506     * function vowels(string) {
43507     *   return _.filter(string, function(v) {
43508     *     return /[aeiou]/i.test(v);
43509     *   });
43510     * }
43511     *
43512     * _.mixin({ 'vowels': vowels });
43513     * _.vowels('fred');
43514     * // => ['e']
43515     *
43516     * _('fred').vowels().value();
43517     * // => ['e']
43518     *
43519     * _.mixin({ 'vowels': vowels }, { 'chain': false });
43520     * _('fred').vowels();
43521     * // => ['e']
43522     */
43523    function mixin(object, source, options) {
43524      var props = keys(source),
43525          methodNames = baseFunctions(source, props);
43526
43527      if (options == null &&
43528          !(isObject(source) && (methodNames.length || !props.length))) {
43529        options = source;
43530        source = object;
43531        object = this;
43532        methodNames = baseFunctions(source, keys(source));
43533      }
43534      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
43535          isFunc = isFunction(object);
43536
43537      arrayEach(methodNames, function(methodName) {
43538        var func = source[methodName];
43539        object[methodName] = func;
43540        if (isFunc) {
43541          object.prototype[methodName] = function() {
43542            var chainAll = this.__chain__;
43543            if (chain || chainAll) {
43544              var result = object(this.__wrapped__),
43545                  actions = result.__actions__ = copyArray(this.__actions__);
43546
43547              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
43548              result.__chain__ = chainAll;
43549              return result;
43550            }
43551            return func.apply(object, arrayPush([this.value()], arguments));
43552          };
43553        }
43554      });
43555
43556      return object;
43557    }
43558
43559    /**
43560     * Reverts the `_` variable to its previous value and returns a reference to
43561     * the `lodash` function.
43562     *
43563     * @static
43564     * @since 0.1.0
43565     * @memberOf _
43566     * @category Util
43567     * @returns {Function} Returns the `lodash` function.
43568     * @example
43569     *
43570     * var lodash = _.noConflict();
43571     */
43572    function noConflict() {
43573      if (root._ === this) {
43574        root._ = oldDash;
43575      }
43576      return this;
43577    }
43578
43579    /**
43580     * This method returns `undefined`.
43581     *
43582     * @static
43583     * @memberOf _
43584     * @since 2.3.0
43585     * @category Util
43586     * @example
43587     *
43588     * _.times(2, _.noop);
43589     * // => [undefined, undefined]
43590     */
43591    function noop() {
43592      // No operation performed.
43593    }
43594
43595    /**
43596     * Creates a function that gets the argument at index `n`. If `n` is negative,
43597     * the nth argument from the end is returned.
43598     *
43599     * @static
43600     * @memberOf _
43601     * @since 4.0.0
43602     * @category Util
43603     * @param {number} [n=0] The index of the argument to return.
43604     * @returns {Function} Returns the new pass-thru function.
43605     * @example
43606     *
43607     * var func = _.nthArg(1);
43608     * func('a', 'b', 'c', 'd');
43609     * // => 'b'
43610     *
43611     * var func = _.nthArg(-2);
43612     * func('a', 'b', 'c', 'd');
43613     * // => 'c'
43614     */
43615    function nthArg(n) {
43616      n = toInteger(n);
43617      return baseRest(function(args) {
43618        return baseNth(args, n);
43619      });
43620    }
43621
43622    /**
43623     * Creates a function that invokes `iteratees` with the arguments it receives
43624     * and returns their results.
43625     *
43626     * @static
43627     * @memberOf _
43628     * @since 4.0.0
43629     * @category Util
43630     * @param {...(Function|Function[])} [iteratees=[_.identity]]
43631     *  The iteratees to invoke.
43632     * @returns {Function} Returns the new function.
43633     * @example
43634     *
43635     * var func = _.over([Math.max, Math.min]);
43636     *
43637     * func(1, 2, 3, 4);
43638     * // => [4, 1]
43639     */
43640    var over = createOver(arrayMap);
43641
43642    /**
43643     * Creates a function that checks if **all** of the `predicates` return
43644     * truthy when invoked with the arguments it receives.
43645     *
43646     * Following shorthands are possible for providing predicates.
43647     * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
43648     * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
43649     *
43650     * @static
43651     * @memberOf _
43652     * @since 4.0.0
43653     * @category Util
43654     * @param {...(Function|Function[])} [predicates=[_.identity]]
43655     *  The predicates to check.
43656     * @returns {Function} Returns the new function.
43657     * @example
43658     *
43659     * var func = _.overEvery([Boolean, isFinite]);
43660     *
43661     * func('1');
43662     * // => true
43663     *
43664     * func(null);
43665     * // => false
43666     *
43667     * func(NaN);
43668     * // => false
43669     */
43670    var overEvery = createOver(arrayEvery);
43671
43672    /**
43673     * Creates a function that checks if **any** of the `predicates` return
43674     * truthy when invoked with the arguments it receives.
43675     *
43676     * Following shorthands are possible for providing predicates.
43677     * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
43678     * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
43679     *
43680     * @static
43681     * @memberOf _
43682     * @since 4.0.0
43683     * @category Util
43684     * @param {...(Function|Function[])} [predicates=[_.identity]]
43685     *  The predicates to check.
43686     * @returns {Function} Returns the new function.
43687     * @example
43688     *
43689     * var func = _.overSome([Boolean, isFinite]);
43690     *
43691     * func('1');
43692     * // => true
43693     *
43694     * func(null);
43695     * // => true
43696     *
43697     * func(NaN);
43698     * // => false
43699     *
43700     * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
43701     * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
43702     */
43703    var overSome = createOver(arraySome);
43704
43705    /**
43706     * Creates a function that returns the value at `path` of a given object.
43707     *
43708     * @static
43709     * @memberOf _
43710     * @since 2.4.0
43711     * @category Util
43712     * @param {Array|string} path The path of the property to get.
43713     * @returns {Function} Returns the new accessor function.
43714     * @example
43715     *
43716     * var objects = [
43717     *   { 'a': { 'b': 2 } },
43718     *   { 'a': { 'b': 1 } }
43719     * ];
43720     *
43721     * _.map(objects, _.property('a.b'));
43722     * // => [2, 1]
43723     *
43724     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
43725     * // => [1, 2]
43726     */
43727    function property(path) {
43728      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
43729    }
43730
43731    /**
43732     * The opposite of `_.property`; this method creates a function that returns
43733     * the value at a given path of `object`.
43734     *
43735     * @static
43736     * @memberOf _
43737     * @since 3.0.0
43738     * @category Util
43739     * @param {Object} object The object to query.
43740     * @returns {Function} Returns the new accessor function.
43741     * @example
43742     *
43743     * var array = [0, 1, 2],
43744     *     object = { 'a': array, 'b': array, 'c': array };
43745     *
43746     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
43747     * // => [2, 0]
43748     *
43749     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
43750     * // => [2, 0]
43751     */
43752    function propertyOf(object) {
43753      return function(path) {
43754        return object == null ? undefined : baseGet(object, path);
43755      };
43756    }
43757
43758    /**
43759     * Creates an array of numbers (positive and/or negative) progressing from
43760     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
43761     * `start` is specified without an `end` or `step`. If `end` is not specified,
43762     * it's set to `start` with `start` then set to `0`.
43763     *
43764     * **Note:** JavaScript follows the IEEE-754 standard for resolving
43765     * floating-point values which can produce unexpected results.
43766     *
43767     * @static
43768     * @since 0.1.0
43769     * @memberOf _
43770     * @category Util
43771     * @param {number} [start=0] The start of the range.
43772     * @param {number} end The end of the range.
43773     * @param {number} [step=1] The value to increment or decrement by.
43774     * @returns {Array} Returns the range of numbers.
43775     * @see _.inRange, _.rangeRight
43776     * @example
43777     *
43778     * _.range(4);
43779     * // => [0, 1, 2, 3]
43780     *
43781     * _.range(-4);
43782     * // => [0, -1, -2, -3]
43783     *
43784     * _.range(1, 5);
43785     * // => [1, 2, 3, 4]
43786     *
43787     * _.range(0, 20, 5);
43788     * // => [0, 5, 10, 15]
43789     *
43790     * _.range(0, -4, -1);
43791     * // => [0, -1, -2, -3]
43792     *
43793     * _.range(1, 4, 0);
43794     * // => [1, 1, 1]
43795     *
43796     * _.range(0);
43797     * // => []
43798     */
43799    var range = createRange();
43800
43801    /**
43802     * This method is like `_.range` except that it populates values in
43803     * descending order.
43804     *
43805     * @static
43806     * @memberOf _
43807     * @since 4.0.0
43808     * @category Util
43809     * @param {number} [start=0] The start of the range.
43810     * @param {number} end The end of the range.
43811     * @param {number} [step=1] The value to increment or decrement by.
43812     * @returns {Array} Returns the range of numbers.
43813     * @see _.inRange, _.range
43814     * @example
43815     *
43816     * _.rangeRight(4);
43817     * // => [3, 2, 1, 0]
43818     *
43819     * _.rangeRight(-4);
43820     * // => [-3, -2, -1, 0]
43821     *
43822     * _.rangeRight(1, 5);
43823     * // => [4, 3, 2, 1]
43824     *
43825     * _.rangeRight(0, 20, 5);
43826     * // => [15, 10, 5, 0]
43827     *
43828     * _.rangeRight(0, -4, -1);
43829     * // => [-3, -2, -1, 0]
43830     *
43831     * _.rangeRight(1, 4, 0);
43832     * // => [1, 1, 1]
43833     *
43834     * _.rangeRight(0);
43835     * // => []
43836     */
43837    var rangeRight = createRange(true);
43838
43839    /**
43840     * This method returns a new empty array.
43841     *
43842     * @static
43843     * @memberOf _
43844     * @since 4.13.0
43845     * @category Util
43846     * @returns {Array} Returns the new empty array.
43847     * @example
43848     *
43849     * var arrays = _.times(2, _.stubArray);
43850     *
43851     * console.log(arrays);
43852     * // => [[], []]
43853     *
43854     * console.log(arrays[0] === arrays[1]);
43855     * // => false
43856     */
43857    function stubArray() {
43858      return [];
43859    }
43860
43861    /**
43862     * This method returns `false`.
43863     *
43864     * @static
43865     * @memberOf _
43866     * @since 4.13.0
43867     * @category Util
43868     * @returns {boolean} Returns `false`.
43869     * @example
43870     *
43871     * _.times(2, _.stubFalse);
43872     * // => [false, false]
43873     */
43874    function stubFalse() {
43875      return false;
vendor: 1,044 bytes, lines 43876-43929
43876    }
43877
43878    /**
43879     * This method returns a new empty object.
43880     *
43881     * @static
43882     * @memberOf _
43883     * @since 4.13.0
43884     * @category Util
43885     * @returns {Object} Returns the new empty object.
43886     * @example
43887     *
43888     * var objects = _.times(2, _.stubObject);
43889     *
43890     * console.log(objects);
43891     * // => [{}, {}]
43892     *
43893     * console.log(objects[0] === objects[1]);
43894     * // => false
43895     */
43896    function stubObject() {
43897      return {};
43898    }
43899
43900    /**
43901     * This method returns an empty string.
43902     *
43903     * @static
43904     * @memberOf _
43905     * @since 4.13.0
43906     * @category Util
43907     * @returns {string} Returns the empty string.
43908     * @example
43909     *
43910     * _.times(2, _.stubString);
43911     * // => ['', '']
43912     */
43913    function stubString() {
43914      return '';
43915    }
43916
43917    /**
43918     * This method returns `true`.
43919     *
43920     * @static
43921     * @memberOf _
43922     * @since 4.13.0
43923     * @category Util
43924     * @returns {boolean} Returns `true`.
43925     * @example
43926     *
43927     * _.times(2, _.stubTrue);
43928     * // => [true, true]
43929     */
vendor: 9,081 bytes, lines 43930-44273
43930    function stubTrue() {
43931      return true;
43932    }
43933
43934    /**
43935     * Invokes the iteratee `n` times, returning an array of the results of
43936     * each invocation. The iteratee is invoked with one argument; (index).
43937     *
43938     * @static
43939     * @since 0.1.0
43940     * @memberOf _
43941     * @category Util
43942     * @param {number} n The number of times to invoke `iteratee`.
43943     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
43944     * @returns {Array} Returns the array of results.
43945     * @example
43946     *
43947     * _.times(3, String);
43948     * // => ['0', '1', '2']
43949     *
43950     *  _.times(4, _.constant(0));
43951     * // => [0, 0, 0, 0]
43952     */
43953    function times(n, iteratee) {
43954      n = toInteger(n);
43955      if (n < 1 || n > MAX_SAFE_INTEGER) {
43956        return [];
43957      }
43958      var index = MAX_ARRAY_LENGTH,
43959          length = nativeMin(n, MAX_ARRAY_LENGTH);
43960
43961      iteratee = getIteratee(iteratee);
43962      n -= MAX_ARRAY_LENGTH;
43963
43964      var result = baseTimes(length, iteratee);
43965      while (++index < n) {
43966        iteratee(index);
43967      }
43968      return result;
43969    }
43970
43971    /**
43972     * Converts `value` to a property path array.
43973     *
43974     * @static
43975     * @memberOf _
43976     * @since 4.0.0
43977     * @category Util
43978     * @param {*} value The value to convert.
43979     * @returns {Array} Returns the new property path array.
43980     * @example
43981     *
43982     * _.toPath('a.b.c');
43983     * // => ['a', 'b', 'c']
43984     *
43985     * _.toPath('a[0].b.c');
43986     * // => ['a', '0', 'b', 'c']
43987     */
43988    function toPath(value) {
43989      if (isArray(value)) {
43990        return arrayMap(value, toKey);
43991      }
43992      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
43993    }
43994
43995    /**
43996     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
43997     *
43998     * @static
43999     * @since 0.1.0
44000     * @memberOf _
44001     * @category Util
44002     * @param {string} [prefix=''] The value to prefix the ID with.
44003     * @returns {string} Returns the unique ID.
44004     * @example
44005     *
44006     * _.uniqueId('contact_');
44007     * // => 'contact_104'
44008     *
44009     * _.uniqueId();
44010     * // => '105'
44011     */
44012    function uniqueId(prefix) {
44013      var id = ++idCounter;
44014      return toString(prefix) + id;
44015    }
44016
44017    /*------------------------------------------------------------------------*/
44018
44019    /**
44020     * Adds two numbers.
44021     *
44022     * @static
44023     * @memberOf _
44024     * @since 3.4.0
44025     * @category Math
44026     * @param {number} augend The first number in an addition.
44027     * @param {number} addend The second number in an addition.
44028     * @returns {number} Returns the total.
44029     * @example
44030     *
44031     * _.add(6, 4);
44032     * // => 10
44033     */
44034    var add = createMathOperation(function(augend, addend) {
44035      return augend + addend;
44036    }, 0);
44037
44038    /**
44039     * Computes `number` rounded up to `precision`.
44040     *
44041     * @static
44042     * @memberOf _
44043     * @since 3.10.0
44044     * @category Math
44045     * @param {number} number The number to round up.
44046     * @param {number} [precision=0] The precision to round up to.
44047     * @returns {number} Returns the rounded up number.
44048     * @example
44049     *
44050     * _.ceil(4.006);
44051     * // => 5
44052     *
44053     * _.ceil(6.004, 2);
44054     * // => 6.01
44055     *
44056     * _.ceil(6040, -2);
44057     * // => 6100
44058     */
44059    var ceil = createRound('ceil');
44060
44061    /**
44062     * Divide two numbers.
44063     *
44064     * @static
44065     * @memberOf _
44066     * @since 4.7.0
44067     * @category Math
44068     * @param {number} dividend The first number in a division.
44069     * @param {number} divisor The second number in a division.
44070     * @returns {number} Returns the quotient.
44071     * @example
44072     *
44073     * _.divide(6, 4);
44074     * // => 1.5
44075     */
44076    var divide = createMathOperation(function(dividend, divisor) {
44077      return dividend / divisor;
44078    }, 1);
44079
44080    /**
44081     * Computes `number` rounded down to `precision`.
44082     *
44083     * @static
44084     * @memberOf _
44085     * @since 3.10.0
44086     * @category Math
44087     * @param {number} number The number to round down.
44088     * @param {number} [precision=0] The precision to round down to.
44089     * @returns {number} Returns the rounded down number.
44090     * @example
44091     *
44092     * _.floor(4.006);
44093     * // => 4
44094     *
44095     * _.floor(0.046, 2);
44096     * // => 0.04
44097     *
44098     * _.floor(4060, -2);
44099     * // => 4000
44100     */
44101    var floor = createRound('floor');
44102
44103    /**
44104     * Computes the maximum value of `array`. If `array` is empty or falsey,
44105     * `undefined` is returned.
44106     *
44107     * @static
44108     * @since 0.1.0
44109     * @memberOf _
44110     * @category Math
44111     * @param {Array} array The array to iterate over.
44112     * @returns {*} Returns the maximum value.
44113     * @example
44114     *
44115     * _.max([4, 2, 8, 6]);
44116     * // => 8
44117     *
44118     * _.max([]);
44119     * // => undefined
44120     */
44121    function max(array) {
44122      return (array && array.length)
44123        ? baseExtremum(array, identity, baseGt)
44124        : undefined;
44125    }
44126
44127    /**
44128     * This method is like `_.max` except that it accepts `iteratee` which is
44129     * invoked for each element in `array` to generate the criterion by which
44130     * the value is ranked. The iteratee is invoked with one argument: (value).
44131     *
44132     * @static
44133     * @memberOf _
44134     * @since 4.0.0
44135     * @category Math
44136     * @param {Array} array The array to iterate over.
44137     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
44138     * @returns {*} Returns the maximum value.
44139     * @example
44140     *
44141     * var objects = [{ 'n': 1 }, { 'n': 2 }];
44142     *
44143     * _.maxBy(objects, function(o) { return o.n; });
44144     * // => { 'n': 2 }
44145     *
44146     * // The `_.property` iteratee shorthand.
44147     * _.maxBy(objects, 'n');
44148     * // => { 'n': 2 }
44149     */
44150    function maxBy(array, iteratee) {
44151      return (array && array.length)
44152        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
44153        : undefined;
44154    }
44155
44156    /**
44157     * Computes the mean of the values in `array`.
44158     *
44159     * @static
44160     * @memberOf _
44161     * @since 4.0.0
44162     * @category Math
44163     * @param {Array} array The array to iterate over.
44164     * @returns {number} Returns the mean.
44165     * @example
44166     *
44167     * _.mean([4, 2, 8, 6]);
44168     * // => 5
44169     */
44170    function mean(array) {
44171      return baseMean(array, identity);
44172    }
44173
44174    /**
44175     * This method is like `_.mean` except that it accepts `iteratee` which is
44176     * invoked for each element in `array` to generate the value to be averaged.
44177     * The iteratee is invoked with one argument: (value).
44178     *
44179     * @static
44180     * @memberOf _
44181     * @since 4.7.0
44182     * @category Math
44183     * @param {Array} array The array to iterate over.
44184     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
44185     * @returns {number} Returns the mean.
44186     * @example
44187     *
44188     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
44189     *
44190     * _.meanBy(objects, function(o) { return o.n; });
44191     * // => 5
44192     *
44193     * // The `_.property` iteratee shorthand.
44194     * _.meanBy(objects, 'n');
44195     * // => 5
44196     */
44197    function meanBy(array, iteratee) {
44198      return baseMean(array, getIteratee(iteratee, 2));
44199    }
44200
44201    /**
44202     * Computes the minimum value of `array`. If `array` is empty or falsey,
44203     * `undefined` is returned.
44204     *
44205     * @static
44206     * @since 0.1.0
44207     * @memberOf _
44208     * @category Math
44209     * @param {Array} array The array to iterate over.
44210     * @returns {*} Returns the minimum value.
44211     * @example
44212     *
44213     * _.min([4, 2, 8, 6]);
44214     * // => 2
44215     *
44216     * _.min([]);
44217     * // => undefined
44218     */
44219    function min(array) {
44220      return (array && array.length)
44221        ? baseExtremum(array, identity, baseLt)
44222        : undefined;
44223    }
44224
44225    /**
44226     * This method is like `_.min` except that it accepts `iteratee` which is
44227     * invoked for each element in `array` to generate the criterion by which
44228     * the value is ranked. The iteratee is invoked with one argument: (value).
44229     *
44230     * @static
44231     * @memberOf _
44232     * @since 4.0.0
44233     * @category Math
44234     * @param {Array} array The array to iterate over.
44235     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
44236     * @returns {*} Returns the minimum value.
44237     * @example
44238     *
44239     * var objects = [{ 'n': 1 }, { 'n': 2 }];
44240     *
44241     * _.minBy(objects, function(o) { return o.n; });
44242     * // => { 'n': 1 }
44243     *
44244     * // The `_.property` iteratee shorthand.
44245     * _.minBy(objects, 'n');
44246     * // => { 'n': 1 }
44247     */
44248    function minBy(array, iteratee) {
44249      return (array && array.length)
44250        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
44251        : undefined;
44252    }
44253
44254    /**
44255     * Multiply two numbers.
44256     *
44257     * @static
44258     * @memberOf _
44259     * @since 4.7.0
44260     * @category Math
44261     * @param {number} multiplier The first number in a multiplication.
44262     * @param {number} multiplicand The second number in a multiplication.
44263     * @returns {number} Returns the product.
44264     * @example
44265     *
44266     * _.multiply(6, 4);
44267     * // => 24
44268     */
44269    var multiply = createMathOperation(function(multiplier, multiplicand) {
44270      return multiplier * multiplicand;
44271    }, 1);
44272
44273    /**
vendor: 13,137 bytes, lines 44274-44712
44274     * Computes `number` rounded to `precision`.
44275     *
44276     * @static
44277     * @memberOf _
44278     * @since 3.10.0
44279     * @category Math
44280     * @param {number} number The number to round.
44281     * @param {number} [precision=0] The precision to round to.
44282     * @returns {number} Returns the rounded number.
44283     * @example
44284     *
44285     * _.round(4.006);
44286     * // => 4
44287     *
44288     * _.round(4.006, 2);
44289     * // => 4.01
44290     *
44291     * _.round(4060, -2);
44292     * // => 4100
44293     */
44294    var round = createRound('round');
44295
44296    /**
44297     * Subtract two numbers.
44298     *
44299     * @static
44300     * @memberOf _
44301     * @since 4.0.0
44302     * @category Math
44303     * @param {number} minuend The first number in a subtraction.
44304     * @param {number} subtrahend The second number in a subtraction.
44305     * @returns {number} Returns the difference.
44306     * @example
44307     *
44308     * _.subtract(6, 4);
44309     * // => 2
44310     */
44311    var subtract = createMathOperation(function(minuend, subtrahend) {
44312      return minuend - subtrahend;
44313    }, 0);
44314
44315    /**
44316     * Computes the sum of the values in `array`.
44317     *
44318     * @static
44319     * @memberOf _
44320     * @since 3.4.0
44321     * @category Math
44322     * @param {Array} array The array to iterate over.
44323     * @returns {number} Returns the sum.
44324     * @example
44325     *
44326     * _.sum([4, 2, 8, 6]);
44327     * // => 20
44328     */
44329    function sum(array) {
44330      return (array && array.length)
44331        ? baseSum(array, identity)
44332        : 0;
44333    }
44334
44335    /**
44336     * This method is like `_.sum` except that it accepts `iteratee` which is
44337     * invoked for each element in `array` to generate the value to be summed.
44338     * The iteratee is invoked with one argument: (value).
44339     *
44340     * @static
44341     * @memberOf _
44342     * @since 4.0.0
44343     * @category Math
44344     * @param {Array} array The array to iterate over.
44345     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
44346     * @returns {number} Returns the sum.
44347     * @example
44348     *
44349     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
44350     *
44351     * _.sumBy(objects, function(o) { return o.n; });
44352     * // => 20
44353     *
44354     * // The `_.property` iteratee shorthand.
44355     * _.sumBy(objects, 'n');
44356     * // => 20
44357     */
44358    function sumBy(array, iteratee) {
44359      return (array && array.length)
44360        ? baseSum(array, getIteratee(iteratee, 2))
44361        : 0;
44362    }
44363
44364    /*------------------------------------------------------------------------*/
44365
44366    // Add methods that return wrapped values in chain sequences.
44367    lodash.after = after;
44368    lodash.ary = ary;
44369    lodash.assign = assign;
44370    lodash.assignIn = assignIn;
44371    lodash.assignInWith = assignInWith;
44372    lodash.assignWith = assignWith;
44373    lodash.at = at;
44374    lodash.before = before;
44375    lodash.bind = bind;
44376    lodash.bindAll = bindAll;
44377    lodash.bindKey = bindKey;
44378    lodash.castArray = castArray;
44379    lodash.chain = chain;
44380    lodash.chunk = chunk;
44381    lodash.compact = compact;
44382    lodash.concat = concat;
44383    lodash.cond = cond;
44384    lodash.conforms = conforms;
44385    lodash.constant = constant;
44386    lodash.countBy = countBy;
44387    lodash.create = create;
44388    lodash.curry = curry;
44389    lodash.curryRight = curryRight;
44390    lodash.debounce = debounce;
44391    lodash.defaults = defaults;
44392    lodash.defaultsDeep = defaultsDeep;
44393    lodash.defer = defer;
44394    lodash.delay = delay;
44395    lodash.difference = difference;
44396    lodash.differenceBy = differenceBy;
44397    lodash.differenceWith = differenceWith;
44398    lodash.drop = drop;
44399    lodash.dropRight = dropRight;
44400    lodash.dropRightWhile = dropRightWhile;
44401    lodash.dropWhile = dropWhile;
44402    lodash.fill = fill;
44403    lodash.filter = filter;
44404    lodash.flatMap = flatMap;
44405    lodash.flatMapDeep = flatMapDeep;
44406    lodash.flatMapDepth = flatMapDepth;
44407    lodash.flatten = flatten;
44408    lodash.flattenDeep = flattenDeep;
44409    lodash.flattenDepth = flattenDepth;
44410    lodash.flip = flip;
44411    lodash.flow = flow;
44412    lodash.flowRight = flowRight;
44413    lodash.fromPairs = fromPairs;
44414    lodash.functions = functions;
44415    lodash.functionsIn = functionsIn;
44416    lodash.groupBy = groupBy;
44417    lodash.initial = initial;
44418    lodash.intersection = intersection;
44419    lodash.intersectionBy = intersectionBy;
44420    lodash.intersectionWith = intersectionWith;
44421    lodash.invert = invert;
44422    lodash.invertBy = invertBy;
44423    lodash.invokeMap = invokeMap;
44424    lodash.iteratee = iteratee;
44425    lodash.keyBy = keyBy;
44426    lodash.keys = keys;
44427    lodash.keysIn = keysIn;
44428    lodash.map = map;
44429    lodash.mapKeys = mapKeys;
44430    lodash.mapValues = mapValues;
44431    lodash.matches = matches;
44432    lodash.matchesProperty = matchesProperty;
44433    lodash.memoize = memoize;
44434    lodash.merge = merge;
44435    lodash.mergeWith = mergeWith;
44436    lodash.method = method;
44437    lodash.methodOf = methodOf;
44438    lodash.mixin = mixin;
44439    lodash.negate = negate;
44440    lodash.nthArg = nthArg;
44441    lodash.omit = omit;
44442    lodash.omitBy = omitBy;
44443    lodash.once = once;
44444    lodash.orderBy = orderBy;
44445    lodash.over = over;
44446    lodash.overArgs = overArgs;
44447    lodash.overEvery = overEvery;
44448    lodash.overSome = overSome;
44449    lodash.partial = partial;
44450    lodash.partialRight = partialRight;
44451    lodash.partition = partition;
44452    lodash.pick = pick;
44453    lodash.pickBy = pickBy;
44454    lodash.property = property;
44455    lodash.propertyOf = propertyOf;
44456    lodash.pull = pull;
44457    lodash.pullAll = pullAll;
44458    lodash.pullAllBy = pullAllBy;
44459    lodash.pullAllWith = pullAllWith;
44460    lodash.pullAt = pullAt;
44461    lodash.range = range;
44462    lodash.rangeRight = rangeRight;
44463    lodash.rearg = rearg;
44464    lodash.reject = reject;
44465    lodash.remove = remove;
44466    lodash.rest = rest;
44467    lodash.reverse = reverse;
44468    lodash.sampleSize = sampleSize;
44469    lodash.set = set;
44470    lodash.setWith = setWith;
44471    lodash.shuffle = shuffle;
44472    lodash.slice = slice;
44473    lodash.sortBy = sortBy;
44474    lodash.sortedUniq = sortedUniq;
44475    lodash.sortedUniqBy = sortedUniqBy;
44476    lodash.split = split;
44477    lodash.spread = spread;
44478    lodash.tail = tail;
44479    lodash.take = take;
44480    lodash.takeRight = takeRight;
44481    lodash.takeRightWhile = takeRightWhile;
44482    lodash.takeWhile = takeWhile;
44483    lodash.tap = tap;
44484    lodash.throttle = throttle;
44485    lodash.thru = thru;
44486    lodash.toArray = toArray;
44487    lodash.toPairs = toPairs;
44488    lodash.toPairsIn = toPairsIn;
44489    lodash.toPath = toPath;
44490    lodash.toPlainObject = toPlainObject;
44491    lodash.transform = transform;
44492    lodash.unary = unary;
44493    lodash.union = union;
44494    lodash.unionBy = unionBy;
44495    lodash.unionWith = unionWith;
44496    lodash.uniq = uniq;
44497    lodash.uniqBy = uniqBy;
44498    lodash.uniqWith = uniqWith;
44499    lodash.unset = unset;
44500    lodash.unzip = unzip;
44501    lodash.unzipWith = unzipWith;
44502    lodash.update = update;
44503    lodash.updateWith = updateWith;
44504    lodash.values = values;
44505    lodash.valuesIn = valuesIn;
44506    lodash.without = without;
44507    lodash.words = words;
44508    lodash.wrap = wrap;
44509    lodash.xor = xor;
44510    lodash.xorBy = xorBy;
44511    lodash.xorWith = xorWith;
44512    lodash.zip = zip;
44513    lodash.zipObject = zipObject;
44514    lodash.zipObjectDeep = zipObjectDeep;
44515    lodash.zipWith = zipWith;
44516
44517    // Add aliases.
44518    lodash.entries = toPairs;
44519    lodash.entriesIn = toPairsIn;
44520    lodash.extend = assignIn;
44521    lodash.extendWith = assignInWith;
44522
44523    // Add methods to `lodash.prototype`.
44524    mixin(lodash, lodash);
44525
44526    /*------------------------------------------------------------------------*/
44527
44528    // Add methods that return unwrapped values in chain sequences.
44529    lodash.add = add;
44530    lodash.attempt = attempt;
44531    lodash.camelCase = camelCase;
44532    lodash.capitalize = capitalize;
44533    lodash.ceil = ceil;
44534    lodash.clamp = clamp;
44535    lodash.clone = clone;
44536    lodash.cloneDeep = cloneDeep;
44537    lodash.cloneDeepWith = cloneDeepWith;
44538    lodash.cloneWith = cloneWith;
44539    lodash.conformsTo = conformsTo;
44540    lodash.deburr = deburr;
44541    lodash.defaultTo = defaultTo;
44542    lodash.divide = divide;
44543    lodash.endsWith = endsWith;
44544    lodash.eq = eq;
44545    lodash.escape = escape;
44546    lodash.escapeRegExp = escapeRegExp;
44547    lodash.every = every;
44548    lodash.find = find;
44549    lodash.findIndex = findIndex;
44550    lodash.findKey = findKey;
44551    lodash.findLast = findLast;
44552    lodash.findLastIndex = findLastIndex;
44553    lodash.findLastKey = findLastKey;
44554    lodash.floor = floor;
44555    lodash.forEach = forEach;
44556    lodash.forEachRight = forEachRight;
44557    lodash.forIn = forIn;
44558    lodash.forInRight = forInRight;
44559    lodash.forOwn = forOwn;
44560    lodash.forOwnRight = forOwnRight;
44561    lodash.get = get;
44562    lodash.gt = gt;
44563    lodash.gte = gte;
44564    lodash.has = has;
44565    lodash.hasIn = hasIn;
44566    lodash.head = head;
44567    lodash.identity = identity;
44568    lodash.includes = includes;
44569    lodash.indexOf = indexOf;
44570    lodash.inRange = inRange;
44571    lodash.invoke = invoke;
44572    lodash.isArguments = isArguments;
44573    lodash.isArray = isArray;
44574    lodash.isArrayBuffer = isArrayBuffer;
44575    lodash.isArrayLike = isArrayLike;
44576    lodash.isArrayLikeObject = isArrayLikeObject;
44577    lodash.isBoolean = isBoolean;
44578    lodash.isBuffer = isBuffer;
44579    lodash.isDate = isDate;
44580    lodash.isElement = isElement;
44581    lodash.isEmpty = isEmpty;
44582    lodash.isEqual = isEqual;
44583    lodash.isEqualWith = isEqualWith;
44584    lodash.isError = isError;
44585    lodash.isFinite = isFinite;
44586    lodash.isFunction = isFunction;
44587    lodash.isInteger = isInteger;
44588    lodash.isLength = isLength;
44589    lodash.isMap = isMap;
44590    lodash.isMatch = isMatch;
44591    lodash.isMatchWith = isMatchWith;
44592    lodash.isNaN = isNaN;
44593    lodash.isNative = isNative;
44594    lodash.isNil = isNil;
44595    lodash.isNull = isNull;
44596    lodash.isNumber = isNumber;
44597    lodash.isObject = isObject;
44598    lodash.isObjectLike = isObjectLike;
44599    lodash.isPlainObject = isPlainObject;
44600    lodash.isRegExp = isRegExp;
44601    lodash.isSafeInteger = isSafeInteger;
44602    lodash.isSet = isSet;
44603    lodash.isString = isString;
44604    lodash.isSymbol = isSymbol;
44605    lodash.isTypedArray = isTypedArray;
44606    lodash.isUndefined = isUndefined;
44607    lodash.isWeakMap = isWeakMap;
44608    lodash.isWeakSet = isWeakSet;
44609    lodash.join = join;
44610    lodash.kebabCase = kebabCase;
44611    lodash.last = last;
44612    lodash.lastIndexOf = lastIndexOf;
44613    lodash.lowerCase = lowerCase;
44614    lodash.lowerFirst = lowerFirst;
44615    lodash.lt = lt;
44616    lodash.lte = lte;
44617    lodash.max = max;
44618    lodash.maxBy = maxBy;
44619    lodash.mean = mean;
44620    lodash.meanBy = meanBy;
44621    lodash.min = min;
44622    lodash.minBy = minBy;
44623    lodash.stubArray = stubArray;
44624    lodash.stubFalse = stubFalse;
44625    lodash.stubObject = stubObject;
44626    lodash.stubString = stubString;
44627    lodash.stubTrue = stubTrue;
44628    lodash.multiply = multiply;
44629    lodash.nth = nth;
44630    lodash.noConflict = noConflict;
44631    lodash.noop = noop;
44632    lodash.now = now;
44633    lodash.pad = pad;
44634    lodash.padEnd = padEnd;
44635    lodash.padStart = padStart;
44636    lodash.parseInt = parseInt;
44637    lodash.random = random;
44638    lodash.reduce = reduce;
44639    lodash.reduceRight = reduceRight;
44640    lodash.repeat = repeat;
44641    lodash.replace = replace;
44642    lodash.result = result;
44643    lodash.round = round;
44644    lodash.runInContext = runInContext;
44645    lodash.sample = sample;
44646    lodash.size = size;
44647    lodash.snakeCase = snakeCase;
44648    lodash.some = some;
44649    lodash.sortedIndex = sortedIndex;
44650    lodash.sortedIndexBy = sortedIndexBy;
44651    lodash.sortedIndexOf = sortedIndexOf;
44652    lodash.sortedLastIndex = sortedLastIndex;
44653    lodash.sortedLastIndexBy = sortedLastIndexBy;
44654    lodash.sortedLastIndexOf = sortedLastIndexOf;
44655    lodash.startCase = startCase;
44656    lodash.startsWith = startsWith;
44657    lodash.subtract = subtract;
44658    lodash.sum = sum;
44659    lodash.sumBy = sumBy;
44660    lodash.template = template;
44661    lodash.times = times;
44662    lodash.toFinite = toFinite;
44663    lodash.toInteger = toInteger;
44664    lodash.toLength = toLength;
44665    lodash.toLower = toLower;
44666    lodash.toNumber = toNumber;
44667    lodash.toSafeInteger = toSafeInteger;
44668    lodash.toString = toString;
44669    lodash.toUpper = toUpper;
44670    lodash.trim = trim;
44671    lodash.trimEnd = trimEnd;
44672    lodash.trimStart = trimStart;
44673    lodash.truncate = truncate;
44674    lodash.unescape = unescape;
44675    lodash.uniqueId = uniqueId;
44676    lodash.upperCase = upperCase;
44677    lodash.upperFirst = upperFirst;
44678
44679    // Add aliases.
44680    lodash.each = forEach;
44681    lodash.eachRight = forEachRight;
44682    lodash.first = head;
44683
44684    mixin(lodash, (function() {
44685      var source = {};
44686      baseForOwn(lodash, function(func, methodName) {
44687        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
44688          source[methodName] = func;
44689        }
44690      });
44691      return source;
44692    }()), { 'chain': false });
44693
44694    /*------------------------------------------------------------------------*/
44695
44696    /**
44697     * The semantic version number.
44698     *
44699     * @static
44700     * @memberOf _
44701     * @type {string}
44702     */
44703    lodash.VERSION = VERSION;
44704
44705    // Assign default placeholders.
44706    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
44707      lodash[methodName].placeholder = lodash;
44708    });
44709
44710    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
44711    arrayEach(['drop', 'take'], function(methodName, index) {
44712      LazyWrapper.prototype[methodName] = function(n) {
vendor: 7,434 bytes, lines 44713-44930
44713        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
44714
44715        var result = (this.__filtered__ && !index)
44716          ? new LazyWrapper(this)
44717          : this.clone();
44718
44719        if (result.__filtered__) {
44720          result.__takeCount__ = nativeMin(n, result.__takeCount__);
44721        } else {
44722          result.__views__.push({
44723            'size': nativeMin(n, MAX_ARRAY_LENGTH),
44724            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
44725          });
44726        }
44727        return result;
44728      };
44729
44730      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
44731        return this.reverse()[methodName](n).reverse();
44732      };
44733    });
44734
44735    // Add `LazyWrapper` methods that accept an `iteratee` value.
44736    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
44737      var type = index + 1,
44738          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
44739
44740      LazyWrapper.prototype[methodName] = function(iteratee) {
44741        var result = this.clone();
44742        result.__iteratees__.push({
44743          'iteratee': getIteratee(iteratee, 3),
44744          'type': type
44745        });
44746        result.__filtered__ = result.__filtered__ || isFilter;
44747        return result;
44748      };
44749    });
44750
44751    // Add `LazyWrapper` methods for `_.head` and `_.last`.
44752    arrayEach(['head', 'last'], function(methodName, index) {
44753      var takeName = 'take' + (index ? 'Right' : '');
44754
44755      LazyWrapper.prototype[methodName] = function() {
44756        return this[takeName](1).value()[0];
44757      };
44758    });
44759
44760    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
44761    arrayEach(['initial', 'tail'], function(methodName, index) {
44762      var dropName = 'drop' + (index ? '' : 'Right');
44763
44764      LazyWrapper.prototype[methodName] = function() {
44765        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
44766      };
44767    });
44768
44769    LazyWrapper.prototype.compact = function() {
44770      return this.filter(identity);
44771    };
44772
44773    LazyWrapper.prototype.find = function(predicate) {
44774      return this.filter(predicate).head();
44775    };
44776
44777    LazyWrapper.prototype.findLast = function(predicate) {
44778      return this.reverse().find(predicate);
44779    };
44780
44781    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
44782      if (typeof path == 'function') {
44783        return new LazyWrapper(this);
44784      }
44785      return this.map(function(value) {
44786        return baseInvoke(value, path, args);
44787      });
44788    });
44789
44790    LazyWrapper.prototype.reject = function(predicate) {
44791      return this.filter(negate(getIteratee(predicate)));
44792    };
44793
44794    LazyWrapper.prototype.slice = function(start, end) {
44795      start = toInteger(start);
44796
44797      var result = this;
44798      if (result.__filtered__ && (start > 0 || end < 0)) {
44799        return new LazyWrapper(result);
44800      }
44801      if (start < 0) {
44802        result = result.takeRight(-start);
44803      } else if (start) {
44804        result = result.drop(start);
44805      }
44806      if (end !== undefined) {
44807        end = toInteger(end);
44808        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
44809      }
44810      return result;
44811    };
44812
44813    LazyWrapper.prototype.takeRightWhile = function(predicate) {
44814      return this.reverse().takeWhile(predicate).reverse();
44815    };
44816
44817    LazyWrapper.prototype.toArray = function() {
44818      return this.take(MAX_ARRAY_LENGTH);
44819    };
44820
44821    // Add `LazyWrapper` methods to `lodash.prototype`.
44822    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
44823      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
44824          isTaker = /^(?:head|last)$/.test(methodName),
44825          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
44826          retUnwrapped = isTaker || /^find/.test(methodName);
44827
44828      if (!lodashFunc) {
44829        return;
44830      }
44831      lodash.prototype[methodName] = function() {
44832        var value = this.__wrapped__,
44833            args = isTaker ? [1] : arguments,
44834            isLazy = value instanceof LazyWrapper,
44835            iteratee = args[0],
44836            useLazy = isLazy || isArray(value);
44837
44838        var interceptor = function(value) {
44839          var result = lodashFunc.apply(lodash, arrayPush([value], args));
44840          return (isTaker && chainAll) ? result[0] : result;
44841        };
44842
44843        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
44844          // Avoid lazy use if the iteratee has a "length" value other than `1`.
44845          isLazy = useLazy = false;
44846        }
44847        var chainAll = this.__chain__,
44848            isHybrid = !!this.__actions__.length,
44849            isUnwrapped = retUnwrapped && !chainAll,
44850            onlyLazy = isLazy && !isHybrid;
44851
44852        if (!retUnwrapped && useLazy) {
44853          value = onlyLazy ? value : new LazyWrapper(this);
44854          var result = func.apply(value, args);
44855          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
44856          return new LodashWrapper(result, chainAll);
44857        }
44858        if (isUnwrapped && onlyLazy) {
44859          return func.apply(this, args);
44860        }
44861        result = this.thru(interceptor);
44862        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
44863      };
44864    });
44865
44866    // Add `Array` methods to `lodash.prototype`.
44867    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
44868      var func = arrayProto[methodName],
44869          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
44870          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
44871
44872      lodash.prototype[methodName] = function() {
44873        var args = arguments;
44874        if (retUnwrapped && !this.__chain__) {
44875          var value = this.value();
44876          return func.apply(isArray(value) ? value : [], args);
44877        }
44878        return this[chainName](function(value) {
44879          return func.apply(isArray(value) ? value : [], args);
44880        });
44881      };
44882    });
44883
44884    // Map minified method names to their real names.
44885    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
44886      var lodashFunc = lodash[methodName];
44887      if (lodashFunc) {
44888        var key = lodashFunc.name + '';
44889        if (!hasOwnProperty.call(realNames, key)) {
44890          realNames[key] = [];
44891        }
44892        realNames[key].push({ 'name': methodName, 'func': lodashFunc });
44893      }
44894    });
44895
44896    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
44897      'name': 'wrapper',
44898      'func': undefined
44899    }];
44900
44901    // Add methods to `LazyWrapper`.
44902    LazyWrapper.prototype.clone = lazyClone;
44903    LazyWrapper.prototype.reverse = lazyReverse;
44904    LazyWrapper.prototype.value = lazyValue;
44905
44906    // Add chain sequence methods to the `lodash` wrapper.
44907    lodash.prototype.at = wrapperAt;
44908    lodash.prototype.chain = wrapperChain;
44909    lodash.prototype.commit = wrapperCommit;
44910    lodash.prototype.next = wrapperNext;
44911    lodash.prototype.plant = wrapperPlant;
44912    lodash.prototype.reverse = wrapperReverse;
44913    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
44914
44915    // Add lazy aliases.
44916    lodash.prototype.first = lodash.prototype.head;
44917
44918    if (symIterator) {
44919      lodash.prototype[symIterator] = wrapperToIterator;
44920    }
44921    return lodash;
44922  });
44923
44924  /*--------------------------------------------------------------------------*/
44925
44926  // Export lodash.
44927  var _ = runInContext();
44928
44929  // Some AMD build optimizers, like r.js, check for condition patterns like:
44930  if (t
vendor: 4,621 bytes, lines 44930-45104
44930ypeof define == 'function' && typeof define.amd == 'object' && define.amd) {
44931    // Expose Lodash on the global object to prevent errors when Lodash is
44932    // loaded by a script tag in the presence of an AMD loader.
44933    // See http://requirejs.org/docs/errors.html#mismatch for more details.
44934    // Use `_.noConflict` to remove Lodash from the global object.
44935    root._ = _;
44936
44937    // Define as an anonymous module so, through path mapping, it can be
44938    // referenced as the "underscore" module.
44939    define(function() {
44940      return _;
44941    });
44942  }
44943  // Check for `exports` after `define` in case a build optimizer adds it.
44944  else if (freeModule) {
44945    // Export for Node.js.
44946    (freeModule.exports = _)._ = _;
44947    // Export for CommonJS support.
44948    freeExports._ = _;
44949  }
44950  else {
44951    // Export to the global object.
44952    root._ = _;
44953  }
44954}.call(this));
44955
44956/**
44957* jquery-match-height 0.7.2 by @liabru
44958* http://brm.io/jquery-match-height/
44959* License: MIT
44960*/
44961
44962;(function(factory) { // eslint-disable-line no-extra-semi
44963    'use strict';
44964    if (typeof define === 'function' && define.amd) {
44965        // AMD
44966        define(['jquery'], factory);
44967    } else if (typeof module !== 'undefined' && module.exports) {
44968        // CommonJS
44969        module.exports = factory(require('jquery'));
44970    } else {
44971        // Global
44972        factory(jQuery);
44973    }
44974})(function($) {
44975    /*
44976    *  internal
44977    */
44978
44979    var _previousResizeWidth = -1,
44980        _updateTimeout = -1;
44981
44982    /*
44983    *  _parse
44984    *  value parse utility function
44985    */
44986
44987    var _parse = function(value) {
44988        // parse value and convert NaN to 0
44989        return parseFloat(value) || 0;
44990    };
44991
44992    /*
44993    *  _rows
44994    *  utility function returns array of jQuery selections representing each row
44995    *  (as displayed after float wrapping applied by browser)
44996    */
44997
44998    var _rows = function(elements) {
44999        var tolerance = 1,
45000            $elements = $(elements),
45001            lastTop = null,
45002            rows = [];
45003
45004        // group elements by their top position
45005        $elements.each(function(){
45006            var $that = $(this),
45007                top = $that.offset().top - _parse($that.css('margin-top')),
45008                lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
45009
45010            if (lastRow === null) {
45011                // first item on the row, so just push it
45012                rows.push($that);
45013            } else {
45014                // if the row top is the same, add to the row group
45015                if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
45016                    rows[rows.length - 1] = lastRow.add($that);
45017                } else {
45018                    // otherwise start a new row group
45019                    rows.push($that);
45020                }
45021            }
45022
45023            // keep track of the last row top
45024            lastTop = top;
45025        });
45026
45027        return rows;
45028    };
45029
45030    /*
45031    *  _parseOptions
45032    *  handle plugin options
45033    */
45034
45035    var _parseOptions = function(options) {
45036        var opts = {
45037            byRow: true,
45038            property: 'height',
45039            target: null,
45040            remove: false
45041        };
45042
45043        if (typeof options === 'object') {
45044            return $.extend(opts, options);
45045        }
45046
45047        if (typeof options === 'boolean') {
45048            opts.byRow = options;
45049        } else if (options === 'remove') {
45050            opts.remove = true;
45051        }
45052
45053        return opts;
45054    };
45055
45056    /*
45057    *  matchHeight
45058    *  plugin definition
45059    */
45060
45061    var matchHeight = $.fn.matchHeight = function(options) {
45062        var opts = _parseOptions(options);
45063
45064        // handle remove
45065        if (opts.remove) {
45066            var that = this;
45067
45068            // remove fixed height from all selected elements
45069            this.css(opts.property, '');
45070
45071            // remove selected elements from all groups
45072            $.each(matchHeight._groups, function(key, group) {
45073                group.elements = group.elements.not(that);
45074            });
45075
45076            // TODO: cleanup empty groups
45077
45078            return this;
45079        }
45080
45081        if (this.length <= 1 && !opts.target) {
45082            return this;
45083        }
45084
45085        // keep track of this group so we can re-apply later on load and resize events
45086        matchHeight._groups.push({
45087            elements: this,
45088            options: opts
45089        });
45090
45091        // match each element's height to the tallest element in the selection
45092        matchHeight._apply(this, opts);
45093
45094        return this;
45095    };
45096
45097    /*
45098    *  plugin global options
45099    */
45100
45101    matchHeight.version = '0.7.2';
45102    matchHeight._groups = [];
45103    matchHeight._throttle = 80;
45104    matchHeight._maintainScroll = false;
45105    matchHeight._beforeUpdate = null;
45106    matchHeight._afterUpdate = null;
45107    matchHeight._rows = _rows;
45108    matchHeight._parse = _parse;
45109    matchHeight._parseOptions = _parseOptions;
45110
45111    /*
45112    *  matchHeight._apply
45113    *  apply matchHeight to given elements
45114    */
45115
45116    matchHeight._apply = function(elements, options) {
45117        var opts = _parseOptions(options),
45118            $elements = $(elements),
45119            rows = [$elements];
45120
45121        // take note of scroll position
45122        var scrollTop = $(window).scrollTop(),
45123            htmlHeight = $('html').outerHeight(true);
45124
45125        // get hidden parents
45126        var $hiddenParents = $elements.parents().filter(':hidden');
45127
45128        // cache the original inline style
45129        $hiddenParents.each(function() {
45130            var $that = $(this);
45131            $that.data('style-cache', $that.attr('style'));
45132        });
45133
45134        // temporarily must force hidden parents visible
45135        $hiddenParents.css('display', 'block');
45136
45137        // get rows if using byRow, otherwise assume one row
45138        if (opts.byRow && !opts.target) {
45139
45140            // must first force an arbitrary equal height so floating elements break evenly
45141            $elements.each(function() {
45142                var $that = $(this),
45143                    display = $that.css('display');
45144
45145                // temporarily force a usable display value
45146                if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
45147                    display = 'block';
45148                }
45149
45150                // cache the original inline style
45151                $that.data('style-cache', $that.attr('style'));
45152
45153                $that.css({
45154                    'display': display,
45155                    'padding-top': '0',
45156                    'padding-bottom': '0',
45157                    'margin-top': '0',
45158                    'margin-bottom': '0',
45159                    'border-top-width': '0',
45160                    'border-bottom-width': '0',
45161                    'height': '100px',
45162                    'overflow': 'hidden'
45163                });
45164            });
45165
45166            // get the array of rows (based on element top position)
45167            rows = _rows($elements);
45168
45169            // revert original inline styles
45170            $elements.each(function() {
45171                var $that = $(this);
45172                $that.attr('style', $that.data('style-cache') || '');
45173            });
45174        }
45175
45176        $.each(rows, function(key, row) {
45177            var $row = $(row),
45178                targetHeight = 0;
45179
45180            if (!opts.target) {
45181                // skip apply to rows with only one item
45182                if (opts.byRow && $row.length <= 1) {
45183                    $row.css(opts.property, '');
45184                    return;
45185                }
45186
45187                // iterate the row and find the max height
45188                $row.each(function(){
45189                    var $that = $(this),
45190                        style = $that.attr('style'),
45191                        display = $that.css('display');
45192
45193                    // temporarily force a usable display value
45194                    if (display !== 'inline-block' && display !== 'flex' && display !== 'inline-flex') {
45195                        display = 'block';
45196                    }
45197
45198                    // ensure we get the correct actual height (and not a previously set height value)
45199                    var css = { 'display': display };
45200                    css[opts.property] = '';
45201                    $that.css(css);
45202
45203                    // find the max height (including padding, but not margin)
45204                    if ($that.outerHeight(false) > targetHeight) {
45205                        targetHeight = $that.outerHeight(false);
45206                    }
45207
45208                    // revert styles
45209                    if (style) {
45210                        $that.attr('style', style);
45211                    } else {
45212                        $that.css('display', '');
45213                    }
45214                });
45215            } else {
45216                // if target set, use the height of the target element
45217                targetHeight = opts.target.outerHeight(false);
45218            }
45219
45220            // iterate the row and apply the height to all elements
45221            $row.each(function(){
45222                var $that = $(this),
45223                    verticalPadding = 0;
45224
45225                // don't apply to a target
45226                if (opts.target && $that.is(opts.target)) {
45227                    return;
45228                }
45229
45230                // handle padding and border correctly (required when not using border-box)
45231                if ($that.css('box-sizing') !== 'border-box') {
45232                    verticalPadding += _parse($that.css('border-top-width')) + _parse($that.css('border-bottom-width'));
45233                    verticalPadding += _parse($that.css('padding-top')) + _parse($that.css('padding-bottom'));
45234                }
45235
45236                // set the height (accounting for padding and border)
45237                $that.css(opts.property, (targetHeight - verticalPadding) + 'px');
45238            });
45239        });
45240
45241        // revert hidden parents
45242        $hiddenParents.each(function() {
45243            var $that = $(this);
45244            $that.attr('style', $that.data('style-cache') || null);
45245        });
45246
45247        // restore scroll position if enabled
45248        if (matchHeight._maintainScroll) {
45249            $(window).scrollTop((scrollTop / htmlHeight) * $('html').outerHeight(true));
45250        }
45251
45252        return this;
45253    };
45254
45255    /*
45256    *  matchHeight._applyDataApi
45257    *  applies matchHeight to all elements with a data-match-height attribute
45258    */
45259
45260    matchHeight._applyDataApi = function() {
45261        var groups = {};
45262
45263        // generate groups by their groupId set by elements using data-match-height
45264        $('[data-match-height], [data-mh]').each(function() {
45265            var $this = $(this),
45266                groupId = $this.attr('data-mh') || $this.attr('data-match-height');
45267
45268            if (groupId in groups) {
45269                groups[groupId] = groups[groupId].add($this);
45270            } else {
45271                groups[groupId] = $this;
45272            }
45273        });
45274
45275        // apply matchHeight to each group
45276        $.each(groups, function() {
45277            this.matchHeight(true);
45278        });
45279    };
45280
45281    /*
45282    *  matchHeight._update
45283    *  updates matchHeight on all current groups with their correct options
45284    */
45285
45286    var _update = function(event) {
45287        if (matchHeight._beforeUpdate) {
45288            matchHeight._beforeUpdate(event, matchHeight._groups);
45289        }
45290
45291        $.each(matchHeight._groups, function() {
45292            matchHeight._apply(this.elements, this.options);
45293        });
45294
45295        if (matchHeight._afterUpdate) {
45296            matchHeight._afterUpdate(event, matchHeight._groups);
45297        }
45298    };
45299
45300    matchHeight._update = function(throttle, event) {
45301        // prevent update if fired from a resize event
45302        // where the viewport width hasn't actually changed
45303        // fixes an event looping bug in IE8
45304        if (event && event.type === 'resize') {
45305            var windowWidth = $(window).width();
45306            if (windowWidth === _previousResizeWidth) {
45307                return;
45308            }
45309            _previousResizeWidth = windowWidth;
45310        }
45311
45312        // throttle updates
45313        if (!throttle) {
45314            _update(event);
45315        } else if (_updateTimeout === -1) {
45316            _updateTimeout = setTimeout(function() {
45317                _update(event);
45318                _updateTimeout = -1;
45319            }, matchHeight._throttle);
45320        }
45321    };
45322
45323    /*
45324    *  bind events
45325    */
45326
45327    // apply on DOM ready event
45328    $(matchHeight._applyDataApi);
45329
45330    // use on or bind where supported
45331    var on = $.fn.on ? 'on' : 'bind';
45332
45333    // update heights on load and resize events
45334    $(window)[on]('load', function(event) {
45335        matchHeight._update(false, event);
45336    });
45337
45338    // throttled update heights on resize events
45339    $(window)[on]('resize orientationchange', function(event) {
45340        matchHeight._update(true, event);
45341    });
45342
45343});
45344
45345/*!
45346 * jQuery Cookie Plugin v1.4.1
45347 * https://github.com/carhartl/jquery-cookie
45348 *
45349 * Copyright 2013 Klaus Hartl
45350 * Released under the MIT license
45351 */
45352(function (factory) {
45353	if (typeof define === 'function' && define.amd) {
45354		// AMD
45355		define(['jquery'], factory);
45356	} else if (typeof exports === 'object') {
45357		// CommonJS
45358		factory(require('jquery'));
45359	} else {
45360		// Browser globals
45361		factory(jQuery);
45362	}
45363}(function ($) {
45364
45365	var pluses = /\+/g;
45366
45367	function encode(s) {
45368		return config.raw ? s : encodeURIComponent(s);
45369	}
45370
45371	function decode(s) {
45372		return config.raw ? s : decodeURIComponent(s);
45373	}
45374
45375	function stringifyCookieValue(value) {
45376		return encode(config.json ? JSON.stringify(value) : String(value));
45377	}
45378
45379	function parseCookieValue(s) {
45380		if (s.indexOf('"') === 0) {
45381			// This is a quoted cookie as according to RFC2068, unescape...
45382			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
45383		}
45384
45385		try {
45386			// Replace server-side written pluses with spaces.
45387			// If we can't decode the cookie, ignore it, it's unusable.
45388			// If we can't parse the cookie, ignore it, it's unusable.
45389			s = decodeURIComponent(s.replace(pluses, ' '));
45390			return config.json ? JSON.parse(s) : s;
45391		} catch(e) {}
45392	}
45393
45394	function read(s, converter) {
45395		var value = config.raw ? s : parseCookieValue(s);
45396		return $.isFunction(converter) ? converter(value) : value;
45397	}
45398
45399	var config = $.cookie = function (key, value, options) {
45400
45401		// Write
45402
45403		if (value !== undefined && !$.isFunction(value)) {
45404			options = $.extend({}, config.defaults, options);
45405
45406			if (typeof options.expires === 'number') {
45407				var days = options.expires, t = options.expires = new Date();
45408				t.setTime(+t + days * 864e+5);
45409			}
45410
45411			return (document.cookie = [
45412				encode(key), '=', stringifyCookieValue(value),
45413				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
45414				options.path    ? '; path=' + options.path : '',
45415				options.domain  ? '; domain=' + options.domain : '',
45416				options.secure  ? '; secure' : ''
45417			].join(''));
45418		}
45419
45420		// Read
45421
45422		var result = key ? undefined : {};
45423
45424		// To prevent the for loop in the first place assign an empty array
45425		// in case there are no cookies at all. Also prevents odd result when
45426		// calling $.cookie().
45427		var cookies = document.cookie ? document.cookie.split('; ') : [];
45428
45429		for (var i = 0, l = cookies.length; i < l; i++) {
45430			var parts = cookies[i].split('=');
45431			var name = decode(parts.shift());
45432			var cookie = parts.join('=');
45433
45434			if (key && key === name) {
45435				// If second argument (value) is a function it's a converter...
45436				result = read(cookie, value);
45437				break;
45438			}
45439
45440			// Prevent storing a cookie that we couldn't decode.
45441			if (!key && (cookie = read(cookie)) !== undefined) {
45442				result[name] = cookie;
45443			}
45444		}
45445
45446		return result;
45447	};
45448
45449	config.defaults = {};
45450
45451	$.removeCookie = function (key, options) {
45452		if ($.cookie(key) === undefined) {
45453			return false;
45454		}
45455
45456		// Must not alter options, thus extending a fresh object...
45457		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
45458		return !$.cookie(key);
45459	};
45460
45461}));
45462
vendor: 94,987 bytes, lines 45463-47934
45463/*!
45464* Parsley.js
45465* Version 2.9.2 - built Tue, Dec 10th 2019, 6:18 pm
45466* http://parsleyjs.org
45467* Guillaume Potier - <[email protected]>
45468* Marc-Andre Lafortune - <[email protected]>
45469* MIT Licensed
45470*/
45471
45472// The source code below is generated by babel as
45473// Parsley is written in ECMAScript 6
45474//
45475
45476(function (global, factory) {
45477  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
45478  typeof define === 'function' && define.amd ? define(['jquery'], factory) :
45479  (global = global || self, global.parsley = factory(global.jQuery));
45480}(this, (function ($) { 'use strict';
45481
45482  function _typeof(obj) {
45483    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
45484      _typeof = function (obj) {
45485        return typeof obj;
45486      };
45487    } else {
45488      _typeof = function (obj) {
45489        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
45490      };
45491    }
45492
45493    return _typeof(obj);
45494  }
45495
45496  function _extends() {
45497    _extends = Object.assign || function (target) {
45498      for (var i = 1; i < arguments.length; i++) {
45499        var source = arguments[i];
45500
45501        for (var key in source) {
45502          if (Object.prototype.hasOwnProperty.call(source, key)) {
45503            target[key] = source[key];
45504          }
45505        }
45506      }
45507
45508      return target;
45509    };
45510
45511    return _extends.apply(this, arguments);
45512  }
45513
45514  function _slicedToArray(arr, i) {
45515    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
45516  }
45517
45518  function _toConsumableArray(arr) {
45519    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
45520  }
45521
45522  function _arrayWithoutHoles(arr) {
45523    if (Array.isArray(arr)) {
45524      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
45525
45526      return arr2;
45527    }
45528  }
45529
45530  function _arrayWithHoles(arr) {
45531    if (Array.isArray(arr)) return arr;
45532  }
45533
45534  function _iterableToArray(iter) {
45535    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
45536  }
45537
45538  function _iterableToArrayLimit(arr, i) {
45539    if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
45540      return;
45541    }
45542
45543    var _arr = [];
45544    var _n = true;
45545    var _d = false;
45546    var _e = undefined;
45547
45548    try {
45549      for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
45550        _arr.push(_s.value);
45551
45552        if (i && _arr.length === i) break;
45553      }
45554    } catch (err) {
45555      _d = true;
45556      _e = err;
45557    } finally {
45558      try {
45559        if (!_n && _i["return"] != null) _i["return"]();
45560      } finally {
45561        if (_d) throw _e;
45562      }
45563    }
45564
45565    return _arr;
45566  }
45567
45568  function _nonIterableSpread() {
45569    throw new TypeError("Invalid attempt to spread non-iterable instance");
45570  }
45571
45572  function _nonIterableRest() {
45573    throw new TypeError("Invalid attempt to destructure non-iterable instance");
45574  }
45575
45576  var globalID = 1;
45577  var pastWarnings = {};
45578  var Utils = {
45579    // Parsley DOM-API
45580    // returns object from dom attributes and values
45581    attr: function attr(element, namespace, obj) {
45582      var i;
45583      var attribute;
45584      var attributes;
45585      var regex = new RegExp('^' + namespace, 'i');
45586      if ('undefined' === typeof obj) obj = {};else {
45587        // Clear all own properties. This won't affect prototype's values
45588        for (i in obj) {
45589          if (obj.hasOwnProperty(i)) delete obj[i];
45590        }
45591      }
45592      if (!element) return obj;
45593      attributes = element.attributes;
45594
45595      for (i = attributes.length; i--;) {
45596        attribute = attributes[i];
45597
45598        if (attribute && attribute.specified && regex.test(attribute.name)) {
45599          obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
45600        }
45601      }
45602
45603      return obj;
45604    },
45605    checkAttr: function checkAttr(element, namespace, _checkAttr) {
45606      return element.hasAttribute(namespace + _checkAttr);
45607    },
45608    setAttr: function setAttr(element, namespace, attr, value) {
45609      element.setAttribute(this.dasherize(namespace + attr), String(value));
45610    },
45611    getType: function getType(element) {
45612      return element.getAttribute('type') || 'text';
45613    },
45614    generateID: function generateID() {
45615      return '' + globalID++;
45616    },
45617
45618    /** Third party functions **/
45619    deserializeValue: function deserializeValue(value) {
45620      var num;
45621
45622      try {
45623        return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value;
45624      } catch (e) {
45625        return value;
45626      }
45627    },
45628    // Zepto camelize function
45629    camelize: function camelize(str) {
45630      return str.replace(/-+(.)?/g, function (match, chr) {
45631        return chr ? chr.toUpperCase() : '';
45632      });
45633    },
45634    // Zepto dasherize function
45635    dasherize: function dasherize(str) {
45636      return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
45637    },
45638    warn: function warn() {
45639      var _window$console;
45640
45641      if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
45642    },
45643    warnOnce: function warnOnce(msg) {
45644      if (!pastWarnings[msg]) {
45645        pastWarnings[msg] = true;
45646        this.warn.apply(this, arguments);
45647      }
45648    },
45649    _resetWarnings: function _resetWarnings() {
45650      pastWarnings = {};
45651    },
45652    trimString: function trimString(string) {
45653      return string.replace(/^\s+|\s+$/g, '');
45654    },
45655    parse: {
45656      date: function date(string) {
45657        var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
45658        if (!parsed) return null;
45659
45660        var _parsed$map = parsed.map(function (x) {
45661          return parseInt(x, 10);
45662        }),
45663            _parsed$map2 = _slicedToArray(_parsed$map, 4),
45664            _ = _parsed$map2[0],
45665            year = _parsed$map2[1],
45666            month = _parsed$map2[2],
45667            day = _parsed$map2[3];
45668
45669        var date = new Date(year, month - 1, day);
45670        if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
45671        return date;
45672      },
45673      string: function string(_string) {
45674        return _string;
45675      },
45676      integer: function integer(string) {
45677        if (isNaN(string)) return null;
45678        return parseInt(string, 10);
45679      },
45680      number: function number(string) {
45681        if (isNaN(string)) throw null;
45682        return parseFloat(string);
45683      },
45684      'boolean': function _boolean(string) {
45685        return !/^\s*false\s*$/i.test(string);
45686      },
45687      object: function object(string) {
45688        return Utils.deserializeValue(string);
45689      },
45690      regexp: function regexp(_regexp) {
45691        var flags = ''; // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
45692
45693        if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
45694          // Replace the regexp literal string with the first match group: ([gimy]*)
45695          // If no flag is present, this will be a blank string
45696          flags = _regexp.replace(/.*\/([gimy]*)$/, '$1'); // Again, replace the regexp literal string with the first match group:
45697          // everything excluding the opening and closing slashes and the flags
45698
45699          _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
45700        } else {
45701          // Anchor regexp:
45702          _regexp = '^' + _regexp + '$';
45703        }
45704
45705        return new RegExp(_regexp, flags);
45706      }
45707    },
45708    parseRequirement: function parseRequirement(requirementType, string) {
45709      var converter = this.parse[requirementType || 'string'];
45710      if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
45711      var converted = converter(string);
45712      if (converted === null) throw "Requirement is not a ".concat(requirementType, ": \"").concat(string, "\"");
45713      return converted;
45714    },
45715    namespaceEvents: function namespaceEvents(events, namespace) {
45716      events = this.trimString(events || '').split(/\s+/);
45717      if (!events[0]) return '';
45718      return $.map(events, function (evt) {
45719        return "".concat(evt, ".").concat(namespace);
45720      }).join(' ');
45721    },
45722    difference: function difference(array, remove) {
45723      // This is O(N^2), should be optimized
45724      var result = [];
45725      $.each(array, function (_, elem) {
45726        if (remove.indexOf(elem) == -1) result.push(elem);
45727      });
45728      return result;
45729    },
45730    // Alter-ego to native Promise.all, but for jQuery
45731    all: function all(promises) {
45732      // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
45733      return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
45734    },
45735    // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
45736    objectCreate: Object.create || function () {
45737      var Object = function Object() {};
45738
45739      return function (prototype) {
45740        if (arguments.length > 1) {
45741          throw Error('Second argument not supported');
45742        }
45743
45744        if (_typeof(prototype) != 'object') {
45745          throw TypeError('Argument must be an object');
45746        }
45747
45748        Object.prototype = prototype;
45749        var result = new Object();
45750        Object.prototype = null;
45751        return result;
45752      };
45753    }(),
45754    _SubmitSelector: 'input[type="submit"], button:submit'
45755  };
45756
45757  // All these options could be overriden and specified directly in DOM using
45758  // `data-parsley-` default DOM-API
45759  // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
45760  // eg: `data-parsley-stop-on-first-failing-constraint="false"`
45761  var Defaults = {
45762    // ### General
45763    // Default data-namespace for DOM API
45764    namespace: 'data-parsley-',
45765    // Supported inputs by default
45766    inputs: 'input, textarea, select',
45767    // Excluded inputs by default
45768    excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
45769    // Stop validating field on highest priority failing constraint
45770    priorityEnabled: true,
45771    // ### Field only
45772    // identifier used to group together inputs (e.g. radio buttons...)
45773    multiple: null,
45774    // identifier (or array of identifiers) used to validate only a select group of inputs
45775    group: null,
45776    // ### UI
45777    // Enable\Disable error messages
45778    uiEnabled: true,
45779    // Key events threshold before validation
45780    validationThreshold: 3,
45781    // Focused field on form validation error. 'first'|'last'|'none'
45782    focus: 'first',
45783    // event(s) that will trigger validation before first failure. eg: `input`...
45784    trigger: false,
45785    // event(s) that will trigger validation after first failure.
45786    triggerAfterFailure: 'input',
45787    // Class that would be added on every failing validation Parsley field
45788    errorClass: 'parsley-error',
45789    // Same for success validation
45790    successClass: 'parsley-success',
45791    // Return the `$element` that will receive these above success or error classes
45792    // Could also be (and given directly from DOM) a valid selector like `'#div'`
45793    classHandler: function classHandler(Field) {},
45794    // Return the `$element` where errors will be appended
45795    // Could also be (and given directly from DOM) a valid selector like `'#div'`
45796    errorsContainer: function errorsContainer(Field) {},
45797    // ul elem that would receive errors' list
45798    errorsWrapper: '<ul class="parsley-errors-list"></ul>',
45799    // li elem that would receive error message
45800    errorTemplate: '<li></li>'
45801  };
45802
45803  var Base = function Base() {
45804    this.__id__ = Utils.generateID();
45805  };
45806
45807  Base.prototype = {
45808    asyncSupport: true,
45809    // Deprecated
45810    _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
45811      var _this = this;
45812
45813      var pipe = function pipe() {
45814        var r = $.Deferred();
45815        if (true !== _this.validationResult) r.reject();
45816        return r.resolve().promise();
45817      };
45818
45819      return [pipe, pipe];
45820    },
45821    actualizeOptions: function actualizeOptions() {
45822      Utils.attr(this.element, this.options.namespace, this.domOptions);
45823      if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
45824      return this;
45825    },
45826    _resetOptions: function _resetOptions(initOptions) {
45827      this.domOptions = Utils.objectCreate(this.parent.options);
45828      this.options = Utils.objectCreate(this.domOptions); // Shallow copy of ownProperties of initOptions:
45829
45830      for (var i in initOptions) {
45831        if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
45832      }
45833
45834      this.actualizeOptions();
45835    },
45836    _listeners: null,
45837    // Register a callback for the given event name
45838    // Callback is called with context as the first argument and the `this`
45839    // The context is the current parsley instance, or window.Parsley if global
45840    // A return value of `false` will interrupt the calls
45841    on: function on(name, fn) {
45842      this._listeners = this._listeners || {};
45843      var queue = this._listeners[name] = this._listeners[name] || [];
45844      queue.push(fn);
45845      return this;
45846    },
45847    // Deprecated. Use `on` instead
45848    subscribe: function subscribe(name, fn) {
45849      $.listenTo(this, name.toLowerCase(), fn);
45850    },
45851    // Unregister a callback (or all if none is given) for the given event name
45852    off: function off(name, fn) {
45853      var queue = this._listeners && this._listeners[name];
45854
45855      if (queue) {
45856        if (!fn) {
45857          delete this._listeners[name];
45858        } else {
45859          for (var i = queue.length; i--;) {
45860            if (queue[i] === fn) queue.splice(i, 1);
45861          }
45862        }
45863      }
45864
45865      return this;
45866    },
45867    // Deprecated. Use `off`
45868    unsubscribe: function unsubscribe(name, fn) {
45869      $.unsubscribeTo(this, name.toLowerCase());
45870    },
45871    // Trigger an event of the given name
45872    // A return value of `false` interrupts the callback chain
45873    // Returns false if execution was interrupted
45874    trigger: function trigger(name, target, extraArg) {
45875      target = target || this;
45876      var queue = this._listeners && this._listeners[name];
45877      var result;
45878
45879      if (queue) {
45880        for (var i = queue.length; i--;) {
45881          result = queue[i].call(target, target, extraArg);
45882          if (result === false) return result;
45883        }
45884      }
45885
45886      if (this.parent) {
45887        return this.parent.trigger(name, target, extraArg);
45888      }
45889
45890      return true;
45891    },
45892    asyncIsValid: function asyncIsValid(group, force) {
45893      Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
45894      return this.whenValid({
45895        group: group,
45896        force: force
45897      });
45898    },
45899    _findRelated: function _findRelated() {
45900      return this.options.multiple ? $(this.parent.element.querySelectorAll("[".concat(this.options.namespace, "multiple=\"").concat(this.options.multiple, "\"]"))) : this.$element;
45901    }
45902  };
45903
45904  var convertArrayRequirement = function convertArrayRequirement(string, length) {
45905    var m = string.match(/^\s*\[(.*)\]\s*$/);
45906    if (!m) throw 'Requirement is not an array: "' + string + '"';
45907    var values = m[1].split(',').map(Utils.trimString);
45908    if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
45909    return values;
45910  };
45911
45912  var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
45913    var main = null;
45914    var extra = {};
45915
45916    for (var key in requirementSpec) {
45917      if (key) {
45918        var value = extraOptionReader(key);
45919        if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
45920        extra[key] = value;
45921      } else {
45922        main = Utils.parseRequirement(requirementSpec[key], string);
45923      }
45924    }
45925
45926    return [main, extra];
45927  }; // A Validator needs to implement the methods `validate` and `parseRequirements`
45928
45929
45930  var Validator = function Validator(spec) {
45931    $.extend(true, this, spec);
45932  };
45933
45934  Validator.prototype = {
45935    // Returns `true` iff the given `value` is valid according the given requirements.
45936    validate: function validate(value, requirementFirstArg) {
45937      if (this.fn) {
45938        // Legacy style validator
45939        if (arguments.length > 3) // If more args then value, requirement, instance...
45940          requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
45941
45942        return this.fn(value, requirementFirstArg);
45943      }
45944
45945      if (Array.isArray(value)) {
45946        if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
45947        return this.validateMultiple.apply(this, arguments);
45948      } else {
45949        var instance = arguments[arguments.length - 1];
45950
45951        if (this.validateDate && instance._isDateInput()) {
45952          arguments[0] = Utils.parse.date(arguments[0]);
45953          if (arguments[0] === null) return false;
45954          return this.validateDate.apply(this, arguments);
45955        }
45956
45957        if (this.validateNumber) {
45958          if (!value) // Builtin validators all accept empty strings, except `required` of course
45959            return true;
45960          if (isNaN(value)) return false;
45961          arguments[0] = parseFloat(arguments[0]);
45962          return this.validateNumber.apply(this, arguments);
45963        }
45964
45965        if (this.validateString) {
45966          return this.validateString.apply(this, arguments);
45967        }
45968
45969        throw 'Validator `' + this.name + '` only handles multiple values';
45970      }
45971    },
45972    // Parses `requirements` into an array of arguments,
45973    // according to `this.requirementType`
45974    parseRequirements: function parseRequirements(requirements, extraOptionReader) {
45975      if ('string' !== typeof requirements) {
45976        // Assume requirement already parsed
45977        // but make sure we return an array
45978        return Array.isArray(requirements) ? requirements : [requirements];
45979      }
45980
45981      var type = this.requirementType;
45982
45983      if (Array.isArray(type)) {
45984        var values = convertArrayRequirement(requirements, type.length);
45985
45986        for (var i = 0; i < values.length; i++) {
45987          values[i] = Utils.parseRequirement(type[i], values[i]);
45988        }
45989
45990        return values;
45991      } else if ($.isPlainObject(type)) {
45992        return convertExtraOptionRequirement(type, requirements, extraOptionReader);
45993      } else {
45994        return [Utils.parseRequirement(type, requirements)];
45995      }
45996    },
45997    // Defaults:
45998    requirementType: 'string',
45999    priority: 2
46000  };
46001
46002  var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
46003    this.__class__ = 'ValidatorRegistry'; // Default Parsley locale is en
46004
46005    this.locale = 'en';
46006    this.init(validators || {}, catalog || {});
46007  };
46008
46009  var typeTesters = {
46010    email: /^((([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))$/,
46011    // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
46012    number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
46013    integer: /^-?\d+$/,
46014    digits: /^\d+$/,
46015    alphanum: /^\w+$/i,
46016    date: {
46017      test: function test(value) {
46018        return Utils.parse.date(value) !== null;
46019      }
46020    },
46021    url: new RegExp("^" + // protocol identifier
46022    "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
46023    // user:pass authentication
46024    "(?:\\S+(?::\\S*)?@)?" + "(?:" + // IP address exclusion
46025    // private & local networks
46026    // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +   // ** mod: allow local networks
46027    // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
46028    // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
46029    // IP address dotted notation octets
46030    // excludes loopback network 0.0.0.0
46031    // excludes reserved space >= 224.0.0.0
46032    // excludes network & broacast addresses
46033    // (first & last IP address of each class)
46034    "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" + // host name
46035    "(?:(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)" + // domain name
46036    "(?:\\.(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)*" + // TLD identifier
46037    "(?:\\.(?:[a-zA-Z\\u00a1-\\uffff]{2,}))" + ")" + // port number
46038    "(?::\\d{2,5})?" + // resource path
46039    "(?:/\\S*)?" + "$")
46040  };
46041  typeTesters.range = typeTesters.number; // See http://stackoverflow.com/a/10454560/8279
46042
46043  var decimalPlaces = function decimalPlaces(num) {
46044    var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
46045
46046    if (!match) {
46047      return 0;
46048    }
46049
46050    return Math.max(0, // Number of digits right of decimal point.
46051    (match[1] ? match[1].length : 0) - ( // Adjust for scientific notation.
46052    match[2] ? +match[2] : 0));
46053  }; // parseArguments('number', ['1', '2']) => [1, 2]
46054
46055
46056  var parseArguments = function parseArguments(type, args) {
46057    return args.map(Utils.parse[type]);
46058  }; // operatorToValidator returns a validating function for an operator function, applied to the given type
46059
46060
46061  var operatorToValidator = function operatorToValidator(type, operator) {
46062    return function (value) {
46063      for (var _len = arguments.length, requirementsAndInput = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
46064        requirementsAndInput[_key - 1] = arguments[_key];
46065      }
46066
46067      requirementsAndInput.pop(); // Get rid of `input` argument
46068
46069      return operator.apply(void 0, [value].concat(_toConsumableArray(parseArguments(type, requirementsAndInput))));
46070    };
46071  };
46072
46073  var comparisonOperator = function comparisonOperator(operator) {
46074    return {
46075      validateDate: operatorToValidator('date', operator),
46076      validateNumber: operatorToValidator('number', operator),
46077      requirementType: operator.length <= 2 ? 'string' : ['string', 'string'],
46078      // Support operators with a 1 or 2 requirement(s)
46079      priority: 30
46080    };
46081  };
46082
46083  ValidatorRegistry.prototype = {
46084    init: function init(validators, catalog) {
46085      this.catalog = catalog; // Copy prototype's validators:
46086
46087      this.validators = _extends({}, this.validators);
46088
46089      for (var name in validators) {
46090        this.addValidator(name, validators[name].fn, validators[name].priority);
46091      }
46092
46093      window.Parsley.trigger('parsley:validator:init');
46094    },
46095    // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
46096    setLocale: function setLocale(locale) {
46097      if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
46098      this.locale = locale;
46099      return this;
46100    },
46101    // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
46102    addCatalog: function addCatalog(locale, messages, set) {
46103      if ('object' === _typeof(messages)) this.catalog[locale] = messages;
46104      if (true === set) return this.setLocale(locale);
46105      return this;
46106    },
46107    // Add a specific message for a given constraint in a given locale
46108    addMessage: function addMessage(locale, name, message) {
46109      if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
46110      this.catalog[locale][name] = message;
46111      return this;
46112    },
46113    // Add messages for a given locale
46114    addMessages: function addMessages(locale, nameMessageObject) {
46115      for (var name in nameMessageObject) {
46116        this.addMessage(locale, name, nameMessageObject[name]);
46117      }
46118
46119      return this;
46120    },
46121    // Add a new validator
46122    //
46123    //    addValidator('custom', {
46124    //        requirementType: ['integer', 'integer'],
46125    //        validateString: function(value, from, to) {},
46126    //        priority: 22,
46127    //        messages: {
46128    //          en: "Hey, that's no good",
46129    //          fr: "Aye aye, pas bon du tout",
46130    //        }
46131    //    })
46132    //
46133    // Old API was addValidator(name, function, priority)
46134    //
46135    addValidator: function addValidator(name, arg1, arg2) {
46136      if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
46137        Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
46138        return;
46139      }
46140      return this._setValidator.apply(this, arguments);
46141    },
46142    hasValidator: function hasValidator(name) {
46143      return !!this.validators[name];
46144    },
46145    updateValidator: function updateValidator(name, arg1, arg2) {
46146      if (!this.validators[name]) {
46147        Utils.warn('Validator "' + name + '" is not already defined.');
46148        return this.addValidator.apply(this, arguments);
46149      }
46150
46151      return this._setValidator.apply(this, arguments);
46152    },
46153    removeValidator: function removeValidator(name) {
46154      if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
46155      delete this.validators[name];
46156      return this;
46157    },
46158    _setValidator: function _setValidator(name, validator, priority) {
46159      if ('object' !== _typeof(validator)) {
46160        // Old style validator, with `fn` and `priority`
46161        validator = {
46162          fn: validator,
46163          priority: priority
46164        };
46165      }
46166
46167      if (!validator.validate) {
46168        validator = new Validator(validator);
46169      }
46170
46171      this.validators[name] = validator;
46172
46173      for (var locale in validator.messages || {}) {
46174        this.addMessage(locale, name, validator.messages[locale]);
46175      }
46176
46177      return this;
46178    },
46179    getErrorMessage: function getErrorMessage(constraint) {
46180      var message; // Type constraints are a bit different, we have to match their requirements too to find right error message
46181
46182      if ('type' === constraint.name) {
46183        var typeMessages = this.catalog[this.locale][constraint.name] || {};
46184        message = typeMessages[constraint.requirements];
46185      } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
46186
46187      return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
46188    },
46189    // Kind of light `sprintf()` implementation
46190    formatMessage: function formatMessage(string, parameters) {
46191      if ('object' === _typeof(parameters)) {
46192        for (var i in parameters) {
46193          string = this.formatMessage(string, parameters[i]);
46194        }
46195
46196        return string;
46197      }
46198
46199      return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
46200    },
46201    // Here is the Parsley default validators list.
46202    // A validator is an object with the following key values:
46203    //  - priority: an integer
46204    //  - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
46205    //  - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
46206    // Alternatively, a validator can be a function that returns such an object
46207    //
46208    validators: {
46209      notblank: {
46210        validateString: function validateString(value) {
46211          return /\S/.test(value);
46212        },
46213        priority: 2
46214      },
46215      required: {
46216        validateMultiple: function validateMultiple(values) {
46217          return values.length > 0;
46218        },
46219        validateString: function validateString(value) {
46220          return /\S/.test(value);
46221        },
46222        priority: 512
46223      },
46224      type: {
46225        validateString: function validateString(value, type) {
46226          var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
46227              _ref$step = _ref.step,
46228              step = _ref$step === void 0 ? 'any' : _ref$step,
46229              _ref$base = _ref.base,
46230              base = _ref$base === void 0 ? 0 : _ref$base;
46231
46232          var tester = typeTesters[type];
46233
46234          if (!tester) {
46235            throw new Error('validator type `' + type + '` is not supported');
46236          }
46237
46238          if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
46239
46240          if (!tester.test(value)) return false;
46241
46242          if ('number' === type) {
46243            if (!/^any$/i.test(step || '')) {
46244              var nb = Number(value);
46245              var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
46246              if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
46247                return false; // Be careful of rounding errors by using integers.
46248
46249              var toInt = function toInt(f) {
46250                return Math.round(f * Math.pow(10, decimals));
46251              };
46252
46253              if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
46254            }
46255          }
46256
46257          return true;
46258        },
46259        requirementType: {
46260          '': 'string',
46261          step: 'string',
46262          base: 'number'
46263        },
46264        priority: 256
46265      },
46266      pattern: {
46267        validateString: function validateString(value, regexp) {
46268          if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
46269
46270          return regexp.test(value);
46271        },
46272        requirementType: 'regexp',
46273        priority: 64
46274      },
46275      minlength: {
46276        validateString: function validateString(value, requirement) {
46277          if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
46278
46279          return value.length >= requirement;
46280        },
46281        requirementType: 'integer',
46282        priority: 30
46283      },
46284      maxlength: {
46285        validateString: function validateString(value, requirement) {
46286          return value.length <= requirement;
46287        },
46288        requirementType: 'integer',
46289        priority: 30
46290      },
46291      length: {
46292        validateString: function validateString(value, min, max) {
46293          if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
46294
46295          return value.length >= min && value.length <= max;
46296        },
46297        requirementType: ['integer', 'integer'],
46298        priority: 30
46299      },
46300      mincheck: {
46301        validateMultiple: function validateMultiple(values, requirement) {
46302          return values.length >= requirement;
46303        },
46304        requirementType: 'integer',
46305        priority: 30
46306      },
46307      maxcheck: {
46308        validateMultiple: function validateMultiple(values, requirement) {
46309          return values.length <= requirement;
46310        },
46311        requirementType: 'integer',
46312        priority: 30
46313      },
46314      check: {
46315        validateMultiple: function validateMultiple(values, min, max) {
46316          return values.length >= min && values.length <= max;
46317        },
46318        requirementType: ['integer', 'integer'],
46319        priority: 30
46320      },
46321      min: comparisonOperator(function (value, requirement) {
46322        return value >= requirement;
46323      }),
46324      max: comparisonOperator(function (value, requirement) {
46325        return value <= requirement;
46326      }),
46327      range: comparisonOperator(function (value, min, max) {
46328        return value >= min && value <= max;
46329      }),
46330      equalto: {
46331        validateString: function validateString(value, refOrValue) {
46332          if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
46333
46334          var $reference = $(refOrValue);
46335          if ($reference.length) return value === $reference.val();else return value === refOrValue;
46336        },
46337        priority: 256
46338      },
46339      euvatin: {
46340        validateString: function validateString(value, refOrValue) {
46341          if (!value) {
46342            return true; // Builtin validators all accept empty strings, except `required` of course
46343          }
46344
46345          var re = /^[A-Z][A-Z][A-Za-z0-9 -]{2,}$/;
46346          return re.test(value);
46347        },
46348        priority: 30
46349      }
46350    }
46351  };
46352
46353  var UI = {};
46354
46355  var diffResults = function diffResults(newResult, oldResult, deep) {
46356    var added = [];
46357    var kept = [];
46358
46359    for (var i = 0; i < newResult.length; i++) {
46360      var found = false;
46361
46362      for (var j = 0; j < oldResult.length; j++) {
46363        if (newResult[i].assert.name === oldResult[j].assert.name) {
46364          found = true;
46365          break;
46366        }
46367      }
46368
46369      if (found) kept.push(newResult[i]);else added.push(newResult[i]);
46370    }
46371
46372    return {
46373      kept: kept,
46374      added: added,
46375      removed: !deep ? diffResults(oldResult, newResult, true).added : []
46376    };
46377  };
46378
46379  UI.Form = {
46380    _actualizeTriggers: function _actualizeTriggers() {
46381      var _this = this;
46382
46383      this.$element.on('submit.Parsley', function (evt) {
46384        _this.onSubmitValidate(evt);
46385      });
46386      this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
46387        _this.onSubmitButton(evt);
46388      }); // UI could be disabled
46389
46390      if (false === this.options.uiEnabled) return;
46391      this.element.setAttribute('novalidate', '');
46392    },
46393    focus: function focus() {
46394      this._focusedField = null;
46395      if (true === this.validationResult || 'none' === this.options.focus) return null;
46396
46397      for (var i = 0; i < this.fields.length; i++) {
46398        var field = this.fields[i];
46399
46400        if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
46401          this._focusedField = field.$element;
46402          if ('first' === this.options.focus) break;
46403        }
46404      }
46405
46406      if (null === this._focusedField) return null;
46407      return this._focusedField.focus();
46408    },
46409    _destroyUI: function _destroyUI() {
46410      // Reset all event listeners
46411      this.$element.off('.Parsley');
46412    }
46413  };
46414  UI.Field = {
46415    _reflowUI: function _reflowUI() {
46416      this._buildUI(); // If this field doesn't have an active UI don't bother doing something
46417
46418
46419      if (!this._ui) return; // Diff between two validation results
46420
46421      var diff = diffResults(this.validationResult, this._ui.lastValidationResult); // Then store current validation result for next reflow
46422
46423      this._ui.lastValidationResult = this.validationResult; // Handle valid / invalid / none field class
46424
46425      this._manageStatusClass(); // Add, remove, updated errors messages
46426
46427
46428      this._manageErrorsMessages(diff); // Triggers impl
46429
46430
46431      this._actualizeTriggers(); // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
46432
46433
46434      if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
46435        this._failedOnce = true;
46436
46437        this._actualizeTriggers();
46438      }
46439    },
46440    // Returns an array of field's error message(s)
46441    getErrorsMessages: function getErrorsMessages() {
46442      // No error message, field is valid
46443      if (true === this.validationResult) return [];
46444      var messages = [];
46445
46446      for (var i = 0; i < this.validationResult.length; i++) {
46447        messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
46448      }
46449
46450      return messages;
46451    },
46452    // It's a goal of Parsley that this method is no longer required [#1073]
46453    addError: function addError(name) {
46454      var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
46455          message = _ref.message,
46456          assert = _ref.assert,
46457          _ref$updateClass = _ref.updateClass,
46458          updateClass = _ref$updateClass === void 0 ? true : _ref$updateClass;
46459
46460      this._buildUI();
46461
46462      this._addError(name, {
46463        message: message,
46464        assert: assert
46465      });
46466
46467      if (updateClass) this._errorClass();
46468    },
46469    // It's a goal of Parsley that this method is no longer required [#1073]
46470    updateError: function updateError(name) {
46471      var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
46472          message = _ref2.message,
46473          assert = _ref2.assert,
46474          _ref2$updateClass = _ref2.updateClass,
46475          updateClass = _ref2$updateClass === void 0 ? true : _ref2$updateClass;
46476
46477      this._buildUI();
46478
46479      this._updateError(name, {
46480        message: message,
46481        assert: assert
46482      });
46483
46484      if (updateClass) this._errorClass();
46485    },
46486    // It's a goal of Parsley that this method is no longer required [#1073]
46487    removeError: function removeError(name) {
46488      var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
46489          _ref3$updateClass = _ref3.updateClass,
46490          updateClass = _ref3$updateClass === void 0 ? true : _ref3$updateClass;
46491
46492      this._buildUI();
46493
46494      this._removeError(name); // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
46495      // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
46496
46497
46498      if (updateClass) this._manageStatusClass();
46499    },
46500    _manageStatusClass: function _manageStatusClass() {
46501      if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
46502    },
46503    _manageErrorsMessages: function _manageErrorsMessages(diff) {
46504      if ('undefined' !== typeof this.options.errorsMessagesDisabled) return; // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
46505
46506      if ('undefined' !== typeof this.options.errorMessage) {
46507        if (diff.added.length || diff.kept.length) {
46508          this._insertErrorWrapper();
46509
46510          if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
46511
46512          this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId);
46513
46514          return this._ui.$errorsWrapper.addClass('filled').attr('aria-hidden', 'false').find('.parsley-custom-error-message').html(this.options.errorMessage);
46515        }
46516
46517        this._ui.$errorClassHandler.removeAttr('aria-describedby');
46518
46519        return this._ui.$errorsWrapper.removeClass('filled').attr('aria-hidden', 'true').find('.parsley-custom-error-message').remove();
46520      } // Show, hide, update failing constraints messages
46521
46522
46523      for (var i = 0; i < diff.removed.length; i++) {
46524        this._removeError(diff.removed[i].assert.name);
46525      }
46526
46527      for (i = 0; i < diff.added.length; i++) {
46528        this._addError(diff.added[i].assert.name, {
46529          message: diff.added[i].errorMessage,
46530          assert: diff.added[i].assert
46531        });
46532      }
46533
46534      for (i = 0; i < diff.kept.length; i++) {
46535        this._updateError(diff.kept[i].assert.name, {
46536          message: diff.kept[i].errorMessage,
46537          assert: diff.kept[i].assert
46538        });
46539      }
46540    },
46541    _addError: function _addError(name, _ref4) {
46542      var message = _ref4.message,
46543          assert = _ref4.assert;
46544
46545      this._insertErrorWrapper();
46546
46547      this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId);
46548
46549      this._ui.$errorsWrapper.addClass('filled').attr('aria-hidden', 'false').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
46550    },
46551    _updateError: function _updateError(name, _ref5) {
46552      var message = _ref5.message,
46553          assert = _ref5.assert;
46554
46555      this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
46556    },
46557    _removeError: function _removeError(name) {
46558      this._ui.$errorClassHandler.removeAttr('aria-describedby');
46559
46560      this._ui.$errorsWrapper.removeClass('filled').attr('aria-hidden', 'true').find('.parsley-' + name).remove();
46561    },
46562    _getErrorMessage: function _getErrorMessage(constraint) {
46563      var customConstraintErrorMessage = constraint.name + 'Message';
46564      if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
46565      return window.Parsley.getErrorMessage(constraint);
46566    },
46567    _buildUI: function _buildUI() {
46568      // UI could be already built or disabled
46569      if (this._ui || false === this.options.uiEnabled) return;
46570      var _ui = {}; // Give field its Parsley id in DOM
46571
46572      this.element.setAttribute(this.options.namespace + 'id', this.__id__);
46573      /** Generate important UI elements and store them in this **/
46574      // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
46575
46576      _ui.$errorClassHandler = this._manageClassHandler(); // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
46577
46578      _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
46579      _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId); // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
46580
46581      _ui.lastValidationResult = [];
46582      _ui.validationInformationVisible = false; // Store it in this for later
46583
46584      this._ui = _ui;
46585    },
46586    // Determine which element will have `parsley-error` and `parsley-success` classes
46587    _manageClassHandler: function _manageClassHandler() {
46588      // Class handled could also be determined by function given in Parsley options
46589      if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler); // Class handled could also be determined by function given in Parsley options
46590
46591      var $handlerFunction = this.options.classHandler; // It might also be the function name of a global function
46592
46593      if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler];
46594
46595      if ('function' === typeof $handlerFunction) {
46596        var $handler = $handlerFunction.call(this, this); // If this function returned a valid existing DOM element, go for it
46597
46598        if ('undefined' !== typeof $handler && $handler.length) return $handler;
46599      } else if ('object' === _typeof($handlerFunction) && $handlerFunction instanceof jQuery && $handlerFunction.length) {
46600        return $handlerFunction;
46601      } else if ($handlerFunction) {
46602        Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function');
46603      }
46604
46605      return this._inputHolder();
46606    },
46607    _inputHolder: function _inputHolder() {
46608      // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
46609      if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element; // But if multiple element (radio, checkbox), that would be their parent
46610
46611      return this.$element.parent();
46612    },
46613    _insertErrorWrapper: function _insertErrorWrapper() {
46614      var $errorsContainer = this.options.errorsContainer; // Nothing to do if already inserted
46615
46616      if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
46617
46618      if ('string' === typeof $errorsContainer) {
46619        if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function');
46620      }
46621
46622      if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this);
46623      if ('object' === _typeof($errorsContainer) && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
46624      return this._inputHolder().after(this._ui.$errorsWrapper);
46625    },
46626    _actualizeTriggers: function _actualizeTriggers() {
46627      var _this2 = this;
46628
46629      var $toBind = this._findRelated();
46630
46631      var trigger; // Remove Parsley events already bound on this field
46632
46633      $toBind.off('.Parsley');
46634      if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
46635        _this2._validateIfNeeded();
46636      });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
46637        $toBind.on(trigger, function (event) {
46638          _this2._validateIfNeeded(event);
46639        });
46640      }
46641    },
46642    _validateIfNeeded: function _validateIfNeeded(event) {
46643      var _this3 = this;
46644
46645      // For keyup, keypress, keydown, input... events that could be a little bit obstrusive
46646      // do not validate if val length < min threshold on first validation. Once field have been validated once and info
46647      // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
46648      if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
46649
46650      if (this.options.debounce) {
46651        window.clearTimeout(this._debounced);
46652        this._debounced = window.setTimeout(function () {
46653          return _this3.validate();
46654        }, this.options.debounce);
46655      } else this.validate();
46656    },
46657    _resetUI: function _resetUI() {
46658      // Reset all event listeners
46659      this._failedOnce = false;
46660
46661      this._actualizeTriggers(); // Nothing to do if UI never initialized for this field
46662
46663
46664      if ('undefined' === typeof this._ui) return; // Reset all errors' li
46665
46666      this._ui.$errorsWrapper.removeClass('filled').children().remove(); // Reset validation class
46667
46668
46669      this._resetClass(); // Reset validation flags and last validation result
46670
46671
46672      this._ui.lastValidationResult = [];
46673      this._ui.validationInformationVisible = false;
46674    },
46675    _destroyUI: function _destroyUI() {
46676      this._resetUI();
46677
46678      if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
46679      delete this._ui;
46680    },
46681    _successClass: function _successClass() {
46682      this._ui.validationInformationVisible = true;
46683
46684      this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
46685    },
46686    _errorClass: function _errorClass() {
46687      this._ui.validationInformationVisible = true;
46688
46689      this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
46690    },
46691    _resetClass: function _resetClass() {
46692      this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
46693    }
46694  };
46695
46696  var Form = function Form(element, domOptions, options) {
46697    this.__class__ = 'Form';
46698    this.element = element;
46699    this.$element = $(element);
46700    this.domOptions = domOptions;
46701    this.options = options;
46702    this.parent = window.Parsley;
46703    this.fields = [];
46704    this.validationResult = null;
46705  };
46706
46707  var statusMapping = {
46708    pending: null,
46709    resolved: true,
46710    rejected: false
46711  };
46712  Form.prototype = {
46713    onSubmitValidate: function onSubmitValidate(event) {
46714      var _this = this;
46715
46716      // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
46717      if (true === event.parsley) return; // If we didn't come here through a submit button, use the first one in the form
46718
46719      var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
46720      this._submitSource = null;
46721      this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
46722      if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
46723      window.Parsley._remoteCache = {};
46724      var promise = this.whenValidate({
46725        event: event
46726      });
46727
46728      if ('resolved' === promise.state() && false !== this._trigger('submit')) ; else {
46729        // Rejected or pending: cancel this submit
46730        event.stopImmediatePropagation();
46731        event.preventDefault();
46732        if ('pending' === promise.state()) promise.done(function () {
46733          _this._submit(submitSource);
46734        });
46735      }
46736    },
46737    onSubmitButton: function onSubmitButton(event) {
46738      this._submitSource = event.currentTarget;
46739    },
46740    // internal
46741    // _submit submits the form, this time without going through the validations.
46742    // Care must be taken to "fake" the actual submit button being clicked.
46743    _submit: function _submit(submitSource) {
46744      if (false === this._trigger('submit')) return; // Add submit button's data
46745
46746      if (submitSource) {
46747        var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
46748        if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
46749        $synthetic.attr({
46750          name: submitSource.getAttribute('name'),
46751          value: submitSource.getAttribute('value')
46752        });
46753      }
46754
46755      this.$element.trigger(_extends($.Event('submit'), {
46756        parsley: true
46757      }));
46758    },
46759    // Performs validation on fields while triggering events.
46760    // @returns `true` if all validations succeeds, `false`
46761    // if a failure is immediately detected, or `null`
46762    // if dependant on a promise.
46763    // Consider using `whenValidate` instead.
46764    validate: function validate(options) {
46765      if (arguments.length >= 1 && !$.isPlainObject(options)) {
46766        Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
46767
46768        var _arguments = Array.prototype.slice.call(arguments),
46769            group = _arguments[0],
46770            force = _arguments[1],
46771            event = _arguments[2];
46772
46773        options = {
46774          group: group,
46775          force: force,
46776          event: event
46777        };
46778      }
46779
46780      return statusMapping[this.whenValidate(options).state()];
46781    },
46782    whenValidate: function whenValidate() {
46783      var _this2 = this,
46784          _Utils$all$done$fail$;
46785
46786      var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
46787          group = _ref.group,
46788          force = _ref.force,
46789          event = _ref.event;
46790
46791      this.submitEvent = event;
46792
46793      if (event) {
46794        this.submitEvent = _extends({}, event, {
46795          preventDefault: function preventDefault() {
46796            Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
46797            _this2.validationResult = false;
46798          }
46799        });
46800      }
46801
46802      this.validationResult = true; // fire validate event to eventually modify things before every validation
46803
46804      this._trigger('validate'); // Refresh form DOM options and form's fields that could have changed
46805
46806
46807      this._refreshFields();
46808
46809      var promises = this._withoutReactualizingFormOptions(function () {
46810        return $.map(_this2.fields, function (field) {
46811          return field.whenValidate({
46812            force: force,
46813            group: group
46814          });
46815        });
46816      });
46817
46818      return (_Utils$all$done$fail$ = Utils.all(promises).done(function () {
46819        _this2._trigger('success');
46820      }).fail(function () {
46821        _this2.validationResult = false;
46822
46823        _this2.focus();
46824
46825        _this2._trigger('error');
46826      }).always(function () {
46827        _this2._trigger('validated');
46828      })).pipe.apply(_Utils$all$done$fail$, _toConsumableArray(this._pipeAccordingToValidationResult()));
46829    },
46830    // Iterate over refreshed fields, and stop on first failure.
46831    // Returns `true` if all fields are valid, `false` if a failure is detected
46832    // or `null` if the result depends on an unresolved promise.
46833    // Prefer using `whenValid` instead.
46834    isValid: function isValid(options) {
46835      if (arguments.length >= 1 && !$.isPlainObject(options)) {
46836        Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
46837
46838        var _arguments2 = Array.prototype.slice.call(arguments),
46839            group = _arguments2[0],
46840            force = _arguments2[1];
46841
46842        options = {
46843          group: group,
46844          force: force
46845        };
46846      }
46847
46848      return statusMapping[this.whenValid(options).state()];
46849    },
46850    // Iterate over refreshed fields and validate them.
46851    // Returns a promise.
46852    // A validation that immediately fails will interrupt the validations.
46853    whenValid: function whenValid() {
46854      var _this3 = this;
46855
46856      var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
46857          group = _ref2.group,
46858          force = _ref2.force;
46859
46860      this._refreshFields();
46861
46862      var promises = this._withoutReactualizingFormOptions(function () {
46863        return $.map(_this3.fields, function (field) {
46864          return field.whenValid({
46865            group: group,
46866            force: force
46867          });
46868        });
46869      });
46870
46871      return Utils.all(promises);
46872    },
46873    refresh: function refresh() {
46874      this._refreshFields();
46875
46876      return this;
46877    },
46878    // Reset UI
46879    reset: function reset() {
46880      // Form case: emit a reset event for each field
46881      for (var i = 0; i < this.fields.length; i++) {
46882        this.fields[i].reset();
46883      }
46884
46885      this._trigger('reset');
46886    },
46887    // Destroy Parsley instance (+ UI)
46888    destroy: function destroy() {
46889      // Field case: emit destroy event to clean UI and then destroy stored instance
46890      this._destroyUI(); // Form case: destroy all its fields and then destroy stored instance
46891
46892
46893      for (var i = 0; i < this.fields.length; i++) {
46894        this.fields[i].destroy();
46895      }
46896
46897      this.$element.removeData('Parsley');
46898
46899      this._trigger('destroy');
46900    },
46901    _refreshFields: function _refreshFields() {
46902      return this.actualizeOptions()._bindFields();
46903    },
46904    _bindFields: function _bindFields() {
46905      var _this4 = this;
46906
46907      var oldFields = this.fields;
46908      this.fields = [];
46909      this.fieldsMappedById = {};
46910
46911      this._withoutReactualizingFormOptions(function () {
46912        _this4.$element.find(_this4.options.inputs).not(_this4.options.excluded).not("[".concat(_this4.options.namespace, "excluded=true]")).each(function (_, element) {
46913          var fieldInstance = new window.Parsley.Factory(element, {}, _this4); // Only add valid and not excluded `Field` and `FieldMultiple` children
46914
46915          if ('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) {
46916            var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
46917
46918            if ('undefined' === typeof _this4.fieldsMappedById[uniqueId]) {
46919              _this4.fieldsMappedById[uniqueId] = fieldInstance;
46920
46921              _this4.fields.push(fieldInstance);
46922            }
46923          }
46924        });
46925
46926        $.each(Utils.difference(oldFields, _this4.fields), function (_, field) {
46927          field.reset();
46928        });
46929      });
46930
46931      return this;
46932    },
46933    // Internal only.
46934    // Looping on a form's fields to do validation or similar
46935    // will trigger reactualizing options on all of them, which
46936    // in turn will reactualize the form's options.
46937    // To avoid calling actualizeOptions so many times on the form
46938    // for nothing, _withoutReactualizingFormOptions temporarily disables
46939    // the method actualizeOptions on this form while `fn` is called.
46940    _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
46941      var oldActualizeOptions = this.actualizeOptions;
46942
46943      this.actualizeOptions = function () {
46944        return this;
46945      };
46946
46947      var result = fn();
46948      this.actualizeOptions = oldActualizeOptions;
46949      return result;
46950    },
46951    // Internal only.
46952    // Shortcut to trigger an event
46953    // Returns true iff event is not interrupted and default not prevented.
46954    _trigger: function _trigger(eventName) {
46955      return this.trigger('form:' + eventName);
46956    }
46957  };
46958
46959  var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
46960    var validatorSpec = window.Parsley._validatorRegistry.validators[name];
46961    var validator = new Validator(validatorSpec);
46962    priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
46963    isDomConstraint = true === isDomConstraint;
46964
46965    _extends(this, {
46966      validator: validator,
46967      name: name,
46968      requirements: requirements,
46969      priority: priority,
46970      isDomConstraint: isDomConstraint
46971    });
46972
46973    this._parseRequirements(parsleyField.options);
46974  };
46975
46976  var capitalize = function capitalize(str) {
46977    var cap = str[0].toUpperCase();
46978    return cap + str.slice(1);
46979  };
46980
46981  Constraint.prototype = {
46982    validate: function validate(value, instance) {
46983      var _this$validator;
46984
46985      return (_this$validator = this.validator).validate.apply(_this$validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
46986    },
46987    _parseRequirements: function _parseRequirements(options) {
46988      var _this = this;
46989
46990      this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
46991        return options[_this.name + capitalize(key)];
46992      });
46993    }
46994  };
46995
46996  var Field = function Field(field, domOptions, options, parsleyFormInstance) {
46997    this.__class__ = 'Field';
46998    this.element = field;
46999    this.$element = $(field); // Set parent if we have one
47000
47001    if ('undefined' !== typeof parsleyFormInstance) {
47002      this.parent = parsleyFormInstance;
47003    }
47004
47005    this.options = options;
47006    this.domOptions = domOptions; // Initialize some properties
47007
47008    this.constraints = [];
47009    this.constraintsByName = {};
47010    this.validationResult = true; // Bind constraints
47011
47012    this._bindConstraints();
47013  };
47014
47015  var statusMapping$1 = {
47016    pending: null,
47017    resolved: true,
47018    rejected: false
47019  };
47020  Field.prototype = {
47021    // # Public API
47022    // Validate field and trigger some events for mainly `UI`
47023    // @returns `true`, an array of the validators that failed, or
47024    // `null` if validation is not finished. Prefer using whenValidate
47025    validate: function validate(options) {
47026      if (arguments.length >= 1 && !$.isPlainObject(options)) {
47027        Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
47028        options = {
47029          options: options
47030        };
47031      }
47032
47033      var promise = this.whenValidate(options);
47034      if (!promise) // If excluded with `group` option
47035        return true;
47036
47037      switch (promise.state()) {
47038        case 'pending':
47039          return null;
47040
47041        case 'resolved':
47042          return true;
47043
47044        case 'rejected':
47045          return this.validationResult;
47046      }
47047    },
47048    // Validate field and trigger some events for mainly `UI`
47049    // @returns a promise that succeeds only when all validations do
47050    // or `undefined` if field is not in the given `group`.
47051    whenValidate: function whenValidate() {
47052      var _this$whenValid$alway,
47053          _this = this;
47054
47055      var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
47056          force = _ref.force,
47057          group = _ref.group;
47058
47059      // do not validate a field if not the same as given validation group
47060      this.refresh();
47061      if (group && !this._isInGroup(group)) return;
47062      this.value = this.getValue(); // Field Validate event. `this.value` could be altered for custom needs
47063
47064      this._trigger('validate');
47065
47066      return (_this$whenValid$alway = this.whenValid({
47067        force: force,
47068        value: this.value,
47069        _refreshed: true
47070      }).always(function () {
47071        _this._reflowUI();
47072      }).done(function () {
47073        _this._trigger('success');
47074      }).fail(function () {
47075        _this._trigger('error');
47076      }).always(function () {
47077        _this._trigger('validated');
47078      })).pipe.apply(_this$whenValid$alway, _toConsumableArray(this._pipeAccordingToValidationResult()));
47079    },
47080    hasConstraints: function hasConstraints() {
47081      return 0 !== this.constraints.length;
47082    },
47083    // An empty optional field does not need validation
47084    needsValidation: function needsValidation(value) {
47085      if ('undefined' === typeof value) value = this.getValue(); // If a field is empty and not required, it is valid
47086      // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
47087
47088      if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
47089      return true;
47090    },
47091    _isInGroup: function _isInGroup(group) {
47092      if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
47093      return this.options.group === group;
47094    },
47095    // Just validate field. Do not trigger any event.
47096    // Returns `true` iff all constraints pass, `false` if there are failures,
47097    // or `null` if the result can not be determined yet (depends on a promise)
47098    // See also `whenValid`.
47099    isValid: function isValid(options) {
47100      if (arguments.length >= 1 && !$.isPlainObject(options)) {
47101        Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
47102
47103        var _arguments = Array.prototype.slice.call(arguments),
47104            force = _arguments[0],
47105            value = _arguments[1];
47106
47107        options = {
47108          force: force,
47109          value: value
47110        };
47111      }
47112
47113      var promise = this.whenValid(options);
47114      if (!promise) // Excluded via `group`
47115        return true;
47116      return statusMapping$1[promise.state()];
47117    },
47118    // Just validate field. Do not trigger any event.
47119    // @returns a promise that succeeds only when all validations do
47120    // or `undefined` if the field is not in the given `group`.
47121    // The argument `force` will force validation of empty fields.
47122    // If a `value` is given, it will be validated instead of the value of the input.
47123    whenValid: function whenValid() {
47124      var _this2 = this;
47125
47126      var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
47127          _ref2$force = _ref2.force,
47128          force = _ref2$force === void 0 ? false : _ref2$force,
47129          value = _ref2.value,
47130          group = _ref2.group,
47131          _refreshed = _ref2._refreshed;
47132
47133      // Recompute options and rebind constraints to have latest changes
47134      if (!_refreshed) this.refresh(); // do not validate a field if not the same as given validation group
47135
47136      if (group && !this._isInGroup(group)) return;
47137      this.validationResult = true; // A field without constraint is valid
47138
47139      if (!this.hasConstraints()) return $.when(); // Value could be passed as argument, needed to add more power to 'field:validate'
47140
47141      if ('undefined' === typeof value || null === value) value = this.getValue();
47142      if (!this.needsValidation(value) && true !== force) return $.when();
47143
47144      var groupedConstraints = this._getGroupedConstraints();
47145
47146      var promises = [];
47147      $.each(groupedConstraints, function (_, constraints) {
47148        // Process one group of constraints at a time, we validate the constraints
47149        // and combine the promises together.
47150        var promise = Utils.all($.map(constraints, function (constraint) {
47151          return _this2._validateConstraint(value, constraint);
47152        }));
47153        promises.push(promise);
47154        if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
47155      });
47156      return Utils.all(promises);
47157    },
47158    // @returns a promise
47159    _validateConstraint: function _validateConstraint(value, constraint) {
47160      var _this3 = this;
47161
47162      var result = constraint.validate(value, this); // Map false to a failed promise
47163
47164      if (false === result) result = $.Deferred().reject(); // Make sure we return a promise and that we record failures
47165
47166      return Utils.all([result]).fail(function (errorMessage) {
47167        if (!(_this3.validationResult instanceof Array)) _this3.validationResult = [];
47168
47169        _this3.validationResult.push({
47170          assert: constraint,
47171          errorMessage: 'string' === typeof errorMessage && errorMessage
47172        });
47173      });
47174    },
47175    // @returns Parsley field computed value that could be overrided or configured in DOM
47176    getValue: function getValue() {
47177      var value; // Value could be overriden in DOM or with explicit options
47178
47179      if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val(); // Handle wrong DOM or configurations
47180
47181      if ('undefined' === typeof value || null === value) return '';
47182      return this._handleWhitespace(value);
47183    },
47184    // Reset UI
47185    reset: function reset() {
47186      this._resetUI();
47187
47188      return this._trigger('reset');
47189    },
47190    // Destroy Parsley instance (+ UI)
47191    destroy: function destroy() {
47192      // Field case: emit destroy event to clean UI and then destroy stored instance
47193      this._destroyUI();
47194
47195      this.$element.removeData('Parsley');
47196      this.$element.removeData('FieldMultiple');
47197
47198      this._trigger('destroy');
47199    },
47200    // Actualize options and rebind constraints
47201    refresh: function refresh() {
47202      this._refreshConstraints();
47203
47204      return this;
47205    },
47206    _refreshConstraints: function _refreshConstraints() {
47207      return this.actualizeOptions()._bindConstraints();
47208    },
47209    refreshConstraints: function refreshConstraints() {
47210      Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh");
47211      return this.refresh();
47212    },
47213
47214    /**
47215    * Add a new constraint to a field
47216    *
47217    * @param {String}   name
47218    * @param {Mixed}    requirements      optional
47219    * @param {Number}   priority          optional
47220    * @param {Boolean}  isDomConstraint   optional
47221    */
47222    addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
47223      if (window.Parsley._validatorRegistry.validators[name]) {
47224        var constraint = new Constraint(this, name, requirements, priority, isDomConstraint); // if constraint already exist, delete it and push new version
47225
47226        if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
47227        this.constraints.push(constraint);
47228        this.constraintsByName[constraint.name] = constraint;
47229      }
47230
47231      return this;
47232    },
47233    // Remove a constraint
47234    removeConstraint: function removeConstraint(name) {
47235      for (var i = 0; i < this.constraints.length; i++) {
47236        if (name === this.constraints[i].name) {
47237          this.constraints.splice(i, 1);
47238          break;
47239        }
47240      }
47241
47242      delete this.constraintsByName[name];
47243      return this;
47244    },
47245    // Update a constraint (Remove + re-add)
47246    updateConstraint: function updateConstraint(name, parameters, priority) {
47247      return this.removeConstraint(name).addConstraint(name, parameters, priority);
47248    },
47249    // # Internals
47250    // Internal only.
47251    // Bind constraints from config + options + DOM
47252    _bindConstraints: function _bindConstraints() {
47253      var constraints = [];
47254      var constraintsByName = {}; // clean all existing DOM constraints to only keep javascript user constraints
47255
47256      for (var i = 0; i < this.constraints.length; i++) {
47257        if (false === this.constraints[i].isDomConstraint) {
47258          constraints.push(this.constraints[i]);
47259          constraintsByName[this.constraints[i].name] = this.constraints[i];
47260        }
47261      }
47262
47263      this.constraints = constraints;
47264      this.constraintsByName = constraintsByName; // then re-add Parsley DOM-API constraints
47265
47266      for (var name in this.options) {
47267        this.addConstraint(name, this.options[name], undefined, true);
47268      } // finally, bind special HTML5 constraints
47269
47270
47271      return this._bindHtml5Constraints();
47272    },
47273    // Internal only.
47274    // Bind specific HTML5 constraints to be HTML5 compliant
47275    _bindHtml5Constraints: function _bindHtml5Constraints() {
47276      // html5 required
47277      if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true); // html5 pattern
47278
47279      if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true); // range
47280
47281      var min = this.element.getAttribute('min');
47282      var max = this.element.getAttribute('max');
47283      if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true); // HTML5 min
47284      else if (null !== min) this.addConstraint('min', min, undefined, true); // HTML5 max
47285        else if (null !== max) this.addConstraint('max', max, undefined, true); // length
47286
47287      if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true); // HTML5 minlength
47288      else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true); // HTML5 maxlength
47289        else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true); // html5 types
47290
47291      var type = Utils.getType(this.element); // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
47292
47293      if ('number' === type) {
47294        return this.addConstraint('type', ['number', {
47295          step: this.element.getAttribute('step') || '1',
47296          base: min || this.element.getAttribute('value')
47297        }], undefined, true); // Regular other HTML5 supported types
47298      } else if (/^(email|url|range|date)$/i.test(type)) {
47299        return this.addConstraint('type', type, undefined, true);
47300      }
47301
47302      return this;
47303    },
47304    // Internal only.
47305    // Field is required if have required constraint without `false` value
47306    _isRequired: function _isRequired() {
47307      if ('undefined' === typeof this.constraintsByName.required) return false;
47308      return false !== this.constraintsByName.required.requirements;
47309    },
47310    // Internal only.
47311    // Shortcut to trigger an event
47312    _trigger: function _trigger(eventName) {
47313      return this.trigger('field:' + eventName);
47314    },
47315    // Internal only
47316    // Handles whitespace in a value
47317    // Use `data-parsley-whitespace="squish"` to auto squish input value
47318    // Use `data-parsley-whitespace="trim"` to auto trim input value
47319    _handleWhitespace: function _handleWhitespace(value) {
47320      if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
47321      if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
47322      if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
47323      return value;
47324    },
47325    _isDateInput: function _isDateInput() {
47326      var c = this.constraintsByName.type;
47327      return c && c.requirements === 'date';
47328    },
47329    // Internal only.
47330    // Returns the constraints, grouped by descending priority.
47331    // The result is thus an array of arrays of constraints.
47332    _getGroupedConstraints: function _getGroupedConstraints() {
47333      if (false === this.options.priorityEnabled) return [this.constraints];
47334      var groupedConstraints = [];
47335      var index = {}; // Create array unique of priorities
47336
47337      for (var i = 0; i < this.constraints.length; i++) {
47338        var p = this.constraints[i].priority;
47339        if (!index[p]) groupedConstraints.push(index[p] = []);
47340        index[p].push(this.constraints[i]);
47341      } // Sort them by priority DESC
47342
47343
47344      groupedConstraints.sort(function (a, b) {
47345        return b[0].priority - a[0].priority;
47346      });
47347      return groupedConstraints;
47348    }
47349  };
47350
47351  var Multiple = function Multiple() {
47352    this.__class__ = 'FieldMultiple';
47353  };
47354
47355  Multiple.prototype = {
47356    // Add new `$element` sibling for multiple field
47357    addElement: function addElement($element) {
47358      this.$elements.push($element);
47359      return this;
47360    },
47361    // See `Field._refreshConstraints()`
47362    _refreshConstraints: function _refreshConstraints() {
47363      var fieldConstraints;
47364      this.constraints = []; // Select multiple special treatment
47365
47366      if (this.element.nodeName === 'SELECT') {
47367        this.actualizeOptions()._bindConstraints();
47368
47369        return this;
47370      } // Gather all constraints for each input in the multiple group
47371
47372
47373      for (var i = 0; i < this.$elements.length; i++) {
47374        // Check if element have not been dynamically removed since last binding
47375        if (!$('html').has(this.$elements[i]).length) {
47376          this.$elements.splice(i, 1);
47377          continue;
47378        }
47379
47380        fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints;
47381
47382        for (var j = 0; j < fieldConstraints.length; j++) {
47383          this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
47384        }
47385      }
47386
47387      return this;
47388    },
47389    // See `Field.getValue()`
47390    getValue: function getValue() {
47391      // Value could be overriden in DOM
47392      if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value; // Radio input case
47393
47394      if (this.element.nodeName === 'INPUT') {
47395        var type = Utils.getType(this.element);
47396        if (type === 'radio') return this._findRelated().filter(':checked').val() || ''; // checkbox input case
47397
47398        if (type === 'checkbox') {
47399          var values = [];
47400
47401          this._findRelated().filter(':checked').each(function () {
47402            values.push($(this).val());
47403          });
47404
47405          return values;
47406        }
47407      } // Select multiple case
47408
47409
47410      if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return []; // Default case that should never happen
47411
47412      return this.$element.val();
47413    },
47414    _init: function _init() {
47415      this.$elements = [this.$element];
47416      return this;
47417    }
47418  };
47419
47420  var Factory = function Factory(element, options, parsleyFormInstance) {
47421    this.element = element;
47422    this.$element = $(element); // If the element has already been bound, returns its saved Parsley instance
47423
47424    var savedparsleyFormInstance = this.$element.data('Parsley');
47425
47426    if (savedparsleyFormInstance) {
47427      // If the saved instance has been bound without a Form parent and there is one given in this call, add it
47428      if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
47429        savedparsleyFormInstance.parent = parsleyFormInstance;
47430
47431        savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
47432      }
47433
47434      if ('object' === _typeof(options)) {
47435        _extends(savedparsleyFormInstance.options, options);
47436      }
47437
47438      return savedparsleyFormInstance;
47439    } // Parsley must be instantiated with a DOM element or jQuery $element
47440
47441
47442    if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
47443    if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
47444    this.parent = parsleyFormInstance || window.Parsley;
47445    return this.init(options);
47446  };
47447
47448  Factory.prototype = {
47449    init: function init(options) {
47450      this.__class__ = 'Parsley';
47451      this.__version__ = '2.9.2';
47452      this.__id__ = Utils.generateID(); // Pre-compute options
47453
47454      this._resetOptions(options); // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
47455
47456
47457      if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm'); // Every other element is bound as a `Field` or `FieldMultiple`
47458
47459      return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
47460    },
47461    isMultiple: function isMultiple() {
47462      var type = Utils.getType(this.element);
47463      return type === 'radio' || type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
47464    },
47465    // Multiples fields are a real nightmare :(
47466    // Maybe some refactoring would be appreciated here...
47467    handleMultiple: function handleMultiple() {
47468      var _this = this;
47469
47470      var name;
47471      var parsleyMultipleInstance; // Handle multiple name
47472
47473      this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id'); // Special select multiple input
47474
47475      if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
47476        this.options.multiple = this.options.multiple || this.__id__;
47477        return this.bind('parsleyFieldMultiple'); // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
47478      } else if (!this.options.multiple) {
47479        Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
47480        return this;
47481      } // Remove special chars
47482
47483
47484      this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, ''); // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
47485
47486      if (name) {
47487        $('input[name="' + name + '"]').each(function (i, input) {
47488          var type = Utils.getType(input);
47489          if (type === 'radio' || type === 'checkbox') input.setAttribute(_this.options.namespace + 'multiple', _this.options.multiple);
47490        });
47491      } // Check here if we don't already have a related multiple instance saved
47492
47493
47494      var $previouslyRelated = this._findRelated();
47495
47496      for (var i = 0; i < $previouslyRelated.length; i++) {
47497        parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
47498
47499        if ('undefined' !== typeof parsleyMultipleInstance) {
47500          if (!this.$element.data('FieldMultiple')) {
47501            parsleyMultipleInstance.addElement(this.$element);
47502          }
47503
47504          break;
47505        }
47506      } // Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')`
47507      // And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance
47508
47509
47510      this.bind('parsleyField', true);
47511      return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
47512    },
47513    // Return proper `Form`, `Field` or `FieldMultiple`
47514    bind: function bind(type, doNotStore) {
47515      var parsleyInstance;
47516
47517      switch (type) {
47518        case 'parsleyForm':
47519          parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
47520          break;
47521
47522        case 'parsleyField':
47523          parsleyInstance = $.extend(new Field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
47524          break;
47525
47526        case 'parsleyFieldMultiple':
47527          parsleyInstance = $.extend(new Field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
47528          break;
47529
47530        default:
47531          throw new Error(type + 'is not a supported Parsley type');
47532      }
47533
47534      if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
47535
47536      if ('undefined' !== typeof doNotStore) {
47537        this.$element.data('FieldMultiple', parsleyInstance);
47538        return parsleyInstance;
47539      } // Store the freshly bound instance in a DOM element for later access using jQuery `data()`
47540
47541
47542      this.$element.data('Parsley', parsleyInstance); // Tell the world we have a new Form or Field instance!
47543
47544      parsleyInstance._actualizeTriggers();
47545
47546      parsleyInstance._trigger('init');
47547
47548      return parsleyInstance;
47549    }
47550  };
47551
47552  var vernums = $.fn.jquery.split('.');
47553
47554  if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
47555    throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
47556  }
47557
47558  if (!vernums.forEach) {
47559    Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
47560  } // Inherit `on`, `off` & `trigger` to Parsley:
47561
47562
47563  var Parsley = _extends(new Base(), {
47564    element: document,
47565    $element: $(document),
47566    actualizeOptions: null,
47567    _resetOptions: null,
47568    Factory: Factory,
47569    version: '2.9.2'
47570  }); // Supplement Field and Form with Base
47571  // This way, the constructors will have access to those methods
47572
47573
47574  _extends(Field.prototype, UI.Field, Base.prototype);
47575
47576  _extends(Form.prototype, UI.Form, Base.prototype); // Inherit actualizeOptions and _resetOptions:
47577
47578
47579  _extends(Factory.prototype, Base.prototype); // ### jQuery API
47580  // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
47581
47582
47583  $.fn.parsley = $.fn.psly = function (options) {
47584    if (this.length > 1) {
47585      var instances = [];
47586      this.each(function () {
47587        instances.push($(this).parsley(options));
47588      });
47589      return instances;
47590    } // Return undefined if applied to non existing DOM element
47591
47592
47593    if (this.length == 0) {
47594      return;
47595    }
47596
47597    return new Factory(this[0], options);
47598  }; // ### Field and Form extension
47599  // Ensure the extension is now defined if it wasn't previously
47600
47601
47602  if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {}; // ### Parsley config
47603  // Inherit from ParsleyDefault, and copy over any existing values
47604
47605  Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
47606  window.ParsleyConfig = Parsley.options; // Old way of accessing global options
47607  // ### Globals
47608
47609  window.Parsley = window.psly = Parsley;
47610  Parsley.Utils = Utils;
47611  window.ParsleyUtils = {};
47612  $.each(Utils, function (key, value) {
47613    if ('function' === typeof value) {
47614      window.ParsleyUtils[key] = function () {
47615        Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
47616        return Utils[key].apply(Utils, arguments);
47617      };
47618    }
47619  }); // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
47620
47621  var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
47622  window.ParsleyValidator = {};
47623  $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator hasValidator'.split(' '), function (i, method) {
47624    window.Parsley[method] = function () {
47625      return registry[method].apply(registry, arguments);
47626    };
47627
47628    window.ParsleyValidator[method] = function () {
47629      var _window$Parsley;
47630
47631      Utils.warnOnce("Accessing the method '".concat(method, "' through Validator is deprecated. Simply call 'window.Parsley.").concat(method, "(...)'"));
47632      return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
47633    };
47634  }); // ### UI
47635  // Deprecated global object
47636
47637  window.Parsley.UI = UI;
47638  window.ParsleyUI = {
47639    removeError: function removeError(instance, name, doNotUpdateClass) {
47640      var updateClass = true !== doNotUpdateClass;
47641      Utils.warnOnce("Accessing UI is deprecated. Call 'removeError' on the instance directly. Please comment in issue 1073 as to your need to call this method.");
47642      return instance.removeError(name, {
47643        updateClass: updateClass
47644      });
47645    },
47646    getErrorsMessages: function getErrorsMessages(instance) {
47647      Utils.warnOnce("Accessing UI is deprecated. Call 'getErrorsMessages' on the instance directly.");
47648      return instance.getErrorsMessages();
47649    }
47650  };
47651  $.each('addError updateError'.split(' '), function (i, method) {
47652    window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
47653      var updateClass = true !== doNotUpdateClass;
47654      Utils.warnOnce("Accessing UI is deprecated. Call '".concat(method, "' on the instance directly. Please comment in issue 1073 as to your need to call this method."));
47655      return instance[method](name, {
47656        message: message,
47657        assert: assert,
47658        updateClass: updateClass
47659      });
47660    };
47661  }); // ### PARSLEY auto-binding
47662  // Prevent it by setting `ParsleyConfig.autoBind` to `false`
47663
47664  if (false !== window.ParsleyConfig.autoBind) {
47665    $(function () {
47666      // Works only on `data-parsley-validate`.
47667      if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
47668    });
47669  }
47670
47671  var o = $({});
47672
47673  var deprecated = function deprecated() {
47674    Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
47675  }; // Returns an event handler that calls `fn` with the arguments it expects
47676
47677
47678  function adapt(fn, context) {
47679    // Store to allow unbinding
47680    if (!fn.parsleyAdaptedCallback) {
47681      fn.parsleyAdaptedCallback = function () {
47682        var args = Array.prototype.slice.call(arguments, 0);
47683        args.unshift(this);
47684        fn.apply(context || o, args);
47685      };
47686    }
47687
47688    return fn.parsleyAdaptedCallback;
47689  }
47690
47691  var eventPrefix = 'parsley:'; // Converts 'parsley:form:validate' into 'form:validate'
47692
47693  function eventName(name) {
47694    if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
47695    return name;
47696  } // $.listen is deprecated. Use Parsley.on instead.
47697
47698
47699  $.listen = function (name, callback) {
47700    var context;
47701    deprecated();
47702
47703    if ('object' === _typeof(arguments[1]) && 'function' === typeof arguments[2]) {
47704      context = arguments[1];
47705      callback = arguments[2];
47706    }
47707
47708    if ('function' !== typeof callback) throw new Error('Wrong parameters');
47709    window.Parsley.on(eventName(name), adapt(callback, context));
47710  };
47711
47712  $.listenTo = function (instance, name, fn) {
47713    deprecated();
47714    if (!(instance instanceof Field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
47715    if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
47716    instance.on(eventName(name), adapt(fn));
47717  };
47718
47719  $.unsubscribe = function (name, fn) {
47720    deprecated();
47721    if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
47722    window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
47723  };
47724
47725  $.unsubscribeTo = function (instance, name) {
47726    deprecated();
47727    if (!(instance instanceof Field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
47728    instance.off(eventName(name));
47729  };
47730
47731  $.unsubscribeAll = function (name) {
47732    deprecated();
47733    window.Parsley.off(eventName(name));
47734    $('form,input,textarea,select').each(function () {
47735      var instance = $(this).data('Parsley');
47736
47737      if (instance) {
47738        instance.off(eventName(name));
47739      }
47740    });
47741  }; // $.emit is deprecated. Use jQuery events instead.
47742
47743
47744  $.emit = function (name, instance) {
47745    var _instance;
47746
47747    deprecated();
47748    var instanceGiven = instance instanceof Field || instance instanceof Form;
47749    var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
47750    args.unshift(eventName(name));
47751
47752    if (!instanceGiven) {
47753      instance = window.Parsley;
47754    }
47755
47756    (_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
47757  };
47758
47759  $.extend(true, Parsley, {
47760    asyncValidators: {
47761      'default': {
47762        fn: function fn(xhr) {
47763          // By default, only status 2xx are deemed successful.
47764          // Note: we use status instead of state() because responses with status 200
47765          // but invalid messages (e.g. an empty body for content type set to JSON) will
47766          // result in state() === 'rejected'.
47767          return xhr.status >= 200 && xhr.status < 300;
47768        },
47769        url: false
47770      },
47771      reverse: {
47772        fn: function fn(xhr) {
47773          // If reverse option is set, a failing ajax request is considered successful
47774          return xhr.status < 200 || xhr.status >= 300;
47775        },
47776        url: false
47777      }
47778    },
47779    addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
47780      Parsley.asyncValidators[name] = {
47781        fn: fn,
47782        url: url || false,
47783        options: options || {}
47784      };
47785      return this;
47786    }
47787  });
47788  Parsley.addValidator('remote', {
47789    requirementType: {
47790      '': 'string',
47791      'validator': 'string',
47792      'reverse': 'boolean',
47793      'options': 'object'
47794    },
47795    validateString: function validateString(value, url, options, instance) {
47796      var data = {};
47797      var ajaxOptions;
47798      var csr;
47799      var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
47800      if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
47801      url = Parsley.asyncValidators[validator].url || url; // Fill current value
47802
47803      if (url.indexOf('{value}') > -1) {
47804        url = url.replace('{value}', encodeURIComponent(value));
47805      } else {
47806        data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
47807      } // Merge options passed in from the function with the ones in the attribute
47808
47809
47810      var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options); // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
47811
47812      ajaxOptions = $.extend(true, {}, {
47813        url: url,
47814        data: data,
47815        type: 'GET'
47816      }, remoteOptions); // Generate store key based on ajax options
47817
47818      instance.trigger('field:ajaxoptions', instance, ajaxOptions);
47819      csr = $.param(ajaxOptions); // Initialise querry cache
47820
47821      if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {}; // Try to retrieve stored xhr
47822
47823      var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
47824
47825      var handleXhr = function handleXhr() {
47826        var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
47827        if (!result) // Map falsy results to rejected promise
47828          result = $.Deferred().reject();
47829        return $.when(result);
47830      };
47831
47832      return xhr.then(handleXhr, handleXhr);
47833    },
47834    priority: -1
47835  });
47836  Parsley.on('form:submit', function () {
47837    Parsley._remoteCache = {};
47838  });
47839
47840  Base.prototype.addAsyncValidator = function () {
47841    Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
47842    return Parsley.addAsyncValidator.apply(Parsley, arguments);
47843  };
47844
47845  // This is included with the Parsley library itself,
47846  Parsley.addMessages('en', {
47847    defaultMessage: "This value seems to be invalid.",
47848    type: {
47849      email: "This value should be a valid email.",
47850      url: "This value should be a valid url.",
47851      number: "This value should be a valid number.",
47852      integer: "This value should be a valid integer.",
47853      digits: "This value should be digits.",
47854      alphanum: "This value should be alphanumeric."
47855    },
47856    notblank: "This value should not be blank.",
47857    required: "This value is required.",
47858    pattern: "This value seems to be invalid.",
47859    min: "This value should be greater than or equal to %s.",
47860    max: "This value should be lower than or equal to %s.",
47861    range: "This value should be between %s and %s.",
47862    minlength: "This value is too short. It should have %s characters or more.",
47863    maxlength: "This value is too long. It should have %s characters or fewer.",
47864    length: "This value length is invalid. It should be between %s and %s characters long.",
47865    mincheck: "You must select at least %s choices.",
47866    maxcheck: "You must select %s choices or fewer.",
47867    check: "You must select between %s and %s choices.",
47868    equalto: "This value should be the same.",
47869    euvatin: "It's not a valid VAT Identification Number."
47870  });
47871  Parsley.setLocale('en');
47872
47873  function InputEvent() {
47874    var _this = this;
47875
47876    var globals = window || global; // Slightly odd way construct our object. This way methods are force bound.
47877    // Used to test for duplicate library.
47878
47879    _extends(this, {
47880      // For browsers that do not support isTrusted, assumes event is native.
47881      isNativeEvent: function isNativeEvent(evt) {
47882        return evt.originalEvent && evt.originalEvent.isTrusted !== false;
47883      },
47884      fakeInputEvent: function fakeInputEvent(evt) {
47885        if (_this.isNativeEvent(evt)) {
47886          $(evt.target).trigger('input');
47887        }
47888      },
47889      misbehaves: function misbehaves(evt) {
47890        if (_this.isNativeEvent(evt)) {
47891          _this.behavesOk(evt);
47892
47893          $(document).on('change.inputevent', evt.data.selector, _this.fakeInputEvent);
47894
47895          _this.fakeInputEvent(evt);
47896        }
47897      },
47898      behavesOk: function behavesOk(evt) {
47899        if (_this.isNativeEvent(evt)) {
47900          $(document) // Simply unbinds the testing handler
47901          .off('input.inputevent', evt.data.selector, _this.behavesOk).off('change.inputevent', evt.data.selector, _this.misbehaves);
47902        }
47903      },
47904      // Bind the testing handlers
47905      install: function install() {
47906        if (globals.inputEventPatched) {
47907          return;
47908        }
47909
47910        globals.inputEventPatched = '0.0.3';
47911
47912        for (var _i = 0, _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]']; _i < _arr.length; _i++) {
47913          var selector = _arr[_i];
47914          $(document).on('input.inputevent', selector, {
47915            selector: selector
47916          }, _this.behavesOk).on('change.inputevent', selector, {
47917            selector: selector
47918          }, _this.misbehaves);
47919        }
47920      },
47921      uninstall: function uninstall() {
47922        delete globals.inputEventPatched;
47923        $(document).off('.inputevent');
47924      }
47925    });
47926  }
47927  var inputevent = new InputEvent();
47928
47929  inputevent.install();
47930
47931  return Parsley;
47932
47933})));
47934//# sourceMappingURL=parsley.js.map
47935
vendor: 40,580 bytes, lines 47936-49035
47936/*
47937== malihu jquery custom scrollbar plugin == 
47938Version: 3.1.5 
47939Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller 
47940Author: malihu
47941Author URI: http://manos.malihu.gr
47942License: MIT License (MIT)
47943*/
47944
47945/*
47946Copyright Manos Malihutsakis (email: [email protected])
47947
47948Permission is hereby granted, free of charge, to any person obtaining a copy
47949of this software and associated documentation files (the "Software"), to deal
47950in the Software without restriction, including without limitation the rights
47951to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
47952copies of the Software, and to permit persons to whom the Software is
47953furnished to do so, subject to the following conditions:
47954
47955The above copyright notice and this permission notice shall be included in
47956all copies or substantial portions of the Software.
47957
47958THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47959IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47960FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47961AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47962LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47963OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47964THE SOFTWARE.
47965*/
47966
47967/*
47968The code below is fairly long, fully commented and should be normally used in development. 
47969For production, use either the minified jquery.mCustomScrollbar.min.js script or 
47970the production-ready jquery.mCustomScrollbar.concat.min.js which contains the plugin 
47971and dependencies (minified). 
47972*/
47973
47974(function(factory){
47975	if(typeof define==="function" && define.amd){
47976		define(["jquery"],factory);
47977	}else if(typeof module!=="undefined" && module.exports){
47978		module.exports=factory;
47979	}else{
47980		factory(jQuery,window,document);
47981	}
47982}(function($){
47983(function(init){
47984	var _rjs=typeof define==="function" && define.amd, /* RequireJS */
47985		_njs=typeof module !== "undefined" && module.exports, /* NodeJS */
47986		_dlp=("https:"==document.location.protocol) ? "https:" : "http:", /* location protocol */
47987		_url="cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js";
47988	if(!_rjs){
47989		if(_njs){
47990			require("jquery-mousewheel")($);
47991		}else{
47992			/* load jquery-mousewheel plugin (via CDN) if it's not present or not loaded via RequireJS 
47993			(works when mCustomScrollbar fn is called on window load) */
47994			$.event.special.mousewheel || $("head").append(decodeURI("%3Cscript src="+_dlp+"//"+_url+"%3E%3C/script%3E"));
47995		}
47996	}
47997	init();
47998}(function(){
47999	
48000	/* 
48001	----------------------------------------
48002	PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S) 
48003	----------------------------------------
48004	*/
48005	
48006	var pluginNS="mCustomScrollbar",
48007		pluginPfx="mCS",
48008		defaultSelector=".mCustomScrollbar",
48009	
48010	
48011		
48012	
48013	
48014	/* 
48015	----------------------------------------
48016	DEFAULT OPTIONS 
48017	----------------------------------------
48018	*/
48019	
48020		defaults={
48021			/*
48022			set element/content width/height programmatically 
48023			values: boolean, pixels, percentage 
48024				option						default
48025				-------------------------------------
48026				setWidth					false
48027				setHeight					false
48028			*/
48029			/*
48030			set the initial css top property of content  
48031			values: string (e.g. "-100px", "10%" etc.)
48032			*/
48033			setTop:0,
48034			/*
48035			set the initial css left property of content  
48036			values: string (e.g. "-100px", "10%" etc.)
48037			*/
48038			setLeft:0,
48039			/* 
48040			scrollbar axis (vertical and/or horizontal scrollbars) 
48041			values (string): "y", "x", "yx"
48042			*/
48043			axis:"y",
48044			/*
48045			position of scrollbar relative to content  
48046			values (string): "inside", "outside" ("outside" requires elements with position:relative)
48047			*/
48048			scrollbarPosition:"inside",
48049			/*
48050			scrolling inertia
48051			values: integer (milliseconds)
48052			*/
48053			scrollInertia:950,
48054			/* 
48055			auto-adjust scrollbar dragger length
48056			values: boolean
48057			*/
48058			autoDraggerLength:true,
48059			/*
48060			auto-hide scrollbar when idle 
48061			values: boolean
48062				option						default
48063				-------------------------------------
48064				autoHideScrollbar			false
48065			*/
48066			/*
48067			auto-expands scrollbar on mouse-over and dragging
48068			values: boolean
48069				option						default
48070				-------------------------------------
48071				autoExpandScrollbar			false
48072			*/
48073			/*
48074			always show scrollbar, even when there's nothing to scroll 
48075			values: integer (0=disable, 1=always show dragger rail and buttons, 2=always show dragger rail, dragger and buttons), boolean
48076			*/
48077			alwaysShowScrollbar:0,
48078			/*
48079			scrolling always snaps to a multiple of this number in pixels
48080			values: integer, array ([y,x])
48081				option						default
48082				-------------------------------------
48083				snapAmount					null
48084			*/
48085			/*
48086			when snapping, snap with this number in pixels as an offset 
48087			values: integer
48088			*/
48089			snapOffset:0,
48090			/* 
48091			mouse-wheel scrolling
48092			*/
48093			mouseWheel:{
48094				/* 
48095				enable mouse-wheel scrolling
48096				values: boolean
48097				*/
48098				enable:true,
48099				/* 
48100				scrolling amount in pixels
48101				values: "auto", integer 
48102				*/
48103				scrollAmount:"auto",
48104				/* 
48105				mouse-wheel scrolling axis 
48106				the default scrolling direction when both vertical and horizontal scrollbars are present 
48107				values (string): "y", "x" 
48108				*/
48109				axis:"y",
48110				/* 
48111				prevent the default behaviour which automatically scrolls the parent element(s) when end of scrolling is reached 
48112				values: boolean
48113					option						default
48114					-------------------------------------
48115					preventDefault				null
48116				*/
48117				/*
48118				the reported mouse-wheel delta value. The number of lines (translated to pixels) one wheel notch scrolls.  
48119				values: "auto", integer 
48120				"auto" uses the default OS/browser value 
48121				*/
48122				deltaFactor:"auto",
48123				/*
48124				normalize mouse-wheel delta to -1 or 1 (disables mouse-wheel acceleration) 
48125				values: boolean
48126					option						default
48127					-------------------------------------
48128					normalizeDelta				null
48129				*/
48130				/*
48131				invert mouse-wheel scrolling direction 
48132				values: boolean
48133					option						default
48134					-------------------------------------
48135					invert						null
48136				*/
48137				/*
48138				the tags that disable mouse-wheel when cursor is over them
48139				*/
48140				disableOver:["select","option","keygen","datalist","textarea"]
48141			},
48142			/* 
48143			scrollbar buttons
48144			*/
48145			scrollButtons:{ 
48146				/*
48147				enable scrollbar buttons
48148				values: boolean
48149					option						default
48150					-------------------------------------
48151					enable						null
48152				*/
48153				/*
48154				scrollbar buttons scrolling type 
48155				values (string): "stepless", "stepped"
48156				*/
48157				scrollType:"stepless",
48158				/*
48159				scrolling amount in pixels
48160				values: "auto", integer 
48161				*/
48162				scrollAmount:"auto"
48163				/*
48164				tabindex of the scrollbar buttons
48165				values: false, integer
48166					option						default
48167					-------------------------------------
48168					tabindex					null
48169				*/
48170			},
48171			/* 
48172			keyboard scrolling
48173			*/
48174			keyboard:{ 
48175				/*
48176				enable scrolling via keyboard
48177				values: boolean
48178				*/
48179				enable:true,
48180				/*
48181				keyboard scrolling type 
48182				values (string): "stepless", "stepped"
48183				*/
48184				scrollType:"stepless",
48185				/*
48186				scrolling amount in pixels
48187				values: "auto", integer 
48188				*/
48189				scrollAmount:"auto"
48190			},
48191			/*
48192			enable content touch-swipe scrolling 
48193			values: boolean, integer, string (number)
48194			integer values define the axis-specific minimum amount required for scrolling momentum
48195			*/
48196			contentTouchScroll:25,
48197			/*
48198			enable/disable document (default) touch-swipe scrolling 
48199			*/
48200			documentTouchScroll:true,
48201			/*
48202			advanced option parameters
48203			*/
48204			advanced:{
48205				/*
48206				auto-expand content horizontally (for "x" or "yx" axis) 
48207				values: boolean, integer (the value 2 forces the non scrollHeight/scrollWidth method, the value 3 forces the scrollHeight/scrollWidth method)
48208					option						default
48209					-------------------------------------
48210					autoExpandHorizontalScroll	null
48211				*/
48212				/*
48213				auto-scroll to elements with focus
48214				*/
48215				autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']",
48216				/*
48217				auto-update scrollbars on content, element or viewport resize 
48218				should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc. 
48219				values: boolean
48220				*/
48221				updateOnContentResize:true,
48222				/*
48223				auto-update scrollbars each time each image inside the element is fully loaded 
48224				values: "auto", boolean
48225				*/
48226				updateOnImageLoad:"auto",
48227				/*
48228				auto-update scrollbars based on the amount and size changes of specific selectors 
48229				useful when you need to update the scrollbar(s) automatically, each time a type of element is added, removed or changes its size 
48230				values: boolean, string (e.g. "ul li" will auto-update scrollbars each time list-items inside the element are changed) 
48231				a value of true (boolean) will auto-update scrollbars each time any element is changed
48232					option						default
48233					-------------------------------------
48234					updateOnSelectorChange		null
48235				*/
48236				/*
48237				extra selectors that'll allow scrollbar dragging upon mousemove/up, pointermove/up, touchend etc. (e.g. "selector-1, selector-2")
48238					option						default
48239					-------------------------------------
48240					extraDraggableSelectors		null
48241				*/
48242				/*
48243				extra selectors that'll release scrollbar dragging upon mouseup, pointerup, touchend etc. (e.g. "selector-1, selector-2")
48244					option						default
48245					-------------------------------------
48246					releaseDraggableSelectors	null
48247				*/
48248				/*
48249				auto-update timeout 
48250				values: integer (milliseconds)
48251				*/
48252				autoUpdateTimeout:60
48253			},
48254			/* 
48255			scrollbar theme 
48256			values: string (see CSS/plugin URI for a list of ready-to-use themes)
48257			*/
48258			theme:"light",
48259			/*
48260			user defined callback functions
48261			*/
48262			callbacks:{
48263				/*
48264				Available callbacks: 
48265					callback					default
48266					-------------------------------------
48267					onCreate					null
48268					onInit						null
48269					onScrollStart				null
48270					onScroll					null
48271					onTotalScroll				null
48272					onTotalScrollBack			null
48273					whileScrolling				null
48274					onOverflowY					null
48275					onOverflowX					null
48276					onOverflowYNone				null
48277					onOverflowXNone				null
48278					onImageLoad					null
48279					onSelectorChange			null
48280					onBeforeUpdate				null
48281					onUpdate					null
48282				*/
48283				onTotalScrollOffset:0,
48284				onTotalScrollBackOffset:0,
48285				alwaysTriggerOffsets:true
48286			}
48287			/*
48288			add scrollbar(s) on all elements matching the current selector, now and in the future 
48289			values: boolean, string 
48290			string values: "on" (enable), "once" (disable after first invocation), "off" (disable)
48291			liveSelector values: string (selector)
48292				option						default
48293				-------------------------------------
48294				live						false
48295				liveSelector				null
48296			*/
48297		},
48298	
48299	
48300	
48301	
48302	
48303	/* 
48304	----------------------------------------
48305	VARS, CONSTANTS 
48306	----------------------------------------
48307	*/
48308	
48309		totalInstances=0, /* plugin instances amount */
48310		liveTimers={}, /* live option timers */
48311		oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */
48312		touchActive=false,touchable, /* global touch vars (for touch and pointer events) */
48313		/* general plugin classes */
48314		classes=[
48315			"mCSB_dragger_onDrag","mCSB_scrollTools_onDrag","mCS_img_loaded","mCS_disabled","mCS_destroyed","mCS_no_scrollbar",
48316			"mCS-autoHide","mCS-dir-rtl","mCS_no_scrollbar_y","mCS_no_scrollbar_x","mCS_y_hidden","mCS_x_hidden","mCSB_draggerContainer",
48317			"mCSB_buttonUp","mCSB_buttonDown","mCSB_buttonLeft","mCSB_buttonRight"
48318		],
48319		
48320	
48321	
48322	
48323	
48324	/* 
48325	----------------------------------------
48326	METHODS 
48327	----------------------------------------
48328	*/
48329	
48330		methods={
48331			
48332			/* 
48333			plugin initialization method 
48334			creates the scrollbar(s), plugin data object and options
48335			----------------------------------------
48336			*/
48337			
48338			init:function(options){
48339				
48340				var options=$.extend(true,{},defaults,options),
48341					selector=_selector.call(this); /* validate selector */
48342				
48343				/* 
48344				if live option is enabled, monitor for elements matching the current selector and 
48345				apply scrollbar(s) when found (now and in the future) 
48346				*/
48347				if(options.live){
48348					var liveSelector=options.liveSelector || this.selector || defaultSelector, /* live selector(s) */
48349						$liveSelector=$(liveSelector); /* live selector(s) as jquery object */
48350					if(options.live==="off"){
48351						/* 
48352						disable live if requested 
48353						usage: $(selector).mCustomScrollbar({live:"off"}); 
48354						*/
48355						removeLiveTimers(liveSelector);
48356						return;
48357					}
48358					liveTimers[liveSelector]=setTimeout(function(){
48359						/* call mCustomScrollbar fn on live selector(s) every half-second */
48360						$liveSelector.mCustomScrollbar(options);
48361						if(options.live==="once" && $liveSelector.length){
48362							/* disable live after first invocation */
48363							removeLiveTimers(liveSelector);
48364						}
48365					},500);
48366				}else{
48367					removeLiveTimers(liveSelector);
48368				}
48369				
48370				/* options backward compatibility (for versions < 3.0.0) and normalization */
48371				options.setWidth=(options.set_width) ? options.set_width : options.setWidth;
48372				options.setHeight=(options.set_height) ? options.set_height : options.setHeight;
48373				options.axis=(options.horizontalScroll) ? "x" : _findAxis(options.axis);
48374				options.scrollInertia=options.scrollInertia>0 && options.scrollInertia<17 ? 17 : options.scrollInertia;
48375				if(typeof options.mouseWheel!=="object" &&  options.mouseWheel==true){ /* old school mouseWheel option (non-object) */
48376					options.mouseWheel={enable:true,scrollAmount:"auto",axis:"y",preventDefault:false,deltaFactor:"auto",normalizeDelta:false,invert:false}
48377				}
48378				options.mouseWheel.scrollAmount=!options.mouseWheelPixels ? options.mouseWheel.scrollAmount : options.mouseWheelPixels;
48379				options.mouseWheel.normalizeDelta=!options.advanced.normalizeMouseWheelDelta ? options.mouseWheel.normalizeDelta : options.advanced.normalizeMouseWheelDelta;
48380				options.scrollButtons.scrollType=_findScrollButtonsType(options.scrollButtons.scrollType); 
48381				
48382				_theme(options); /* theme-specific options */
48383				
48384				/* plugin constructor */
48385				return $(selector).each(function(){
48386					
48387					var $this=$(this);
48388					
48389					if(!$this.data(pluginPfx)){ /* prevent multiple instantiations */
48390					
48391						/* store options and create objects in jquery data */
48392						$this.data(pluginPfx,{
48393							idx:++totalInstances, /* instance index */
48394							opt:options, /* options */
48395							scrollRatio:{y:null,x:null}, /* scrollbar to content ratio */
48396							overflowed:null, /* overflowed axis */
48397							contentReset:{y:null,x:null}, /* object to check when content resets */
48398							bindEvents:false, /* object to check if events are bound */
48399							tweenRunning:false, /* object to check if tween is running */
48400							sequential:{}, /* sequential scrolling object */
48401							langDir:$this.css("direction"), /* detect/store direction (ltr or rtl) */
48402							cbOffsets:null, /* object to check whether callback offsets always trigger */
48403							/* 
48404							object to check how scrolling events where last triggered 
48405							"internal" (default - triggered by this script), "external" (triggered by other scripts, e.g. via scrollTo method) 
48406							usage: object.data("mCS").trigger
48407							*/
48408							trigger:null,
48409							/* 
48410							object to check for changes in elements in order to call the update method automatically 
48411							*/
48412							poll:{size:{o:0,n:0},img:{o:0,n:0},change:{o:0,n:0}}
48413						});
48414						
48415						var d=$this.data(pluginPfx),o=d.opt,
48416							/* HTML data attributes */
48417							htmlDataAxis=$this.data("mcs-axis"),htmlDataSbPos=$this.data("mcs-scrollbar-position"),htmlDataTheme=$this.data("mcs-theme");
48418						 
48419						if(htmlDataAxis){o.axis=htmlDataAxis;} /* usage example: data-mcs-axis="y" */
48420						if(htmlDataSbPos){o.scrollbarPosition=htmlDataSbPos;} /* usage example: data-mcs-scrollbar-position="outside" */
48421						if(htmlDataTheme){ /* usage example: data-mcs-theme="minimal" */
48422							o.theme=htmlDataTheme;
48423							_theme(o); /* theme-specific options */
48424						}
48425						
48426						_pluginMarkup.call(this); /* add plugin markup */
48427						
48428						if(d && o.callbacks.onCreate && typeof o.callbacks.onCreate==="function"){o.callbacks.onCreate.call(this);} /* callbacks: onCreate */
48429						
48430						$("#mCSB_"+d.idx+"_container img:not(."+classes[2]+")").addClass(classes[2]); /* flag loaded images */
48431						
48432						methods.update.call(null,$this); /* call the update method */
48433					
48434					}
48435					
48436				});
48437				
48438			},
48439			/* ---------------------------------------- */
48440			
48441			
48442			
48443			/* 
48444			plugin update method 
48445			updates content and scrollbar(s) values, events and status 
48446			----------------------------------------
48447			usage: $(selector).mCustomScrollbar("update");
48448			*/
48449			
48450			update:function(el,cb){
48451				
48452				var selector=el || _selector.call(this); /* validate selector */
48453				
48454				return $(selector).each(function(){
48455					
48456					var $this=$(this);
48457					
48458					if($this.data(pluginPfx)){ /* check if plugin has initialized */
48459						
48460						var d=$this.data(pluginPfx),o=d.opt,
48461							mCSB_container=$("#mCSB_"+d.idx+"_container"),
48462							mCustomScrollBox=$("#mCSB_"+d.idx),
48463							mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
48464						
48465						if(!mCSB_container.length){return;}
48466						
48467						if(d.tweenRunning){_stop($this);} /* stop any running tweens while updating */
48468						
48469						if(cb && d && o.callbacks.onBeforeUpdate && typeof o.callbacks.onBeforeUpdate==="function"){o.callbacks.onBeforeUpdate.call(this);} /* callbacks: onBeforeUpdate */
48470						
48471						/* if element was disabled or destroyed, remove class(es) */
48472						if($this.hasClass(classes[3])){$this.removeClass(classes[3]);}
48473						if($this.hasClass(classes[4])){$this.removeClass(classes[4]);}
48474						
48475						/* css flexbox fix, detect/set max-height */
48476						mCustomScrollBox.css("max-height","none");
48477						if(mCustomScrollBox.height()!==$this.height()){mCustomScrollBox.css("max-height",$this.height());}
48478						
48479						_expandContentHorizontally.call(this); /* expand content horizontally */
48480						
48481						if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){
48482							mCSB_container.css("width",_contentWidth(mCSB_container));
48483						}
48484						
48485						d.overflowed=_overflowed.call(this); /* determine if scrolling is required */
48486						
48487						_scrollbarVisibility.call(this); /* show/hide scrollbar(s) */
48488						
48489						/* auto-adjust scrollbar dragger length analogous to content */
48490						if(o.autoDraggerLength){_setDraggerLength.call(this);}
48491						
48492						_scrollRatio.call(this); /* calculate and store scrollbar to content ratio */
48493						
48494						_bindEvents.call(this); /* bind scrollbar events */
48495						
48496						/* reset scrolling position and/or events */
48497						var to=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)];
48498						if(o.axis!=="x"){ /* y/yx axis */
48499							if(!d.overflowed[0]){ /* y scrolling is not required */
48500								_resetContentPosition.call(this); /* reset content position */
48501								if(o.axis==="y"){
48502									_unbindEvents.call(this);
48503								}else if(o.axis==="yx" && d.overflowed[1]){
48504									_scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"});
48505								}
48506							}else if(mCSB_dragger[0].height()>mCSB_dragger[0].parent().height()){
48507								_resetContentPosition.call(this); /* reset content position */
48508							}else{ /* y scrolling is required */
48509								_scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"});
48510								d.contentReset.y=null;
48511							}
48512						}
48513						if(o.axis!=="y"){ /* x/yx axis */
48514							if(!d.overflowed[1]){ /* x scrolling is not required */
48515								_resetContentPosition.call(this); /* reset content position */
48516								if(o.axis==="x"){
48517									_unbindEvents.call(this);
48518								}else if(o.axis==="yx" && d.overflowed[0]){
48519									_scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"});
48520								}
48521							}else if(mCSB_dragger[1].width()>mCSB_dragger[1].parent().width()){
48522								_resetContentPosition.call(this); /* reset content position */
48523							}else{ /* x scrolling is required */
48524								_scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"});
48525								d.contentReset.x=null;
48526							}
48527						}
48528						
48529						/* callbacks: onImageLoad, onSelectorChange, onUpdate */
48530						if(cb && d){
48531							if(cb===2 && o.callbacks.onImageLoad && typeof o.callbacks.onImageLoad==="function"){
48532								o.callbacks.onImageLoad.call(this);
48533							}else if(cb===3 && o.callbacks.onSelectorChange && typeof o.callbacks.onSelectorChange==="function"){
48534								o.callbacks.onSelectorChange.call(this);
48535							}else if(o.callbacks.onUpdate && typeof o.callbacks.onUpdate==="function"){
48536								o.callbacks.onUpdate.call(this);
48537							}
48538						}
48539						
48540						_autoUpdate.call(this); /* initialize automatic updating (for dynamic content, fluid layouts etc.) */
48541						
48542					}
48543					
48544				});
48545				
48546			},
48547			/* ---------------------------------------- */
48548			
48549			
48550			
48551			/* 
48552			plugin scrollTo method 
48553			triggers a scrolling event to a specific value
48554			----------------------------------------
48555			usage: $(selector).mCustomScrollbar("scrollTo",value,options);
48556			*/
48557		
48558			scrollTo:function(val,options){
48559				
48560				/* prevent silly things like $(selector).mCustomScrollbar("scrollTo",undefined); */
48561				if(typeof val=="undefined" || val==null){return;}
48562				
48563				var selector=_selector.call(this); /* validate selector */
48564				
48565				return $(selector).each(function(){
48566					
48567					var $this=$(this);
48568					
48569					if($this.data(pluginPfx)){ /* check if plugin has initialized */
48570					
48571						var d=$this.data(pluginPfx),o=d.opt,
48572							/* method default options */
48573							methodDefaults={
48574								trigger:"external", /* method is by default triggered externally (e.g. from other scripts) */
48575								scrollInertia:o.scrollInertia, /* scrolling inertia (animation duration) */
48576								scrollEasing:"mcsEaseInOut", /* animation easing */
48577								moveDragger:false, /* move dragger instead of content */
48578								timeout:60, /* scroll-to delay */
48579								callbacks:true, /* enable/disable callbacks */
48580								onStart:true,
48581								onUpdate:true,
48582								onComplete:true
48583							},
48584							methodOptions=$.extend(true,{},methodDefaults,options),
48585							to=_arr.call(this,val),dur=methodOptions.scrollInertia>0 && methodOptions.scrollInertia<17 ? 17 : methodOptions.scrollInertia;
48586						
48587						/* translate yx values to actual scroll-to positions */
48588						to[0]=_to.call(this,to[0],"y");
48589						to[1]=_to.call(this,to[1],"x");
48590						
48591						/* 
48592						check if scroll-to value moves the dragger instead of content. 
48593						Only pixel values apply on dragger (e.g. 100, "100px", "-=100" etc.) 
48594						*/
48595						if(methodOptions.moveDragger){
48596							to[0]*=d.scrollRatio.y;
48597							to[1]*=d.scrollRatio.x;
48598						}
48599						
48600						methodOptions.dur=_isTabHidden() ? 0 : dur; //skip animations if browser tab is hidden
48601						
48602						setTimeout(function(){ 
48603							/* do the scrolling */
48604							if(to[0]!==null && typeof to[0]!=="undefined" && o.axis!=="x" && d.overflowed[0]){ /* scroll y */
48605								methodOptions.dir="y";
48606								methodOptions.overwrite="all";
48607								_scrollTo($this,to[0].toString(),methodOptions);
48608							}
48609							if(to[1]!==null && typeof to[1]!=="undefined" && o.axis!=="y" && d.overflowed[1]){ /* scroll x */
48610								methodOptions.dir="x";
48611								methodOptions.overwrite="none";
48612								_scrollTo($this,to[1].toString(),methodOptions);
48613							}
48614						},methodOptions.timeout);
48615						
48616					}
48617					
48618				});
48619				
48620			},
48621			/* ---------------------------------------- */
48622			
48623			
48624			
48625			/*
48626			plugin stop method 
48627			stops scrolling animation
48628			----------------------------------------
48629			usage: $(selector).mCustomScrollbar("stop");
48630			*/
48631			stop:function(){
48632				
48633				var selector=_selector.call(this); /* validate selector */
48634				
48635				return $(selector).each(function(){
48636					
48637					var $this=$(this);
48638					
48639					if($this.data(pluginPfx)){ /* check if plugin has initialized */
48640										
48641						_stop($this);
48642					
48643					}
48644					
48645				});
48646				
48647			},
48648			/* ---------------------------------------- */
48649			
48650			
48651			
48652			/*
48653			plugin disable method 
48654			temporarily disables the scrollbar(s) 
48655			----------------------------------------
48656			usage: $(selector).mCustomScrollbar("disable",reset); 
48657			reset (boolean): resets content position to 0 
48658			*/
48659			disable:function(r){
48660				
48661				var selector=_selector.call(this); /* validate selector */
48662				
48663				return $(selector).each(function(){
48664					
48665					var $this=$(this);
48666					
48667					if($this.data(pluginPfx)){ /* check if plugin has initialized */
48668						
48669						var d=$this.data(pluginPfx);
48670						
48671						_autoUpdate.call(this,"remove"); /* remove automatic updating */
48672						
48673						_unbindEvents.call(this); /* unbind events */
48674						
48675						if(r){_resetContentPosition.call(this);} /* reset content position */
48676						
48677						_scrollbarVisibility.call(this,true); /* show/hide scrollbar(s) */
48678						
48679						$this.addClass(classes[3]); /* add disable class */
48680					
48681					}
48682					
48683				});
48684				
48685			},
48686			/* ---------------------------------------- */
48687			
48688			
48689			
48690			/*
48691			plugin destroy method 
48692			completely removes the scrollbar(s) and returns the element to its original state
48693			----------------------------------------
48694			usage: $(selector).mCustomScrollbar("destroy"); 
48695			*/
48696			destroy:function(){
48697				
48698				var selector=_selector.call(this); /* validate selector */
48699				
48700				return $(selector).each(function(){
48701					
48702					var $this=$(this);
48703					
48704					if($this.data(pluginPfx)){ /* check if plugin has initialized */
48705					
48706						var d=$this.data(pluginPfx),o=d.opt,
48707							mCustomScrollBox=$("#mCSB_"+d.idx),
48708							mCSB_container=$("#mCSB_"+d.idx+"_container"),
48709							scrollbar=$(".mCSB_"+d.idx+"_scrollbar");
48710					
48711						if(o.live){removeLiveTimers(o.liveSelector || $(selector).selector);} /* remove live timers */
48712						
48713						_autoUpdate.call(this,"remove"); /* remove automatic updating */
48714						
48715						_unbindEvents.call(this); /* unbind events */
48716						
48717						_resetContentPosition.call(this); /* reset content position */
48718						
48719						$this.removeData(pluginPfx); /* remove plugin data object */
48720						
48721						_delete(this,"mcs"); /* delete callbacks object */
48722						
48723						/* remove plugin markup */
48724						scrollbar.remove(); /* remove scrollbar(s) first (those can be either inside or outside plugin's inner wrapper) */
48725						mCSB_container.find("img."+classes[2]).removeClass(classes[2]); /* remove loaded images flag */
48726						mCustomScrollBox.replaceWith(mCSB_container.contents()); /* replace plugin's inner wrapper with the original content */
48727						/* remove plugin classes from the element and add destroy class */
48728						$this.removeClass(pluginNS+" _"+pluginPfx+"_"+d.idx+" "+classes[6]+" "+classes[7]+" "+classes[5]+" "+classes[3]).addClass(classes[4]);
48729					
48730					}
48731					
48732				});
48733				
48734			}
48735			/* ---------------------------------------- */
48736			
48737		},
48738	
48739	
48740	
48741	
48742		
48743	/* 
48744	----------------------------------------
48745	FUNCTIONS
48746	----------------------------------------
48747	*/
48748	
48749		/* validates selector (if selector is invalid or undefined uses the default one) */
48750		_selector=function(){
48751			return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this;
48752		},
48753		/* -------------------- */
48754		
48755		
48756		/* changes options according to theme */
48757		_theme=function(obj){
48758			var fixedSizeScrollbarThemes=["rounded","rounded-dark","rounded-dots","rounded-dots-dark"],
48759				nonExpandedScrollbarThemes=["rounded-dots","rounded-dots-dark","3d","3d-dark","3d-thick","3d-thick-dark","inset","inset-dark","inset-2","inset-2-dark","inset-3","inset-3-dark"],
48760				disabledScrollButtonsThemes=["minimal","minimal-dark"],
48761				enabledAutoHideScrollbarThemes=["minimal","minimal-dark"],
48762				scrollbarPositionOutsideThemes=["minimal","minimal-dark"];
48763			obj.autoDraggerLength=$.inArray(obj.theme,fixedSizeScrollbarThemes) > -1 ? false : obj.autoDraggerLength;
48764			obj.autoExpandScrollbar=$.inArray(obj.theme,nonExpandedScrollbarThemes) > -1 ? false : obj.autoExpandScrollbar;
48765			obj.scrollButtons.enable=$.inArray(obj.theme,disabledScrollButtonsThemes) > -1 ? false : obj.scrollButtons.enable;
48766			obj.autoHideScrollbar=$.inArray(obj.theme,enabledAutoHideScrollbarThemes) > -1 ? true : obj.autoHideScrollbar;
48767			obj.scrollbarPosition=$.inArray(obj.theme,scrollbarPositionOutsideThemes) > -1 ? "outside" : obj.scrollbarPosition;
48768		},
48769		/* -------------------- */
48770		
48771		
48772		/* live option timers removal */
48773		removeLiveTimers=function(selector){
48774			if(liveTimers[selector]){
48775				clearTimeout(liveTimers[selector]);
48776				_delete(liveTimers,selector);
48777			}
48778		},
48779		/* -------------------- */
48780		
48781		
48782		/* normalizes axis option to valid values: "y", "x", "yx" */
48783		_findAxis=function(val){
48784			return (val==="yx" || val==="xy" || val==="auto") ? "yx" : (val==="x" || val==="horizontal") ? "x" : "y";
48785		},
48786		/* -------------------- */
48787		
48788		
48789		/* normalizes scrollButtons.scrollType option to valid values: "stepless", "stepped" */
48790		_findScrollButtonsType=function(val){
48791			return (val==="stepped" || val==="pixels" || val==="step" || val==="click") ? "stepped" : "stepless";
48792		},
48793		/* -------------------- */
48794		
48795		
48796		/* generates plugin markup */
48797		_pluginMarkup=function(){
48798			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
48799				expandClass=o.autoExpandScrollbar ? " "+classes[1]+"_expand" : "",
48800				scrollbar=["<div id='mCSB_"+d.idx+"_scrollbar_vertical' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_vertical"+expandClass+"'><div class='"+classes[12]+"'><div id='mCSB_"+d.idx+"_dragger_vertical' class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>","<div id='mCSB_"+d.idx+"_scrollbar_horizontal' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_horizontal"+expandClass+"'><div class='"+classes[12]+"'><div id='mCSB_"+d.idx+"_dragger_horizontal' class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>"],
48801				wrapperClass=o.axis==="yx" ? "mCSB_vertical_horizontal" : o.axis==="x" ? "mCSB_horizontal" : "mCSB_vertical",
48802				scrollbars=o.axis==="yx" ? scrollbar[0]+scrollbar[1] : o.axis==="x" ? scrollbar[1] : scrollbar[0],
48803				contentWrapper=o.axis==="yx" ? "<div id='mCSB_"+d.idx+"_container_wrapper' class='mCSB_container_wrapper' />" : "",
48804				autoHideClass=o.autoHideScrollbar ? " "+classes[6] : "",
48805				scrollbarDirClass=(o.axis!=="x" && d.langDir==="rtl") ? " "+classes[7] : "";
48806			if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */
48807			if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */
48808			o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "989999px" : o.setLeft; /* adjust left position for rtl direction */
48809			$this.addClass(pluginNS+" _"+pluginPfx+"_"+d.idx+autoHideClass+scrollbarDirClass).wrapInner("<div id='mCSB_"+d.idx+"' class='mCustomScrollBox mCS-"+o.theme+" "+wrapperClass+"'><div id='mCSB_"+d.idx+"_container' class='mCSB_container' style='position:relative; top:"+o.setTop+"; left:"+o.setLeft+";' dir='"+d.langDir+"' /></div>");
48810			var mCustomScrollBox=$("#mCSB_"+d.idx),
48811				mCSB_container=$("#mCSB_"+d.idx+"_container");
48812			if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){
48813				mCSB_container.css("width",_contentWidth(mCSB_container));
48814			}
48815			if(o.scrollbarPosition==="outside"){
48816				if($this.css("position")==="static"){ /* requires elements with non-static position */
48817					$this.css("position","relative");
48818				}
48819				$this.css("overflow","visible");
48820				mCustomScrollBox.addClass("mCSB_outside").after(scrollbars);
48821			}else{
48822				mCustomScrollBox.addClass("mCSB_inside").append(scrollbars);
48823				mCSB_container.wrap(contentWrapper);
48824			}
48825			_scrollButtons.call(this); /* add scrollbar buttons */
48826			/* minimum dragger length */
48827			var mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
48828			mCSB_dragger[0].css("min-height",mCSB_dragger[0].height());
48829			mCSB_dragger[1].css("min-width",mCSB_dragger[1].width());
48830		},
48831		/* -------------------- */
48832		
48833		
48834		/* calculates content width */
48835		_contentWidth=function(el){
48836			var val=[el[0].scrollWidth,Math.max.apply(Math,el.children().map(function(){return $(this).outerWidth(true);}).get())],w=el.parent().width();
48837			return val[0]>w ? val[0] : val[1]>w ? val[1] : "100%";
48838		},
48839		/* -------------------- */
48840		
48841		
48842		/* expands content horizontally */
48843		_expandContentHorizontally=function(){
48844			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
48845				mCSB_container=$("#mCSB_"+d.idx+"_container");
48846			if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){
48847				/* calculate scrollWidth */
48848				mCSB_container.css({"width":"auto","min-width":0,"overflow-x":"scroll"});
48849				var w=Math.ceil(mCSB_container[0].scrollWidth);
48850				if(o.advanced.autoExpandHorizontalScroll===3 || (o.advanced.autoExpandHorizontalScroll!==2 && w>mCSB_container.parent().width())){
48851					mCSB_container.css({"width":w,"min-width":"100%","overflow-x":"inherit"});
48852				}else{
48853					/* 
48854					wrap content with an infinite width div and set its position to absolute and width to auto. 
48855					Setting width to auto before calculating the actual width is important! 
48856					We must let the browser set the width as browser zoom values are impossible to calculate.
48857					*/
48858					mCSB_container.css({"overflow-x":"inherit","position":"absolute"})
48859						.wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />")
48860						.css({ /* set actual width, original position and un-wrap */
48861							/* 
48862							get the exact width (with decimals) and then round-up. 
48863							Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width
48864							*/
48865							"width":(Math.ceil(mCSB_container[0].getBoundingClientRect().right+0.4)-Math.floor(mCSB_container[0].getBoundingClientRect().left)),
48866							"min-width":"100%",
48867							"position":"relative"
48868						}).unwrap();
48869				}
48870			}
48871		},
48872		/* -------------------- */
48873		
48874		
48875		/* adds scrollbar buttons */
48876		_scrollButtons=function(){
48877			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
48878				mCSB_scrollTools=$(".mCSB_"+d.idx+"_scrollbar:first"),
48879				tabindex=!_isNumeric(o.scrollButtons.tabindex) ? "" : "tabindex='"+o.scrollButtons.tabindex+"'",
48880				btnHTML=[
48881					"<a href='#' class='"+classes[13]+"' "+tabindex+" />",
48882					"<a href='#' class='"+classes[14]+"' "+tabindex+" />",
48883					"<a href='#' class='"+classes[15]+"' "+tabindex+" />",
48884					"<a href='#' class='"+classes[16]+"' "+tabindex+" />"
48885				],
48886				btn=[(o.axis==="x" ? btnHTML[2] : btnHTML[0]),(o.axis==="x" ? btnHTML[3] : btnHTML[1]),btnHTML[2],btnHTML[3]];
48887			if(o.scrollButtons.enable){
48888				mCSB_scrollTools.prepend(btn[0]).append(btn[1]).next(".mCSB_scrollTools").prepend(btn[2]).append(btn[3]);
48889			}
48890		},
48891		/* -------------------- */
48892		
48893		
48894		/* auto-adjusts scrollbar dragger length */
48895		_setDraggerLength=function(){
48896			var $this=$(this),d=$this.data(pluginPfx),
48897				mCustomScrollBox=$("#mCSB_"+d.idx),
48898				mCSB_container=$("#mCSB_"+d.idx+"_container"),
48899				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
48900				ratio=[mCustomScrollBox.height()/mCSB_container.outerHeight(false),mCustomScrollBox.width()/mCSB_container.outerWidth(false)],
48901				l=[
48902					parseInt(mCSB_dragger[0].css("min-height")),Math.round(ratio[0]*mCSB_dragger[0].parent().height()),
48903					parseInt(mCSB_dragger[1].css("min-width")),Math.round(ratio[1]*mCSB_dragger[1].parent().width())
48904				],
48905				h=oldIE && (l[1]<l[0]) ? l[0] : l[1],w=oldIE && (l[3]<l[2]) ? l[2] : l[3];
48906			mCSB_dragger[0].css({
48907				"height":h,"max-height":(mCSB_dragger[0].parent().height()-10)
48908			}).find(".mCSB_dragger_bar").css({"line-height":l[0]+"px"});
48909			mCSB_dragger[1].css({
48910				"width":w,"max-width":(mCSB_dragger[1].parent().width()-10)
48911			});
48912		},
48913		/* -------------------- */
48914		
48915		
48916		/* calculates scrollbar to content ratio */
48917		_scrollRatio=function(){
48918			var $this=$(this),d=$this.data(pluginPfx),
48919				mCustomScrollBox=$("#mCSB_"+d.idx),
48920				mCSB_container=$("#mCSB_"+d.idx+"_container"),
48921				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
48922				scrollAmount=[mCSB_container.outerHeight(false)-mCustomScrollBox.height(),mCSB_container.outerWidth(false)-mCustomScrollBox.width()],
48923				ratio=[
48924					scrollAmount[0]/(mCSB_dragger[0].parent().height()-mCSB_dragger[0].height()),
48925					scrollAmount[1]/(mCSB_dragger[1].parent().width()-mCSB_dragger[1].width())
48926				];
48927			d.scrollRatio={y:ratio[0],x:ratio[1]};
48928		},
48929		/* -------------------- */
48930		
48931		
48932		/* toggles scrolling classes */
48933		_onDragClasses=function(el,action,xpnd){
48934			var expandClass=xpnd ? classes[0]+"_expanded" : "",
48935				scrollbar=el.closest(".mCSB_scrollTools");
48936			if(action==="active"){
48937				el.toggleClass(classes[0]+" "+expandClass); scrollbar.toggleClass(classes[1]); 
48938				el[0]._draggable=el[0]._draggable ? 0 : 1;
48939			}else{
48940				if(!el[0]._draggable){
48941					if(action==="hide"){
48942						el.removeClass(classes[0]); scrollbar.removeClass(classes[1]);
48943					}else{
48944						el.addClass(classes[0]); scrollbar.addClass(classes[1]);
48945					}
48946				}
48947			}
48948		},
48949		/* -------------------- */
48950		
48951		
48952		/* checks if content overflows its container to determine if scrolling is required */
48953		_overflowed=function(){
48954			var $this=$(this),d=$this.data(pluginPfx),
48955				mCustomScrollBox=$("#mCSB_"+d.idx),
48956				mCSB_container=$("#mCSB_"+d.idx+"_container"),
48957				contentHeight=d.overflowed==null ? mCSB_container.height() : mCSB_container.outerHeight(false),
48958				contentWidth=d.overflowed==null ? mCSB_container.width() : mCSB_container.outerWidth(false),
48959				h=mCSB_container[0].scrollHeight,w=mCSB_container[0].scrollWidth;
48960			if(h>contentHeight){contentHeight=h;}
48961			if(w>contentWidth){contentWidth=w;}
48962			return [contentHeight>mCustomScrollBox.height(),contentWidth>mCustomScrollBox.width()];
48963		},
48964		/* -------------------- */
48965		
48966		
48967		/* resets content position to 0 */
48968		_resetContentPosition=function(){
48969			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
48970				mCustomScrollBox=$("#mCSB_"+d.idx),
48971				mCSB_container=$("#mCSB_"+d.idx+"_container"),
48972				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
48973			_stop($this); /* stop any current scrolling before resetting */
48974			if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){ /* reset y */
48975				mCSB_dragger[0].add(mCSB_container).css("top",0);
48976				_scrollTo($this,"_resetY");
48977			}
48978			if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */
48979				var cx=dx=0;
48980				if(d.langDir==="rtl"){ /* adjust left position for rtl direction */
48981					cx=mCustomScrollBox.width()-mCSB_container.outerWidth(false);
48982					dx=Math.abs(cx/d.scrollRatio.x);
48983				}
48984				mCSB_container.css("left",cx);
48985				mCSB_dragger[1].css("left",dx);
48986				_scrollTo($this,"_resetX");
48987			}
48988		},
48989		/* -------------------- */
48990		
48991		
48992		/* binds scrollbar events */
48993		_bindEvents=function(){
48994			var $this=$(this),d=$this.data(pluginPfx),o=d.opt;
48995			if(!d.bindEvents){ /* check if events are already bound */
48996				_draggable.call(this);
48997				if(o.contentTouchScroll){_contentDraggable.call(this);}
48998				_selectable.call(this);
48999				if(o.mouseWheel.enable){ /* bind mousewheel fn when plugin is available */
49000					function _mwt(){
49001						mousewheelTimeout=setTimeout(function(){
49002							if(!$.event.special.mousewheel){
49003								_mwt();
49004							}else{
49005								clearTimeout(mousewheelTimeout);
49006								_mousewheel.call($this[0]);
49007							}
49008						},100);
49009					}
49010					var mousewheelTimeout;
49011					_mwt();
49012				}
49013				_draggerRail.call(this);
49014				_wrapperScroll.call(this);
49015				if(o.advanced.autoScrollOnFocus){_focus.call(this);}
49016				if(o.scrollButtons.enable){_buttons.call(this);}
49017				if(o.keyboard.enable){_keyboard.call(this);}
49018				d.bindEvents=true;
49019			}
49020		},
49021		/* -------------------- */
49022		
49023		
49024		/* unbinds scrollbar events */
49025		_unbindEvents=function(){
49026			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49027				namespace=pluginPfx+"_"+d.idx,
49028				sb=".mCSB_"+d.idx+"_scrollbar",
49029				sel=$("#mCSB_"+d.idx+",#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,"+sb+" ."+classes[12]+",#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal,"+sb+">a"),
49030				mCSB_container=$("#mCSB_"+d.idx+"_container");
49031			if(o.advanced.releaseDraggableSelectors){sel.add($(o.advanced.releaseDraggableSelectors));}
49032			if(o.advanced.extraDraggableSelectors){sel.add($(o.advanced.extraDraggableSelectors));}
49033			if(d.bindEvents){ /* check if events are bound */
49034				/* unbind namespaced events from document/selectors */
49035				
49035$(document).add($(!_canAccessIFrame() || top.document
vendor: 3,898 bytes, lines 49035-49127
49035)).unbind("."+namespace);
49036				sel.each(function(){
49037					$(this).unbind("."+namespace);
49038				});
49039				/* clear and delete timeouts/objects */
49040				clearTimeout($this[0]._focusTimeout); _delete($this[0],"_focusTimeout");
49041				clearTimeout(d.sequential.step); _delete(d.sequential,"step");
49042				clearTimeout(mCSB_container[0].onCompleteTimeout); _delete(mCSB_container[0],"onCompleteTimeout");
49043				d.bindEvents=false;
49044			}
49045		},
49046		/* -------------------- */
49047		
49048		
49049		/* toggles scrollbar visibility */
49050		_scrollbarVisibility=function(disabled){
49051			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49052				contentWrapper=$("#mCSB_"+d.idx+"_container_wrapper"),
49053				content=contentWrapper.length ? contentWrapper : $("#mCSB_"+d.idx+"_container"),
49054				scrollbar=[$("#mCSB_"+d.idx+"_scrollbar_vertical"),$("#mCSB_"+d.idx+"_scrollbar_horizontal")],
49055				mCSB_dragger=[scrollbar[0].find(".mCSB_dragger"),scrollbar[1].find(".mCSB_dragger")];
49056			if(o.axis!=="x"){
49057				if(d.overflowed[0] && !disabled){
49058					scrollbar[0].add(mCSB_dragger[0]).add(scrollbar[0].children("a")).css("display","block");
49059					content.removeClass(classes[8]+" "+classes[10]);
49060				}else{
49061					if(o.alwaysShowScrollbar){
49062						if(o.alwaysShowScrollbar!==2){mCSB_dragger[0].css("display","none");}
49063						content.removeClass(classes[10]);
49064					}else{
49065						scrollbar[0].css("display","none");
49066						content.addClass(classes[10]);
49067					}
49068					content.addClass(classes[8]);
49069				}
49070			}
49071			if(o.axis!=="y"){
49072				if(d.overflowed[1] && !disabled){
49073					scrollbar[1].add(mCSB_dragger[1]).add(scrollbar[1].children("a")).css("display","block");
49074					content.removeClass(classes[9]+" "+classes[11]);
49075				}else{
49076					if(o.alwaysShowScrollbar){
49077						if(o.alwaysShowScrollbar!==2){mCSB_dragger[1].css("display","none");}
49078						content.removeClass(classes[11]);
49079					}else{
49080						scrollbar[1].css("display","none");
49081						content.addClass(classes[11]);
49082					}
49083					content.addClass(classes[9]);
49084				}
49085			}
49086			if(!d.overflowed[0] && !d.overflowed[1]){
49087				$this.addClass(classes[5]);
49088			}else{
49089				$this.removeClass(classes[5]);
49090			}
49091		},
49092		/* -------------------- */
49093		
49094		
49095		/* returns input coordinates of pointer, touch and mouse events (relative to document) */
49096		_coordinates=function(e){
49097			var t=e.type,o=e.target.ownerDocument!==document && frameElement!==null ? [$(frameElement).offset().top,$(frameElement).offset().left] : null,
49098				io=_canAccessIFrame() && e.target.ownerDocument!==top.document && frameElement!==null ? [$(e.view.frameElement).offset().top,$(e.view.frameElement).offset().left] : [0,0];
49099			switch(t){
49100				case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp":
49101					return o ? [e.originalEvent.pageY-o[0]+io[0],e.originalEvent.pageX-o[1]+io[1],false] : [e.originalEvent.pageY,e.originalEvent.pageX,false];
49102					break;
49103				case "touchstart": case "touchmove": case "touchend":
49104					var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
49105						touches=e.originalEvent.touches.length || e.originalEvent.changedTouches.length;
49106					return e.target.ownerDocument!==document ? [touch.screenY,touch.screenX,touches>1] : [touch.pageY,touch.pageX,touches>1];
49107					break;
49108				default:
49109					return o ? [e.pageY-o[0]+io[0],e.pageX-o[1]+io[1],false] : [e.pageY,e.pageX,false];
49110			}
49111		},
49112		/* -------------------- */
49113		
49114		
49115		/* 
49116		SCROLLBAR DRAG EVENTS
49117		scrolls content via scrollbar dragging 
49118		*/
49119		_draggable=function(){
49120			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49121				namespace=pluginPfx+"_"+d.idx,
49122				draggerId=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"],
49123				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49124				mCSB_dragger=$("#"+draggerId[0]+",#"+draggerId[1]),
49125				draggable,dragY,dragX,
49126				rds=o.advanced.releaseDraggableSelectors ? mCSB_dragger.add($(o.advanced.releaseDraggableSelectors)) : mCSB_dragger,
49127				
49127eds=o.advanced.extraDraggableSelectors ? $(!_canAccessIFrame() || top.document).add($(o.advanced.extraDraggableSelectors)) : $(!_canAccessIFrame() || top.document
vendor: 48,256 bytes, lines 49127-50393
49127);
49128			mCSB_dragger.bind("contextmenu."+namespace,function(e){
49129				e.preventDefault(); //prevent right click
49130			}).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
49131				e.stopImmediatePropagation();
49132				e.preventDefault();
49133				if(!_mouseBtnLeft(e)){return;} /* left mouse button only */
49134				touchActive=true;
49135				if(oldIE){document.onselectstart=function(){return false;}} /* disable text selection for IE < 9 */
49136				_iframe.call(mCSB_container,false); /* enable scrollbar dragging over iframes by disabling their events */
49137				_stop($this);
49138				draggable=$(this);
49139				var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left,
49140					h=draggable.height()+offset.top,w=draggable.width()+offset.left;
49141				if(y<h && y>0 && x<w && x>0){
49142					dragY=y; 
49143					dragX=x;
49144				}
49145				_onDragClasses(draggable,"active",o.autoExpandScrollbar); 
49146			}).bind("touchmove."+namespace,function(e){
49147				e.stopImmediatePropagation();
49148				e.preventDefault();
49149				var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left;
49150				_drag(dragY,dragX,y,x);
49151			});
49152			$(document).add(eds).bind("mousemove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){
49153				if(draggable){
49154					var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left;
49155					if(dragY===y && dragX===x){return;} /* has it really moved? */
49156					_drag(dragY,dragX,y,x);
49157				}
49158			}).add(rds).bind("mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){
49159				if(draggable){
49160					_onDragClasses(draggable,"active",o.autoExpandScrollbar); 
49161					draggable=null;
49162				}
49163				touchActive=false;
49164				if(oldIE){document.onselectstart=null;} /* enable text selection for IE < 9 */
49165				_iframe.call(mCSB_container,true); /* enable iframes events */
49166			});
49167			function _drag(dragY,dragX,y,x){
49168				mCSB_container[0].idleTimer=o.scrollInertia<233 ? 250 : 0;
49169				if(draggable.attr("id")===draggerId[1]){
49170					var dir="x",to=((draggable[0].offsetLeft-dragX)+x)*d.scrollRatio.x;
49171				}else{
49172					var dir="y",to=((draggable[0].offsetTop-dragY)+y)*d.scrollRatio.y;
49173				}
49174				_scrollTo($this,to.toString(),{dir:dir,drag:true});
49175			}
49176		},
49177		/* -------------------- */
49178		
49179		
49180		/* 
49181		TOUCH SWIPE EVENTS
49182		scrolls content via touch swipe 
49183		Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices 
49184		*/
49185		_contentDraggable=function(){
49186			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49187				namespace=pluginPfx+"_"+d.idx,
49188				mCustomScrollBox=$("#mCSB_"+d.idx),
49189				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49190				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
49191				draggable,dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount,
49192				durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[],touchDrag,docDrag,
49193				iframe=mCSB_container.find("iframe"),
49194				events=[
49195					"touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace, //start
49196					"touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace, //move
49197					"touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace //end
49198				],
49199				touchAction=document.body.style.touchAction!==undefined && document.body.style.touchAction!=="";
49200			mCSB_container.bind(events[0],function(e){
49201				_onTouchstart(e);
49202			}).bind(events[1],function(e){
49203				_onTouchmove(e);
49204			});
49205			mCustomScrollBox.bind(events[0],function(e){
49206				_onTouchstart2(e);
49207			}).bind(events[2],function(e){
49208				_onTouchend(e);
49209			});
49210			if(iframe.length){
49211				iframe.each(function(){
49212					$(this).bind("load",function(){
49213						/* bind events on accessible iframes */
49214						if(_canAccessIFrame(this)){
49215							$(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){
49216								_onTouchstart(e);
49217								_onTouchstart2(e);
49218							}).bind(events[1],function(e){
49219								_onTouchmove(e);
49220							}).bind(events[2],function(e){
49221								_onTouchend(e);
49222							});
49223						}
49224					});
49225				});
49226			}
49227			function _onTouchstart(e){
49228				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;}
49229				touchable=1; touchDrag=0; docDrag=0; draggable=1;
49230				$this.removeClass("mCS_touch_action");
49231				var offset=mCSB_container.offset();
49232				dragY=_coordinates(e)[0]-offset.top;
49233				dragX=_coordinates(e)[1]-offset.left;
49234				touchIntent=[_coordinates(e)[0],_coordinates(e)[1]];
49235			}
49236			function _onTouchmove(e){
49237				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;}
49238				if(!o.documentTouchScroll){e.preventDefault();} 
49239				e.stopImmediatePropagation();
49240				if(docDrag && !touchDrag){return;}
49241				if(draggable){
49242					runningTime=_getTime();
49243					var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left,
49244						easing="mcsLinearOut";
49245					touchMoveY.push(y);
49246					touchMoveX.push(x);
49247					touchIntent[2]=Math.abs(_coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(_coordinates(e)[1]-touchIntent[1]);
49248					if(d.overflowed[0]){
49249						var limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(),
49250							prevent=((dragY-y)>0 && (y-dragY)>-(limit*d.scrollRatio.y) && (touchIntent[3]*2<touchIntent[2] || o.axis==="yx"));
49251					}
49252					if(d.overflowed[1]){
49253						var limitX=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(),
49254							preventX=((dragX-x)>0 && (x-dragX)>-(limitX*d.scrollRatio.x) && (touchIntent[2]*2<touchIntent[3] || o.axis==="yx"));
49255					}
49256					if(prevent || preventX){ /* prevent native document scrolling */
49257						if(!touchAction){e.preventDefault();} 
49258						touchDrag=1;
49259					}else{
49260						docDrag=1;
49261						$this.addClass("mCS_touch_action");
49262					}
49263					if(touchAction){e.preventDefault();} 
49264					amount=o.axis==="yx" ? [(dragY-y),(dragX-x)] : o.axis==="x" ? [null,(dragX-x)] : [(dragY-y),null];
49265					mCSB_container[0].idleTimer=250;
49266					if(d.overflowed[0]){_drag(amount[0],durA,easing,"y","all",true);}
49267					if(d.overflowed[1]){_drag(amount[1],durA,easing,"x",overwrite,true);}
49268				}
49269			}
49270			function _onTouchstart2(e){
49271				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;}
49272				touchable=1;
49273				e.stopImmediatePropagation();
49274				_stop($this);
49275				startTime=_getTime();
49276				var offset=mCustomScrollBox.offset();
49277				touchStartY=_coordinates(e)[0]-offset.top;
49278				touchStartX=_coordinates(e)[1]-offset.left;
49279				touchMoveY=[]; touchMoveX=[];
49280			}
49281			function _onTouchend(e){
49282				if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;}
49283				draggable=0;
49284				e.stopImmediatePropagation();
49285				touchDrag=0; docDrag=0;
49286				endTime=_getTime();
49287				var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left;
49288				if((endTime-runningTime)>30){return;}
49289				speed=1000/(endTime-startTime);
49290				var easing="mcsEaseOut",slow=speed<2.5,
49291					diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0];
49292				distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX];
49293				var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])];
49294				speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed];
49295				var a=[
49296					Math.abs(mCSB_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])),
49297					Math.abs(mCSB_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1]))
49298				];
49299				amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null,a[1]] : [a[0],null];
49300				durB=[(absDistance[0]*4)+o.scrollInertia,(absDistance[1]*4)+o.scrollInertia];
49301				var md=parseInt(o.contentTouchScroll) || 0; /* absolute minimum distance required */
49302				amount[0]=absDistance[0]>md ? amount[0] : 0;
49303				amount[1]=absDistance[1]>md ? amount[1] : 0;
49304				if(d.overflowed[0]){_drag(amount[0],durB[0],easing,"y",overwrite,false);}
49305				if(d.overflowed[1]){_drag(amount[1],durB[1],easing,"x",overwrite,false);}
49306			}
49307			function _m(ds,s){
49308				var r=[s*1.5,s*2,s/1.5,s/2];
49309				if(ds>90){
49310					return s>4 ? r[0] : r[3];
49311				}else if(ds>60){
49312					return s>3 ? r[3] : r[2];
49313				}else if(ds>30){
49314					return s>8 ? r[1] : s>6 ? r[0] : s>4 ? s : r[2];
49315				}else{
49316					return s>8 ? s : r[3];
49317				}
49318			}
49319			function _drag(amount,dur,easing,dir,overwrite,drag){
49320				if(!amount){return;}
49321				_scrollTo($this,amount.toString(),{dur:dur,scrollEasing:easing,dir:dir,overwrite:overwrite,drag:drag});
49322			}
49323		},
49324		/* -------------------- */
49325		
49326		
49327		/* 
49328		SELECT TEXT EVENTS 
49329		scrolls content when text is selected 
49330		*/
49331		_selectable=function(){
49332			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential,
49333				namespace=pluginPfx+"_"+d.idx,
49334				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49335				wrapper=mCSB_container.parent(),
49336				action;
49337			mCSB_container.bind("mousedown."+namespace,function(e){
49338				if(touchable){return;}
49339				if(!action){action=1; touchActive=true;}
49340			}).add(document).bind("mousemove."+namespace,function(e){
49341				if(!touchable && action && _sel()){
49342					var offset=mCSB_container.offset(),
49343						y=_coordinates(e)[0]-offset.top+mCSB_container[0].offsetTop,x=_coordinates(e)[1]-offset.left+mCSB_container[0].offsetLeft;
49344					if(y>0 && y<wrapper.height() && x>0 && x<wrapper.width()){
49345						if(seq.step){_seq("off",null,"stepped");}
49346					}else{
49347						if(o.axis!=="x" && d.overflowed[0]){
49348							if(y<0){
49349								_seq("on",38);
49350							}else if(y>wrapper.height()){
49351								_seq("on",40);
49352							}
49353						}
49354						if(o.axis!=="y" && d.overflowed[1]){
49355							if(x<0){
49356								_seq("on",37);
49357							}else if(x>wrapper.width()){
49358								_seq("on",39);
49359							}
49360						}
49361					}
49362				}
49363			}).bind("mouseup."+namespace+" dragend."+namespace,function(e){
49364				if(touchable){return;}
49365				if(action){action=0; _seq("off",null);}
49366				touchActive=false;
49367			});
49368			function _sel(){
49369				return 	window.getSelection ? window.getSelection().toString() : 
49370						document.selection && document.selection.type!="Control" ? document.selection.createRange().text : 0;
49371			}
49372			function _seq(a,c,s){
49373				seq.type=s && action ? "stepped" : "stepless";
49374				seq.scrollAmount=10;
49375				_sequentialScroll($this,a,c,"mcsLinearOut",s ? 60 : null);
49376			}
49377		},
49378		/* -------------------- */
49379		
49380		
49381		/* 
49382		MOUSE WHEEL EVENT
49383		scrolls content via mouse-wheel 
49384		via mouse-wheel plugin (https://github.com/brandonaaron/jquery-mousewheel)
49385		*/
49386		_mousewheel=function(){
49387			if(!$(this).data(pluginPfx)){return;} /* Check if the scrollbar is ready to use mousewheel events (issue: #185) */
49388			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49389				namespace=pluginPfx+"_"+d.idx,
49390				mCustomScrollBox=$("#mCSB_"+d.idx),
49391				mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
49392				iframe=$("#mCSB_"+d.idx+"_container").find("iframe");
49393			if(iframe.length){
49394				iframe.each(function(){
49395					$(this).bind("load",function(){
49396						/* bind events on accessible iframes */
49397						if(_canAccessIFrame(this)){
49398							$(this.contentDocument || this.contentWindow.document).bind("mousewheel."+namespace,function(e,delta){
49399								_onMousewheel(e,delta);
49400							});
49401						}
49402					});
49403				});
49404			}
49405			mCustomScrollBox.bind("mousewheel."+namespace,function(e,delta){
49406				_onMousewheel(e,delta);
49407			});
49408			function _onMousewheel(e,delta){
49409				_stop($this);
49410				if(_disableMousewheel($this,e.target)){return;} /* disables mouse-wheel when hovering specific elements */
49411				var deltaFactor=o.mouseWheel.deltaFactor!=="auto" ? parseInt(o.mouseWheel.deltaFactor) : (oldIE && e.deltaFactor<100) ? 100 : e.deltaFactor || 100,
49412					dur=o.scrollInertia;
49413				if(o.axis==="x" || o.mouseWheel.axis==="x"){
49414					var dir="x",
49415						px=[Math.round(deltaFactor*d.scrollRatio.x),parseInt(o.mouseWheel.scrollAmount)],
49416						amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.width() ? mCustomScrollBox.width()*0.9 : px[0],
49417						contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetLeft),
49418						draggerPos=mCSB_dragger[1][0].offsetLeft,
49419						limit=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(),
49420						dlt=o.mouseWheel.axis==="y" ? (e.deltaY || delta) : e.deltaX;
49421				}else{
49422					var dir="y",
49423						px=[Math.round(deltaFactor*d.scrollRatio.y),parseInt(o.mouseWheel.scrollAmount)],
49424						amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.height() ? mCustomScrollBox.height()*0.9 : px[0],
49425						contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetTop),
49426						draggerPos=mCSB_dragger[0][0].offsetTop,
49427						limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(),
49428						dlt=e.deltaY || delta;
49429				}
49430				if((dir==="y" && !d.overflowed[0]) || (dir==="x" && !d.overflowed[1])){return;}
49431				if(o.mouseWheel.invert || e.webkitDirectionInvertedFromDevice){dlt=-dlt;}
49432				if(o.mouseWheel.normalizeDelta){dlt=dlt<0 ? -1 : 1;}
49433				if((dlt>0 && draggerPos!==0) || (dlt<0 && draggerPos!==limit) || o.mouseWheel.preventDefault){
49434					e.stopImmediatePropagation();
49435					e.preventDefault();
49436				}
49437				if(e.deltaFactor<5 && !o.mouseWheel.normalizeDelta){
49438					//very low deltaFactor values mean some kind of delta acceleration (e.g. osx trackpad), so adjusting scrolling accordingly
49439					amount=e.deltaFactor; dur=17;
49440				}
49441				_scrollTo($this,(contentPos-(dlt*amount)).toString(),{dir:dir,dur:dur});
49442			}
49443		},
49444		/* -------------------- */
49445		
49446		
49447		/* checks if iframe can be accessed */
49448		_canAccessIFrameCache=new Object(),
49449		_canAccessIFrame=function(iframe){
49450		    var result=false,cacheKey=false,html=null;
49451		    if(iframe===undefined){
49452				cacheKey="#empty";
49453		    }else if($(iframe).attr("id")!==undefined){
49454				cacheKey=$(iframe).attr("id");
49455		    }
49456			if(cacheKey!==false && _canAccessIFrameCache[cacheKey]!==undefined){
49457				return _canAccessIFrameCache[cacheKey];
49458			}
49459			if(!iframe){
49460				try{
49461					var doc=top.document;
49462					html=doc.body.innerHTML;
49463				}catch(err){/* do nothing */}
49464				result=(html!==null);
49465			}else{
49466				try{
49467					var doc=iframe.contentDocument || iframe.contentWindow.document;
49468					html=doc.body.innerHTML;
49469				}catch(err){/* do nothing */}
49470				result=(html!==null);
49471			}
49472			if(cacheKey!==false){_canAccessIFrameCache[cacheKey]=result;}
49473			return result;
49474		},
49475		/* -------------------- */
49476		
49477		
49478		/* switches iframe's pointer-events property (drag, mousewheel etc. over cross-domain iframes) */
49479		_iframe=function(evt){
49480			var el=this.find("iframe");
49481			if(!el.length){return;} /* check if content contains iframes */
49482			var val=!evt ? "none" : "auto";
49483			el.css("pointer-events",val); /* for IE11, iframe's display property should not be "block" */
49484		},
49485		/* -------------------- */
49486		
49487		
49488		/* disables mouse-wheel when hovering specific elements like select, datalist etc. */
49489		_disableMousewheel=function(el,target){
49490			var tag=target.nodeName.toLowerCase(),
49491				tags=el.data(pluginPfx).opt.mouseWheel.disableOver,
49492				/* elements that require focus */
49493				focusTags=["select","textarea"];
49494			return $.inArray(tag,tags) > -1 && !($.inArray(tag,focusTags) > -1 && !$(target).is(":focus"));
49495		},
49496		/* -------------------- */
49497		
49498		
49499		/* 
49500		DRAGGER RAIL CLICK EVENT
49501		scrolls content via dragger rail 
49502		*/
49503		_draggerRail=function(){
49504			var $this=$(this),d=$this.data(pluginPfx),
49505				namespace=pluginPfx+"_"+d.idx,
49506				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49507				wrapper=mCSB_container.parent(),
49508				mCSB_draggerContainer=$(".mCSB_"+d.idx+"_scrollbar ."+classes[12]),
49509				clickable;
49510			mCSB_draggerContainer.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
49511				touchActive=true;
49512				if(!$(e.target).hasClass("mCSB_dragger")){clickable=1;}
49513			}).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){
49514				touchActive=false;
49515			}).bind("click."+namespace,function(e){
49516				if(!clickable){return;}
49517				clickable=0;
49518				if($(e.target).hasClass(classes[12]) || $(e.target).hasClass("mCSB_draggerRail")){
49519					_stop($this);
49520					var el=$(this),mCSB_dragger=el.find(".mCSB_dragger");
49521					if(el.parent(".mCSB_scrollTools_horizontal").length>0){
49522						if(!d.overflowed[1]){return;}
49523						var dir="x",
49524							clickDir=e.pageX>mCSB_dragger.offset().left ? -1 : 1,
49525							to=Math.abs(mCSB_container[0].offsetLeft)-(clickDir*(wrapper.width()*0.9));
49526					}else{
49527						if(!d.overflowed[0]){return;}
49528						var dir="y",
49529							clickDir=e.pageY>mCSB_dragger.offset().top ? -1 : 1,
49530							to=Math.abs(mCSB_container[0].offsetTop)-(clickDir*(wrapper.height()*0.9));
49531					}
49532					_scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"});
49533				}
49534			});
49535		},
49536		/* -------------------- */
49537		
49538		
49539		/* 
49540		FOCUS EVENT
49541		scrolls content via element focus (e.g. clicking an input, pressing TAB key etc.)
49542		*/
49543		_focus=function(){
49544			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49545				namespace=pluginPfx+"_"+d.idx,
49546				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49547				wrapper=mCSB_container.parent();
49548			mCSB_container.bind("focusin."+namespace,function(e){
49549				var el=$(document.activeElement),
49550					nested=mCSB_container.find(".mCustomScrollBox").length,
49551					dur=0;
49552				if(!el.is(o.advanced.autoScrollOnFocus)){return;}
49553				_stop($this);
49554				clearTimeout($this[0]._focusTimeout);
49555				$this[0]._focusTimer=nested ? (dur+17)*nested : 0;
49556				$this[0]._focusTimeout=setTimeout(function(){
49557					var	to=[_childPos(el)[0],_childPos(el)[1]],
49558						contentPos=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft],
49559						isVisible=[
49560							(contentPos[0]+to[0]>=0 && contentPos[0]+to[0]<wrapper.height()-el.outerHeight(false)),
49561							(contentPos[1]+to[1]>=0 && contentPos[0]+to[1]<wrapper.width()-el.outerWidth(false))
49562						],
49563						overwrite=(o.axis==="yx" && !isVisible[0] && !isVisible[1]) ? "none" : "all";
49564					if(o.axis!=="x" && !isVisible[0]){
49565						_scrollTo($this,to[0].toString(),{dir:"y",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur});
49566					}
49567					if(o.axis!=="y" && !isVisible[1]){
49568						_scrollTo($this,to[1].toString(),{dir:"x",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur});
49569					}
49570				},$this[0]._focusTimer);
49571			});
49572		},
49573		/* -------------------- */
49574		
49575		
49576		/* sets content wrapper scrollTop/scrollLeft always to 0 */
49577		_wrapperScroll=function(){
49578			var $this=$(this),d=$this.data(pluginPfx),
49579				namespace=pluginPfx+"_"+d.idx,
49580				wrapper=$("#mCSB_"+d.idx+"_container").parent();
49581			wrapper.bind("scroll."+namespace,function(e){
49582				if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){
49583					$(".mCSB_"+d.idx+"_scrollbar").css("visibility","hidden"); /* hide scrollbar(s) */
49584				}
49585			});
49586		},
49587		/* -------------------- */
49588		
49589		
49590		/* 
49591		BUTTONS EVENTS
49592		scrolls content via up, down, left and right buttons 
49593		*/
49594		_buttons=function(){
49595			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential,
49596				namespace=pluginPfx+"_"+d.idx,
49597				sel=".mCSB_"+d.idx+"_scrollbar",
49598				btn=$(sel+">a");
49599			btn.bind("contextmenu."+namespace,function(e){
49600				e.preventDefault(); //prevent right click
49601			}).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace+" mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace+" mouseout."+namespace+" pointerout."+namespace+" MSPointerOut."+namespace+" click."+namespace,function(e){
49602				e.preventDefault();
49603				if(!_mouseBtnLeft(e)){return;} /* left mouse button only */
49604				var btnClass=$(this).attr("class");
49605				seq.type=o.scrollButtons.scrollType;
49606				switch(e.type){
49607					case "mousedown": case "touchstart": case "pointerdown": case "MSPointerDown":
49608						if(seq.type==="stepped"){return;}
49609						touchActive=true;
49610						d.tweenRunning=false;
49611						_seq("on",btnClass);
49612						break;
49613					case "mouseup": case "touchend": case "pointerup": case "MSPointerUp":
49614					case "mouseout": case "pointerout": case "MSPointerOut":
49615						if(seq.type==="stepped"){return;}
49616						touchActive=false;
49617						if(seq.dir){_seq("off",btnClass);}
49618						break;
49619					case "click":
49620						if(seq.type!=="stepped" || d.tweenRunning){return;}
49621						_seq("on",btnClass);
49622						break;
49623				}
49624				function _seq(a,c){
49625					seq.scrollAmount=o.scrollButtons.scrollAmount;
49626					_sequentialScroll($this,a,c);
49627				}
49628			});
49629		},
49630		/* -------------------- */
49631		
49632		
49633		/* 
49634		KEYBOARD EVENTS
49635		scrolls content via keyboard 
49636		Keys: up arrow, down arrow, left arrow, right arrow, PgUp, PgDn, Home, End
49637		*/
49638		_keyboard=function(){
49639			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential,
49640				namespace=pluginPfx+"_"+d.idx,
49641				mCustomScrollBox=$("#mCSB_"+d.idx),
49642				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49643				wrapper=mCSB_container.parent(),
49644				editables="input,textarea,select,datalist,keygen,[contenteditable='true']",
49645				iframe=mCSB_container.find("iframe"),
49646				events=["blur."+namespace+" keydown."+namespace+" keyup."+namespace];
49647			if(iframe.length){
49648				iframe.each(function(){
49649					$(this).bind("load",function(){
49650						/* bind events on accessible iframes */
49651						if(_canAccessIFrame(this)){
49652							$(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){
49653								_onKeyboard(e);
49654							});
49655						}
49656					});
49657				});
49658			}
49659			mCustomScrollBox.attr("tabindex","0").bind(events[0],function(e){
49660				_onKeyboard(e);
49661			});
49662			function _onKeyboard(e){
49663				switch(e.type){
49664					case "blur":
49665						if(d.tweenRunning && seq.dir){_seq("off",null);}
49666						break;
49667					case "keydown": case "keyup":
49668						var code=e.keyCode ? e.keyCode : e.which,action="on";
49669						if((o.axis!=="x" && (code===38 || code===40)) || (o.axis!=="y" && (code===37 || code===39))){
49670							/* up (38), down (40), left (37), right (39) arrows */
49671							if(((code===38 || code===40) && !d.overflowed[0]) || ((code===37 || code===39) && !d.overflowed[1])){return;}
49672							if(e.type==="keyup"){action="off";}
49673							if(!$(document.activeElement).is(editables)){
49674								e.preventDefault();
49675								e.stopImmediatePropagation();
49676								_seq(action,code);
49677							}
49678						}else if(code===33 || code===34){
49679							/* PgUp (33), PgDn (34) */
49680							if(d.overflowed[0] || d.overflowed[1]){
49681								e.preventDefault();
49682								e.stopImmediatePropagation();
49683							}
49684							if(e.type==="keyup"){
49685								_stop($this);
49686								var keyboardDir=code===34 ? -1 : 1;
49687								if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){
49688									var dir="x",to=Math.abs(mCSB_container[0].offsetLeft)-(keyboardDir*(wrapper.width()*0.9));
49689								}else{
49690									var dir="y",to=Math.abs(mCSB_container[0].offsetTop)-(keyboardDir*(wrapper.height()*0.9));
49691								}
49692								_scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"});
49693							}
49694						}else if(code===35 || code===36){
49695							/* End (35), Home (36) */
49696							if(!$(document.activeElement).is(editables)){
49697								if(d.overflowed[0] || d.overflowed[1]){
49698									e.preventDefault();
49699									e.stopImmediatePropagation();
49700								}
49701								if(e.type==="keyup"){
49702									if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){
49703										var dir="x",to=code===35 ? Math.abs(wrapper.width()-mCSB_container.outerWidth(false)) : 0;
49704									}else{
49705										var dir="y",to=code===35 ? Math.abs(wrapper.height()-mCSB_container.outerHeight(false)) : 0;
49706									}
49707									_scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"});
49708								}
49709							}
49710						}
49711						break;
49712				}
49713				function _seq(a,c){
49714					seq.type=o.keyboard.scrollType;
49715					seq.scrollAmount=o.keyboard.scrollAmount;
49716					if(seq.type==="stepped" && d.tweenRunning){return;}
49717					_sequentialScroll($this,a,c);
49718				}
49719			}
49720		},
49721		/* -------------------- */
49722		
49723		
49724		/* scrolls content sequentially (used when scrolling via buttons, keyboard arrows etc.) */
49725		_sequentialScroll=function(el,action,trigger,e,s){
49726			var d=el.data(pluginPfx),o=d.opt,seq=d.sequential,
49727				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49728				once=seq.type==="stepped" ? true : false,
49729				steplessSpeed=o.scrollInertia < 26 ? 26 : o.scrollInertia, /* 26/1.5=17 */
49730				steppedSpeed=o.scrollInertia < 1 ? 17 : o.scrollInertia;
49731			switch(action){
49732				case "on":
49733					seq.dir=[
49734						(trigger===classes[16] || trigger===classes[15] || trigger===39 || trigger===37 ? "x" : "y"),
49735						(trigger===classes[13] || trigger===classes[15] || trigger===38 || trigger===37 ? -1 : 1)
49736					];
49737					_stop(el);
49738					if(_isNumeric(trigger) && seq.type==="stepped"){return;}
49739					_on(once);
49740					break;
49741				case "off":
49742					_off();
49743					if(once || (d.tweenRunning && seq.dir)){
49744						_on(true);
49745					}
49746					break;
49747			}
49748			
49749			/* starts sequence */
49750			function _on(once){
49751				if(o.snapAmount){seq.scrollAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : seq.dir[0]==="x" ? o.snapAmount[1] : o.snapAmount[0];} /* scrolling snapping */
49752				var c=seq.type!=="stepped", /* continuous scrolling */
49753					t=s ? s : !once ? 1000/60 : c ? steplessSpeed/1.5 : steppedSpeed, /* timer */
49754					m=!once ? 2.5 : c ? 7.5 : 40, /* multiplier */
49755					contentPos=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)],
49756					ratio=[d.scrollRatio.y>10 ? 10 : d.scrollRatio.y,d.scrollRatio.x>10 ? 10 : d.scrollRatio.x],
49757					amount=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*(ratio[1]*m)) : contentPos[0]+(seq.dir[1]*(ratio[0]*m)),
49758					px=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*parseInt(seq.scrollAmount)) : contentPos[0]+(seq.dir[1]*parseInt(seq.scrollAmount)),
49759					to=seq.scrollAmount!=="auto" ? px : amount,
49760					easing=e ? e : !once ? "mcsLinear" : c ? "mcsLinearOut" : "mcsEaseInOut",
49761					onComplete=!once ? false : true;
49762				if(once && t<17){
49763					to=seq.dir[0]==="x" ? contentPos[1] : contentPos[0];
49764				}
49765				_scrollTo(el,to.toString(),{dir:seq.dir[0],scrollEasing:easing,dur:t,onComplete:onComplete});
49766				if(once){
49767					seq.dir=false;
49768					return;
49769				}
49770				clearTimeout(seq.step);
49771				seq.step=setTimeout(function(){
49772					_on();
49773				},t);
49774			}
49775			/* stops sequence */
49776			function _off(){
49777				clearTimeout(seq.step);
49778				_delete(seq,"step");
49779				_stop(el);
49780			}
49781		},
49782		/* -------------------- */
49783		
49784		
49785		/* returns a yx array from value */
49786		_arr=function(val){
49787			var o=$(this).data(pluginPfx).opt,vals=[];
49788			if(typeof val==="function"){val=val();} /* check if the value is a single anonymous function */
49789			/* check if value is object or array, its length and create an array with yx values */
49790			if(!(val instanceof Array)){ /* object value (e.g. {y:"100",x:"100"}, 100 etc.) */
49791				vals[0]=val.y ? val.y : val.x || o.axis==="x" ? null : val;
49792				vals[1]=val.x ? val.x : val.y || o.axis==="y" ? null : val;
49793			}else{ /* array value (e.g. [100,100]) */
49794				vals=val.length>1 ? [val[0],val[1]] : o.axis==="x" ? [null,val[0]] : [val[0],null];
49795			}
49796			/* check if array values are anonymous functions */
49797			if(typeof vals[0]==="function"){vals[0]=vals[0]();}
49798			if(typeof vals[1]==="function"){vals[1]=vals[1]();}
49799			return vals;
49800		},
49801		/* -------------------- */
49802		
49803		
49804		/* translates values (e.g. "top", 100, "100px", "#id") to actual scroll-to positions */
49805		_to=function(val,dir){
49806			if(val==null || typeof val=="undefined"){return;}
49807			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49808				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49809				wrapper=mCSB_container.parent(),
49810				t=typeof val;
49811			if(!dir){dir=o.axis==="x" ? "x" : "y";}
49812			var contentLength=dir==="x" ? mCSB_container.outerWidth(false)-wrapper.width() : mCSB_container.outerHeight(false)-wrapper.height(),
49813				contentPos=dir==="x" ? mCSB_container[0].offsetLeft : mCSB_container[0].offsetTop,
49814				cssProp=dir==="x" ? "left" : "top";
49815			switch(t){
49816				case "function": /* this currently is not used. Consider removing it */
49817					return val();
49818					break;
49819				case "object": /* js/jquery object */
49820					var obj=val.jquery ? val : $(val);
49821					if(!obj.length){return;}
49822					return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0];
49823					break;
49824				case "string": case "number":
49825					if(_isNumeric(val)){ /* numeric value */
49826						return Math.abs(val);
49827					}else if(val.indexOf("%")!==-1){ /* percentage value */
49828						return Math.abs(contentLength*parseInt(val)/100);
49829					}else if(val.indexOf("-=")!==-1){ /* decrease value */
49830						return Math.abs(contentPos-parseInt(val.split("-=")[1]));
49831					}else if(val.indexOf("+=")!==-1){ /* inrease value */
49832						var p=(contentPos+parseInt(val.split("+=")[1]));
49833						return p>=0 ? 0 : Math.abs(p);
49834					}else if(val.indexOf("px")!==-1 && _isNumeric(val.split("px")[0])){ /* pixels string value (e.g. "100px") */
49835						return Math.abs(val.split("px")[0]);
49836					}else{
49837						if(val==="top" || val==="left"){ /* special strings */
49838							return 0;
49839						}else if(val==="bottom"){
49840							return Math.abs(wrapper.height()-mCSB_container.outerHeight(false));
49841						}else if(val==="right"){
49842							return Math.abs(wrapper.width()-mCSB_container.outerWidth(false));
49843						}else if(val==="first" || val==="last"){
49844							var obj=mCSB_container.find(":"+val);
49845							return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0];
49846						}else{
49847							if($(val).length){ /* jquery selector */
49848								return dir==="x" ? _childPos($(val))[1] : _childPos($(val))[0];
49849							}else{ /* other values (e.g. "100em") */
49850								mCSB_container.css(cssProp,val);
49851								methods.update.call(null,$this[0]);
49852								return;
49853							}
49854						}
49855					}
49856					break;
49857			}
49858		},
49859		/* -------------------- */
49860		
49861		
49862		/* calls the update method automatically */
49863		_autoUpdate=function(rem){
49864			var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
49865				mCSB_container=$("#mCSB_"+d.idx+"_container");
49866			if(rem){
49867				/* 
49868				removes autoUpdate timer 
49869				usage: _autoUpdate.call(this,"remove");
49870				*/
49871				clearTimeout(mCSB_container[0].autoUpdate);
49872				_delete(mCSB_container[0],"autoUpdate");
49873				return;
49874			}
49875			upd();
49876			function upd(){
49877				clearTimeout(mCSB_container[0].autoUpdate);
49878				if($this.parents("html").length===0){
49879					/* check element in dom tree */
49880					$this=null;
49881					return;
49882				}
49883				mCSB_container[0].autoUpdate=setTimeout(function(){
49884					/* update on specific selector(s) length and size change */
49885					if(o.advanced.updateOnSelectorChange){
49886						d.poll.change.n=sizesSum();
49887						if(d.poll.change.n!==d.poll.change.o){
49888							d.poll.change.o=d.poll.change.n;
49889							doUpd(3);
49890							return;
49891						}
49892					}
49893					/* update on main element and scrollbar size changes */
49894					if(o.advanced.updateOnContentResize){
49895						d.poll.size.n=$this[0].scrollHeight+$this[0].scrollWidth+mCSB_container[0].offsetHeight+$this[0].offsetHeight+$this[0].offsetWidth;
49896						if(d.poll.size.n!==d.poll.size.o){
49897							d.poll.size.o=d.poll.size.n;
49898							doUpd(1);
49899							return;
49900						}
49901					}
49902					/* update on image load */
49903					if(o.advanced.updateOnImageLoad){
49904						if(!(o.advanced.updateOnImageLoad==="auto" && o.axis==="y")){ //by default, it doesn't run on vertical content
49905							d.poll.img.n=mCSB_container.find("img").length;
49906							if(d.poll.img.n!==d.poll.img.o){
49907								d.poll.img.o=d.poll.img.n;
49908								mCSB_container.find("img").each(function(){
49909									imgLoader(this);
49910								});
49911								return;
49912							}
49913						}
49914					}
49915					if(o.advanced.updateOnSelectorChange || o.advanced.updateOnContentResize || o.advanced.updateOnImageLoad){upd();}
49916				},o.advanced.autoUpdateTimeout);
49917			}
49918			/* a tiny image loader */
49919			function imgLoader(el){
49920				if($(el).hasClass(classes[2])){doUpd(); return;}
49921				var img=new Image();
49922				function createDelegate(contextObject,delegateMethod){
49923					return function(){return delegateMethod.apply(contextObject,arguments);}
49924				}
49925				function imgOnLoad(){
49926					this.onload=null;
49927					$(el).addClass(classes[2]);
49928					doUpd(2);
49929				}
49930				img.onload=createDelegate(img,imgOnLoad);
49931				img.src=el.src;
49932			}
49933			/* returns the total height and width sum of all elements matching the selector */
49934			function sizesSum(){
49935				if(o.advanced.updateOnSelectorChange===true){o.advanced.updateOnSelectorChange="*";}
49936				var total=0,sel=mCSB_container.find(o.advanced.updateOnSelectorChange);
49937				if(o.advanced.updateOnSelectorChange && sel.length>0){sel.each(function(){total+=this.offsetHeight+this.offsetWidth;});}
49938				return total;
49939			}
49940			/* calls the update method */
49941			function doUpd(cb){
49942				clearTimeout(mCSB_container[0].autoUpdate);
49943				methods.update.call(null,$this[0],cb);
49944			}
49945		},
49946		/* -------------------- */
49947		
49948		
49949		/* snaps scrolling to a multiple of a pixels number */
49950		_snapAmount=function(to,amount,offset){
49951			return (Math.round(to/amount)*amount-offset); 
49952		},
49953		/* -------------------- */
49954		
49955		
49956		/* stops content and scrollbar animations */
49957		_stop=function(el){
49958			var d=el.data(pluginPfx),
49959				sel=$("#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal");
49960			sel.each(function(){
49961				_stopTween.call(this);
49962			});
49963		},
49964		/* -------------------- */
49965		
49966		
49967		/* 
49968		ANIMATES CONTENT 
49969		This is where the actual scrolling happens
49970		*/
49971		_scrollTo=function(el,to,options){
49972			var d=el.data(pluginPfx),o=d.opt,
49973				defaults={
49974					trigger:"internal",
49975					dir:"y",
49976					scrollEasing:"mcsEaseOut",
49977					drag:false,
49978					dur:o.scrollInertia,
49979					overwrite:"all",
49980					callbacks:true,
49981					onStart:true,
49982					onUpdate:true,
49983					onComplete:true
49984				},
49985				options=$.extend(defaults,options),
49986				dur=[options.dur,(options.drag ? 0 : options.dur)],
49987				mCustomScrollBox=$("#mCSB_"+d.idx),
49988				mCSB_container=$("#mCSB_"+d.idx+"_container"),
49989				wrapper=mCSB_container.parent(),
49990				totalScrollOffsets=o.callbacks.onTotalScrollOffset ? _arr.call(el,o.callbacks.onTotalScrollOffset) : [0,0],
49991				totalScrollBackOffsets=o.callbacks.onTotalScrollBackOffset ? _arr.call(el,o.callbacks.onTotalScrollBackOffset) : [0,0];
49992			d.trigger=options.trigger;
49993			if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ /* always reset scrollTop/Left */
49994				$(".mCSB_"+d.idx+"_scrollbar").css("visibility","visible");
49995				wrapper.scrollTop(0).scrollLeft(0);
49996			}
49997			if(to==="_resetY" && !d.contentReset.y){
49998				/* callbacks: onOverflowYNone */
49999				if(_cb("onOverflowYNone")){o.callbacks.onOverflowYNone.call(el[0]);}
50000				d.contentReset.y=1;
50001			}
50002			if(to==="_resetX" && !d.contentReset.x){
50003				/* callbacks: onOverflowXNone */
50004				if(_cb("onOverflowXNone")){o.callbacks.onOverflowXNone.call(el[0]);}
50005				d.contentReset.x=1;
50006			}
50007			if(to==="_resetY" || to==="_resetX"){return;}
50008			if((d.contentReset.y || !el[0].mcs) && d.overflowed[0]){
50009				/* callbacks: onOverflowY */
50010				if(_cb("onOverflowY")){o.callbacks.onOverflowY.call(el[0]);}
50011				d.contentReset.x=null;
50012			}
50013			if((d.contentReset.x || !el[0].mcs) && d.overflowed[1]){
50014				/* callbacks: onOverflowX */
50015				if(_cb("onOverflowX")){o.callbacks.onOverflowX.call(el[0]);}
50016				d.contentReset.x=null;
50017			}
50018			if(o.snapAmount){ /* scrolling snapping */
50019				var snapAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : options.dir==="x" ? o.snapAmount[1] : o.snapAmount[0];
50020				to=_snapAmount(to,snapAmount,o.snapOffset);
50021			}
50022			switch(options.dir){
50023				case "x":
50024					var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_horizontal"),
50025						property="left",
50026						contentPos=mCSB_container[0].offsetLeft,
50027						limit=[
50028							mCustomScrollBox.width()-mCSB_container.outerWidth(false),
50029							mCSB_dragger.parent().width()-mCSB_dragger.width()
50030						],
50031						scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.x)],
50032						tso=totalScrollOffsets[1],
50033						tsbo=totalScrollBackOffsets[1],
50034						totalScrollOffset=tso>0 ? tso/d.scrollRatio.x : 0,
50035						totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.x : 0;
50036					break;
50037				case "y":
50038					var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_vertical"),
50039						property="top",
50040						contentPos=mCSB_container[0].offsetTop,
50041						limit=[
50042							mCustomScrollBox.height()-mCSB_container.outerHeight(false),
50043							mCSB_dragger.parent().height()-mCSB_dragger.height()
50044						],
50045						scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.y)],
50046						tso=totalScrollOffsets[0],
50047						tsbo=totalScrollBackOffsets[0],
50048						totalScrollOffset=tso>0 ? tso/d.scrollRatio.y : 0,
50049						totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.y : 0;
50050					break;
50051			}
50052			if(scrollTo[1]<0 || (scrollTo[0]===0 && scrollTo[1]===0)){
50053				scrollTo=[0,0];
50054			}else if(scrollTo[1]>=limit[1]){
50055				scrollTo=[limit[0],limit[1]];
50056			}else{
50057				scrollTo[0]=-scrollTo[0];
50058			}
50059			if(!el[0].mcs){
50060				_mcs();  /* init mcs object (once) to make it available before callbacks */
50061				if(_cb("onInit")){o.callbacks.onInit.call(el[0]);} /* callbacks: onInit */
50062			}
50063			clearTimeout(mCSB_container[0].onCompleteTimeout);
50064			_tweenTo(mCSB_dragger[0],property,Math.round(scrollTo[1]),dur[1],options.scrollEasing);
50065			if(!d.tweenRunning && ((contentPos===0 && scrollTo[0]>=0) || (contentPos===limit[0] && scrollTo[0]<=limit[0]))){return;}
50066			_tweenTo(mCSB_container[0],property,Math.round(scrollTo[0]),dur[0],options.scrollEasing,options.overwrite,{
50067				onStart:function(){
50068					if(options.callbacks && options.onStart && !d.tweenRunning){
50069						/* callbacks: onScrollStart */
50070						if(_cb("onScrollStart")){_mcs(); o.callbacks.onScrollStart.call(el[0]);}
50071						d.tweenRunning=true;
50072						_onDragClasses(mCSB_dragger);
50073						d.cbOffsets=_cbOffsets();
50074					}
50075				},onUpdate:function(){
50076					if(options.callbacks && options.onUpdate){
50077						/* callbacks: whileScrolling */
50078						if(_cb("whileScrolling")){_mcs(); o.callbacks.whileScrolling.call(el[0]);}
50079					}
50080				},onComplete:function(){
50081					if(options.callbacks && options.onComplete){
50082						if(o.axis==="yx"){clearTimeout(mCSB_container[0].onCompleteTimeout);}
50083						var t=mCSB_container[0].idleTimer || 0;
50084						mCSB_container[0].onCompleteTimeout=setTimeout(function(){
50085							/* callbacks: onScroll, onTotalScroll, onTotalScrollBack */
50086							if(_cb("onScroll")){_mcs(); o.callbacks.onScroll.call(el[0]);}
50087							if(_cb("onTotalScroll") && scrollTo[1]>=limit[1]-totalScrollOffset && d.cbOffsets[0]){_mcs(); o.callbacks.onTotalScroll.call(el[0]);}
50088							if(_cb("onTotalScrollBack") && scrollTo[1]<=totalScrollBackOffset && d.cbOffsets[1]){_mcs(); o.callbacks.onTotalScrollBack.call(el[0]);}
50089							d.tweenRunning=false;
50090							mCSB_container[0].idleTimer=0;
50091							_onDragClasses(mCSB_dragger,"hide");
50092						},t);
50093					}
50094				}
50095			});
50096			/* checks if callback function exists */
50097			function _cb(cb){
50098				return d && o.callbacks[cb] && typeof o.callbacks[cb]==="function";
50099			}
50100			/* checks whether callback offsets always trigger */
50101			function _cbOffsets(){
50102				return [o.callbacks.alwaysTriggerOffsets || contentPos>=limit[0]+tso,o.callbacks.alwaysTriggerOffsets || contentPos<=-tsbo];
50103			}
50104			/* 
50105			populates object with useful values for the user 
50106			values: 
50107				content: this.mcs.content
50108				content top position: this.mcs.top 
50109				content left position: this.mcs.left 
50110				dragger top position: this.mcs.draggerTop 
50111				dragger left position: this.mcs.draggerLeft 
50112				scrolling y percentage: this.mcs.topPct 
50113				scrolling x percentage: this.mcs.leftPct 
50114				scrolling direction: this.mcs.direction
50115			*/
50116			function _mcs(){
50117				var cp=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], /* content position */
50118					dp=[mCSB_dragger[0].offsetTop,mCSB_dragger[0].offsetLeft], /* dragger position */
50119					cl=[mCSB_container.outerHeight(false),mCSB_container.outerWidth(false)], /* content length */
50120					pl=[mCustomScrollBox.height(),mCustomScrollBox.width()]; /* content parent length */
50121				el[0].mcs={
50122					content:mCSB_container, /* original content wrapper as jquery object */
50123					top:cp[0],left:cp[1],draggerTop:dp[0],draggerLeft:dp[1],
50124					topPct:Math.round((100*Math.abs(cp[0]))/(Math.abs(cl[0])-pl[0])),leftPct:Math.round((100*Math.abs(cp[1]))/(Math.abs(cl[1])-pl[1])),
50125					direction:options.dir
50126				};
50127				/* 
50128				this refers to the original element containing the scrollbar(s)
50129				usage: this.mcs.top, this.mcs.leftPct etc. 
50130				*/
50131			}
50132		},
50133		/* -------------------- */
50134		
50135		
50136		/* 
50137		CUSTOM JAVASCRIPT ANIMATION TWEEN 
50138		Lighter and faster than jquery animate() and css transitions 
50139		Animates top/left properties and includes easings 
50140		*/
50141		_tweenTo=function(el,prop,to,duration,easing,overwrite,callbacks){
50142			if(!el._mTween){el._mTween={top:{},left:{}};}
50143			var callbacks=callbacks || {},
50144				onStart=callbacks.onStart || function(){},onUpdate=callbacks.onUpdate || function(){},onComplete=callbacks.onComplete || function(){},
50145				startTime=_getTime(),_delay,progress=0,from=el.offsetTop,elStyle=el.style,_request,tobj=el._mTween[prop];
50146			if(prop==="left"){from=el.offsetLeft;}
50147			var diff=to-from;
50148			tobj.stop=0;
50149			if(overwrite!=="none"){_cancelTween();}
50150			_startTween();
50151			function _step(){
50152				if(tobj.stop){return;}
50153				if(!progress){onStart.call();}
50154				progress=_getTime()-startTime;
50155				_tween();
50156				if(progress>=tobj.time){
50157					tobj.time=(progress>tobj.time) ? progress+_delay-(progress-tobj.time) : progress+_delay-1;
50158					if(tobj.time<progress+1){tobj.time=progress+1;}
50159				}
50160				if(tobj.time<duration){tobj.id=_request(_step);}else{onComplete.call();}
50161			}
50162			function _tween(){
50163				if(duration>0){
50164					tobj.currVal=_ease(tobj.time,from,diff,duration,easing);
50165					elStyle[prop]=Math.round(tobj.currVal)+"px";
50166				}else{
50167					elStyle[prop]=to+"px";
50168				}
50169				onUpdate.call();
50170			}
50171			function _startTween(){
50172				_delay=1000/60;
50173				tobj.time=progress+_delay;
50174				_request=(!window.requestAnimationFrame) ? function(f){_tween(); return setTimeout(f,0.01);} : window.requestAnimationFrame;
50175				tobj.id=_request(_step);
50176			}
50177			function _cancelTween(){
50178				if(tobj.id==null){return;}
50179				if(!window.requestAnimationFrame){clearTimeout(tobj.id);
50180				}else{window.cancelAnimationFrame(tobj.id);}
50181				tobj.id=null;
50182			}
50183			function _ease(t,b,c,d,type){
50184				switch(type){
50185					case "linear": case "mcsLinear":
50186						return c*t/d + b;
50187						break;
50188					case "mcsLinearOut":
50189						t/=d; t--; return c * Math.sqrt(1 - t*t) + b;
50190						break;
50191					case "easeInOutSmooth":
50192						t/=d/2;
50193						if(t<1) return c/2*t*t + b;
50194						t--;
50195						return -c/2 * (t*(t-2) - 1) + b;
50196						break;
50197					case "easeInOutStrong":
50198						t/=d/2;
50199						if(t<1) return c/2 * Math.pow( 2, 10 * (t - 1) ) + b;
50200						t--;
50201						return c/2 * ( -Math.pow( 2, -10 * t) + 2 ) + b;
50202						break;
50203					case "easeInOut": case "mcsEaseInOut":
50204						t/=d/2;
50205						if(t<1) return c/2*t*t*t + b;
50206						t-=2;
50207						return c/2*(t*t*t + 2) + b;
50208						break;
50209					case "easeOutSmooth":
50210						t/=d; t--;
50211						return -c * (t*t*t*t - 1) + b;
50212						break;
50213					case "easeOutStrong":
50214						return c * ( -Math.pow( 2, -10 * t/d ) + 1 ) + b;
50215						break;
50216					case "easeOut": case "mcsEaseOut": default:
50217						var ts=(t/=d)*t,tc=ts*t;
50218						return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t);
50219				}
50220			}
50221		},
50222		/* -------------------- */
50223		
50224		
50225		/* returns current time */
50226		_getTime=function(){
50227			if(window.performance && window.performance.now){
50228				return window.performance.now();
50229			}else{
50230				if(window.performance && window.performance.webkitNow){
50231					return window.performance.webkitNow();
50232				}else{
50233					if(Date.now){return Date.now();}else{return new Date().getTime();}
50234				}
50235			}
50236		},
50237		/* -------------------- */
50238		
50239		
50240		/* stops a tween */
50241		_stopTween=function(){
50242			var el=this;
50243			if(!el._mTween){el._mTween={top:{},left:{}};}
50244			var props=["top","left"];
50245			for(var i=0; i<props.length; i++){
50246				var prop=props[i];
50247				if(el._mTween[prop].id){
50248					if(!window.requestAnimationFrame){clearTimeout(el._mTween[prop].id);
50249					}else{window.cancelAnimationFrame(el._mTween[prop].id);}
50250					el._mTween[prop].id=null;
50251					el._mTween[prop].stop=1;
50252				}
50253			}
50254		},
50255		/* -------------------- */
50256		
50257		
50258		/* deletes a property (avoiding the exception thrown by IE) */
50259		_delete=function(c,m){
50260			try{delete c[m];}catch(e){c[m]=null;}
50261		},
50262		/* -------------------- */
50263		
50264		
50265		/* detects left mouse button */
50266		_mouseBtnLeft=function(e){
50267			return !(e.which && e.which!==1);
50268		},
50269		/* -------------------- */
50270		
50271		
50272		/* detects if pointer type event is touch */
50273		_pointerTouch=function(e){
50274			var t=e.originalEvent.pointerType;
50275			return !(t && t!=="touch" && t!==2);
50276		},
50277		/* -------------------- */
50278		
50279		
50280		/* checks if value is numeric */
50281		_isNumeric=function(val){
50282			return !isNaN(parseFloat(val)) && isFinite(val);
50283		},
50284		/* -------------------- */
50285		
50286		
50287		/* returns element position according to content */
50288		_childPos=function(el){
50289			var p=el.parents(".mCSB_container");
50290			return [el.offset().top-p.offset().top,el.offset().left-p.offset().left];
50291		},
50292		/* -------------------- */
50293		
50294		
50295		/* checks if browser tab is hidden/inactive via Page Visibility API */
50296		_isTabHidden=function(){
50297			var prop=_getHiddenProp();
50298			if(!prop) return false;
50299			return document[prop];
50300			function _getHiddenProp(){
50301				var pfx=["webkit","moz","ms","o"];
50302				if("hidden" in document) return "hidden"; //natively supported
50303				for(var i=0; i<pfx.length; i++){ //prefixed
50304				    if((pfx[i]+"Hidden") in document) 
50305				        return pfx[i]+"Hidden";
50306				}
50307				return null; //not supported
50308			}
50309		};
50310		/* -------------------- */
50311		
50312	
50313	
50314	
50315	
50316	/* 
50317	----------------------------------------
50318	PLUGIN SETUP 
50319	----------------------------------------
50320	*/
50321	
50322	/* plugin constructor functions */
50323	$.fn[pluginNS]=function(method){ /* usage: $(selector).mCustomScrollbar(); */
50324		if(methods[method]){
50325			return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
50326		}else if(typeof method==="object" || !method){
50327			return methods.init.apply(this,arguments);
50328		}else{
50329			$.error("Method "+method+" does not exist");
50330		}
50331	};
50332	$[pluginNS]=function(method){ /* usage: $.mCustomScrollbar(); */
50333		if(methods[method]){
50334			return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
50335		}else if(typeof method==="object" || !method){
50336			return methods.init.apply(this,arguments);
50337		}else{
50338			$.error("Method "+method+" does not exist");
50339		}
50340	};
50341	
50342	/* 
50343	allow setting plugin default options. 
50344	usage: $.mCustomScrollbar.defaults.scrollInertia=500; 
50345	to apply any changed default options on default selectors (below), use inside document ready fn 
50346	e.g.: $(document).ready(function(){ $.mCustomScrollbar.defaults.scrollInertia=500; });
50347	*/
50348	$[pluginNS].defaults=defaults;
50349	
50350	/* 
50351	add window object (window.mCustomScrollbar) 
50352	usage: if(window.mCustomScrollbar){console.log("custom scrollbar plugin loaded");}
50353	*/
50354	window[pluginNS]=true;
50355	
50356	$(window).bind("load",function(){
50357		
50358		$(defaultSelector)[pluginNS](); /* add scrollbars automatically on default selector */
50359		
50360		/* extend jQuery expressions */
50361		$.extend($.expr[":"],{
50362			/* checks if element is within scrollable viewport */
50363			mcsInView:$.expr[":"].mcsInView || function(el){
50364				var $el=$(el),content=$el.parents(".mCSB_container"),wrapper,cPos;
50365				if(!content.length){return;}
50366				wrapper=content.parent();
50367				cPos=[content[0].offsetTop,content[0].offsetLeft];
50368				return 	cPos[0]+_childPos($el)[0]>=0 && cPos[0]+_childPos($el)[0]<wrapper.height()-$el.outerHeight(false) && 
50369						cPos[1]+_childPos($el)[1]>=0 && cPos[1]+_childPos($el)[1]<wrapper.width()-$el.outerWidth(false);
50370			},
50371			/* checks if element or part of element is in view of scrollable viewport */
50372			mcsInSight:$.expr[":"].mcsInSight || function(el,i,m){
50373				var $el=$(el),elD,content=$el.parents(".mCSB_container"),wrapperView,pos,wrapperViewPct,
50374					pctVals=m[3]==="exact" ? [[1,0],[1,0]] : [[0.9,0.1],[0.6,0.4]];
50375				if(!content.length){return;}
50376				elD=[$el.outerHeight(false),$el.outerWidth(false)];
50377				pos=[content[0].offsetTop+_childPos($el)[0],content[0].offsetLeft+_childPos($el)[1]];
50378				wrapperView=[content.parent()[0].offsetHeight,content.parent()[0].offsetWidth];
50379				wrapperViewPct=[elD[0]<wrapperView[0] ? pctVals[0] : pctVals[1],elD[1]<wrapperView[1] ? pctVals[0] : pctVals[1]];
50380				return 	pos[0]-(wrapperView[0]*wrapperViewPct[0][0])<0 && pos[0]+elD[0]-(wrapperView[0]*wrapperViewPct[0][1])>=0 && 
50381						pos[1]-(wrapperView[1]*wrapperViewPct[1][0])<0 && pos[1]+elD[1]-(wrapperView[1]*wrapperViewPct[1][1])>=0;
50382			},
50383			/* checks if element is overflowed having visible scrollbar(s) */
50384			mcsOverflow:$.expr[":"].mcsOverflow || function(el){
50385				var d=$(el).data(pluginPfx);
50386				if(!d){return;}
50387				return d.overflowed[0] || d.overflowed[1];
50388			}
50389		});
50390	
50391	});
50392
50393}))}));
vendor: 2,721 bytes, lines 50393-50519
50393
50394/**
50395 * Fizzy UI utils v2.0.7
50396 * MIT license
50397 */
50398
50399/*jshint browser: true, undef: true, unused: true, strict: true */
50400
50401( function( window, factory ) {
50402  // universal module definition
50403  /*jshint strict: false */ /*globals define, module, require */
50404
50405  if ( typeof define == 'function' && define.amd ) {
50406    // AMD
50407    define( [
50408      'desandro-matches-selector/matches-selector'
50409    ], function( matchesSelector ) {
50410      return factory( window, matchesSelector );
50411    });
50412  } else if ( typeof module == 'object' && module.exports ) {
50413    // CommonJS
50414    module.exports = factory(
50415      window,
50416      require('desandro-matches-selector')
50417    );
50418  } else {
50419    // browser global
50420    window.fizzyUIUtils = factory(
50421      window,
50422      window.matchesSelector
50423    );
50424  }
50425
50426}( window, function factory( window, matchesSelector ) {
50427
50428'use strict';
50429
50430var utils = {};
50431
50432// ----- extend ----- //
50433
50434// extends objects
50435utils.extend = function( a, b ) {
50436  for ( var prop in b ) {
50437    a[ prop ] = b[ prop ];
50438  }
50439  return a;
50440};
50441
50442// ----- modulo ----- //
50443
50444utils.modulo = function( num, div ) {
50445  return ( ( num % div ) + div ) % div;
50446};
50447
50448// ----- makeArray ----- //
50449
50450var arraySlice = Array.prototype.slice;
50451
50452// turn element or nodeList into an array
50453utils.makeArray = function( obj ) {
50454  if ( Array.isArray( obj ) ) {
50455    // use object if already an array
50456    return obj;
50457  }
50458  // return empty array if undefined or null. #6
50459  if ( obj === null || obj === undefined ) {
50460    return [];
50461  }
50462
50463  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
50464  if ( isArrayLike ) {
50465    // convert nodeList to array
50466    return arraySlice.call( obj );
50467  }
50468
50469  // array of single index
50470  return [ obj ];
50471};
50472
50473// ----- removeFrom ----- //
50474
50475utils.removeFrom = function( ary, obj ) {
50476  var index = ary.indexOf( obj );
50477  if ( index != -1 ) {
50478    ary.splice( index, 1 );
50479  }
50480};
50481
50482// ----- getParent ----- //
50483
50484utils.getParent = function( elem, selector ) {
50485  while ( elem.parentNode && elem != document.body ) {
50486    elem = elem.parentNode;
50487    if ( matchesSelector( elem, selector ) ) {
50488      return elem;
50489    }
50490  }
50491};
50492
50493// ----- getQueryElement ----- //
50494
50495// use element as selector string
50496utils.getQueryElement = function( elem ) {
50497  if ( typeof elem == 'string' ) {
50498    return document.querySelector( elem );
50499  }
50500  return elem;
50501};
50502
50503// ----- handleEvent ----- //
50504
50505// enable .ontype to trigger from .addEventListener( elem, 'type' )
50506utils.handleEvent = function( event ) {
50507  var method = 'on' + event.type;
50508  if ( this[ method ] ) {
50509    this[ method ]( event );
50510  }
50511};
50512
50513// ----- filterFindElements ----- //
50514
50515utils.filterFindElements = function( elems, selector ) {
50516  // make array of elems
50517  elems = utils.makeArray( elems );
50518  var ffElems = [];
50519
vendor: 3,289 bytes, lines 50520-50635
50520  elems.forEach( function( elem ) {
50521    // check that elem is an actual element
50522    if ( !( elem instanceof HTMLElement ) ) {
50523      return;
50524    }
50525    // add elem if no selector
50526    if ( !selector ) {
50527      ffElems.push( elem );
50528      return;
50529    }
50530    // filter & find items if we have a selector
50531    // filter
50532    if ( matchesSelector( elem, selector ) ) {
50533      ffElems.push( elem );
50534    }
50535    // find children
50536    var childElems = elem.querySelectorAll( selector );
50537    // concat childElems to filterFound array
50538    for ( var i=0; i < childElems.length; i++ ) {
50539      ffElems.push( childElems[i] );
50540    }
50541  });
50542
50543  return ffElems;
50544};
50545
50546// ----- debounceMethod ----- //
50547
50548utils.debounceMethod = function( _class, methodName, threshold ) {
50549  threshold = threshold || 100;
50550  // original method
50551  var method = _class.prototype[ methodName ];
50552  var timeoutName = methodName + 'Timeout';
50553
50554  _class.prototype[ methodName ] = function() {
50555    var timeout = this[ timeoutName ];
50556    clearTimeout( timeout );
50557
50558    var args = arguments;
50559    var _this = this;
50560    this[ timeoutName ] = setTimeout( function() {
50561      method.apply( _this, args );
50562      delete _this[ timeoutName ];
50563    }, threshold );
50564  };
50565};
50566
50567// ----- docReady ----- //
50568
50569utils.docReady = function( callback ) {
50570  var readyState = document.readyState;
50571  if ( readyState == 'complete' || readyState == 'interactive' ) {
50572    // do async to allow for other scripts to run. metafizzy/flickity#441
50573    setTimeout( callback );
50574  } else {
50575    document.addEventListener( 'DOMContentLoaded', callback );
50576  }
50577};
50578
50579// ----- htmlInit ----- //
50580
50581// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
50582utils.toDashed = function( str ) {
50583  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
50584    return $1 + '-' + $2;
50585  }).toLowerCase();
50586};
50587
50588var console = window.console;
50589/**
50590 * allow user to initialize classes via [data-namespace] or .js-namespace class
50591 * htmlInit( Widget, 'widgetName' )
50592 * options are parsed from data-namespace-options
50593 */
50594utils.htmlInit = function( WidgetClass, namespace ) {
50595  utils.docReady( function() {
50596    var dashedNamespace = utils.toDashed( namespace );
50597    var dataAttr = 'data-' + dashedNamespace;
50598    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
50599    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
50600    var elems = utils.makeArray( dataAttrElems )
50601      .concat( utils.makeArray( jsDashElems ) );
50602    var dataOptionsAttr = dataAttr + '-options';
50603    var jQuery = window.jQuery;
50604
50605    elems.forEach( function( elem ) {
50606      var attr = elem.getAttribute( dataAttr ) ||
50607        elem.getAttribute( dataOptionsAttr );
50608      var options;
50609      try {
50610        options = attr && JSON.parse( attr );
50611      } catch ( error ) {
50612        // log error, do not initialize
50613        if ( console ) {
50614          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
50615          ': ' + error );
50616        }
50617        return;
50618      }
50619      // initialize
50620      var instance = new WidgetClass( elem, options );
50621      // make available via $().data('namespace')
50622      if ( jQuery ) {
50623        jQuery.data( elem, namespace, instance );
50624      }
50625    });
50626
50627  });
50628};
50629
50630// -----  ----- //
50631
50632return utils;
50633
50634}));
50635
vendor: 39,554 bytes, lines 50636-52203
50636/*!
50637 * Masonry PACKAGED v4.2.2
50638 * Cascading grid layout library
50639 * https://masonry.desandro.com
50640 * MIT License
50641 * by David DeSandro
50642 */
50643
50644/**
50645 * Bridget makes jQuery widgets
50646 * v2.0.1
50647 * MIT license
50648 */
50649
50650/* jshint browser: true, strict: true, undef: true, unused: true */
50651
50652( function( window, factory ) {
50653  // universal module definition
50654  /*jshint strict: false */ /* globals define, module, require */
50655  if ( typeof define == 'function' && define.amd ) {
50656    // AMD
50657    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
50658      return factory( window, jQuery );
50659    });
50660  } else if ( typeof module == 'object' && module.exports ) {
50661    // CommonJS
50662    module.exports = factory(
50663      window,
50664      require('jquery')
50665    );
50666  } else {
50667    // browser global
50668    window.jQueryBridget = factory(
50669      window,
50670      window.jQuery
50671    );
50672  }
50673
50674}( window, function factory( window, jQuery ) {
50675'use strict';
50676
50677// ----- utils ----- //
50678
50679var arraySlice = Array.prototype.slice;
50680
50681// helper function for logging errors
50682// $.error breaks jQuery chaining
50683var console = window.console;
50684var logError = typeof console == 'undefined' ? function() {} :
50685  function( message ) {
50686    console.error( message );
50687  };
50688
50689// ----- jQueryBridget ----- //
50690
50691function jQueryBridget( namespace, PluginClass, $ ) {
50692  $ = $ || jQuery || window.jQuery;
50693  if ( !$ ) {
50694    return;
50695  }
50696
50697  // add option method -> $().plugin('option', {...})
50698  if ( !PluginClass.prototype.option ) {
50699    // option setter
50700    PluginClass.prototype.option = function( opts ) {
50701      // bail out if not an object
50702      if ( !$.isPlainObject( opts ) ){
50703        return;
50704      }
50705      this.options = $.extend( true, this.options, opts );
50706    };
50707  }
50708
50709  // make jQuery plugin
50710  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
50711    if ( typeof arg0 == 'string' ) {
50712      // method call $().plugin( 'methodName', { options } )
50713      // shift arguments by 1
50714      var args = arraySlice.call( arguments, 1 );
50715      return methodCall( this, arg0, args );
50716    }
50717    // just $().plugin({ options })
50718    plainCall( this, arg0 );
50719    return this;
50720  };
50721
50722  // $().plugin('methodName')
50723  function methodCall( $elems, methodName, args ) {
50724    var returnValue;
50725    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
50726
50727    $elems.each( function( i, elem ) {
50728      // get instance
50729      var instance = $.data( elem, namespace );
50730      if ( !instance ) {
50731        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
50732          pluginMethodStr );
50733        return;
50734      }
50735
50736      var method = instance[ methodName ];
50737      if ( !method || methodName.charAt(0) == '_' ) {
50738        logError( pluginMethodStr + ' is not a valid method' );
50739        return;
50740      }
50741
50742      // apply method, get return value
50743      var value = method.apply( instance, args );
50744      // set return value if value is returned, use only first value
50745      returnValue = returnValue === undefined ? value : returnValue;
50746    });
50747
50748    return returnValue !== undefined ? returnValue : $elems;
50749  }
50750
50751  function plainCall( $elems, options ) {
50752    $elems.each( function( i, elem ) {
50753      var instance = $.data( elem, namespace );
50754      if ( instance ) {
50755        // set options & init
50756        instance.option( options );
50757        instance._init();
50758      } else {
50759        // initialize new instance
50760        instance = new PluginClass( elem, options );
50761        $.data( elem, namespace, instance );
50762      }
50763    });
50764  }
50765
50766  updateJQuery( $ );
50767
50768}
50769
50770// ----- updateJQuery ----- //
50771
50772// set $.bridget for v1 backwards compatibility
50773function updateJQuery( $ ) {
50774  if ( !$ || ( $ && $.bridget ) ) {
50775    return;
50776  }
50777  $.bridget = jQueryBridget;
50778}
50779
50780updateJQuery( jQuery || window.jQuery );
50781
50782// -----  ----- //
50783
50784return jQueryBridget;
50785
50786}));
50787
50788/**
50789 * EvEmitter v1.1.0
50790 * Lil' event emitter
50791 * MIT License
50792 */
50793
50794/* jshint unused: true, undef: true, strict: true */
50795
50796( function( global, factory ) {
50797  // universal module definition
50798  /* jshint strict: false */ /* globals define, module, window */
50799  if ( typeof define == 'function' && define.amd ) {
50800    // AMD - RequireJS
50801    define( 'ev-emitter/ev-emitter',factory );
50802  } else if ( typeof module == 'object' && module.exports ) {
50803    // CommonJS - Browserify, Webpack
50804    module.exports = factory();
50805  } else {
50806    // Browser globals
50807    global.EvEmitter = factory();
50808  }
50809
50810}( typeof window != 'undefined' ? window : this, function() {
50811
50812
50813
50814function EvEmitter() {}
50815
50816var proto = EvEmitter.prototype;
50817
50818proto.on = function( eventName, listener ) {
50819  if ( !eventName || !listener ) {
50820    return;
50821  }
50822  // set events hash
50823  var events = this._events = this._events || {};
50824  // set listeners array
50825  var listeners = events[ eventName ] = events[ eventName ] || [];
50826  // only add once
50827  if ( listeners.indexOf( listener ) == -1 ) {
50828    listeners.push( listener );
50829  }
50830
50831  return this;
50832};
50833
50834proto.once = function( eventName, listener ) {
50835  if ( !eventName || !listener ) {
50836    return;
50837  }
50838  // add event
50839  this.on( eventName, listener );
50840  // set once flag
50841  // set onceEvents hash
50842  var onceEvents = this._onceEvents = this._onceEvents || {};
50843  // set onceListeners object
50844  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
50845  // set flag
50846  onceListeners[ listener ] = true;
50847
50848  return this;
50849};
50850
50851proto.off = function( eventName, listener ) {
50852  var listeners = this._events && this._events[ eventName ];
50853  if ( !listeners || !listeners.length ) {
50854    return;
50855  }
50856  var index = listeners.indexOf( listener );
50857  if ( index != -1 ) {
50858    listeners.splice( index, 1 );
50859  }
50860
50861  return this;
50862};
50863
50864proto.emitEvent = function( eventName, args ) {
50865  var listeners = this._events && this._events[ eventName ];
50866  if ( !listeners || !listeners.length ) {
50867    return;
50868  }
50869  // copy over to avoid interference if .off() in listener
50870  listeners = listeners.slice(0);
50871  args = args || [];
50872  // once stuff
50873  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
50874
50875  for ( var i=0; i < listeners.length; i++ ) {
50876    var listener = listeners[i]
50877    var isOnce = onceListeners && onceListeners[ listener ];
50878    if ( isOnce ) {
50879      // remove listener
50880      // remove before trigger to prevent recursion
50881      this.off( eventName, listener );
50882      // unset once flag
50883      delete onceListeners[ listener ];
50884    }
50885    // trigger listener
50886    listener.apply( this, args );
50887  }
50888
50889  return this;
50890};
50891
50892proto.allOff = function() {
50893  delete this._events;
50894  delete this._onceEvents;
50895};
50896
50897return EvEmitter;
50898
50899}));
50900
50901/*!
50902 * getSize v2.0.3
50903 * measure size of elements
50904 * MIT license
50905 */
50906
50907/* jshint browser: true, strict: true, undef: true, unused: true */
50908/* globals console: false */
50909
50910( function( window, factory ) {
50911  /* jshint strict: false */ /* globals define, module */
50912  if ( typeof define == 'function' && define.amd ) {
50913    // AMD
50914    define( 'get-size/get-size',factory );
50915  } else if ( typeof module == 'object' && module.exports ) {
50916    // CommonJS
50917    module.exports = factory();
50918  } else {
50919    // browser global
50920    window.getSize = factory();
50921  }
50922
50923})( window, function factory() {
50924'use strict';
50925
50926// -------------------------- helpers -------------------------- //
50927
50928// get a number from a string, not a percentage
50929function getStyleSize( value ) {
50930  var num = parseFloat( value );
50931  // not a percent like '100%', and a number
50932  var isValid = value.indexOf('%') == -1 && !isNaN( num );
50933  return isValid && num;
50934}
50935
50936function noop() {}
50937
50938var logError = typeof console == 'undefined' ? noop :
50939  function( message ) {
50940    console.error( message );
50941  };
50942
50943// -------------------------- measurements -------------------------- //
50944
50945var measurements = [
50946  'paddingLeft',
50947  'paddingRight',
50948  'paddingTop',
50949  'paddingBottom',
50950  'marginLeft',
50951  'marginRight',
50952  'marginTop',
50953  'marginBottom',
50954  'borderLeftWidth',
50955  'borderRightWidth',
50956  'borderTopWidth',
50957  'borderBottomWidth'
50958];
50959
50960var measurementsLength = measurements.length;
50961
50962function getZeroSize() {
50963  var size = {
50964    width: 0,
50965    height: 0,
50966    innerWidth: 0,
50967    innerHeight: 0,
50968    outerWidth: 0,
50969    outerHeight: 0
50970  };
50971  for ( var i=0; i < measurementsLength; i++ ) {
50972    var measurement = measurements[i];
50973    size[ measurement ] = 0;
50974  }
50975  return size;
50976}
50977
50978// -------------------------- getStyle -------------------------- //
50979
50980/**
50981 * getStyle, get style of element, check for Firefox bug
50982 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
50983 */
50984function getStyle( elem ) {
50985  var style = getComputedStyle( elem );
50986  if ( !style ) {
50987    logError( 'Style returned ' + style +
50988      '. Are you running this code in a hidden iframe on Firefox? ' +
50989      'See https://bit.ly/getsizebug1' );
50990  }
50991  return style;
50992}
50993
50994// -------------------------- setup -------------------------- //
50995
50996var isSetup = false;
50997
50998var isBoxSizeOuter;
50999
51000/**
51001 * setup
51002 * check isBoxSizerOuter
51003 * do on first getSize() rather than on page load for Firefox bug
51004 */
51005function setup() {
51006  // setup once
51007  if ( isSetup ) {
51008    return;
51009  }
51010  isSetup = true;
51011
51012  // -------------------------- box sizing -------------------------- //
51013
51014  /**
51015   * Chrome & Safari measure the outer-width on style.width on border-box elems
51016   * IE11 & Firefox<29 measures the inner-width
51017   */
51018  var div = document.createElement('div');
51019  div.style.width = '200px';
51020  div.style.padding = '1px 2px 3px 4px';
51021  div.style.borderStyle = 'solid';
51022  div.style.borderWidth = '1px 2px 3px 4px';
51023  div.style.boxSizing = 'border-box';
51024
51025  var body = document.body || document.documentElement;
51026  body.appendChild( div );
51027  var style = getStyle( div );
51028  // round value for browser zoom. desandro/masonry#928
51029  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
51030  getSize.isBoxSizeOuter = isBoxSizeOuter;
51031
51032  body.removeChild( div );
51033}
51034
51035// -------------------------- getSize -------------------------- //
51036
51037function getSize( elem ) {
51038  setup();
51039
51040  // use querySeletor if elem is string
51041  if ( typeof elem == 'string' ) {
51042    elem = document.querySelector( elem );
51043  }
51044
51045  // do not proceed on non-objects
51046  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
51047    return;
51048  }
51049
51050  var style = getStyle( elem );
51051
51052  // if hidden, everything is 0
51053  if ( style.display == 'none' ) {
51054    return getZeroSize();
51055  }
51056
51057  var size = {};
51058  size.width = elem.offsetWidth;
51059  size.height = elem.offsetHeight;
51060
51061  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
51062
51063  // get all measurements
51064  for ( var i=0; i < measurementsLength; i++ ) {
51065    var measurement = measurements[i];
51066    var value = style[ measurement ];
51067    var num = parseFloat( value );
51068    // any 'auto', 'medium' value will be 0
51069    size[ measurement ] = !isNaN( num ) ? num : 0;
51070  }
51071
51072  var paddingWidth = size.paddingLeft + size.paddingRight;
51073  var paddingHeight = size.paddingTop + size.paddingBottom;
51074  var marginWidth = size.marginLeft + size.marginRight;
51075  var marginHeight = size.marginTop + size.marginBottom;
51076  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
51077  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
51078
51079  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
51080
51081  // overwrite width and height if we can get it from style
51082  var styleWidth = getStyleSize( style.width );
51083  if ( styleWidth !== false ) {
51084    size.width = styleWidth +
51085      // add padding and border unless it's already including it
51086      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
51087  }
51088
51089  var styleHeight = getStyleSize( style.height );
51090  if ( styleHeight !== false ) {
51091    size.height = styleHeight +
51092      // add padding and border unless it's already including it
51093      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
51094  }
51095
51096  size.innerWidth = size.width - ( paddingWidth + borderWidth );
51097  size.innerHeight = size.height - ( paddingHeight + borderHeight );
51098
51099  size.outerWidth = size.width + marginWidth;
51100  size.outerHeight = size.height + marginHeight;
51101
51102  return size;
51103}
51104
51105return getSize;
51106
51107});
51108
51109/**
51110 * matchesSelector v2.0.2
51111 * matchesSelector( element, '.selector' )
51112 * MIT license
51113 */
51114
51115/*jshint browser: true, strict: true, undef: true, unused: true */
51116
51117( function( window, factory ) {
51118  /*global define: false, module: false */
51119  'use strict';
51120  // universal module definition
51121  if ( typeof define == 'function' && define.amd ) {
51122    // AMD
51123    define( 'desandro-matches-selector/matches-selector',factory );
51124  } else if ( typeof module == 'object' && module.exports ) {
51125    // CommonJS
51126    module.exports = factory();
51127  } else {
51128    // browser global
51129    window.matchesSelector = factory();
51130  }
51131
51132}( window, function factory() {
51133  'use strict';
51134
51135  var matchesMethod = ( function() {
51136    var ElemProto = window.Element.prototype;
51137    // check for the standard method name first
51138    if ( ElemProto.matches ) {
51139      return 'matches';
51140    }
51141    // check un-prefixed
51142    if ( ElemProto.matchesSelector ) {
51143      return 'matchesSelector';
51144    }
51145    // check vendor prefixes
51146    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
51147
51148    for ( var i=0; i < prefixes.length; i++ ) {
51149      var prefix = prefixes[i];
51150      var method = prefix + 'MatchesSelector';
51151      if ( ElemProto[ method ] ) {
51152        return method;
51153      }
51154    }
51155  })();
51156
51157  return function matchesSelector( elem, selector ) {
51158    return elem[ matchesMethod ]( selector );
51159  };
51160
51161}));
51162
51163/**
51164 * Fizzy UI utils v2.0.7
51165 * MIT license
51166 */
51167
51168/*jshint browser: true, undef: true, unused: true, strict: true */
51169
51170( function( window, factory ) {
51171  // universal module definition
51172  /*jshint strict: false */ /*globals define, module, require */
51173
51174  if ( typeof define == 'function' && define.amd ) {
51175    // AMD
51176    define( 'fizzy-ui-utils/utils',[
51177      'desandro-matches-selector/matches-selector'
51178    ], function( matchesSelector ) {
51179      return factory( window, matchesSelector );
51180    });
51181  } else if ( typeof module == 'object' && module.exports ) {
51182    // CommonJS
51183    module.exports = factory(
51184      window,
51185      require('desandro-matches-selector')
51186    );
51187  } else {
51188    // browser global
51189    window.fizzyUIUtils = factory(
51190      window,
51191      window.matchesSelector
51192    );
51193  }
51194
51195}( window, function factory( window, matchesSelector ) {
51196
51197
51198
51199var utils = {};
51200
51201// ----- extend ----- //
51202
51203// extends objects
51204utils.extend = function( a, b ) {
51205  for ( var prop in b ) {
51206    a[ prop ] = b[ prop ];
51207  }
51208  return a;
51209};
51210
51211// ----- modulo ----- //
51212
51213utils.modulo = function( num, div ) {
51214  return ( ( num % div ) + div ) % div;
51215};
51216
51217// ----- makeArray ----- //
51218
51219var arraySlice = Array.prototype.slice;
51220
51221// turn element or nodeList into an array
51222utils.makeArray = function( obj ) {
51223  if ( Array.isArray( obj ) ) {
51224    // use object if already an array
51225    return obj;
51226  }
51227  // return empty array if undefined or null. #6
51228  if ( obj === null || obj === undefined ) {
51229    return [];
51230  }
51231
51232  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
51233  if ( isArrayLike ) {
51234    // convert nodeList to array
51235    return arraySlice.call( obj );
51236  }
51237
51238  // array of single index
51239  return [ obj ];
51240};
51241
51242// ----- removeFrom ----- //
51243
51244utils.removeFrom = function( ary, obj ) {
51245  var index = ary.indexOf( obj );
51246  if ( index != -1 ) {
51247    ary.splice( index, 1 );
51248  }
51249};
51250
51251// ----- getParent ----- //
51252
51253utils.getParent = function( elem, selector ) {
51254  while ( elem.parentNode && elem != document.body ) {
51255    elem = elem.parentNode;
51256    if ( matchesSelector( elem, selector ) ) {
51257      return elem;
51258    }
51259  }
51260};
51261
51262// ----- getQueryElement ----- //
51263
51264// use element as selector string
51265utils.getQueryElement = function( elem ) {
51266  if ( typeof elem == 'string' ) {
51267    return document.querySelector( elem );
51268  }
51269  return elem;
51270};
51271
51272// ----- handleEvent ----- //
51273
51274// enable .ontype to trigger from .addEventListener( elem, 'type' )
51275utils.handleEvent = function( event ) {
51276  var method = 'on' + event.type;
51277  if ( this[ method ] ) {
51278    this[ method ]( event );
51279  }
51280};
51281
51282// ----- filterFindElements ----- //
51283
51284utils.filterFindElements = function( elems, selector ) {
51285  // make array of elems
51286  elems = utils.makeArray( elems );
51287  var ffElems = [];
51288
51289  elems.forEach( function( elem ) {
51290    // check that elem is an actual element
51291    if ( !( elem instanceof HTMLElement ) ) {
51292      return;
51293    }
51294    // add elem if no selector
51295    if ( !selector ) {
51296      ffElems.push( elem );
51297      return;
51298    }
51299    // filter & find items if we have a selector
51300    // filter
51301    if ( matchesSelector( elem, selector ) ) {
51302      ffElems.push( elem );
51303    }
51304    // find children
51305    var childElems = elem.querySelectorAll( selector );
51306    // concat childElems to filterFound array
51307    for ( var i=0; i < childElems.length; i++ ) {
51308      ffElems.push( childElems[i] );
51309    }
51310  });
51311
51312  return ffElems;
51313};
51314
51315// ----- debounceMethod ----- //
51316
51317utils.debounceMethod = function( _class, methodName, threshold ) {
51318  threshold = threshold || 100;
51319  // original method
51320  var method = _class.prototype[ methodName ];
51321  var timeoutName = methodName + 'Timeout';
51322
51323  _class.prototype[ methodName ] = function() {
51324    var timeout = this[ timeoutName ];
51325    clearTimeout( timeout );
51326
51327    var args = arguments;
51328    var _this = this;
51329    this[ timeoutName ] = setTimeout( function() {
51330      method.apply( _this, args );
51331      delete _this[ timeoutName ];
51332    }, threshold );
51333  };
51334};
51335
51336// ----- docReady ----- //
51337
51338utils.docReady = function( callback ) {
51339  var readyState = document.readyState;
51340  if ( readyState == 'complete' || readyState == 'interactive' ) {
51341    // do async to allow for other scripts to run. metafizzy/flickity#441
51342    setTimeout( callback );
51343  } else {
51344    document.addEventListener( 'DOMContentLoaded', callback );
51345  }
51346};
51347
51348// ----- htmlInit ----- //
51349
51350// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
51351utils.toDashed = function( str ) {
51352  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
51353    return $1 + '-' + $2;
51354  }).toLowerCase();
51355};
51356
51357var console = window.console;
51358/**
51359 * allow user to initialize classes via [data-namespace] or .js-namespace class
51360 * htmlInit( Widget, 'widgetName' )
51361 * options are parsed from data-namespace-options
51362 */
51363utils.htmlInit = function( WidgetClass, namespace ) {
51364  utils.docReady( function() {
51365    var dashedNamespace = utils.toDashed( namespace );
51366    var dataAttr = 'data-' + dashedNamespace;
51367    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
51368    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
51369    var elems = utils.makeArray( dataAttrElems )
51370      .concat( utils.makeArray( jsDashElems ) );
51371    var dataOptionsAttr = dataAttr + '-options';
51372    var jQuery = window.jQuery;
51373
51374    elems.forEach( function( elem ) {
51375      var attr = elem.getAttribute( dataAttr ) ||
51376        elem.getAttribute( dataOptionsAttr );
51377      var options;
51378      try {
51379        options = attr && JSON.parse( attr );
51380      } catch ( error ) {
51381        // log error, do not initialize
51382        if ( console ) {
51383          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
51384          ': ' + error );
51385        }
51386        return;
51387      }
51388      // initialize
51389      var instance = new WidgetClass( elem, options );
51390      // make available via $().data('namespace')
51391      if ( jQuery ) {
51392        jQuery.data( elem, namespace, instance );
51393      }
51394    });
51395
51396  });
51397};
51398
51399// -----  ----- //
51400
51401return utils;
51402
51403}));
51404
51405/**
51406 * Outlayer Item
51407 */
51408
51409( function( window, factory ) {
51410  // universal module definition
51411  /* jshint strict: false */ /* globals define, module, require */
51412  if ( typeof define == 'function' && define.amd ) {
51413    // AMD - RequireJS
51414    define( 'outlayer/item',[
51415        'ev-emitter/ev-emitter',
51416        'get-size/get-size'
51417      ],
51418      factory
51419    );
51420  } else if ( typeof module == 'object' && module.exports ) {
51421    // CommonJS - Browserify, Webpack
51422    module.exports = factory(
51423      require('ev-emitter'),
51424      require('get-size')
51425    );
51426  } else {
51427    // browser global
51428    window.Outlayer = {};
51429    window.Outlayer.Item = factory(
51430      window.EvEmitter,
51431      window.getSize
51432    );
51433  }
51434
51435}( window, function factory( EvEmitter, getSize ) {
51436'use strict';
51437
51438// ----- helpers ----- //
51439
51440function isEmptyObj( obj ) {
51441  for ( var prop in obj ) {
51442    return false;
51443  }
51444  prop = null;
51445  return true;
51446}
51447
51448// -------------------------- CSS3 support -------------------------- //
51449
51450
51451var docElemStyle = document.documentElement.style;
51452
51453var transitionProperty = typeof docElemStyle.transition == 'string' ?
51454  'transition' : 'WebkitTransition';
51455var transformProperty = typeof docElemStyle.transform == 'string' ?
51456  'transform' : 'WebkitTransform';
51457
51458var transitionEndEvent = {
51459  WebkitTransition: 'webkitTransitionEnd',
51460  transition: 'transitionend'
51461}[ transitionProperty ];
51462
51463// cache all vendor properties that could have vendor prefix
51464var vendorProperties = {
51465  transform: transformProperty,
51466  transition: transitionProperty,
51467  transitionDuration: transitionProperty + 'Duration',
51468  transitionProperty: transitionProperty + 'Property',
51469  transitionDelay: transitionProperty + 'Delay'
51470};
51471
51472// -------------------------- Item -------------------------- //
51473
51474function Item( element, layout ) {
51475  if ( !element ) {
51476    return;
51477  }
51478
51479  this.element = element;
51480  // parent layout class, i.e. Masonry, Isotope, or Packery
51481  this.layout = layout;
51482  this.position = {
51483    x: 0,
51484    y: 0
51485  };
51486
51487  this._create();
51488}
51489
51490// inherit EvEmitter
51491var proto = Item.prototype = Object.create( EvEmitter.prototype );
51492proto.constructor = Item;
51493
51494proto._create = function() {
51495  // transition objects
51496  this._transn = {
51497    ingProperties: {},
51498    clean: {},
51499    onEnd: {}
51500  };
51501
51502  this.css({
51503    position: 'absolute'
51504  });
51505};
51506
51507// trigger specified handler for event type
51508proto.handleEvent = function( event ) {
51509  var method = 'on' + event.type;
51510  if ( this[ method ] ) {
51511    this[ method ]( event );
51512  }
51513};
51514
51515proto.getSize = function() {
51516  this.size = getSize( this.element );
51517};
51518
51519/**
51520 * apply CSS styles to element
51521 * @param {Object} style
51522 */
51523proto.css = function( style ) {
51524  var elemStyle = this.element.style;
51525
51526  for ( var prop in style ) {
51527    // use vendor property if available
51528    var supportedProp = vendorProperties[ prop ] || prop;
51529    elemStyle[ supportedProp ] = style[ prop ];
51530  }
51531};
51532
51533 // measure position, and sets it
51534proto.getPosition = function() {
51535  var style = getComputedStyle( this.element );
51536  var isOriginLeft = this.layout._getOption('originLeft');
51537  var isOriginTop = this.layout._getOption('originTop');
51538  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
51539  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
51540  var x = parseFloat( xValue );
51541  var y = parseFloat( yValue );
51542  // convert percent to pixels
51543  var layoutSize = this.layout.size;
51544  if ( xValue.indexOf('%') != -1 ) {
51545    x = ( x / 100 ) * layoutSize.width;
51546  }
51547  if ( yValue.indexOf('%') != -1 ) {
51548    y = ( y / 100 ) * layoutSize.height;
51549  }
51550  // clean up 'auto' or other non-integer values
51551  x = isNaN( x ) ? 0 : x;
51552  y = isNaN( y ) ? 0 : y;
51553  // remove padding from measurement
51554  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
51555  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
51556
51557  this.position.x = x;
51558  this.position.y = y;
51559};
51560
51561// set settled position, apply padding
51562proto.layoutPosition = function() {
51563  var layoutSize = this.layout.size;
51564  var style = {};
51565  var isOriginLeft = this.layout._getOption('originLeft');
51566  var isOriginTop = this.layout._getOption('originTop');
51567
51568  // x
51569  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
51570  var xProperty = isOriginLeft ? 'left' : 'right';
51571  var xResetProperty = isOriginLeft ? 'right' : 'left';
51572
51573  var x = this.position.x + layoutSize[ xPadding ];
51574  // set in percentage or pixels
51575  style[ xProperty ] = this.getXValue( x );
51576  // reset other property
51577  style[ xResetProperty ] = '';
51578
51579  // y
51580  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
51581  var yProperty = isOriginTop ? 'top' : 'bottom';
51582  var yResetProperty = isOriginTop ? 'bottom' : 'top';
51583
51584  var y = this.position.y + layoutSize[ yPadding ];
51585  // set in percentage or pixels
51586  style[ yProperty ] = this.getYValue( y );
51587  // reset other property
51588  style[ yResetProperty ] = '';
51589
51590  this.css( style );
51591  this.emitEvent( 'layout', [ this ] );
51592};
51593
51594proto.getXValue = function( x ) {
51595  var isHorizontal = this.layout._getOption('horizontal');
51596  return this.layout.options.percentPosition && !isHorizontal ?
51597    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
51598};
51599
51600proto.getYValue = function( y ) {
51601  var isHorizontal = this.layout._getOption('horizontal');
51602  return this.layout.options.percentPosition && isHorizontal ?
51603    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
51604};
51605
51606proto._transitionTo = function( x, y ) {
51607  this.getPosition();
51608  // get current x & y from top/left
51609  var curX = this.position.x;
51610  var curY = this.position.y;
51611
51612  var didNotMove = x == this.position.x && y == this.position.y;
51613
51614  // save end position
51615  this.setPosition( x, y );
51616
51617  // if did not move and not transitioning, just go to layout
51618  if ( didNotMove && !this.isTransitioning ) {
51619    this.layoutPosition();
51620    return;
51621  }
51622
51623  var transX = x - curX;
51624  var transY = y - curY;
51625  var transitionStyle = {};
51626  transitionStyle.transform = this.getTranslate( transX, transY );
51627
51628  this.transition({
51629    to: transitionStyle,
51630    onTransitionEnd: {
51631      transform: this.layoutPosition
51632    },
51633    isCleaning: true
51634  });
51635};
51636
51637proto.getTranslate = function( x, y ) {
51638  // flip cooridinates if origin on right or bottom
51639  var isOriginLeft = this.layout._getOption('originLeft');
51640  var isOriginTop = this.layout._getOption('originTop');
51641  x = isOriginLeft ? x : -x;
51642  y = isOriginTop ? y : -y;
51643  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
51644};
51645
51646// non transition + transform support
51647proto.goTo = function( x, y ) {
51648  this.setPosition( x, y );
51649  this.layoutPosition();
51650};
51651
51652proto.moveTo = proto._transitionTo;
51653
51654proto.setPosition = function( x, y ) {
51655  this.position.x = parseFloat( x );
51656  this.position.y = parseFloat( y );
51657};
51658
51659// ----- transition ----- //
51660
51661/**
51662 * @param {Object} style - CSS
51663 * @param {Function} onTransitionEnd
51664 */
51665
51666// non transition, just trigger callback
51667proto._nonTransition = function( args ) {
51668  this.css( args.to );
51669  if ( args.isCleaning ) {
51670    this._removeStyles( args.to );
51671  }
51672  for ( var prop in args.onTransitionEnd ) {
51673    args.onTransitionEnd[ prop ].call( this );
51674  }
51675};
51676
51677/**
51678 * proper transition
51679 * @param {Object} args - arguments
51680 *   @param {Object} to - style to transition to
51681 *   @param {Object} from - style to start transition from
51682 *   @param {Boolean} isCleaning - removes transition styles after transition
51683 *   @param {Function} onTransitionEnd - callback
51684 */
51685proto.transition = function( args ) {
51686  // redirect to nonTransition if no transition duration
51687  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
51688    this._nonTransition( args );
51689    return;
51690  }
51691
51692  var _transition = this._transn;
51693  // keep track of onTransitionEnd callback by css property
51694  for ( var prop in args.onTransitionEnd ) {
51695    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
51696  }
51697  // keep track of properties that are transitioning
51698  for ( prop in args.to ) {
51699    _transition.ingProperties[ prop ] = true;
51700    // keep track of properties to clean up when transition is done
51701    if ( args.isCleaning ) {
51702      _transition.clean[ prop ] = true;
51703    }
51704  }
51705
51706  // set from styles
51707  if ( args.from ) {
51708    this.css( args.from );
51709    // force redraw. http://blog.alexmaccaw.com/css-transitions
51710    var h = this.element.offsetHeight;
51711    // hack for JSHint to hush about unused var
51712    h = null;
51713  }
51714  // enable transition
51715  this.enableTransition( args.to );
51716  // set styles that are transitioning
51717  this.css( args.to );
51718
51719  this.isTransitioning = true;
51720
51721};
51722
51723// dash before all cap letters, including first for
51724// WebkitTransform => -webkit-transform
51725function toDashedAll( str ) {
51726  return str.replace( /([A-Z])/g, function( $1 ) {
51727    return '-' + $1.toLowerCase();
51728  });
51729}
51730
51731var transitionProps = 'opacity,' + toDashedAll( transformProperty );
51732
51733proto.enableTransition = function(/* style */) {
51734  // HACK changing transitionProperty during a transition
51735  // will cause transition to jump
51736  if ( this.isTransitioning ) {
51737    return;
51738  }
51739
51740  // make `transition: foo, bar, baz` from style object
51741  // HACK un-comment this when enableTransition can work
51742  // while a transition is happening
51743  // var transitionValues = [];
51744  // for ( var prop in style ) {
51745  //   // dash-ify camelCased properties like WebkitTransition
51746  //   prop = vendorProperties[ prop ] || prop;
51747  //   transitionValues.push( toDashedAll( prop ) );
51748  // }
51749  // munge number to millisecond, to match stagger
51750  var duration = this.layout.options.transitionDuration;
51751  duration = typeof duration == 'number' ? duration + 'ms' : duration;
51752  // enable transition styles
51753  this.css({
51754    transitionProperty: transitionProps,
51755    transitionDuration: duration,
51756    transitionDelay: this.staggerDelay || 0
51757  });
51758  // listen for transition end event
51759  this.element.addEventListener( transitionEndEvent, this, false );
51760};
51761
51762// ----- events ----- //
51763
51764proto.onwebkitTransitionEnd = function( event ) {
51765  this.ontransitionend( event );
51766};
51767
51768proto.onotransitionend = function( event ) {
51769  this.ontransitionend( event );
51770};
51771
51772// properties that I munge to make my life easier
51773var dashedVendorProperties = {
51774  '-webkit-transform': 'transform'
51775};
51776
51777proto.ontransitionend = function( event ) {
51778  // disregard bubbled events from children
51779  if ( event.target !== this.element ) {
51780    return;
51781  }
51782  var _transition = this._transn;
51783  // get property name of transitioned property, convert to prefix-free
51784  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
51785
51786  // remove property that has completed transitioning
51787  delete _transition.ingProperties[ propertyName ];
51788  // check if any properties are still transitioning
51789  if ( isEmptyObj( _transition.ingProperties ) ) {
51790    // all properties have completed transitioning
51791    this.disableTransition();
51792  }
51793  // clean style
51794  if ( propertyName in _transition.clean ) {
51795    // clean up style
51796    this.element.style[ event.propertyName ] = '';
51797    delete _transition.clean[ propertyName ];
51798  }
51799  // trigger onTransitionEnd callback
51800  if ( propertyName in _transition.onEnd ) {
51801    var onTransitionEnd = _transition.onEnd[ propertyName ];
51802    onTransitionEnd.call( this );
51803    delete _transition.onEnd[ propertyName ];
51804  }
51805
51806  this.emitEvent( 'transitionEnd', [ this ] );
51807};
51808
51809proto.disableTransition = function() {
51810  this.removeTransitionStyles();
51811  this.element.removeEventListener( transitionEndEvent, this, false );
51812  this.isTransitioning = false;
51813};
51814
51815/**
51816 * removes style property from element
51817 * @param {Object} style
51818**/
51819proto._removeStyles = function( style ) {
51820  // clean up transition styles
51821  var cleanStyle = {};
51822  for ( var prop in style ) {
51823    cleanStyle[ prop ] = '';
51824  }
51825  this.css( cleanStyle );
51826};
51827
51828var cleanTransitionStyle = {
51829  transitionProperty: '',
51830  transitionDuration: '',
51831  transitionDelay: ''
51832};
51833
51834proto.removeTransitionStyles = function() {
51835  // remove transition
51836  this.css( cleanTransitionStyle );
51837};
51838
51839// ----- stagger ----- //
51840
51841proto.stagger = function( delay ) {
51842  delay = isNaN( delay ) ? 0 : delay;
51843  this.staggerDelay = delay + 'ms';
51844};
51845
51846// ----- show/hide/remove ----- //
51847
51848// remove element from DOM
51849proto.removeElem = function() {
51850  this.element.parentNode.removeChild( this.element );
51851  // remove display: none
51852  this.css({ display: '' });
51853  this.emitEvent( 'remove', [ this ] );
51854};
51855
51856proto.remove = function() {
51857  // just remove element if no transition support or no transition
51858  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
51859    this.removeElem();
51860    return;
51861  }
51862
51863  // start transition
51864  this.once( 'transitionEnd', function() {
51865    this.removeElem();
51866  });
51867  this.hide();
51868};
51869
51870proto.reveal = function() {
51871  delete this.isHidden;
51872  // remove display: none
51873  this.css({ display: '' });
51874
51875  var options = this.layout.options;
51876
51877  var onTransitionEnd = {};
51878  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
51879  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
51880
51881  this.transition({
51882    from: options.hiddenStyle,
51883    to: options.visibleStyle,
51884    isCleaning: true,
51885    onTransitionEnd: onTransitionEnd
51886  });
51887};
51888
51889proto.onRevealTransitionEnd = function() {
51890  // check if still visible
51891  // during transition, item may have been hidden
51892  if ( !this.isHidden ) {
51893    this.emitEvent('reveal');
51894  }
51895};
51896
51897/**
51898 * get style property use for hide/reveal transition end
51899 * @param {String} styleProperty - hiddenStyle/visibleStyle
51900 * @returns {String}
51901 */
51902proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
51903  var optionStyle = this.layout.options[ styleProperty ];
51904  // use opacity
51905  if ( optionStyle.opacity ) {
51906    return 'opacity';
51907  }
51908  // get first property
51909  for ( var prop in optionStyle ) {
51910    return prop;
51911  }
51912};
51913
51914proto.hide = function() {
51915  // set flag
51916  this.isHidden = true;
51917  // remove display: none
51918  this.css({ display: '' });
51919
51920  var options = this.layout.options;
51921
51922  var onTransitionEnd = {};
51923  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
51924  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
51925
51926  this.transition({
51927    from: options.visibleStyle,
51928    to: options.hiddenStyle,
51929    // keep hidden stuff hidden
51930    isCleaning: true,
51931    onTransitionEnd: onTransitionEnd
51932  });
51933};
51934
51935proto.onHideTransitionEnd = function() {
51936  // check if still hidden
51937  // during transition, item may have been un-hidden
51938  if ( this.isHidden ) {
51939    this.css({ display: 'none' });
51940    this.emitEvent('hide');
51941  }
51942};
51943
51944proto.destroy = function() {
51945  this.css({
51946    position: '',
51947    left: '',
51948    right: '',
51949    top: '',
51950    bottom: '',
51951    transition: '',
51952    transform: ''
51953  });
51954};
51955
51956return Item;
51957
51958}));
51959
51960/*!
51961 * Outlayer v2.1.1
51962 * the brains and guts of a layout library
51963 * MIT license
51964 */
51965
51966( function( window, factory ) {
51967  'use strict';
51968  // universal module definition
51969  /* jshint strict: false */ /* globals define, module, require */
51970  if ( typeof define == 'function' && define.amd ) {
51971    // AMD - RequireJS
51972    define( 'outlayer/outlayer',[
51973        'ev-emitter/ev-emitter',
51974        'get-size/get-size',
51975        'fizzy-ui-utils/utils',
51976        './item'
51977      ],
51978      function( EvEmitter, getSize, utils, Item ) {
51979        return factory( window, EvEmitter, getSize, utils, Item);
51980      }
51981    );
51982  } else if ( typeof module == 'object' && module.exports ) {
51983    // CommonJS - Browserify, Webpack
51984    module.exports = factory(
51985      window,
51986      require('ev-emitter'),
51987      require('get-size'),
51988      require('fizzy-ui-utils'),
51989      require('./item')
51990    );
51991  } else {
51992    // browser global
51993    window.Outlayer = factory(
51994      window,
51995      window.EvEmitter,
51996      window.getSize,
51997      window.fizzyUIUtils,
51998      window.Outlayer.Item
51999    );
52000  }
52001
52002}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
52003'use strict';
52004
52005// ----- vars ----- //
52006
52007var console = window.console;
52008var jQuery = window.jQuery;
52009var noop = function() {};
52010
52011// -------------------------- Outlayer -------------------------- //
52012
52013// globally unique identifiers
52014var GUID = 0;
52015// internal store of all Outlayer intances
52016var instances = {};
52017
52018
52019/**
52020 * @param {Element, String} element
52021 * @param {Object} options
52022 * @constructor
52023 */
52024function Outlayer( element, options ) {
52025  var queryElement = utils.getQueryElement( element );
52026  if ( !queryElement ) {
52027    if ( console ) {
52028      console.error( 'Bad element for ' + this.constructor.namespace +
52029        ': ' + ( queryElement || element ) );
52030    }
52031    return;
52032  }
52033  this.element = queryElement;
52034  // add jQuery
52035  if ( jQuery ) {
52036    this.$element = jQuery( this.element );
52037  }
52038
52039  // options
52040  this.options = utils.extend( {}, this.constructor.defaults );
52041  this.option( options );
52042
52043  // add id for Outlayer.getFromElement
52044  var id = ++GUID;
52045  this.element.outlayerGUID = id; // expando
52046  instances[ id ] = this; // associate via id
52047
52048  // kick it off
52049  this._create();
52050
52051  var isInitLayout = this._getOption('initLayout');
52052  if ( isInitLayout ) {
52053    this.layout();
52054  }
52055}
52056
52057// settings are for internal use only
52058Outlayer.namespace = 'outlayer';
52059Outlayer.Item = Item;
52060
52061// default options
52062Outlayer.defaults = {
52063  containerStyle: {
52064    position: 'relative'
52065  },
52066  initLayout: true,
52067  originLeft: true,
52068  originTop: true,
52069  resize: true,
52070  resizeContainer: true,
52071  // item options
52072  transitionDuration: '0.4s',
52073  hiddenStyle: {
52074    opacity: 0,
52075    transform: 'scale(0.001)'
52076  },
52077  visibleStyle: {
52078    opacity: 1,
52079    transform: 'scale(1)'
52080  }
52081};
52082
52083var proto = Outlayer.prototype;
52084// inherit EvEmitter
52085utils.extend( proto, EvEmitter.prototype );
52086
52087/**
52088 * set options
52089 * @param {Object} opts
52090 */
52091proto.option = function( opts ) {
52092  utils.extend( this.options, opts );
52093};
52094
52095/**
52096 * get backwards compatible option value, check old name
52097 */
52098proto._getOption = function( option ) {
52099  var oldOption = this.constructor.compatOptions[ option ];
52100  return oldOption && this.options[ oldOption ] !== undefined ?
52101    this.options[ oldOption ] : this.options[ option ];
52102};
52103
52104Outlayer.compatOptions = {
52105  // currentName: oldName
52106  initLayout: 'isInitLayout',
52107  horizontal: 'isHorizontal',
52108  layoutInstant: 'isLayoutInstant',
52109  originLeft: 'isOriginLeft',
52110  originTop: 'isOriginTop',
52111  resize: 'isResizeBound',
52112  resizeContainer: 'isResizingContainer'
52113};
52114
52115proto._create = function() {
52116  // get items from children
52117  this.reloadItems();
52118  // elements that affect layout, but are not laid out
52119  this.stamps = [];
52120  this.stamp( this.options.stamp );
52121  // set container style
52122  utils.extend( this.element.style, this.options.containerStyle );
52123
52124  // bind resize method
52125  var canBindResize = this._getOption('resize');
52126  if ( canBindResize ) {
52127    this.bindResize();
52128  }
52129};
52130
52131// goes through all children again and gets bricks in proper order
52132proto.reloadItems = function() {
52133  // collection of item elements
52134  this.items = this._itemize( this.element.children );
52135};
52136
52137
52138/**
52139 * turn elements into Outlayer.Items to be used in layout
52140 * @param {Array or NodeList or HTMLElement} elems
52141 * @returns {Array} items - collection of new Outlayer Items
52142 */
52143proto._itemize = function( elems ) {
52144
52145  var itemElems = this._filterFindItemElements( elems );
52146  var Item = this.constructor.Item;
52147
52148  // create new Outlayer Items for collection
52149  var items = [];
52150  for ( var i=0; i < itemElems.length; i++ ) {
52151    var elem = itemElems[i];
52152    var item = new Item( elem, this );
52153    items.push( item );
52154  }
52155
52156  return items;
52157};
52158
52159/**
52160 * get item elements to be used in layout
52161 * @param {Array or NodeList or HTMLElement} elems
52162 * @returns {Array} items - item elements
52163 */
52164proto._filterFindItemElements = function( elems ) {
52165  return utils.filterFindElements( elems, this.options.itemSelector );
52166};
52167
52168/**
52169 * getter method for getting item elements
52170 * @returns {Array} elems - collection of item elements
52171 */
52172proto.getItemElements = function() {
52173  return this.items.map( function( item ) {
52174    return item.element;
52175  });
52176};
52177
52178// ----- init & layout ----- //
52179
52180/**
52181 * lays out all items
52182 */
52183proto.layout = function() {
52184  this._resetLayout();
52185  this._manageStamps();
52186
52187  // don't animate first layout
52188  var layoutInstant = this._getOption('layoutInstant');
52189  var isInstant = layoutInstant !== undefined ?
52190    layoutInstant : !this._isLayoutInited;
52191  this.layoutItems( this.items, isInstant );
52192
52193  // flag for initalized
52194  this._isLayoutInited = true;
52195};
52196
52197// _init is alias for layout
52198proto._init = proto.layout;
52199
52200/**
52201 * logic before any new layout
52202 */
52203proto._resetLayout = function() {
vendor: 13,499 bytes, lines 52204-52772
52204  this.getSize();
52205};
52206
52207
52208proto.getSize = function() {
52209  this.size = getSize( this.element );
52210};
52211
52212/**
52213 * get measurement from option, for columnWidth, rowHeight, gutter
52214 * if option is String -> get element from selector string, & get size of element
52215 * if option is Element -> get size of element
52216 * else use option as a number
52217 *
52218 * @param {String} measurement
52219 * @param {String} size - width or height
52220 * @private
52221 */
52222proto._getMeasurement = function( measurement, size ) {
52223  var option = this.options[ measurement ];
52224  var elem;
52225  if ( !option ) {
52226    // default to 0
52227    this[ measurement ] = 0;
52228  } else {
52229    // use option as an element
52230    if ( typeof option == 'string' ) {
52231      elem = this.element.querySelector( option );
52232    } else if ( option instanceof HTMLElement ) {
52233      elem = option;
52234    }
52235    // use size of element, if element
52236    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
52237  }
52238};
52239
52240/**
52241 * layout a collection of item elements
52242 * @api public
52243 */
52244proto.layoutItems = function( items, isInstant ) {
52245  items = this._getItemsForLayout( items );
52246
52247  this._layoutItems( items, isInstant );
52248
52249  this._postLayout();
52250};
52251
52252/**
52253 * get the items to be laid out
52254 * you may want to skip over some items
52255 * @param {Array} items
52256 * @returns {Array} items
52257 */
52258proto._getItemsForLayout = function( items ) {
52259  return items.filter( function( item ) {
52260    return !item.isIgnored;
52261  });
52262};
52263
52264/**
52265 * layout items
52266 * @param {Array} items
52267 * @param {Boolean} isInstant
52268 */
52269proto._layoutItems = function( items, isInstant ) {
52270  this._emitCompleteOnItems( 'layout', items );
52271
52272  if ( !items || !items.length ) {
52273    // no items, emit event with empty array
52274    return;
52275  }
52276
52277  var queue = [];
52278
52279  items.forEach( function( item ) {
52280    // get x/y object from method
52281    var position = this._getItemLayoutPosition( item );
52282    // enqueue
52283    position.item = item;
52284    position.isInstant = isInstant || item.isLayoutInstant;
52285    queue.push( position );
52286  }, this );
52287
52288  this._processLayoutQueue( queue );
52289};
52290
52291/**
52292 * get item layout position
52293 * @param {Outlayer.Item} item
52294 * @returns {Object} x and y position
52295 */
52296proto._getItemLayoutPosition = function( /* item */ ) {
52297  return {
52298    x: 0,
52299    y: 0
52300  };
52301};
52302
52303/**
52304 * iterate over array and position each item
52305 * Reason being - separating this logic prevents 'layout invalidation'
52306 * thx @paul_irish
52307 * @param {Array} queue
52308 */
52309proto._processLayoutQueue = function( queue ) {
52310  this.updateStagger();
52311  queue.forEach( function( obj, i ) {
52312    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
52313  }, this );
52314};
52315
52316// set stagger from option in milliseconds number
52317proto.updateStagger = function() {
52318  var stagger = this.options.stagger;
52319  if ( stagger === null || stagger === undefined ) {
52320    this.stagger = 0;
52321    return;
52322  }
52323  this.stagger = getMilliseconds( stagger );
52324  return this.stagger;
52325};
52326
52327/**
52328 * Sets position of item in DOM
52329 * @param {Outlayer.Item} item
52330 * @param {Number} x - horizontal position
52331 * @param {Number} y - vertical position
52332 * @param {Boolean} isInstant - disables transitions
52333 */
52334proto._positionItem = function( item, x, y, isInstant, i ) {
52335  if ( isInstant ) {
52336    // if not transition, just set CSS
52337    item.goTo( x, y );
52338  } else {
52339    item.stagger( i * this.stagger );
52340    item.moveTo( x, y );
52341  }
52342};
52343
52344/**
52345 * Any logic you want to do after each layout,
52346 * i.e. size the container
52347 */
52348proto._postLayout = function() {
52349  this.resizeContainer();
52350};
52351
52352proto.resizeContainer = function() {
52353  var isResizingContainer = this._getOption('resizeContainer');
52354  if ( !isResizingContainer ) {
52355    return;
52356  }
52357  var size = this._getContainerSize();
52358  if ( size ) {
52359    this._setContainerMeasure( size.width, true );
52360    this._setContainerMeasure( size.height, false );
52361  }
52362};
52363
52364/**
52365 * Sets width or height of container if returned
52366 * @returns {Object} size
52367 *   @param {Number} width
52368 *   @param {Number} height
52369 */
52370proto._getContainerSize = noop;
52371
52372/**
52373 * @param {Number} measure - size of width or height
52374 * @param {Boolean} isWidth
52375 */
52376proto._setContainerMeasure = function( measure, isWidth ) {
52377  if ( measure === undefined ) {
52378    return;
52379  }
52380
52381  var elemSize = this.size;
52382  // add padding and border width if border box
52383  if ( elemSize.isBorderBox ) {
52384    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
52385      elemSize.borderLeftWidth + elemSize.borderRightWidth :
52386      elemSize.paddingBottom + elemSize.paddingTop +
52387      elemSize.borderTopWidth + elemSize.borderBottomWidth;
52388  }
52389
52390  measure = Math.max( measure, 0 );
52391  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
52392};
52393
52394/**
52395 * emit eventComplete on a collection of items events
52396 * @param {String} eventName
52397 * @param {Array} items - Outlayer.Items
52398 */
52399proto._emitCompleteOnItems = function( eventName, items ) {
52400  var _this = this;
52401  function onComplete() {
52402    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
52403  }
52404
52405  var count = items.length;
52406  if ( !items || !count ) {
52407    onComplete();
52408    return;
52409  }
52410
52411  var doneCount = 0;
52412  function tick() {
52413    doneCount++;
52414    if ( doneCount == count ) {
52415      onComplete();
52416    }
52417  }
52418
52419  // bind callback
52420  items.forEach( function( item ) {
52421    item.once( eventName, tick );
52422  });
52423};
52424
52425/**
52426 * emits events via EvEmitter and jQuery events
52427 * @param {String} type - name of event
52428 * @param {Event} event - original event
52429 * @param {Array} args - extra arguments
52430 */
52431proto.dispatchEvent = function( type, event, args ) {
52432  // add original event to arguments
52433  var emitArgs = event ? [ event ].concat( args ) : args;
52434  this.emitEvent( type, emitArgs );
52435
52436  if ( jQuery ) {
52437    // set this.$element
52438    this.$element = this.$element || jQuery( this.element );
52439    if ( event ) {
52440      // create jQuery event
52441      var $event = jQuery.Event( event );
52442      $event.type = type;
52443      this.$element.trigger( $event, args );
52444    } else {
52445      // just trigger with type if no event available
52446      this.$element.trigger( type, args );
52447    }
52448  }
52449};
52450
52451// -------------------------- ignore & stamps -------------------------- //
52452
52453
52454/**
52455 * keep item in collection, but do not lay it out
52456 * ignored items do not get skipped in layout
52457 * @param {Element} elem
52458 */
52459proto.ignore = function( elem ) {
52460  var item = this.getItem( elem );
52461  if ( item ) {
52462    item.isIgnored = true;
52463  }
52464};
52465
52466/**
52467 * return item to layout collection
52468 * @param {Element} elem
52469 */
52470proto.unignore = function( elem ) {
52471  var item = this.getItem( elem );
52472  if ( item ) {
52473    delete item.isIgnored;
52474  }
52475};
52476
52477/**
52478 * adds elements to stamps
52479 * @param {NodeList, Array, Element, or String} elems
52480 */
52481proto.stamp = function( elems ) {
52482  elems = this._find( elems );
52483  if ( !elems ) {
52484    return;
52485  }
52486
52487  this.stamps = this.stamps.concat( elems );
52488  // ignore
52489  elems.forEach( this.ignore, this );
52490};
52491
52492/**
52493 * removes elements to stamps
52494 * @param {NodeList, Array, or Element} elems
52495 */
52496proto.unstamp = function( elems ) {
52497  elems = this._find( elems );
52498  if ( !elems ){
52499    return;
52500  }
52501
52502  elems.forEach( function( elem ) {
52503    // filter out removed stamp elements
52504    utils.removeFrom( this.stamps, elem );
52505    this.unignore( elem );
52506  }, this );
52507};
52508
52509/**
52510 * finds child elements
52511 * @param {NodeList, Array, Element, or String} elems
52512 * @returns {Array} elems
52513 */
52514proto._find = function( elems ) {
52515  if ( !elems ) {
52516    return;
52517  }
52518  // if string, use argument as selector string
52519  if ( typeof elems == 'string' ) {
52520    elems = this.element.querySelectorAll( elems );
52521  }
52522  elems = utils.makeArray( elems );
52523  return elems;
52524};
52525
52526proto._manageStamps = function() {
52527  if ( !this.stamps || !this.stamps.length ) {
52528    return;
52529  }
52530
52531  this._getBoundingRect();
52532
52533  this.stamps.forEach( this._manageStamp, this );
52534};
52535
52536// update boundingLeft / Top
52537proto._getBoundingRect = function() {
52538  // get bounding rect for container element
52539  var boundingRect = this.element.getBoundingClientRect();
52540  var size = this.size;
52541  this._boundingRect = {
52542    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
52543    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
52544    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
52545    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
52546  };
52547};
52548
52549/**
52550 * @param {Element} stamp
52551**/
52552proto._manageStamp = noop;
52553
52554/**
52555 * get x/y position of element relative to container element
52556 * @param {Element} elem
52557 * @returns {Object} offset - has left, top, right, bottom
52558 */
52559proto._getElementOffset = function( elem ) {
52560  var boundingRect = elem.getBoundingClientRect();
52561  var thisRect = this._boundingRect;
52562  var size = getSize( elem );
52563  var offset = {
52564    left: boundingRect.left - thisRect.left - size.marginLeft,
52565    top: boundingRect.top - thisRect.top - size.marginTop,
52566    right: thisRect.right - boundingRect.right - size.marginRight,
52567    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
52568  };
52569  return offset;
52570};
52571
52572// -------------------------- resize -------------------------- //
52573
52574// enable event handlers for listeners
52575// i.e. resize -> onresize
52576proto.handleEvent = utils.handleEvent;
52577
52578/**
52579 * Bind layout to window resizing
52580 */
52581proto.bindResize = function() {
52582  window.addEventListener( 'resize', this );
52583  this.isResizeBound = true;
52584};
52585
52586/**
52587 * Unbind layout to window resizing
52588 */
52589proto.unbindResize = function() {
52590  window.removeEventListener( 'resize', this );
52591  this.isResizeBound = false;
52592};
52593
52594proto.onresize = function() {
52595  this.resize();
52596};
52597
52598utils.debounceMethod( Outlayer, 'onresize', 100 );
52599
52600proto.resize = function() {
52601  // don't trigger if size did not change
52602  // or if resize was unbound. See #9
52603  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
52604    return;
52605  }
52606
52607  this.layout();
52608};
52609
52610/**
52611 * check if layout is needed post layout
52612 * @returns Boolean
52613 */
52614proto.needsResizeLayout = function() {
52615  var size = getSize( this.element );
52616  // check that this.size and size are there
52617  // IE8 triggers resize on body size change, so they might not be
52618  var hasSizes = this.size && size;
52619  return hasSizes && size.innerWidth !== this.size.innerWidth;
52620};
52621
52622// -------------------------- methods -------------------------- //
52623
52624/**
52625 * add items to Outlayer instance
52626 * @param {Array or NodeList or Element} elems
52627 * @returns {Array} items - Outlayer.Items
52628**/
52629proto.addItems = function( elems ) {
52630  var items = this._itemize( elems );
52631  // add items to collection
52632  if ( items.length ) {
52633    this.items = this.items.concat( items );
52634  }
52635  return items;
52636};
52637
52638/**
52639 * Layout newly-appended item elements
52640 * @param {Array or NodeList or Element} elems
52641 */
52642proto.appended = function( elems ) {
52643  var items = this.addItems( elems );
52644  if ( !items.length ) {
52645    return;
52646  }
52647  // layout and reveal just the new items
52648  this.layoutItems( items, true );
52649  this.reveal( items );
52650};
52651
52652/**
52653 * Layout prepended elements
52654 * @param {Array or NodeList or Element} elems
52655 */
52656proto.prepended = function( elems ) {
52657  var items = this._itemize( elems );
52658  if ( !items.length ) {
52659    return;
52660  }
52661  // add items to beginning of collection
52662  var previousItems = this.items.slice(0);
52663  this.items = items.concat( previousItems );
52664  // start new layout
52665  this._resetLayout();
52666  this._manageStamps();
52667  // layout new stuff without transition
52668  this.layoutItems( items, true );
52669  this.reveal( items );
52670  // layout previous items
52671  this.layoutItems( previousItems );
52672};
52673
52674/**
52675 * reveal a collection of items
52676 * @param {Array of Outlayer.Items} items
52677 */
52678proto.reveal = function( items ) {
52679  this._emitCompleteOnItems( 'reveal', items );
52680  if ( !items || !items.length ) {
52681    return;
52682  }
52683  var stagger = this.updateStagger();
52684  items.forEach( function( item, i ) {
52685    item.stagger( i * stagger );
52686    item.reveal();
52687  });
52688};
52689
52690/**
52691 * hide a collection of items
52692 * @param {Array of Outlayer.Items} items
52693 */
52694proto.hide = function( items ) {
52695  this._emitCompleteOnItems( 'hide', items );
52696  if ( !items || !items.length ) {
52697    return;
52698  }
52699  var stagger = this.updateStagger();
52700  items.forEach( function( item, i ) {
52701    item.stagger( i * stagger );
52702    item.hide();
52703  });
52704};
52705
52706/**
52707 * reveal item elements
52708 * @param {Array}, {Element}, {NodeList} items
52709 */
52710proto.revealItemElements = function( elems ) {
52711  var items = this.getItems( elems );
52712  this.reveal( items );
52713};
52714
52715/**
52716 * hide item elements
52717 * @param {Array}, {Element}, {NodeList} items
52718 */
52719proto.hideItemElements = function( elems ) {
52720  var items = this.getItems( elems );
52721  this.hide( items );
52722};
52723
52724/**
52725 * get Outlayer.Item, given an Element
52726 * @param {Element} elem
52727 * @param {Function} callback
52728 * @returns {Outlayer.Item} item
52729 */
52730proto.getItem = function( elem ) {
52731  // loop through items to get the one that matches
52732  for ( var i=0; i < this.items.length; i++ ) {
52733    var item = this.items[i];
52734    if ( item.element == elem ) {
52735      // return item
52736      return item;
52737    }
52738  }
52739};
52740
52741/**
52742 * get collection of Outlayer.Items, given Elements
52743 * @param {Array} elems
52744 * @returns {Array} items - Outlayer.Items
52745 */
52746proto.getItems = function( elems ) {
52747  elems = utils.makeArray( elems );
52748  var items = [];
52749  elems.forEach( function( elem ) {
52750    var item = this.getItem( elem );
52751    if ( item ) {
52752      items.push( item );
52753    }
52754  }, this );
52755
52756  return items;
52757};
52758
52759/**
52760 * remove element(s) from instance and DOM
52761 * @param {Array or NodeList or Element} elems
52762 */
52763proto.remove = function( elems ) {
52764  var removeItems = this.getItems( elems );
52765
52766  this._emitCompleteOnItems( 'remove', removeItems );
52767
52768  // bail if no items to remove
52769  if ( !removeItems || !removeItems.length ) {
52770    return;
52771  }
52772
vendor: 10,263 bytes, lines 52773-53139
52773  removeItems.forEach( function( item ) {
52774    item.remove();
52775    // remove item from collection
52776    utils.removeFrom( this.items, item );
52777  }, this );
52778};
52779
52780// ----- destroy ----- //
52781
52782// remove and disable Outlayer instance
52783proto.destroy = function() {
52784  // clean up dynamic styles
52785  var style = this.element.style;
52786  style.height = '';
52787  style.position = '';
52788  style.width = '';
52789  // destroy items
52790  this.items.forEach( function( item ) {
52791    item.destroy();
52792  });
52793
52794  this.unbindResize();
52795
52796  var id = this.element.outlayerGUID;
52797  delete instances[ id ]; // remove reference to instance by id
52798  delete this.element.outlayerGUID;
52799  // remove data for jQuery
52800  if ( jQuery ) {
52801    jQuery.removeData( this.element, this.constructor.namespace );
52802  }
52803
52804};
52805
52806// -------------------------- data -------------------------- //
52807
52808/**
52809 * get Outlayer instance from element
52810 * @param {Element} elem
52811 * @returns {Outlayer}
52812 */
52813Outlayer.data = function( elem ) {
52814  elem = utils.getQueryElement( elem );
52815  var id = elem && elem.outlayerGUID;
52816  return id && instances[ id ];
52817};
52818
52819
52820// -------------------------- create Outlayer class -------------------------- //
52821
52822/**
52823 * create a layout class
52824 * @param {String} namespace
52825 */
52826Outlayer.create = function( namespace, options ) {
52827  // sub-class Outlayer
52828  var Layout = subclass( Outlayer );
52829  // apply new options and compatOptions
52830  Layout.defaults = utils.extend( {}, Outlayer.defaults );
52831  utils.extend( Layout.defaults, options );
52832  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );
52833
52834  Layout.namespace = namespace;
52835
52836  Layout.data = Outlayer.data;
52837
52838  // sub-class Item
52839  Layout.Item = subclass( Item );
52840
52841  // -------------------------- declarative -------------------------- //
52842
52843  utils.htmlInit( Layout, namespace );
52844
52845  // -------------------------- jQuery bridge -------------------------- //
52846
52847  // make into jQuery plugin
52848  if ( jQuery && jQuery.bridget ) {
52849    jQuery.bridget( namespace, Layout );
52850  }
52851
52852  return Layout;
52853};
52854
52855function subclass( Parent ) {
52856  function SubClass() {
52857    Parent.apply( this, arguments );
52858  }
52859
52860  SubClass.prototype = Object.create( Parent.prototype );
52861  SubClass.prototype.constructor = SubClass;
52862
52863  return SubClass;
52864}
52865
52866// ----- helpers ----- //
52867
52868// how many milliseconds are in each unit
52869var msUnits = {
52870  ms: 1,
52871  s: 1000
52872};
52873
52874// munge time-like parameter into millisecond number
52875// '0.4s' -> 40
52876function getMilliseconds( time ) {
52877  if ( typeof time == 'number' ) {
52878    return time;
52879  }
52880  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
52881  var num = matches && matches[1];
52882  var unit = matches && matches[2];
52883  if ( !num.length ) {
52884    return 0;
52885  }
52886  num = parseFloat( num );
52887  var mult = msUnits[ unit ] || 1;
52888  return num * mult;
52889}
52890
52891// ----- fin ----- //
52892
52893// back in global
52894Outlayer.Item = Item;
52895
52896return Outlayer;
52897
52898}));
52899
52900/*!
52901 * Masonry v4.2.2
52902 * Cascading grid layout library
52903 * https://masonry.desandro.com
52904 * MIT License
52905 * by David DeSandro
52906 */
52907
52908( function( window, factory ) {
52909  // universal module definition
52910  /* jshint strict: false */ /*globals define, module, require */
52911  if ( typeof define == 'function' && define.amd ) {
52912    // AMD
52913    define( [
52914        'outlayer/outlayer',
52915        'get-size/get-size'
52916      ],
52917      factory );
52918  } else if ( typeof module == 'object' && module.exports ) {
52919    // CommonJS
52920    module.exports = factory(
52921      require('outlayer'),
52922      require('get-size')
52923    );
52924  } else {
52925    // browser global
52926    window.Masonry = factory(
52927      window.Outlayer,
52928      window.getSize
52929    );
52930  }
52931
52932}( window, function factory( Outlayer, getSize ) {
52933
52934
52935
52936// -------------------------- masonryDefinition -------------------------- //
52937
52938  // create an Outlayer layout class
52939  var Masonry = Outlayer.create('masonry');
52940  // isFitWidth -> fitWidth
52941  Masonry.compatOptions.fitWidth = 'isFitWidth';
52942
52943  var proto = Masonry.prototype;
52944
52945  proto._resetLayout = function() {
52946    this.getSize();
52947    this._getMeasurement( 'columnWidth', 'outerWidth' );
52948    this._getMeasurement( 'gutter', 'outerWidth' );
52949    this.measureColumns();
52950
52951    // reset column Y
52952    this.colYs = [];
52953    for ( var i=0; i < this.cols; i++ ) {
52954      this.colYs.push( 0 );
52955    }
52956
52957    this.maxY = 0;
52958    this.horizontalColIndex = 0;
52959  };
52960
52961  proto.measureColumns = function() {
52962    this.getContainerWidth();
52963    // if columnWidth is 0, default to outerWidth of first item
52964    if ( !this.columnWidth ) {
52965      var firstItem = this.items[0];
52966      var firstItemElem = firstItem && firstItem.element;
52967      // columnWidth fall back to item of first element
52968      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
52969        // if first elem has no width, default to size of container
52970        this.containerWidth;
52971    }
52972
52973    var columnWidth = this.columnWidth += this.gutter;
52974
52975    // calculate columns
52976    var containerWidth = this.containerWidth + this.gutter;
52977    var cols = containerWidth / columnWidth;
52978    // fix rounding errors, typically with gutters
52979    var excess = columnWidth - containerWidth % columnWidth;
52980    // if overshoot is less than a pixel, round up, otherwise floor it
52981    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
52982    cols = Math[ mathMethod ]( cols );
52983    this.cols = Math.max( cols, 1 );
52984  };
52985
52986  proto.getContainerWidth = function() {
52987    // container is parent if fit width
52988    var isFitWidth = this._getOption('fitWidth');
52989    var container = isFitWidth ? this.element.parentNode : this.element;
52990    // check that this.size and size are there
52991    // IE8 triggers resize on body size change, so they might not be
52992    var size = getSize( container );
52993    this.containerWidth = size && size.innerWidth;
52994  };
52995
52996  proto._getItemLayoutPosition = function( item ) {
52997    item.getSize();
52998    // how many columns does this brick span
52999    var remainder = item.size.outerWidth % this.columnWidth;
53000    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
53001    // round if off by 1 pixel, otherwise use ceil
53002    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
53003    colSpan = Math.min( colSpan, this.cols );
53004    // use horizontal or top column position
53005    var colPosMethod = this.options.horizontalOrder ?
53006      '_getHorizontalColPosition' : '_getTopColPosition';
53007    var colPosition = this[ colPosMethod ]( colSpan, item );
53008    // position the brick
53009    var position = {
53010      x: this.columnWidth * colPosition.col,
53011      y: colPosition.y
53012    };
53013    // apply setHeight to necessary columns
53014    var setHeight = colPosition.y + item.size.outerHeight;
53015    var setMax = colSpan + colPosition.col;
53016    for ( var i = colPosition.col; i < setMax; i++ ) {
53017      this.colYs[i] = setHeight;
53018    }
53019
53020    return position;
53021  };
53022
53023  proto._getTopColPosition = function( colSpan ) {
53024    var colGroup = this._getTopColGroup( colSpan );
53025    // get the minimum Y value from the columns
53026    var minimumY = Math.min.apply( Math, colGroup );
53027
53028    return {
53029      col: colGroup.indexOf( minimumY ),
53030      y: minimumY,
53031    };
53032  };
53033
53034  /**
53035   * @param {Number} colSpan - number of columns the element spans
53036   * @returns {Array} colGroup
53037   */
53038  proto._getTopColGroup = function( colSpan ) {
53039    if ( colSpan < 2 ) {
53040      // if brick spans only one column, use all the column Ys
53041      return this.colYs;
53042    }
53043
53044    var colGroup = [];
53045    // how many different places could this brick fit horizontally
53046    var groupCount = this.cols + 1 - colSpan;
53047    // for each group potential horizontal position
53048    for ( var i = 0; i < groupCount; i++ ) {
53049      colGroup[i] = this._getColGroupY( i, colSpan );
53050    }
53051    return colGroup;
53052  };
53053
53054  proto._getColGroupY = function( col, colSpan ) {
53055    if ( colSpan < 2 ) {
53056      return this.colYs[ col ];
53057    }
53058    // make an array of colY values for that one group
53059    var groupColYs = this.colYs.slice( col, col + colSpan );
53060    // and get the max value of the array
53061    return Math.max.apply( Math, groupColYs );
53062  };
53063
53064  // get column position based on horizontal index. #873
53065  proto._getHorizontalColPosition = function( colSpan, item ) {
53066    var col = this.horizontalColIndex % this.cols;
53067    var isOver = colSpan > 1 && col + colSpan > this.cols;
53068    // shift to next row if item can't fit on current row
53069    col = isOver ? 0 : col;
53070    // don't let zero-size items take up space
53071    var hasSize = item.size.outerWidth && item.size.outerHeight;
53072    this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;
53073
53074    return {
53075      col: col,
53076      y: this._getColGroupY( col, colSpan ),
53077    };
53078  };
53079
53080  proto._manageStamp = function( stamp ) {
53081    var stampSize = getSize( stamp );
53082    var offset = this._getElementOffset( stamp );
53083    // get the columns that this stamp affects
53084    var isOriginLeft = this._getOption('originLeft');
53085    var firstX = isOriginLeft ? offset.left : offset.right;
53086    var lastX = firstX + stampSize.outerWidth;
53087    var firstCol = Math.floor( firstX / this.columnWidth );
53088    firstCol = Math.max( 0, firstCol );
53089    var lastCol = Math.floor( lastX / this.columnWidth );
53090    // lastCol should not go over if multiple of columnWidth #425
53091    lastCol -= lastX % this.columnWidth ? 0 : 1;
53092    lastCol = Math.min( this.cols - 1, lastCol );
53093    // set colYs to bottom of the stamp
53094
53095    var isOriginTop = this._getOption('originTop');
53096    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
53097      stampSize.outerHeight;
53098    for ( var i = firstCol; i <= lastCol; i++ ) {
53099      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
53100    }
53101  };
53102
53103  proto._getContainerSize = function() {
53104    this.maxY = Math.max.apply( Math, this.colYs );
53105    var size = {
53106      height: this.maxY
53107    };
53108
53109    if ( this._getOption('fitWidth') ) {
53110      size.width = this._getContainerFitWidth();
53111    }
53112
53113    return size;
53114  };
53115
53116  proto._getContainerFitWidth = function() {
53117    var unusedCols = 0;
53118    // count unused columns
53119    var i = this.cols;
53120    while ( --i ) {
53121      if ( this.colYs[i] !== 0 ) {
53122        break;
53123      }
53124      unusedCols++;
53125    }
53126    // fit container to columns that have been used
53127    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
53128  };
53129
53130  proto.needsResizeLayout = function() {
53131    var previousWidth = this.containerWidth;
53132    this.getContainerWidth();
53133    return previousWidth != this.containerWidth;
53134  };
53135
53136  return Masonry;
53137
53138}));
53139
vendor: 5,161 bytes, lines 53140-53300
53140
53141// Sticky Plugin v1.0.4 for jQuery
53142// =============
53143// Author: Anthony Garand
53144// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk)
53145// Improvements by Leonardo C. Daronco (daronco)
53146// Created: 02/14/2011
53147// Date: 07/20/2015
53148// Website: http://stickyjs.com/
53149// Description: Makes an element on the page stick on the screen as you scroll
53150//              It will only set the 'top' and 'position' of your element, you
53151//              might need to adjust the width in some cases.
53152
53153(function (factory) {
53154	if (typeof define === 'function' && define.amd) {
53155		// AMD. Register as an anonymous module.
53156		define(['jquery'], factory);
53157	} else if (typeof module === 'object' && module.exports) {
53158		// Node/CommonJS
53159		module.exports = factory(require('jquery'));
53160	} else {
53161		// Browser globals
53162		factory(jQuery);
53163	}
53164}(function ($) {
53165	var slice = Array.prototype.slice; // save ref to original slice()
53166	var splice = Array.prototype.splice; // save ref to original slice()
53167
53168	var defaults = {
53169			topSpacing: 0,
53170			bottomSpacing: 0,
53171			className: 'is-sticky',
53172			wrapperClassName: 'sticky-wrapper',
53173			center: false,
53174			getWidthFrom: '',
53175			widthFromWrapper: true, // works only when .getWidthFrom is empty
53176			responsiveWidth: false,
53177			zIndex: 'auto'
53178		},
53179		$window = $(window),
53180		$document = $(document),
53181		sticked = [],
53182		windowHeight = $window.height(),
53183		scroller = function() {
53184			var scrollTop = $window.scrollTop(),
53185				documentHeight = $document.height(),
53186				dwh = documentHeight - windowHeight,
53187				extra = (scrollTop > dwh) ? dwh - scrollTop : 0;
53188
53189			for (var i = 0, l = sticked.length; i < l; i++) {
53190				var s = sticked[i],
53191					elementTop = s.stickyWrapper.offset().top,
53192					etse = elementTop - s.topSpacing - extra;
53193
53194				//update height in case of dynamic content
53195				s.stickyWrapper.css('height', s.stickyElement.outerHeight());
53196
53197				if (scrollTop <= etse) {
53198					if (s.currentTop !== null) {
53199						s.stickyElement
53200							.css({
53201								'width': '',
53202								'position': '',
53203								'top': '',
53204								'z-index': ''
53205							});
53206						s.stickyElement.parent().removeClass(s.className);
53207						s.stickyElement.trigger('sticky-end', [s]);
53208						s.currentTop = null;
53209					}
53210				}
53211				else {
53212					var newTop = documentHeight - s.stickyElement.outerHeight()
53213						- s.topSpacing - s.bottomSpacing - scrollTop - extra;
53214					if (newTop < 0) {
53215						newTop = newTop + s.topSpacing;
53216					} else {
53217						newTop = s.topSpacing;
53218					}
53219					if (s.currentTop !== newTop) {
53220						var newWidth;
53221						if (s.getWidthFrom) {
53222							newWidth = $(s.getWidthFrom).width() || null;
53223						} else if (s.widthFromWrapper) {
53224							newWidth = s.stickyWrapper.width();
53225						}
53226						if (newWidth == null) {
53227							newWidth = s.stickyElement.width();
53228						}
53229						s.stickyElement
53230							.css('width', newWidth)
53231							.css('position', 'fixed')
53232							.css('top', newTop)
53233							.css('z-index', s.zIndex);
53234
53235						s.stickyElement.parent().addClass(s.className);
53236
53237						if (s.currentTop === null) {
53238							s.stickyElement.trigger('sticky-start', [s]);
53239						} else {
53240							// sticky is started but it have to be repositioned
53241							s.stickyElement.trigger('sticky-update', [s]);
53242						}
53243
53244						if (s.currentTop === s.topSpacing && s.currentTop > newTop || s.currentTop === null && newTop < s.topSpacing) {
53245							// just reached bottom || just started to stick but bottom is already reached
53246							s.stickyElement.trigger('sticky-bottom-reached', [s]);
53247						} else if(s.currentTop !== null && newTop === s.topSpacing && s.currentTop < newTop) {
53248							// sticky is started && sticked at topSpacing && overflowing from top just finished
53249							s.stickyElement.trigger('sticky-bottom-unreached', [s]);
53250						}
53251
53252						s.currentTop = newTop;
53253					}
53254
53255					// Check if sticky has reached end of container and stop sticking
53256					var stickyWrapperContainer = s.stickyWrapper.parent();
53257					var unstick = (s.stickyElement.offset().top + s.stickyElement.outerHeight() >= stickyWrapperContainer.offset().top + stickyWrapperContainer.outerHeight()) && (s.stickyElement.offset().top <= s.topSpacing);
53258
53259					if( unstick ) {
53260						s.stickyElement
53261							.css('position', 'absolute')
53262							.css('top', '')
53263							.css('bottom', 0)
53264							.css('z-index', '');
53265					} else {
53266						s.stickyElement
53267							.css('position', 'fixed')
53268							.css('top', newTop)
53269							.css('bottom', '')
53270							.css('z-index', s.zIndex);
53271					}
53272				}
53273			}
53274		},
53275		resizer = function() {
53276			windowHeight = $window.height();
53277
53278			for (var i = 0, l = sticked.length; i < l; i++) {
53279				var s = sticked[i];
53280				var newWidth = null;
53281				if (s.getWidthFrom) {
53282					if (s.responsiveWidth) {
53283						newWidth = $(s.getWidthFrom).width();
53284					}
53285				} else if(s.widthFromWrapper) {
53286					newWidth = s.stickyWrapper.width();
53287				}
53288				if (newWidth != null) {
53289					s.stickyElement.css('width', newWidth);
53290				}
53291			}
53292		},
53293		methods = {
53294			init: function(options) {
53295				return this.each(function() {
53296					var o = $.extend({}, defaults, options);
53297					var stickyElement = $(this);
53298
53299					var stickyId = stickyElement.attr('id');
53300					var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName;
53301					var wrapper = $('<div></div>')
53302						.attr('id', wrapperId)
53303						.addClass(o.wrapperClassName);
53304
53305					stickyElement.wrapAll(function() {
53306						if ($(this).parent("#" + wrapperId).length == 0) {
53307							return wrapper;
53308						}
53309					});
53310
53311					var stickyWrapper = stickyElement.parent();
53312
53313					if (o.center) {
53314						stickyWrapper.css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"});
53315					}
53316
53317					if (stickyElement.css("float") === "right") {
53318						stickyElement.css({"float":"none"}).parent().css({"float":"right"});
53319					}
53320
53321					o.stickyElement = stickyElement;
53322					o.stickyWrapper = stickyWrapper;
53323					o.currentTop    = null;
53324
53325					sticked.push(o);
53326
53327					methods.setWrapperHeight(this);
53328					methods.setupChangeListeners(this);
53329				});
53330			},
53331
53332			setWrapperHeight: function(stickyElement) {
53333				var element = $(stickyElement);
53334				var stickyWrapper = element.parent();
53335				if (stickyWrapper) {
53336					stickyWrapper.css('height', element.outerHeight());
53337				}
53338			},
53339
53340			setupChangeListeners: function(stickyElement) {
53341				if (window.MutationObserver) {
53342					var mutationObserver = new window.MutationObserver(function(mutations) {
53343						if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) {
53344							methods.setWrapperHeight(stickyElement);
53345						}
53346					});
53347					mutationObserver.observe(stickyElement, {subtree: true, childList: true});
53348				} else {
53349					if (window.addEventListener) {
53350						stickyElement.addEventListener('DOMNodeInserted', function() {
53351							methods.setWrapperHeight(stickyElement);
53352						}, false);
53353						stickyElement.addEventListener('DOMNodeRemoved', function() {
53354							methods.setWrapperHeight(stickyElement);
53355						}, false);
53356					} else if (window.attachEvent) {
53357						stickyElement.attachEvent('onDOMNodeInserted', function() {
53358							methods.setWrapperHeight(stickyElement);
53359						});
53360						stickyElement.attachEvent('onDOMNodeRemoved', function() {
53361							methods.setWrapperHeight(stickyElement);
53362						});
53363					}
53364				}
53365			},
53366			update: scroller,
53367			unstick: function(options) {
53368				return this.each(function() {
53369					var that = this;
53370					var unstickyElement = $(that);
53371
53372					var removeIdx = -1;
53373					var i = sticked.length;
53374					while (i-- > 0) {
53375						if (sticked[i].stickyElement.get(0) === that) {
53376							splice.call(sticked,i,1);
53377							removeIdx = i;
53378						}
53379					}
53380					if(removeIdx !== -1) {
53381						unstickyElement.unwrap();
53382						unstickyElement
53383							.css({
53384								'width': '',
53385								'position': '',
53386								'top': '',
53387								'float': '',
53388								'z-index': ''
53389							})
53390						;
53391					}
53392				});
53393			}
53394		};
53395
53396	// should be more efficient than using $window.scroll(scroller) and $window.resize(resizer):
53397	if (window.addEventListener) {
53398		window.addEventListener('scroll', scroller, false);
53399		window.addEventListener('resize', resizer, false);
53400	} else if (window.attachEvent) {
53401		window.attachEvent('onscroll', scroller);
53402		window.attachEvent('onresize', resizer);
53403	}
53404
53405	$.fn.sticky = function(method) {
53406		if (methods[method]) {
53407			return methods[method].apply(this, slice.call(arguments, 1));
53408		} else if (typeof method === 'object' || !method ) {
53409			return methods.init.apply( this, arguments );
53410		} else {
53411			$.error('Method ' + method + ' does not exist on jQuery.sticky');
53412		}
53413	};
53414
53415	$.fn.unstick = function(method) {
53416		if (methods[method]) {
53417			return methods[method].apply(this, slice.call(arguments, 1));
53418		} else if (typeof method === 'object' || !method ) {
53419			return methods.unstick.apply( this, arguments );
53420		} else {
53421			$.error('Method ' + method + ' does not exist on jQuery.sticky');
53422		}
53423	};
53424	$(function() {
53425		setTimeout(scroller, 0);
53426	});
53427}));
53428
53429/*!
53430 hey, [be]Lazy.js - v1.8.2 - 2016.10.25
53431 A fast, small and dependency free lazy load script (https://github.com/dinbror/blazy)
53432 (c) Bjoern Klinggaard - @bklinggaard - http://dinbror.dk/blazy
53433 */
53434(function(q,m){"function"===typeof define&&define.amd?define(m):"object"===typeof exports?module.exports=m():q.Blazy=m()})(this,function(){function q(b){var c=b._util;c.elements=E(b.options);c.count=c.elements.length;c.destroyed&&(c.destroyed=!1,b.options.container&&l(b.options.container,function(a){n(a,"scroll",c.validateT)}),n(window,"resize",c.saveViewportOffsetT),n(window,"resize",c.validateT),n(window,"scroll",c.validateT));m(b)}function m(b){for(var c=b._util,a=0;a<c.count;a++){var d=c.elements[a],e;a:{var g=d;e=b.options;var p=g.getBoundingClientRect();if(e.container&&y&&(g=g.closest(e.containerClass))){g=g.getBoundingClientRect();e=r(g,f)?r(p,{top:g.top-e.offset,right:g.right+e.offset,bottom:g.bottom+e.offset,left:g.left-e.offset}):!1;break a}e=r(p,f)}if(e||t(d,b.options.successClass))b.load(d),c.elements.splice(a,1),c.count--,a--}0===c.count&&b.destroy()}function r(b,c){return b.right>=c.left&&b.bottom>=c.top&&b.left<=c.right&&b.top<=c.bottom}function z(b,c,a){if(!t(b,a.successClass)&&(c||a.loadInvisible||0<b.offsetWidth&&0<b.offsetHeight))if(c=b.getAttribute(u)||b.getAttribute(a.src)){c=c.split(a.separator);var d=c[A&&1<c.length?1:0],e=b.getAttribute(a.srcset),g="img"===b.nodeName.toLowerCase(),p=(c=b.parentNode)&&"picture"===c.nodeName.toLowerCase();if(g||void 0===b.src){var h=new Image,w=function(){a.error&&a.error(b,"invali
53434d");v(b,a.errorClass);k(h,"error",w);k(h,"load",f)},f=function(){g?p||B(b,d,e):b.style.backgroundImage='url("'+d+'")';x(b,a);k(h,"load",f);k(h,"error",w)};p&&(h=b,l(c.getElementsByTagName("source"),function(b){var c=a.srcset,e=b.getAttribute(c);e&&(b.setAttribute("srcset",e),b.removeAttribute(c))}));n(h,"error",w);n(h,"load",f);B(h,d,e)}else b.src=d,x(b,a)}else"video"===b.nodeName.toLowerCase()?(l(b.getElementsByTagName("source"),function(b){var c=a.src,e=b.getAttribute(c);e&&(b.setAttribute("src",e),b.removeAttribute(c))}),b.load(),x(b,a)):(a.error&&a.error(b,"missing"),v(b,a.errorClass))}function x(b,c){v(b,c.successClass);c.success&&c.success(b);b.removeAttribute(c.src);b.removeAttribute(c.srcset);l(c.breakpoints,function(a){b.removeAttribute(a.src)})}function B(b,c,a){a&&b.setAttribute("srcset",a);b.src=c}function t(b,c){return-1!==(" "+b.className+" ").indexOf(" "+c+" ")}function v(b,c){t(b,c)||(b.className+=" "+c)}function E(b){var c=[];b=b.root.querySelectorAll(b.selector);for(var a=b.length;a--;c.unshift(b[a]));return c}function C(b){f.bottom=(window.innerHeight||document.documentElement.clientHeight)+b;f.right=(window.innerWidth||document.documentElement.clientWidth)+b}function n(b,c,a){b.attachEvent?b.attachEvent&&b.attachEvent("on"+c,a):b.addEventListener(c,a,{capture:!1,passive:!0})}function k(b,c,a){b.detachEvent?b.detachEvent&&b.detachEvent("on"+c,a):b.removeEventListener(c,a,{capture:!1,passive:!0})}function l(b,c){if(b&&c)for(var a=b.length,d=0;d<a&&!1!==c(b[d],d);d++);}function D(b,c,a){var d=0;return function(){var e=+new Date;e-d<c||(d=e,b.apply(a,arguments))}}var u,f,A,y;return function(b){if(!document.querySelectorAll){var c=document.createStyleSheet();document.querySelectorAll=function(a,b,d,h,f){f=document.all;b=[];a=a.replace(/\[for\b/gi,"[htmlFor").split(",");for(d=a.length;d--;){c.addRule(a[d],"k:v");for(h=f.length;h--;)f[h].currentStyle.k&&b.push(f[h]);c.removeRule(0)}return b}}var a=this,d=a._util={};d.elements=[];d.destroyed=!0;a.options=b||{};a.options.error=a.options.error||!1;a.options.offset=a.options.offset||100;a.options.root=a.options.root||document;a.options.success=a.options.success||!1;a.options.selector=a.options.selector||".b-lazy";a.options.separator=a.options.separator||"|";a.options.containerClass=a.options.container;a.options.container=a.options.containerClass?document.querySelectorAll(a.options.containerClass):!1;a.options.errorClass=a.options.errorClass||"b-error";a.options.breakpoints=a.options.breakpoints||!1;a.options.loadInvisible=a.options.loadInvisible||!1;a.options.successClass=a.options.successClass||"b-loaded";a.options.validateDelay=a.options.validateDelay||25;a.options.saveViewportOffsetDelay=a.options.saveViewportOffsetDelay||50;a.options.srcset=a.options.srcset||"data-srcset";a.options.src=u=a.options.src||"data-src";y=Element.prototype.closest;A=1<window.devicePixelRatio;f={};f.top=0-a.options.offset;f.left=0-a.options.offset;a.revalidate=function(){q(a)};a.load=function(a,b){var c=this.options;void 0===a.length?z(a,b,c):l(a,function(a){z(a,b,c)})};a.destroy=function(){var a=this._util;this.options.container&&l(this.options.container,function(b){k(b,"scroll",a.validateT)});k(window,"scroll",a.validateT);k(window,"resize",a.validateT);k(window,"resize",a.saveViewportOffsetT);a.count=0;a.elements.length=0;a.destroyed=!0};d.validateT=D(function(){m(a)},a.options.validateDelay,a);d.saveViewportOffsetT=D(function(){C(a.options.offset)},a.options.saveViewportOffsetDelay,a);C(a.options.offset);l(a.options.breakpoints,function(a){if(a.width>=window.screen.width)return u=a.src,!1});setTimeout(function(){q(a)})}});
53435
53436/*
53437	By Osvaldas Valutis, www.osvaldas.info
53438	Available for use under the MIT License
53439*/
53440
53441'use strict';
53442
53443; (function ($, window, document, undefined) {
53444	$('.inputfile').each(function () {
53445
53446		var $input = $(this),
53447			$label = $input.next('label'),
53448			labelVal = $label.html();
53449
53450		$input.on('change', function (e) {
53451			var fileName = '';
53452
53453			if (this.files && this.files.length > 1)
53454				fileName = (this.getAttribute('data-multiple-caption') || '').replace('{count}', this.files.length);
53455			else if (e.target.value)
53456				fileName = e.target.value.split('\\').pop();
53457
53458			if (fileName)
53459				$label.find('span').html(fileName);
53460			else
53461				$label.html(labelVal);
53462
53463		});
53464
53465		// Firefox bug fix
53466		$input
53467			.on('focus', function () { $input.addClass('has-focus'); })
53468			.on('blur', function () { $input.removeClass('has-focus'); });
53469	});
53470})(jQuery, window, document);
53471
53472var bLazy;
53473(function ($) {
53474
53475  $(document).ready(function () {
53476
53477    initLazyLoading();
53478    initExpandArticle();
53479    initExpandErrorList();
53480    initMasonry();
53481    initAccordion();
53482    initSlideToggle();
53483    initHacklines();
53484    init360();
53485    initBooking();
53486    initMobileBooking();
53487    initSticky();
53488    initScrollbars();
53489    initSlider();
53490    initTabs();
53491    initMobileMenu();
53492    initEqualHeight();
53493    initContentNav();
53494    initSearchBtn();
53495    initSearch();
53496    initHome();
53497    initDiscoverPage();
53498    initSubMenu();
53499    initForms();
53500    initAjaxEntries();
53501    initLightbox();
53502    initTilesTransition();
53503    initBuyInPerson();
53504    initTools();
53505    initHeaderBooking();
53506    initGeneralBooking();
53507    initPageLang();
53508    initBreadcrumb();
53509    initArticleClick();
53510    initDiscountClick();
53511    verifyAnchors();
53512    initPreventOverScrollMobile();
53513    initHideTools();
53514    initDiscountsSlider();
53515    initHeaderImage();
53516    initCareerForm();
53517    initHeaderPopinBookDirect();
53518
53519    // Must stay at the end
53520    initAnchors();
53521
53522  });
53523
53524  function initLazyLoading() {
53525    bLazy = new Blazy({
53526      loadInvisible: true,
53527      offset: 200
53528    });
53529  }
53530
53531  function initAnchors() {
53532    $("#content a[href^='#']").click(function () {
53533      var $target = $($(this).attr("href"));
53534      if ($target.length > 0) {
53535        var targetOffsetTop = $target.offset().top;
53536        var topSpacing = getTopSpacing(targetOffsetTop);
53537        $('html, body').animate({ scrollTop: targetOffsetTop - topSpacing }, 600);
53538        return false;
53539      }
53540    });
53541
53542
53543    //var CookieGet = $.cookie("arrow-down");
53544    if (/*!CookieGet && */$('.btn-arrow-down').length > 0) {
53545      var hideArrowDown = function () {
53546        //$.cookie("arrow-down", 1, { path: '/' });
53547        $('.btn-arrow-down').fadeOut(250);
53548      }
53549
53550      /*$(window).bind("scroll", function () {
53551          if ($(this).scrollTop() >= 350 && $('.btn-arrow-down').is(":visible")) {
53552              hideArrowDown();
53553          }
53554      });*/
53555
53556      $('.btn-arrow-down').show().click(function (e) {
53557        e.preventDefault();
53558        var $headerImage = $(this).closest('.header-image');
53559
53560        $('html, body').animate({
53561          scrollTop: $headerImage.offset().top + $headerImage.height()
53562        }, 600);
53563
53564        //hideArrowDown();
53565
53566      });
53567    }
53568  }
53569
53570  function initDiscountsSlider() {
53571    var userAgent = navigator.userAgent.toLowerCase();
53572    var $discountsSlider = $('#offers-discounts .slider .slick-list, #offers-discounts .slider .slick-track');
53573    if (userAgent.indexOf('safari') != -1) {
53574      if (userAgent.indexOf('chrome') > -1) {
53575        //browser is chrome
53576        $discountsSlider.css({ "display": "flex" });
53577      } else if (userAgent.indexOf('MSIE') > -1) {
53578        //browser is explorer
53579        $discountsSlider.css({ "display": "block" });
53580      } else {
53581        //browser is safari, add css
53582        $discountsSlider.css({ "display": "block" });
53583      }
53584    }
53585  }
53586
53587  function initHeaderImage() {
53588    var $hasVideo = $('.has-video');
53589    var $noVideo = $('.no-video');
53590    if ($hasVideo.length > 0 && $noVideo.length > 0) {
53591      $hasVideo.addClass('enable');
53592      $noVideo.addClass('enable');
53593    }
53594  }
53595
53596  function initTools() {
53597    $('.tools .icon-share').click(function () {
53598      return false;
53599    });
53600    $('.tools ._share').mouseenter(function () {
53601      $(this).css({ "transform": "translate(-80.5%, 0px)" });
53602    }).mouseleave(function () {
53603      $(this).css({ "transform": "translate(0px, 0px)" });
53604    });
53605    $('.tools .icon-arrow-regular-right').click(function () {
53606      $('html, body').animate({
53607        scrollTop: $('body')
53608          .offset()
53609          .top
53610      }, 600);
53611      return false;
53612    });
53613  }
53614
53615  function initBreadcrumb() {
53616    var $breadcrumbCurrentPage = $('.breadcrumb >ul >li:last-child a');
53617    $breadcrumbCurrentPage.click(function () {
53618      return false;
53619    });
53620  }
53621
53622  function initExpandArticle() {
53623    $("#content").on("click", ".expand-article", function () {
53624      var $card = $(this).closest(".article-card");
53625      var $teaser = $card.find("._teaser");
53626      var $expand = $card.find("._expand");
53627      var teaserHeight = $teaser[0].scrollHeight;
53628      var $thumb = $card.find("._thumb");
53629      if ($teaser.height() == 0) {
53630        $teaser.animate({ height: teaserHeight }, 400);
53631        $thumb.animate({ height: $thumb.find(">div").outerHeight() - teaserHeight }, 400);
53632        $thumb.find(">div").animate({ top: -teaserHeight / 2 }, 400);
53633        $expand.css({ "transform": "rotate(90deg)" });
53634      } else {
53635        $teaser.animate({ height: 0 }, 400);
53636        $thumb.animate({ height: $thumb.find(">div").outerHeight() }, 400);
53637        $thumb.find(">div").animate({ top: 0 }, 400);
53638        $expand.css({ "transform": "rotate(0deg)" });
53639      }
53640      return false;
53641    });
53642
53643    $('._intro-btn .button, ._expand-btn .button').click(function () {
53644      if ($(this).find('.read-more').is(':visible')) {
53645        $(this).find('.read-more').css({ "display": "none" });
53646        $(this).find('.close').css({ "display": "block" });
53647      } else {
53648        $(this).find('.read-more').css({ "display": "block" });
53649        $(this).find('.close').css({ "display": "none" });
53650      }
53651    });
53652  }
53653
53654  function initExpandErrorList() {
53655    var $errorsBtn = $("._errors-list .button");
53656    var $errorList = $('._errors-list').find("._list");
53657    var initialHeight = $errorList.height();
53658    if ($errorList.height() > 90) {
53659      $errorsBtn.show();
53660      $errorList.height(90);
53661      initialHeight = 90;
53662    }
53663    $errorsBtn.on("click", function () {
53664      var errorListHeight = $errorList[0].scrollHeight;
53665
53666      if ($errorList.height() == initialHeight) {
53667        $('._errors-list ._list').animate({ height: errorListHeight }, 400);
53668      } else {
53669        $('._errors-list ._list').animate({ height: initialHeight }, 400);
53670
53671        $('html, body').animate({
53672          scrollTop: $(this).closest('._errors-list').offset().top - $('.header').height() - 20
53673        }, 400);
53674      }
53675
53676      return false;
53677    });
53678  }
53679
53680  function initMasonry() {
53681    $('.masonry').masonry({
53682      percentPosition: true,
53683      gutter: 24,
53684      transitionDuration: 0
53685    });
53686  }
53687
53688  function initAccordion() {
53689    $('.accordion').each(function () {
53690      var $accordion = $(this);
53691      $accordion.find("._item > ._title").click(function () {
53692        $accordion.find("._item.active").not($(this).parent()).removeClass("active").find("._text").slideUp(400);
53693        $(this).siblings("._text").slideToggle(400);
53694        $(this).parent().toggleClass("active");
53695      });
53696    });
53697  }
53698
53699  function initSlideToggle() {
53700    $('.slide-toggle').click(function (event) {
53701      if ($(this).find('.read-more').is(':visible')) {
53702        $(this).find('.read-more').css({ "display": "none" });
53703        $(this).find('.close').css({ "display": "block" });
53704      } else {
53705        $(this).find('.read-more').css({ "display": "block" });
53706        $(this).find('.close').css({ "display": "none" });
53707      }
53708
53709      $($(this).attr("href")).slideToggle(400);
53710      event.stopImmediatePropagation();
53711      return false;
53712    });
53713  }
53714
53715  function initHacklines() {
53716    $('[data-hack-lines]').each(function () {
53717      var $link = $(this);
53718      var $target = $($link.attr("href"));
53719
53720      var lineHeight = parseFloat($target.css('line-height'));
53721
53722      var nbLines = parseFloat($link.data('hack-lines'));
53723      var initialHeight = lineHeight * nbLines;
53724
53725      var currentHeight = $target.height();
53726
53727      if (currentHeight <= initialHeight) return;
53728
53729      $link.show();
53730
53731      $target.css({ "height": initialHeight, "overflow": "hidden" });
53732
53733      $link.click(function (event) {
53734        var targetHeight = $target.height();
53735        if (targetHeight == initialHeight) {
53736          $target.css("height", "auto");
53737          var heightAuto = $target.height();
53738          $target.css("height", initialHeight);
53739
53740          $target.animate({
53741            "height": heightAuto
53742          });
53743        }
53744        else {
53745          $target.animate({
53746            "height": initialHeight
53747          });
53748        }
53749        event.stopImmediatePropagation();
53750        return false;
53751      });
53752    });
53753  }
53754
53755  function init360() {
53756    $('.toggle-360').click(function () {
53757      $($(this).attr("href")).toggle();
53758      return false;
53759    });
53760  }
53761
53762  function initBooking() {
53763    if ($('.header-booking-wrapper').is(":visible")) {
53764      $('.header-booking').sticky({
53765        topSpacing: 0,
53766        zIndex: 3000
53767      });
53768    }
53769  }
53770
53771  function initSticky() {
53772    $('.sticky').each(function () {
53773      var $this = $(this);
53774      var topSpacing = 0;
53775      $(".sticky").not($this).each(function () {
53776        if ($(this).offset().top < $this.offset().top) {
53777          topSpacing += $(this).height();
53778        }
53779      });
53780      $this.sticky({
53781        topSpacing: topSpacing,
53782        zIndex: 2000
53783      });
53784    });
53785  }
53786
53787  function initScrollbars() {
53788    $('.custom-scrollbar').mCustomScrollbar();
53789  }
53790
53791  function initSlider() {
53792    var $slider2and3 = $(".slider[data-slick*='3'], .slider[data-slick*='2']").slick({
53793      dots: true,
53794      infinite: true, //false
53795      slidesToShow: 3,
53796      slidesToScroll: 3,
53797      autoplay: true,
53798      autoplaySpeed: 5000,
53799
53800      responsive: [
53801        {
53802          breakpoint: 900,
53803          settings: {
53804            slidesToShow: 2,
53805            slidesToScroll: 2
53806          }
53807        },
53808        {
53809          breakpoint: 680,
53810          settings: {
53811            slidesToShow: 1,
53812            slidesToScroll: 1
53813          }
53814        }
53815      ],
53816    });
53817
53818    $('.slider').not($slider2and3).slick({
53819      dots: true,
53820      infinite: true, //false
53821      autoplay: true,
53822      autoplaySpeed: 5000,
53823    });
53824
53825    $('.slider').on("afterChange", function (event, slick, currentSlide) {
53826      bLazy.revalidate();
53827    });
53828  }
53829
53830  function initTabs() {
53831    $(".tab-content").hide().first().show();
53832    $(".tabs .tab").first().addClass("current");
53833    $(".tabs .tab").click(function () {
53834      $(".tabs .tab").removeClass("current");
53835      $(this).addClass("current");
53836      $(".tab-content").hide();
53837      $("#" + $(this).data("tab")).show();
53838    });
53839  }
53840
53841  function initMobileMenu() {
53842    var $secondaryNav = $('.header ._container ._secondary-nav');
53843    var $menuMobile = $('.menu-mobile');
53844    var $toggleButton = $('<div class="toggle-button"><span></span><span></span><span></span></div>').insertAfter($secondaryNav);
53845    var $toggleButtonClose = $('<div class="toggle-button-close"><span></span><span></span></div>').appendTo($menuMobile);
53846
53847    var openFunction = function (e) {
53848      e.preventDefault();
53849      $('#content, .footer').bind('touchstart', function (e) {
53850        e.preventDefault();
53851      });
53852      $('.header').bind('touchmove', function (e) {
53853        e.preventDefault();
53854      });
53855      $('.toggle-button').css({
53856        "visibility": "hidden"
53857      });
53858      $('.toggle-button-close').css({
53859        "display": "block"
53860      });
53861
53862      $menuMobile.addClass("open");
53863
53864      $('html, body').css({
53865        "overflow": "hidden"
53866      });
53867    };
53868
53869    var closeFunction = function (e) {
53870      e.preventDefault();
53871      $('#content, .footer').unbind('touchstart');
53872      $('.header').unbind('touchmove');
53873      $('.toggle-button').css({
53874        "visibility": "visible"
53875      });
53876      $('.toggle-button-close').css({
53877        "display": "none"
53878      });
53879
53880      $menuMobile.removeClass("open");
53881
53882      $('html, body').css({
53883        "overflow": "auto"
53884      });
53885    };
53886
53887    $toggleButton.click(function (e) {
53888      openFunction(e);
53889    });
53890    $toggleButtonClose.click(function (e) {
53891      closeFunction(e);
53892    });
53893
53894    /*$('#content, .footer').click(function (e) {
53895      closeFunction(e);
53896    });*/
53897
53898    var $mobileHome = $('.menu-mobile .mobile-home');
53899    $mobileHome.fadeIn(250);
53900    $('.header ._main-nav').clone().appendTo($mobileHome);
53901    $('.footer ._footer-1 ._menu.-gray').clone().appendTo($mobileHome);
53902    $('.footer ._footer-2').clone().appendTo($mobileHome);
53903    $('.menu-mobile ._btn-container').insertAfter($('.menu-mobile .mobile-home ._menu.-gray'));
53904    $('.footer ._footer-1 ._follow').clone().insertAfter('.menu-mobile .mobile-home ._btn-container');
53905
53906    var $mobileDestinationsLink = $('.menu-mobile .mobile-home ._main-nav li.-has-subnav');
53907    $mobileDestinationsLink.removeClass('-has-subnav').addClass('-has-mobile-subnav');
53908    var $mobileDestinations = $('.mobile-destinations');
53909
53910    var $mobileSubNav = $(".mobile-sub-nav");
53911    var $mobileProvincesSubNav = $('.provinces-sub-nav');
53912    var $mobileAllHostels = $(".mobile-all-hostels");
53913
53914    $('.mobile-home ._main-nav >ul >li.-has-mobile-subnav >a').click(function () {
53915      $(this).closest(".mobile-sub-nav").fadeOut(250);
53916      $('.mobile-toggle-lang').css('display', 'none');
53917      $mobileDestinations.fadeIn(250);
53918      $('.menu-mobile').scrollTop($('body').offset().top);
53919      return false;
53920    });
53921
53922    $('.mobile-destinations .toggle-mobile-all-hostels').click(function () {
53923      $(this).closest(".mobile-sub-nav").fadeOut(250);
53924      $mobileAllHostels.fadeIn(250);
53925      $('.menu-mobile').animate({ scrollTop: $('body').offset().top }, 250);
53926      return false;
53927    });
53928
53929    $('.mobile-destinations .toggle-mobile-province').click(function () {
53930      $(this).closest(".mobile-sub-nav").fadeOut(250);
53931      $mobileProvincesSubNav.filter("#mobile-" + $(this).attr("href").substr(1)).fadeIn(250);
53932      $('.menu-mobile').animate({ scrollTop: $('body').offset().top }, 250);
53933      return false;
53934    });
53935
53936    // back
53937    $('.mobile-destinations ._top-title').click(function () {
53938      $(this).closest(".mobile-sub-nav").fadeOut(0);
53939      $mobileHome.fadeIn(250);
53940      $('.menu-mobile').animate({ scrollTop: $('body').offset().top }, 250);
53941      $('.mobile-toggle-lang').css('display', 'inline-block');
53942      return false;
53943    });
53944
53945    $('.provinces-sub-nav ._top-title').click(function () {
53946      $(this).closest(".provinces-sub-nav").fadeOut(250);
53947      $mobileDestinations.fadeIn(250);
53948      $('.menu-mobile').animate({ scrollTop: $('body').offset().top }, 250);
53949      return false;
53950    });
53951
53952    $('.mobile-all-hostels ._top-title').click(function () {
53953      $(this).closest(".mobile-sub-nav").fadeOut(250);
53954      $mobileDestinations.fadeIn(250);
53955      $('.menu-mobile').animate({ scrollTop: $('body').offset().top }, 250);
53956      return false;
53957    });
53958  }
53959
53960  function beginTilesTransition() {
53961    var elementsToShow = [];
53962    $('.card').each(function () {
53963      if (!$(this).hasClass("-beganAnimation") && isScrolledIntoView(this) && elementsToShow.indexOf($(this)) == -1) {
53964        $(this).addClass("-beganAnimation");
53965        elementsToShow.push($(this));
53966      }
53967    });
53968    $.each(elementsToShow, function (index, element) {
53969      var $element = element;
53970      setTimeout(function () {
53971        $element.addClass("-fadeIn");
53972      }, 200 * index);
53973    });
53974  }
53975
53976  function initTilesTransition() {
53977    $(window).bind("scroll resize", function () {
53978      beginTilesTransition();
53979    });
53980    beginTilesTransition();
53981  }
53982
53983  function isScrolledIntoView(elem) {
53984    var docViewTop = $(window).scrollTop();
53985    var docViewBottom = docViewTop + $(window).height();
53986
53987    var elemTop = $(elem).offset().top;
53988    var elemBottom = elemTop + ($(elem).height() * .16);
53989
53990    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
53991  }
53992
53993  function initSearchBtn() {
53994    if ($('.header-booking-wrapper').length > 0) {
53995
53996      var $searchBtn = $('.search-btn');
53997      var $searchBtnClone = $searchBtn.clone().addClass('search-clone').insertAfter('.header.sticky');
53998
53999      var distance = $('.header-booking-wrapper').offset().top;
54000      var $window = $(window);
54001
54002      if (!Modernizr.mq('(max-width: 900px)')) {
54003        $window.bind("scroll resize", function () {
54004          if ($window.scrollTop() >= distance - $(".header").height()) {
54005            $searchBtn.css("visibility", "hidden");
54006            $searchBtnClone.show().css({
54007              'left': $searchBtn.offset().left,
54008              'top': 0,
54009            });
54010          } else {
54011            $searchBtnClone.hide();
54012            $searchBtn.css("visibility", "visible");
54013          }
54014        });
54015      }
54016    }
54017  }
54018
54019  function getTopSpacing(targetOffsetTop) {
54020    var topSpacing = 0;
54021    $(".sticky").each(function () {
54022      if ($(this).parent().offset().top < targetOffsetTop) {
54023        topSpacing += $(this).height();
54024      }
54025    });
54026    return topSpacing;
54027  }
54028
54029  function initEqualHeight() {
54030    if ($(window).width() >= 681) {
54031      $(".information-cards .card").matchHeight({
54032        byRow: false
54033      });
54034    }
54035  }
54036
54037  function initContentNav() {
54038    var $contentNav = $(".content-nav");
54039    var $indicator = $contentNav.find('.current-indicator');
54040    $(document).bind("scroll", function () {
54041      var docScroll = $(document).scrollTop();
54042      var $link = null;
54043      var padding = ($contentNav.find("a").first().outerWidth() - $contentNav.find("a").first().width()) / 2;
54044
54045      $contentNav.find("a").each(function () {
54046        var $target = $($(this).attr("href"));
54047        if ($target.length > 0) {
54048          var offsetTop = $target.offset().top;
54049          if (docScroll >= (offsetTop - getTopSpacing(offsetTop) - 5) &&
54050            docScroll < (offsetTop - getTopSpacing(offsetTop)) + $target.outerHeight()) {
54051            $link = $(this);
54052          }
54053        }
54054      });
54055
54056      if ($link) {
54057        $indicator.css({
54058          width: $link.width(),
54059          left: $link.position().left + padding
54060        });
54061      }
54062
54063      var $firstTarget = $($contentNav.find("a").first().attr("href"));
54064      var $lastTarget = $($contentNav.find("a").last().attr("href"));
54065
54066      if ($firstTarget.length > 0 && $lastTarget.length > 0) {
54067        var firstTargetOffset = $firstTarget.offset().top;
54068        var lastTargetOffset = $lastTarget.offset().top;
54069        if (docScroll >= (firstTargetOffset - getTopSpacing(firstTargetOffset) - 5) &&
54070          docScroll < (lastTargetOffset - getTopSpacing(lastTargetOffset)) + $lastTarget.outerHeight()) {
54071          $indicator.fadeIn();
54072        } else {
54073          $indicator.fadeOut();
54074        }
54075      }
54076    }).trigger("scroll");
54077  }
54078
54079  // Survey popup hide show functionality
54080  $(document).ready(function () {
54081    var siteLang = $('html')[0].lang,
54082      cookieID = $('#js-popup').data('cookieId'),
54083      langSetting = $('#js-popup').data('langSetting'),
54084      langMatch = false;
54085
54086    if (langSetting == 'en fr') {
54087      langMatch = true;
54088    } else {
54089      if (siteLang == langSetting) {
54090        langMatch = true;
54091      }
54092    }
54093
54094    if (langMatch) {
54095      if (localStorage.getItem(cookieID) != 'shown' || cookieID == 'dev') {
54096        $('#js-popup').fadeIn();
54097        localStorage.setItem(cookieID, 'shown');
54098        $('body').addClass('u-overflow-hidden');
54099      }
54100    }
54101
54102    $('.js-popup-close').click(function (e) {
54103      $(e).preventDefault();
54104      $('#js-popup').fadeOut();
54105      $('body').removeClass('u-overflow-hidden');
54106    });
54107
54108    // hiding popup if clicked outside the element
54109    $('body').click(function (e) {
54110      if (!$(event.target).hasClass('popup')) {
54111        $("#js-popup").fadeOut();
54112        $('body').removeClass('u-overflow-hidden');
54113      }
54114    });
54115
54116    // hiding popup if esc key is clicked
54117    $(document).on('keydown', function (e) {
54118      if (e.keyCode === 27) { // ESC
54119        $("#js-popup").fadeOut();
54120        $('body').removeClass('u-overflow-hidden');
54121      }
54122    });
54123  });
54124  // END POPUP
54125  // Survey popup hide show functionality
54126  $(document).ready(function () {
54127    var cookieID = $('#js-popup-information').data('cookieId');
54128    if (sessionStorage.getItem(cookieID) != 'shown' || cookieID == 'dev') {
54129      $('#js-popup-information').fadeIn();
54130    }
54131
54132    $('.js-info').click(function (e) {
54133      sessionStorage.setItem(cookieID, 'shown');
54134      $("#js-popup-information").fadeOut();
54135    });
54136  });
54137
54138  function initForms() {
54139    $("#hostels").each(function () {
54140      var $select = $(this);
54141      var $groups = $select.find("optgroup");
54142      $groups.remove();
54143      $groups = $groups.sort(function (g1, g2) {
54144        return g1.label.localeCompare(g2.label);
54145      });
54146      $select.append($groups);
54147      $groups.each(function () {
54148        var $group = $(this);
54149        var options = $group.find("option");
54150        options.remove();
54151        options = options.sort(function (a, b) {
54152          return a.innerHTML.localeCompare(b.innerHTML);
54153        });
54154        $group.append(options);
54155      });
54156    });
54157
54158    $('select').each(function () {
54159      if (!Modernizr.mq('(max-width: 1024px)')) {
54160        $(this).select2({
54161          minimumResultsForSearch: 15
54162        });
54163      } else {
54164        var placeholder = $(this).data("placeholder");
54165        if (placeholder) {
54166          $(this).find("option").first().text(placeholder).attr("disabled", "disabled");
54167        }
54168      }
54169    });
54170
54171
54172
54173    $('#hostels').select2({
54174      minimumResultsForSearch: 0,
54175      matcher: matchGroup,
54176      sorter: function (data) {
54177        /* Sort data using lowercase comparison */
54178        return data.sort(function (a, b) {
54179          a = a.text.toLowerCase();
54180          b = b.text.toLowerCase();
54181          if (a > b) {
54182            return 1;
54183          } else if (a < b) {
54184            return -1;
54185          }
54186          return 0;
54187        });
54188      }
54189    });
54190
54191    $.when(
54192      $('#hostels').select2({
54193        allowClear: true
54194      })).done(function () {
54195        $('#hibooking-widget').addClass('is-ready');
54196      });
54197
54198    function matchGroup(params, data) {
54199      // If there are no search terms, return all of the data
54200      if ($.trim(params.term) === '') {
54201        return data;
54202      }
54203
54204      // Skip if there is no 'children' property
54205      if (typeof data.children === 'undefined') {
54206        return null;
54207      }
54208
54209      // `data.children` contains the actual options that we are matching against
54210      var filteredChildren = [];
54211      var regex = new RegExp(params.term.toLowerCase());
54212
54213      //check the optgropu
54214      if (regex.exec(data.text.toLowerCase())) {
54215        filteredChildren = data.children;
54216      }
54217      else {
54218        $.each(data.children, function (idx, child) {
54219          if (regex.exec(child.text.toLowerCase())) {
54220            filteredChildren.push(child);
54221          }
54222        });
54223      }
54224
54225
54226      // If we matched any of the timezone group's children, then set the matched children on the group
54227      // and return the group object
54228      if (filteredChildren.length) {
54229        var modifiedData = $.extend({}, data, true);
54230        modifiedData.children = filteredChildren;
54231
54232        // You can return modified objects from here
54233        // This includes matching the `children` how you want in nested data sets
54234        return modifiedData;
54235      }
54236
54237      // Return `null` if the term should not be displayed
54238      return null;
54239    }
54240
54241    //
54242    // BOOKING WIDGET
54243    //
54244
54245    $('#scroll-top, .js-scroll-to-top').click(function (e) {
54246      e.preventDefault();
54247      $("html, body").animate({ scrollTop: 0 }, "slow");
54248
54249      if ($('#current-hostel').length) {
54250        $('._dates .flatpickr--booking.form-text.flatpickr-input.form-control.input').focus();
54251      } else {
54252        $("#hostels").focus();
54253      }
54254
54255      return false;
54256    });
54257
54258
54259    //
54260    // This bit of code is causing multiple select2 elements to open and close on click/focus
54261    //
54262
54263    // OPEN SELECT2 ON FOCUS
54264    // $(document).on('focus', '.select2.select2-container', function (e) {
54265    //   var isOriginalEvent = e.originalEvent // don't re-open on closing focus event
54266    //   var isSingleSelect = $(this).find(".select2-selection--single").length > 0
54267    //   if (isOriginalEvent && isSingleSelect) {
54268    //     $(this).siblings('select:enabled').select2('open');
54269    //   }
54270    // });
54271
54272
54273    $('#hostels').on('select2:select', function (e) {
54274      var selectedID = (e).params.data.id;
54275      if (selectedID != '') {
54276        $(".hibooking-widget").addClass("active");
54277        buildBookingAction();
54278      } else {
54279        $(".hibooking-widget").removeClass("active is-enabled");
54280      }
54281    });
54282
54283    // Called onChange for #hostels, #qty and .flatpickr--booking
54284    function buildBookingAction() {
54285      if ($("#hibooking-widget.hibooking-widget--single").length) {
54286        var $selectedHostel = $('#current-hostel');
54287      } else {
54288        var $selectedHostel = $('#hostels').find(':selected');
54289      }
54290
54291      var bookingEngine = $selectedHostel.data('bookingEngine'),
54292        defaultStay = $selectedHostel.data('defaultStay'),
54293        roommasterUrl = $selectedHostel.data('roommasterUrl'),
54294        wrpID = $selectedHostel.data('wrpId'),
54295        rcID = $selectedHostel.data('rcId'),
54296        sirvoyID = $selectedHostel.data('sirvoyId'),
54297        siteminderSlug = $selectedHostel.data('siteminderSlug'),
54298        boomworksSlug = $selectedHostel.data('boomworksSlug'),
54299        frontdeskSlug = $selectedHostel.data('frontdeskSlug'),
54300        cloudbedsUrl = $selectedHostel.data('cloudbedsUrl'),
54301        alpineid = $selectedHostel.data('alpineId'),
54302        dateSplit = $('html:lang(en)').length > 0 ? ' to ' : ' au ',
54303        $dates = $('.flatpickr--booking').val().split(dateSplit),
54304        qty = $('#qty').val(),
54305        $messagesContainer = $(".hibooking-widget .messages-container"),
54306        siteLang = $('html')[0].lang,
54307        today = new Date(),
54308        membershiptoken = $selectedHostel.data('membershiptoken'),
54309        environment = $selectedHostel.data('environment');
54310
54311      if (qty >= 10) {
54312        $messagesContainer.addClass("is-group-notification");
54313      } else {
54314        $messagesContainer.removeClass("is-group-notification");
54315      }
54316
54317      $bookingDatePicker.config.defaultDate = [today];
54318
54319      // IF checkin and checkout date have been selected build the action
54320      if ($dates.length == 2) {
54321        var checkInDate = moment($dates[0]),
54322          checkOutDate = moment($dates[1]),
54323          numberOfNights = checkInDate.diff(checkOutDate, 'days') * -1,
54324          bookingLang = (siteLang == "en") ? 'english' : 'french',
54325          boomworksLang = (siteLang == "en") ? 'en-US' : 'fr-CA',
54326          actionUrl = null;
54327
54328        switch (bookingEngine) {
54329
54330          case 'alpineclubofcanada':
54331            actionUrl = 'https://alpine-club-of-canada.checkfront.com/reserve/?category_id=' + alpineid + '&date=' + checkInDate.format('YYYY-MM-DD');
54332            break;
54333
54334          case 'boomworks':
54335            var hostUrl = environment === 'production' ? 'https://book.hihostels.ca' : 'https://bookings-test.hihostels.ca';
54336            actionUrl = hostUrl + '/booking-steps.html?hostelcode=' + boomworksSlug + '&startDate=' + checkInDate.format('YYYY-MM-DD') + '&endDate=' + checkOutDate.format('YYYY-MM-DD') + '&lang=' + boomworksLang;
54337            if (membershiptoken) {
54338              actionUrl = new URL(actionUrl);
54339              actionUrl.searchParams.set('membershiptoken', membershiptoken);
54340              actionUrl = actionUrl.toString();
54341            }
54342            break;
54343
54344          case 'cloudbeds':
54345            actionUrl = cloudbedsUrl + '#checkin=' + checkInDate.format('YYYY-MM-DD') + '&checkout=' + checkOutDate.format('YYYY-MM-DD')
54346            break;
54347
54348          case 'frontdeskcounter':
54349            actionUrl = 'https://frontdesk.counter.app/booking/' + frontdeskSlug;
54350            break;
54351
54352          case 'roommaster':
54353            actionUrl = 'https://us01.iqwebbook.com/' + roommasterUrl + '/~/';
54354            break;
54355
54356          case 'sirvoy':
54357            actionUrl = 'https://' + sirvoyID + '.sirvoy.me/?adults=' + qty + '&check_in=' + checkInDate.format('YYYY-MM-DD') + '&check_out=' + checkOutDate.format('YYYY-MM-DD');
54358            break;
54359
54360          case 'siteminder':
54361            actionUrl = 'https://app.thebookingbutton.com/properties/' + siteminderSlug + '?utf8=%E2%9C%93&locale=' + siteLang + '&from_widget=true&check_in_date=' + checkInDate.format('YYYY-MM-DD') + '&check_out_date=' + checkOutDate.format('YYYY-MM-DD') + '&number_adults=' + qty + '&number_children=0&commit=%EF%84%B8%2BCheck%2BAvailability';
54362            break;
54363
54364          case 'webrezpro':
54365            actionUrl = 'https://secure.webrez.com/hotel/' + wrpID + '?language=' + bookingLang + '&date_from=' + checkInDate.format('YYYYMMDD') + '&date_to=' + checkOutDate.format('YYYYMMDD') + '&num_adults=' + qty + '&num_nights=' + numberOfNights + '&rc_id=' + rcID;
54366            break;
54367
54368          default:
54369            return null;
54370        }
54371
54372
54373        if (actionUrl) {
54374          $("form#hibooking").attr('action', actionUrl);
54375          $("#hibooking-submit").prop('disabled', false);
54376          $(".hibooking-widget").addClass("is-enabled");
54377        }
54378
54379      } else {
54380        // dates not selected exit
54381        $(".hibooking-widget").removeClass("is-enabled");
54382        return null;
54383      }
54384    }
54385
54386    flatpickr(".flatpickr", {
54387      "mode": "range",
54388      inline: true,
54389      minDate: "today",
54390      "locale": $("html").attr("lang")
54391    });
54392
54393    const $bookingDatePicker = $(".flatpickr--booking").flatpickr({
54394      "mode": "range",
54395      inline: false,
54396      appendTo: window.document.querySelector('.date-container'),
54397      static: true,
54398      minDate: "today",
54399      altInput: true,
54400      altFormat: "m/d/y",
54401      "locale": $("html").attr("lang"),
54402      onChange: [function (selectedDates) {
54403        buildBookingAction();
54404      }]
54405    });
54406
54407    var addInput = $("#qty");
54408    var n = 1;
54409    $(addInput).val(n);
54410
54411    $('#guestup_btn').click(function (e) {
54412      $(addInput).val(++n);
54413      buildBookingAction();
54414    });
54415
54416    $('#guestsdown_btn').click(function (e) {
54417      //If n is bigger or equal to 1 subtract 1 from n
54418      if (n >= 1) {
54419        $(addInput).val(--n);
54420        buildBookingAction();
54421      } else {
54422        //Otherwise do nothing
54423      }
54424    });
54425
54426    // END BOOKING WIDGET
54427
54428
54429    var $groupsForm = $('#groups-form');
54430
54431    if ($groupsForm.length > 0) {
54432      var $selectProvince = $groupsForm.find('select[name="provinceId"]');
54433      var $selectHostel = $groupsForm.find('select[name="hostelId"]');
54434      var hostelId = getQueryVariable("hostelId");
54435      var provinceId = getQueryVariable("provinceId");
54436      var hostelsData = [];
54437      $.each($selectHostel.find('option'), function (i, el) {
54438        hostelsData.push({ id: $(el).attr("value"), text: $(el).text(), province: $(el).data("province") });
54439      });
54440      $selectProvince.change(function () {
54441        var val = $(this).val();
54442        var data = _.filter(hostelsData, function (item) {
54443          return item.province == val;
54444        });
54445        var hostelVal = $selectHostel.val();
54446        if (!Modernizr.mq('(max-width: 1024px)')) {
54447          $selectHostel.select2().empty();
54448          $selectHostel.select2({
54449            data: [{ id: "", text: "" }].concat(data),
54450            minimumResultsForSearch: 15
54451          })
54452        } else {
54453          $selectHostel.html("");
54454          $('<option value="" disabled="disabled" selected="selected">' + $selectHostel.data("placeholder") + '</option>').appendTo($selectHostel);
54455          _.each(data, function (item) {
54456            $('<option value="' + item.id + '">' + item.text + '</option>').appendTo($selectHostel);
54457          });
54458        }
54459        if (hostelVal != "" && $selectHostel.find("option[value='" + hostelVal + "']").length > 0) {
54460          $selectHostel.val(hostelVal).trigger("change");
54461        }
54462        if (hostelId != false) {
54463          $selectHostel.val(hostelId).trigger("change");
54464          $groupsForm.find(".show-step-2").trigger("click");
54465        }
54466      });
54467
54468      $selectHostel.change(function () {
54469        var val = $(this).val();
54470        $groupsForm.find(".show-step-2").hide();
54471        $groupsForm.find(".show-step-2-none").hide();
54472        $groupsForm.find(".button_-" + $selectHostel.val()).show();
54473      });
54474
54475      if (hostelId != false && provinceId != false) {
54476        $selectProvince.val(provinceId).trigger("change");
54477      }
54478
54479      $groupsForm.find(".show-step-2").click(function () {
54480        if ($selectProvince.val() == null || $selectHostel.val() == null || $selectProvince.val() == "" || $selectHostel.val() == "") return false;
54481        $groupsForm.find("#step-2").show();
54482        $groupsForm.find('.groups-hostel').hide();
54483        $groupsForm.find('#hostel-' + $selectHostel.val()).show();
54484        return false;
54485      });
54486
54487      $groupsForm.find("._destination select").change(function () {
54488        if ($selectProvince.val() == null || $selectHostel.val() == null || $selectProvince.val() == "" || $selectHostel.val() == "") {
54489          $groupsForm.find(".show-step-2").addClass("disabled").click(function () {
54490            $('html,body').stop();
54491          });
54492          $groupsForm.find(".show-step-2-none").addClass("disabled").click(function () {
54493            $('html,body').stop();
54494          });
54495        }
54496        else {
54497          $groupsForm.find(".show-step-2-none").removeClass("disabled");
54498          $groupsForm.find(".show-step-2").removeClass("disabled").click(function () {
54499            $("html, body").animate({
54500              scrollTop: $groupsForm.find("._destination").offset().top + 80
54501            }, 600);
54502          });
54503        }
54504        if (hostelId != false) {
54505          hostelId = "";
54506          provinceId = "";
54507          $groupsForm.find(".button_-" + $selectHostel.val()).click();
54508        }
54509      }).first().trigger("change");
54510
54511      var $inputDate = $groupsForm.find('input[name="date"]');
54512      var calculateDate = function () {
54513        var val = $inputDate.val();
54514        var dateRegexp = /([0-9]+\-[0-9]+\-[0-9]+)/g;
54515        var matches;
54516        var dates = [];
54517        while (matches = dateRegexp.exec(val)) {
54518          dates.push(moment(matches[1]));
54519        }
54520        if (dates.length > 1) {
54521          var date1 = dates[0];
54522          var date2 = dates[1];
54523          var dateFormat = 'YYYY-MM-DD';
54524          $groupsForm.find('input[name="checkIn"]').val(date1.format(dateFormat));
54525          $groupsForm.find('input[name="checkOut"]').val(date2.format(dateFormat));
54526          $groupsForm.find("input[name='nbNights']").val(Math.round(moment.duration(date2.diff(date1)).asDays())).trigger("change");
54527        }
54528      };
54529      $inputDate.change(function () {
54530        calculateDate();
54531      });
54532      calculateDate();
54533
54534      var $womenTotal = $groupsForm.find("input[name='womenTotal']");
54535      var $menTotal = $groupsForm.find("input[name='menTotal']");
54536      var $peopleTotal = $groupsForm.find('input[name="peopleTotal"]');
54537      var calculatePeopleTotal = function () {
54538        if ($womenTotal.val() != "" && $menTotal.val() != "") {
54539          $peopleTotal.closest('.disabled-input').addClass('active');
54540          $peopleTotal.val(parseInt($womenTotal.val()) + parseInt($menTotal.val()));
54541        }
54542      };
54543      $groupsForm.find("input[name='womenTotal'], input[name='menTotal']").bind("change keyup", function () {
54544        calculatePeopleTotal();
54545      });
54546      calculatePeopleTotal();
54547
54548      if ($('._errors-list').length > 0) {
54549        $("html, body").animate({
54550          scrollTop: $('._errors-list').offset().top - $('.header').height() - 20
54551        }, 1);
54552      } else if ($('.error').length > 0) {
54553        $("html, body").animate({
54554          scrollTop: $('.error').first().offset().top - $('.header').height() - 20
54555        }, 1);
54556      }
54557
54558      $groupsForm.submit(function () {
54559        if ($groupsForm.find(".error").length > 0) {
54560          var $firstInput = $groupsForm.find(".error").first().find("input, select");
54561          $firstInput.focus();
54562          $('html, body').animate({
54563            scrollTop: $firstInput.offset().top - $('.header').height() - 20
54564          }, 0);
54565
54566          return false;
54567        }
54568      });
54569    }
54570
54571    $('.textbox').each(function () {
54572      var $this = $(this);
54573      var $input = $(this).find("input");
54574      var cssClass = "active";
54575      if ($input.val() != "") {
54576        $this.addClass(cssClass);
54577      }
54578      $input.bind("change keyup", function () {
54579        $this.removeClass("error");
54580        if ($input.val() == "") {
54581          $this.removeClass(cssClass);
54582        }
54583        else {
54584          $this.addClass(cssClass);
54585        }
54586      });
54587
54588      $input.blur(function () {
54589        if ($input.prop('required') && $input.val() == "") {
54590          $this.addClass("error");
54591        }
54592        else if ($input.attr("name") == "phone" && !validatePhone($input.val())) {
54593          $this.addClass("error");
54594        }
54595        else if ($input.attr("type") == "email" && !validateEmail($input.val())) {
54596          $this.addClass("error");
54597        }
54598        else {
54599          $this.removeClass("error");
54600        }
54601      });
54602    });
54603
54604    $('.checkbox, .dropdown').each(function () {
54605      var $this = $(this);
54606      var $input = $(this).find("input, select");
54607      $input.bind("change", function () {
54608        $this.removeClass("error");
54609      });
54610      $input.blur(function () {
54611        if ($input.prop('required') && $input.val() == "") {
54612          $this.addClass("error");
54613        }
54614        else {
54615          $this.removeClass("error");
54616        }
54617      });
54618    });
54619
54620    $('form').submit(function () {
54621      var $form = $(this);
54622      var $unchecked = $form.find("input[type='checkbox'][required]:not(:checked)");
54623      if ($unchecked.length > 0) {
54624        $unchecked.parent().addClass("error");
54625        return false;
54626      }
54627    });
54628
54629    $('#countries select').change(function () {
54630      $('.regions').hide();
54631      if ($(this).val() == "US") {
54632        $('#states').show();
54633      } else if ($(this).val() == "CA") {
54634        $('#provinces').show();
54635      }
54636    }).trigger("change");
54637  }
54638
54639  function initBuyInPerson() {
54640    $('#radioProvince').click(function () {
54641      $("#radioProvinceInput").prop("checked", true);
54642      $("#radioPostalInput").prop("checked", false);
54643
54644      $('#textPostalCode').css({
54645        "display": "none"
54646      });
54647      $('._sub-2 ._dropdowns').css({
54648        "display": "flex"
54649      });
54650    });
54651
54652    $('#radioPostalCode').click(function () {
54653      $("#radioPostalInput").prop("checked", true);
54654      $("#radioProvinceInput").prop("checked", false);
54655
54656      $('._sub-2 ._dropdowns').css({
54657        "display": "none"
54658      });
54659      $('#textPostalCode').css({
54660        "display": "block"
54661      });
54662    });
54663  }
54664
54665  function initAjaxEntries() {
54666    $('.ajax-nav').find("a").first().addClass("current");
54667
54668    $('.ajax-nav').each(function () {
54669      var $this = $(this);
54670      $this.find("a").click(function (event) {
54671        var val = $(this).attr("href").substring(1).split(":");
54672        if (val[1] != null) {
54673          var $target = $('.ajax-entries').first();
54674          var targetOffsetTop = $target.offset().top;
54675          var topSpacing = getTopSpacing(targetOffsetTop);
54676          $('html, body').animate({ scrollTop: targetOffsetTop - topSpacing - 40 }, 600);
54677
54678
54679          $('select[name="' + val[0] + '"]').val(val[1]).trigger("change");
54680
54681          event.stopImmediatePropagation();
54682          return false;
54683        } else {
54684          var $target = $($(this).attr("href"));
54685          if ($target.length > 0) {
54686            var targetOffsetTop = $target.offset().top;
54687            var topSpacing = getTopSpacing(targetOffsetTop);
54688            $('html, body').animate({ scrollTop: targetOffsetTop - topSpacing }, 600);
54689            return false;
54690          }
54691        }
54692      });
54693    });
54694
54695    $('.ajax-entries').each(function () {
54696      var $this = $(this);
54697      var $filters = $this.find(".filters");
54698      var $grid = $this.find(".entries");
54699      var $totalItems = $this.find(".total-items");
54700      var $totalPlurial = $this.find(".total-plurial");
54701      var $totalSingular = $this.find(".total-singular");
54702
54703      var loading = false;
54704      var currentPage = parseInt($this.find("input[name='currentPage']").val());
54705      var totalPages = parseInt($this.find("input[name='totalPages']").val());
54706      var totalItems = parseInt($this.find("input[name='totalItems']").val());
54707
54708      var entryUrl = $this.find("input[name='entryUrl']").val();
54709
54710      var getParams = function () {
54711        var data = {};
54712        $filters.find('select').each(function () {
54713          data[$(this).attr("name")] = $(this).val();
54714        });
54715        return data;
54716      };
54717
54718      var updateElements = function () {
54719        $totalItems.text(totalItems);
54720        if (totalItems > 1) {
54721          $totalPlurial.show();
54722          $totalSingular.hide();
54723        } else {
54724          $totalPlurial.hide();
54725          $totalSingular.show();
54726        }
54727      };
54728
54729      var $loader = $grid.siblings("._loading");
54730      var loadResults = function () {
54731        if (loading) return;
54732
54733        loading = true;
54734        $loader.fadeIn(750);
54735        $grid.fadeOut(150);
54736
54737        $.get(entryUrl + "/p" + currentPage, getParams(), function (result) {
54738          loading = false;
54739          $loader.hide();
54740          $grid.fadeIn(750);
54741
54742          totalItems = result.totalItems;
54743          totalPages = result.totalPages;
54744          updateElements();
54745
54746          var $oldElements = $grid.find(">*:not(.grid-sizer)");
54747          var $newElements = $($('<div />').html(result.html).text());
54748          if ($grid.hasClass("masonry")) {
54749            $grid.masonry('remove', $oldElements).append($newElements).masonry('appended', $newElements).masonry();
54750            $grid.find('img').each(function () {
54751              $(this).on("load", function () {
54752                $grid.masonry('layout');
54753              });
54754            });
54755          }
54756          else {
54757            $oldElements.remove();
54758            $grid.append($newElements);
54759          }
54760          beginTilesTransition();
54761          bLazy.revalidate();
54762
54763          $this.find(".paging").after($($('<div />').html(result.pagingHtml).text())).remove();
54764        });
54765      };
54766
54767      $filters.find('select').change(function () {
54768        loadResults();
54769        $('.ajax-nav').find("a").removeClass("current");
54770        if ($(this).val() == "" || $(this).val() == null) {
54771          $('.ajax-nav').find("a").first().addClass("current");
54772        } else {
54773          $('.ajax-nav').find("a[href='#" + $(this).attr("name") + ":" + $(this).val() + "']").addClass("current");
54774        }
54775      });
54776
54777      var $selectProvince = $filters.find('select[name="province"]');
54778      var $selectHostel = $filters.find('select[name="hostel"]');
54779      var hostelsData = [];
54780      $.each($selectHostel.find('option'), function (i, el) {
54781        hostelsData.push({ id: $(el).attr("value"), text: $(el).text(), province: $(el).data("province") });
54782      });
54783      $selectProvince.change(function () {
54784        var val = $(this).val();
54785        var data = _.filter(hostelsData, function (item) {
54786          return item.province == val;
54787        });
54788        if (!Modernizr.mq('(max-width: 1024px)')) {
54789          $selectHostel.select2().empty();
54790          $selectHostel.select2({
54791            data: [{ id: "", text: "" }].concat(data),
54792            minimumResultsForSearch: 15
54793          })
54794        } else {
54795          $selectHostel.html("");
54796          $('<option value="" disabled="disabled" selected="selected">' + $selectHostel.data("placeholder") + '</option>').appendTo($selectHostel);
54797          _.each(data, function (item) {
54798            $('<option value="' + item.id + '">' + item.text + '</option>').appendTo($selectHostel);
54799          });
54800        }
54801      });
54802
54803      $filters.find('.reset-filters').click(function () {
54804        $filters.find('select').val("").trigger('change');
54805        return false;
54806      });
54807
54808      $this.on("click", ".paging [data-page]", function () {
54809        currentPage = $(this).data("page");
54810        loadResults();
54811        return false;
54812      });
54813
54814      $this.on("click", ".paging [data-previous]", function () {
54815        currentPage = currentPage - 1;
54816        loadResults();
54817        return false;
54818      });
54819
54820      $this.on("click", ".paging [data-first]", function () {
54821        currentPage = 1;
54822        loadResults();
54823        return false;
54824      });
54825
54826      $this.on("click", ".paging [data-next]", function () {
54827        currentPage = currentPage + 1;
54828        loadResults();
54829        return false;
54830      });
54831
54832      $this.on("click", ".paging [data-last]", function () {
54833        currentPage = totalPages;
54834        loadResults();
54835        return false;
54836      });
54837    });
54838  }
54839
54840  function hideSubMenu($element) {
54841    var transitionEndEvent = "webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend";
54842    $element.removeClass("open").bind(transitionEndEvent, function () {
54843      $element.unbind(transitionEndEvent);
54844      $element.removeClass("from-top from-left from-right to-top to-left to-right open-content");
54845    });
54846  }
54847
54848  function initSubMenu() {
54849    $('._main-nav >ul >li.-has-subnav >a').click(function () {
54850      var $subNav = $(".sub-nav").first();
54851      var $submit = $('.search > ._container > ._form button');
54852      $('.search-btn').removeClass("active-search");
54853      if ($subNav.length > 0) {
54854        $('.header-booking-wrapper .general-booking').fadeOut(250);
54855        $('.search').removeClass("open");
54856        $(this).parent().toggleClass("-active");
54857        hideSubMenu($(".sub-nav.open").not($subNav));
54858
54859        if ($(this).parent().hasClass("-active")) {
54860          $('body').addClass('disable-scroll');
54861          $subNav.removeClass("to-top").addClass("open from-top");
54862          setTimeout(function () {
54863            $subNav.addClass("open-content");
54864          }, 100);
54865          $('body').addClass('disable-scroll');
54866        } else {
54867          hideSubMenu($subNav);
54868          $('body').removeClass('disable-scroll');
54869        }
54870        return false;
54871      }
54872    });
54873
54874    $('.toggle-province').click(function () {
54875      $(this).closest(".sub-nav").removeClass("from-top from-right from-left open-content").addClass("to-left");
54876
54877      var $currentMenu = $($(this).attr("href"));
54878      $currentMenu.removeClass("from-top to-right to-top").addClass("open from-right");
54879      setTimeout(function () {
54880        $currentMenu.addClass("open-content");
54881      }, 100);
54882
54883      $currentMenu.find("._explore").css("background-image", 'url(' + $currentMenu.find("._explore").data("src") + ')');
54884
54885      return false;
54886    });
54887
54888    $('.toggle-all-hostels').click(function () {
54889      $(this).closest(".sub-nav").removeClass("from-top from-right from-left open-content").addClass("to-left");
54890
54891      var $allHostels = $('#app .all-hostels');
54892      $allHostels.removeClass("from-top to-right to-top").addClass("open from-right");
54893
54894      var $currentMenu = $($(this).attr("href"));
54895      $currentMenu.removeClass("from-top to-right to-top").addClass("open from-right");
54896      setTimeout(function () {
54897        $allHostels.addClass("open-content");
54898        $currentMenu.addClass("open-content");
54899      }, 100);
54900
54901      return false;
54902    });
54903
54904    $('.toggle-main-nav').click(function () {
54905      var $closestNav = $(this).closest(".sub-nav");
54906      $closestNav.removeClass("open open-content from-right to-top").addClass("to-right");
54907      $closestNav.siblings(".sub-nav").first().addClass("open-content from-left").removeClass("to-left");
54908      return false;
54909    });
54910
54911    var $destinationNav = $('#destination-nav, .destination-province, .all-hostels');
54912    var $destinationBtnClose = $('<div class="destination-btn-close"></div>').appendTo($destinationNav);
54913    $('.destination-btn-close').click(function () {
54914      $('body').removeClass('disable-scroll')
54915      hideSubMenu($(".sub-nav.open"));
54916      $('._main-nav >ul >li.-has-subnav').removeClass("-active");
54917      return false;
54918    });
54919
54920    var $content = $('#content');
54921    $content.click(function () {
54922      hideSubMenu($(".sub-nav.open"));
54923      $('._main-nav >ul >li.-has-subnav').removeClass("-active");
54924      $('body').removeClass('disable-scroll');
54925    });
54926  }
54927
54928  function initSearch() {
54929    var $search = $('.search');
54930    var $searchResultsList = $('.search ._results ._list');
54931    var $searchInput = $search.find("input[type='search']");
54932    var $searchResults = $search.find('._results');
54933    var $searchLoader = $search.find("._loading");
54934    var $submit = $('.search > ._container > ._form button');
54935    var $clear = $('.search > ._container > ._form div');
54936    var $currentPageFirstNav = $('.-is-in-path');
54937    var $currentPageSecondNav = $('.-is-current');
54938    if ($('.page-search').length) {
54939      $('.search-btn').toggleClass("active-search");
54940      $submit.hide();
54941      $clear.show();
54942      $clear.click(function () {
54943        $searchInput.val("");
54944        $clear.hide();
54945      });
54946    }
54947    $('.search-btn').click(function () {
54948      $('.header-booking-wrapper .general-booking').fadeOut(250);
54949      hideSubMenu($(".sub-nav.open"));
54950      $('._main-nav >ul >li.-has-subnav').removeClass("-active");
54951      $currentPageFirstNav.removeClass('-is-in-path -is-top-parent');
54952      $currentPageSecondNav.toggleClass('-is-current');
54953      $('.search-btn').toggleClass("active-search");
54954      $search.toggleClass("open");
54955      if ($search.hasClass("open")) {
54956        $(document).bind('touchmove', function (e) {
54957          e.preventDefault();
54958        });
54959        $searchInput.focus();
54960        if ($searchInput.val() != "" && !$('.page-search').length) {
54961          $('body').addClass('disable-scroll');
54962        }
54963        else {
54964
54965          $('body').removeClass('disable-scroll');
54966        }
54967      }
54968      else {
54969        $currentPageFirstNav.addClass('-is-in-path -is-top-parent');
54970        $(document).unbind('touchmove');
54971        $('body').removeClass('disable-scroll');
54972      }
54973
54974      return false;
54975    });
54976
54977    var $searchBtnClose = $('<div class="search-btn-close"></div>').appendTo($search);
54978    $('.search-btn-close').click(function () {
54979      if ($search.hasClass("open")) {
54980        $search.removeClass("open")
54981      }
54982      $(document).unbind('touchmove');
54983      $currentPageFirstNav.addClass('-is-in-path -is-top-parent');
54984      $currentPageSecondNav.toggleClass('-is-current');
54985      $('.search-btn').toggleClass("active-search");
54986      $('body').removeClass('disable-scroll');
54987
54988      return false;
54989    });
54990
54991    if ($(window).width() <= 680) {
54992      $searchResultsList.removeClass('custom-scrollbar');
54993    }
54994
54995    var xhr;
54996    var timeout;
54997    var inputVal = "";
54998    $searchInput.bind("change keyup", function () {
54999      if (timeout) {
55000        clearTimeout(timeout);
55001      }
55002      timeout = setTimeout(function () {
55003        if (inputVal == $searchInput.val() && $searchResults.is(":visible")) return;
55004        if (xhr) {
55005          xhr.abort();
55006        }
55007        $searchResults.hide();
55008        $('.search.open').removeClass('results-open');
55009
55010        $('body').removeClass('disable-scroll');
55011        $clear.fadeOut(150);
55012
55013        if ($searchInput.val() == "") {
55014          $submit.fadeOut(150);
55015          return;
55016        } else {
55017          $submit.fadeIn(250);
55018        }
55019
55020        $searchLoader.show();
55021
55022        xhr = $.get("/" + $("html").attr("lang") + "/search.json?search=" + $searchInput.val(), function (result) {
55023          inputVal = $searchInput.val();
55024          $searchLoader.hide();
55025
55026          if (result.data.length < 1) {
55027            return;
55028          }
55029
55030          $searchResults.show();
55031          $('.search.open').addClass('results-open');
55032
55033          if (!$('.page-search').length) {
55034            $('body').addClass('disable-scroll');
55035          }
55036          var groups = _.groupBy(result.data, function (item) {
55037            return item["section"];
55038          });
55039          var hostels = groups["hostels"];
55040
55041          var orderProvinces = $('.js-provinces-list-order').data("provinces");
55042
55043          var ordered = _.sortBy(groups["hostels"], function (item) {
55044            return orderProvinces.indexOf(item.province)
55045          });
55046          var hostelsByDestinations = _.groupBy(ordered, function (item) {
55047            return item["province"];
55048          });
55049          // var discounts = groups["discountsOffers"];
55050          var articles = groups["articles"];
55051          var packages = groups["packages"];
55052          var secondaryPages = groups["secondaryPages"];
55053
55054          $search.find(".search-destinations-nb").text(hostelsByDestinations != undefined ? Object.keys(hostelsByDestinations).length : 0);
55055          $search.find(".search-hostels-nb").text(hostels != undefined ? Object.keys(hostels).length : 0);
55056          // $search.find(".search-discounts-nb").text(discounts != undefined ? Object.keys(discounts).length : 0);
55057          $search.find(".search-articles-nb").text(articles != undefined ? Object.keys(articles).length : 0);
55058          $search.find(".search-packages-nb").text(packages != undefined ? Object.keys(packages).length : 0);
55059          $search.find(".search-pages-nb").text(secondaryPages != undefined ? Object.keys(secondaryPages).length : 0);
55060
55061          var itemLi = function (item) {
55062            return "<li><a href='" + item["url"] + "'>" + item["title"] + "</a></li>";
55063
55064            // return "<li> <span>"+item["province"]+"</span><a href='" + item["url"] + "'>" + item["title"] + "</a></li>";
55065          };
55066
55067          var $hostelsResults = $searchResults.find(".search-hostels-results").html("");
55068          _.each(hostelsByDestinations, function (item, key, list) {
55069            var hostelsHtml = "";
55070            _.each(item, function (hostel) {
55071              hostelsHtml += itemLi(hostel);
55072            });
55073            $hostelsResults.append(
55074              $('<li><span>' + key + '</span><ul>' + hostelsHtml + '</ul></li>')
55075
55076              //$('<ul>' + hostelsHtml + '</ul>')
55077            );
55078          });
55079
55080          // var $discountsResults = $searchResults.find(".search-discounts-results").html("");
55081          //  _.each(discounts, function(item, key, list) {
55082          //   $discountsResults.append($(itemLi(item)));
55083          // });
55084
55085          var $articlesResults = $searchResults.find(".search-articles-results").html("");
55086          _.each(articles, function (item, key, list) {
55087            $articlesResults.append($(itemLi(item)));
55088          });
55089
55090          var $packagesResults = $searchResults.find(".search-packages-results").html("");
55091          _.each(packages, function (item, key, list) {
55092            $packagesResults.append($(itemLi(item)));
55093          });
55094
55095          var $pagesResults = $searchResults.find(".search-pages-results").html("");
55096          _.each(secondaryPages, function (item, key, list) {
55097            $pagesResults.append($(itemLi(item)));
55098          });
55099        });
55100      }, 200);
55101    });
55102  }
55103
55104  function initHome() {
55105    $('.home-all-hostels').click(function () {
55106      showSubNav($('.all-hostels'));
55107      return false;
55108    });
55109  }
55110
55111  function initDiscoverPage() {
55112    $('.show-first-province').click((e) => {
55113      e.preventDefault();
55114      var $slider = $(e.currentTarget).closest(".slider");
55115      if ($slider.hasClass("slick-initialized")) {
55116        $slider.slick('slickGoTo', 1);
55117      }
55118    });
55119
55120    $('.show-all-hostels').click((e) => {
55121      showSubNav($('.all-hostels'));
55122      return false;
55123    });
55124
55125    $('.show-province').click((e) => {
55126      showSubNav($("#" + $(e.currentTarget).data("province")));
55127      return false;
55128    });
55129
55130    $(window).scroll((e) => {
55131      var $nextToShow = null;
55132      $(".province").each(function () {
55133        var offsetTop = $(this).offset().top;
55134        var scrollTop = $(window).scrollTop();
55135        if ((offsetTop + 120) < scrollTop &&
55136          (offsetTop + $(this).height()) > (scrollTop + $(window).height())) {
55137          $nextToShow = $(this).find('.next-province-mobile').fadeIn();
55138        }
55139      });
55140      $('.next-province-mobile').not($nextToShow).fadeOut();
55141    });
55142    $('.next-province-mobile').hide();
55143
55144    $('.next-province-mobile').click((e) => {
55145      $("html, body").animate({
55146        scrollTop: $(e.currentTarget).closest(".province").next().offset().top - $(".header").height()
55147      }, 400);
55148      return false;
55149    });
55150  }
55151
55152  function showSubNav($nav) {
55153    var $search = $('.search');
55154
55155    $nav.addClass('open open-content');
55156    $('body').addClass('disable-scroll');
55157    hideSubMenu($("#app .sub-nav.open").not($nav).first());
55158
55159    $('._main-nav >ul >li.-has-subnav').removeClass("-active");
55160    $('.search-btn').removeClass("active-search");
55161
55162    if ($nav.find("._explore").length > 0) {
55163      $nav.find("._explore").css("background-image", 'url(' + $nav.find("._explore").data("src") + ')')
55164    }
55165
55166    if ($search.hasClass("open")) {
55167      $search.removeClass("open");
55168    }
55169  }
55170
55171  function initLightbox() {
55172    var $footerNewsletterForm = $("#footer-newsletter-form");
55173    var $magazineSubscribe = $('.page-magazine #content').find('a[href="Magazine"], a[href="/en/magazine"], a[href="/fr/magazine"]');
55174    var $careerApplyForm = $(".page-jobs .jobs .content-block .button");
55175    var $lightbox = $('#newsletter-lightbox');
55176    var $lightboxCareer = $('#career-lightbox');
55177
55178    var openLightbox = function () {
55179      $lightbox.fadeIn();
55180      $('body').addClass("has-lightbox");
55181    };
55182
55183    var openLightboxCareer = function () {
55184      $lightboxCareer.fadeIn();
55185      $('body').addClass("has-lightbox");
55186    };
55187
55188    $careerApplyForm.click(function (event) {
55189      event.preventDefault();
55190      openLightboxCareer();
55191    });
55192
55193    $magazineSubscribe.click(function () {
55194      openLightbox();
55195      $lightbox.find("input[name='group[11457][4]']").attr("checked", "checked");
55196      return false;
55197    });
55198
55199    $footerNewsletterForm.submit(function () {
55200      openLightbox();
55201      $('#newsletter-form').find('input[name="EMAIL"]')
55202        .val($footerNewsletterForm.find("input[type='email']").val())
55203        .trigger("change");
55204      return false;
55205    });
55206
55207    var closeLightbox = function () {
55208      $lightbox.fadeOut(400, function () {
55209        $('body').removeClass("has-lightbox");
55210      });
55211      $lightboxCareer.fadeOut(400, function () {
55212        $('body').removeClass("has-lightbox");
55213      });
55214
55215      if ($(window).width() < 681) {
55216        $("html, body").animate({
55217          scrollTop: $('.footer').find("._subscribe").offset().top - 50
55218        }, 400);
55219      }
55220    };
55221
55222    $('.lightbox').click(function (event) {
55223      if (!$(event.target).hasClass("lightbox")) return;
55224      closeLightbox();
55225      return false;
55226    });
55227
55228    $('.close-lightbox').click(function () {
55229      closeLightbox();
55230      return false;
55231    });
55232  }
55233
55234  function initHeaderBooking() {
55235    if ($('.header-booking').length > 0) {
55236      var distance = $('.header-booking-wrapper').offset().top;
55237      var $headerGeneralBooking = $('.header-booking-wrapper .general-booking');
55238      var $bookingBtnClose = $('<div class="booking-btn-close"></div>').appendTo($headerGeneralBooking);
55239      var $window = $(window);
55240      var $homepageHeaderImage = $('body.page-homepage .header-image');
55241
55242      $headerGeneralBooking.css({
55243        "top": distance - 50
55244      });
55245
55246      $('.header-booking').click(function () {
55247
55248        if (!$headerGeneralBooking.find("iframe").attr("src")) {
55249          $headerGeneralBooking.find("iframe").attr("src", $headerGeneralBooking.find("iframe").data("src"));
55250        }
55251
55252        $headerGeneralBooking.fadeIn(250);
55253        $('body').removeClass("disable-scroll");
55254        $('.search').removeClass("open");
55255        $('.search-btn').removeClass("active-search");
55256      });
55257
55258      $bookingBtnClose.click(function () {
55259        $headerGeneralBooking.fadeOut(250);
55260      });
55261
55262      if (!($('body').hasClass('page-homepage'))) {
55263        $window.bind("scroll resize", function () {
55264          if ($window.scrollTop() >= distance) {
55265            $headerGeneralBooking.css({
55266              'position': 'fixed',
55267              'top': 0
55268            });
55269            $('.mobile-plan-trip').addClass('is-active');
55270          } else {
55271            $headerGeneralBooking.css({
55272              'position': '',
55273              'top': 0
55274            });
55275            $('.mobile-plan-trip').removeClass('is-active');
55276          }
55277        });
55278      } else {
55279        $window.bind("scroll resize", function () {
55280          if ($window.scrollTop() >= distance) {
55281            $headerGeneralBooking.css({
55282              'position': 'fixed',
55283              'top': 0
55284            });
55285
55286            $('.header .small').addClass('booking-is-sticky');
55287            $homepageHeaderImage.addClass('header-image--scrolled');
55288            $('.mobile-plan-trip').addClass('is-active');
55289          } else {
55290            $headerGeneralBooking.css({
55291              'position': '',
55292              'top': distance - 50
55293            });
55294
55295            $('.header .small').removeClass('booking-is-sticky');
55296            $homepageHeaderImage.removeClass('header-image--scrolled');
55297            $('.mobile-plan-trip').removeClass('is-active');
55298          }
55299        });
55300      }
55301
55302      if (!($('body').hasClass('page-homepage'))) {
55303        $window.bind("scroll resize", function () {
55304          if ($window.scrollTop() >= distance + 51) {
55305            $('.header .small').addClass('booking-is-sticky');
55306          } else {
55307            $('.header .small').removeClass('booking-is-sticky');
55308          }
55309        });
55310      }
55311
55312      $('.header-booking .small').mouseover(function () {
55313        $('.header .small').addClass('hover');
55314      });
55315      $('.header-booking .small').mouseout(function () {
55316        $('.header .small').removeClass('hover');
55317      });
55318
55319      if ($('html').attr('lang') == "en") {
55320        $('.header .small, .header-booking .small').addClass('is-en');
55321      } else {
55322        $('.header .small, .header-booking .small').addClass('is-fr');
55323      }
55324    }
55325  }
55326
55327  function initGeneralBooking() {
55328    var $window = $(window);
55329    var $generalBooking = $("#content > .general-booking");
55330    if ($generalBooking.length > 0) {
55331      $window.bind("scroll resize", function () {
55332        if (($window.scrollTop() + $(window).height()) > $generalBooking.offset().top) {
55333          if (!$generalBooking.find("iframe").attr("src")) {
55334            $generalBooking.find("iframe").attr("src", $generalBooking.find("iframe").data("src"));
55335          }
55336        }
55337      });
55338    }
55339  }
55340
55341  function initMobileBooking() {
55342    var $mobileBooking = $('.mobile-booking');
55343    var $mobileGeneralBooking = $('.mobile-booking .general-booking');
55344    var $bookingBtnClose = $('<div class="booking-btn-close"></div>').appendTo($mobileGeneralBooking);
55345    //     $('.mobile-plan-trip').click(function () {
55346    // 	if (!$mobileBooking.find("iframe").attr("src")) {
55347    // 		$mobileBooking.find("iframe").attr("src", $mobileBooking.find("iframe").data("src"));
55348    // 	}
55349    // 	$mobileBooking.fadeIn(250);
55350    //         $('html, body').css({"overflow": "hidden", "position": "relative", "height": "100%"});
55351    // 	return false;
55352    // });
55353
55354    $bookingBtnClose.click(function () {
55355      $mobileBooking.fadeOut(250);
55356      if (!$('.menu-mobile').hasClass("open")) {
55357        $('html, body').css({ "overflow": "auto", "position": "initial", "height": "auto" });
55358      }
55359    });
55360  }
55361
55362  function initPageLang() {
55363    if ($('html').attr('lang') == "en") {
55364      $('.mobile-lang-en').css({ "display": "" });
55365      $('.mobile-lang-fr').css({ "display": "none" });
55366      $('.label-en').css({ "display": "" });
55367      $('.label-fr').css({ "display": "none" });
55368    } else {
55369      $('.mobile-lang-en').css({ "display": "none" });
55370      $('.mobile-lang-fr').css({ "display": "" });
55371      $('.label-en').css({ "display": "none" });
55372      $('.label-fr').css({ "display": "" });
55373    }
55374
55375    $('.mobile-lang-en, .mobile-lang-fr').on('mousedown touchstart', function (e) {
55376      if (e.which === 1) {
55377        var button = $(this);
55378        var parent_width = button.parent().innerWidth();
55379        var left = parseInt(button.css('left')); //current left position
55380        var original_xpos = button.css('left', '').position().left; //original xpos (without left)
55381        button.css({ left: left + 'px' }); //restore left pos
55382        var drag_min_xpos = 0 - original_xpos + 4; //btn stop on left border
55383        var drag_max_xpos = parent_width - original_xpos - button.outerWidth() + 4; //btn stop on right border
55384        var drag_start_xpos = e.clientX;
55385        $(window).on('mousemove touchmove', function (e) {
55386          //Drag started
55387          var new_left = left + (e.clientX - drag_start_xpos);
55388          button.css({ left: new_left + 'px' });
55389          if (new_left < drag_min_xpos) { button.css({ left: drag_min_xpos + 'px' }); }
55390          if (new_left > drag_max_xpos) { button.css({ left: drag_max_xpos + 'px' }); }
55391        });
55392        $(window).on('mouseup touchend', function (e) {
55393          if (e.which === 1) {
55394            //Drag finished
55395            $(window).off('mouseup mousemove touchend touchmove');
55396          }
55397        });
55398      }
55399    });
55400    $('.mobile-lang-en').on('mousedown touchstart', function (e) {
55401      if (e.which === 1) {
55402        var button = $(this);
55403        $(window).on('mouseup touchend', function (e) {
55404          if (e.which === 1) {
55405            if (button.css({ left: -49.75 + 'px' })) {
55406              $('.mobile-toggle-lang >div >a')[0].click();
55407              $('.mobile-toggle-lang .label-en').addClass('changed');
55408              $('.mobile-toggle-lang a').css({ "color": "#371c41" });
55409            }
55410          }
55411        });
55412      }
55413    });
55414    $('.mobile-lang-fr').on('mousedown touchstart', function (e) {
55415      if (e.which === 1) {
55416        var button = $(this);
55417        $(window).on('mouseup touchend', function (e) {
55418          if (e.which === 1) {
55419            if (button.css({ left: 51.3438 + 'px' })) {
55420              $('.mobile-toggle-lang >div >a')[0].click();
55421              $('.mobile-toggle-lang .label-fr').addClass('changed');
55422              $('.mobile-toggle-lang a').css({ "color": "#371c41" });
55423            }
55424          }
55425        });
55426      }
55427    });
55428  }
55429
55430}(jQuery));
55431
55432function validateEmail(email) {
55433  var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
55434  return re.test(email);
55435}
55436
55437function validatePhone(phone) {
55438  var re = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;
55439  return re.test(phone);
55440}
55441
55442var saleAgentsMap;
55443function initMap() {
55444  $('.gm-map').each(function () {
55445    var $map = $(this);
55446    var map = new google.maps.Map($map[0], {
55447      scrollwheel: false,
55448      zoom: $map.data("zoom"),
55449      minZoom: 3,
55450      center: new google.maps.LatLng(parseFloat($map.data("lat")), parseFloat($map.data("lng"))),
55451      styles: mapStyle,
55452      zoomControl: true
55453    });
55454    var dataMarkers = $map.data("markers");
55455    var dataOtherMarkers = $map.data("other-markers");
55456    var markers = [];
55457    var otherMarkers = [];
55458    var marker1 = "/dist/images/marker.png";
55459    var marker2 = "/dist/images/marker2.png";
55460    var otherMarker1 = "/dist/images/otherMarker.png";
55461    var otherMarker2 = "/dist/images/otherMarker2.png";
55462
55463    var specials = ['attraction', 'dining', 'discount', 'transit']
55464    var specialsMarkerPath = '/dist/images/markers/'
55465    function isSpecial(type) {
55466      return specials.includes(type)
55467    }
55468
55469    var addMarkerListeners = function (element) {
55470      element.addListener('mouseover', function () {
55471        element.setIcon(marker2);
55472      });
55473      element.addListener('mouseout', function () {
55474        element.setIcon(marker1);
55475      });
55476    };
55477
55478    function markerIconByType(type) {
55479      return isSpecial(type)
55480        ? {
55481          url: `${specialsMarkerPath}${type}.svg`, // url
55482          scaledSize: new google.maps.Size(32, 48), // scaled size
55483          origin: new google.maps.Point(0, 0), // origin
55484          anchor: new google.maps.Point(16, 48) // anchor
55485        }
55486        : otherMarker1
55487    }
55488
55489    function markerIconByTypeHover(type) {
55490      return isSpecial(type)
55491        ? {
55492          url: `${specialsMarkerPath}${type}.svg`, // url
55493          scaledSize: new google.maps.Size(40, 60), // scaled size
55494          origin: new google.maps.Point(0, 0), // origin
55495          anchor: new google.maps.Point(20, 60) // anchor
55496        }
55497        : otherMarker2
55498    }
55499
55500    var addOtherMarkerListeners = function (element) {
55501      var type = element['type'];
55502      element.addListener('mouseover', function () {
55503        element.setIcon(markerIconByTypeHover(type));
55504      });
55505      element.addListener('mouseout', function () {
55506        element.setIcon(markerIconByType(type));
55507      });
55508    }
55509
55510    var resetAllMarkers = function () {
55511      _.each(markers, function (element, index, list) {
55512        element.setIcon(marker1);
55513        clearMarkerListeners(element);
55514        addMarkerListeners(element);
55515      });
55516      _.each(otherMarkers, function (element, index, list) {
55517        var type = element['type'];
55518        var icon = markerIconByType(type)
55519        element.setIcon(icon);
55520        clearMarkerListeners(element);
55521        addOtherMarkerListeners(element);
55522      });
55523    };
55524
55525    var clearMarkerListeners = function (element) {
55526      google.maps.event.clearListeners(element, 'mouseover');
55527      google.maps.event.clearListeners(element, 'mouseout');
55528    };
55529
55530    // Setup the click event listener - zoomIn
55531    var zoomInButton = document.getElementById("zoom-in");
55532    google.maps.event.addDomListener(zoomInButton, 'click', function () {
55533      map.setZoom(map.getZoom() + 1);
55534    });
55535    // Setup the click event listener - zoomOut
55536    var zoomOutButton = document.getElementById("zoom-out");
55537    google.maps.event.addDomListener(zoomOutButton, 'click', function () {
55538      map.setZoom(map.getZoom() - 1);
55539    });
55540
55541    // Markers ----------------------------------------------------------------------------
55542    _.each(dataMarkers, function (element, index, list) {
55543      var markerPoint = new google.maps.LatLng(
55544        parseFloat(element["latitude"]),
55545        parseFloat(element["longitude"])
55546      );
55547      var marker = new google.maps.Marker({
55548        animation: google.maps.Animation.DROP,
55549        position: { lat: parseFloat(element["latitude"]), lng: parseFloat(element["longitude"]) },
55550        map: map,
55551        icon: "/dist/images/marker.png"
55552      });
55553
55554      addMarkerListeners(marker);
55555
55556      var $target = $("#hostel-" + element["id"]);
55557      if ($target.length > 0) {
55558        marker.addListener('click', function () {
55559          _.each(dataMarkers, function (element, index, list) {
55560            $("#hostel-" + element["id"]).not($target).removeClass('open');
55561            $(".hostels-map ._proximity").removeClass('open');
55562          });
55563          resetAllMarkers();
55564          $target.toggleClass('open');
55565          if ($target.hasClass("open")) {
55566            $target.find("img").attr("src", $target.find("img").data("src"));
55567            clearMarkerListeners(marker);
55568          } else {
55569            addMarkerListeners(marker);
55570          }
55571          marker.setIcon(marker2);
55572
55573          if ($(window).width() < 681) {
55574            $('html, body').animate({
55575              scrollTop: $target.offset().top - 300
55576            }, 600);
55577          }
55578        });
55579
55580        $target.find(".close-hostel").click(function () {
55581          $target.removeClass("open");
55582          marker.setIcon(marker1);
55583          addMarkerListeners(marker);
55584
55585          if ($(window).width() < 681) {
55586            $('html, body').animate({
55587              scrollTop: $('#map').offset().top - 100
55588            }, 600);
55589          }
55590
55591          return false;
55592        });
55593      }
55594      markers.push(marker);
55595    });
55596    // Other markers ----------------------------------------------------------------------
55597    _.each(dataOtherMarkers, function (element, index, list) {
55598      var marker = new google.maps.Marker({
55599        animation: google.maps.Animation.DROP,
55600        position: { lat: parseFloat(element["latitude"]), lng: parseFloat(element["longitude"]) },
55601        map: map,
55602        type: element["type"],
55603        icon: markerIconByType(element["type"])
55604      });
55605
55606      addOtherMarkerListeners(marker);
55607
55608      var $target = $("#marker-detail-" + element["id"]);
55609      if ($target.length > 0) {
55610        marker.addListener('click', function () {
55611          _.each(dataOtherMarkers, function (element, index, list) {
55612            $("#marker-detail-" + element["id"]).not($target).removeClass('open');
55613            $(".hostels-map ._hostel").removeClass('open');
55614          });
55615          resetAllMarkers();
55616          $target.toggleClass('open');
55617          if ($target.hasClass("open")) {
55618            $target.find("img").attr("src", $target.find("img").data("src"));
55619            clearMarkerListeners(marker);
55620          } else {
55621            addOtherMarkerListeners(marker);
55622          }
55623
55624          marker.setIcon(markerIconByTypeHover(marker.type));
55625
55626          if ($(window).width() < 681) {
55627            $('html, body').animate({
55628              scrollTop: $target.offset().top - 300
55629            }, 600);
55630          }
55631        });
55632
55633        $target.find(".close-proximity").click(function () {
55634          $target.removeClass("open");
55635          marker.setIcon(markerIconByType(marker.type));
55636          addOtherMarkerListeners(marker);
55637
55638          if ($(window).width() < 681) {
55639            $('html, body').animate({
55640              scrollTop: $('#map').offset().top - 100
55641            }, 600);
55642          }
55643
55644          return false;
55645        });
55646      }
55647
55648      otherMarkers.push(marker);
55649    });
55650  });
55651
55652  // Sales agents map ----------------------------------------------------------
55653  var $saleAgents = $("#sale-agents");
55654  if ($saleAgents.length > 0) {
55655    var $selectProvince = $saleAgents.find('select[name="province"]');
55656    var $selectCity = $saleAgents.find('select[name="city"]');
55657    var citiesData = [];
55658    $.each($selectCity.find('option'), function (i, el) {
55659      citiesData.push({ id: $(el).attr("value"), text: $(el).text(), province: $(el).data("province") });
55660    });
55661    $selectProvince.change(function () {
55662      var val = $(this).val();
55663      var filteredData = _.filter(citiesData, function (item) {
55664        return item.province == val;
55665      });
55666      if (!Modernizr.mq('(max-width: 1024px)')) {
55667        $selectCity.select2().empty();
55668        $selectCity.select2({
55669          data: [{ id: "", text: "" }].concat(filteredData),
55670          minimumResultsForSearch: 15
55671        })
55672      } else {
55673        $selectCity.html("");
55674        $('<option value="" disabled="disabled" selected="selected">' + $selectCity.data("placeholder") + '</option>').appendTo($selectCity);
55675        _.each(filteredData, function (item) {
55676          $('<option value="' + item.id + '">' + item.text + '</option>').appendTo($selectCity);
55677        });
55678      }
55679    });
55680
55681    var $filters = $saleAgents.find(".filters");
55682    var $grid = $saleAgents.find("._sales-agents");
55683
55684    var getParams = function () {
55685      var data = {};
55686      $filters.find('input, select').each(function () {
55687        data[$(this).attr("name")] = $(this).val();
55688      });
55689      return data;
55690    };
55691
55692    var updateElements = function () {
55693      $.get("", getParams(), function (result) {
55694        var html = $($('<div />').html(result.html).text());
55695
55696        $grid.html("");
55697        $grid.append(html);
55698        bLazy.revalidate();
55699
55700        var markers = result.markers;
55701
55702        var markerBounds = new google.maps.LatLngBounds();
55703
55704        clearAllMarkers();
55705        addMarkers(markers);
55706
55707        _.each(markers, function (element, index, list) {
55708          if (element["latitude"] != "" && element["longitude"] != "") {
55709            var markerPoint = new google.maps.LatLng(
55710              parseFloat(element["latitude"]),
55711              parseFloat(element["longitude"])
55712            );
55713
55714            markerBounds.extend(markerPoint);
55715          }
55716        });
55717
55718        if (markers.length > 0) {
55719          if (markerBounds.getNorthEast().equals(markerBounds.getSouthWest
55719())) {
55720            var extendPoint1 = new google.maps.LatLng(markerBounds.getNorthEast().lat() + 0.005, markerBounds.getNorthEast().lng() + 0.005);
55721            var extendPoint2 = new google.maps.LatLng(markerBounds.getNorthEast().lat() - 0.005, markerBounds.getNorthEast().lng() - 0.005);
55722            markerBounds.extend(extendPoint1);
55723            markerBounds.extend(extendPoint2);
55724          }
55725
55726          saleAgentsMap.fitBounds(markerBounds);
55727        }
55728      });
55729    };
55730
55731    var doNotLoadElements = false;
55732
55733    $filters.find("input, select").change(function () {
55734      if (doNotLoadElements) return;
55735      updateElements();
55736    });
55737    $filters.find('.reset-filters').click(function () {
55738      doNotLoadElements = true;
55739      $filters.find('select,input').val("").trigger('change');
55740      doNotLoadElements = false;
55741      updateElements();
55742      return false;
55743    });
55744
55745
55746    var $map = $('.sale-agents-map');
55747
55748    saleAgentsMap = new google.maps.Map($map[0], {
55749      scrollwheel: false,
55750      zoom: $map.data("zoom"),
55751      minZoom: 3,
55752      center: { lat: $map.data("lat"), lng: $map.data("lng") },
55753      styles: mapStyle,
55754      zoomControl: false
55755    });
55756    var dataMarkers = $map.data("markers");
55757    var markers = [];
55758    var marker1 = "/dist/images/otherMarker.png";
55759    var marker2 = "/dist/images/otherMarker2.png";
55760
55761    var specials = ['attraction', 'dining', 'discount', 'transit']
55762    var specialsMarkerPath = '/dist/images/markers/'
55763    function isSpecial(type) {
55764      return specials.includes(type)
55765    }
55766
55767    function markerIconByType(type) {
55768      return isSpecial(type)
55769        ? {
55770          url: `${specialsMarkerPath}${type}.svg`, // url
55771          scaledSize: new google.maps.Size(32, 48), // scaled size
55772          origin: new google.maps.Point(0, 0), // origin
55773          anchor: new google.maps.Point(16, 48) // anchor
55774        }
55775        : otherMarker1
55776    }
55777
55778    function markerIconByTypeHover(type) {
55779      return isSpecial(type)
55780        ? {
55781          url: `${specialsMarkerPath}${type}.svg`, // url
55782          scaledSize: new google.maps.Size(40, 60), // scaled size
55783          origin: new google.maps.Point(0, 0), // origin
55784          anchor: new google.maps.Point(20, 60) // anchor
55785        }
55786        : otherMarker2
55787    }
55788
55789    var addMarkerListeners = function (element) {
55790      var type = element['type'];
55791      element.addListener('mouseover', function () {
55792        element.setIcon(markerIconByTypeHover(type));
55793      });
55794      element.addListener('mouseout', function () {
55795        element.setIcon(markerIconByType(type));
55796      });
55797    }
55798
55799    var clearAllMarkers = function () {
55800      _.each(markers, function (element, index, list) {
55801        clearMarkerListeners(element);
55802        element.setMap(null);
55803      });
55804      markers = [];
55805    };
55806
55807    var resetAllMarkers = function () {
55808      _.each(markers, function (element, index, list) {
55809        element.setIcon(marker1);
55810        clearMarkerListeners(element);
55811        addMarkerListeners(element);
55812      });
55813    };
55814
55815    var clearMarkerListeners = function (element) {
55816      google.maps.event.clearListeners(element, 'mouseover');
55817      google.maps.event.clearListeners(element, 'mouseout');
55818    };
55819
55820    var addMarkers = function (data) {
55821      _.each(data, function (element, index, list) {
55822        var markerPoint = new google.maps.LatLng(
55823          parseFloat(element["latitude"]),
55824          parseFloat(element["longitude"])
55825        );
55826        var marker = new google.maps.Marker({
55827          animation: google.maps.Animation.DROP,
55828          position: { lat: parseFloat(element["latitude"]), lng: parseFloat(element["longitude"]) },
55829          map: saleAgentsMap,
55830          type: element["type"],
55831          icon: markerIconByTypeHover(element["type"]),
55832          title: element["title"] + ' - ' + element["id"]
55833        });
55834
55835        addMarkerListeners(marker);
55836
55837        var $target = $("#sales-agent-" + element["id"]);
55838        if ($target.length > 0) {
55839          marker.addListener('click', function () {
55840            window.dataLayer.push({
55841              'event': 'membershipMarkerClick',
55842              'markerEventAction': 'Clicked on Membership Map Marker',
55843              'markerEventCategory': 'Membership Retailers',
55844              'markerEventLabel': marker.getTitle()
55845            });
55846            _.each(data, function (element, index, list) {
55847              $("#sales-agent-" + element["id"]).not($target).removeClass('open');
55848              $(".sales-agents-map ._proximity").removeClass('open');
55849            });
55850            resetAllMarkers();
55851            $target.toggleClass('open');
55852            if ($target.hasClass("open")) {
55853              clearMarkerListeners(marker);
55854            } else {
55855              addMarkerListeners(marker);
55856            }
55857            marker.setIcon(markerIconByTypeHover(marker.type));
55858
55859            if ($(window).width() < 681) {
55860              $('html, body').animate({
55861                scrollTop: $target.offset().top - 300
55862              }, 600);
55863            }
55864          });
55865
55866          $target.find("._close").click(function () {
55867            $target.removeClass("open");
55868            marker.setIcon(markerIconByTypeHover(marker.type));
55869            addMarkerListeners(marker);
55870
55871            if ($(window).width() < 681) {
55872              $('html, body').animate({
55873                scrollTop: $('#map').offset().top - 100
55874              }, 600);
55875            }
55876
55877            return false;
55878          });
55879        }
55880        markers.push(marker);
55881      });
55882    }
55883
55884    // Setup the click event listener - zoomIn
55885    var zoomInButton = document.getElementById("zoom-in");
55886    google.maps.event.addDomListener(zoomInButton, 'click', function () {
55887      saleAgentsMap.setZoom(saleAgentsMap.getZoom() + 1);
55888    });
55889    // Setup the click event listener - zoomOut
55890    var zoomOutButton = document.getElementById("zoom-out");
55891    google.maps.event.addDomListener(zoomOutButton, 'click', function () {
55892      saleAgentsMap.setZoom(saleAgentsMap.getZoom() - 1);
55893    });
55894
55895    // Markers ----------------------------------------------------------------
55896    addMarkers(dataMarkers);
55897  }
55898}
55899
55900function initArticleClick() {
55901  $("#content").on("click", ".article-card", function () {
55902    var $url = $(this).find('._thumb').attr('href');
55903    window.location.href = $url;
55904  });
55905}
55906function initDiscountClick() {
55907  $("#content").on("click", ".offer-card", function () {
55908    var $url = $(this).find('._thumb').attr('href');
55909    window.location.href = $url;
55910  });
55911}
55912
55913function verifyAnchors() {
55914  if ($('.content-nav').length > 0 && $('.articles-ajax').length == 0) {
55915    $(".content-nav ul li a").each(function () {
55916      var $anchor = $(this).attr('href');
55917      if ($($anchor).length > 0) return;
55918      $(this).hide();
55919    });
55920  }
55921}
55922function initPreventOverScrollMobile() {
55923  $('document').on('touchmove', function (e) {
55924    e.preventDefault();
55925  });
55926  $('body').on('touchstart', '.scrollable', function (e) {
55927
55928    if ((e.currentTarget).scrollTop === 0) {
55929      (e.currentTarget).scrollTop = 1;
55930    } else if ((e.currentTarget).scrollHeight === (e.currentTarget).scrollTop + (e.currentTarget).offsetHeight) {
55931      (e.currentTarget).scrollTop -= 1;
55932    }
55933  });
55934  $('body').on('touchmove', '.scrollable', function (e) {
55935    if ((e.currentTarget).scrollHeight > (e.currentTarget).offsetHeight) {
55936      e.stopPropagation();
55937    } else {
55938      e.preventDefault();
55939    }
55940
55941  });
55942}
55943function initHideTools() {
55944  $(document).scroll(function () {
55945    var y = $(this).scrollTop();
55946    if (y > 100 && Modernizr.mq('(min-width: 900px)')) {
55947      $('.tools').fadeIn(250);
55948    } else {
55949      $('.tools').fadeOut(250);
55950    }
55951  });
55952}
55953
55954function initCareerForm() {
55955  $('#career-form').parsley();
55956  $('#career-form').submit(function () {
55957    ga('send', 'event', 'Job Application', 'Submit Apply Form', $(this).data('job-title'));
55958  });
55959}
55960
55961function initHeaderPopinBookDirect() {
55962  var bookdirect = {
55963    cookie: 'bookdirect',
55964    isHidden: function () {
55965      var value = sessionStorage.getItem(bookdirect.cookie)
55966      return value === 'hide'
55967    },
55968    el: document.querySelector('#bookdirect'),
55969    close: document.querySelector('#close_book-direct')
55970  }
55971  if (!bookdirect.el
55972    || bookdirect.isHidden()) {
55973    return
55974  }
55975  bookdirect.el.setAttribute('aria-hidden', 'false')
55976
55977  // mobile toggle
55978  bookdirect.el.addEventListener('click', function (event) {
55979    // event.preventDefault()
55980    var isOpen = bookdirect.el.getAttribute('data-open') === 'true'
55981    bookdirect.el.setAttribute('data-open', !isOpen)
55982    // sessionStorage.setItem(bookdirect.cookie, 'hide');
55983    // return false
55984  })
55985
55986  // desktop close
55987  bookdirect.close.addEventListener('click', function (event) {
55988    event.preventDefault()
55989    var isOpen = bookdirect.el.getAttribute('aria-hidden') === 'false'
55990    bookdirect.el.setAttribute('aria-hidden', isOpen)
55991    sessionStorage.setItem(bookdirect.cookie, 'hide');
55992    return false
55993  })
55994}
55995
55996var mapStyle = [
55997  {
55998    "featureType": "administrative",
55999    "elementType": "geometry.stroke",
56000    "stylers": [
56001      {
56002        "color": "#cccccc"
56003      },
56004      {
56005        "weight": 0.5
56006      }
56007    ]
56008  },
56009  {
56010    "featureType": "administrative",
56011    "elementType": "labels.text",
56012    "stylers": [
56013      {
56014        "color": "#703686"
56015      },
56016      {
56017        "visibility": "simplified"
56018      }
56019    ]
56020  },
56021  {
56022    "featureType": "administrative.country",
56023    "elementType": "labels.text",
56024    "stylers": [
56025      {
56026        "color": "#ce1936"
56027      }
56028    ]
56029  },
56030  {
56031    "featureType": "landscape.man_made",
56032    "stylers": [
56033      {
56034        "color": "#e6e6e6"
56035      }
56036    ]
56037  },
56038  {
56039    "featureType": "landscape.man_made",
56040    "elementType": "geometry.fill",
56041    "stylers": [
56042      {
56043        "color": "#ebebf5"
56044      }
56045    ]
56046  },
56047  {
56048    "featureType": "landscape.natural",
56049    "stylers": [
56050      {
56051        "color": "#ffffff"
56052      }
56053    ]
56054  },
56055  {
56056    "featureType": "poi",
56057    "elementType": "geometry.fill",
56058    "stylers": [
56059      {
56060        "color": "#c8c8db"
56061      }
56062    ]
56063  },
56064  {
56065    "featureType": "poi",
56066    "elementType": "labels.text",
56067    "stylers": [
56068      {
56069        "color": "#9c8e8b"
56070      },
56071      {
56072        "visibility": "off"
56073      }
56074    ]
56075  },
56076  {
56077    "featureType": "poi.business",
56078    "stylers": [
56079      {
56080        "visibility": "off"
56081      }
56082    ]
56083  },
56084  {
56085    "featureType": "poi.park",
56086    "stylers": [
56087      {
56088        "color": "#b1da8b"
56089      },
56090      {
56091        "visibility": "on"
56092      },
56093      {
56094        "weight": 3
56095      }
56096    ]
56097  },
56098  {
56099    "featureType": "poi.park",
56100    "elementType": "labels.text",
56101    "stylers": [
56102      {
56103        "visibility": "off"
56104      }
56105    ]
56106  },
56107  {
56108    "featureType": "poi.place_of_worship",
56109    "stylers": [
56110      {
56111        "visibility": "off"
56112      }
56113    ]
56114  },
56115  {
56116    "featureType": "road.arterial",
56117    "elementType": "labels.text",
56118    "stylers": [
56119      {
56120        "visibility": "simplified"
56121      }
56122    ]
56123  },
56124  {
56125    "featureType": "road.highway",
56126    "stylers": [
56127      {
56128        "visibility": "off"
56129      }
56130    ]
56131  },
56132  {
56133    "featureType": "road.highway",
56134    "elementType": "geometry",
56135    "stylers": [
56136      {
56137        "visibility": "simplified"
56138      }
56139    ]
56140  },
56141  {
56142    "featureType": "road.highway",
56143    "elementType": "geometry.fill",
56144    "stylers": [
56145      {
56146        "visibility": "simplified"
56147      }
56148    ]
56149  },
56150  {
56151    "featureType": "road.highway",
56152    "elementType": "geometry.stroke",
56153    "stylers": [
56154      {
56155        "visibility": "simplified"
56156      }
56157    ]
56158  },
56159  {
56160    "featureType": "road.highway.controlled_access",
56161    "elementType": "labels.text",
56162    "stylers": [
56163      {
56164        "visibility": "simplified"
56165      }
56166    ]
56167  },
56168  {
56169    "featureType": "road.local",
56170    "elementType": "labels.text",
56171    "stylers": [
56172      {
56173        "visibility": "simplified"
56174      }
56175    ]
56176  },
56177  {
56178    "featureType": "transit",
56179    "elementType": "geometry.fill",
56180    "stylers": [
56181      {
56182        "color": "#ccccd4"
56183      }
56184    ]
56185  },
56186  {
56187    "featureType": "transit",
56188    "elementType": "labels.text",
56189    "stylers": [
56190      {
56191        "visibility": "off"
56192      }
56193    ]
56194  },
56195  {
56196    "featureType": "water",
56197    "stylers": [
56198      {
56199        "color": "#dcf5f5"
56200      }
56201    ]
56202  },
56203  {
56204    "featureType": "water",
56205    "elementType": "geometry.fill",
56206    "stylers": [
56207      {
56208        "color": "#d2f5f3"
56209      }
56210    ]
56211  },
56212  {
56213    "featureType": "water",
56214    "elementType": "labels.text",
56215    "stylers": [
56216      {
56217        "color": "#7ac6bd"
56218      }
56219    ]
56220  }
56221];
56222function getQueryVariable(variable) {
56223  var query = window.location.search.substring(1);
56224  var vars = query.split("&");
56225  for (var i = 0; i < vars.length; i++) {
56226    var pair = vars[i].split("=");
56227    if (pair[0] == variable) { return pair[1]; }
56228  }
56229  return (false);
56230}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.