PageSourceSearch

https://www.keepscotlandbeautiful.org/js/forms.js

js keepscotlandbeautiful.org collected 2026-10-02 05:30:51 UTC 375,000 bytes, 13,193 lines download raw bytes

vendor: 78 bytes, lines 1-3
1/******/ (() => { // webpackBootstrap
2/******/ 	var __webpack_modules__ = ({
3
vendor: 20,442 bytes, lines 4-445
4/***/ "./node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js":
5/*!****************************************************************************************!*\
6  !*** ./node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js ***!
7  \****************************************************************************************/
8/***/ ((module, exports, __webpack_require__) => {
9
10var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
11 * @license
12 * Unobtrusive validation support library for jQuery and jQuery Validate
13 * Copyright (c) .NET Foundation. All rights reserved.
14 * Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
15 * @version v4.0.0
16 */
17
18/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
19/*global document: false, jQuery: false */
20
21(function (factory) {
22    if (true) {
23        // AMD. Register as an anonymous module.
24        !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery-validation */ "./node_modules/jquery-validation/dist/jquery.validate.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
25		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
26		(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
27		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
28    } else {}
29}(function ($) {
30    var $jQval = $.validator,
31        adapters,
32        data_validation = "unobtrusiveValidation";
33
34    function setValidationValues(options, ruleName, value) {
35        options.rules[ruleName] = value;
36        if (options.message) {
37            options.messages[ruleName] = options.message;
38        }
39    }
40
41    function splitAndTrim(value) {
42        return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
43    }
44
45    function escapeAttributeValue(value) {
46        // As mentioned on http://api.jquery.com/category/selectors/
47        return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
48    }
49
50    function getModelPrefix(fieldName) {
51        return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
52    }
53
54    function appendModelPrefix(value, prefix) {
55        if (value.indexOf("*.") === 0) {
56            value = value.replace("*.", prefix);
57        }
58        return value;
59    }
60
61    function onError(error, inputElement) {  // 'this' is the form element
62        var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
63            replaceAttrValue = container.attr("data-valmsg-replace"),
64            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
65
66        container.removeClass("field-validation-valid").addClass("field-validation-error");
67        error.data("unobtrusiveContainer", container);
68
69        if (replace) {
70            container.empty();
71            error.removeClass("input-validation-error").appendTo(container);
72        }
73        else {
74            error.hide();
75        }
76    }
77
78    function onErrors(event, validator) {  // 'this' is the form element
79        var container = $(this).find("[data-valmsg-summary=true]"),
80            list = container.find("ul");
81
82        if (list && list.length && validator.errorList.length) {
83            list.empty();
84            container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
85
86            $.each(validator.errorList, function () {
87                $("<li />").html(this.message).appendTo(list);
88            });
89        }
90    }
91
92    function onSuccess(error) {  // 'this' is the form element
93        var container = error.data("unobtrusiveContainer");
94
95        if (container) {
96            var replaceAttrValue = container.attr("data-valmsg-replace"),
97                replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
98
99            container.addClass("field-validation-valid").removeClass("field-validation-error");
100            error.removeData("unobtrusiveContainer");
101
102            if (replace) {
103                container.empty();
104            }
105        }
106    }
107
108    function onReset(event) {  // 'this' is the form element
109        var $form = $(this),
110            key = '__jquery_unobtrusive_validation_form_reset';
111        if ($form.data(key)) {
112            return;
113        }
114        // Set a flag that indicates we're currently resetting the form.
115        $form.data(key, true);
116        try {
117            $form.data("validator").resetForm();
118        } finally {
119            $form.removeData(key);
120        }
121
122        $form.find(".validation-summary-errors")
123            .addClass("validation-summary-valid")
124            .removeClass("validation-summary-errors");
125        $form.find(".field-validation-error")
126            .addClass("field-validation-valid")
127            .removeClass("field-validation-error")
128            .removeData("unobtrusiveContainer")
129            .find(">*")  // If we were using valmsg-replace, get the underlying error
130            .removeData("unobtrusiveContainer");
131    }
132
133    function validationInfo(form) {
134        var $form = $(form),
135            result = $form.data(data_validation),
136            onResetProxy = $.proxy(onReset, form),
137            defaultOptions = $jQval.unobtrusive.options || {},
138            execInContext = function (name, args) {
139                var func = defaultOptions[name];
140                func && $.isFunction(func) && func.apply(form, args);
141            };
142
143        if (!result) {
144            result = {
145                options: {  // options structure passed to jQuery Validate's validate() method
146                    errorClass: defaultOptions.errorClass || "input-validation-error",
147                    errorElement: defaultOptions.errorElement || "span",
148                    errorPlacement: function () {
149                        onError.apply(form, arguments);
150                        execInContext("errorPlacement", arguments);
151                    },
152                    invalidHandler: function () {
153                        onErrors.apply(form, arguments);
154                        execInContext("invalidHandler", arguments);
155                    },
156                    messages: {},
157                    rules: {},
158                    success: function () {
159                        onSuccess.apply(form, arguments);
160                        execInContext("success", arguments);
161                    }
162                },
163                attachValidation: function () {
164                    $form
165                        .off("reset." + data_validation, onResetProxy)
166                        .on("reset." + data_validation, onResetProxy)
167                        .validate(this.options);
168                },
169                validate: function () {  // a validation function that is called by unobtrusive Ajax
170                    $form.validate();
171                    return $form.valid();
172                }
173            };
174            $form.data(data_validation, result);
175        }
176
177        return result;
178    }
179
180    $jQval.unobtrusive = {
181        adapters: [],
182
183        parseElement: function (element, skipAttach) {
184            /// <summary>
185            /// Parses a single HTML element for unobtrusive validation attributes.
186            /// </summary>
187            /// <param name="element" domElement="true">The HTML element to be parsed.</param>
188            /// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
189            /// validation to the form. If parsing just this single element, you should specify true.
190            /// If parsing several elements, you should specify false, and manually attach the validation
191            /// to the form when you are finished. The default is false.</param>
192            var $element = $(element),
193                form = $element.parents("form")[0],
194                valInfo, rules, messages;
195
196            if (!form) {  // Cannot do client-side validation without a form
197                return;
198            }
199
200            valInfo = validationInfo(form);
201            valInfo.options.rules[element.name] = rules = {};
202            valInfo.options.messages[element.name] = messages = {};
203
204            $.each(this.adapters, function () {
205                var prefix = "data-val-" + this.name,
206                    message = $element.attr(prefix),
207                    paramValues = {};
208
209                if (message !== undefined) {  // Compare against undefined, because an empty message is legal (and falsy)
210                    prefix += "-";
211
212                    $.each(this.params, function () {
213                        paramValues[this] = $element.attr(prefix + this);
214                    });
215
216                    this.adapt({
217                        element: element,
218                        form: form,
219                        message: message,
220                        params: paramValues,
221                        rules: rules,
222                        messages: messages
223                    });
224                }
225            });
226
227            $.extend(rules, { "__dummy__": true });
228
229            if (!skipAttach) {
230                valInfo.attachValidation();
231            }
232        },
233
234        parse: function (selector) {
235            /// <summary>
236            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
237            /// with the [data-val=true] attribute value and enables validation according to the data-val-*
238            /// attribute values.
239            /// </summary>
240            /// <param name="selector" type="String">Any valid jQuery selector.</param>
241
242            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
243            // element with data-val=true
244            var $selector = $(selector),
245                $forms = $selector.parents()
246                    .addBack()
247                    .filter("form")
248                    .add($selector.find("form"))
249                    .has("[data-val=true]");
250
251            $selector.find("[data-val=true]").each(function () {
252                $jQval.unobtrusive.parseElement(this, true);
253            });
254
255            $forms.each(function () {
256                var info = validationInfo(this);
257                if (info) {
258                    info.attachValidation();
259                }
260            });
261        }
262    };
263
264    adapters = $jQval.unobtrusive.adapters;
265
266    adapters.add = function (adapterName, params, fn) {
267        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
268        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
269        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
270        /// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
271        /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
272        /// mmmm is the parameter name).</param>
273        /// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
274        /// attributes into jQuery Validate rules and/or messages.</param>
275        /// <returns type="jQuery.validator.unobtrusive.adapters" />
276        if (!fn) {  // Called with no params, just a function
277            fn = params;
278            params = [];
279        }
280        this.push({ name: adapterName, params: params, adapt: fn });
281        return this;
282    };
283
284    adapters.addBool = function (adapterName, ruleName) {
285        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
286        /// the jQuery Validate validation rule has no parameter values.</summary>
287        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
288        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
289        /// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
290        /// of adapterName will be used instead.</param>
291        /// <returns type="jQuery.validator.unobtrusive.adapters" />
292        return this.add(adapterName, function (options) {
293            setValidationValues(options, ruleName || adapterName, true);
294        });
295    };
296
297    adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
298        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
299        /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
300        /// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
301        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
302        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
303        /// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
304        /// have a minimum value.</param>
305        /// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
306        /// have a maximum value.</param>
307        /// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
308        /// have both a minimum and maximum value.</param>
309        /// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
310        /// contains the minimum value. The default is "min".</param>
311        /// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
312        /// contains the maximum value. The default is "max".</param>
313        /// <returns type="jQuery.validator.unobtrusive.adapters" />
314        return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
315            var min = options.params.min,
316                max = options.params.max;
317
318            if (min && max) {
319                setValidationValues(options, minMaxRuleName, [min, max]);
320            }
321            else if (min) {
322                setValidationValues(options, minRuleName, min);
323            }
324            else if (max) {
325                setValidationValues(options, maxRuleName, max);
326            }
327        });
328    };
329
330    adapters.addSingleVal = function (adapterName, attribute, ruleName) {
331        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
332        /// the jQuery Validate validation rule has a single value.</summary>
333        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
334        /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
335        /// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
336        /// The default is "val".</param>
337        /// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
338        /// of adapterName will be used instead.</param>
339        /// <returns type="jQuery.validator.unobtrusive.adapters" />
340        return this.add(adapterName, [attribute || "val"], function (options) {
341            setValidationValues(options, ruleName || adapterName, options.params[attribute]);
342        });
343    };
344
345    $jQval.addMethod("__dummy__", function (value, element, params) {
346        return true;
347    });
348
349    $jQval.addMethod("regex", function (value, element, params) {
350        var match;
351        if (this.optional(element)) {
352            return true;
353        }
354
355        match = new RegExp(params).exec(value);
356        return (match && (match.index === 0) && (match[0].length === value.length));
357    });
358
359    $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
360        var match;
361        if (nonalphamin) {
362            match = value.match(/\W/g);
363            match = match && match.length >= nonalphamin;
364        }
365        return match;
366    });
367
368    if ($jQval.methods.extension) {
369        adapters.addSingleVal("accept", "mimtype");
370        adapters.addSingleVal("extension", "extension");
371    } else {
372        // for backward compatibility, when the 'extension' validation method does not exist, such as with versions
373        // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
374        // validating the extension, and ignore mime-type validations as they are not supported.
375        adapters.addSingleVal("extension", "extension", "accept");
376    }
377
378    adapters.addSingleVal("regex", "pattern");
379    adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
380    adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
381    adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
382    adapters.add("equalto", ["other"], function (options) {
383        var prefix = getModelPrefix(options.element.name),
384            other = options.params.other,
385            fullOtherName = appendModelPrefix(other, prefix),
386            element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
387
388        setValidationValues(options, "equalTo", element);
389    });
390    adapters.add("required", function (options) {
391        // jQuery Validate equates "required" with "mandatory" for checkbox elements
392        if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
393            setValidationValues(options, "required", true);
394        }
395    });
396    adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
397        var value = {
398            url: options.params.url,
399            type: options.params.type || "GET",
400            data: {}
401        },
402            prefix = getModelPrefix(options.element.name);
403
404        $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
405            var paramName = appendModelPrefix(fieldName, prefix);
406            value.data[paramName] = function () {
407                var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
408                // For checkboxes and radio buttons, only pick up values from checked fields.
409                if (field.is(":checkbox")) {
410                    return field.filter(":checked").val() || field.filter(":hidden").val() || '';
411                }
412                else if (field.is(":radio")) {
413                    return field.filter(":checked").val() || '';
414                }
415                return field.val();
416            };
417        });
418
419        setValidationValues(options, "remote", value);
420    });
421    adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
422        if (options.params.min) {
423            setValidationValues(options, "minlength", options.params.min);
424        }
425        if (options.params.nonalphamin) {
426            setValidationValues(options, "nonalphamin", options.params.nonalphamin);
427        }
428        if (options.params.regex) {
429            setValidationValues(options, "regex", options.params.regex);
430        }
431    });
432    adapters.add("fileextensions", ["extensions"], function (options) {
433        setValidationValues(options, "extension", options.params.extensions);
434    });
435
436    $(function () {
437        $jQval.unobtrusive.parse(document);
438    });
439
440    return $jQval.unobtrusive;
441}));
442
443
444/***/ }),
445
vendor: 52,887 bytes, lines 446-2154
446/***/ "./node_modules/jquery-validation/dist/jquery.validate.js":
447/*!****************************************************************!*\
448  !*** ./node_modules/jquery-validation/dist/jquery.validate.js ***!
449  \****************************************************************/
450/***/ ((module, exports, __webpack_require__) => {
451
452var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
453 * jQuery Validation Plugin v1.20.1
454 *
455 * https://jqueryvalidation.org/
456 *
457 * Copyright (c) 2024 Jörn Zaefferer
458 * Released under the MIT license
459 */
460(function( factory ) {
461	if ( true ) {
462		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
463		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
464		(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
465		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
466	} else {}
467}(function( $ ) {
468
469$.extend( $.fn, {
470
471	// https://jqueryvalidation.org/validate/
472	validate: function( options ) {
473
474		// If nothing is selected, return nothing; can't chain anyway
475		if ( !this.length ) {
476			if ( options && options.debug && window.console ) {
477				console.warn( "Nothing selected, can't validate, returning nothing." );
478			}
479			return;
480		}
481
482		// Check if a validator for this form was already created
483		var validator = $.data( this[ 0 ], "validator" );
484		if ( validator ) {
485			return validator;
486		}
487
488		// Add novalidate tag if HTML5.
489		this.attr( "novalidate", "novalidate" );
490
491		validator = new $.validator( options, this[ 0 ] );
492		$.data( this[ 0 ], "validator", validator );
493
494		if ( validator.settings.onsubmit ) {
495
496			this.on( "click.validate", ":submit", function( event ) {
497
498				// Track the used submit button to properly handle scripted
499				// submits later.
500				validator.submitButton = event.currentTarget;
501
502				// Allow suppressing validation by adding a cancel class to the submit button
503				if ( $( this ).hasClass( "cancel" ) ) {
504					validator.cancelSubmit = true;
505				}
506
507				// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
508				if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
509					validator.cancelSubmit = true;
510				}
511			} );
512
513			// Validate the form on submit
514			this.on( "submit.validate", function( event ) {
515				if ( validator.settings.debug ) {
516
517					// Prevent form submit to be able to see console output
518					event.preventDefault();
519				}
520
521				function handle() {
522					var hidden, result;
523
524					// Insert a hidden input as a replacement for the missing submit button
525					// The hidden input is inserted in two cases:
526					//   - A user defined a `submitHandler`
527					//   - There was a pending request due to `remote` method and `stopRequest()`
528					//     was called to submit the form in case it's valid
529					if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
530						hidden = $( "<input type='hidden'/>" )
531							.attr( "name", validator.submitButton.name )
532							.val( $( validator.submitButton ).val() )
533							.appendTo( validator.currentForm );
534					}
535
536					if ( validator.settings.submitHandler && !validator.settings.debug ) {
537						result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
538						if ( hidden ) {
539
540							// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
541							hidden.remove();
542						}
543						if ( result !== undefined ) {
544							return result;
545						}
546						return false;
547					}
548					return true;
549				}
550
551				// Prevent submit for invalid forms or custom submit handlers
552				if ( validator.cancelSubmit ) {
553					validator.cancelSubmit = false;
554					return handle();
555				}
556				if ( validator.form() ) {
557					if ( validator.pendingRequest ) {
558						validator.formSubmitted = true;
559						return false;
560					}
561					return handle();
562				} else {
563					validator.focusInvalid();
564					return false;
565				}
566			} );
567		}
568
569		return validator;
570	},
571
572	// https://jqueryvalidation.org/valid/
573	valid: function() {
574		var valid, validator, errorList;
575
576		if ( $( this[ 0 ] ).is( "form" ) ) {
577			valid = this.validate().form();
578		} else {
579			errorList = [];
580			valid = true;
581			validator = $( this[ 0 ].form ).validate();
582			this.each( function() {
583				valid = validator.element( this ) && valid;
584				if ( !valid ) {
585					errorList = errorList.concat( validator.errorList );
586				}
587			} );
588			validator.errorList = errorList;
589		}
590		return valid;
591	},
592
593	// https://jqueryvalidation.org/rules/
594	rules: function( command, argument ) {
595		var element = this[ 0 ],
596			isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false",
597			settings, staticRules, existingRules, data, param, filtered;
598
599		// If nothing is selected, return empty object; can't chain anyway
600		if ( element == null ) {
601			return;
602		}
603
604		if ( !element.form && isContentEditable ) {
605			element.form = this.closest( "form" )[ 0 ];
606			element.name = this.attr( "name" );
607		}
608
609		if ( element.form == null ) {
610			return;
611		}
612
613		if ( command ) {
614			settings = $.data( element.form, "validator" ).settings;
615			staticRules = settings.rules;
616			existingRules = $.validator.staticRules( element );
617			switch ( command ) {
618			case "add":
619				$.extend( existingRules, $.validator.normalizeRule( argument ) );
620
621				// Remove messages from rules, but allow them to be set separately
622				delete existingRules.messages;
623				staticRules[ element.name ] = existingRules;
624				if ( argument.messages ) {
625					settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
626				}
627				break;
628			case "remove":
629				if ( !argument ) {
630					delete staticRules[ element.name ];
631					return existingRules;
632				}
633				filtered = {};
634				$.each( argument.split( /\s/ ), function( index, method ) {
635					filtered[ method ] = existingRules[ method ];
636					delete existingRules[ method ];
637				} );
638				return filtered;
639			}
640		}
641
642		data = $.validator.normalizeRules(
643		$.extend(
644			{},
645			$.validator.classRules( element ),
646			$.validator.attributeRules( element ),
647			$.validator.dataRules( element ),
648			$.validator.staticRules( element )
649		), element );
650
651		// Make sure required is at front
652		if ( data.required ) {
653			param = data.required;
654			delete data.required;
655			data = $.extend( { required: param }, data );
656		}
657
658		// Make sure remote is at back
659		if ( data.remote ) {
660			param = data.remote;
661			delete data.remote;
662			data = $.extend( data, { remote: param } );
663		}
664
665		return data;
666	}
667} );
668
669// JQuery trim is deprecated, provide a trim method based on String.prototype.trim
670var trim = function( str ) {
671
672	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
673	return str.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "" );
674};
675
676// Custom selectors
677$.extend( $.expr.pseudos || $.expr[ ":" ], {		// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
678
679	// https://jqueryvalidation.org/blank-selector/
680	blank: function( a ) {
681		return !trim( "" + $( a ).val() );
682	},
683
684	// https://jqueryvalidation.org/filled-selector/
685	filled: function( a ) {
686		var val = $( a ).val();
687		return val !== null && !!trim( "" + val );
688	},
689
690	// https://jqueryvalidation.org/unchecked-selector/
691	unchecked: function( a ) {
692		return !$( a ).prop( "checked" );
693	}
694} );
695
696// Constructor for validator
697$.validator = function( options, form ) {
698	this.settings = $.extend( true, {}, $.validator.defaults, options );
699	this.currentForm = form;
700	this.init();
701};
702
703// https://jqueryvalidation.org/jQuery.validator.format/
704$.validator.format = function( source, params ) {
705	if ( arguments.length === 1 ) {
706		return function() {
707			var args = $.makeArray( arguments );
708			args.unshift( source );
709			return $.validator.format.apply( this, args );
710		};
711	}
712	if ( params === undefined ) {
713		return source;
714	}
715	if ( arguments.length > 2 && params.constructor !== Array  ) {
716		params = $.makeArray( arguments ).slice( 1 );
717	}
718	if ( params.constructor !== Array ) {
719		params = [ params ];
720	}
721	$.each( params, function( i, n ) {
722		source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
723			return n;
724		} );
725	} );
726	return source;
727};
728
729$.extend( $.validator, {
730
731	defaults: {
732		messages: {},
733		groups: {},
734		rules: {},
735		errorClass: "error",
736		pendingClass: "pending",
737		validClass: "valid",
738		errorElement: "label",
739		focusCleanup: false,
740		focusInvalid: true,
741		errorContainer: $( [] ),
742		errorLabelContainer: $( [] ),
743		onsubmit: true,
744		ignore: ":hidden",
745		ignoreTitle: false,
746		onfocusin: function( element ) {
747			this.lastActive = element;
748
749			// Hide error label and remove error class on focus if enabled
750			if ( this.settings.focusCleanup ) {
751				if ( this.settings.unhighlight ) {
752					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
753				}
754				this.hideThese( this.errorsFor( element ) );
755			}
756		},
757		onfocusout: function( element ) {
758			if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
759				this.element( element );
760			}
761		},
762		onkeyup: function( element, event ) {
763
764			// Avoid revalidate the field when pressing one of the following keys
765			// Shift       => 16
766			// Ctrl        => 17
767			// Alt         => 18
768			// Caps lock   => 20
769			// End         => 35
770			// Home        => 36
771			// Left arrow  => 37
772			// Up arrow    => 38
773			// Right arrow => 39
774			// Down arrow  => 40
775			// Insert      => 45
776			// Num lock    => 144
777			// AltGr key   => 225
778			var excludedKeys = [
779				16, 17, 18, 20, 35, 36, 37,
780				38, 39, 40, 45, 144, 225
781			];
782
783			if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
784				return;
785			} else if ( element.name in this.submitted || element.name in this.invalid ) {
786				this.element( element );
787			}
788		},
789		onclick: function( element ) {
790
791			// Click on selects, radiobuttons and checkboxes
792			if ( element.name in this.submitted ) {
793				this.element( element );
794
795			// Or option elements, check parent select in that case
796			} else if ( element.parentNode.name in this.submitted ) {
797				this.element( element.parentNode );
798			}
799		},
800		highlight: function( element, errorClass, validClass ) {
801			if ( element.type === "radio" ) {
802				this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
803			} else {
804				$( element ).addClass( errorClass ).removeClass( validClass );
805			}
806		},
807		unhighlight: function( element, errorClass, validClass ) {
808			if ( element.type === "radio" ) {
809				this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
810			} else {
811				$( element ).removeClass( errorClass ).addClass( validClass );
812			}
813		}
814	},
815
816	// https://jqueryvalidation.org/jQuery.validator.setDefaults/
817	setDefaults: function( settings ) {
818		$.extend( $.validator.defaults, settings );
819	},
820
821	messages: {
822		required: "This field is required.",
823		remote: "Please fix this field.",
824		email: "Please enter a valid email address.",
825		url: "Please enter a valid URL.",
826		date: "Please enter a valid date.",
827		dateISO: "Please enter a valid date (ISO).",
828		number: "Please enter a valid number.",
829		digits: "Please enter only digits.",
830		equalTo: "Please enter the same value again.",
831		maxlength: $.validator.format( "Please enter no more than {0} characters." ),
832		minlength: $.validator.format( "Please enter at least {0} characters." ),
833		rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
834		range: $.validator.format( "Please enter a value between {0} and {1}." ),
835		max: $.validator.format( "Please enter a value less than or equal to {0}." ),
836		min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
837		step: $.validator.format( "Please enter a multiple of {0}." )
838	},
839
840	autoCreateRanges: false,
841
842	prototype: {
843
844		init: function() {
845			this.labelContainer = $( this.settings.errorLabelContainer );
846			this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
847			this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
848			this.submitted = {};
849			this.valueCache = {};
850			this.pendingRequest = 0;
851			this.pending = {};
852			this.invalid = {};
853			this.reset();
854
855			var currentForm = this.currentForm,
856				groups = ( this.groups = {} ),
857				rules;
858			$.each( this.settings.groups, function( key, value ) {
859				if ( typeof value === "string" ) {
860					value = value.split( /\s/ );
861				}
862				$.each( value, function( index, name ) {
863					groups[ name ] = key;
864				} );
865			} );
866			rules = this.settings.rules;
867			$.each( rules, function( key, value ) {
868				rules[ key ] = $.validator.normalizeRule( value );
869			} );
870
871			function delegate( event ) {
872				var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
873
874				// Set form expando on contenteditable
875				if ( !this.form && isContentEditable ) {
876					this.form = $( this ).closest( "form" )[ 0 ];
877					this.name = $( this ).attr( "name" );
878				}
879
880				// Ignore the element if it belongs to another form. This will happen mainly
881				// when setting the `form` attribute of an input to the id of another form.
882				if ( currentForm !== this.form ) {
883					return;
884				}
885
886				var validator = $.data( this.form, "validator" ),
887					eventType = "on" + event.type.replace( /^validate/, "" ),
888					settings = validator.settings;
889				if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
890					settings[ eventType ].call( validator, this, event );
891				}
892			}
893
894			$( this.currentForm )
895				.on( "focusin.validate focusout.validate keyup.validate",
896					":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
897					"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
898					"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
899					"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
900
901				// Support: Chrome, oldIE
902				// "select" is provided as event.target when clicking a option
903				.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
904
905			if ( this.settings.invalidHandler ) {
906				$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
907			}
908		},
909
910		// https://jqueryvalidation.org/Validator.form/
911		form: function() {
912			this.checkForm();
913			$.extend( this.submitted, this.errorMap );
914			this.invalid = $.extend( {}, this.errorMap );
915			if ( !this.valid() ) {
916				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
917			}
918			this.showErrors();
919			return this.valid();
920		},
921
922		checkForm: function() {
923			this.prepareForm();
924			for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
925				this.check( elements[ i ] );
926			}
927			return this.valid();
928		},
929
930		// https://jqueryvalidation.org/Validator.element/
931		element: function( element ) {
932			var cleanElement = this.clean( element ),
933				checkElement = this.validationTargetFor( cleanElement ),
934				v = this,
935				result = true,
936				rs, group;
937
938			if ( checkElement === undefined ) {
939				delete this.invalid[ cleanElement.name ];
940			} else {
941				this.prepareElement( checkElement );
942				this.currentElements = $( checkElement );
943
944				// If this element is grouped, then validate all group elements already
945				// containing a value
946				group = this.groups[ checkElement.name ];
947				if ( group ) {
948					$.each( this.groups, function( name, testgroup ) {
949						if ( testgroup === group && name !== checkElement.name ) {
950							cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
951							if ( cleanElement && cleanElement.name in v.invalid ) {
952								v.currentElements.push( cleanElement );
953								result = v.check( cleanElement ) && result;
954							}
955						}
956					} );
957				}
958
959				rs = this.check( checkElement ) !== false;
960				result = result && rs;
961				if ( rs ) {
962					this.invalid[ checkElement.name ] = false;
963				} else {
964					this.invalid[ checkElement.name ] = true;
965				}
966
967				if ( !this.numberOfInvalids() ) {
968
969					// Hide error containers on last error
970					this.toHide = this.toHide.add( this.containers );
971				}
972				this.showErrors();
973
974				// Add aria-invalid status for screen readers
975				$( element ).attr( "aria-invalid", !rs );
976			}
977
978			return result;
979		},
980
981		// https://jqueryvalidation.org/Validator.showErrors/
982		showErrors: function( errors ) {
983			if ( errors ) {
984				var validator = this;
985
986				// Add items to error list and map
987				$.extend( this.errorMap, errors );
988				this.errorList = $.map( this.errorMap, function( message, name ) {
989					return {
990						message: message,
991						element: validator.findByName( name )[ 0 ]
992					};
993				} );
994
995				// Remove items from success list
996				this.successList = $.grep( this.successList, function( element ) {
997					return !( element.name in errors );
998				} );
999			}
1000			if ( this.settings.showErrors ) {
1001				this.settings.showErrors.call( this, this.errorMap, this.errorList );
1002			} else {
1003				this.defaultShowErrors();
1004			}
1005		},
1006
1007		// https://jqueryvalidation.org/Validator.resetForm/
1008		resetForm: function() {
1009			if ( $.fn.resetForm ) {
1010				$( this.currentForm ).resetForm();
1011			}
1012			this.invalid = {};
1013			this.submitted = {};
1014			this.prepareForm();
1015			this.hideErrors();
1016			var elements = this.elements()
1017				.removeData( "previousValue" )
1018				.removeAttr( "aria-invalid" );
1019
1020			this.resetElements( elements );
1021		},
1022
1023		resetElements: function( elements ) {
1024			var i;
1025
1026			if ( this.settings.unhighlight ) {
1027				for ( i = 0; elements[ i ]; i++ ) {
1028					this.settings.unhighlight.call( this, elements[ i ],
1029						this.settings.errorClass, "" );
1030					this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
1031				}
1032			} else {
1033				elements
1034					.removeClass( this.settings.errorClass )
1035					.removeClass( this.settings.validClass );
1036			}
1037		},
1038
1039		numberOfInvalids: function() {
1040			return this.objectLength( this.invalid );
1041		},
1042
1043		objectLength: function( obj ) {
1044			/* jshint unused: false */
1045			var count = 0,
1046				i;
1047			for ( i in obj ) {
1048
1049				// This check allows counting elements with empty error
1050				// message as invalid elements
1051				if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
1052					count++;
1053				}
1054			}
1055			return count;
1056		},
1057
1058		hideErrors: function() {
1059			this.hideThese( this.toHide );
1060		},
1061
1062		hideThese: function( errors ) {
1063			errors.not( this.containers ).text( "" );
1064			this.addWrapper( errors ).hide();
1065		},
1066
1067		valid: function() {
1068			return this.size() === 0;
1069		},
1070
1071		size: function() {
1072			return this.errorList.length;
1073		},
1074
1075		focusInvalid: function() {
1076			if ( this.settings.focusInvalid ) {
1077				try {
1078					$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
1079					.filter( ":visible" )
1080					.trigger( "focus" )
1081
1082					// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
1083					.trigger( "focusin" );
1084				} catch ( e ) {
1085
1086					// Ignore IE throwing errors when focusing hidden elements
1087				}
1088			}
1089		},
1090
1091		findLastActive: function() {
1092			var lastActive = this.lastActive;
1093			return lastActive && $.grep( this.errorList, function( n ) {
1094				return n.element.name === lastActive.name;
1095			} ).length === 1 && lastActive;
1096		},
1097
1098		elements: function() {
1099			var validator = this,
1100				rulesCache = {};
1101
1102			// Select all valid inputs inside the form (no submit or reset buttons)
1103			return $( this.currentForm )
1104			.find( "input, select, textarea, [contenteditable]" )
1105			.not( ":submit, :reset, :image, :disabled" )
1106			.not( this.settings.ignore )
1107			.filter( function() {
1108				var name = this.name || $( this ).attr( "name" ); // For contenteditable
1109				var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
1110
1111				if ( !name && validator.settings.debug && window.console ) {
1112					console.error( "%o has no name assigned", this );
1113				}
1114
1115				// Set form expando on contenteditable
1116				if ( isContentEditable ) {
1117					this.form = $( this ).closest( "form" )[ 0 ];
1118					this.name = name;
1119				}
1120
1121				// Ignore elements that belong to other/nested forms
1122				if ( this.form !== validator.currentForm ) {
1123					return false;
1124				}
1125
1126				// Select only the first element for each name, and only those with rules specified
1127				if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
1128					return false;
1129				}
1130
1131				rulesCache[ name ] = true;
1132				return true;
1133			} );
1134		},
1135
1136		clean: function( selector ) {
1137			return $( selector )[ 0 ];
1138		},
1139
1140		errors: function() {
1141			var errorClass = this.settings.errorClass.split( " " ).join( "." );
1142			return $( this.settings.errorElement + "." + errorClass, this.errorContext );
1143		},
1144
1145		resetInternals: function() {
1146			this.successList = [];
1147			this.errorList = [];
1148			this.errorMap = {};
1149			this.toShow = $( [] );
1150			this.toHide = $( [] );
1151		},
1152
1153		reset: function() {
1154			this.resetInternals();
1155			this.currentElements = $( [] );
1156		},
1157
1158		prepareForm: function() {
1159			this.reset();
1160			this.toHide = this.errors().add( this.containers );
1161		},
1162
1163		prepareElement: function( element ) {
1164			this.reset();
1165			this.toHide = this.errorsFor( element );
1166		},
1167
1168		elementValue: function( element ) {
1169			var $element = $( element ),
1170				type = element.type,
1171				isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false",
1172				val, idx;
1173
1174			if ( type === "radio" || type === "checkbox" ) {
1175				return this.findByName( element.name ).filter( ":checked" ).val();
1176			} else if ( type === "number" && typeof element.validity !== "undefined" ) {
1177				return element.validity.badInput ? "NaN" : $element.val();
1178			}
1179
1180			if ( isContentEditable ) {
1181				val = $element.text();
1182			} else {
1183				val = $element.val();
1184			}
1185
1186			if ( type === "file" ) {
1187
1188				// Modern browser (chrome & safari)
1189				if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
1190					return val.substr( 12 );
1191				}
1192
1193				// Legacy browsers
1194				// Unix-based path
1195				idx = val.lastIndexOf( "/" );
1196				if ( idx >= 0 ) {
1197					return val.substr( idx + 1 );
1198				}
1199
1200				// Windows-based path
1201				idx = val.lastIndexOf( "\\" );
1202				if ( idx >= 0 ) {
1203					return val.substr( idx + 1 );
1204				}
1205
1206				// Just the file name
1207				return val;
1208			}
1209
1210			if ( typeof val === "string" ) {
1211				return val.replace( /\r/g, "" );
1212			}
1213			return val;
1214		},
1215
1216		check: function( element ) {
1217			element = this.validationTargetFor( this.clean( element ) );
1218
1219			var rules = $( element ).rules(),
1220				rulesCount = $.map( rules, function( n, i ) {
1221					return i;
1222				} ).length,
1223				dependencyMismatch = false,
1224				val = this.elementValue( element ),
1225				result, method, rule, normalizer;
1226
1227			// Abort any pending Ajax request from a previous call to this method.
1228			this.abortRequest( element );
1229
1230			// Prioritize the local normalizer defined for this element over the global one
1231			// if the former exists, otherwise user the global one in case it exists.
1232			if ( typeof rules.normalizer === "function" ) {
1233				normalizer = rules.normalizer;
1234			} else if (	typeof this.settings.normalizer === "function" ) {
1235				normalizer = this.settings.normalizer;
1236			}
1237
1238			// If normalizer is defined, then call it to retreive the changed value instead
1239			// of using the real one.
1240			// Note that `this` in the normalizer is `element`.
1241			if ( normalizer ) {
1242				val = normalizer.call( element, val );
1243
1244				// Delete the normalizer from rules to avoid treating it as a pre-defined method.
1245				delete rules.normalizer;
1246			}
1247
1248			for ( method in rules ) {
1249				rule = { method: method, parameters: rules[ method ] };
1250				try {
1251					result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
1252
1253					// If a method indicates that the field is optional and therefore valid,
1254					// don't mark it as valid when there are no other rules
1255					if ( result === "dependency-mismatch" && rulesCount === 1 ) {
1256						dependencyMismatch = true;
1257						continue;
1258					}
1259					dependencyMismatch = false;
1260
1261					if ( result === "pending" ) {
1262						this.toHide = this.toHide.not( this.errorsFor( element ) );
1263						return;
1264					}
1265
1266					if ( !result ) {
1267						this.formatAndAdd( element, rule );
1268						return false;
1269					}
1270				} catch ( e ) {
1271					if ( this.settings.debug && window.console ) {
1272						console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
1273					}
1274					if ( e instanceof TypeError ) {
1275						e.message += ".  Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
1276					}
1277
1278					throw e;
1279				}
1280			}
1281			if ( dependencyMismatch ) {
1282				return;
1283			}
1284			if ( this.objectLength( rules ) ) {
1285				this.successList.push( element );
1286			}
1287			return true;
1288		},
1289
1290		// Return the custom message for the given element and validation method
1291		// specified in the element's HTML5 data attribute
1292		// return the generic message if present and no method specific message is present
1293		customDataMessage: function( element, method ) {
1294			return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
1295				method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
1296		},
1297
1298		// Return the custom message for the given element name and validation method
1299		customMessage: function( name, method ) {
1300			var m = this.settings.messages[ name ];
1301			return m && ( m.constructor === String ? m : m[ method ] );
1302		},
1303
1304		// Return the first defined argument, allowing empty strings
1305		findDefined: function() {
1306			for ( var i = 0; i < arguments.length; i++ ) {
1307				if ( arguments[ i ] !== undefined ) {
1308					return arguments[ i ];
1309				}
1310			}
1311			return undefined;
1312		},
1313
1314		// The second parameter 'rule' used to be a string, and extended to an object literal
1315		// of the following form:
1316		// rule = {
1317		//     method: "method name",
1318		//     parameters: "the given method parameters"
1319		// }
1320		//
1321		// The old behavior still supported, kept to maintain backward compatibility with
1322		// old code, and will be removed in the next major release.
1323		defaultMessage: function( element, rule ) {
1324			if ( typeof rule === "string" ) {
1325				rule = { method: rule };
1326			}
1327
1328			var message = this.findDefined(
1329					this.customMessage( element.name, rule.method ),
1330					this.customDataMessage( element, rule.method ),
1331
1332					// 'title' is never undefined, so handle empty string as undefined
1333					!this.settings.ignoreTitle && element.title || undefined,
1334					$.validator.messages[ rule.method ],
1335					"<strong>Warning: No message defined for " + element.name + "</strong>"
1336				),
1337				theregex = /\$?\{(\d+)\}/g;
1338			if ( typeof message === "function" ) {
1339				message = message.call( this, rule.parameters, element );
1340			} else if ( theregex.test( message ) ) {
1341				message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
1342			}
1343
1344			return message;
1345		},
1346
1347		formatAndAdd: function( element, rule ) {
1348			var message = this.defaultMessage( element, rule );
1349
1350			this.errorList.push( {
1351				message: message,
1352				element: element,
1353				method: rule.method
1354			} );
1355
1356			this.errorMap[ element.name ] = message;
1357			this.submitted[ element.name ] = message;
1358		},
1359
1360		addWrapper: function( toToggle ) {
1361			if ( this.settings.wrapper ) {
1362				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
1363			}
1364			return toToggle;
1365		},
1366
1367		defaultShowErrors: function() {
1368			var i, elements, error;
1369			for ( i = 0; this.errorList[ i ]; i++ ) {
1370				error = this.errorList[ i ];
1371				if ( this.settings.highlight ) {
1372					this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
1373				}
1374				this.showLabel( error.element, error.message );
1375			}
1376			if ( this.errorList.length ) {
1377				this.toShow = this.toShow.add( this.containers );
1378			}
1379			if ( this.settings.success ) {
1380				for ( i = 0; this.successList[ i ]; i++ ) {
1381					this.showLabel( this.successList[ i ] );
1382				}
1383			}
1384			if ( this.settings.unhighlight ) {
1385				for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
1386					this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
1387				}
1388			}
1389			this.toHide = this.toHide.not( this.toShow );
1390			this.hideErrors();
1391			this.addWrapper( this.toShow ).show();
1392		},
1393
1394		validElements: function() {
1395			return this.currentElements.not( this.invalidElements() );
1396		},
1397
1398		invalidElements: function() {
1399			return $( this.errorList ).map( function() {
1400				return this.element;
1401			} );
1402		},
1403
1404		showLabel: function( element, message ) {
1405			var place, group, errorID, v,
1406				error = this.errorsFor( element ),
1407				elementID = this.idOrName( element ),
1408				describedBy = $( element ).attr( "aria-describedby" );
1409
1410			if ( error.length ) {
1411
1412				// Refresh error/success class
1413				error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
1414
1415				// Replace message on existing label
1416				if ( this.settings && this.settings.escapeHtml ) {
1417					error.text( message || "" );
1418				} else {
1419					error.html( message || "" );
1420				}
1421			} else {
1422
1423				// Create error element
1424				error = $( "<" + this.settings.errorElement + ">" )
1425					.attr( "id", elementID + "-error" )
1426					.addClass( this.settings.errorClass );
1427
1428				if ( this.settings && this.settings.escapeHtml ) {
1429					error.text( message || "" );
1430				} else {
1431					error.html( message || "" );
1432				}
1433
1434				// Maintain reference to the element to be placed into the DOM
1435				place = error;
1436				if ( this.settings.wrapper ) {
1437
1438					// Make sure the element is visible, even in IE
1439					// actually showing the wrapped element is handled elsewhere
1440					place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
1441				}
1442				if ( this.labelContainer.length ) {
1443					this.labelContainer.append( place );
1444				} else if ( this.settings.errorPlacement ) {
1445					this.settings.errorPlacement.call( this, place, $( element ) );
1446				} else {
1447					place.insertAfter( element );
1448				}
1449
1450				// Link error back to the element
1451				if ( error.is( "label" ) ) {
1452
1453					// If the error is a label, then associate using 'for'
1454					error.attr( "for", elementID );
1455
1456					// If the element is not a child of an associated label, then it's necessary
1457					// to explicitly apply aria-describedby
1458				} else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
1459					errorID = error.attr( "id" );
1460
1461					// Respect existing non-error aria-describedby
1462					if ( !describedBy ) {
1463						describedBy = errorID;
1464					} else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
1465
1466						// Add to end of list if not already present
1467						describedBy += " " + errorID;
1468					}
1469					$( element ).attr( "aria-describedby", describedBy );
1470
1471					// If this element is grouped, then assign to all elements in the same group
1472					group = this.groups[ element.name ];
1473					if ( group ) {
1474						v = this;
1475						$.each( v.groups, function( name, testgroup ) {
1476							if ( testgroup === group ) {
1477								$( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
1478									.attr( "aria-describedby", error.attr( "id" ) );
1479							}
1480						} );
1481					}
1482				}
1483			}
1484			if ( !message && this.settings.success ) {
1485				error.text( "" );
1486				if ( typeof this.settings.success === "string" ) {
1487					error.addClass( this.settings.success );
1488				} else {
1489					this.settings.success( error, element );
1490				}
1491			}
1492			this.toShow = this.toShow.add( error );
1493		},
1494
1495		errorsFor: function( element ) {
1496			var name = this.escapeCssMeta( this.idOrName( element ) ),
1497				describer = $( element ).attr( "aria-describedby" ),
1498				selector = "label[for='" + name + "'], label[for='" + name + "'] *";
1499
1500			// 'aria-describedby' should directly reference the error element
1501			if ( describer ) {
1502				selector = selector + ", #" + this.escapeCssMeta( describer )
1503					.replace( /\s+/g, ", #" );
1504			}
1505
1506			return this
1507				.errors()
1508				.filter( selector );
1509		},
1510
1511		// See https://api.jquery.com/category/selectors/, for CSS
1512		// meta-characters that should be escaped in order to be used with JQuery
1513		// as a literal part of a name/id or any selector.
1514		escapeCssMeta: function( string ) {
1515			if ( string === undefined ) {
1516				return "";
1517			}
1518
1519			return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
1520		},
1521
1522		idOrName: function( element ) {
1523			return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
1524		},
1525
1526		validationTargetFor: function( element ) {
1527
1528			// If radio/checkbox, validate first element in group instead
1529			if ( this.checkable( element ) ) {
1530				element = this.findByName( element.name );
1531			}
1532
1533			// Always apply ignore filter
1534			return $( element ).not( this.settings.ignore )[ 0 ];
1535		},
1536
1537		checkable: function( element ) {
1538			return ( /radio|checkbox/i ).test( element.type );
1539		},
1540
1541		findByName: function( name ) {
1542			return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
1543		},
1544
1545		getLength: function( value, element ) {
1546			switch ( element.nodeName.toLowerCase() ) {
1547			case "select":
1548				return $( "option:selected", element ).length;
1549			case "input":
1550				if ( this.checkable( element ) ) {
1551					return this.findByName( element.name ).filter( ":checked" ).length;
1552				}
1553			}
1554			return value.length;
1555		},
1556
1557		depend: function( param, element ) {
1558			return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
1559		},
1560
1561		dependTypes: {
1562			"boolean": function( param ) {
1563				return param;
1564			},
1565			"string": function( param, element ) {
1566				return !!$( param, element.form ).length;
1567			},
1568			"function": function( param, element ) {
1569				return param( element );
1570			}
1571		},
1572
1573		optional: function( element ) {
1574			var val = this.elementValue( element );
1575			return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
1576		},
1577
1578		elementAjaxPort: function( element ) {
1579			return "validate" + element.name;
1580		},
1581
1582		startRequest: function( element ) {
1583			if ( !this.pending[ element.name ] ) {
1584				this.pendingRequest++;
1585				$( element ).addClass( this.settings.pendingClass );
1586				this.pending[ element.name ] = true;
1587			}
1588		},
1589
1590		stopRequest: function( element, valid ) {
1591			this.pendingRequest--;
1592
1593			// Sometimes synchronization fails, make sure pendingRequest is never < 0
1594			if ( this.pendingRequest < 0 ) {
1595				this.pendingRequest = 0;
1596			}
1597			delete this.pending[ element.name ];
1598			$( element ).removeClass( this.settings.pendingClass );
1599			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) {
1600				$( this.currentForm ).trigger( "submit" );
1601
1602				// Remove the hidden input that was used as a replacement for the
1603				// missing submit button. The hidden input is added by `handle()`
1604				// to ensure that the value of the used submit button is passed on
1605				// for scripted submits triggered by this method
1606				if ( this.submitButton ) {
1607					$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
1608				}
1609
1610				this.formSubmitted = false;
1611			} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
1612				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
1613				this.formSubmitted = false;
1614			}
1615		},
1616
1617		abortRequest: function( element ) {
1618			var port;
1619
1620			if ( this.pending[ element.name ] ) {
1621				port = this.elementAjaxPort( element );
1622				$.ajaxAbort( port );
1623
1624				this.pendingRequest--;
1625
1626				// Sometimes synchronization fails, make sure pendingRequest is never < 0
1627				if ( this.pendingRequest < 0 ) {
1628					this.pendingRequest = 0;
1629				}
1630
1631				delete this.pending[ element.name ];
1632				$( element ).removeClass( this.settings.pendingClass );
1633			}
1634		},
1635
1636		previousValue: function( element, method ) {
1637			method = typeof method === "string" && method || "remote";
1638
1639			return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
1640				old: null,
1641				valid: true,
1642				message: this.defaultMessage( element, { method: method } )
1643			} );
1644		},
1645
1646		// Cleans up all forms and elements, removes validator-specific events
1647		destroy: function() {
1648			this.resetForm();
1649
1650			$( this.currentForm )
1651				.off( ".validate" )
1652				.removeData( "validator" )
1653				.find( ".validate-equalTo-blur" )
1654					.off( ".validate-equalTo" )
1655					.removeClass( "validate-equalTo-blur" )
1656				.find( ".validate-lessThan-blur" )
1657					.off( ".validate-lessThan" )
1658					.removeClass( "validate-lessThan-blur" )
1659				.find( ".validate-lessThanEqual-blur" )
1660					.off( ".validate-lessThanEqual" )
1661					.removeClass( "validate-lessThanEqual-blur" )
1662				.find( ".validate-greaterThanEqual-blur" )
1663					.off( ".validate-greaterThanEqual" )
1664					.removeClass( "validate-greaterThanEqual-blur" )
1665				.find( ".validate-greaterThan-blur" )
1666					.off( ".validate-greaterThan" )
1667					.removeClass( "validate-greaterThan-blur" );
1668		}
1669
1670	},
1671
1672	classRuleSettings: {
1673		required: { required: true },
1674		email: { email: true },
1675		url: { url: true },
1676		date: { date: true },
1677		dateISO: { dateISO: true },
1678		number: { number: true },
1679		digits: { digits: true },
1680		creditcard: { creditcard: true }
1681	},
1682
1683	addClassRules: function( className, rules ) {
1684		if ( className.constructor === String ) {
1685			this.classRuleSettings[ className ] = rules;
1686		} else {
1687			$.extend( this.classRuleSettings, className );
1688		}
1689	},
1690
1691	classRules: function( element ) {
1692		var rules = {},
1693			classes = $( element ).attr( "class" );
1694
1695		if ( classes ) {
1696			$.each( classes.split( " " ), function() {
1697				if ( this in $.validator.classRuleSettings ) {
1698					$.extend( rules, $.validator.classRuleSettings[ this ] );
1699				}
1700			} );
1701		}
1702		return rules;
1703	},
1704
1705	normalizeAttributeRule: function( rules, type, method, value ) {
1706
1707		// Convert the value to a number for number inputs, and for text for backwards compability
1708		// allows type="date" and others to be compared as strings
1709		if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
1710			value = Number( value );
1711
1712			// Support Opera Mini, which returns NaN for undefined minlength
1713			if ( isNaN( value ) ) {
1714				value = undefined;
1715			}
1716		}
1717
1718		if ( value || value === 0 ) {
1719			rules[ method ] = value;
1720		} else if ( type === method && type !== "range" ) {
1721
1722			// Exception: the jquery validate 'range' method
1723			// does not test for the html5 'range' type
1724			rules[ type === "date" ? "dateISO" : method ] = true;
1725		}
1726	},
1727
1728	attributeRules: function( element ) {
1729		var rules = {},
1730			$element = $( element ),
1731			type = element.getAttribute( "type" ),
1732			method, value;
1733
1734		for ( method in $.validator.methods ) {
1735
1736			// Support for <input required> in both html5 and older browsers
1737			if ( method === "required" ) {
1738				value = element.getAttribute( method );
1739
1740				// Some browsers return an empty string for the required attribute
1741				// and non-HTML5 browsers might have required="" markup
1742				if ( value === "" ) {
1743					value = true;
1744				}
1745
1746				// Force non-HTML5 browsers to return bool
1747				value = !!value;
1748			} else {
1749				value = $element.attr( method );
1750			}
1751
1752			this.normalizeAttributeRule( rules, type, method, value );
1753		}
1754
1755		// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
1756		if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
1757			delete rules.maxlength;
1758		}
1759
1760		return rules;
1761	},
1762
1763	dataRules: function( element ) {
1764		var rules = {},
1765			$element = $( element ),
1766			type = element.getAttribute( "type" ),
1767			method, value;
1768
1769		for ( method in $.validator.methods ) {
1770			value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
1771
1772			// Cast empty attributes like `data-rule-required` to `true`
1773			if ( value === "" ) {
1774				value = true;
1775			}
1776
1777			this.normalizeAttributeRule( rules, type, method, value );
1778		}
1779		return rules;
1780	},
1781
1782	staticRules: function( element ) {
1783		var rules = {},
1784			validator = $.data( element.form, "validator" );
1785
1786		if ( validator.settings.rules ) {
1787			rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
1788		}
1789		return rules;
1790	},
1791
1792	normalizeRules: function( rules, element ) {
1793
1794		// Handle dependency check
1795		$.each( rules, function( prop, val ) {
1796
1797			// Ignore rule when param is explicitly false, eg. required:false
1798			if ( val === false ) {
1799				delete rules[ prop ];
1800				return;
1801			}
1802			if ( val.param || val.depends ) {
1803				var keepRule = true;
1804				switch ( typeof val.depends ) {
1805				case "string":
1806					keepRule = !!$( val.depends, element.form ).length;
1807					break;
1808				case "function":
1809					keepRule = val.depends.call( element, element );
1810					break;
1811				}
1812				if ( keepRule ) {
1813					rules[ prop ] = val.param !== undefined ? val.param : true;
1814				} else {
1815					$.data( element.form, "validator" ).resetElements( $( element ) );
1816					delete rules[ prop ];
1817				}
1818			}
1819		} );
1820
1821		// Evaluate parameters
1822		$.each( rules, function( rule, parameter ) {
1823			rules[ rule ] = typeof parameter === "function" && rule !== "normalizer" ? parameter( element ) : parameter;
1824		} );
1825
1826		// Clean number parameters
1827		$.each( [ "minlength", "maxlength" ], function() {
1828			if ( rules[ this ] ) {
1829				rules[ this ] = Number( rules[ this ] );
1830			}
1831		} );
1832		$.each( [ "rangelength", "range" ], function() {
1833			var parts;
1834			if ( rules[ this ] ) {
1835				if ( Array.isArray( rules[ this ] ) ) {
1836					rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
1837				} else if ( typeof rules[ this ] === "string" ) {
1838					parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
1839					rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
1840				}
1841			}
1842		} );
1843
1844		if ( $.validator.autoCreateRanges ) {
1845
1846			// Auto-create ranges
1847			if ( rules.min != null && rules.max != null ) {
1848				rules.range = [ rules.min, rules.max ];
1849				delete rules.min;
1850				delete rules.max;
1851			}
1852			if ( rules.minlength != null && rules.maxlength != null ) {
1853				rules.rangelength = [ rules.minlength, rules.maxlength ];
1854				delete rules.minlength;
1855				delete rules.maxlength;
1856			}
1857		}
1858
1859		return rules;
1860	},
1861
1862	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1863	normalizeRule: function( data ) {
1864		if ( typeof data === "string" ) {
1865			var transformed = {};
1866			$.each( data.split( /\s/ ), function() {
1867				transformed[ this ] = true;
1868			} );
1869			data = transformed;
1870		}
1871		return data;
1872	},
1873
1874	// https://jqueryvalidation.org/jQuery.validator.addMethod/
1875	addMethod: function( name, method, message ) {
1876		$.validator.methods[ name ] = method;
1877		$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
1878		if ( method.length < 3 ) {
1879			$.validator.addClassRules( name, $.validator.normalizeRule( name ) );
1880		}
1881	},
1882
1883	// https://jqueryvalidation.org/jQuery.validator.methods/
1884	methods: {
1885
1886		// https://jqueryvalidation.org/required-method/
1887		required: function( value, element, param ) {
1888
1889			// Check if dependency is met
1890			if ( !this.depend( param, element ) ) {
1891				return "dependency-mismatch";
1892			}
1893			if ( element.nodeName.toLowerCase() === "select" ) {
1894
1895				// Could be an array for select-multiple or a string, both are fine this way
1896				var val = $( element ).val();
1897				return val && val.length > 0;
1898			}
1899			if ( this.checkable( element ) ) {
1900				return this.getLength( value, element ) > 0;
1901			}
1902			return value !== undefined && value !== null && value.length > 0;
1903		},
1904
1905		// https://jqueryvalidation.org/email-method/
1906		email: function( value, element ) {
1907
1908			// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
1909			// Retrieved 2014-01-14
1910			// If you have a problem with this implementation, report a bug against the above spec
1911			// Or use custom methods to implement your own email validation
1912			return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
1913		},
1914
1915		// https://jqueryvalidation.org/url-method/
1916		url: function( value, element ) {
1917
1918			// Copyright (c) 2010-2013 Diego Perini, MIT licensed
1919			// https://gist.github.com/dperini/729294
1920			// see also https://mathiasbynens.be/demo/url-regex
1921			// modified to allow protocol-relative URLs
1922			return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})+(?::(?:[^\]\[?\/<~#`!@$^&*()+=}|:";',>{ ]|%[0-9A-Fa-f]{2})*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[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]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
1923		},
1924
1925		// https://jqueryvalidation.org/date-method/
1926		date: ( function() {
1927			var called = false;
1928
1929			return function( value, element ) {
1930				if ( !called ) {
1931					called = true;
1932					if ( this.settings.debug && window.console ) {
1933						console.warn(
1934							"The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
1935							"Please don't use it, since it relies on the Date constructor, which\n" +
1936							"behaves very differently across browsers and locales. Use `dateISO`\n" +
1937							"instead or one of the locale specific methods in `localizations/`\n" +
1938							"and `additional-methods.js`."
1939						);
1940					}
1941				}
1942
1943				return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
1944			};
1945		}() ),
1946
1947		// https://jqueryvalidation.org/dateISO-method/
1948		dateISO: function( value, element ) {
1949			return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
1950		},
1951
1952		// https://jqueryvalidation.org/number-method/
1953		number: function( value, element ) {
1954			return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
1955		},
1956
1957		// https://jqueryvalidation.org/digits-method/
1958		digits: function( value, element ) {
1959			return this.optional( element ) || /^\d+$/.test( value );
1960		},
1961
1962		// https://jqueryvalidation.org/minlength-method/
1963		minlength: function( value, element, param ) {
1964			var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
1965			return this.optional( element ) || length >= param;
1966		},
1967
1968		// https://jqueryvalidation.org/maxlength-method/
1969		maxlength: function( value, element, param ) {
1970			var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
1971			return this.optional( element ) || length <= param;
1972		},
1973
1974		// https://jqueryvalidation.org/rangelength-method/
1975		rangelength: function( value, element, param ) {
1976			var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
1977			return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
1978		},
1979
1980		// https://jqueryvalidation.org/min-method/
1981		min: function( value, element, param ) {
1982			return this.optional( element ) || value >= param;
1983		},
1984
1985		// https://jqueryvalidation.org/max-method/
1986		max: function( value, element, param ) {
1987			return this.optional( element ) || value <= param;
1988		},
1989
1990		// https://jqueryvalidation.org/range-method/
1991		range: function( value, element, param ) {
1992			return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
1993		},
1994
1995		// https://jqueryvalidation.org/step-method/
1996		step: function( value, element, param ) {
1997			var type = $( element ).attr( "type" ),
1998				errorMessage = "Step attribute on input type " + type + " is not supported.",
1999				supportedTypes = [ "text", "number", "range" ],
2000				re = new RegExp( "\\b" + type + "\\b" ),
2001				notSupported = type && !re.test( supportedTypes.join() ),
2002				decimalPlaces = function( num ) {
2003					var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
2004					if ( !match ) {
2005						return 0;
2006					}
2007
2008					// Number of digits right of decimal point.
2009					return match[ 1 ] ? match[ 1 ].length : 0;
2010				},
2011				toInt = function( num ) {
2012					return Math.round( num * Math.pow( 10, decimals ) );
2013				},
2014				valid = true,
2015				decimals;
2016
2017			// Works only for text, number and range input types
2018			// TODO find a way to support input types date, datetime, datetime-local, month, time and week
2019			if ( notSupported ) {
2020				throw new Error( errorMessage );
2021			}
2022
2023			decimals = decimalPlaces( param );
2024
2025			// Value can't have too many decimals
2026			if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
2027				valid = false;
2028			}
2029
2030			return this.optional( element ) || valid;
2031		},
2032
2033		// https://jqueryvalidation.org/equalTo-method/
2034		equalTo: function( value, element, param ) {
2035
2036			// Bind to the blur event of the target in order to revalidate whenever the target field is updated
2037			var target = $( param );
2038			if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
2039				target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
2040					$( element ).valid();
2041				} );
2042			}
2043			return value === target.val();
2044		},
2045
2046		// https://jqueryvalidation.org/remote-method/
2047		remote: function( value, element, param, method ) {
2048			if ( this.optional( element ) ) {
2049				return "dependency-mismatch";
2050			}
2051
2052			method = typeof method === "string" && method || "remote";
2053
2054			var previous = this.previousValue( element, method ),
2055				validator, data, optionDataString;
2056
2057			if ( !this.settings.messages[ element.name ] ) {
2058				this.settings.messages[ element.name ] = {};
2059			}
2060			previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
2061			this.settings.messages[ element.name ][ method ] = previous.message;
2062
2063			param = typeof param === "string" && { url: param } || param;
2064			optionDataString = $.param( $.extend( { data: value }, param.data ) );
2065			if ( previous.valid !== null && previous.old === optionDataString ) {
2066				return previous.valid;
2067			}
2068
2069			previous.old = optionDataString;
2070			previous.valid = null;
2071			validator = this;
2072			this.startRequest( element );
2073			data = {};
2074			data[ element.name ] = value;
2075			$.ajax( $.extend( true, {
2076				mode: "abort",
2077				port: this.elementAjaxPort( element ),
2078				dataType: "json",
2079				data: data,
2080				context: validator.currentForm,
2081				success: function( response ) {
2082					var valid = response === true || response === "true",
2083						errors, message, submitted;
2084
2085					validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
2086					if ( valid ) {
2087						submitted = validator.formSubmitted;
2088						validator.toHide = validator.errorsFor( element );
2089						validator.formSubmitted = submitted;
2090						validator.successList.push( element );
2091						validator.invalid[ element.name ] = false;
2092						validator.showErrors();
2093					} else {
2094						errors = {};
2095						message = response || validator.defaultMessage( element, { method: method, parameters: value } );
2096						errors[ element.name ] = previous.message = message;
2097						validator.invalid[ element.name ] = true;
2098						validator.showErrors( errors );
2099					}
2100					previous.valid = valid;
2101					validator.stopRequest( element, valid );
2102				}
2103			}, param ) );
2104			return "pending";
2105		}
2106	}
2107
2108} );
2109
2110// Ajax mode: abort
2111// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
2112//        $.ajaxAbort( port );
2113// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
2114
2115var pendingRequests = {},
2116	ajax;
2117
2118// Use a prefilter if available (1.5+)
2119if ( $.ajaxPrefilter ) {
2120	$.ajaxPrefilter( function( settings, _, xhr ) {
2121		var port = settings.port;
2122		if ( settings.mode === "abort" ) {
2123			$.ajaxAbort( port );
2124			pendingRequests[ port ] = xhr;
2125		}
2126	} );
2127} else {
2128
2129	// Proxy ajax
2130	ajax = $.ajax;
2131	$.ajax = function( settings ) {
2132		var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
2133			port = ( "port" in settings ? settings : $.ajaxSettings ).port;
2134		if ( mode === "abort" ) {
2135			$.ajaxAbort( port );
2136			pendingRequests[ port ] = ajax.apply( this, arguments );
2137			return pendingRequests[ port ];
2138		}
2139		return ajax.apply( this, arguments );
2140	};
2141}
2142
2143// Abort the previous request without sending a new one
2144$.ajaxAbort = function( port ) {
2145	if ( pendingRequests[ port ] ) {
2146		pendingRequests[ port ].abort();
2147		delete pendingRequests[ port ];
2148	}
2149};
2150return $;
2151}));
2152
2153/***/ }),
2154
vendor: 285,752 bytes, lines 2155-12880
2155/***/ "./node_modules/jquery/dist/jquery.js":
2156/*!********************************************!*\
2157  !*** ./node_modules/jquery/dist/jquery.js ***!
2158  \********************************************/
2159/***/ (function(module, exports) {
2160
2161var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
2162 * jQuery JavaScript Library v3.7.1
2163 * https://jquery.com/
2164 *
2165 * Copyright OpenJS Foundation and other contributors
2166 * Released under the MIT license
2167 * https://jquery.org/license
2168 *
2169 * Date: 2023-08-28T13:37Z
2170 */
2171( function( global, factory ) {
2172
2173	"use strict";
2174
2175	if (  true && typeof module.exports === "object" ) {
2176
2177		// For CommonJS and CommonJS-like environments where a proper `window`
2178		// is present, execute the factory and get jQuery.
2179		// For environments that do not have a `window` with a `document`
2180		// (such as Node.js), expose a factory as module.exports.
2181		// This accentuates the need for the creation of a real `window`.
2182		// e.g. var jQuery = require("jquery")(window);
2183		// See ticket trac-14549 for more info.
2184		module.exports = global.document ?
2185			factory( global, true ) :
2186			function( w ) {
2187				if ( !w.document ) {
2188					throw new Error( "jQuery requires a window with a document" );
2189				}
2190				return factory( w );
2191			};
2192	} else {
2193		factory( global );
2194	}
2195
2196// Pass this if window is not defined yet
2197} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
2198
2199// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
2200// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
2201// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
2202// enough that all such attempts are guarded in a try block.
2203"use strict";
2204
2205var arr = [];
2206
2207var getProto = Object.getPrototypeOf;
2208
2209var slice = arr.slice;
2210
2211var flat = arr.flat ? function( array ) {
2212	return arr.flat.call( array );
2213} : function( array ) {
2214	return arr.concat.apply( [], array );
2215};
2216
2217
2218var push = arr.push;
2219
2220var indexOf = arr.indexOf;
2221
2222var class2type = {};
2223
2224var toString = class2type.toString;
2225
2226var hasOwn = class2type.hasOwnProperty;
2227
2228var fnToString = hasOwn.toString;
2229
2230var ObjectFunctionString = fnToString.call( Object );
2231
2232var support = {};
2233
2234var isFunction = function isFunction( obj ) {
2235
2236		// Support: Chrome <=57, Firefox <=52
2237		// In some browsers, typeof returns "function" for HTML <object> elements
2238		// (i.e., `typeof document.createElement( "object" ) === "function"`).
2239		// We don't want to classify *any* DOM node as a function.
2240		// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
2241		// Plus for old WebKit, typeof returns "function" for HTML collections
2242		// (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
2243		return typeof obj === "function" && typeof obj.nodeType !== "number" &&
2244			typeof obj.item !== "function";
2245	};
2246
2247
2248var isWindow = function isWindow( obj ) {
2249		return obj != null && obj === obj.window;
2250	};
2251
2252
2253var document = window.document;
2254
2255
2256
2257	var preservedScriptAttributes = {
2258		type: true,
2259		src: true,
2260		nonce: true,
2261		noModule: true
2262	};
2263
2264	function DOMEval( code, node, doc ) {
2265		doc = doc || document;
2266
2267		var i, val,
2268			script = doc.createElement( "script" );
2269
2270		script.text = code;
2271		if ( node ) {
2272			for ( i in preservedScriptAttributes ) {
2273
2274				// Support: Firefox 64+, Edge 18+
2275				// Some browsers don't support the "nonce" property on scripts.
2276				// On the other hand, just using `getAttribute` is not enough as
2277				// the `nonce` attribute is reset to an empty string whenever it
2278				// becomes browsing-context connected.
2279				// See https://github.com/whatwg/html/issues/2369
2280				// See https://html.spec.whatwg.org/#nonce-attributes
2281				// The `node.getAttribute` check was added for the sake of
2282				// `jQuery.globalEval` so that it can fake a nonce-containing node
2283				// via an object.
2284				val = node[ i ] || node.getAttribute && node.getAttribute( i );
2285				if ( val ) {
2286					script.setAttribute( i, val );
2287				}
2288			}
2289		}
2290		doc.head.appendChild( script ).parentNode.removeChild( script );
2291	}
2292
2293
2294function toType( obj ) {
2295	if ( obj == null ) {
2296		return obj + "";
2297	}
2298
2299	// Support: Android <=2.3 only (functionish RegExp)
2300	return typeof obj === "object" || typeof obj === "function" ?
2301		class2type[ toString.call( obj ) ] || "object" :
2302		typeof obj;
2303}
2304/* global Symbol */
2305// Defining this global in .eslintrc.json would create a danger of using the global
2306// unguarded in another place, it seems safer to define global only for this module
2307
2308
2309
2310var version = "3.7.1",
2311
2312	rhtmlSuffix = /HTML$/i,
2313
2314	// Define a local copy of jQuery
2315	jQuery = function( selector, context ) {
2316
2317		// The jQuery object is actually just the init constructor 'enhanced'
2318		// Need init if jQuery is called (just allow error to be thrown if not included)
2319		return new jQuery.fn.init( selector, context );
2320	};
2321
2322jQuery.fn = jQuery.prototype = {
2323
2324	// The current version of jQuery being used
2325	jquery: version,
2326
2327	constructor: jQuery,
2328
2329	// The default length of a jQuery object is 0
2330	length: 0,
2331
2332	toArray: function() {
2333		return slice.call( this );
2334	},
2335
2336	// Get the Nth element in the matched element set OR
2337	// Get the whole matched element set as a clean array
2338	get: function( num ) {
2339
2340		// Return all the elements in a clean array
2341		if ( num == null ) {
2342			return slice.call( this );
2343		}
2344
2345		// Return just the one element from the set
2346		return num < 0 ? this[ num + this.length ] : this[ num ];
2347	},
2348
2349	// Take an array of elements and push it onto the stack
2350	// (returning the new matched element set)
2351	pushStack: function( elems ) {
2352
2353		// Build a new jQuery matched element set
2354		var ret = jQuery.merge( this.constructor(), elems );
2355
2356		// Add the old object onto the stack (as a reference)
2357		ret.prevObject = this;
2358
2359		// Return the newly-formed element set
2360		return ret;
2361	},
2362
2363	// Execute a callback for every element in the matched set.
2364	each: function( callback ) {
2365		return jQuery.each( this, callback );
2366	},
2367
2368	map: function( callback ) {
2369		return this.pushStack( jQuery.map( this, function( elem, i ) {
2370			return callback.call( elem, i, elem );
2371		} ) );
2372	},
2373
2374	slice: function() {
2375		return this.pushStack( slice.apply( this, arguments ) );
2376	},
2377
2378	first: function() {
2379		return this.eq( 0 );
2380	},
2381
2382	last: function() {
2383		return this.eq( -1 );
2384	},
2385
2386	even: function() {
2387		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
2388			return ( i + 1 ) % 2;
2389		} ) );
2390	},
2391
2392	odd: function() {
2393		return this.pushStack( jQuery.grep( this, function( _elem, i ) {
2394			return i % 2;
2395		} ) );
2396	},
2397
2398	eq: function( i ) {
2399		var len = this.length,
2400			j = +i + ( i < 0 ? len : 0 );
2401		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
2402	},
2403
2404	end: function() {
2405		return this.prevObject || this.constructor();
2406	},
2407
2408	// For internal use only.
2409	// Behaves like an Array's method, not like a jQuery method.
2410	push: push,
2411	sort: arr.sort,
2412	splice: arr.splice
2413};
2414
2415jQuery.extend = jQuery.fn.extend = function() {
2416	var options, name, src, copy, copyIsArray, clone,
2417		target = arguments[ 0 ] || {},
2418		i = 1,
2419		length = arguments.length,
2420		deep = false;
2421
2422	// Handle a deep copy situation
2423	if ( typeof target === "boolean" ) {
2424		deep = target;
2425
2426		// Skip the boolean and the target
2427		target = arguments[ i ] || {};
2428		i++;
2429	}
2430
2431	// Handle case when target is a string or something (possible in deep copy)
2432	if ( typeof target !== "object" && !isFunction( target ) ) {
2433		target = {};
2434	}
2435
2436	// Extend jQuery itself if only one argument is passed
2437	if ( i === length ) {
2438		target = this;
2439		i--;
2440	}
2441
2442	for ( ; i < length; i++ ) {
2443
2444		// Only deal with non-null/undefined values
2445		if ( ( options = arguments[ i ] ) != null ) {
2446
2447			// Extend the base object
2448			for ( name in options ) {
2449				copy = options[ name ];
2450
2451				// Prevent Object.prototype pollution
2452				// Prevent never-ending loop
2453				if ( name === "__proto__" || target === copy ) {
2454					continue;
2455				}
2456
2457				// Recurse if we're merging plain objects or arrays
2458				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
2459					( copyIsArray = Array.isArray( copy ) ) ) ) {
2460					src = target[ name ];
2461
2462					// Ensure proper type for the source value
2463					if ( copyIsArray && !Array.isArray( src ) ) {
2464						clone = [];
2465					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
2466						clone = {};
2467					} else {
2468						clone = src;
2469					}
2470					copyIsArray = false;
2471
2472					// Never move original objects, clone them
2473					target[ name ] = jQuery.extend( deep, clone, copy );
2474
2475				// Don't bring in undefined values
2476				} else if ( copy !== undefined ) {
2477					target[ name ] = copy;
2478				}
2479			}
2480		}
2481	}
2482
2483	// Return the modified object
2484	return target;
2485};
2486
2487jQuery.extend( {
2488
2489	// Unique for each copy of jQuery on the page
2490	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
2491
2492	// Assume jQuery is ready without the ready module
2493	isReady: true,
2494
2495	error: function( msg ) {
2496		throw new Error( msg );
2497	},
2498
2499	noop: function() {},
2500
2501	isPlainObject: function( obj ) {
2502		var proto, Ctor;
2503
2504		// Detect obvious negatives
2505		// Use toString instead of jQuery.type to catch host objects
2506		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
2507			return false;
2508		}
2509
2510		proto = getProto( obj );
2511
2512		// Objects with no prototype (e.g., `Object.create( null )`) are plain
2513		if ( !proto ) {
2514			return true;
2515		}
2516
2517		// Objects with prototype are plain iff they were constructed by a global Object function
2518		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
2519		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
2520	},
2521
2522	isEmptyObject: function( obj ) {
2523		var name;
2524
2525		for ( name in obj ) {
2526			return false;
2527		}
2528		return true;
2529	},
2530
2531	// Evaluates a script in a provided context; falls back to the global one
2532	// if not specified.
2533	globalEval: function( code, options, doc ) {
2534		DOMEval( code, { nonce: options && options.nonce }, doc );
2535	},
2536
2537	each: function( obj, callback ) {
2538		var length, i = 0;
2539
2540		if ( isArrayLike( obj ) ) {
2541			length = obj.length;
2542			for ( ; i < length; i++ ) {
2543				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
2544					break;
2545				}
2546			}
2547		} else {
2548			for ( i in obj ) {
2549				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
2550					break;
2551				}
2552			}
2553		}
2554
2555		return obj;
2556	},
2557
2558
2559	// Retrieve the text value of an array of DOM nodes
2560	text: function( elem ) {
2561		var node,
2562			ret = "",
2563			i = 0,
2564			nodeType = elem.nodeType;
2565
2566		if ( !nodeType ) {
2567
2568			// If no nodeType, this is expected to be an array
2569			while ( ( node = elem[ i++ ] ) ) {
2570
2571				// Do not traverse comment nodes
2572				ret += jQuery.text( node );
2573			}
2574		}
2575		if ( nodeType === 1 || nodeType === 11 ) {
2576			return elem.textContent;
2577		}
2578		if ( nodeType === 9 ) {
2579			return elem.documentElement.textContent;
2580		}
2581		if ( nodeType === 3 || nodeType === 4 ) {
2582			return elem.nodeValue;
2583		}
2584
2585		// Do not include comment or processing instruction nodes
2586
2587		return ret;
2588	},
2589
2590	// results is for internal usage only
2591	makeArray: function( arr, results ) {
2592		var ret = results || [];
2593
2594		if ( arr != null ) {
2595			if ( isArrayLike( Object( arr ) ) ) {
2596				jQuery.merge( ret,
2597					typeof arr === "string" ?
2598						[ arr ] : arr
2599				);
2600			} else {
2601				push.call( ret, arr );
2602			}
2603		}
2604
2605		return ret;
2606	},
2607
2608	inArray: function( elem, arr, i ) {
2609		return arr == null ? -1 : indexOf.call( arr, elem, i );
2610	},
2611
2612	isXMLDoc: function( elem ) {
2613		var namespace = elem && elem.namespaceURI,
2614			docElem = elem && ( elem.ownerDocument || elem ).documentElement;
2615
2616		// Assume HTML when documentElement doesn't yet exist, such as inside
2617		// document fragments.
2618		return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" );
2619	},
2620
2621	// Support: Android <=4.0 only, PhantomJS 1 only
2622	// push.apply(_, arraylike) throws on ancient WebKit
2623	merge: function( first, second ) {
2624		var len = +second.length,
2625			j = 0,
2626			i = first.length;
2627
2628		for ( ; j < len; j++ ) {
2629			first[ i++ ] = second[ j ];
2630		}
2631
2632		first.length = i;
2633
2634		return first;
2635	},
2636
2637	grep: function( elems, callback, invert ) {
2638		var callbackInverse,
2639			matches = [],
2640			i = 0,
2641			length = elems.length,
2642			callbackExpect = !invert;
2643
2644		// Go through the array, only saving the items
2645		// that pass the validator function
2646		for ( ; i < length; i++ ) {
2647			callbackInverse = !callback( elems[ i ], i );
2648			if ( callbackInverse !== callbackExpect ) {
2649				matches.push( elems[ i ] );
2650			}
2651		}
2652
2653		return matches;
2654	},
2655
2656	// arg is for internal usage only
2657	map: function( elems, callback, arg ) {
2658		var length, value,
2659			i = 0,
2660			ret = [];
2661
2662		// Go through the array, translating each of the items to their new values
2663		if ( isArrayLike( elems ) ) {
2664			length = elems.length;
2665			for ( ; i < length; i++ ) {
2666				value = callback( elems[ i ], i, arg );
2667
2668				if ( value != null ) {
2669					ret.push( value );
2670				}
2671			}
2672
2673		// Go through every key on the object,
2674		} else {
2675			for ( i in elems ) {
2676				value = callback( elems[ i ], i, arg );
2677
2678				if ( value != null ) {
2679					ret.push( value );
2680				}
2681			}
2682		}
2683
2684		// Flatten any nested arrays
2685		return flat( ret );
2686	},
2687
2688	// A global GUID counter for objects
2689	guid: 1,
2690
2691	// jQuery.support is not used in Core but other projects attach their
2692	// properties to it so it needs to exist.
2693	support: support
2694} );
2695
2696if ( typeof Symbol === "function" ) {
2697	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
2698}
2699
2700// Populate the class2type map
2701jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
2702	function( _i, name ) {
2703		class2type[ "[object " + name + "]" ] = name.toLowerCase();
2704	} );
2705
2706function isArrayLike( obj ) {
2707
2708	// Support: real iOS 8.2 only (not reproducible in simulator)
2709	// `in` check used to prevent JIT error (gh-2145)
2710	// hasOwn isn't used here due to false negatives
2711	// regarding Nodelist length in IE
2712	var length = !!obj && "length" in obj && obj.length,
2713		type = toType( obj );
2714
2715	if ( isFunction( obj ) || isWindow( obj ) ) {
2716		return false;
2717	}
2718
2719	return type === "array" || length === 0 ||
2720		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
2721}
2722
2723
2724function nodeName( elem, name ) {
2725
2726	return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
2727
2728}
2729var pop = arr.pop;
2730
2731
2732var sort = arr.sort;
2733
2734
2735var splice = arr.splice;
2736
2737
2738var whitespace = "[\\x20\\t\\r\\n\\f]";
2739
2740
2741var rtrimCSS = new RegExp(
2742	"^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
2743	"g"
2744);
2745
2746
2747
2748
2749// Note: an element does not contain itself
2750jQuery.contains = function( a, b ) {
2751	var bup = b && b.parentNode;
2752
2753	return a === bup || !!( bup && bup.nodeType === 1 && (
2754
2755		// Support: IE 9 - 11+
2756		// IE doesn't have `contains` on SVG.
2757		a.contains ?
2758			a.contains( bup ) :
2759			a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
2760	) );
2761};
2762
2763
2764
2765
2766// CSS string/identifier serialization
2767// https://drafts.csswg.org/cssom/#common-serializing-idioms
2768var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
2769
2770function fcssescape( ch, asCodePoint ) {
2771	if ( asCodePoint ) {
2772
2773		// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
2774		if ( ch === "\0" ) {
2775			return "\uFFFD";
2776		}
2777
2778		// Control characters and (dependent upon position) numbers get escaped as code points
2779		return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
2780	}
2781
2782	// Other potentially-special ASCII characters get backslash-escaped
2783	return "\\" + ch;
2784}
2785
2786jQuery.escapeSelector = function( sel ) {
2787	return ( sel + "" ).replace( rcssescape, fcssescape );
2788};
2789
2790
2791
2792
2793var preferredDoc = document,
2794	pushNative = push;
2795
2796( function() {
2797
2798var i,
2799	Expr,
2800	outermostContext,
2801	sortInput,
2802	hasDuplicate,
2803	push = pushNative,
2804
2805	// Local document vars
2806	document,
2807	documentElement,
2808	documentIsHTML,
2809	rbuggyQSA,
2810	matches,
2811
2812	// Instance-specific data
2813	expando = jQuery.expando,
2814	dirruns = 0,
2815	done = 0,
2816	classCache = createCache(),
2817	tokenCache = createCache(),
2818	compilerCache = createCache(),
2819	nonnativeSelectorCache = createCache(),
2820	sortOrder = function( a, b ) {
2821		if ( a === b ) {
2822			hasDuplicate = true;
2823		}
2824		return 0;
2825	},
2826
2827	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +
2828		"loop|multiple|open|readonly|required|scoped",
2829
2830	// Regular expressions
2831
2832	// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
2833	identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
2834		"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
2835
2836	// Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
2837	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
2838
2839		// Operator (capture 2)
2840		"*([*^$|!~]?=)" + whitespace +
2841
2842		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
2843		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
2844		whitespace + "*\\]",
2845
2846	pseudos = ":(" + identifier + ")(?:\\((" +
2847
2848		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
2849		// 1. quoted (capture 3; capture 4 or capture 5)
2850		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
2851
2852		// 2. simple (capture 6)
2853		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
2854
2855		// 3. anything else (capture 2)
2856		".*" +
2857		")\\)|)",
2858
2859	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
2860	rwhitespace = new RegExp( whitespace + "+", "g" ),
2861
2862	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
2863	rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" +
2864		whitespace + "*" ),
2865	rdescend = new RegExp( whitespace + "|>" ),
2866
2867	rpseudo = new RegExp( pseudos ),
2868	ridentifier = new RegExp( "^" + identifier + "$" ),
2869
2870	matchExpr = {
2871		ID: new RegExp( "^#(" + identifier + ")" ),
2872		CLASS: new RegExp( "^\\.(" + identifier + ")" ),
2873		TAG: new RegExp( "^(" + identifier + "|[*])" ),
2874		ATTR: new RegExp( "^" + attributes ),
2875		PSEUDO: new RegExp( "^" + pseudos ),
2876		CHILD: new RegExp(
2877			"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
2878				whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
2879				whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
2880		bool: new RegExp( "^(?:" + booleans + ")$", "i" ),
2881
2882		// For use in libraries implementing .is()
2883		// We use this for POS matching in `select`
2884		needsContext: new RegExp( "^" + whitespace +
2885			"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
2886			"*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
2887	},
2888
2889	rinputs = /^(?:input|select|textarea|button)$/i,
2890	rheader = /^h\d$/i,
2891
2892	// Easily-parseable/retrievable ID or TAG or CLASS selectors
2893	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
2894
2895	rsibling = /[+~]/,
2896
2897	// CSS escapes
2898	// https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
2899	runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace +
2900		"?|\\\\([^\\r\\n\\f])", "g" ),
2901	funescape = function( escape, nonHex ) {
2902		var high = "0x" + escape.slice( 1 ) - 0x10000;
2903
2904		if ( nonHex ) {
2905
2906			// Strip the backslash prefix from a non-hex escape sequence
2907			return nonHex;
2908		}
2909
2910		// Replace a hexadecimal escape sequence with the encoded Unicode code point
2911		// Support: IE <=11+
2912		// For values outside the Basic Multilingual Plane (BMP), manually construct a
2913		// surrogate pair
2914		return high < 0 ?
2915			String.fromCharCode( high + 0x10000 ) :
2916			String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
2917	},
2918
2919	// Used for iframes; see `setDocument`.
2920	// Support: IE 9 - 11+, Edge 12 - 18+
2921	// Removing the function wrapper causes a "Permission Denied"
2922	// error in IE/Edge.
2923	unloadHandler = function() {
2924		setDocument();
2925	},
2926
2927	inDisabledFieldset = addCombinator(
2928		function( elem ) {
2929			return elem.disabled === true && nodeName( elem, "fieldset" );
2930		},
2931		{ dir: "parentNode", next: "legend" }
2932	);
2933
2934// Support: IE <=9 only
2935// Accessing document.activeElement can throw unexpectedly
2936// https://bugs.jquery.com/ticket/13393
2937function safeActiveElement() {
2938	try {
2939		return document.activeElement;
2940	} catch ( err ) { }
2941}
2942
2943// Optimize for push.apply( _, NodeList )
2944try {
2945	push.apply(
2946		( arr = slice.call( preferredDoc.childNodes ) ),
2947		preferredDoc.childNodes
2948	);
2949
2950	// Support: Android <=4.0
2951	// Detect silently failing push.apply
2952	// eslint-disable-next-line no-unused-expressions
2953	arr[ preferredDoc.childNodes.length ].nodeType;
2954} catch ( e ) {
2955	push = {
2956		apply: function( target, els ) {
2957			pushNative.apply( target, slice.call( els ) );
2958		},
2959		call: function( target ) {
2960			pushNative.apply( target, slice.call( arguments, 1 ) );
2961		}
2962	};
2963}
2964
2965function find( selector, context, results, seed ) {
2966	var m, i, elem, nid, match, groups, newSelector,
2967		newContext = context && context.ownerDocument,
2968
2969		// nodeType defaults to 9, since context defaults to document
2970		nodeType = context ? context.nodeType : 9;
2971
2972	results = results || [];
2973
2974	// Return early from calls with invalid selector or context
2975	if ( typeof selector !== "string" || !selector ||
2976		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
2977
2978		return results;
2979	}
2980
2981	// Try to shortcut find operations (as opposed to filters) in HTML documents
2982	if ( !seed ) {
2983		setDocument( context );
2984		context = context || document;
2985
2986		if ( documentIsHTML ) {
2987
2988			// If the selector is sufficiently simple, try using a "get*By*" DOM method
2989			// (excepting DocumentFragment context, where the methods don't exist)
2990			if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
2991
2992				// ID selector
2993				if ( ( m = match[ 1 ] ) ) {
2994
2995					// Document context
2996					if ( nodeType === 9 ) {
2997						if ( ( elem = context.getElementById( m ) ) ) {
2998
2999							// Support: IE 9 only
3000							// getElementById can match elements by name instead of ID
3001							if ( elem.id === m ) {
3002								push.call( results, elem );
3003								return results;
3004							}
3005						} else {
3006							return results;
3007						}
3008
3009					// Element context
3010					} else {
3011
3012						// Support: IE 9 only
3013						// getElementById can match elements by name instead of ID
3014						if ( newContext && ( elem = newContext.getElementById( m ) ) &&
3015							find.contains( context, elem ) &&
3016							elem.id === m ) {
3017
3018							push.call( results, elem );
3019							return results;
3020						}
3021					}
3022
3023				// Type selector
3024				} else if ( match[ 2 ] ) {
3025					push.apply( results, context.getElementsByTagName( selector ) );
3026					return results;
3027
3028				// Class selector
3029				} else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) {
3030					push.apply( results, context.getElementsByClassName( m ) );
3031					return results;
3032				}
3033			}
3034
3035			// Take advantage of querySelectorAll
3036			if ( !nonnativeSelectorCache[ selector + " " ] &&
3037				( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) {
3038
3039				newSelector = selector;
3040				newContext = context;
3041
3042				// qSA considers elements outside a scoping root when evaluating child or
3043				// descendant combinators, which is not what we want.
3044				// In such cases, we work around the behavior by prefixing every selector in the
3045				// list with an ID selector referencing the scope context.
3046				// The technique has to be used as well when a leading combinator is used
3047				// as such selectors are not recognized by querySelectorAll.
3048				// Thanks to Andrew Dupont for this technique.
3049				if ( nodeType === 1 &&
3050					( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) {
3051
3052					// Expand context for sibling selectors
3053					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
3054						context;
3055
3056					// We can use :scope instead of the ID hack if the browser
3057					// supports it & if we're not changing the context.
3058					// Support: IE 11+, Edge 17 - 18+
3059					// IE/Edge sometimes throw a "Permission denied" error when
3060					// strict-comparing two documents; shallow comparisons work.
3061					// eslint-disable-next-line eqeqeq
3062					if ( newContext != context || !support.scope ) {
3063
3064						// Capture the context ID, setting it first if necessary
3065						if ( ( nid = context.getAttribute( "id" ) ) ) {
3066							nid = jQuery.escapeSelector( nid );
3067						} else {
3068							context.setAttribute( "id", ( nid = expando ) );
3069						}
3070					}
3071
3072					// Prefix every selector in the list
3073					groups = tokenize( selector );
3074					i = groups.length;
3075					while ( i-- ) {
3076						groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
3077							toSelector( groups[ i ] );
3078					}
3079					newSelector = groups.join( "," );
3080				}
3081
3082				try {
3083					push.apply( results,
3084						newContext.querySelectorAll( newSelector )
3085					);
3086					return results;
3087				} catch ( qsaError ) {
3088					nonnativeSelectorCache( selector, true );
3089				} finally {
3090					if ( nid === expando ) {
3091						context.removeAttribute( "id" );
3092					}
3093				}
3094			}
3095		}
3096	}
3097
3098	// All others
3099	return select( selector.replace( rtrimCSS, "$1" ), context, results, seed );
3100}
3101
3102/**
3103 * Create key-value caches of limited size
3104 * @returns {function(string, object)} Returns the Object data after storing it on itself with
3105 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
3106 *	deleting the oldest entry
3107 */
3108function createCache() {
3109	var keys = [];
3110
3111	function cache( key, value ) {
3112
3113		// Use (key + " ") to avoid collision with native prototype properties
3114		// (see https://github.com/jquery/sizzle/issues/157)
3115		if ( keys.push( key + " " ) > Expr.cacheLength ) {
3116
3117			// Only keep the most recent entries
3118			delete cache[ keys.shift() ];
3119		}
3120		return ( cache[ key + " " ] = value );
3121	}
3122	return cache;
3123}
3124
3125/**
3126 * Mark a function for special use by jQuery selector module
3127 * @param {Function} fn The function to mark
3128 */
3129function markFunction( fn ) {
3130	fn[ expando ] = true;
3131	return fn;
3132}
3133
3134/**
3135 * Support testing using an element
3136 * @param {Function} fn Passed the created element and returns a boolean result
3137 */
3138function assert( fn ) {
3139	var el = document.createElement( "fieldset" );
3140
3141	try {
3142		return !!fn( el );
3143	} catch ( e ) {
3144		return false;
3145	} finally {
3146
3147		// Remove from its parent by default
3148		if ( el.parentNode ) {
3149			el.parentNode.removeChild( el );
3150		}
3151
3152		// release memory in IE
3153		el = null;
3154	}
3155}
3156
3157/**
3158 * Returns a function to use in pseudos for input types
3159 * @param {String} type
3160 */
3161function createInputPseudo( type ) {
3162	return function( elem ) {
3163		return nodeName( elem, "input" ) && elem.type === type;
3164	};
3165}
3166
3167/**
3168 * Returns a function to use in pseudos for buttons
3169 * @param {String} type
3170 */
3171function createButtonPseudo( type ) {
3172	return function( elem ) {
3173		return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) &&
3174			elem.type === type;
3175	};
3176}
3177
3178/**
3179 * Returns a function to use in pseudos for :enabled/:disabled
3180 * @param {Boolean} disabled true for :disabled; false for :enabled
3181 */
3182function createDisabledPseudo( disabled ) {
3183
3184	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
3185	return function( elem ) {
3186
3187		// Only certain elements can match :enabled or :disabled
3188		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
3189		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
3190		if ( "form" in elem ) {
3191
3192			// Check for inherited disabledness on relevant non-disabled elements:
3193			// * listed form-associated elements in a disabled fieldset
3194			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
3195			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
3196			// * option elements in a disabled optgroup
3197			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
3198			// All such elements have a "form" property.
3199			if ( elem.parentNode && elem.disabled === false ) {
3200
3201				// Option elements defer to a parent optgroup if present
3202				if ( "label" in elem ) {
3203					if ( "label" in elem.parentNode ) {
3204						return elem.parentNode.disabled === disabled;
3205					} else {
3206						return elem.disabled === disabled;
3207					}
3208				}
3209
3210				// Support: IE 6 - 11+
3211				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
3212				return elem.isDisabled === disabled ||
3213
3214					// Where there is no isDisabled, check manually
3215					elem.isDisabled !== !disabled &&
3216						inDisabledFieldset( elem ) === disabled;
3217			}
3218
3219			return elem.disabled === disabled;
3220
3221		// Try to winnow out elements that can't be disabled before trusting the disabled property.
3222		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
3223		// even exist on them, let alone have a boolean value.
3224		} else if ( "label" in elem ) {
3225			return elem.disabled === disabled;
3226		}
3227
3228		// Remaining elements are neither :enabled nor :disabled
3229		return false;
3230	};
3231}
3232
3233/**
3234 * Returns a function to use in pseudos for positionals
3235 * @param {Function} fn
3236 */
3237function createPositionalPseudo( fn ) {
3238	return markFunction( function( argument ) {
3239		argument = +argument;
3240		return markFunction( function( seed, matches ) {
3241			var j,
3242				matchIndexes = fn( [], seed.length, argument ),
3243				i = matchIndexes.length;
3244
3245			// Match elements found at the specified indexes
3246			while ( i-- ) {
3247				if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
3248					seed[ j ] = !( matches[ j ] = seed[ j ] );
3249				}
3250			}
3251		} );
3252	} );
3253}
3254
3255/**
3256 * Checks a node for validity as a jQuery selector context
3257 * @param {Element|Object=} context
3258 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
3259 */
3260function testContext( context ) {
3261	return context && typeof context.getElementsByTagName !== "undefined" && context;
3262}
3263
3264/**
3265 * Sets document-related variables once based on the current document
3266 * @param {Element|Object} [node] An element or document object to use to set the document
3267 * @returns {Object} Returns the current document
3268 */
3269function setDocument( node ) {
3270	var subWindow,
3271		doc = node ? node.ownerDocument || node : preferredDoc;
3272
3273	// Return early if doc is invalid or already selected
3274	// Support: IE 11+, Edge 17 - 18+
3275	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3276	// two documents; shallow comparisons work.
3277	// eslint-disable-next-line eqeqeq
3278	if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
3279		return document;
3280	}
3281
3282	// Update global variables
3283	document = doc;
3284	documentElement = document.documentElement;
3285	documentIsHTML = !jQuery.isXMLDoc( document );
3286
3287	// Support: iOS 7 only, IE 9 - 11+
3288	// Older browsers didn't support unprefixed `matches`.
3289	matches = documentElement.matches ||
3290		documentElement.webkitMatchesSelector ||
3291		documentElement.msMatchesSelector;
3292
3293	// Support: IE 9 - 11+, Edge 12 - 18+
3294	// Accessing iframe documents after unload throws "permission denied" errors
3295	// (see trac-13936).
3296	// Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
3297	// all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
3298	if ( documentElement.msMatchesSelector &&
3299
3300		// Support: IE 11+, Edge 17 - 18+
3301		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3302		// two documents; shallow comparisons work.
3303		// eslint-disable-next-line eqeqeq
3304		preferredDoc != document &&
3305		( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
3306
3307		// Support: IE 9 - 11+, Edge 12 - 18+
3308		subWindow.addEventListener( "unload", unloadHandler );
3309	}
3310
3311	// Support: IE <10
3312	// Check if getElementById returns elements by name
3313	// The broken getElementById methods don't pick up programmatically-set names,
3314	// so use a roundabout getElementsByName test
3315	support.getById = assert( function( el ) {
3316		documentElement.appendChild( el ).id = jQuery.expando;
3317		return !document.getElementsByName ||
3318			!document.getElementsByName( jQuery.expando ).length;
3319	} );
3320
3321	// Support: IE 9 only
3322	// Check to see if it's possible to do matchesSelector
3323	// on a disconnected node.
3324	support.disconnectedMatch = assert( function( el ) {
3325		return matches.call( el, "*" );
3326	} );
3327
3328	// Support: IE 9 - 11+, Edge 12 - 18+
3329	// IE/Edge don't support the :scope pseudo-class.
3330	support.scope = assert( function() {
3331		return document.querySelectorAll( ":scope" );
3332	} );
3333
3334	// Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
3335	// Make sure the `:has()` argument is parsed unforgivingly.
3336	// We include `*` in the test to detect buggy implementations that are
3337	// _selectively_ forgiving (specifically when the list includes at least
3338	// one valid selector).
3339	// Note that we treat complete lack of support for `:has()` as if it were
3340	// spec-compliant support, which is fine because use of `:has()` in such
3341	// environments will fail in the qSA path and fall back to jQuery traversal
3342	// anyway.
3343	support.cssHas = assert( function() {
3344		try {
3345			document.querySelector( ":has(*,:jqfake)" );
3346			return false;
3347		} catch ( e ) {
3348			return true;
3349		}
3350	} );
3351
3352	// ID filter and find
3353	if ( support.getById ) {
3354		Expr.filter.ID = function( id ) {
3355			var attrId = id.replace( runescape, funescape );
3356			return function( elem ) {
3357				return elem.getAttribute( "id" ) === attrId;
3358			};
3359		};
3360		Expr.find.ID = function( id, context ) {
3361			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
3362				var elem = context.getElementById( id );
3363				return elem ? [ elem ] : [];
3364			}
3365		};
3366	} else {
3367		Expr.filter.ID =  function( id ) {
3368			var attrId = id.replace( runescape, funescape );
3369			return function( elem ) {
3370				var node = typeof elem.getAttributeNode !== "undefined" &&
3371					elem.getAttributeNode( "id" );
3372				return node && node.value === attrId;
3373			};
3374		};
3375
3376		// Support: IE 6 - 7 only
3377		// getElementById is not reliable as a find shortcut
3378		Expr.find.ID = function( id, context ) {
3379			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
3380				var node, i, elems,
3381					elem = context.getElementById( id );
3382
3383				if ( elem ) {
3384
3385					// Verify the id attribute
3386					node = elem.getAttributeNode( "id" );
3387					if ( node && node.value === id ) {
3388						return [ elem ];
3389					}
3390
3391					// Fall back on getElementsByName
3392					elems = context.getElementsByName( id );
3393					i = 0;
3394					while ( ( elem = elems[ i++ ] ) ) {
3395						node = elem.getAttributeNode( "id" );
3396						if ( node && node.value === id ) {
3397							return [ elem ];
3398						}
3399					}
3400				}
3401
3402				return [];
3403			}
3404		};
3405	}
3406
3407	// Tag
3408	Expr.find.TAG = function( tag, context ) {
3409		if ( typeof context.getElementsByTagName !== "undefined" ) {
3410			return context.getElementsByTagName( tag );
3411
3412		// DocumentFragment nodes don't have gEBTN
3413		} else {
3414			return context.querySelectorAll( tag );
3415		}
3416	};
3417
3418	// Class
3419	Expr.find.CLASS = function( className, context ) {
3420		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
3421			return context.getElementsByClassName( className );
3422		}
3423	};
3424
3425	/* QSA/matchesSelector
3426	---------------------------------------------------------------------- */
3427
3428	// QSA and matchesSelector support
3429
3430	rbuggyQSA = [];
3431
3432	// Build QSA regex
3433	// Regex strategy adopted from Diego Perini
3434	assert( function( el ) {
3435
3436		var input;
3437
3438		documentElement.appendChild( el ).innerHTML =
3439			"<a id='" + expando + "' href='' disabled='disabled'></a>" +
3440			"<select id='" + expando + "-\r\\' disabled='disabled'>" +
3441			"<option selected=''></option></select>";
3442
3443		// Support: iOS <=7 - 8 only
3444		// Boolean attributes and "value" are not treated correctly in some XML documents
3445		if ( !el.querySelectorAll( "[selected]" ).length ) {
3446			rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
3447		}
3448
3449		// Support: iOS <=7 - 8 only
3450		if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
3451			rbuggyQSA.push( "~=" );
3452		}
3453
3454		// Support: iOS 8 only
3455		// https://bugs.webkit.org/show_bug.cgi?id=136851
3456		// In-page `selector#id sibling-combinator selector` fails
3457		if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
3458			rbuggyQSA.push( ".#.+[+~]" );
3459		}
3460
3461		// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
3462		// In some of the document kinds, these selectors wouldn't work natively.
3463		// This is probably OK but for backwards compatibility we want to maintain
3464		// handling them through jQuery traversal in jQuery 3.x.
3465		if ( !el.querySelectorAll( ":checked" ).length ) {
3466			rbuggyQSA.push( ":checked" );
3467		}
3468
3469		// Support: Windows 8 Native Apps
3470		// The type and name attributes are restricted during .innerHTML assignment
3471		input = document.createElement( "input" );
3472		input.setAttribute( "type", "hidden" );
3473		el.appendChild( input ).setAttribute( "name", "D" );
3474
3475		// Support: IE 9 - 11+
3476		// IE's :disabled selector does not pick up the children of disabled fieldsets
3477		// Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
3478		// In some of the document kinds, these selectors wouldn't work natively.
3479		// This is probably OK but for backwards compatibility we want to maintain
3480		// handling them through jQuery traversal in jQuery 3.x.
3481		documentElement.appendChild( el ).disabled = true;
3482		if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
3483			rbuggyQSA.push( ":enabled", ":disabled" );
3484		}
3485
3486		// Support: IE 11+, Edge 15 - 18+
3487		// IE 11/Edge don't find elements on a `[name='']` query in some cases.
3488		// Adding a temporary attribute to the document before the selection works
3489		// around the issue.
3490		// Interestingly, IE 10 & older don't seem to have the issue.
3491		input = document.createElement( "input" );
3492		input.setAttribute( "name", "" );
3493		el.appendChild( input );
3494		if ( !el.querySelectorAll( "[name='']" ).length ) {
3495			rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
3496				whitespace + "*(?:''|\"\")" );
3497		}
3498	} );
3499
3500	if ( !support.cssHas ) {
3501
3502		// Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
3503		// Our regular `try-catch` mechanism fails to detect natively-unsupported
3504		// pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
3505		// in browsers that parse the `:has()` argument as a forgiving selector list.
3506		// https://drafts.csswg.org/selectors/#relational now requires the argument
3507		// to be parsed unforgivingly, but browsers have not yet fully adjusted.
3508		rbuggyQSA.push( ":has" );
3509	}
3510
3511	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
3512
3513	/* Sorting
3514	---------------------------------------------------------------------- */
3515
3516	// Document order sorting
3517	sortOrder = function( a, b ) {
3518
3519		// Flag for duplicate removal
3520		if ( a === b ) {
3521			hasDuplicate = true;
3522			return 0;
3523		}
3524
3525		// Sort on method existence if only one input has compareDocumentPosition
3526		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
3527		if ( compare ) {
3528			return compare;
3529		}
3530
3531		// Calculate position if both inputs belong to the same document
3532		// Support: IE 11+, Edge 17 - 18+
3533		// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3534		// two documents; shallow comparisons work.
3535		// eslint-disable-next-line eqeqeq
3536		compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
3537			a.compareDocumentPosition( b ) :
3538
3539			// Otherwise we know they are disconnected
3540			1;
3541
3542		// Disconnected nodes
3543		if ( compare & 1 ||
3544			( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
3545
3546			// Choose the first element that is related to our preferred document
3547			// Support: IE 11+, Edge 17 - 18+
3548			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3549			// two documents; shallow comparisons work.
3550			// eslint-disable-next-line eqeqeq
3551			if ( a === document || a.ownerDocument == preferredDoc &&
3552				find.contains( preferredDoc, a ) ) {
3553				return -1;
3554			}
3555
3556			// Support: IE 11+, Edge 17 - 18+
3557			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3558			// two documents; shallow comparisons work.
3559			// eslint-disable-next-line eqeqeq
3560			if ( b === document || b.ownerDocument == preferredDoc &&
3561				find.contains( preferredDoc, b ) ) {
3562				return 1;
3563			}
3564
3565			// Maintain original order
3566			return sortInput ?
3567				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
3568				0;
3569		}
3570
3571		return compare & 4 ? -1 : 1;
3572	};
3573
3574	return document;
3575}
3576
3577find.matches = function( expr, elements ) {
3578	return find( expr, null, null, elements );
3579};
3580
3581find.matchesSelector = function( elem, expr ) {
3582	setDocument( elem );
3583
3584	if ( documentIsHTML &&
3585		!nonnativeSelectorCache[ expr + " " ] &&
3586		( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
3587
3588		try {
3589			var ret = matches.call( elem, expr );
3590
3591			// IE 9's matchesSelector returns false on disconnected nodes
3592			if ( ret || support.disconnectedMatch ||
3593
3594					// As well, disconnected nodes are said to be in a document
3595					// fragment in IE 9
3596					elem.document && elem.document.nodeType !== 11 ) {
3597				return ret;
3598			}
3599		} catch ( e ) {
3600			nonnativeSelectorCache( expr, true );
3601		}
3602	}
3603
3604	return find( expr, document, null, [ elem ] ).length > 0;
3605};
3606
3607find.contains = function( context, elem ) {
3608
3609	// Set document vars if needed
3610	// Support: IE 11+, Edge 17 - 18+
3611	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3612	// two documents; shallow comparisons work.
3613	// eslint-disable-next-line eqeqeq
3614	if ( ( context.ownerDocument || context ) != document ) {
3615		setDocument( context );
3616	}
3617	return jQuery.contains( context, elem );
3618};
3619
3620
3621find.attr = function( elem, name ) {
3622
3623	// Set document vars if needed
3624	// Support: IE 11+, Edge 17 - 18+
3625	// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3626	// two documents; shallow comparisons work.
3627	// eslint-disable-next-line eqeqeq
3628	if ( ( elem.ownerDocument || elem ) != document ) {
3629		setDocument( elem );
3630	}
3631
3632	var fn = Expr.attrHandle[ name.toLowerCase() ],
3633
3634		// Don't get fooled by Object.prototype properties (see trac-13807)
3635		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
3636			fn( elem, name, !documentIsHTML ) :
3637			undefined;
3638
3639	if ( val !== undefined ) {
3640		return val;
3641	}
3642
3643	return elem.getAttribute( name );
3644};
3645
3646find.error = function( msg ) {
3647	throw new Error( "Syntax error, unrecognized expression: " + msg );
3648};
3649
3650/**
3651 * Document sorting and removing duplicates
3652 * @param {ArrayLike} results
3653 */
3654jQuery.uniqueSort = function( results ) {
3655	var elem,
3656		duplicates = [],
3657		j = 0,
3658		i = 0;
3659
3660	// Unless we *know* we can detect duplicates, assume their presence
3661	//
3662	// Support: Android <=4.0+
3663	// Testing for detecting duplicates is unpredictable so instead assume we can't
3664	// depend on duplicate detection in all browsers without a stable sort.
3665	hasDuplicate = !support.sortStable;
3666	sortInput = !support.sortStable && slice.call( results, 0 );
3667	sort.call( results, sortOrder );
3668
3669	if ( hasDuplicate ) {
3670		while ( ( elem = results[ i++ ] ) ) {
3671			if ( elem === results[ i ] ) {
3672				j = duplicates.push( i );
3673			}
3674		}
3675		while ( j-- ) {
3676			splice.call( results, duplicates[ j ], 1 );
3677		}
3678	}
3679
3680	// Clear input after sorting to release objects
3681	// See https://github.com/jquery/sizzle/pull/225
3682	sortInput = null;
3683
3684	return results;
3685};
3686
3687jQuery.fn.uniqueSort = function() {
3688	return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) );
3689};
3690
3691Expr = jQuery.expr = {
3692
3693	// Can be adjusted by the user
3694	cacheLength: 50,
3695
3696	createPseudo: markFunction,
3697
3698	match: matchExpr,
3699
3700	attrHandle: {},
3701
3702	find: {},
3703
3704	relative: {
3705		">": { dir: "parentNode", first: true },
3706		" ": { dir: "parentNode" },
3707		"+": { dir: "previousSibling", first: true },
3708		"~": { dir: "previousSibling" }
3709	},
3710
3711	preFilter: {
3712		ATTR: function( match ) {
3713			match[ 1 ] = match[ 1 ].replace( runescape, funescape );
3714
3715			// Move the given value to match[3] whether quoted or unquoted
3716			match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" )
3717				.replace( runescape, funescape );
3718
3719			if ( match[ 2 ] === "~=" ) {
3720				match[ 3 ] = " " + match[ 3 ] + " ";
3721			}
3722
3723			return match.slice( 0, 4 );
3724		},
3725
3726		CHILD: function( match ) {
3727
3728			/* matches from matchExpr["CHILD"]
3729				1 type (only|nth|...)
3730				2 what (child|of-type)
3731				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
3732				4 xn-component of xn+y argument ([+-]?\d*n|)
3733				5 sign of xn-component
3734				6 x of xn-component
3735				7 sign of y-component
3736				8 y of y-component
3737			*/
3738			match[ 1 ] = match[ 1 ].toLowerCase();
3739
3740			if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
3741
3742				// nth-* requires argument
3743				if ( !match[ 3 ] ) {
3744					find.error( match[ 0 ] );
3745				}
3746
3747				// numeric x and y parameters for Expr.filter.CHILD
3748				// remember that false/true cast respectively to 0/1
3749				match[ 4 ] = +( match[ 4 ] ?
3750					match[ 5 ] + ( match[ 6 ] || 1 ) :
3751					2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" )
3752				);
3753				match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
3754
3755			// other types prohibit arguments
3756			} else if ( match[ 3 ] ) {
3757				find.error( match[ 0 ] );
3758			}
3759
3760			return match;
3761		},
3762
3763		PSEUDO: function( match ) {
3764			var excess,
3765				unquoted = !match[ 6 ] && match[ 2 ];
3766
3767			if ( matchExpr.CHILD.test( match[ 0 ] ) ) {
3768				return null;
3769			}
3770
3771			// Accept quoted arguments as-is
3772			if ( match[ 3 ] ) {
3773				match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
3774
3775			// Strip excess characters from unquoted arguments
3776			} else if ( unquoted && rpseudo.test( unquoted ) &&
3777
3778				// Get excess from tokenize (recursively)
3779				( excess = tokenize( unquoted, true ) ) &&
3780
3781				// advance to the next closing parenthesis
3782				( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
3783
3784				// excess is a negative index
3785				match[ 0 ] = match[ 0 ].slice( 0, excess );
3786				match[ 2 ] = unquoted.slice( 0, excess );
3787			}
3788
3789			// Return only captures needed by the pseudo filter method (type and argument)
3790			return match.slice( 0, 3 );
3791		}
3792	},
3793
3794	filter: {
3795
3796		TAG: function( nodeNameSelector ) {
3797			var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
3798			return nodeNameSelector === "*" ?
3799				function() {
3800					return true;
3801				} :
3802				function( elem ) {
3803					return nodeName( elem, expectedNodeName );
3804				};
3805		},
3806
3807		CLASS: function( className ) {
3808			var pattern = classCache[ className + " " ];
3809
3810			return pattern ||
3811				( pattern = new RegExp( "(^|" + whitespace + ")" + className +
3812					"(" + whitespace + "|$)" ) ) &&
3813				classCache( className, function( elem ) {
3814					return pattern.test(
3815						typeof elem.className === "string" && elem.className ||
3816							typeof elem.getAttribute !== "undefined" &&
3817								elem.getAttribute( "class" ) ||
3818							""
3819					);
3820				} );
3821		},
3822
3823		ATTR: function( name, operator, check ) {
3824			return function( elem ) {
3825				var result = find.attr( elem, name );
3826
3827				if ( result == null ) {
3828					return operator === "!=";
3829				}
3830				if ( !operator ) {
3831					return true;
3832				}
3833
3834				result += "";
3835
3836				if ( operator === "=" ) {
3837					return result === check;
3838				}
3839				if ( operator === "!=" ) {
3840					return result !== check;
3841				}
3842				if ( operator === "^=" ) {
3843					return check && result.indexOf( check ) === 0;
3844				}
3845				if ( operator === "*=" ) {
3846					return check && result.indexOf( check ) > -1;
3847				}
3848				if ( operator === "$=" ) {
3849					return check && result.slice( -check.length ) === check;
3850				}
3851				if ( operator === "~=" ) {
3852					return ( " " + result.replace( rwhitespace, " " ) + " " )
3853						.indexOf( check ) > -1;
3854				}
3855				if ( operator === "|=" ) {
3856					return result === check || result.slice( 0, check.length + 1 ) === check + "-";
3857				}
3858
3859				return false;
3860			};
3861		},
3862
3863		CHILD: function( type, what, _argument, first, last ) {
3864			var simple = type.slice( 0, 3 ) !== "nth",
3865				forward = type.slice( -4 ) !== "last",
3866				ofType = what === "of-type";
3867
3868			return first === 1 && last === 0 ?
3869
3870				// Shortcut for :nth-*(n)
3871				function( elem ) {
3872					return !!elem.parentNode;
3873				} :
3874
3875				function( elem, _context, xml ) {
3876					var cache, outerCache, node, nodeIndex, start,
3877						dir = simple !== forward ? "nextSibling" : "previousSibling",
3878						parent = elem.parentNode,
3879						name = ofType && elem.nodeName.toLowerCase(),
3880						useCache = !xml && !ofType,
3881						diff = false;
3882
3883					if ( parent ) {
3884
3885						// :(first|last|only)-(child|of-type)
3886						if ( simple ) {
3887							while ( dir ) {
3888								node = elem;
3889								while ( ( node = node[ dir ] ) ) {
3890									if ( ofType ?
3891										nodeName( node, name ) :
3892										node.nodeType === 1 ) {
3893
3894										return false;
3895									}
3896								}
3897
3898								// Reverse direction for :only-* (if we haven't yet done so)
3899								start = dir = type === "only" && !start && "nextSibling";
3900							}
3901							return true;
3902						}
3903
3904						start = [ forward ? parent.firstChild : parent.lastChild ];
3905
3906						// non-xml :nth-child(...) stores cache data on `parent`
3907						if ( forward && useCache ) {
3908
3909							// Seek `elem` from a previously-cached index
3910							outerCache = parent[ expando ] || ( parent[ expando ] = {} );
3911							cache = outerCache[ type ] || [];
3912							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
3913							diff = nodeIndex && cache[ 2 ];
3914							node = nodeIndex && parent.childNodes[ nodeIndex ];
3915
3916							while ( ( node = ++nodeIndex && node && node[ dir ] ||
3917
3918								// Fallback to seeking `elem` from the start
3919								( diff = nodeIndex = 0 ) || start.pop() ) ) {
3920
3921								// When found, cache indexes on `parent` and break
3922								if ( node.nodeType === 1 && ++diff && node === elem ) {
3923									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
3924									break;
3925								}
3926							}
3927
3928						} else {
3929
3930							// Use previously-cached element index if available
3931							if ( useCache ) {
3932								outerCache = elem[ expando ] || ( elem[ expando ] = {} );
3933								cache = outerCache[ type ] || [];
3934								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
3935								diff = nodeIndex;
3936							}
3937
3938							// xml :nth-child(...)
3939							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
3940							if ( diff === false ) {
3941
3942								// Use the same loop as above to seek `elem` from the start
3943								while ( ( node = ++nodeIndex && node && node[ dir ] ||
3944									( diff = nodeIndex = 0 ) || start.pop() ) ) {
3945
3946									if ( ( ofType ?
3947										nodeName( node, name ) :
3948										node.nodeType === 1 ) &&
3949										++diff ) {
3950
3951										// Cache the index of each encountered element
3952										if ( useCache ) {
3953											outerCache = node[ expando ] ||
3954												( node[ expando ] = {} );
3955											outerCache[ type ] = [ dirruns, diff ];
3956										}
3957
3958										if ( node === elem ) {
3959											break;
3960										}
3961									}
3962								}
3963							}
3964						}
3965
3966						// Incorporate the offset, then check against cycle size
3967						diff -= last;
3968						return diff === first || ( diff % first === 0 && diff / first >= 0 );
3969					}
3970				};
3971		},
3972
3973		PSEUDO: function( pseudo, argument ) {
3974
3975			// pseudo-class names are case-insensitive
3976			// https://www.w3.org/TR/selectors/#pseudo-classes
3977			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
3978			// Remember that setFilters inherits from pseudos
3979			var args,
3980				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
3981					find.error( "unsupported pseudo: " + pseudo );
3982
3983			// The user may use createPseudo to indicate that
3984			// arguments are needed to create the filter function
3985			// just as jQuery does
3986			if ( fn[ expando ] ) {
3987				return fn( argument );
3988			}
3989
3990			// But maintain support for old signatures
3991			if ( fn.length > 1 ) {
3992				args = [ pseudo, pseudo, "", argument ];
3993				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
3994					markFunction( function( seed, matches ) {
3995						var idx,
3996							matched = fn( seed, argument ),
3997							i = matched.length;
3998						while ( i-- ) {
3999							idx = indexOf.call( seed, matched[ i ] );
4000							seed[ idx ] = !( matches[ idx ] = matched[ i ] );
4001						}
4002					} ) :
4003					function( elem ) {
4004						return fn( elem, 0, args );
4005					};
4006			}
4007
4008			return fn;
4009		}
4010	},
4011
4012	pseudos: {
4013
4014		// Potentially complex pseudos
4015		not: markFunction( function( selector ) {
4016
4017			// Trim the selector passed to compile
4018			// to avoid treating leading and trailing
4019			// spaces as combinators
4020			var input = [],
4021				results = [],
4022				matcher = compile( selector.replace( rtrimCSS, "$1" ) );
4023
4024			return matcher[ expando ] ?
4025				markFunction( function( seed, matches, _context, xml ) {
4026					var elem,
4027						unmatched = matcher( seed, null, xml, [] ),
4028						i = seed.length;
4029
4030					// Match elements unmatched by `matcher`
4031					while ( i-- ) {
4032						if ( ( elem = unmatched[ i ] ) ) {
4033							seed[ i ] = !( matches[ i ] = elem );
4034						}
4035					}
4036				} ) :
4037				function( elem, _context, xml ) {
4038					input[ 0 ] = elem;
4039					matcher( input, null, xml, results );
4040
4041					// Don't keep the element
4042					// (see https://github.com/jquery/sizzle/issues/299)
4043					input[ 0 ] = null;
4044					return !results.pop();
4045				};
4046		} ),
4047
4048		has: markFunction( function( selector ) {
4049			return function( elem ) {
4050				return find( selector, elem ).length > 0;
4051			};
4052		} ),
4053
4054		contains: markFunction( function( text ) {
4055			text = text.replace( runescape, funescape );
4056			return function( elem ) {
4057				return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1;
4058			};
4059		} ),
4060
4061		// "Whether an element is represented by a :lang() selector
4062		// is based solely on the element's language value
4063		// being equal to the identifier C,
4064		// or beginning with the identifier C immediately followed by "-".
4065		// The matching of C against the element's language value is performed case-insensitively.
4066		// The identifier C does not have to be a valid language name."
4067		// https://www.w3.org/TR/selectors/#lang-pseudo
4068		lang: markFunction( function( lang ) {
4069
4070			// lang value must be a valid identifier
4071			if ( !ridentifier.test( lang || "" ) ) {
4072				find.error( "unsupported lang: " + lang );
4073			}
4074			lang = lang.replace( runescape, funescape ).toLowerCase();
4075			return function( elem ) {
4076				var elemLang;
4077				do {
4078					if ( ( elemLang = documentIsHTML ?
4079						elem.lang :
4080						elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
4081
4082						elemLang = elemLang.toLowerCase();
4083						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
4084					}
4085				} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
4086				return false;
4087			};
4088		} ),
4089
4090		// Miscellaneous
4091		target: function( elem ) {
4092			var hash = window.location && window.location.hash;
4093			return hash && hash.slice( 1 ) === elem.id;
4094		},
4095
4096		root: function( elem ) {
4097			return elem === documentElement;
4098		},
4099
4100		focus: function( elem ) {
4101			return elem === safeActiveElement() &&
4102				document.hasFocus() &&
4103				!!( elem.type || elem.href || ~elem.tabIndex );
4104		},
4105
4106		// Boolean properties
4107		enabled: createDisabledPseudo( false ),
4108		disabled: createDisabledPseudo( true ),
4109
4110		checked: function( elem ) {
4111
4112			// In CSS3, :checked should return both checked and selected elements
4113			// https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
4114			return ( nodeName( elem, "input" ) && !!elem.checked ) ||
4115				( nodeName( elem, "option" ) && !!elem.selected );
4116		},
4117
4118		selected: function( elem ) {
4119
4120			// Support: IE <=11+
4121			// Accessing the selectedIndex property
4122			// forces the browser to treat the default option as
4123			// selected when in an optgroup.
4124			if ( elem.parentNode ) {
4125				// eslint-disable-next-line no-unused-expressions
4126				elem.parentNode.selectedIndex;
4127			}
4128
4129			return elem.selected === true;
4130		},
4131
4132		// Contents
4133		empty: function( elem ) {
4134
4135			// https://www.w3.org/TR/selectors/#empty-pseudo
4136			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
4137			//   but not by others (comment: 8; processing instruction: 7; etc.)
4138			// nodeType < 6 works because attributes (2) do not appear as children
4139			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
4140				if ( elem.nodeType < 6 ) {
4141					return false;
4142				}
4143			}
4144			return true;
4145		},
4146
4147		parent: function( elem ) {
4148			return !Expr.pseudos.empty( elem );
4149		},
4150
4151		// Element/input types
4152		header: function( elem ) {
4153			return rheader.test( elem.nodeName );
4154		},
4155
4156		input: function( elem ) {
4157			return rinputs.test( elem.nodeName );
4158		},
4159
4160		button: function( elem ) {
4161			return nodeName( elem, "input" ) && elem.type === "button" ||
4162				nodeName( elem, "button" );
4163		},
4164
4165		text: function( elem ) {
4166			var attr;
4167			return nodeName( elem, "input" ) && elem.type === "text" &&
4168
4169				// Support: IE <10 only
4170				// New HTML5 attribute values (e.g., "search") appear
4171				// with elem.type === "text"
4172				( ( attr = elem.getAttribute( "type" ) ) == null ||
4173					attr.toLowerCase() === "text" );
4174		},
4175
4176		// Position-in-collection
4177		first: createPositionalPseudo( function() {
4178			return [ 0 ];
4179		} ),
4180
4181		last: createPositionalPseudo( function( _matchIndexes, length ) {
4182			return [ length - 1 ];
4183		} ),
4184
4185		eq: createPositionalPseudo( function( _matchIndexes, length, argument ) {
4186			return [ argument < 0 ? argument + length : argument ];
4187		} ),
4188
4189		even: createPositionalPseudo( function( matchIndexes, length ) {
4190			var i = 0;
4191			for ( ; i < length; i += 2 ) {
4192				matchIndexes.push( i );
4193			}
4194			return matchIndexes;
4195		} ),
4196
4197		odd: createPositionalPseudo( function( matchIndexes, length ) {
4198			var i = 1;
4199			for ( ; i < length; i += 2 ) {
4200				matchIndexes.push( i );
4201			}
4202			return matchIndexes;
4203		} ),
4204
4205		lt: createPositionalPseudo( function( matchIndexes, length, argument ) {
4206			var i;
4207
4208			if ( argument < 0 ) {
4209				i = argument + length;
4210			} else if ( argument > length ) {
4211				i = length;
4212			} else {
4213				i = argument;
4214			}
4215
4216			for ( ; --i >= 0; ) {
4217				matchIndexes.push( i );
4218			}
4219			return matchIndexes;
4220		} ),
4221
4222		gt: createPositionalPseudo( function( matchIndexes, length, argument ) {
4223			var i = argument < 0 ? argument + length : argument;
4224			for ( ; ++i < length; ) {
4225				matchIndexes.push( i );
4226			}
4227			return matchIndexes;
4228		} )
4229	}
4230};
4231
4232Expr.pseudos.nth = Expr.pseudos.eq;
4233
4234// Add button/input type pseudos
4235for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
4236	Expr.pseudos[ i ] = createInputPseudo( i );
4237}
4238for ( i in { submit: true, reset: true } ) {
4239	Expr.pseudos[ i ] = createButtonPseudo( i );
4240}
4241
4242// Easy API for creating new setFilters
4243function setFilters() {}
4244setFilters.prototype = Expr.filters = Expr.pseudos;
4245Expr.setFilters = new setFilters();
4246
4247function tokenize( selector, parseOnly ) {
4248	var matched, match, tokens, type,
4249		soFar, groups, preFilters,
4250		cached = tokenCache[ selector + " " ];
4251
4252	if ( cached ) {
4253		return parseOnly ? 0 : cached.slice( 0 );
4254	}
4255
4256	soFar = selector;
4257	groups = [];
4258	preFilters = Expr.preFilter;
4259
4260	while ( soFar ) {
4261
4262		// Comma and first run
4263		if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
4264			if ( match ) {
4265
4266				// Don't consume trailing commas as valid
4267				soFar = soFar.slice( match[ 0 ].length ) || soFar;
4268			}
4269			groups.push( ( tokens = [] ) );
4270		}
4271
4272		matched = false;
4273
4274		// Combinators
4275		if ( ( match = rleadingCombinator.exec( soFar ) ) ) {
4276			matched = match.shift();
4277			tokens.push( {
4278				value: matched,
4279
4280				// Cast descendant combinators to space
4281				type: match[ 0 ].replace( rtrimCSS, " " )
4282			} );
4283			soFar = soFar.slice( matched.length );
4284		}
4285
4286		// Filters
4287		for ( type in Expr.filter ) {
4288			if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
4289				( match = preFilters[ type ]( match ) ) ) ) {
4290				matched = match.shift();
4291				tokens.push( {
4292					value: matched,
4293					type: type,
4294					matches: match
4295				} );
4296				soFar = soFar.slice( matched.length );
4297			}
4298		}
4299
4300		if ( !matched ) {
4301			break;
4302		}
4303	}
4304
4305	// Return the length of the invalid excess
4306	// if we're just parsing
4307	// Otherwise, throw an error or return tokens
4308	if ( parseOnly ) {
4309		return soFar.length;
4310	}
4311
4312	return soFar ?
4313		find.error( selector ) :
4314
4315		// Cache the tokens
4316		tokenCache( selector, groups ).slice( 0 );
4317}
4318
4319function toSelector( tokens ) {
4320	var i = 0,
4321		len = tokens.length,
4322		selector = "";
4323	for ( ; i < len; i++ ) {
4324		selector += tokens[ i ].value;
4325	}
4326	return selector;
4327}
4328
4329function addCombinator( matcher, combinator, base ) {
4330	var dir = combinator.dir,
4331		skip = combinator.next,
4332		key = skip || dir,
4333		checkNonElements = base && key === "parentNode",
4334		doneName = done++;
4335
4336	return combinator.first ?
4337
4338		// Check against closest ancestor/preceding element
4339		function( elem, context, xml ) {
4340			while ( ( elem = elem[ dir ] ) ) {
4341				if ( elem.nodeType === 1 || checkNonElements ) {
4342					return matcher( elem, context, xml );
4343				}
4344			}
4345			return false;
4346		} :
4347
4348		// Check against all ancestor/preceding elements
4349		function( elem, context, xml ) {
4350			var oldCache, outerCache,
4351				newCache = [ dirruns, doneName ];
4352
4353			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
4354			if ( xml ) {
4355				while ( ( elem = elem[ dir ] ) ) {
4356					if ( elem.nodeType === 1 || checkNonElements ) {
4357						if ( matcher( elem, context, xml ) ) {
4358							return true;
4359						}
4360					}
4361				}
4362			} else {
4363				while ( ( elem = elem[ dir ] ) ) {
4364					if ( elem.nodeType === 1 || checkNonElements ) {
4365						outerCache = elem[ expando ] || ( elem[ expando ] = {} );
4366
4367						if ( skip && nodeName( elem, skip ) ) {
4368							elem = elem[ dir ] || elem;
4369						} else if ( ( oldCache = outerCache[ key ] ) &&
4370							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
4371
4372							// Assign to newCache so results back-propagate to previous elements
4373							return ( newCache[ 2 ] = oldCache[ 2 ] );
4374						} else {
4375
4376							// Reuse newcache so results back-propagate to previous elements
4377							outerCache[ key ] = newCache;
4378
4379							// A match means we're done; a fail means we have to keep checking
4380							if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
4381								return true;
4382							}
4383						}
4384					}
4385				}
4386			}
4387			return false;
4388		};
4389}
4390
4391function elementMatcher( matchers ) {
4392	return matchers.length > 1 ?
4393		function( elem, context, xml ) {
4394			var i = matchers.length;
4395			while ( i-- ) {
4396				if ( !matchers[ i ]( elem, context, xml ) ) {
4397					return false;
4398				}
4399			}
4400			return true;
4401		} :
4402		matchers[ 0 ];
4403}
4404
4405function multipleContexts( selector, contexts, results ) {
4406	var i = 0,
4407		len = contexts.length;
4408	for ( ; i < len; i++ ) {
4409		find( selector, contexts[ i ], results );
4410	}
4411	return results;
4412}
4413
4414function condense( unmatched, map, filter, context, xml ) {
4415	var elem,
4416		newUnmatched = [],
4417		i = 0,
4418		len = unmatched.length,
4419		mapped = map != null;
4420
4421	for ( ; i < len; i++ ) {
4422		if ( ( elem = unmatched[ i ] ) ) {
4423			if ( !filter || filter( elem, context, xml ) ) {
4424				newUnmatched.push( elem );
4425				if ( mapped ) {
4426					map.push( i );
4427				}
4428			}
4429		}
4430	}
4431
4432	return newUnmatched;
4433}
4434
4435function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
4436	if ( postFilter && !postFilter[ expando ] ) {
4437		postFilter = setMatcher( postFilter );
4438	}
4439	if ( postFinder && !postFinder[ expando ] ) {
4440		postFinder = setMatcher( postFinder, postSelector );
4441	}
4442	return markFunction( function( seed, results, context, xml ) {
4443		var temp, i, elem, matcherOut,
4444			preMap = [],
4445			postMap = [],
4446			preexisting = results.length,
4447
4448			// Get initial elements from seed or context
4449			elems = seed ||
4450				multipleContexts( selector || "*",
4451					context.nodeType ? [ context ] : context, [] ),
4452
4453			// Prefilter to get matcher input, preserving a map for seed-results synchronization
4454			matcherIn = preFilter && ( seed || !selector ) ?
4455				condense( elems, preMap, preFilter, context, xml ) :
4456				elems;
4457
4458		if ( matcher ) {
4459
4460			// If we have a postFinder, or filtered seed, or non-seed postFilter
4461			// or preexisting results,
4462			matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
4463
4464				// ...intermediate processing is necessary
4465				[] :
4466
4467				// ...otherwise use results directly
4468				results;
4469
4470			// Find primary matches
4471			matcher( matcherIn, matcherOut, context, xml );
4472		} else {
4473			matcherOut = matcherIn;
4474		}
4475
4476		// Apply postFilter
4477		if ( postFilter ) {
4478			temp = condense( matcherOut, postMap );
4479			postFilter( temp, [], context, xml );
4480
4481			// Un-match failing elements by moving them back to matcherIn
4482			i = temp.length;
4483			while ( i-- ) {
4484				if ( ( elem = temp[ i ] ) ) {
4485					matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
4486				}
4487			}
4488		}
4489
4490		if ( seed ) {
4491			if ( postFinder || preFilter ) {
4492				if ( postFinder ) {
4493
4494					// Get the final matcherOut by condensing this intermediate into postFinder contexts
4495					temp = [];
4496					i = matcherOut.length;
4497					while ( i-- ) {
4498						if ( ( elem = matcherOut[ i ] ) ) {
4499
4500							// Restore matcherIn since elem is not yet a final match
4501							temp.push( ( matcherIn[ i ] = elem ) );
4502						}
4503					}
4504					postFinder( null, ( matcherOut = [] ), temp, xml );
4505				}
4506
4507				// Move matched elements from seed to results to keep them synchronized
4508				i = matcherOut.length;
4509				while ( i-- ) {
4510					if ( ( elem = matcherOut[ i ] ) &&
4511						( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) {
4512
4513						seed[ temp ] = !( results[ temp ] = elem );
4514					}
4515				}
4516			}
4517
4518		// Add elements to results, through postFinder if defined
4519		} else {
4520			matcherOut = condense(
4521				matcherOut === results ?
4522					matcherOut.splice( preexisting, matcherOut.length ) :
4523					matcherOut
4524			);
4525			if ( postFinder ) {
4526				postFinder( null, results, matcherOut, xml );
4527			} else {
4528				push.apply( results, matcherOut );
4529			}
4530		}
4531	} );
4532}
4533
4534function matcherFromTokens( tokens ) {
4535	var checkContext, matcher, j,
4536		len = tokens.length,
4537		leadingRelative = Expr.relative[ tokens[ 0 ].type ],
4538		implicitRelative = leadingRelative || Expr.relative[ " " ],
4539		i = leadingRelative ? 1 : 0,
4540
4541		// The foundational matcher ensures that elements are reachable from top-level context(s)
4542		matchContext = addCombinator( function( elem ) {
4543			return elem === checkContext;
4544		}, implicitRelative, true ),
4545		matchAnyContext = addCombinator( function( elem ) {
4546			return indexOf.call( checkContext, elem ) > -1;
4547		}, implicitRelative, true ),
4548		matchers = [ function( elem, context, xml ) {
4549
4550			// Support: IE 11+, Edge 17 - 18+
4551			// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
4552			// two documents; shallow comparisons work.
4553			// eslint-disable-next-line eqeqeq
4554			var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || (
4555				( checkContext = context ).nodeType ?
4556					matchContext( elem, context, xml ) :
4557					matchAnyContext( elem, context, xml ) );
4558
4559			// Avoid hanging onto element
4560			// (see https://github.com/jquery/sizzle/issues/299)
4561			checkContext = null;
4562			return ret;
4563		} ];
4564
4565	for ( ; i < len; i++ ) {
4566		if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
4567			matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
4568		} else {
4569			matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
4570
4571			// Return special upon seeing a positional matcher
4572			if ( matcher[ expando ] ) {
4573
4574				// Find the next relative operator (if any) for proper handling
4575				j = ++i;
4576				for ( ; j < len; j++ ) {
4577					if ( Expr.relative[ tokens[ j ].type ] ) {
4578						break;
4579					}
4580				}
4581				return setMatcher(
4582					i > 1 && elementMatcher( matchers ),
4583					i > 1 && toSelector(
4584
4585						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
4586						tokens.slice( 0, i - 1 )
4587							.concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
4588					).replace( rtrimCSS, "$1" ),
4589					matcher,
4590					i < j && matcherFromTokens( tokens.slice( i, j ) ),
4591					j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
4592					j < len && toSelector( tokens )
4593				);
4594			}
4595			matchers.push( matcher );
4596		}
4597	}
4598
4599	return elementMatcher( matchers );
4600}
4601
4602function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
4603	var bySet = setMatchers.length > 0,
4604		byElement = elementMatchers.length > 0,
4605		superMatcher = function( seed, context, xml, results, outermost ) {
4606			var elem, j, matcher,
4607				matchedCount = 0,
4608				i = "0",
4609				unmatched = seed && [],
4610				setMatched = [],
4611				contextBackup = outermostContext,
4612
4613				// We must always have either seed elements or outermost context
4614				elems = seed || byElement && Expr.find.TAG( "*", outermost ),
4615
4616				// Use integer dirruns iff this is the outermost matcher
4617				dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
4618				len = elems.length;
4619
4620			if ( outermost ) {
4621
4622				// Support: IE 11+, Edge 17 - 18+
4623				// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
4624				// two documents; shallow comparisons work.
4625				// eslint-disable-next-line eqeqeq
4626				outermostContext = context == document || context || outermost;
4627			}
4628
4629			// Add elements passing elementMatchers directly to results
4630			// Support: iOS <=7 - 9 only
4631			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching
4632			// elements by id. (see trac-14142)
4633			for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
4634				if ( byElement && elem ) {
4635					j = 0;
4636
4637					// Support: IE 11+, Edge 17 - 18+
4638					// IE/Edge sometimes throw a "Permission denied" error when strict-comparing
4639					// two documents; shallow comparisons work.
4640					// eslint-disable-next-line eqeqeq
4641					if ( !context && elem.ownerDocument != document ) {
4642						setDocument( elem );
4643						xml = !documentIsHTML;
4644					}
4645					while ( ( matcher = elementMatchers[ j++ ] ) ) {
4646						if ( matcher( elem, context || document, xml ) ) {
4647							push.call( results, elem );
4648							break;
4649						}
4650					}
4651					if ( outermost ) {
4652						dirruns = dirrunsUnique;
4653					}
4654				}
4655
4656				// Track unmatched elements for set filters
4657				if ( bySet ) {
4658
4659					// They will have gone through all possible matchers
4660					if ( ( elem = !matcher && elem ) ) {
4661						matchedCount--;
4662					}
4663
4664					// Lengthen the array for every element, matched or not
4665					if ( seed ) {
4666						unmatched.push( elem );
4667					}
4668				}
4669			}
4670
4671			// `i` is now the count of elements visited above, and adding it to `matchedCount`
4672			// makes the latter nonnegative.
4673			matchedCount += i;
4674
4675			// Apply set filters to unmatched elements
4676			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
4677			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
4678			// no element matchers and no seed.
4679			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
4680			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
4681			// numerically zero.
4682			if ( bySet && i !== matchedCount ) {
4683				j = 0;
4684				while ( ( matcher = setMatchers[ j++ ] ) ) {
4685					matcher( unmatched, setMatched, context, xml );
4686				}
4687
4688				if ( seed ) {
4689
4690					// Reintegrate element matches to eliminate the need for sorting
4691					if ( matchedCount > 0 ) {
4692						while ( i-- ) {
4693							if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
4694								setMatched[ i ] = pop.call( results );
4695							}
4696						}
4697					}
4698
4699					// Discard index placeholder values to get only actual matches
4700					setMatched = condense( setMatched );
4701				}
4702
4703				// Add matches to results
4704				push.apply( results, setMatched );
4705
4706				// Seedless set matches succeeding multiple successful matchers stipulate sorting
4707				if ( outermost && !seed && setMatched.length > 0 &&
4708					( matchedCount + setMatchers.length ) > 1 ) {
4709
4710					jQuery.uniqueSort( results );
4711				}
4712			}
4713
4714			// Override manipulation of globals by nested matchers
4715			if ( outermost ) {
4716				dirruns = dirrunsUnique;
4717				outermostContext = contextBackup;
4718			}
4719
4720			return unmatched;
4721		};
4722
4723	return bySet ?
4724		markFunction( superMatcher ) :
4725		superMatcher;
4726}
4727
4728function compile( selector, match /* Internal Use Only */ ) {
4729	var i,
4730		setMatchers = [],
4731		elementMatchers = [],
4732		cached = compilerCache[ selector + " " ];
4733
4734	if ( !cached ) {
4735
4736		// Generate a function of recursive functions that can be used to check each element
4737		if ( !match ) {
4738			match = tokenize( selector );
4739		}
4740		i = match.length;
4741		while ( i-- ) {
4742			cached = matcherFromTokens( match[ i ] );
4743			if ( cached[ expando ] ) {
4744				setMatchers.push( cached );
4745			} else {
4746				elementMatchers.push( cached );
4747			}
4748		}
4749
4750		// Cache the compiled function
4751		cached = compilerCache( selector,
4752			matcherFromGroupMatchers( elementMatchers, setMatchers ) );
4753
4754		// Save selector and tokenization
4755		cached.selector = selector;
4756	}
4757	return cached;
4758}
4759
4760/**
4761 * A low-level selection function that works with jQuery's compiled
4762 *  selector functions
4763 * @param {String|Function} selector A selector or a pre-compiled
4764 *  selector function built with jQuery selector compile
4765 * @param {Element} context
4766 * @param {Array} [results]
4767 * @param {Array} [seed] A set of elements to match against
4768 */
4769function select( selector, context, results, seed ) {
4770	var i, tokens, token, type, find,
4771		compiled = typeof selector === "function" && selector,
4772		match = !seed && tokenize( ( selector = compiled.selector || selector ) );
4773
4774	results = results || [];
4775
4776	// Try to minimize operations if there is only one selector in the list and no seed
4777	// (the latter of which guarantees us context)
4778	if ( match.length === 1 ) {
4779
4780		// Reduce context if the leading compound selector is an ID
4781		tokens = match[ 0 ] = match[ 0 ].slice( 0 );
4782		if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
4783				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
4784
4785			context = ( Expr.find.ID(
4786				token.matches[ 0 ].replace( runescape, funescape ),
4787				context
4788			) || [] )[ 0 ];
4789			if ( !context ) {
4790				return results;
4791
4792			// Precompiled matchers will still verify ancestry, so step up a level
4793			} else if ( compiled ) {
4794				context = context.parentNode;
4795			}
4796
4797			selector = selector.slice( tokens.shift().value.length );
4798		}
4799
4800		// Fetch a seed set for right-to-left matching
4801		i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length;
4802		while ( i-- ) {
4803			token = tokens[ i ];
4804
4805			// Abort if we hit a combinator
4806			if ( Expr.relative[ ( type = token.type ) ] ) {
4807				break;
4808			}
4809			if ( ( find = Expr.find[ type ] ) ) {
4810
4811				// Search, expanding context for leading sibling combinators
4812				if ( ( seed = find(
4813					token.matches[ 0 ].replace( runescape, funescape ),
4814					rsibling.test( tokens[ 0 ].type ) &&
4815						testContext( context.parentNode ) || context
4816				) ) ) {
4817
4818					// If seed is empty or no tokens remain, we can return early
4819					tokens.splice( i, 1 );
4820					selector = seed.length && toSelector( tokens );
4821					if ( !selector ) {
4822						push.apply( results, seed );
4823						return results;
4824					}
4825
4826					break;
4827				}
4828			}
4829		}
4830	}
4831
4832	// Compile and execute a filtering function if one is not provided
4833	// Provide `match` to avoid retokenization if we modified the selector above
4834	( compiled || compile( selector, match ) )(
4835		seed,
4836		context,
4837		!documentIsHTML,
4838		results,
4839		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
4840	);
4841	return results;
4842}
4843
4844// One-time assignments
4845
4846// Support: Android <=4.0 - 4.1+
4847// Sort stability
4848support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
4849
4850// Initialize against the default document
4851setDocument();
4852
4853// Support: Android <=4.0 - 4.1+
4854// Detached nodes confoundingly follow *each other*
4855support.sortDetached = assert( function( el ) {
4856
4857	// Should return 1, but returns 4 (following)
4858	return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
4859} );
4860
4861jQuery.find = find;
4862
4863// Deprecated
4864jQuery.expr[ ":" ] = jQuery.expr.pseudos;
4865jQuery.unique = jQuery.uniqueSort;
4866
4867// These have always been private, but they used to be documented as part of
4868// Sizzle so let's maintain them for now for backwards compatibility purposes.
4869find.compile = compile;
4870find.select = select;
4871find.setDocument = setDocument;
4872find.tokenize = tokenize;
4873
4874find.escape = jQuery.escapeSelector;
4875find.getText = jQuery.text;
4876find.isXML = jQuery.isXMLDoc;
4877find.selectors = jQuery.expr;
4878find.support = jQuery.support;
4879find.uniqueSort = jQuery.uniqueSort;
4880
4881	/* eslint-enable */
4882
4883} )();
4884
4885
4886var dir = function( elem, dir, until ) {
4887	var matched = [],
4888		truncate = until !== undefined;
4889
4890	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
4891		if ( elem.nodeType === 1 ) {
4892			if ( truncate && jQuery( elem ).is( until ) ) {
4893				break;
4894			}
4895			matched.push( elem );
4896		}
4897	}
4898	return matched;
4899};
4900
4901
4902var siblings = function( n, elem ) {
4903	var matched = [];
4904
4905	for ( ; n; n = n.nextSibling ) {
4906		if ( n.nodeType === 1 && n !== elem ) {
4907			matched.push( n );
4908		}
4909	}
4910
4911	return matched;
4912};
4913
4914
4915var rneedsContext = jQuery.expr.match.needsContext;
4916
4917var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
4918
4919
4920
4921// Implement the identical functionality for filter and not
4922function winnow( elements, qualifier, not ) {
4923	if ( isFunction( qualifier ) ) {
4924		return jQuery.grep( elements, function( elem, i ) {
4925			return !!qualifier.call( elem, i, elem ) !== not;
4926		} );
4927	}
4928
4929	// Single element
4930	if ( qualifier.nodeType ) {
4931		return jQuery.grep( elements, function( elem ) {
4932			return ( elem === qualifier ) !== not;
4933		} );
4934	}
4935
4936	// Arraylike of elements (jQuery, arguments, Array)
4937	if ( typeof qualifier !== "string" ) {
4938		return jQuery.grep( elements, function( elem ) {
4939			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
4940		} );
4941	}
4942
4943	// Filtered directly for both simple and complex selectors
4944	return jQuery.filter( qualifier, elements, not );
4945}
4946
4947jQuery.filter = function( expr, elems, not ) {
4948	var elem = elems[ 0 ];
4949
4950	if ( not ) {
4951		expr = ":not(" + expr + ")";
4952	}
4953
4954	if ( elems.length === 1 && elem.nodeType === 1 ) {
4955		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
4956	}
4957
4958	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
4959		return elem.nodeType === 1;
4960	} ) );
4961};
4962
4963jQuery.fn.extend( {
4964	find: function( selector ) {
4965		var i, ret,
4966			len = this.length,
4967			self = this;
4968
4969		if ( typeof selector !== "string" ) {
4970			return this.pushStack( jQuery( selector ).filter( function() {
4971				for ( i = 0; i < len; i++ ) {
4972					if ( jQuery.contains( self[ i ], this ) ) {
4973						return true;
4974					}
4975				}
4976			} ) );
4977		}
4978
4979		ret = this.pushStack( [] );
4980
4981		for ( i = 0; i < len; i++ ) {
4982			jQuery.find( selector, self[ i ], ret );
4983		}
4984
4985		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
4986	},
4987	filter: function( selector ) {
4988		return this.pushStack( winnow( this, selector || [], false ) );
4989	},
4990	not: function( selector ) {
4991		return this.pushStack( winnow( this, selector || [], true ) );
4992	},
4993	is: function( selector ) {
4994		return !!winnow(
4995			this,
4996
4997			// If this is a positional/relative selector, check membership in the returned set
4998			// so $("p:first").is("p:last") won't return true for a doc with two "p".
4999			typeof selector === "string" && rneedsContext.test( selector ) ?
5000				jQuery( selector ) :
5001				selector || [],
5002			false
5003		).length;
5004	}
5005} );
5006
5007
5008// Initialize a jQuery object
5009
5010
5011// A central reference to the root jQuery(document)
5012var rootjQuery,
5013
5014	// A simple way to check for HTML strings
5015	// Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
5016	// Strict HTML recognition (trac-11290: must start with <)
5017	// Shortcut simple #id case for speed
5018	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
5019
5020	init = jQuery.fn.init = function( selector, context, root ) {
5021		var match, elem;
5022
5023		// HANDLE: $(""), $(null), $(undefined), $(false)
5024		if ( !selector ) {
5025			return this;
5026		}
5027
5028		// Method init() accepts an alternate rootjQuery
5029		// so migrate can support jQuery.sub (gh-2101)
5030		root = root || rootjQuery;
5031
5032		// Handle HTML strings
5033		if ( typeof selector === "string" ) {
5034			if ( selector[ 0 ] === "<" &&
5035				selector[ selector.length - 1 ] === ">" &&
5036				selector.length >= 3 ) {
5037
5038				// Assume that strings that start and end with <> are HTML and skip the regex check
5039				match = [ null, selector, null ];
5040
5041			} else {
5042				match = rquickExpr.exec( selector );
5043			}
5044
5045			// Match html or make sure no context is specified for #id
5046			if ( match && ( match[ 1 ] || !context ) ) {
5047
5048				// HANDLE: $(html) -> $(array)
5049				if ( match[ 1 ] ) {
5050					context = context instanceof jQuery ? context[ 0 ] : context;
5051
5052					// Option to run scripts is true for back-compat
5053					// Intentionally let the error be thrown if parseHTML is not present
5054					jQuery.merge( this, jQuery.parseHTML(
5055						match[ 1 ],
5056						context && context.nodeType ? context.ownerDocument || context : document,
5057						true
5058					) );
5059
5060					// HANDLE: $(html, props)
5061					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
5062						for ( match in context ) {
5063
5064							// Properties of context are called as methods if possible
5065							if ( isFunction( this[ match ] ) ) {
5066								this[ match ]( context[ match ] );
5067
5068							// ...and otherwise set as attributes
5069							} else {
5070								this.attr( match, context[ match ] );
5071							}
5072						}
5073					}
5074
5075					return this;
5076
5077				// HANDLE: $(#id)
5078				} else {
5079					elem = document.getElementById( match[ 2 ] );
5080
5081					if ( elem ) {
5082
5083						// Inject the element directly into the jQuery object
5084						this[ 0 ] = elem;
5085						this.length = 1;
5086					}
5087					return this;
5088				}
5089
5090			// HANDLE: $(expr, $(...))
5091			} else if ( !context || context.jquery ) {
5092				return ( context || root ).find( selector );
5093
5094			// HANDLE: $(expr, context)
5095			// (which is just equivalent to: $(context).find(expr)
5096			} else {
5097				return this.constructor( context ).find( selector );
5098			}
5099
5100		// HANDLE: $(DOMElement)
5101		} else if ( selector.nodeType ) {
5102			this[ 0 ] = selector;
5103			this.length = 1;
5104			return this;
5105
5106		// HANDLE: $(function)
5107		// Shortcut for document ready
5108		} else if ( isFunction( selector ) ) {
5109			return root.ready !== undefined ?
5110				root.ready( selector ) :
5111
5112				// Execute immediately if ready is not present
5113				selector( jQuery );
5114		}
5115
5116		return jQuery.makeArray( selector, this );
5117	};
5118
5119// Give the init function the jQuery prototype for later instantiation
5120init.prototype = jQuery.fn;
5121
5122// Initialize central reference
5123rootjQuery = jQuery( document );
5124
5125
5126var rparentsprev = /^(?:parents|prev(?:Until|All))/,
5127
5128	// Methods guaranteed to produce a unique set when starting from a unique set
5129	guaranteedUnique = {
5130		children: true,
5131		contents: true,
5132		next: true,
5133		prev: true
5134	};
5135
5136jQuery.fn.extend( {
5137	has: function( target ) {
5138		var targets = jQuery( target, this ),
5139			l = targets.length;
5140
5141		return this.filter( function() {
5142			var i = 0;
5143			for ( ; i < l; i++ ) {
5144				if ( jQuery.contains( this, targets[ i ] ) ) {
5145					return true;
5146				}
5147			}
5148		} );
5149	},
5150
5151	closest: function( selectors, context ) {
5152		var cur,
5153			i = 0,
5154			l = this.length,
5155			matched = [],
5156			targets = typeof selectors !== "string" && jQuery( selectors );
5157
5158		// Positional selectors never match, since there's no _selection_ context
5159		if ( !rneedsContext.test( selectors ) ) {
5160			for ( ; i < l; i++ ) {
5161				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
5162
5163					// Always skip document fragments
5164					if ( cur.nodeType < 11 && ( targets ?
5165						targets.index( cur ) > -1 :
5166
5167						// Don't pass non-elements to jQuery#find
5168						cur.nodeType === 1 &&
5169							jQuery.find.matchesSelector( cur, selectors ) ) ) {
5170
5171						matched.push( cur );
5172						break;
5173					}
5174				}
5175			}
5176		}
5177
5178		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
5179	},
5180
5181	// Determine the position of an element within the set
5182	index: function( elem ) {
5183
5184		// No argument, return index in parent
5185		if ( !elem ) {
5186			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
5187		}
5188
5189		// Index in selector
5190		if ( typeof elem === "string" ) {
5191			return indexOf.call( jQuery( elem ), this[ 0 ] );
5192		}
5193
5194		// Locate the position of the desired element
5195		return indexOf.call( this,
5196
5197			// If it receives a jQuery object, the first element is used
5198			elem.jquery ? elem[ 0 ] : elem
5199		);
5200	},
5201
5202	add: function( selector, context ) {
5203		return this.pushStack(
5204			jQuery.uniqueSort(
5205				jQuery.merge( this.get(), jQuery( selector, context ) )
5206			)
5207		);
5208	},
5209
5210	addBack: function( selector ) {
5211		return this.add( selector == null ?
5212			this.prevObject : this.prevObject.filter( selector )
5213		);
5214	}
5215} );
5216
5217function sibling( cur, dir ) {
5218	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
5219	return cur;
5220}
5221
5222jQuery.each( {
5223	parent: function( elem ) {
5224		var parent = elem.parentNode;
5225		return parent && parent.nodeType !== 11 ? parent : null;
5226	},
5227	parents: function( elem ) {
5228		return dir( elem, "parentNode" );
5229	},
5230	parentsUntil: function( elem, _i, until ) {
5231		return dir( elem, "parentNode", until );
5232	},
5233	next: function( elem ) {
5234		return sibling( elem, "nextSibling" );
5235	},
5236	prev: function( elem ) {
5237		return sibling( elem, "previousSibling" );
5238	},
5239	nextAll: function( elem ) {
5240		return dir( elem, "nextSibling" );
5241	},
5242	prevAll: function( elem ) {
5243		return dir( elem, "previousSibling" );
5244	},
5245	nextUntil: function( elem, _i, until ) {
5246		return dir( elem, "nextSibling", until );
5247	},
5248	prevUntil: function( elem, _i, until ) {
5249		return dir( elem, "previousSibling", until );
5250	},
5251	siblings: function( elem ) {
5252		return siblings( ( elem.parentNode || {} ).firstChild, elem );
5253	},
5254	children: function( elem ) {
5255		return siblings( elem.firstChild );
5256	},
5257	contents: function( elem ) {
5258		if ( elem.contentDocument != null &&
5259
5260			// Support: IE 11+
5261			// <object> elements with no `data` attribute has an object
5262			// `contentDocument` with a `null` prototype.
5263			getProto( elem.contentDocument ) ) {
5264
5265			return elem.contentDocument;
5266		}
5267
5268		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
5269		// Treat the template element as a regular one in browsers that
5270		// don't support it.
5271		if ( nodeName( elem, "template" ) ) {
5272			elem = elem.content || elem;
5273		}
5274
5275		return jQuery.merge( [], elem.childNodes );
5276	}
5277}, function( name, fn ) {
5278	jQuery.fn[ name ] = function( until, selector ) {
5279		var matched = jQuery.map( this, fn, until );
5280
5281		if ( name.slice( -5 ) !== "Until" ) {
5282			selector = until;
5283		}
5284
5285		if ( selector && typeof selector === "string" ) {
5286			matched = jQuery.filter( selector, matched );
5287		}
5288
5289		if ( this.length > 1 ) {
5290
5291			// Remove duplicates
5292			if ( !guaranteedUnique[ name ] ) {
5293				jQuery.uniqueSort( matched );
5294			}
5295
5296			// Reverse order for parents* and prev-derivatives
5297			if ( rparentsprev.test( name ) ) {
5298				matched.reverse();
5299			}
5300		}
5301
5302		return this.pushStack( matched );
5303	};
5304} );
5305var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
5306
5307
5308
5309// Convert String-formatted options into Object-formatted ones
5310function createOptions( options ) {
5311	var object = {};
5312	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
5313		object[ flag ] = true;
5314	} );
5315	return object;
5316}
5317
5318/*
5319 * Create a callback list using the following parameters:
5320 *
5321 *	options: an optional list of space-separated options that will change how
5322 *			the callback list behaves or a more traditional option object
5323 *
5324 * By default a callback list will act like an event callback list and can be
5325 * "fired" multiple times.
5326 *
5327 * Possible options:
5328 *
5329 *	once:			will ensure the callback list can only be fired once (like a Deferred)
5330 *
5331 *	memory:			will keep track of previous values and will call any callback added
5332 *					after the list has been fired right away with the latest "memorized"
5333 *					values (like a Deferred)
5334 *
5335 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
5336 *
5337 *	stopOnFalse:	interrupt callings when a callback returns false
5338 *
5339 */
5340jQuery.Callbacks = function( options ) {
5341
5342	// Convert options from String-formatted to Object-formatted if needed
5343	// (we check in cache first)
5344	options = typeof options === "string" ?
5345		createOptions( options ) :
5346		jQuery.extend( {}, options );
5347
5348	var // Flag to know if list is currently firing
5349		firing,
5350
5351		// Last fire value for non-forgettable lists
5352		memory,
5353
5354		// Flag to know if list was already fired
5355		fired,
5356
5357		// Flag to prevent firing
5358		locked,
5359
5360		// Actual callback list
5361		list = [],
5362
5363		// Queue of execution data for repeatable lists
5364		queue = [],
5365
5366		// Index of currently firing callback (modified by add/remove as needed)
5367		firingIndex = -1,
5368
5369		// Fire callbacks
5370		fire = function() {
5371
5372			// Enforce single-firing
5373			locked = locked || options.once;
5374
5375			// Execute callbacks for all pending executions,
5376			// respecting firingIndex overrides and runtime changes
5377			fired = firing = true;
5378			for ( ; queue.length; firingIndex = -1 ) {
5379				memory = queue.shift();
5380				while ( ++firingIndex < list.length ) {
5381
5382					// Run callback and check for early termination
5383					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
5384						options.stopOnFalse ) {
5385
5386						// Jump to end and forget the data so .add doesn't re-fire
5387						firingIndex = list.length;
5388						memory = false;
5389					}
5390				}
5391			}
5392
5393			// Forget the data if we're done with it
5394			if ( !options.memory ) {
5395				memory = false;
5396			}
5397
5398			firing = false;
5399
5400			// Clean up if we're done firing for good
5401			if ( locked ) {
5402
5403				// Keep an empty list if we have data for future add calls
5404				if ( memory ) {
5405					list = [];
5406
5407				// Otherwise, this object is spent
5408				} else {
5409					list = "";
5410				}
5411			}
5412		},
5413
5414		// Actual Callbacks object
5415		self = {
5416
5417			// Add a callback or a collection of callbacks to the list
5418			add: function() {
5419				if ( list ) {
5420
5421					// If we have memory from a past run, we should fire after adding
5422					if ( memory && !firing ) {
5423						firingIndex = list.length - 1;
5424						queue.push( memory );
5425					}
5426
5427					( function add( args ) {
5428						jQuery.each( args, function( _, arg ) {
5429							if ( isFunction( arg ) ) {
5430								if ( !options.unique || !self.has( arg ) ) {
5431									list.push( arg );
5432								}
5433							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
5434
5435								// Inspect recursively
5436								add( arg );
5437							}
5438						} );
5439					} )( arguments );
5440
5441					if ( memory && !firing ) {
5442						fire();
5443					}
5444				}
5445				return this;
5446			},
5447
5448			// Remove a callback from the list
5449			remove: function() {
5450				jQuery.each( arguments, function( _, arg ) {
5451					var index;
5452					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
5453						list.splice( index, 1 );
5454
5455						// Handle firing indexes
5456						if ( index <= firingIndex ) {
5457							firingIndex--;
5458						}
5459					}
5460				} );
5461				return this;
5462			},
5463
5464			// Check if a given callback is in the list.
5465			// If no argument is given, return whether or not list has callbacks attached.
5466			has: function( fn ) {
5467				return fn ?
5468					jQuery.inArray( fn, list ) > -1 :
5469					list.length > 0;
5470			},
5471
5472			// Remove all callbacks from the list
5473			empty: function() {
5474				if ( list ) {
5475					list = [];
5476				}
5477				return this;
5478			},
5479
5480			// Disable .fire and .add
5481			// Abort any current/pending executions
5482			// Clear all callbacks and values
5483			disable: function() {
5484				locked = queue = [];
5485				list = memory = "";
5486				return this;
5487			},
5488			disabled: function() {
5489				return !list;
5490			},
5491
5492			// Disable .fire
5493			// Also disable .add unless we have memory (since it would have no effect)
5494			// Abort any pending executions
5495			lock: function() {
5496				locked = queue = [];
5497				if ( !memory && !firing ) {
5498					list = memory = "";
5499				}
5500				return this;
5501			},
5502			locked: function() {
5503				return !!locked;
5504			},
5505
5506			// Call all callbacks with the given context and arguments
5507			fireWith: function( context, args ) {
5508				if ( !locked ) {
5509					args = args || [];
5510					args = [ context, args.slice ? args.slice() : args ];
5511					queue.push( args );
5512					if ( !firing ) {
5513						fire();
5514					}
5515				}
5516				return this;
5517			},
5518
5519			// Call all the callbacks with the given arguments
5520			fire: function() {
5521				self.fireWith( this, arguments );
5522				return this;
5523			},
5524
5525			// To know if the callbacks have already been called at least once
5526			fired: function() {
5527				return !!fired;
5528			}
5529		};
5530
5531	return self;
5532};
5533
5534
5535function Identity( v ) {
5536	return v;
5537}
5538function Thrower( ex ) {
5539	throw ex;
5540}
5541
5542function adoptValue( value, resolve, reject, noValue ) {
5543	var method;
5544
5545	try {
5546
5547		// Check for promise aspect first to privilege synchronous behavior
5548		if ( value && isFunction( ( method = value.promise ) ) ) {
5549			method.call( value ).done( resolve ).fail( reject );
5550
5551		// Other thenables
5552		} else if ( value && isFunction( ( method = value.then ) ) ) {
5553			method.call( value, resolve, reject );
5554
5555		// Other non-thenables
5556		} else {
5557
5558			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
5559			// * false: [ value ].slice( 0 ) => resolve( value )
5560			// * true: [ value ].slice( 1 ) => resolve()
5561			resolve.apply( undefined, [ value ].slice( noValue ) );
5562		}
5563
5564	// For Promises/A+, convert exceptions into rejections
5565	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
5566	// Deferred#then to conditionally suppress rejection.
5567	} catch ( value ) {
5568
5569		// Support: Android 4.0 only
5570		// Strict mode functions invoked without .call/.apply get global-object context
5571		reject.apply( undefined, [ value ] );
5572	}
5573}
5574
5575jQuery.extend( {
5576
5577	Deferred: function( func ) {
5578		var tuples = [
5579
5580				// action, add listener, callbacks,
5581				// ... .then handlers, argument index, [final state]
5582				[ "notify", "progress", jQuery.Callbacks( "memory" ),
5583					jQuery.Callbacks( "memory" ), 2 ],
5584				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
5585					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
5586				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
5587					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
5588			],
5589			state = "pending",
5590			promise = {
5591				state: function() {
5592					return state;
5593				},
5594				always: function() {
5595					deferred.done( arguments ).fail( arguments );
5596					return this;
5597				},
5598				"catch": function( fn ) {
5599					return promise.then( null, fn );
5600				},
5601
5602				// Keep pipe for back-compat
5603				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
5604					var fns = arguments;
5605
5606					return jQuery.Deferred( function( newDefer ) {
5607						jQuery.each( tuples, function( _i, tuple ) {
5608
5609							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
5610							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
5611
5612							// deferred.progress(function() { bind to newDefer or newDefer.notify })
5613							// deferred.done(function() { bind to newDefer or newDefer.resolve })
5614							// deferred.fail(function() { bind to newDefer or newDefer.reject })
5615							deferred[ tuple[ 1 ] ]( function() {
5616								var returned = fn && fn.apply( this, arguments );
5617								if ( returned && isFunction( returned.promise ) ) {
5618									returned.promise()
5619										.progress( newDefer.notify )
5620										.done( newDefer.resolve )
5621										.fail( newDefer.reject );
5622								} else {
5623									newDefer[ tuple[ 0 ] + "With" ](
5624										this,
5625										fn ? [ returned ] : arguments
5626									);
5627								}
5628							} );
5629						} );
5630						fns = null;
5631					} ).promise();
5632				},
5633				then: function( onFulfilled, onRejected, onProgress ) {
5634					var maxDepth = 0;
5635					function resolve( depth, deferred, handler, special ) {
5636						return function() {
5637							var that = this,
5638								args = arguments,
5639								mightThrow = function() {
5640									var returned, then;
5641
5642									// Support: Promises/A+ section 2.3.3.3.3
5643									// https://promisesaplus.com/#point-59
5644									// Ignore double-resolution attempts
5645									if ( depth < maxDepth ) {
5646										return;
5647									}
5648
5649									returned = handler.apply( that, args );
5650
5651									// Support: Promises/A+ section 2.3.1
5652									// https://promisesaplus.com/#point-48
5653									if ( returned === deferred.promise() ) {
5654										throw new TypeError( "Thenable self-resolution" );
5655									}
5656
5657									// Support: Promises/A+ sections 2.3.3.1, 3.5
5658									// https://promisesaplus.com/#point-54
5659									// https://promisesaplus.com/#point-75
5660									// Retrieve `then` only once
5661									then = returned &&
5662
5663										// Support: Promises/A+ section 2.3.4
5664										// https://promisesaplus.com/#point-64
5665										// Only check objects and functions for thenability
5666										( typeof returned === "object" ||
5667											typeof returned === "function" ) &&
5668										returned.then;
5669
5670									// Handle a returned thenable
5671									if ( isFunction( then ) ) {
5672
5673										// Special processors (notify) just wait for resolution
5674										if ( special ) {
5675											then.call(
5676												returned,
5677												resolve( maxDepth, deferred, Identity, special ),
5678												resolve( maxDepth, deferred, Thrower, special )
5679											);
5680
5681										// Normal processors (resolve) also hook into progress
5682										} else {
5683
5684											// ...and disregard older resolution values
5685											maxDepth++;
5686
5687											then.call(
5688												returned,
5689												resolve( maxDepth, deferred, Identity, special ),
5690												resolve( maxDepth, deferred, Thrower, special ),
5691												resolve( maxDepth, deferred, Identity,
5692													deferred.notifyWith )
5693											);
5694										}
5695
5696									// Handle all other returned values
5697									} else {
5698
5699										// Only substitute handlers pass on context
5700										// and multiple values (non-spec behavior)
5701										if ( handler !== Identity ) {
5702											that = undefined;
5703											args = [ returned ];
5704										}
5705
5706										// Process the value(s)
5707										// Default process is resolve
5708										( special || deferred.resolveWith )( that, args );
5709									}
5710								},
5711
5712								// Only normal processors (resolve) catch and reject exceptions
5713								process = special ?
5714									mightThrow :
5715									function() {
5716										try {
5717											mightThrow();
5718										} catch ( e ) {
5719
5720											if ( jQuery.Deferred.exceptionHook ) {
5721												jQuery.Deferred.exceptionHook( e,
5722													process.error );
5723											}
5724
5725											// Support: Promises/A+ section 2.3.3.3.4.1
5726											// https://promisesaplus.com/#point-61
5727											// Ignore post-resolution exceptions
5728											if ( depth + 1 >= maxDepth ) {
5729
5730												// Only substitute handlers pass on context
5731												// and multiple values (non-spec behavior)
5732												if ( handler !== Thrower ) {
5733													that = undefined;
5734													args = [ e ];
5735												}
5736
5737												deferred.rejectWith( that, args );
5738											}
5739										}
5740									};
5741
5742							// Support: Promises/A+ section 2.3.3.3.1
5743							// https://promisesaplus.com/#point-57
5744							// Re-resolve promises immediately to dodge false rejection from
5745							// subsequent errors
5746							if ( depth ) {
5747								process();
5748							} else {
5749
5750								// Call an optional hook to record the error, in case of exception
5751								// since it's otherwise lost when execution goes async
5752								if ( jQuery.Deferred.getErrorHook ) {
5753									process.error = jQuery.Deferred.getErrorHook();
5754
5755								// The deprecated alias of the above. While the name suggests
5756								// returning the stack, not an error instance, jQuery just passes
5757								// it directly to `console.warn` so both will work; an instance
5758								// just better cooperates with source maps.
5759								} else if ( jQuery.Deferred.getStackHook ) {
5760									process.error = jQuery.Deferred.getStackHook();
5761								}
5762								window.setTimeout( process );
5763							}
5764						};
5765					}
5766
5767					return jQuery.Deferred( function( newDefer ) {
5768
5769						// progress_handlers.add( ... )
5770						tuples[ 0 ][ 3 ].add(
5771							resolve(
5772								0,
5773								newDefer,
5774								isFunction( onProgress ) ?
5775									onProgress :
5776									Identity,
5777								newDefer.notifyWith
5778							)
5779						);
5780
5781						// fulfilled_handlers.add( ... )
5782						tuples[ 1 ][ 3 ].add(
5783							resolve(
5784								0,
5785								newDefer,
5786								isFunction( onFulfilled ) ?
5787									onFulfilled :
5788									Identity
5789							)
5790						);
5791
5792						// rejected_handlers.add( ... )
5793						tuples[ 2 ][ 3 ].add(
5794							resolve(
5795								0,
5796								newDefer,
5797								isFunction( onRejected ) ?
5798									onRejected :
5799									Thrower
5800							)
5801						);
5802					} ).promise();
5803				},
5804
5805				// Get a promise for this deferred
5806				// If obj is provided, the promise aspect is added to the object
5807				promise: function( obj ) {
5808					return obj != null ? jQuery.extend( obj, promise ) : promise;
5809				}
5810			},
5811			deferred = {};
5812
5813		// Add list-specific methods
5814		jQuery.each( tuples, function( i, tuple ) {
5815			var list = tuple[ 2 ],
5816				stateString = tuple[ 5 ];
5817
5818			// promise.progress = list.add
5819			// promise.done = list.add
5820			// promise.fail = list.add
5821			promise[ tuple[ 1 ] ] = list.add;
5822
5823			// Handle state
5824			if ( stateString ) {
5825				list.add(
5826					function() {
5827
5828						// state = "resolved" (i.e., fulfilled)
5829						// state = "rejected"
5830						state = stateString;
5831					},
5832
5833					// rejected_callbacks.disable
5834					// fulfilled_callbacks.disable
5835					tuples[ 3 - i ][ 2 ].disable,
5836
5837					// rejected_handlers.disable
5838					// fulfilled_handlers.disable
5839					tuples[ 3 - i ][ 3 ].disable,
5840
5841					// progress_callbacks.lock
5842					tuples[ 0 ][ 2 ].lock,
5843
5844					// progress_handlers.lock
5845					tuples[ 0 ][ 3 ].lock
5846				);
5847			}
5848
5849			// progress_handlers.fire
5850			// fulfilled_handlers.fire
5851			// rejected_handlers.fire
5852			list.add( tuple[ 3 ].fire );
5853
5854			// deferred.notify = function() { deferred.notifyWith(...) }
5855			// deferred.resolve = function() { deferred.resolveWith(...) }
5856			// deferred.reject = function() { deferred.rejectWith(...) }
5857			deferred[ tuple[ 0 ] ] = function() {
5858				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
5859				return this;
5860			};
5861
5862			// deferred.notifyWith = list.fireWith
5863			// deferred.resolveWith = list.fireWith
5864			// deferred.rejectWith = list.fireWith
5865			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
5866		} );
5867
5868		// Make the deferred a promise
5869		promise.promise( deferred );
5870
5871		// Call given func if any
5872		if ( func ) {
5873			func.call( deferred, deferred );
5874		}
5875
5876		// All done!
5877		return deferred;
5878	},
5879
5880	// Deferred helper
5881	when: function( singleValue ) {
5882		var
5883
5884			// count of uncompleted subordinates
5885			remaining = arguments.length,
5886
5887			// count of unprocessed arguments
5888			i = remaining,
5889
5890			// subordinate fulfillment data
5891			resolveContexts = Array( i ),
5892			resolveValues = slice.call( arguments ),
5893
5894			// the primary Deferred
5895			primary = jQuery.Deferred(),
5896
5897			// subordinate callback factory
5898			updateFunc = function( i ) {
5899				return function( value ) {
5900					resolveContexts[ i ] = this;
5901					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
5902					if ( !( --remaining ) ) {
5903						primary.resolveWith( resolveContexts, resolveValues );
5904					}
5905				};
5906			};
5907
5908		// Single- and empty arguments are adopted like Promise.resolve
5909		if ( remaining <= 1 ) {
5910			adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,
5911				!remaining );
5912
5913			// Use .then() to unwrap secondary thenables (cf. gh-3000)
5914			if ( primary.state() === "pending" ||
5915				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
5916
5917				return primary.then();
5918			}
5919		}
5920
5921		// Multiple arguments are aggregated like Promise.all array elements
5922		while ( i-- ) {
5923			adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );
5924		}
5925
5926		return primary.promise();
5927	}
5928} );
5929
5930
5931// These usually indicate a programmer mistake during development,
5932// warn about them ASAP rather than swallowing them by default.
5933var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
5934
5935// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error
5936// captured before the async barrier to get the original error cause
5937// which may otherwise be hidden.
5938jQuery.Deferred.exceptionHook = function( error, asyncError ) {
5939
5940	// Support: IE 8 - 9 only
5941	// Console exists when dev tools are open, which can happen at any time
5942	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
5943		window.console.warn( "jQuery.Deferred exception: " + error.message,
5944			error.stack, asyncError );
5945	}
5946};
5947
5948
5949
5950
5951jQuery.readyException = function( error ) {
5952	window.setTimeout( function() {
5953		throw error;
5954	} );
5955};
5956
5957
5958
5959
5960// The deferred used on DOM ready
5961var readyList = jQuery.Deferred();
5962
5963jQuery.fn.ready = function( fn ) {
5964
5965	readyList
5966		.then( fn )
5967
5968		// Wrap jQuery.readyException in a function so that the lookup
5969		// happens at the time of error handling instead of callback
5970		// registration.
5971		.catch( function( error ) {
5972			jQuery.readyException( error );
5973		} );
5974
5975	return this;
5976};
5977
5978jQuery.extend( {
5979
5980	// Is the DOM ready to be used? Set to true once it occurs.
5981	isReady: false,
5982
5983	// A counter to track how many items to wait for before
5984	// the ready event fires. See trac-6781
5985	readyWait: 1,
5986
5987	// Handle when the DOM is ready
5988	ready: function( wait ) {
5989
5990		// Abort if there are pending holds or we're already ready
5991		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
5992			return;
5993		}
5994
5995		// Remember that the DOM is ready
5996		jQuery.isReady = true;
5997
5998		// If a normal DOM Ready event fired, decrement, and wait if need be
5999		if ( wait !== true && --jQuery.readyWait > 0 ) {
6000			return;
6001		}
6002
6003		// If there are functions bound, to execute
6004		readyList.resolveWith( document, [ jQuery ] );
6005	}
6006} );
6007
6008jQuery.ready.then = readyList.then;
6009
6010// The ready event handler and self cleanup method
6011function completed() {
6012	document.removeEventListener( "DOMContentLoaded", completed );
6013	window.removeEventListener( "load", completed );
6014	jQuery.ready();
6015}
6016
6017// Catch cases where $(document).ready() is called
6018// after the browser event has already occurred.
6019// Support: IE <=9 - 10 only
6020// Older IE sometimes signals "interactive" too soon
6021if ( document.readyState === "complete" ||
6022	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
6023
6024	// Handle it asynchronously to allow scripts the opportunity to delay ready
6025	window.setTimeout( jQuery.ready );
6026
6027} else {
6028
6029	// Use the handy event callback
6030	document.addEventListener( "DOMContentLoaded", completed );
6031
6032	// A fallback to window.onload, that will always work
6033	window.addEventListener( "load", completed );
6034}
6035
6036
6037
6038
6039// Multifunctional method to get and set values of a collection
6040// The value/s can optionally be executed if it's a function
6041var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
6042	var i = 0,
6043		len = elems.length,
6044		bulk = key == null;
6045
6046	// Sets many values
6047	if ( toType( key ) === "object" ) {
6048		chainable = true;
6049		for ( i in key ) {
6050			access( elems, fn, i, key[ i ], true, emptyGet, raw );
6051		}
6052
6053	// Sets one value
6054	} else if ( value !== undefined ) {
6055		chainable = true;
6056
6057		if ( !isFunction( value ) ) {
6058			raw = true;
6059		}
6060
6061		if ( bulk ) {
6062
6063			// Bulk operations run against the entire set
6064			if ( raw ) {
6065				fn.call( elems, value );
6066				fn = null;
6067
6068			// ...except when executing function values
6069			} else {
6070				bulk = fn;
6071				fn = function( elem, _key, value ) {
6072					return bulk.call( jQuery( elem ), value );
6073				};
6074			}
6075		}
6076
6077		if ( fn ) {
6078			for ( ; i < len; i++ ) {
6079				fn(
6080					elems[ i ], key, raw ?
6081						value :
6082						value.call( elems[ i ], i, fn( elems[ i ], key ) )
6083				);
6084			}
6085		}
6086	}
6087
6088	if ( chainable ) {
6089		return elems;
6090	}
6091
6092	// Gets
6093	if ( bulk ) {
6094		return fn.call( elems );
6095	}
6096
6097	return len ? fn( elems[ 0 ], key ) : emptyGet;
6098};
6099
6100
6101// Matches dashed string for camelizing
6102var rmsPrefix = /^-ms-/,
6103	rdashAlpha = /-([a-z])/g;
6104
6105// Used by camelCase as callback to replace()
6106function fcamelCase( _all, letter ) {
6107	return letter.toUpperCase();
6108}
6109
6110// Convert dashed to camelCase; used by the css and data modules
6111// Support: IE <=9 - 11, Edge 12 - 15
6112// Microsoft forgot to hump their vendor prefix (trac-9572)
6113function camelCase( string ) {
6114	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
6115}
6116var acceptData = function( owner ) {
6117
6118	// Accepts only:
6119	//  - Node
6120	//    - Node.ELEMENT_NODE
6121	//    - Node.DOCUMENT_NODE
6122	//  - Object
6123	//    - Any
6124	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
6125};
6126
6127
6128
6129
6130function Data() {
6131	this.expando = jQuery.expando + Data.uid++;
6132}
6133
6134Data.uid = 1;
6135
6136Data.prototype = {
6137
6138	cache: function( owner ) {
6139
6140		// Check if the owner object already has a cache
6141		var value = owner[ this.expando ];
6142
6143		// If not, create one
6144		if ( !value ) {
6145			value = {};
6146
6147			// We can accept data for non-element nodes in modern browsers,
6148			// but we should not, see trac-8335.
6149			// Always return an empty object.
6150			if ( acceptData( owner ) ) {
6151
6152				// If it is a node unlikely to be stringify-ed or looped over
6153				// use plain assignment
6154				if ( owner.nodeType ) {
6155					owner[ this.expando ] = value;
6156
6157				// Otherwise secure it in a non-enumerable property
6158				// configurable must be true to allow the property to be
6159				// deleted when data is removed
6160				} else {
6161					Object.defineProperty( owner, this.expando, {
6162						value: value,
6163						configurable: true
6164					} );
6165				}
6166			}
6167		}
6168
6169		return value;
6170	},
6171	set: function( owner, data, value ) {
6172		var prop,
6173			cache = this.cache( owner );
6174
6175		// Handle: [ owner, key, value ] args
6176		// Always use camelCase key (gh-2257)
6177		if ( typeof data === "string" ) {
6178			cache[ camelCase( data ) ] = value;
6179
6180		// Handle: [ owner, { properties } ] args
6181		} else {
6182
6183			// Copy the properties one-by-one to the cache object
6184			for ( prop in data ) {
6185				cache[ camelCase( prop ) ] = data[ prop ];
6186			}
6187		}
6188		return cache;
6189	},
6190	get: function( owner, key ) {
6191		return key === undefined ?
6192			this.cache( owner ) :
6193
6194			// Always use camelCase key (gh-2257)
6195			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
6196	},
6197	access: function( owner, key, value ) {
6198
6199		// In cases where either:
6200		//
6201		//   1. No key was specified
6202		//   2. A string key was specified, but no value provided
6203		//
6204		// Take the "read" path and allow the get method to determine
6205		// which value to return, respectively either:
6206		//
6207		//   1. The entire cache object
6208		//   2. The data stored at the key
6209		//
6210		if ( key === undefined ||
6211				( ( key && typeof key === "string" ) && value === undefined ) ) {
6212
6213			return this.get( owner, key );
6214		}
6215
6216		// When the key is not a string, or both a key and value
6217		// are specified, set or extend (existing objects) with either:
6218		//
6219		//   1. An object of properties
6220		//   2. A key and value
6221		//
6222		this.set( owner, key, value );
6223
6224		// Since the "set" path can have two possible entry points
6225		// return the expected data based on which path was taken[*]
6226		return value !== undefined ? value : key;
6227	},
6228	remove: function( owner, key ) {
6229		var i,
6230			cache = owner[ this.expando ];
6231
6232		if ( cache === undefined ) {
6233			return;
6234		}
6235
6236		if ( key !== undefined ) {
6237
6238			// Support array or space separated string of keys
6239			if ( Array.isArray( key ) ) {
6240
6241				// If key is an array of keys...
6242				// We always set camelCase keys, so remove that.
6243				key = key.map( camelCase );
6244			} else {
6245				key = camelCase( key );
6246
6247				// If a key with the spaces exists, use it.
6248				// Otherwise, create an array by matching non-whitespace
6249				key = key in cache ?
6250					[ key ] :
6251					( key.match( rnothtmlwhite ) || [] );
6252			}
6253
6254			i = key.length;
6255
6256			while ( i-- ) {
6257				delete cache[ key[ i ] ];
6258			}
6259		}
6260
6261		// Remove the expando if there's no more data
6262		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
6263
6264			// Support: Chrome <=35 - 45
6265			// Webkit & Blink performance suffers when deleting properties
6266			// from DOM nodes, so set to undefined instead
6267			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
6268			if ( owner.nodeType ) {
6269				owner[ this.expando ] = undefined;
6270			} else {
6271				delete owner[ this.expando ];
6272			}
6273		}
6274	},
6275	hasData: function( owner ) {
6276		var cache = owner[ this.expando ];
6277		return cache !== undefined && !jQuery.isEmptyObject( cache );
6278	}
6279};
6280var dataPriv = new Data();
6281
6282var dataUser = new Data();
6283
6284
6285
6286//	Implementation Summary
6287//
6288//	1. Enforce API surface and semantic compatibility with 1.9.x branch
6289//	2. Improve the module's maintainability by reducing the storage
6290//		paths to a single mechanism.
6291//	3. Use the same single mechanism to support "private" and "user" data.
6292//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
6293//	5. Avoid exposing implementation details on user objects (eg. expando properties)
6294//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
6295
6296var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
6297	rmultiDash = /[A-Z]/g;
6298
6299function getData( data ) {
6300	if ( data === "true" ) {
6301		return true;
6302	}
6303
6304	if ( data === "false" ) {
6305		return false;
6306	}
6307
6308	if ( data === "null" ) {
6309		return null;
6310	}
6311
6312	// Only convert to a number if it doesn't change the string
6313	if ( data === +data + "" ) {
6314		return +data;
6315	}
6316
6317	if ( rbrace.test( data ) ) {
6318		return JSON.parse( data );
6319	}
6320
6321	return data;
6322}
6323
6324function dataAttr( elem, key, data ) {
6325	var name;
6326
6327	// If nothing was found internally, try to fetch any
6328	// data from the HTML5 data-* attribute
6329	if ( data === undefined && elem.nodeType === 1 ) {
6330		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
6331		data = elem.getAttribute( name );
6332
6333		if ( typeof data === "string" ) {
6334			try {
6335				data = getData( data );
6336			} catch ( e ) {}
6337
6338			// Make sure we set the data so it isn't changed later
6339			dataUser.set( elem, key, data );
6340		} else {
6341			data = undefined;
6342		}
6343	}
6344	return data;
6345}
6346
6347jQuery.extend( {
6348	hasData: function( elem ) {
6349		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
6350	},
6351
6352	data: function( elem, name, data ) {
6353		return dataUser.access( elem, name, data );
6354	},
6355
6356	removeData: function( elem, name ) {
6357		dataUser.remove( elem, name );
6358	},
6359
6360	// TODO: Now that all calls to _data and _removeData have been replaced
6361	// with direct calls to dataPriv methods, these can be deprecated.
6362	_data: function( elem, name, data ) {
6363		return dataPriv.access( elem, name, data );
6364	},
6365
6366	_removeData: function( elem, name ) {
6367		dataPriv.remove( elem, name );
6368	}
6369} );
6370
6371jQuery.fn.extend( {
6372	data: function( key, value ) {
6373		var i, name, data,
6374			elem = this[ 0 ],
6375			attrs = elem && elem.attributes;
6376
6377		// Gets all values
6378		if ( key === undefined ) {
6379			if ( this.length ) {
6380				data = dataUser.get( elem );
6381
6382				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
6383					i = attrs.length;
6384					while ( i-- ) {
6385
6386						// Support: IE 11 only
6387						// The attrs elements can be null (trac-14894)
6388						if ( attrs[ i ] ) {
6389							name = attrs[ i ].name;
6390							if ( name.indexOf( "data-" ) === 0 ) {
6391								name = camelCase( name.slice( 5 ) );
6392								dataAttr( elem, name, data[ name ] );
6393							}
6394						}
6395					}
6396					dataPriv.set( elem, "hasDataAttrs", true );
6397				}
6398			}
6399
6400			return data;
6401		}
6402
6403		// Sets multiple values
6404		if ( typeof key === "object" ) {
6405			return this.each( function() {
6406				dataUser.set( this, key );
6407			} );
6408		}
6409
6410		return access( this, function( value ) {
6411			var data;
6412
6413			// The calling jQuery object (element matches) is not empty
6414			// (and therefore has an element appears at this[ 0 ]) and the
6415			// `value` parameter was not undefined. An empty jQuery object
6416			// will result in `undefined` for elem = this[ 0 ] which will
6417			// throw an exception if an attempt to read a data cache is made.
6418			if ( elem && value === undefined ) {
6419
6420				// Attempt to get data from the cache
6421				// The key will always be camelCased in Data
6422				data = dataUser.get( elem, key );
6423				if ( data !== undefined ) {
6424					return data;
6425				}
6426
6427				// Attempt to "discover" the data in
6428				// HTML5 custom data-* attrs
6429				data = dataAttr( elem, key );
6430				if ( data !== undefined ) {
6431					return data;
6432				}
6433
6434				// We tried really hard, but the data doesn't exist.
6435				return;
6436			}
6437
6438			// Set the data...
6439			this.each( function() {
6440
6441				// We always store the camelCased key
6442				dataUser.set( this, key, value );
6443			} );
6444		}, null, value, arguments.length > 1, null, true );
6445	},
6446
6447	removeData: function( key ) {
6448		return this.each( function() {
6449			dataUser.remove( this, key );
6450		} );
6451	}
6452} );
6453
6454
6455jQuery.extend( {
6456	queue: function( elem, type, data ) {
6457		var queue;
6458
6459		if ( elem ) {
6460			type = ( type || "fx" ) + "queue";
6461			queue = dataPriv.get( elem, type );
6462
6463			// Speed up dequeue by getting out quickly if this is just a lookup
6464			if ( data ) {
6465				if ( !queue || Array.isArray( data ) ) {
6466					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
6467				} else {
6468					queue.push( data );
6469				}
6470			}
6471			return queue || [];
6472		}
6473	},
6474
6475	dequeue: function( elem, type ) {
6476		type = type || "fx";
6477
6478		var queue = jQuery.queue( elem, type ),
6479			startLength = queue.length,
6480			fn = queue.shift(),
6481			hooks = jQuery._queueHooks( elem, type ),
6482			next = function() {
6483				jQuery.dequeue( elem, type );
6484			};
6485
6486		// If the fx queue is dequeued, always remove the progress sentinel
6487		if ( fn === "inprogress" ) {
6488			fn = queue.shift();
6489			startLength--;
6490		}
6491
6492		if ( fn ) {
6493
6494			// Add a progress sentinel to prevent the fx queue from being
6495			// automatically dequeued
6496			if ( type === "fx" ) {
6497				queue.unshift( "inprogress" );
6498			}
6499
6500			// Clear up the last queue stop function
6501			delete hooks.stop;
6502			fn.call( elem, next, hooks );
6503		}
6504
6505		if ( !startLength && hooks ) {
6506			hooks.empty.fire();
6507		}
6508	},
6509
6510	// Not public - generate a queueHooks object, or return the current one
6511	_queueHooks: function( elem, type ) {
6512		var key = type + "queueHooks";
6513		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
6514			empty: jQuery.Callbacks( "once memory" ).add( function() {
6515				dataPriv.remove( elem, [ type + "queue", key ] );
6516			} )
6517		} );
6518	}
6519} );
6520
6521jQuery.fn.extend( {
6522	queue: function( type, data ) {
6523		var setter = 2;
6524
6525		if ( typeof type !== "string" ) {
6526			data = type;
6527			type = "fx";
6528			setter--;
6529		}
6530
6531		if ( arguments.length < setter ) {
6532			return jQuery.queue( this[ 0 ], type );
6533		}
6534
6535		return data === undefined ?
6536			this :
6537			this.each( function() {
6538				var queue = jQuery.queue( this, type, data );
6539
6540				// Ensure a hooks for this queue
6541				jQuery._queueHooks( this, type );
6542
6543				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
6544					jQuery.dequeue( this, type );
6545				}
6546			} );
6547	},
6548	dequeue: function( type ) {
6549		return this.each( function() {
6550			jQuery.dequeue( this, type );
6551		} );
6552	},
6553	clearQueue: function( type ) {
6554		return this.queue( type || "fx", [] );
6555	},
6556
6557	// Get a promise resolved when queues of a certain type
6558	// are emptied (fx is the type by default)
6559	promise: function( type, obj ) {
6560		var tmp,
6561			count = 1,
6562			defer = jQuery.Deferred(),
6563			elements = this,
6564			i = this.length,
6565			resolve = function() {
6566				if ( !( --count ) ) {
6567					defer.resolveWith( elements, [ elements ] );
6568				}
6569			};
6570
6571		if ( typeof type !== "string" ) {
6572			obj = type;
6573			type = undefined;
6574		}
6575		type = type || "fx";
6576
6577		while ( i-- ) {
6578			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
6579			if ( tmp && tmp.empty ) {
6580				count++;
6581				tmp.empty.add( resolve );
6582			}
6583		}
6584		resolve();
6585		return defer.promise( obj );
6586	}
6587} );
6588var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
6589
6590var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
6591
6592
6593var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
6594
6595var documentElement = document.documentElement;
6596
6597
6598
6599	var isAttached = function( elem ) {
6600			return jQuery.contains( elem.ownerDocument, elem );
6601		},
6602		composed = { composed: true };
6603
6604	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
6605	// Check attachment across shadow DOM boundaries when possible (gh-3504)
6606	// Support: iOS 10.0-10.2 only
6607	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
6608	// leading to errors. We need to check for `getRootNode`.
6609	if ( documentElement.getRootNode ) {
6610		isAttached = function( elem ) {
6611			return jQuery.contains( elem.ownerDocument, elem ) ||
6612				elem.getRootNode( composed ) === elem.ownerDocument;
6613		};
6614	}
6615var isHiddenWithinTree = function( elem, el ) {
6616
6617		// isHiddenWithinTree might be called from jQuery#filter function;
6618		// in that case, element will be second argument
6619		elem = el || elem;
6620
6621		// Inline style trumps all
6622		return elem.style.display === "none" ||
6623			elem.style.display === "" &&
6624
6625			// Otherwise, check computed style
6626			// Support: Firefox <=43 - 45
6627			// Disconnected elements can have computed display: none, so first confirm that elem is
6628			// in the document.
6629			isAttached( elem ) &&
6630
6631			jQuery.css( elem, "display" ) === "none";
6632	};
6633
6634
6635
6636function adjustCSS( elem, prop, valueParts, tween ) {
6637	var adjusted, scale,
6638		maxIterations = 20,
6639		currentValue = tween ?
6640			function() {
6641				return tween.cur();
6642			} :
6643			function() {
6644				return jQuery.css( elem, prop, "" );
6645			},
6646		initial = currentValue(),
6647		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
6648
6649		// Starting value computation is required for potential unit mismatches
6650		initialInUnit = elem.nodeType &&
6651			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
6652			rcssNum.exec( jQuery.css( elem, prop ) );
6653
6654	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
6655
6656		// Support: Firefox <=54
6657		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
6658		initial = initial / 2;
6659
6660		// Trust units reported by jQuery.css
6661		unit = unit || initialInUnit[ 3 ];
6662
6663		// Iteratively approximate from a nonzero starting point
6664		initialInUnit = +initial || 1;
6665
6666		while ( maxIterations-- ) {
6667
6668			// Evaluate and update our best guess (doubling guesses that zero out).
6669			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
6670			jQuery.style( elem, prop, initialInUnit + unit );
6671			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
6672				maxIterations = 0;
6673			}
6674			initialInUnit = initialInUnit / scale;
6675
6676		}
6677
6678		initialInUnit = initialInUnit * 2;
6679		jQuery.style( elem, prop, initialInUnit + unit );
6680
6681		// Make sure we update the tween properties later on
6682		valueParts = valueParts || [];
6683	}
6684
6685	if ( valueParts ) {
6686		initialInUnit = +initialInUnit || +initial || 0;
6687
6688		// Apply relative offset (+=/-=) if specified
6689		adjusted = valueParts[ 1 ] ?
6690			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
6691			+valueParts[ 2 ];
6692		if ( tween ) {
6693			tween.unit = unit;
6694			tween.start = initialInUnit;
6695			tween.end = adjusted;
6696		}
6697	}
6698	return adjusted;
6699}
6700
6701
6702var defaultDisplayMap = {};
6703
6704function getDefaultDisplay( elem ) {
6705	var temp,
6706		doc = elem.ownerDocument,
6707		nodeName = elem.nodeName,
6708		display = defaultDisplayMap[ nodeName ];
6709
6710	if ( display ) {
6711		return display;
6712	}
6713
6714	temp = doc.body.appendChild( doc.createElement( nodeName ) );
6715	display = jQuery.css( temp, "display" );
6716
6717	temp.parentNode.removeChild( temp );
6718
6719	if ( display === "none" ) {
6720		display = "block";
6721	}
6722	defaultDisplayMap[ nodeName ] = display;
6723
6724	return display;
6725}
6726
6727function showHide( elements, show ) {
6728	var display, elem,
6729		values = [],
6730		index = 0,
6731		length = elements.length;
6732
6733	// Determine new display value for elements that need to change
6734	for ( ; index < length; index++ ) {
6735		elem = elements[ index ];
6736		if ( !elem.style ) {
6737			continue;
6738		}
6739
6740		display = elem.style.display;
6741		if ( show ) {
6742
6743			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
6744			// check is required in this first loop unless we have a nonempty display value (either
6745			// inline or about-to-be-restored)
6746			if ( display === "none" ) {
6747				values[ index ] = dataPriv.get( elem, "display" ) || null;
6748				if ( !values[ index ] ) {
6749					elem.style.display = "";
6750				}
6751			}
6752			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
6753				values[ index ] = getDefaultDisplay( elem );
6754			}
6755		} else {
6756			if ( display !== "none" ) {
6757				values[ index ] = "none";
6758
6759				// Remember what we're overwriting
6760				dataPriv.set( elem, "display", display );
6761			}
6762		}
6763	}
6764
6765	// Set the display of the elements in a second loop to avoid constant reflow
6766	for ( index = 0; index < length; index++ ) {
6767		if ( values[ index ] != null ) {
6768			elements[ index ].style.display = values[ index ];
6769		}
6770	}
6771
6772	return elements;
6773}
6774
6775jQuery.fn.extend( {
6776	show: function() {
6777		return showHide( this, true );
6778	},
6779	hide: function() {
6780		return showHide( this );
6781	},
6782	toggle: function( state ) {
6783		if ( typeof state === "boolean" ) {
6784			return state ? this.show() : this.hide();
6785		}
6786
6787		return this.each( function() {
6788			if ( isHiddenWithinTree( this ) ) {
6789				jQuery( this ).show();
6790			} else {
6791				jQuery( this ).hide();
6792			}
6793		} );
6794	}
6795} );
6796var rcheckableType = ( /^(?:checkbox|radio)$/i );
6797
6798var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
6799
6800var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
6801
6802
6803
6804( function() {
6805	var fragment = document.createDocumentFragment(),
6806		div = fragment.appendChild( document.createElement( "div" ) ),
6807		input = document.createElement( "input" );
6808
6809	// Support: Android 4.0 - 4.3 only
6810	// Check state lost if the name is set (trac-11217)
6811	// Support: Windows Web Apps (WWA)
6812	// `name` and `type` must use .setAttribute for WWA (trac-14901)
6813	input.setAttribute( "type", "radio" );
6814	input.setAttribute( "checked", "checked" );
6815	input.setAttribute( "name", "t" );
6816
6817	div.appendChild( input );
6818
6819	// Support: Android <=4.1 only
6820	// Older WebKit doesn't clone checked state correctly in fragments
6821	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
6822
6823	// Support: IE <=11 only
6824	// Make sure textarea (and checkbox) defaultValue is properly cloned
6825	div.innerHTML = "<textarea>x</textarea>";
6826	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
6827
6828	// Support: IE <=9 only
6829	// IE <=9 replaces <option> tags with their contents when inserted outside of
6830	// the select element.
6831	div.innerHTML = "<option></option>";
6832	support.option = !!div.lastChild;
6833} )();
6834
6835
6836// We have to close these tags to support XHTML (trac-13200)
6837var wrapMap = {
6838
6839	// XHTML parsers do not magically insert elements in the
6840	// same way that tag soup parsers do. So we cannot shorten
6841	// this by omitting <tbody> or other required elements.
6842	thead: [ 1, "<table>", "</table>" ],
6843	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
6844	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
6845	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
6846
6847	_default: [ 0, "", "" ]
6848};
6849
6850wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
6851wrapMap.th = wrapMap.td;
6852
6853// Support: IE <=9 only
6854if ( !support.option ) {
6855	wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
6856}
6857
6858
6859function getAll( context, tag ) {
6860
6861	// Support: IE <=9 - 11 only
6862	// Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
6863	var ret;
6864
6865	if ( typeof context.getElementsByTagName !== "undefined" ) {
6866		ret = context.getElementsByTagName( tag || "*" );
6867
6868	} else if ( typeof context.querySelectorAll !== "undefined" ) {
6869		ret = context.querySelectorAll( tag || "*" );
6870
6871	} else {
6872		ret = [];
6873	}
6874
6875	if ( tag === undefined || tag && nodeName( context, tag ) ) {
6876		return jQuery.merge( [ context ], ret );
6877	}
6878
6879	return ret;
6880}
6881
6882
6883// Mark scripts as having already been evaluated
6884function setGlobalEval( elems, refElements ) {
6885	var i = 0,
6886		l = elems.length;
6887
6888	for ( ; i < l; i++ ) {
6889		dataPriv.set(
6890			elems[ i ],
6891			"globalEval",
6892			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
6893		);
6894	}
6895}
6896
6897
6898var rhtml = /<|&#?\w+;/;
6899
6900function buildFragment( elems, context, scripts, selection, ignored ) {
6901	var elem, tmp, tag, wrap, attached, j,
6902		fragment = context.createDocumentFragment(),
6903		nodes = [],
6904		i = 0,
6905		l = elems.length;
6906
6907	for ( ; i < l; i++ ) {
6908		elem = elems[ i ];
6909
6910		if ( elem || elem === 0 ) {
6911
6912			// Add nodes directly
6913			if ( toType( elem ) === "object" ) {
6914
6915				// Support: Android <=4.0 only, PhantomJS 1 only
6916				// push.apply(_, arraylike) throws on ancient WebKit
6917				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
6918
6919			// Convert non-html into a text node
6920			} else if ( !rhtml.test( elem ) ) {
6921				nodes.push( context.createTextNode( elem ) );
6922
6923			// Convert html into DOM nodes
6924			} else {
6925				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
6926
6927				// Deserialize a standard representation
6928				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
6929				wrap = wrapMap[ tag ] || wrapMap._default;
6930				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
6931
6932				// Descend through wrappers to the right content
6933				j = wrap[ 0 ];
6934				while ( j-- ) {
6935					tmp = tmp.lastChild;
6936				}
6937
6938				// Support: Android <=4.0 only, PhantomJS 1 only
6939				// push.apply(_, arraylike) throws on ancient WebKit
6940				jQuery.merge( nodes, tmp.childNodes );
6941
6942				// Remember the top-level container
6943				tmp = fragment.firstChild;
6944
6945				// Ensure the created nodes are orphaned (trac-12392)
6946				tmp.textContent = "";
6947			}
6948		}
6949	}
6950
6951	// Remove wrapper from fragment
6952	fragment.textContent = "";
6953
6954	i = 0;
6955	while ( ( elem = nodes[ i++ ] ) ) {
6956
6957		// Skip elements already in the context collection (trac-4087)
6958		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
6959			if ( ignored ) {
6960				ignored.push( elem );
6961			}
6962			continue;
6963		}
6964
6965		attached = isAttached( elem );
6966
6967		// Append to fragment
6968		tmp = getAll( fragment.appendChild( elem ), "script" );
6969
6970		// Preserve script evaluation history
6971		if ( attached ) {
6972			setGlobalEval( tmp );
6973		}
6974
6975		// Capture executables
6976		if ( scripts ) {
6977			j = 0;
6978			while ( ( elem = tmp[ j++ ] ) ) {
6979				if ( rscriptType.test( elem.type || "" ) ) {
6980					scripts.push( elem );
6981				}
6982			}
6983		}
6984	}
6985
6986	return fragment;
6987}
6988
6989
6990var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
6991
6992function returnTrue() {
6993	return true;
6994}
6995
6996function returnFalse() {
6997	return false;
6998}
6999
7000function on( elem, types, selector, data, fn, one ) {
7001	var origFn, type;
7002
7003	// Types can be a map of types/handlers
7004	if ( typeof types === "object" ) {
7005
7006		// ( types-Object, selector, data )
7007		if ( typeof selector !== "string" ) {
7008
7009			// ( types-Object, data )
7010			data = data || selector;
7011			selector = undefined;
7012		}
7013		for ( type in types ) {
7014			on( elem, type, selector, data, types[ type ], one );
7015		}
7016		return elem;
7017	}
7018
7019	if ( data == null && fn == null ) {
7020
7021		// ( types, fn )
7022		fn = selector;
7023		data = selector = undefined;
7024	} else if ( fn == null ) {
7025		if ( typeof selector === "string" ) {
7026
7027			// ( types, selector, fn )
7028			fn = data;
7029			data = undefined;
7030		} else {
7031
7032			// ( types, data, fn )
7033			fn = data;
7034			data = selector;
7035			selector = undefined;
7036		}
7037	}
7038	if ( fn === false ) {
7039		fn = returnFalse;
7040	} else if ( !fn ) {
7041		return elem;
7042	}
7043
7044	if ( one === 1 ) {
7045		origFn = fn;
7046		fn = function( event ) {
7047
7048			// Can use an empty set, since event contains the info
7049			jQuery().off( event );
7050			return origFn.apply( this, arguments );
7051		};
7052
7053		// Use same guid so caller can remove using origFn
7054		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
7055	}
7056	return elem.each( function() {
7057		jQuery.event.add( this, types, fn, data, selector );
7058	} );
7059}
7060
7061/*
7062 * Helper functions for managing events -- not part of the public interface.
7063 * Props to Dean Edwards' addEvent library for many of the ideas.
7064 */
7065jQuery.event = {
7066
7067	global: {},
7068
7069	add: function( elem, types, handler, data, selector ) {
7070
7071		var handleObjIn, eventHandle, tmp,
7072			events, t, handleObj,
7073			special, handlers, type, namespaces, origType,
7074			elemData = dataPriv.get( elem );
7075
7076		// Only attach events to objects that accept data
7077		if ( !acceptData( elem ) ) {
7078			return;
7079		}
7080
7081		// Caller can pass in an object of custom data in lieu of the handler
7082		if ( handler.handler ) {
7083			handleObjIn = handler;
7084			handler = handleObjIn.handler;
7085			selector = handleObjIn.selector;
7086		}
7087
7088		// Ensure that invalid selectors throw exceptions at attach time
7089		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
7090		if ( selector ) {
7091			jQuery.find.matchesSelector( documentElement, selector );
7092		}
7093
7094		// Make sure that the handler has a unique ID, used to find/remove it later
7095		if ( !handler.guid ) {
7096			handler.guid = jQuery.guid++;
7097		}
7098
7099		// Init the element's event structure and main handler, if this is the first
7100		if ( !( events = elemData.events ) ) {
7101			events = elemData.events = Object.create( null );
7102		}
7103		if ( !( eventHandle = elemData.handle ) ) {
7104			eventHandle = elemData.handle = function( e ) {
7105
7106				// Discard the second event of a jQuery.event.trigger() and
7107				// when an event is called after a page has unloaded
7108				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
7109					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
7110			};
7111		}
7112
7113		// Handle multiple events separated by a space
7114		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
7115		t = types.length;
7116		while ( t-- ) {
7117			tmp = rtypenamespace.exec( types[ t ] ) || [];
7118			type = origType = tmp[ 1 ];
7119			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
7120
7121			// There *must* be a type, no attaching namespace-only handlers
7122			if ( !type ) {
7123				continue;
7124			}
7125
7126			// If event changes its type, use the special event handlers for the changed type
7127			special = jQuery.event.special[ type ] || {};
7128
7129			// If selector defined, determine special event api type, otherwise given type
7130			type = ( selector ? special.delegateType : special.bindType ) || type;
7131
7132			// Update special based on newly reset type
7133			special = jQuery.event.special[ type ] || {};
7134
7135			// handleObj is passed to all event handlers
7136			handleObj = jQuery.extend( {
7137				type: type,
7138				origType: origType,
7139				data: data,
7140				handler: handler,
7141				guid: handler.guid,
7142				selector: selector,
7143				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
7144				namespace: namespaces.join( "." )
7145			}, handleObjIn );
7146
7147			// Init the event handler queue if we're the first
7148			if ( !( handlers = events[ type ] ) ) {
7149				handlers = events[ type ] = [];
7150				handlers.delegateCount = 0;
7151
7152				// Only use addEventListener if the special events handler returns false
7153				if ( !special.setup ||
7154					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
7155
7156					if ( elem.addEventListener ) {
7157						elem.addEventListener( type, eventHandle );
7158					}
7159				}
7160			}
7161
7162			if ( special.add ) {
7163				special.add.call( elem, handleObj );
7164
7165				if ( !handleObj.handler.guid ) {
7166					handleObj.handler.guid = handler.guid;
7167				}
7168			}
7169
7170			// Add to the element's handler list, delegates in front
7171			if ( selector ) {
7172				handlers.splice( handlers.delegateCount++, 0, handleObj );
7173			} else {
7174				handlers.push( handleObj );
7175			}
7176
7177			// Keep track of which events have ever been used, for event optimization
7178			jQuery.event.global[ type ] = true;
7179		}
7180
7181	},
7182
7183	// Detach an event or set of events from an element
7184	remove: function( elem, types, handler, selector, mappedTypes ) {
7185
7186		var j, origCount, tmp,
7187			events, t, handleObj,
7188			special, handlers, type, namespaces, origType,
7189			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
7190
7191		if ( !elemData || !( events = elemData.events ) ) {
7192			return;
7193		}
7194
7195		// Once for each type.namespace in types; type may be omitted
7196		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
7197		t = types.length;
7198		while ( t-- ) {
7199			tmp = rtypenamespace.exec( types[ t ] ) || [];
7200			type = origType = tmp[ 1 ];
7201			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
7202
7203			// Unbind all events (on this namespace, if provided) for the element
7204			if ( !type ) {
7205				for ( type in events ) {
7206					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
7207				}
7208				continue;
7209			}
7210
7211			special = jQuery.event.special[ type ] || {};
7212			type = ( selector ? special.delegateType : special.bindType ) || type;
7213			handlers = events[ type ] || [];
7214			tmp = tmp[ 2 ] &&
7215				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
7216
7217			// Remove matching events
7218			origCount = j = handlers.length;
7219			while ( j-- ) {
7220				handleObj = handlers[ j ];
7221
7222				if ( ( mappedTypes || origType === handleObj.origType ) &&
7223					( !handler || handler.guid === handleObj.guid ) &&
7224					( !tmp || tmp.test( handleObj.namespace ) ) &&
7225					( !selector || selector === handleObj.selector ||
7226						selector === "**" && handleObj.selector ) ) {
7227					handlers.splice( j, 1 );
7228
7229					if ( handleObj.selector ) {
7230						handlers.delegateCount--;
7231					}
7232					if ( special.remove ) {
7233						special.remove.call( elem, handleObj );
7234					}
7235				}
7236			}
7237
7238			// Remove generic event handler if we removed something and no more handlers exist
7239			// (avoids potential for endless recursion during removal of special event handlers)
7240			if ( origCount && !handlers.length ) {
7241				if ( !special.teardown ||
7242					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
7243
7244					jQuery.removeEvent( elem, type, elemData.handle );
7245				}
7246
7247				delete events[ type ];
7248			}
7249		}
7250
7251		// Remove data and the expando if it's no longer used
7252		if ( jQuery.isEmptyObject( events ) ) {
7253			dataPriv.remove( elem, "handle events" );
7254		}
7255	},
7256
7257	dispatch: function( nativeEvent ) {
7258
7259		var i, j, ret, matched, handleObj, handlerQueue,
7260			args = new Array( arguments.length ),
7261
7262			// Make a writable jQuery.Event from the native event object
7263			event = jQuery.event.fix( nativeEvent ),
7264
7265			handlers = (
7266				dataPriv.get( this, "events" ) || Object.create( null )
7267			)[ event.type ] || [],
7268			special = jQuery.event.special[ event.type ] || {};
7269
7270		// Use the fix-ed jQuery.Event rather than the (read-only) native event
7271		args[ 0 ] = event;
7272
7273		for ( i = 1; i < arguments.length; i++ ) {
7274			args[ i ] = arguments[ i ];
7275		}
7276
7277		event.delegateTarget = this;
7278
7279		// Call the preDispatch hook for the mapped type, and let it bail if desired
7280		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
7281			return;
7282		}
7283
7284		// Determine handlers
7285		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
7286
7287		// Run delegates first; they may want to stop propagation beneath us
7288		i = 0;
7289		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
7290			event.currentTarget = matched.elem;
7291
7292			j = 0;
7293			while ( ( handleObj = matched.handlers[ j++ ] ) &&
7294				!event.isImmediatePropagationStopped() ) {
7295
7296				// If the event is namespaced, then each handler is only invoked if it is
7297				// specially universal or its namespaces are a superset of the event's.
7298				if ( !event.rnamespace || handleObj.namespace === false ||
7299					event.rnamespace.test( handleObj.namespace ) ) {
7300
7301					event.handleObj = handleObj;
7302					event.data = handleObj.data;
7303
7304					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
7305						handleObj.handler ).apply( matched.elem, args );
7306
7307					if ( ret !== undefined ) {
7308						if ( ( event.result = ret ) === false ) {
7309							event.preventDefault();
7310							event.stopPropagation();
7311						}
7312					}
7313				}
7314			}
7315		}
7316
7317		// Call the postDispatch hook for the mapped type
7318		if ( special.postDispatch ) {
7319			special.postDispatch.call( this, event );
7320		}
7321
7322		return event.result;
7323	},
7324
7325	handlers: function( event, handlers ) {
7326		var i, handleObj, sel, matchedHandlers, matchedSelectors,
7327			handlerQueue = [],
7328			delegateCount = handlers.delegateCount,
7329			cur = event.target;
7330
7331		// Find delegate handlers
7332		if ( delegateCount &&
7333
7334			// Support: IE <=9
7335			// Black-hole SVG <use> instance trees (trac-13180)
7336			cur.nodeType &&
7337
7338			// Support: Firefox <=42
7339			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
7340			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
7341			// Support: IE 11 only
7342			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
7343			!( event.type === "click" && event.button >= 1 ) ) {
7344
7345			for ( ; cur !== this; cur = cur.parentNode || this ) {
7346
7347				// Don't check non-elements (trac-13208)
7348				// Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
7349				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
7350					matchedHandlers = [];
7351					matchedSelectors = {};
7352					for ( i = 0; i < delegateCount; i++ ) {
7353						handleObj = handlers[ i ];
7354
7355						// Don't conflict with Object.prototype properties (trac-13203)
7356						sel = handleObj.selector + " ";
7357
7358						if ( matchedSelectors[ sel ] === undefined ) {
7359							matchedSelectors[ sel ] = handleObj.needsContext ?
7360								jQuery( sel, this ).index( cur ) > -1 :
7361								jQuery.find( sel, this, null, [ cur ] ).length;
7362						}
7363						if ( matchedSelectors[ sel ] ) {
7364							matchedHandlers.push( handleObj );
7365						}
7366					}
7367					if ( matchedHandlers.length ) {
7368						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
7369					}
7370				}
7371			}
7372		}
7373
7374		// Add the remaining (directly-bound) handlers
7375		cur = this;
7376		if ( delegateCount < handlers.length ) {
7377			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
7378		}
7379
7380		return handlerQueue;
7381	},
7382
7383	addProp: function( name, hook ) {
7384		Object.defineProperty( jQuery.Event.prototype, name, {
7385			enumerable: true,
7386			configurable: true,
7387
7388			get: isFunction( hook ) ?
7389				function() {
7390					if ( this.originalEvent ) {
7391						return hook( this.originalEvent );
7392					}
7393				} :
7394				function() {
7395					if ( this.originalEvent ) {
7396						return this.originalEvent[ name ];
7397					}
7398				},
7399
7400			set: function( value ) {
7401				Object.defineProperty( this, name, {
7402					enumerable: true,
7403					configurable: true,
7404					writable: true,
7405					value: value
7406				} );
7407			}
7408		} );
7409	},
7410
7411	fix: function( originalEvent ) {
7412		return originalEvent[ jQuery.expando ] ?
7413			originalEvent :
7414			new jQuery.Event( originalEvent );
7415	},
7416
7417	special: {
7418		load: {
7419
7420			// Prevent triggered image.load events from bubbling to window.load
7421			noBubble: true
7422		},
7423		click: {
7424
7425			// Utilize native event to ensure correct state for checkable inputs
7426			setup: function( data ) {
7427
7428				// For mutual compressibility with _default, replace `this` access with a local var.
7429				// `|| data` is dead code meant only to preserve the variable through minification.
7430				var el = this || data;
7431
7432				// Claim the first handler
7433				if ( rcheckableType.test( el.type ) &&
7434					el.click && nodeName( el, "input" ) ) {
7435
7436					// dataPriv.set( el, "click", ... )
7437					leverageNative( el, "click", true );
7438				}
7439
7440				// Return false to allow normal processing in the caller
7441				return false;
7442			},
7443			trigger: function( data ) {
7444
7445				// For mutual compressibility with _default, replace `this` access with a local var.
7446				// `|| data` is dead code meant only to preserve the variable through minification.
7447				var el = this || data;
7448
7449				// Force setup before triggering a click
7450				if ( rcheckableType.test( el.type ) &&
7451					el.click && nodeName( el, "input" ) ) {
7452
7453					leverageNative( el, "click" );
7454				}
7455
7456				// Return non-false to allow normal event-path propagation
7457				return true;
7458			},
7459
7460			// For cross-browser consistency, suppress native .click() on links
7461			// Also prevent it if we're currently inside a leveraged native-event stack
7462			_default: function( event ) {
7463				var target = event.target;
7464				return rcheckableType.test( target.type ) &&
7465					target.click && nodeName( target, "input" ) &&
7466					dataPriv.get( target, "click" ) ||
7467					nodeName( target, "a" );
7468			}
7469		},
7470
7471		beforeunload: {
7472			postDispatch: function( event ) {
7473
7474				// Support: Firefox 20+
7475				// Firefox doesn't alert if the returnValue field is not set.
7476				if ( event.result !== undefined && event.originalEvent ) {
7477					event.originalEvent.returnValue = event.result;
7478				}
7479			}
7480		}
7481	}
7482};
7483
7484// Ensure the presence of an event listener that handles manually-triggered
7485// synthetic events by interrupting progress until reinvoked in response to
7486// *native* events that it fires directly, ensuring that state changes have
7487// already occurred before other listeners are invoked.
7488function leverageNative( el, type, isSetup ) {
7489
7490	// Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add
7491	if ( !isSetup ) {
7492		if ( dataPriv.get( el, type ) === undefined ) {
7493			jQuery.event.add( el, type, returnTrue );
7494		}
7495		return;
7496	}
7497
7498	// Register the controller as a special universal handler for all event namespaces
7499	dataPriv.set( el, type, false );
7500	jQuery.event.add( el, type, {
7501		namespace: false,
7502		handler: function( event ) {
7503			var result,
7504				saved = dataPriv.get( this, type );
7505
7506			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
7507
7508				// Interrupt processing of the outer synthetic .trigger()ed event
7509				if ( !saved ) {
7510
7511					// Store arguments for use when handling the inner native event
7512					// There will always be at least one argument (an event object), so this array
7513					// will not be confused with a leftover capture object.
7514					saved = slice.call( arguments );
7515					dataPriv.set( this, type, saved );
7516
7517					// Trigger the native event and capture its result
7518					this[ type ]();
7519					result = dataPriv.get( this, type );
7520					dataPriv.set( this, type, false );
7521
7522					if ( saved !== result ) {
7523
7524						// Cancel the outer synthetic event
7525						event.stopImmediatePropagation();
7526						event.preventDefault();
7527
7528						return result;
7529					}
7530
7531				// If this is an inner synthetic event for an event with a bubbling surrogate
7532				// (focus or blur), assume that the surrogate already propagated from triggering
7533				// the native event and prevent that from happening again here.
7534				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
7535				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
7536				// less bad than duplication.
7537				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
7538					event.stopPropagation();
7539				}
7540
7541			// If this is a native event triggered above, everything is now in order
7542			// Fire an inner synthetic event with the original arguments
7543			} else if ( saved ) {
7544
7545				// ...and capture the result
7546				dataPriv.set( this, type, jQuery.event.trigger(
7547					saved[ 0 ],
7548					saved.slice( 1 ),
7549					this
7550				) );
7551
7552				// Abort handling of the native event by all jQuery handlers while allowing
7553				// native handlers on the same element to run. On target, this is achieved
7554				// by stopping immediate propagation just on the jQuery event. However,
7555				// the native event is re-wrapped by a jQuery one on each level of the
7556				// propagation so the only way to stop it for jQuery is to stop it for
7557				// everyone via native `stopPropagation()`. This is not a problem for
7558				// focus/blur which don't bubble, but it does also stop click on checkboxes
7559				// and radios. We accept this limitation.
7560				event.stopPropagation();
7561				event.isImmediatePropagationStopped = returnTrue;
7562			}
7563		}
7564	} );
7565}
7566
7567jQuery.removeEvent = function( elem, type, handle ) {
7568
7569	// This "if" is needed for plain objects
7570	if ( elem.removeEventListener ) {
7571		elem.removeEventListener( type, handle );
7572	}
7573};
7574
7575jQuery.Event = function( src, props ) {
7576
7577	// Allow instantiation without the 'new' keyword
7578	if ( !( this instanceof jQuery.Event ) ) {
7579		return new jQuery.Event( src, props );
7580	}
7581
7582	// Event object
7583	if ( src && src.type ) {
7584		this.originalEvent = src;
7585		this.type = src.type;
7586
7587		// Events bubbling up the document may have been marked as prevented
7588		// by a handler lower down the tree; reflect the correct value.
7589		this.isDefaultPrevented = src.defaultPrevented ||
7590				src.defaultPrevented === undefined &&
7591
7592				// Support: Android <=2.3 only
7593				src.returnValue === false ?
7594			returnTrue :
7595			returnFalse;
7596
7597		// Create target properties
7598		// Support: Safari <=6 - 7 only
7599		// Target should not be a text node (trac-504, trac-13143)
7600		this.target = ( src.target && src.target.nodeType === 3 ) ?
7601			src.target.parentNode :
7602			src.target;
7603
7604		this.currentTarget = src.currentTarget;
7605		this.relatedTarget = src.relatedTarget;
7606
7607	// Event type
7608	} else {
7609		this.type = src;
7610	}
7611
7612	// Put explicitly provided properties onto the event object
7613	if ( props ) {
7614		jQuery.extend( this, props );
7615	}
7616
7617	// Create a timestamp if incoming event doesn't have one
7618	this.timeStamp = src && src.timeStamp || Date.now();
7619
7620	// Mark it as fixed
7621	this[ jQuery.expando ] = true;
7622};
7623
7624// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
7625// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
7626jQuery.Event.prototype = {
7627	constructor: jQuery.Event,
7628	isDefaultPrevented: returnFalse,
7629	isPropagationStopped: returnFalse,
7630	isImmediatePropagationStopped: returnFalse,
7631	isSimulated: false,
7632
7633	preventDefault: function() {
7634		var e = this.originalEvent;
7635
7636		this.isDefaultPrevented = returnTrue;
7637
7638		if ( e && !this.isSimulated ) {
7639			e.preventDefault();
7640		}
7641	},
7642	stopPropagation: function() {
7643		var e = this.originalEvent;
7644
7645		this.isPropagationStopped = returnTrue;
7646
7647		if ( e && !this.isSimulated ) {
7648			e.stopPropagation();
7649		}
7650	},
7651	stopImmediatePropagation: function() {
7652		var e = this.originalEvent;
7653
7654		this.isImmediatePropagationStopped = returnTrue;
7655
7656		if ( e && !this.isSimulated ) {
7657			e.stopImmediatePropagation();
7658		}
7659
7660		this.stopPropagation();
7661	}
7662};
7663
7664// Includes all common event props including KeyEvent and MouseEvent specific props
7665jQuery.each( {
7666	altKey: true,
7667	bubbles: true,
7668	cancelable: true,
7669	changedTouches: true,
7670	ctrlKey: true,
7671	detail: true,
7672	eventPhase: true,
7673	metaKey: true,
7674	pageX: true,
7675	pageY: true,
7676	shiftKey: true,
7677	view: true,
7678	"char": true,
7679	code: true,
7680	charCode: true,
7681	key: true,
7682	keyCode: true,
7683	button: true,
7684	buttons: true,
7685	clientX: true,
7686	clientY: true,
7687	offsetX: true,
7688	offsetY: true,
7689	pointerId: true,
7690	pointerType: true,
7691	screenX: true,
7692	screenY: true,
7693	targetTouches: true,
7694	toElement: true,
7695	touches: true,
7696	which: true
7697}, jQuery.event.addProp );
7698
7699jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
7700
7701	function focusMappedHandler( nativeEvent ) {
7702		if ( document.documentMode ) {
7703
7704			// Support: IE 11+
7705			// Attach a single focusin/focusout handler on the document while someone wants
7706			// focus/blur. This is because the former are synchronous in IE while the latter
7707			// are async. In other browsers, all those handlers are invoked synchronously.
7708
7709			// `handle` from private data would already wrap the event, but we need
7710			// to change the `type` here.
7711			var handle = dataPriv.get( this, "handle" ),
7712				event = jQuery.event.fix( nativeEvent );
7713			event.type = nativeEvent.type === "focusin" ? "focus" : "blur";
7714			event.isSimulated = true;
7715
7716			// First, handle focusin/focusout
7717			handle( nativeEvent );
7718
7719			// ...then, handle focus/blur
7720			//
7721			// focus/blur don't bubble while focusin/focusout do; simulate the former by only
7722			// invoking the handler at the lower level.
7723			if ( event.target === event.currentTarget ) {
7724
7725				// The setup part calls `leverageNative`, which, in turn, calls
7726				// `jQuery.event.add`, so event handle will already have been set
7727				// by this point.
7728				handle( event );
7729			}
7730		} else {
7731
7732			// For non-IE browsers, attach a single capturing handler on the document
7733			// while someone wants focusin/focusout.
7734			jQuery.event.simulate( delegateType, nativeEvent.target,
7735				jQuery.event.fix( nativeEvent ) );
7736		}
7737	}
7738
7739	jQuery.event.special[ type ] = {
7740
7741		// Utilize native event if possible so blur/focus sequence is correct
7742		setup: function() {
7743
7744			var attaches;
7745
7746			// Claim the first handler
7747			// dataPriv.set( this, "focus", ... )
7748			// dataPriv.set( this, "blur", ... )
7749			leverageNative( this, type, true );
7750
7751			if ( document.documentMode ) {
7752
7753				// Support: IE 9 - 11+
7754				// We use the same native handler for focusin & focus (and focusout & blur)
7755				// so we need to coordinate setup & teardown parts between those events.
7756				// Use `delegateType` as the key as `type` is already used by `leverageNative`.
7757				attaches = dataPriv.get( this, delegateType );
7758				if ( !attaches ) {
7759					this.addEventListener( delegateType, focusMappedHandler );
7760				}
7761				dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 );
7762			} else {
7763
7764				// Return false to allow normal processing in the caller
7765				return false;
7766			}
7767		},
7768		trigger: function() {
7769
7770			// Force setup before trigger
7771			leverageNative( this, type );
7772
7773			// Return non-false to allow normal event-path propagation
7774			return true;
7775		},
7776
7777		teardown: function() {
7778			var attaches;
7779
7780			if ( document.documentMode ) {
7781				attaches = dataPriv.get( this, delegateType ) - 1;
7782				if ( !attaches ) {
7783					this.removeEventListener( delegateType, focusMappedHandler );
7784					dataPriv.remove( this, delegateType );
7785				} else {
7786					dataPriv.set( this, delegateType, attaches );
7787				}
7788			} else {
7789
7790				// Return false to indicate standard teardown should be applied
7791				return false;
7792			}
7793		},
7794
7795		// Suppress native focus or blur if we're currently inside
7796		// a leveraged native-event stack
7797		_default: function( event ) {
7798			return dataPriv.get( event.target, type );
7799		},
7800
7801		delegateType: delegateType
7802	};
7803
7804	// Support: Firefox <=44
7805	// Firefox doesn't have focus(in | out) events
7806	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
7807	//
7808	// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
7809	// focus(in | out) events fire after focus & blur events,
7810	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
7811	// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
7812	//
7813	// Support: IE 9 - 11+
7814	// To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,
7815	// attach a single handler for both events in IE.
7816	jQuery.event.special[ delegateType ] = {
7817		setup: function() {
7818
7819			// Handle: regular nodes (via `this.ownerDocument`), window
7820			// (via `this.document`) & document (via `this`).
7821			var doc = this.ownerDocument || this.document || this,
7822				dataHolder = document.documentMode ? this : doc,
7823				attaches = dataPriv.get( dataHolder, delegateType );
7824
7825			// Support: IE 9 - 11+
7826			// We use the same native handler for focusin & focus (and focusout & blur)
7827			// so we need to coordinate setup & teardown parts between those events.
7828			// Use `delegateType` as the key as `type` is already used by `leverageNative`.
7829			if ( !attaches ) {
7830				if ( document.documentMode ) {
7831					this.addEventListener( delegateType, focusMappedHandler );
7832				} else {
7833					doc.addEventListener( type, focusMappedHandler, true );
7834				}
7835			}
7836			dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 );
7837		},
7838		teardown: function() {
7839			var doc = this.ownerDocument || this.document || this,
7840				dataHolder = document.documentMode ? this : doc,
7841				attaches = dataPriv.get( dataHolder, delegateType ) - 1;
7842
7843			if ( !attaches ) {
7844				if ( document.documentMode ) {
7845					this.removeEventListener( delegateType, focusMappedHandler );
7846				} else {
7847					doc.removeEventListener( type, focusMappedHandler, true );
7848				}
7849				dataPriv.remove( dataHolder, delegateType );
7850			} else {
7851				dataPriv.set( dataHolder, delegateType, attaches );
7852			}
7853		}
7854	};
7855} );
7856
7857// Create mouseenter/leave events using mouseover/out and event-time checks
7858// so that event delegation works in jQuery.
7859// Do the same for pointerenter/pointerleave and pointerover/pointerout
7860//
7861// Support: Safari 7 only
7862// Safari sends mouseenter too often; see:
7863// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
7864// for the description of the bug (it existed in older Chrome versions as well).
7865jQuery.each( {
7866	mouseenter: "mouseover",
7867	mouseleave: "mouseout",
7868	pointerenter: "pointerover",
7869	pointerleave: "pointerout"
7870}, function( orig, fix ) {
7871	jQuery.event.special[ orig ] = {
7872		delegateType: fix,
7873		bindType: fix,
7874
7875		handle: function( event ) {
7876			var ret,
7877				target = this,
7878				related = event.relatedTarget,
7879				handleObj = event.handleObj;
7880
7881			// For mouseenter/leave call the handler if related is outside the target.
7882			// NB: No relatedTarget if the mouse left/entered the browser window
7883			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
7884				event.type = handleObj.origType;
7885				ret = handleObj.handler.apply( this, arguments );
7886				event.type = fix;
7887			}
7888			return ret;
7889		}
7890	};
7891} );
7892
7893jQuery.fn.extend( {
7894
7895	on: function( types, selector, data, fn ) {
7896		return on( this, types, selector, data, fn );
7897	},
7898	one: function( types, selector, data, fn ) {
7899		return on( this, types, selector, data, fn, 1 );
7900	},
7901	off: function( types, selector, fn ) {
7902		var handleObj, type;
7903		if ( types && types.preventDefault && types.handleObj ) {
7904
7905			// ( event )  dispatched jQuery.Event
7906			handleObj = types.handleObj;
7907			jQuery( types.delegateTarget ).off(
7908				handleObj.namespace ?
7909					handleObj.origType + "." + handleObj.namespace :
7910					handleObj.origType,
7911				handleObj.selector,
7912				handleObj.handler
7913			);
7914			return this;
7915		}
7916		if ( typeof types === "object" ) {
7917
7918			// ( types-object [, selector] )
7919			for ( type in types ) {
7920				this.off( type, selector, types[ type ] );
7921			}
7922			return this;
7923		}
7924		if ( selector === false || typeof selector === "function" ) {
7925
7926			// ( types [, fn] )
7927			fn = selector;
7928			selector = undefined;
7929		}
7930		if ( fn === false ) {
7931			fn = returnFalse;
7932		}
7933		return this.each( function() {
7934			jQuery.event.remove( this, types, fn, selector );
7935		} );
7936	}
7937} );
7938
7939
7940var
7941
7942	// Support: IE <=10 - 11, Edge 12 - 13 only
7943	// In IE/Edge using regex groups here causes severe slowdowns.
7944	// See https://connect.microsoft.com/IE/feedback/details/1736512/
7945	rnoInnerhtml = /<script|<style|<link/i,
7946
7947	// checked="checked" or checked
7948	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
7949
7950	rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;
7951
7952// Prefer a tbody over its parent table for containing new rows
7953function manipulationTarget( elem, content ) {
7954	if ( nodeName( elem, "table" ) &&
7955		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
7956
7957		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
7958	}
7959
7960	return elem;
7961}
7962
7963// Replace/restore the type attribute of script elements for safe DOM manipulation
7964function disableScript( elem ) {
7965	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
7966	return elem;
7967}
7968function restoreScript( elem ) {
7969	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
7970		elem.type = elem.type.slice( 5 );
7971	} else {
7972		elem.removeAttribute( "type" );
7973	}
7974
7975	return elem;
7976}
7977
7978function cloneCopyEvent( src, dest ) {
7979	var i, l, type, pdataOld, udataOld, udataCur, events;
7980
7981	if ( dest.nodeType !== 1 ) {
7982		return;
7983	}
7984
7985	// 1. Copy private data: events, handlers, etc.
7986	if ( dataPriv.hasData( src ) ) {
7987		pdataOld = dataPriv.get( src );
7988		events = pdataOld.events;
7989
7990		if ( events ) {
7991			dataPriv.remove( dest, "handle events" );
7992
7993			for ( type in events ) {
7994				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
7995					jQuery.event.add( dest, type, events[ type ][ i ] );
7996				}
7997			}
7998		}
7999	}
8000
8001	// 2. Copy user data
8002	if ( dataUser.hasData( src ) ) {
8003		udataOld = dataUser.access( src );
8004		udataCur = jQuery.extend( {}, udataOld );
8005
8006		dataUser.set( dest, udataCur );
8007	}
8008}
8009
8010// Fix IE bugs, see support tests
8011function fixInput( src, dest ) {
8012	var nodeName = dest.nodeName.toLowerCase();
8013
8014	// Fails to persist the checked state of a cloned checkbox or radio button.
8015	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
8016		dest.checked = src.checked;
8017
8018	// Fails to return the selected option to the default selected state when cloning options
8019	} else if ( nodeName === "input" || nodeName === "textarea" ) {
8020		dest.defaultValue = src.defaultValue;
8021	}
8022}
8023
8024function domManip( collection, args, callback, ignored ) {
8025
8026	// Flatten any nested arrays
8027	args = flat( args );
8028
8029	var fragment, first, scripts, hasScripts, node, doc,
8030		i = 0,
8031		l = collection.length,
8032		iNoClone = l - 1,
8033		value = args[ 0 ],
8034		valueIsFunction = isFunction( value );
8035
8036	// We can't cloneNode fragments that contain checked, in WebKit
8037	if ( valueIsFunction ||
8038			( l > 1 && typeof value === "string" &&
8039				!support.checkClone && rchecked.test( value ) ) ) {
8040		return collection.each( function( index ) {
8041			var self = collection.eq( index );
8042			if ( valueIsFunction ) {
8043				args[ 0 ] = value.call( this, index, self.html() );
8044			}
8045			domManip( self, args, callback, ignored );
8046		} );
8047	}
8048
8049	if ( l ) {
8050		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
8051		first = fragment.firstChild;
8052
8053		if ( fragment.childNodes.length === 1 ) {
8054			fragment = first;
8055		}
8056
8057		// Require either new content or an interest in ignored elements to invoke the callback
8058		if ( first || ignored ) {
8059			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
8060			hasScripts = scripts.length;
8061
8062			// Use the original fragment for the last item
8063			// instead of the first because it can end up
8064			// being emptied incorrectly in certain situations (trac-8070).
8065			for ( ; i < l; i++ ) {
8066				node = fragment;
8067
8068				if ( i !== iNoClone ) {
8069					node = jQuery.clone( node, true, true );
8070
8071					// Keep references to cloned scripts for later restoration
8072					if ( hasScripts ) {
8073
8074						// Support: Android <=4.0 only, PhantomJS 1 only
8075						// push.apply(_, arraylike) throws on ancient WebKit
8076						jQuery.merge( scripts, getAll( node, "script" ) );
8077					}
8078				}
8079
8080				callback.call( collection[ i ], node, i );
8081			}
8082
8083			if ( hasScripts ) {
8084				doc = scripts[ scripts.length - 1 ].ownerDocument;
8085
8086				// Re-enable scripts
8087				jQuery.map( scripts, restoreScript );
8088
8089				// Evaluate executable scripts on first document insertion
8090				for ( i = 0; i < hasScripts; i++ ) {
8091					node = scripts[ i ];
8092					if ( rscriptType.test( node.type || "" ) &&
8093						!dataPriv.access( node, "globalEval" ) &&
8094						jQuery.contains( doc, node ) ) {
8095
8096						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
8097
8098							// Optional AJAX dependency, but won't run scripts if not present
8099							if ( jQuery._evalUrl && !node.noModule ) {
8100								jQuery._evalUrl( node.src, {
8101									nonce: node.nonce || node.getAttribute( "nonce" )
8102								}, doc );
8103							}
8104						} else {
8105
8106							// Unwrap a CDATA section containing script contents. This shouldn't be
8107							// needed as in XML documents they're already not visible when
8108							// inspecting element contents and in HTML documents they have no
8109							// meaning but we're preserving that logic for backwards compatibility.
8110							// This will be removed completely in 4.0. See gh-4904.
8111							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
8112						}
8113					}
8114				}
8115			}
8116		}
8117	}
8118
8119	return collection;
8120}
8121
8122function remove( elem, selector, keepData ) {
8123	var node,
8124		nodes = selector ? jQuery.filter( selector, elem ) : elem,
8125		i = 0;
8126
8127	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
8128		if ( !keepData && node.nodeType === 1 ) {
8129			jQuery.cleanData( getAll( node ) );
8130		}
8131
8132		if ( node.parentNode ) {
8133			if ( keepData && isAttached( node ) ) {
8134				setGlobalEval( getAll( node, "script" ) );
8135			}
8136			node.parentNode.removeChild( node );
8137		}
8138	}
8139
8140	return elem;
8141}
8142
8143jQuery.extend( {
8144	htmlPrefilter: function( html ) {
8145		return html;
8146	},
8147
8148	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
8149		var i, l, srcElements, destElements,
8150			clone = elem.cloneNode( true ),
8151			inPage = isAttached( elem );
8152
8153		// Fix IE cloning issues
8154		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
8155				!jQuery.isXMLDoc( elem ) ) {
8156
8157			// We eschew jQuery#find here for performance reasons:
8158			// https://jsperf.com/getall-vs-sizzle/2
8159			destElements = getAll( clone );
8160			srcElements = getAll( elem );
8161
8162			for ( i = 0, l = srcElements.length; i < l; i++ ) {
8163				fixInput( srcElements[ i ], destElements[ i ] );
8164			}
8165		}
8166
8167		// Copy the events from the original to the clone
8168		if ( dataAndEvents ) {
8169			if ( deepDataAndEvents ) {
8170				srcElements = srcElements || getAll( elem );
8171				destElements = destElements || getAll( clone );
8172
8173				for ( i = 0, l = srcElements.length; i < l; i++ ) {
8174					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
8175				}
8176			} else {
8177				cloneCopyEvent( elem, clone );
8178			}
8179		}
8180
8181		// Preserve script evaluation history
8182		destElements = getAll( clone, "script" );
8183		if ( destElements.length > 0 ) {
8184			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
8185		}
8186
8187		// Return the cloned set
8188		return clone;
8189	},
8190
8191	cleanData: function( elems ) {
8192		var data, elem, type,
8193			special = jQuery.event.special,
8194			i = 0;
8195
8196		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
8197			if ( acceptData( elem ) ) {
8198				if ( ( data = elem[ dataPriv.expando ] ) ) {
8199					if ( data.events ) {
8200						for ( type in data.events ) {
8201							if ( special[ type ] ) {
8202								jQuery.event.remove( elem, type );
8203
8204							// This is a shortcut to avoid jQuery.event.remove's overhead
8205							} else {
8206								jQuery.removeEvent( elem, type, data.handle );
8207							}
8208						}
8209					}
8210
8211					// Support: Chrome <=35 - 45+
8212					// Assign undefined instead of using delete, see Data#remove
8213					elem[ dataPriv.expando ] = undefined;
8214				}
8215				if ( elem[ dataUser.expando ] ) {
8216
8217					// Support: Chrome <=35 - 45+
8218					// Assign undefined instead of using delete, see Data#remove
8219					elem[ dataUser.expando ] = undefined;
8220				}
8221			}
8222		}
8223	}
8224} );
8225
8226jQuery.fn.extend( {
8227	detach: function( selector ) {
8228		return remove( this, selector, true );
8229	},
8230
8231	remove: function( selector ) {
8232		return remove( this, selector );
8233	},
8234
8235	text: function( value ) {
8236		return access( this, function( value ) {
8237			return value === undefined ?
8238				jQuery.text( this ) :
8239				this.empty().each( function() {
8240					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
8241						this.textContent = value;
8242					}
8243				} );
8244		}, null, value, arguments.length );
8245	},
8246
8247	append: function() {
8248		return domManip( this, arguments, function( elem ) {
8249			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
8250				var target = manipulationTarget( this, elem );
8251				target.appendChild( elem );
8252			}
8253		} );
8254	},
8255
8256	prepend: function() {
8257		return domManip( this, arguments, function( elem ) {
8258			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
8259				var target = manipulationTarget( this, elem );
8260				target.insertBefore( elem, target.firstChild );
8261			}
8262		} );
8263	},
8264
8265	before: function() {
8266		return domManip( this, arguments, function( elem ) {
8267			if ( this.parentNode ) {
8268				this.parentNode.insertBefore( elem, this );
8269			}
8270		} );
8271	},
8272
8273	after: function() {
8274		return domManip( this, arguments, function( elem ) {
8275			if ( this.parentNode ) {
8276				this.parentNode.insertBefore( elem, this.nextSibling );
8277			}
8278		} );
8279	},
8280
8281	empty: function() {
8282		var elem,
8283			i = 0;
8284
8285		for ( ; ( elem = this[ i ] ) != null; i++ ) {
8286			if ( elem.nodeType === 1 ) {
8287
8288				// Prevent memory leaks
8289				jQuery.cleanData( getAll( elem, false ) );
8290
8291				// Remove any remaining nodes
8292				elem.textContent = "";
8293			}
8294		}
8295
8296		return this;
8297	},
8298
8299	clone: function( dataAndEvents, deepDataAndEvents ) {
8300		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
8301		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
8302
8303		return this.map( function() {
8304			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
8305		} );
8306	},
8307
8308	html: function( value ) {
8309		return access( this, function( value ) {
8310			var elem = this[ 0 ] || {},
8311				i = 0,
8312				l = this.length;
8313
8314			if ( value === undefined && elem.nodeType === 1 ) {
8315				return elem.innerHTML;
8316			}
8317
8318			// See if we can take a shortcut and just use innerHTML
8319			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
8320				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
8321
8322				value = jQuery.htmlPrefilter( value );
8323
8324				try {
8325					for ( ; i < l; i++ ) {
8326						elem = this[ i ] || {};
8327
8328						// Remove element nodes and prevent memory leaks
8329						if ( elem.nodeType === 1 ) {
8330							jQuery.cleanData( getAll( elem, false ) );
8331							elem.innerHTML = value;
8332						}
8333					}
8334
8335					elem = 0;
8336
8337				// If using innerHTML throws an exception, use the fallback method
8338				} catch ( e ) {}
8339			}
8340
8341			if ( elem ) {
8342				this.empty().append( value );
8343			}
8344		}, null, value, arguments.length );
8345	},
8346
8347	replaceWith: function() {
8348		var ignored = [];
8349
8350		// Make the changes, replacing each non-ignored context element with the new content
8351		return domManip( this, arguments, function( elem ) {
8352			var parent = this.parentNode;
8353
8354			if ( jQuery.inArray( this, ignored ) < 0 ) {
8355				jQuery.cleanData( getAll( this ) );
8356				if ( parent ) {
8357					parent.replaceChild( elem, this );
8358				}
8359			}
8360
8361		// Force callback invocation
8362		}, ignored );
8363	}
8364} );
8365
8366jQuery.each( {
8367	appendTo: "append",
8368	prependTo: "prepend",
8369	insertBefore: "before",
8370	insertAfter: "after",
8371	replaceAll: "replaceWith"
8372}, function( name, original ) {
8373	jQuery.fn[ name ] = function( selector ) {
8374		var elems,
8375			ret = [],
8376			insert = jQuery( selector ),
8377			last = insert.length - 1,
8378			i = 0;
8379
8380		for ( ; i <= last; i++ ) {
8381			elems = i === last ? this : this.clone( true );
8382			jQuery( insert[ i ] )[ original ]( elems );
8383
8384			// Support: Android <=4.0 only, PhantomJS 1 only
8385			// .get() because push.apply(_, arraylike) throws on ancient WebKit
8386			push.apply( ret, elems.get() );
8387		}
8388
8389		return this.pushStack( ret );
8390	};
8391} );
8392var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
8393
8394var rcustomProp = /^--/;
8395
8396
8397var getStyles = function( elem ) {
8398
8399		// Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
8400		// IE throws on elements created in popups
8401		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
8402		var view = elem.ownerDocument.defaultView;
8403
8404		if ( !view || !view.opener ) {
8405			view = window;
8406		}
8407
8408		return view.getComputedStyle( elem );
8409	};
8410
8411var swap = function( elem, options, callback ) {
8412	var ret, name,
8413		old = {};
8414
8415	// Remember the old values, and insert the new ones
8416	for ( name in options ) {
8417		old[ name ] = elem.style[ name ];
8418		elem.style[ name ] = options[ name ];
8419	}
8420
8421	ret = callback.call( elem );
8422
8423	// Revert the old values
8424	for ( name in options ) {
8425		elem.style[ name ] = old[ name ];
8426	}
8427
8428	return ret;
8429};
8430
8431
8432var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
8433
8434
8435
8436( function() {
8437
8438	// Executing both pixelPosition & boxSizingReliable tests require only one layout
8439	// so they're executed at the same time to save the second computation.
8440	function computeStyleTests() {
8441
8442		// This is a singleton, we need to execute it only once
8443		if ( !div ) {
8444			return;
8445		}
8446
8447		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
8448			"margin-top:1px;padding:0;border:0";
8449		div.style.cssText =
8450			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
8451			"margin:auto;border:1px;padding:1px;" +
8452			"width:60%;top:1%";
8453		documentElement.appendChild( container ).appendChild( div );
8454
8455		var divStyle = window.getComputedStyle( div );
8456		pixelPositionVal = divStyle.top !== "1%";
8457
8458		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
8459		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
8460
8461		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
8462		// Some styles come back with percentage values, even though they shouldn't
8463		div.style.right = "60%";
8464		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
8465
8466		// Support: IE 9 - 11 only
8467		// Detect misreporting of content dimensions for box-sizing:border-box elements
8468		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
8469
8470		// Support: IE 9 only
8471		// Detect overflow:scroll screwiness (gh-3699)
8472		// Support: Chrome <=64
8473		// Don't get tricked when zoom affects offsetWidth (gh-4029)
8474		div.style.position = "absolute";
8475		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
8476
8477		documentElement.removeChild( container );
8478
8479		// Nullify the div so it wouldn't be stored in the memory and
8480		// it will also be a sign that checks already performed
8481		div = null;
8482	}
8483
8484	function roundPixelMeasures( measure ) {
8485		return Math.round( parseFloat( measure ) );
8486	}
8487
8488	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
8489		reliableTrDimensionsVal, reliableMarginLeftVal,
8490		container = document.createElement( "div" ),
8491		div = document.createElement( "div" );
8492
8493	// Finish early in limited (non-browser) environments
8494	if ( !div.style ) {
8495		return;
8496	}
8497
8498	// Support: IE <=9 - 11 only
8499	// Style of cloned element affects source element cloned (trac-8908)
8500	div.style.backgroundClip = "content-box";
8501	div.cloneNode( true ).style.backgroundClip = "";
8502	support.clearCloneStyle = div.style.backgroundClip === "content-box";
8503
8504	jQuery.extend( support, {
8505		boxSizingReliable: function() {
8506			computeStyleTests();
8507			return boxSizingReliableVal;
8508		},
8509		pixelBoxStyles: function() {
8510			computeStyleTests();
8511			return pixelBoxStylesVal;
8512		},
8513		pixelPosition: function() {
8514			computeStyleTests();
8515			return pixelPositionVal;
8516		},
8517		reliableMarginLeft: function() {
8518			computeStyleTests();
8519			return reliableMarginLeftVal;
8520		},
8521		scrollboxSize: function() {
8522			computeStyleTests();
8523			return scrollboxSizeVal;
8524		},
8525
8526		// Support: IE 9 - 11+, Edge 15 - 18+
8527		// IE/Edge misreport `getComputedStyle` of table rows with width/height
8528		// set in CSS while `offset*` properties report correct values.
8529		// Behavior in IE 9 is more subtle than in newer versions & it passes
8530		// some versions of this test; make sure not to make it pass there!
8531		//
8532		// Support: Firefox 70+
8533		// Only Firefox includes border widths
8534		// in computed dimensions. (gh-4529)
8535		reliableTrDimensions: function() {
8536			var table, tr, trChild, trStyle;
8537			if ( reliableTrDimensionsVal == null ) {
8538				table = document.createElement( "table" );
8539				tr = document.createElement( "tr" );
8540				trChild = document.createElement( "div" );
8541
8542				table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
8543				tr.style.cssText = "box-sizing:content-box;border:1px solid";
8544
8545				// Support: Chrome 86+
8546				// Height set through cssText does not get applied.
8547				// Computed height then comes back as 0.
8548				tr.style.height = "1px";
8549				trChild.style.height = "9px";
8550
8551				// Support: Android 8 Chrome 86+
8552				// In our bodyBackground.html iframe,
8553				// display for all div elements is set to "inline",
8554				// which causes a problem only in Android 8 Chrome 86.
8555				// Ensuring the div is `display: block`
8556				// gets around this issue.
8557				trChild.style.display = "block";
8558
8559				documentElement
8560					.appendChild( table )
8561					.appendChild( tr )
8562					.appendChild( trChild );
8563
8564				trStyle = window.getComputedStyle( tr );
8565				reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +
8566					parseInt( trStyle.borderTopWidth, 10 ) +
8567					parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;
8568
8569				documentElement.removeChild( table );
8570			}
8571			return reliableTrDimensionsVal;
8572		}
8573	} );
8574} )();
8575
8576
8577function curCSS( elem, name, computed ) {
8578	var width, minWidth, maxWidth, ret,
8579		isCustomProp = rcustomProp.test( name ),
8580
8581		// Support: Firefox 51+
8582		// Retrieving style before computed somehow
8583		// fixes an issue with getting wrong values
8584		// on detached elements
8585		style = elem.style;
8586
8587	computed = computed || getStyles( elem );
8588
8589	// getPropertyValue is needed for:
8590	//   .css('filter') (IE 9 only, trac-12537)
8591	//   .css('--customProperty) (gh-3144)
8592	if ( computed ) {
8593
8594		// Support: IE <=9 - 11+
8595		// IE only supports `"float"` in `getPropertyValue`; in computed styles
8596		// it's only available as `"cssFloat"`. We no longer modify properties
8597		// sent to `.css()` apart from camelCasing, so we need to check both.
8598		// Normally, this would create difference in behavior: if
8599		// `getPropertyValue` returns an empty string, the value returned
8600		// by `.css()` would be `undefined`. This is usually the case for
8601		// disconnected elements. However, in IE even disconnected elements
8602		// with no styles return `"none"` for `getPropertyValue( "float" )`
8603		ret = computed.getPropertyValue( name ) || computed[ name ];
8604
8605		if ( isCustomProp && ret ) {
8606
8607			// Support: Firefox 105+, Chrome <=105+
8608			// Spec requires trimming whitespace for custom properties (gh-4926).
8609			// Firefox only trims leading whitespace. Chrome just collapses
8610			// both leading & trailing whitespace to a single space.
8611			//
8612			// Fall back to `undefined` if empty string returned.
8613			// This collapses a missing definition with property defined
8614			// and set to an empty string but there's no standard API
8615			// allowing us to differentiate them without a performance penalty
8616			// and returning `undefined` aligns with older jQuery.
8617			//
8618			// rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED
8619			// as whitespace while CSS does not, but this is not a problem
8620			// because CSS preprocessing replaces them with U+000A LINE FEED
8621			// (which *is* CSS whitespace)
8622			// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
8623			ret = ret.replace( rtrimCSS, "$1" ) || undefined;
8624		}
8625
8626		if ( ret === "" && !isAttached( elem ) ) {
8627			ret = jQuery.style( elem, name );
8628		}
8629
8630		// A tribute to the "awesome hack by Dean Edwards"
8631		// Android Browser returns percentage for some values,
8632		// but width seems to be reliably pixels.
8633		// This is against the CSSOM draft spec:
8634		// https://drafts.csswg.org/cssom/#resolved-values
8635		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
8636
8637			// Remember the original values
8638			width = style.width;
8639			minWidth = style.minWidth;
8640			maxWidth = style.maxWidth;
8641
8642			// Put in the new values to get a computed value out
8643			style.minWidth = style.maxWidth = style.width = ret;
8644			ret = computed.width;
8645
8646			// Revert the changed values
8647			style.width = width;
8648			style.minWidth = minWidth;
8649			style.maxWidth = maxWidth;
8650		}
8651	}
8652
8653	return ret !== undefined ?
8654
8655		// Support: IE <=9 - 11 only
8656		// IE returns zIndex value as an integer.
8657		ret + "" :
8658		ret;
8659}
8660
8661
8662function addGetHookIf( conditionFn, hookFn ) {
8663
8664	// Define the hook, we'll check on the first run if it's really needed.
8665	return {
8666		get: function() {
8667			if ( conditionFn() ) {
8668
8669				// Hook not needed (or it's not possible to use it due
8670				// to missing dependency), remove it.
8671				delete this.get;
8672				return;
8673			}
8674
8675			// Hook needed; redefine it so that the support test is not executed again.
8676			return ( this.get = hookFn ).apply( this, arguments );
8677		}
8678	};
8679}
8680
8681
8682var cssPrefixes = [ "Webkit", "Moz", "ms" ],
8683	emptyStyle = document.createElement( "div" ).style,
8684	vendorProps = {};
8685
8686// Return a vendor-prefixed property or undefined
8687function vendorPropName( name ) {
8688
8689	// Check for vendor prefixed names
8690	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
8691		i = cssPrefixes.length;
8692
8693	while ( i-- ) {
8694		name = cssPrefixes[ i ] + capName;
8695		if ( name in emptyStyle ) {
8696			return name;
8697		}
8698	}
8699}
8700
8701// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
8702function finalPropName( name ) {
8703	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
8704
8705	if ( final ) {
8706		return final;
8707	}
8708	if ( name in emptyStyle ) {
8709		return name;
8710	}
8711	return vendorProps[ name ] = vendorPropName( name ) || name;
8712}
8713
8714
8715var
8716
8717	// Swappable if display is none or starts with table
8718	// except "table", "table-cell", or "table-caption"
8719	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
8720	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
8721	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
8722	cssNormalTransform = {
8723		letterSpacing: "0",
8724		fontWeight: "400"
8725	};
8726
8727function setPositiveNumber( _elem, value, subtract ) {
8728
8729	// Any relative (+/-) values have already been
8730	// normalized at this point
8731	var matches = rcssNum.exec( value );
8732	return matches ?
8733
8734		// Guard against undefined "subtract", e.g., when used as in cssHooks
8735		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
8736		value;
8737}
8738
8739function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
8740	var i = dimension === "width" ? 1 : 0,
8741		extra = 0,
8742		delta = 0,
8743		marginDelta = 0;
8744
8745	// Adjustment may not be necessary
8746	if ( box === ( isBorderBox ? "border" : "content" ) ) {
8747		return 0;
8748	}
8749
8750	for ( ; i < 4; i += 2 ) {
8751
8752		// Both box models exclude margin
8753		// Count margin delta separately to only add it after scroll gutter adjustment.
8754		// This is needed to make negative margins work with `outerHeight( true )` (gh-3982).
8755		if ( box === "margin" ) {
8756			marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
8757		}
8758
8759		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
8760		if ( !isBorderBox ) {
8761
8762			// Add padding
8763			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
8764
8765			// For "border" or "margin", add border
8766			if ( box !== "padding" ) {
8767				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
8768
8769			// But still keep track of it otherwise
8770			} else {
8771				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
8772			}
8773
8774		// If we get here with a border-box (content + padding + border), we're seeking "content" or
8775		// "padding" or "margin"
8776		} else {
8777
8778			// For "content", subtract padding
8779			if ( box === "content" ) {
8780				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
8781			}
8782
8783			// For "content" or "padding", subtract border
8784			if ( box !== "margin" ) {
8785				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
8786			}
8787		}
8788	}
8789
8790	// Account for positive content-box scroll gutter when requested by providing computedVal
8791	if ( !isBorderBox && computedVal >= 0 ) {
8792
8793		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
8794		// Assuming integer scroll gutter, subtract the rest and round down
8795		delta += Math.max( 0, Math.ceil(
8796			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
8797			computedVal -
8798			delta -
8799			extra -
8800			0.5
8801
8802		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
8803		// Use an explicit zero to avoid NaN (gh-3964)
8804		) ) || 0;
8805	}
8806
8807	return delta + marginDelta;
8808}
8809
8810function getWidthOrHeight( elem, dimension, extra ) {
8811
8812	// Start with computed style
8813	var styles = getStyles( elem ),
8814
8815		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
8816		// Fake content-box until we know it's needed to know the true value.
8817		boxSizingNeeded = !support.boxSizingReliable() || extra,
8818		isBorderBox = boxSizingNeeded &&
8819			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
8820		valueIsBorderBox = isBorderBox,
8821
8822		val = curCSS( elem, dimension, styles ),
8823		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
8824
8825	// Support: Firefox <=54
8826	// Return a confounding non-pixel value or feign ignorance, as appropriate.
8827	if ( rnumnonpx.test( val ) ) {
8828		if ( !extra ) {
8829			return val;
8830		}
8831		val = "auto";
8832	}
8833
8834
8835	// Support: IE 9 - 11 only
8836	// Use offsetWidth/offsetHeight for when box sizing is unreliable.
8837	// In those cases, the computed value can be trusted to be border-box.
8838	if ( ( !support.boxSizingReliable() && isBorderBox ||
8839
8840		// Support: IE 10 - 11+, Edge 15 - 18+
8841		// IE/Edge misreport `getComputedStyle` of table rows with width/height
8842		// set in CSS while `offset*` properties report correct values.
8843		// Interestingly, in some cases IE 9 doesn't suffer from this issue.
8844		!support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
8845
8846		// Fall back to offsetWidth/offsetHeight when value is "auto"
8847		// This happens for inline elements with no explicit setting (gh-3571)
8848		val === "auto" ||
8849
8850		// Support: Android <=4.1 - 4.3 only
8851		// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
8852		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
8853
8854		// Make sure the element is visible & connected
8855		elem.getClientRects().length ) {
8856
8857		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
8858
8859		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
8860		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
8861		// retrieved value as a content box dimension.
8862		valueIsBorderBox = offsetProp in elem;
8863		if ( valueIsBorderBox ) {
8864			val = elem[ offsetProp ];
8865		}
8866	}
8867
8868	// Normalize "" and auto
8869	val = parseFloat( val ) || 0;
8870
8871	// Adjust for the element's box model
8872	return ( val +
8873		boxModelAdjustment(
8874			elem,
8875			dimension,
8876			extra || ( isBorderBox ? "border" : "content" ),
8877			valueIsBorderBox,
8878			styles,
8879
8880			// Provide the current computed size to request scroll gutter calculation (gh-3589)
8881			val
8882		)
8883	) + "px";
8884}
8885
8886jQuery.extend( {
8887
8888	// Add in style property hooks for overriding the default
8889	// behavior of getting and setting a style property
8890	cssHooks: {
8891		opacity: {
8892			get: function( elem, computed ) {
8893				if ( computed ) {
8894
8895					// We should always get a number back from opacity
8896					var ret = curCSS( elem, "opacity" );
8897					return ret === "" ? "1" : ret;
8898				}
8899			}
8900		}
8901	},
8902
8903	// Don't automatically add "px" to these possibly-unitless properties
8904	cssNumber: {
8905		animationIterationCount: true,
8906		aspectRatio: true,
8907		borderImageSlice: true,
8908		columnCount: true,
8909		flexGrow: true,
8910		flexShrink: true,
8911		fontWeight: true,
8912		gridArea: true,
8913		gridColumn: true,
8914		gridColumnEnd: true,
8915		gridColumnStart: true,
8916		gridRow: true,
8917		gridRowEnd: true,
8918		gridRowStart: true,
8919		lineHeight: true,
8920		opacity: true,
8921		order: true,
8922		orphans: true,
8923		scale: true,
8924		widows: true,
8925		zIndex: true,
8926		zoom: true,
8927
8928		// SVG-related
8929		fillOpacity: true,
8930		floodOpacity: true,
8931		stopOpacity: true,
8932		strokeMiterlimit: true,
8933		strokeOpacity: true
8934	},
8935
8936	// Add in properties whose names you wish to fix before
8937	// setting or getting the value
8938	cssProps: {},
8939
8940	// Get and set the style property on a DOM Node
8941	style: function( elem, name, value, extra ) {
8942
8943		// Don't set styles on text and comment nodes
8944		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
8945			return;
8946		}
8947
8948		// Make sure that we're working with the right name
8949		var ret, type, hooks,
8950			origName = camelCase( name ),
8951			isCustomProp = rcustomProp.test( name ),
8952			style = elem.style;
8953
8954		// Make sure that we're working with the right name. We don't
8955		// want to query the value if it is a CSS custom property
8956		// since they are user-defined.
8957		if ( !isCustomProp ) {
8958			name = finalPropName( origName );
8959		}
8960
8961		// Gets hook for the prefixed version, then unprefixed version
8962		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
8963
8964		// Check if we're setting a value
8965		if ( value !== undefined ) {
8966			type = typeof value;
8967
8968			// Convert "+=" or "-=" to relative numbers (trac-7345)
8969			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
8970				value = adjustCSS( elem, name, ret );
8971
8972				// Fixes bug trac-9237
8973				type = "number";
8974			}
8975
8976			// Make sure that null and NaN values aren't set (trac-7116)
8977			if ( value == null || value !== value ) {
8978				return;
8979			}
8980
8981			// If a number was passed in, add the unit (except for certain CSS properties)
8982			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
8983			// "px" to a few hardcoded values.
8984			if ( type === "number" && !isCustomProp ) {
8985				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
8986			}
8987
8988			// background-* props affect original clone's values
8989			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
8990				style[ name ] = "inherit";
8991			}
8992
8993			// If a hook was provided, use that value, otherwise just set the specified value
8994			if ( !hooks || !( "set" in hooks ) ||
8995				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
8996
8997				if ( isCustomProp ) {
8998					style.setProperty( name, value );
8999				} else {
9000					style[ name ] = value;
9001				}
9002			}
9003
9004		} else {
9005
9006			// If a hook was provided get the non-computed value from there
9007			if ( hooks && "get" in hooks &&
9008				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
9009
9010				return ret;
9011			}
9012
9013			// Otherwise just get the value from the style object
9014			return style[ name ];
9015		}
9016	},
9017
9018	css: function( elem, name, extra, styles ) {
9019		var val, num, hooks,
9020			origName = camelCase( name ),
9021			isCustomProp = rcustomProp.test( name );
9022
9023		// Make sure that we're working with the right name. We don't
9024		// want to modify the value if it is a CSS custom property
9025		// since they are user-defined.
9026		if ( !isCustomProp ) {
9027			name = finalPropName( origName );
9028		}
9029
9030		// Try prefixed name followed by the unprefixed name
9031		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
9032
9033		// If a hook was provided get the computed value from there
9034		if ( hooks && "get" in hooks ) {
9035			val = hooks.get( elem, true, extra );
9036		}
9037
9038		// Otherwise, if a way to get the computed value exists, use that
9039		if ( val === undefined ) {
9040			val = curCSS( elem, name, styles );
9041		}
9042
9043		// Convert "normal" to computed value
9044		if ( val === "normal" && name in cssNormalTransform ) {
9045			val = cssNormalTransform[ name ];
9046		}
9047
9048		// Make numeric if forced or a qualifier was provided and val looks numeric
9049		if ( extra === "" || extra ) {
9050			num = parseFloat( val );
9051			return extra === true || isFinite( num ) ? num || 0 : val;
9052		}
9053
9054		return val;
9055	}
9056} );
9057
9058jQuery.each( [ "height", "width" ], function( _i, dimension ) {
9059	jQuery.cssHooks[ dimension ] = {
9060		get: function( elem, computed, extra ) {
9061			if ( computed ) {
9062
9063				// Certain elements can have dimension info if we invisibly show them
9064				// but it must have a current display style that would benefit
9065				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
9066
9067					// Support: Safari 8+
9068					// Table columns in Safari have non-zero offsetWidth & zero
9069					// getBoundingClientRect().width unless display is changed.
9070					// Support: IE <=11 only
9071					// Running getBoundingClientRect on a disconnected node
9072					// in IE throws an error.
9073					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
9074					swap( elem, cssShow, function() {
9075						return getWidthOrHeight( elem, dimension, extra );
9076					} ) :
9077					getWidthOrHeight( elem, dimension, extra );
9078			}
9079		},
9080
9081		set: function( elem, value, extra ) {
9082			var matches,
9083				styles = getStyles( elem ),
9084
9085				// Only read styles.position if the test has a chance to fail
9086				// to avoid forcing a reflow.
9087				scrollboxSizeBuggy = !support.scrollboxSize() &&
9088					styles.position === "absolute",
9089
9090				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
9091				boxSizingNeeded = scrollboxSizeBuggy || extra,
9092				isBorderBox = boxSizingNeeded &&
9093					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
9094				subtract = extra ?
9095					boxModelAdjustment(
9096						elem,
9097						dimension,
9098						extra,
9099						isBorderBox,
9100						styles
9101					) :
9102					0;
9103
9104			// Account for unreliable border-box dimensions by comparing offset* to computed and
9105			// faking a content-box to get border and padding (gh-3699)
9106			if ( isBorderBox && scrollboxSizeBuggy ) {
9107				subtract -= Math.ceil(
9108					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
9109					parseFloat( styles[ dimension ] ) -
9110					boxModelAdjustment( elem, dimension, "border", false, styles ) -
9111					0.5
9112				);
9113			}
9114
9115			// Convert to pixels if value adjustment is needed
9116			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
9117				( matches[ 3 ] || "px" ) !== "px" ) {
9118
9119				elem.style[ dimension ] = value;
9120				value = jQuery.css( elem, dimension );
9121			}
9122
9123			return setPositiveNumber( elem, value, subtract );
9124		}
9125	};
9126} );
9127
9128jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
9129	function( elem, computed ) {
9130		if ( computed ) {
9131			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
9132				elem.getBoundingClientRect().left -
9133					swap( elem, { marginLeft: 0 }, function() {
9134						return elem.getBoundingClientRect().left;
9135					} )
9136			) + "px";
9137		}
9138	}
9139);
9140
9141// These hooks are used by animate to expand properties
9142jQuery.each( {
9143	margin: "",
9144	padding: "",
9145	border: "Width"
9146}, function( prefix, suffix ) {
9147	jQuery.cssHooks[ prefix + suffix ] = {
9148		expand: function( value ) {
9149			var i = 0,
9150				expanded = {},
9151
9152				// Assumes a single number if not a string
9153				parts = typeof value === "string" ? value.split( " " ) : [ value ];
9154
9155			for ( ; i < 4; i++ ) {
9156				expanded[ prefix + cssExpand[ i ] + suffix ] =
9157					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
9158			}
9159
9160			return expanded;
9161		}
9162	};
9163
9164	if ( prefix !== "margin" ) {
9165		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
9166	}
9167} );
9168
9169jQuery.fn.extend( {
9170	css: function( name, value ) {
9171		return access( this, function( elem, name, value ) {
9172			var styles, len,
9173				map = {},
9174				i = 0;
9175
9176			if ( Array.isArray( name ) ) {
9177				styles = getStyles( elem );
9178				len = name.length;
9179
9180				for ( ; i < len; i++ ) {
9181					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
9182				}
9183
9184				return map;
9185			}
9186
9187			return value !== undefined ?
9188				jQuery.style( elem, name, value ) :
9189				jQuery.css( elem, name );
9190		}, name, value, arguments.length > 1 );
9191	}
9192} );
9193
9194
9195function Tween( elem, options, prop, end, easing ) {
9196	return new Tween.prototype.init( elem, options, prop, end, easing );
9197}
9198jQuery.Tween = Tween;
9199
9200Tween.prototype = {
9201	constructor: Tween,
9202	init: function( elem, options, prop, end, easing, unit ) {
9203		this.elem = elem;
9204		this.prop = prop;
9205		this.easing = easing || jQuery.easing._default;
9206		this.options = options;
9207		this.start = this.now = this.cur();
9208		this.end = end;
9209		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
9210	},
9211	cur: function() {
9212		var hooks = Tween.propHooks[ this.prop ];
9213
9214		return hooks && hooks.get ?
9215			hooks.get( this ) :
9216			Tween.propHooks._default.get( this );
9217	},
9218	run: function( percent ) {
9219		var eased,
9220			hooks = Tween.propHooks[ this.prop ];
9221
9222		if ( this.options.duration ) {
9223			this.pos = eased = jQuery.easing[ this.easing ](
9224				percent, this.options.duration * percent, 0, 1, this.options.duration
9225			);
9226		} else {
9227			this.pos = eased = percent;
9228		}
9229		this.now = ( this.end - this.start ) * eased + this.start;
9230
9231		if ( this.options.step ) {
9232			this.options.step.call( this.elem, this.now, this );
9233		}
9234
9235		if ( hooks && hooks.set ) {
9236			hooks.set( this );
9237		} else {
9238			Tween.propHooks._default.set( this );
9239		}
9240		return this;
9241	}
9242};
9243
9244Tween.prototype.init.prototype = Tween.prototype;
9245
9246Tween.propHooks = {
9247	_default: {
9248		get: function( tween ) {
9249			var result;
9250
9251			// Use a property on the element directly when it is not a DOM element,
9252			// or when there is no matching style property that exists.
9253			if ( tween.elem.nodeType !== 1 ||
9254				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
9255				return tween.elem[ tween.prop ];
9256			}
9257
9258			// Passing an empty string as a 3rd parameter to .css will automatically
9259			// attempt a parseFloat and fallback to a string if the parse fails.
9260			// Simple values such as "10px" are parsed to Float;
9261			// complex values such as "rotate(1rad)" are returned as-is.
9262			result = jQuery.css( tween.elem, tween.prop, "" );
9263
9264			// Empty strings, null, undefined and "auto" are converted to 0.
9265			return !result || result === "auto" ? 0 : result;
9266		},
9267		set: function( tween ) {
9268
9269			// Use step hook for back compat.
9270			// Use cssHook if its there.
9271			// Use .style if available and use plain properties where available.
9272			if ( jQuery.fx.step[ tween.prop ] ) {
9273				jQuery.fx.step[ tween.prop ]( tween );
9274			} else if ( tween.elem.nodeType === 1 && (
9275				jQuery.cssHooks[ tween.prop ] ||
9276					tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
9277				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
9278			} else {
9279				tween.elem[ tween.prop ] = tween.now;
9280			}
9281		}
9282	}
9283};
9284
9285// Support: IE <=9 only
9286// Panic based approach to setting things on disconnected nodes
9287Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
9288	set: function( tween ) {
9289		if ( tween.elem.nodeType && tween.elem.parentNode ) {
9290			tween.elem[ tween.prop ] = tween.now;
9291		}
9292	}
9293};
9294
9295jQuery.easing = {
9296	linear: function( p ) {
9297		return p;
9298	},
9299	swing: function( p ) {
9300		return 0.5 - Math.cos( p * Math.PI ) / 2;
9301	},
9302	_default: "swing"
9303};
9304
9305jQuery.fx = Tween.prototype.init;
9306
9307// Back compat <1.8 extension point
9308jQuery.fx.step = {};
9309
9310
9311
9312
9313var
9314	fxNow, inProgress,
9315	rfxtypes = /^(?:toggle|show|hide)$/,
9316	rrun = /queueHooks$/;
9317
9318function schedule() {
9319	if ( inProgress ) {
9320		if ( document.hidden === false && window.requestAnimationFrame ) {
9321			window.requestAnimationFrame( schedule );
9322		} else {
9323			window.setTimeout( schedule, jQuery.fx.interval );
9324		}
9325
9326		jQuery.fx.tick();
9327	}
9328}
9329
9330// Animations created synchronously will run synchronously
9331function createFxNow() {
9332	window.setTimeout( function() {
9333		fxNow = undefined;
9334	} );
9335	return ( fxNow = Date.now() );
9336}
9337
9338// Generate parameters to create a standard animation
9339function genFx( type, includeWidth ) {
9340	var which,
9341		i = 0,
9342		attrs = { height: type };
9343
9344	// If we include width, step value is 1 to do all cssExpand values,
9345	// otherwise step value is 2 to skip over Left and Right
9346	includeWidth = includeWidth ? 1 : 0;
9347	for ( ; i < 4; i += 2 - includeWidth ) {
9348		which = cssExpand[ i ];
9349		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
9350	}
9351
9352	if ( includeWidth ) {
9353		attrs.opacity = attrs.width = type;
9354	}
9355
9356	return attrs;
9357}
9358
9359function createTween( value, prop, animation ) {
9360	var tween,
9361		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
9362		index = 0,
9363		length = collection.length;
9364	for ( ; index < length; index++ ) {
9365		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
9366
9367			// We're done with this property
9368			return tween;
9369		}
9370	}
9371}
9372
9373function defaultPrefilter( elem, props, opts ) {
9374	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
9375		isBox = "width" in props || "height" in props,
9376		anim = this,
9377		orig = {},
9378		style = elem.style,
9379		hidden = elem.nodeType && isHiddenWithinTree( elem ),
9380		dataShow = dataPriv.get( elem, "fxshow" );
9381
9382	// Queue-skipping animations hijack the fx hooks
9383	if ( !opts.queue ) {
9384		hooks = jQuery._queueHooks( elem, "fx" );
9385		if ( hooks.unqueued == null ) {
9386			hooks.unqueued = 0;
9387			oldfire = hooks.empty.fire;
9388			hooks.empty.fire = function() {
9389				if ( !hooks.unqueued ) {
9390					oldfire();
9391				}
9392			};
9393		}
9394		hooks.unqueued++;
9395
9396		anim.always( function() {
9397
9398			// Ensure the complete handler is called before this completes
9399			anim.always( function() {
9400				hooks.unqueued--;
9401				if ( !jQuery.queue( elem, "fx" ).length ) {
9402					hooks.empty.fire();
9403				}
9404			} );
9405		} );
9406	}
9407
9408	// Detect show/hide animations
9409	for ( prop in props ) {
9410		value = props[ prop ];
9411		if ( rfxtypes.test( value ) ) {
9412			delete props[ prop ];
9413			toggle = toggle || value === "toggle";
9414			if ( value === ( hidden ? "hide" : "show" ) ) {
9415
9416				// Pretend to be hidden if this is a "show" and
9417				// there is still data from a stopped show/hide
9418				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
9419					hidden = true;
9420
9421				// Ignore all other no-op show/hide data
9422				} else {
9423					continue;
9424				}
9425			}
9426			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
9427		}
9428	}
9429
9430	// Bail out if this is a no-op like .hide().hide()
9431	propTween = !jQuery.isEmptyObject( props );
9432	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
9433		return;
9434	}
9435
9436	// Restrict "overflow" and "display" styles during box animations
9437	if ( isBox && elem.nodeType === 1 ) {
9438
9439		// Support: IE <=9 - 11, Edge 12 - 15
9440		// Record all 3 overflow attributes because IE does not infer the shorthand
9441		// from identically-valued overflowX and overflowY and Edge just mirrors
9442		// the overflowX value there.
9443		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
9444
9445		// Identify a display type, preferring old show/hide data over the CSS cascade
9446		restoreDisplay = dataShow && dataShow.display;
9447		if ( restoreDisplay == null ) {
9448			restoreDisplay = dataPriv.get( elem, "display" );
9449		}
9450		display = jQuery.css( elem, "display" );
9451		if ( display === "none" ) {
9452			if ( restoreDisplay ) {
9453				display = restoreDisplay;
9454			} else {
9455
9456				// Get nonempty value(s) by temporarily forcing visibility
9457				showHide( [ elem ], true );
9458				restoreDisplay = elem.style.display || restoreDisplay;
9459				display = jQuery.css( elem, "display" );
9460				showHide( [ elem ] );
9461			}
9462		}
9463
9464		// Animate inline elements as inline-block
9465		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
9466			if ( jQuery.css( elem, "float" ) === "none" ) {
9467
9468				// Restore the original display value at the end of pure show/hide animations
9469				if ( !propTween ) {
9470					anim.done( function() {
9471						style.display = restoreDisplay;
9472					} );
9473					if ( restoreDisplay == null ) {
9474						display = style.display;
9475						restoreDisplay = display === "none" ? "" : display;
9476					}
9477				}
9478				style.display = "inline-block";
9479			}
9480		}
9481	}
9482
9483	if ( opts.overflow ) {
9484		style.overflow = "hidden";
9485		anim.always( function() {
9486			style.overflow = opts.overflow[ 0 ];
9487			style.overflowX = opts.overflow[ 1 ];
9488			style.overflowY = opts.overflow[ 2 ];
9489		} );
9490	}
9491
9492	// Implement show/hide animations
9493	propTween = false;
9494	for ( prop in orig ) {
9495
9496		// General show/hide setup for this element animation
9497		if ( !propTween ) {
9498			if ( dataShow ) {
9499				if ( "hidden" in dataShow ) {
9500					hidden = dataShow.hidden;
9501				}
9502			} else {
9503				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
9504			}
9505
9506			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
9507			if ( toggle ) {
9508				dataShow.hidden = !hidden;
9509			}
9510
9511			// Show elements before animating them
9512			if ( hidden ) {
9513				showHide( [ elem ], true );
9514			}
9515
9516			/* eslint-disable no-loop-func */
9517
9518			anim.done( function() {
9519
9520				/* eslint-enable no-loop-func */
9521
9522				// The final step of a "hide" animation is actually hiding the element
9523				if ( !hidden ) {
9524					showHide( [ elem ] );
9525				}
9526				dataPriv.remove( elem, "fxshow" );
9527				for ( prop in orig ) {
9528					jQuery.style( elem, prop, orig[ prop ] );
9529				}
9530			} );
9531		}
9532
9533		// Per-property setup
9534		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
9535		if ( !( prop in dataShow ) ) {
9536			dataShow[ prop ] = propTween.start;
9537			if ( hidden ) {
9538				propTween.end = propTween.start;
9539				propTween.start = 0;
9540			}
9541		}
9542	}
9543}
9544
9545function propFilter( props, specialEasing ) {
9546	var index, name, easing, value, hooks;
9547
9548	// camelCase, specialEasing and expand cssHook pass
9549	for ( index in props ) {
9550		name = camelCase( index );
9551		easing = specialEasing[ name ];
9552		value = props[ index ];
9553		if ( Array.isArray( value ) ) {
9554			easing = value[ 1 ];
9555			value = props[ index ] = value[ 0 ];
9556		}
9557
9558		if ( index !== name ) {
9559			props[ name ] = value;
9560			delete props[ index ];
9561		}
9562
9563		hooks = jQuery.cssHooks[ name ];
9564		if ( hooks && "expand" in hooks ) {
9565			value = hooks.expand( value );
9566			delete props[ name ];
9567
9568			// Not quite $.extend, this won't overwrite existing keys.
9569			// Reusing 'index' because we have the correct "name"
9570			for ( index in value ) {
9571				if ( !( index in props ) ) {
9572					props[ index ] = value[ index ];
9573					specialEasing[ index ] = easing;
9574				}
9575			}
9576		} else {
9577			specialEasing[ name ] = easing;
9578		}
9579	}
9580}
9581
9582function Animation( elem, properties, options ) {
9583	var result,
9584		stopped,
9585		index = 0,
9586		length = Animation.prefilters.length,
9587		deferred = jQuery.Deferred().always( function() {
9588
9589			// Don't match elem in the :animated selector
9590			delete tick.elem;
9591		} ),
9592		tick = function() {
9593			if ( stopped ) {
9594				return false;
9595			}
9596			var currentTime = fxNow || createFxNow(),
9597				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
9598
9599				// Support: Android 2.3 only
9600				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
9601				temp = remaining / animation.duration || 0,
9602				percent = 1 - temp,
9603				index = 0,
9604				length = animation.tweens.length;
9605
9606			for ( ; index < length; index++ ) {
9607				animation.tweens[ index ].run( percent );
9608			}
9609
9610			deferred.notifyWith( elem, [ animation, percent, remaining ] );
9611
9612			// If there's more to do, yield
9613			if ( percent < 1 && length ) {
9614				return remaining;
9615			}
9616
9617			// If this was an empty animation, synthesize a final progress notification
9618			if ( !length ) {
9619				deferred.notifyWith( elem, [ animation, 1, 0 ] );
9620			}
9621
9622			// Resolve the animation and report its conclusion
9623			deferred.resolveWith( elem, [ animation ] );
9624			return false;
9625		},
9626		animation = deferred.promise( {
9627			elem: elem,
9628			props: jQuery.extend( {}, properties ),
9629			opts: jQuery.extend( true, {
9630				specialEasing: {},
9631				easing: jQuery.easing._default
9632			}, options ),
9633			originalProperties: properties,
9634			originalOptions: options,
9635			startTime: fxNow || createFxNow(),
9636			duration: options.duration,
9637			tweens: [],
9638			createTween: function( prop, end ) {
9639				var tween = jQuery.Tween( elem, animation.opts, prop, end,
9640					animation.opts.specialEasing[ prop ] || animation.opts.easing );
9641				animation.tweens.push( tween );
9642				return tween;
9643			},
9644			stop: function( gotoEnd ) {
9645				var index = 0,
9646
9647					// If we are going to the end, we want to run all the tweens
9648					// otherwise we skip this part
9649					length = gotoEnd ? animation.tweens.length : 0;
9650				if ( stopped ) {
9651					return this;
9652				}
9653				stopped = true;
9654				for ( ; index < length; index++ ) {
9655					animation.tweens[ index ].run( 1 );
9656				}
9657
9658				// Resolve when we played the last frame; otherwise, reject
9659				if ( gotoEnd ) {
9660					deferred.notifyWith( elem, [ animation, 1, 0 ] );
9661					deferred.resolveWith( elem, [ animation, gotoEnd ] );
9662				} else {
9663					deferred.rejectWith( elem, [ animation, gotoEnd ] );
9664				}
9665				return this;
9666			}
9667		} ),
9668		props = animation.props;
9669
9670	propFilter( props, animation.opts.specialEasing );
9671
9672	for ( ; index < length; index++ ) {
9673		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
9674		if ( result ) {
9675			if ( isFunction( result.stop ) ) {
9676				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
9677					result.stop.bind( result );
9678			}
9679			return result;
9680		}
9681	}
9682
9683	jQuery.map( props, createTween, animation );
9684
9685	if ( isFunction( animation.opts.start ) ) {
9686		animation.opts.start.call( elem, animation );
9687	}
9688
9689	// Attach callbacks from options
9690	animation
9691		.progress( animation.opts.progress )
9692		.done( animation.opts.done, animation.opts.complete )
9693		.fail( animation.opts.fail )
9694		.always( animation.opts.always );
9695
9696	jQuery.fx.timer(
9697		jQuery.extend( tick, {
9698			elem: elem,
9699			anim: animation,
9700			queue: animation.opts.queue
9701		} )
9702	);
9703
9704	return animation;
9705}
9706
9707jQuery.Animation = jQuery.extend( Animation, {
9708
9709	tweeners: {
9710		"*": [ function( prop, value ) {
9711			var tween = this.createTween( prop, value );
9712			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
9713			return tween;
9714		} ]
9715	},
9716
9717	tweener: function( props, callback ) {
9718		if ( isFunction( props ) ) {
9719			callback = props;
9720			props = [ "*" ];
9721		} else {
9722			props = props.match( rnothtmlwhite );
9723		}
9724
9725		var prop,
9726			index = 0,
9727			length = props.length;
9728
9729		for ( ; index < length; index++ ) {
9730			prop = props[ index ];
9731			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
9732			Animation.tweeners[ prop ].unshift( callback );
9733		}
9734	},
9735
9736	prefilters: [ defaultPrefilter ],
9737
9738	prefilter: function( callback, prepend ) {
9739		if ( prepend ) {
9740			Animation.prefilters.unshift( callback );
9741		} else {
9742			Animation.prefilters.push( callback );
9743		}
9744	}
9745} );
9746
9747jQuery.speed = function( speed, easing, fn ) {
9748	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
9749		complete: fn || !fn && easing ||
9750			isFunction( speed ) && speed,
9751		duration: speed,
9752		easing: fn && easing || easing && !isFunction( easing ) && easing
9753	};
9754
9755	// Go to the end state if fx are off
9756	if ( jQuery.fx.off ) {
9757		opt.duration = 0;
9758
9759	} else {
9760		if ( typeof opt.duration !== "number" ) {
9761			if ( opt.duration in jQuery.fx.speeds ) {
9762				opt.duration = jQuery.fx.speeds[ opt.duration ];
9763
9764			} else {
9765				opt.duration = jQuery.fx.speeds._default;
9766			}
9767		}
9768	}
9769
9770	// Normalize opt.queue - true/undefined/null -> "fx"
9771	if ( opt.queue == null || opt.queue === true ) {
9772		opt.queue = "fx";
9773	}
9774
9775	// Queueing
9776	opt.old = opt.complete;
9777
9778	opt.complete = function() {
9779		if ( isFunction( opt.old ) ) {
9780			opt.old.call( this );
9781		}
9782
9783		if ( opt.queue ) {
9784			jQuery.dequeue( this, opt.queue );
9785		}
9786	};
9787
9788	return opt;
9789};
9790
9791jQuery.fn.extend( {
9792	fadeTo: function( speed, to, easing, callback ) {
9793
9794		// Show any hidden elements after setting opacity to 0
9795		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
9796
9797			// Animate to the value specified
9798			.end().animate( { opacity: to }, speed, easing, callback );
9799	},
9800	animate: function( prop, speed, easing, callback ) {
9801		var empty = jQuery.isEmptyObject( prop ),
9802			optall = jQuery.speed( speed, easing, callback ),
9803			doAnimation = function() {
9804
9805				// Operate on a copy of prop so per-property easing won't be lost
9806				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
9807
9808				// Empty animations, or finishing resolves immediately
9809				if ( empty || dataPriv.get( this, "finish" ) ) {
9810					anim.stop( true );
9811				}
9812			};
9813
9814		doAnimation.finish = doAnimation;
9815
9816		return empty || optall.queue === false ?
9817			this.each( doAnimation ) :
9818			this.queue( optall.queue, doAnimation );
9819	},
9820	stop: function( type, clearQueue, gotoEnd ) {
9821		var stopQueue = function( hooks ) {
9822			var stop = hooks.stop;
9823			delete hooks.stop;
9824			stop( gotoEnd );
9825		};
9826
9827		if ( typeof type !== "string" ) {
9828			gotoEnd = clearQueue;
9829			clearQueue = type;
9830			type = undefined;
9831		}
9832		if ( clearQueue ) {
9833			this.queue( type || "fx", [] );
9834		}
9835
9836		return this.each( function() {
9837			var dequeue = true,
9838				index = type != null && type + "queueHooks",
9839				timers = jQuery.timers,
9840				data = dataPriv.get( this );
9841
9842			if ( index ) {
9843				if ( data[ index ] && data[ index ].stop ) {
9844					stopQueue( data[ index ] );
9845				}
9846			} else {
9847				for ( index in data ) {
9848					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
9849						stopQueue( data[ index ] );
9850					}
9851				}
9852			}
9853
9854			for ( index = timers.length; index--; ) {
9855				if ( timers[ index ].elem === this &&
9856					( type == null || timers[ index ].queue === type ) ) {
9857
9858					timers[ index ].anim.stop( gotoEnd );
9859					dequeue = false;
9860					timers.splice( index, 1 );
9861				}
9862			}
9863
9864			// Start the next in the queue if the last step wasn't forced.
9865			// Timers currently will call their complete callbacks, which
9866			// will dequeue but only if they were gotoEnd.
9867			if ( dequeue || !gotoEnd ) {
9868				jQuery.dequeue( this, type );
9869			}
9870		} );
9871	},
9872	finish: function( type ) {
9873		if ( type !== false ) {
9874			type = type || "fx";
9875		}
9876		return this.each( function() {
9877			var index,
9878				data = dataPriv.get( this ),
9879				queue = data[ type + "queue" ],
9880				hooks = data[ type + "queueHooks" ],
9881				timers = jQuery.timers,
9882				length = queue ? queue.length : 0;
9883
9884			// Enable finishing flag on private data
9885			data.finish = true;
9886
9887			// Empty the queue first
9888			jQuery.queue( this, type, [] );
9889
9890			if ( hooks && hooks.stop ) {
9891				hooks.stop.call( this, true );
9892			}
9893
9894			// Look for any active animations, and finish them
9895			for ( index = timers.length; index--; ) {
9896				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
9897					timers[ index ].anim.stop( true );
9898					timers.splice( index, 1 );
9899				}
9900			}
9901
9902			// Look for any animations in the old queue and finish them
9903			for ( index = 0; index < length; index++ ) {
9904				if ( queue[ index ] && queue[ index ].finish ) {
9905					queue[ index ].finish.call( this );
9906				}
9907			}
9908
9909			// Turn off finishing flag
9910			delete data.finish;
9911		} );
9912	}
9913} );
9914
9915jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
9916	var cssFn = jQuery.fn[ name ];
9917	jQuery.fn[ name ] = function( speed, easing, callback ) {
9918		return speed == null || typeof speed === "boolean" ?
9919			cssFn.apply( this, arguments ) :
9920			this.animate( genFx( name, true ), speed, easing, callback );
9921	};
9922} );
9923
9924// Generate shortcuts for custom animations
9925jQuery.each( {
9926	slideDown: genFx( "show" ),
9927	slideUp: genFx( "hide" ),
9928	slideToggle: genFx( "toggle" ),
9929	fadeIn: { opacity: "show" },
9930	fadeOut: { opacity: "hide" },
9931	fadeToggle: { opacity: "toggle" }
9932}, function( name, props ) {
9933	jQuery.fn[ name ] = function( speed, easing, callback ) {
9934		return this.animate( props, speed, easing, callback );
9935	};
9936} );
9937
9938jQuery.timers = [];
9939jQuery.fx.tick = function() {
9940	var timer,
9941		i = 0,
9942		timers = jQuery.timers;
9943
9944	fxNow = Date.now();
9945
9946	for ( ; i < timers.length; i++ ) {
9947		timer = timers[ i ];
9948
9949		// Run the timer and safely remove it when done (allowing for external removal)
9950		if ( !timer() && timers[ i ] === timer ) {
9951			timers.splice( i--, 1 );
9952		}
9953	}
9954
9955	if ( !timers.length ) {
9956		jQuery.fx.stop();
9957	}
9958	fxNow = undefined;
9959};
9960
9961jQuery.fx.timer = function( timer ) {
9962	jQuery.timers.push( timer );
9963	jQuery.fx.start();
9964};
9965
9966jQuery.fx.interval = 13;
9967jQuery.fx.start = function() {
9968	if ( inProgress ) {
9969		return;
9970	}
9971
9972	inProgress = true;
9973	schedule();
9974};
9975
9976jQuery.fx.stop = function() {
9977	inProgress = null;
9978};
9979
9980jQuery.fx.speeds = {
9981	slow: 600,
9982	fast: 200,
9983
9984	// Default speed
9985	_default: 400
9986};
9987
9988
9989// Based off of the plugin by Clint Helfers, with permission.
9990jQuery.fn.delay = function( time, type ) {
9991	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
9992	type = type || "fx";
9993
9994	return this.queue( type, function( next, hooks ) {
9995		var timeout = window.setTimeout( next, time );
9996		hooks.stop = function() {
9997			window.clearTimeout( timeout );
9998		};
9999	} );
10000};
10001
10002
10003( function() {
10004	var input = document.createElement( "input" ),
10005		select = document.createElement( "select" ),
10006		opt = select.appendChild( document.createElement( "option" ) );
10007
10008	input.type = "checkbox";
10009
10010	// Support: Android <=4.3 only
10011	// Default value for a checkbox should be "on"
10012	support.checkOn = input.value !== "";
10013
10014	// Support: IE <=11 only
10015	// Must access selectedIndex to make default options select
10016	support.optSelected = opt.selected;
10017
10018	// Support: IE <=11 only
10019	// An input loses its value after becoming a radio
10020	input = document.createElement( "input" );
10021	input.value = "t";
10022	input.type = "radio";
10023	support.radioValue = input.value === "t";
10024} )();
10025
10026
10027var boolHook,
10028	attrHandle = jQuery.expr.attrHandle;
10029
10030jQuery.fn.extend( {
10031	attr: function( name, value ) {
10032		return access( this, jQuery.attr, name, value, arguments.length > 1 );
10033	},
10034
10035	removeAttr: function( name ) {
10036		return this.each( function() {
10037			jQuery.removeAttr( this, name );
10038		} );
10039	}
10040} );
10041
10042jQuery.extend( {
10043	attr: function( elem, name, value ) {
10044		var ret, hooks,
10045			nType = elem.nodeType;
10046
10047		// Don't get/set attributes on text, comment and attribute nodes
10048		if ( nType === 3 || nType === 8 || nType === 2 ) {
10049			return;
10050		}
10051
10052		// Fallback to prop when attributes are not supported
10053		if ( typeof elem.getAttribute === "undefined" ) {
10054			return jQuery.prop( elem, name, value );
10055		}
10056
10057		// Attribute hooks are determined by the lowercase version
10058		// Grab necessary hook if one is defined
10059		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
10060			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
10061				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
10062		}
10063
10064		if ( value !== undefined ) {
10065			if ( value === null ) {
10066				jQuery.removeAttr( elem, name );
10067				return;
10068			}
10069
10070			if ( hooks && "set" in hooks &&
10071				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
10072				return ret;
10073			}
10074
10075			elem.setAttribute( name, value + "" );
10076			return value;
10077		}
10078
10079		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
10080			return ret;
10081		}
10082
10083		ret = jQuery.find.attr( elem, name );
10084
10085		// Non-existent attributes return null, we normalize to undefined
10086		return ret == null ? undefined : ret;
10087	},
10088
10089	attrHooks: {
10090		type: {
10091			set: function( elem, value ) {
10092				if ( !support.radioValue && value === "radio" &&
10093					nodeName( elem, "input" ) ) {
10094					var val = elem.value;
10095					elem.setAttribute( "type", value );
10096					if ( val ) {
10097						elem.value = val;
10098					}
10099					return value;
10100				}
10101			}
10102		}
10103	},
10104
10105	removeAttr: function( elem, value ) {
10106		var name,
10107			i = 0,
10108
10109			// Attribute names can contain non-HTML whitespace characters
10110			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
10111			attrNames = value && value.match( rnothtmlwhite );
10112
10113		if ( attrNames && elem.nodeType === 1 ) {
10114			while ( ( name = attrNames[ i++ ] ) ) {
10115				elem.removeAttribute( name );
10116			}
10117		}
10118	}
10119} );
10120
10121// Hooks for boolean attributes
10122boolHook = {
10123	set: function( elem, value, name ) {
10124		if ( value === false ) {
10125
10126			// Remove boolean attributes when set to false
10127			jQuery.removeAttr( elem, name );
10128		} else {
10129			elem.setAttribute( name, name );
10130		}
10131		return name;
10132	}
10133};
10134
10135jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
10136	var getter = attrHandle[ name ] || jQuery.find.attr;
10137
10138	attrHandle[ name ] = function( elem, name, isXML ) {
10139		var ret, handle,
10140			lowercaseName = name.toLowerCase();
10141
10142		if ( !isXML ) {
10143
10144			// Avoid an infinite loop by temporarily removing this function from the getter
10145			handle = attrHandle[ lowercaseName ];
10146			attrHandle[ lowercaseName ] = ret;
10147			ret = getter( elem, name, isXML ) != null ?
10148				lowercaseName :
10149				null;
10150			attrHandle[ lowercaseName ] = handle;
10151		}
10152		return ret;
10153	};
10154} );
10155
10156
10157
10158
10159var rfocusable = /^(?:input|select|textarea|button)$/i,
10160	rclickable = /^(?:a|area)$/i;
10161
10162jQuery.fn.extend( {
10163	prop: function( name, value ) {
10164		return access( this, jQuery.prop, name, value, arguments.length > 1 );
10165	},
10166
10167	removeProp: function( name ) {
10168		return this.each( function() {
10169			delete this[ jQuery.propFix[ name ] || name ];
10170		} );
10171	}
10172} );
10173
10174jQuery.extend( {
10175	prop: function( elem, name, value ) {
10176		var ret, hooks,
10177			nType = elem.nodeType;
10178
10179		// Don't get/set properties on text, comment and attribute nodes
10180		if ( nType === 3 || nType === 8 || nType === 2 ) {
10181			return;
10182		}
10183
10184		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
10185
10186			// Fix name and attach hooks
10187			name = jQuery.propFix[ name ] || name;
10188			hooks = jQuery.propHooks[ name ];
10189		}
10190
10191		if ( value !== undefined ) {
10192			if ( hooks && "set" in hooks &&
10193				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
10194				return ret;
10195			}
10196
10197			return ( elem[ name ] = value );
10198		}
10199
10200		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
10201			return ret;
10202		}
10203
10204		return elem[ name ];
10205	},
10206
10207	propHooks: {
10208		tabIndex: {
10209			get: function( elem ) {
10210
10211				// Support: IE <=9 - 11 only
10212				// elem.tabIndex doesn't always return the
10213				// correct value when it hasn't been explicitly set
10214				// Use proper attribute retrieval (trac-12072)
10215				var tabindex = jQuery.find.attr( elem, "tabindex" );
10216
10217				if ( tabindex ) {
10218					return parseInt( tabindex, 10 );
10219				}
10220
10221				if (
10222					rfocusable.test( elem.nodeName ) ||
10223					rclickable.test( elem.nodeName ) &&
10224					elem.href
10225				) {
10226					return 0;
10227				}
10228
10229				return -1;
10230			}
10231		}
10232	},
10233
10234	propFix: {
10235		"for": "htmlFor",
10236		"class": "className"
10237	}
10238} );
10239
10240// Support: IE <=11 only
10241// Accessing the selectedIndex property
10242// forces the browser to respect setting selected
10243// on the option
10244// The getter ensures a default option is selected
10245// when in an optgroup
10246// eslint rule "no-unused-expressions" is disabled for this code
10247// since it considers such accessions noop
10248if ( !support.optSelected ) {
10249	jQuery.propHooks.selected = {
10250		get: function( elem ) {
10251
10252			/* eslint no-unused-expressions: "off" */
10253
10254			var parent = elem.parentNode;
10255			if ( parent && parent.parentNode ) {
10256				parent.parentNode.selectedIndex;
10257			}
10258			return null;
10259		},
10260		set: function( elem ) {
10261
10262			/* eslint no-unused-expressions: "off" */
10263
10264			var parent = elem.parentNode;
10265			if ( parent ) {
10266				parent.selectedIndex;
10267
10268				if ( parent.parentNode ) {
10269					parent.parentNode.selectedIndex;
10270				}
10271			}
10272		}
10273	};
10274}
10275
10276jQuery.each( [
10277	"tabIndex",
10278	"readOnly",
10279	"maxLength",
10280	"cellSpacing",
10281	"cellPadding",
10282	"rowSpan",
10283	"colSpan",
10284	"useMap",
10285	"frameBorder",
10286	"contentEditable"
10287], function() {
10288	jQuery.propFix[ this.toLowerCase() ] = this;
10289} );
10290
10291
10292
10293
10294	// Strip and collapse whitespace according to HTML spec
10295	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
10296	function stripAndCollapse( value ) {
10297		var tokens = value.match( rnothtmlwhite ) || [];
10298		return tokens.join( " " );
10299	}
10300
10301
10302function getClass( elem ) {
10303	return elem.getAttribute && elem.getAttribute( "class" ) || "";
10304}
10305
10306function classesToArray( value ) {
10307	if ( Array.isArray( value ) ) {
10308		return value;
10309	}
10310	if ( typeof value === "string" ) {
10311		return value.match( rnothtmlwhite ) || [];
10312	}
10313	return [];
10314}
10315
10316jQuery.fn.extend( {
10317	addClass: function( value ) {
10318		var classNames, cur, curValue, className, i, finalValue;
10319
10320		if ( isFunction( value ) ) {
10321			return this.each( function( j ) {
10322				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
10323			} );
10324		}
10325
10326		classNames = classesToArray( value );
10327
10328		if ( classNames.length ) {
10329			return this.each( function() {
10330				curValue = getClass( this );
10331				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
10332
10333				if ( cur ) {
10334					for ( i = 0; i < classNames.length; i++ ) {
10335						className = classNames[ i ];
10336						if ( cur.indexOf( " " + className + " " ) < 0 ) {
10337							cur += className + " ";
10338						}
10339					}
10340
10341					// Only assign if different to avoid unneeded rendering.
10342					finalValue = stripAndCollapse( cur );
10343					if ( curValue !== finalValue ) {
10344						this.setAttribute( "class", finalValue );
10345					}
10346				}
10347			} );
10348		}
10349
10350		return this;
10351	},
10352
10353	removeClass: function( value ) {
10354		var classNames, cur, curValue, className, i, finalValue;
10355
10356		if ( isFunction( value ) ) {
10357			return this.each( function( j ) {
10358				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
10359			} );
10360		}
10361
10362		if ( !arguments.length ) {
10363			return this.attr( "class", "" );
10364		}
10365
10366		classNames = classesToArray( value );
10367
10368		if ( classNames.length ) {
10369			return this.each( function() {
10370				curValue = getClass( this );
10371
10372				// This expression is here for better compressibility (see addClass)
10373				cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
10374
10375				if ( cur ) {
10376					for ( i = 0; i < classNames.length; i++ ) {
10377						className = classNames[ i ];
10378
10379						// Remove *all* instances
10380						while ( cur.indexOf( " " + className + " " ) > -1 ) {
10381							cur = cur.replace( " " + className + " ", " " );
10382						}
10383					}
10384
10385					// Only assign if different to avoid unneeded rendering.
10386					finalValue = stripAndCollapse( cur );
10387					if ( curValue !== finalValue ) {
10388						this.setAttribute( "class", finalValue );
10389					}
10390				}
10391			} );
10392		}
10393
10394		return this;
10395	},
10396
10397	toggleClass: function( value, stateVal ) {
10398		var classNames, className, i, self,
10399			type = typeof value,
10400			isValidValue = type === "string" || Array.isArray( value );
10401
10402		if ( isFunction( value ) ) {
10403			return this.each( function( i ) {
10404				jQuery( this ).toggleClass(
10405					value.call( this, i, getClass( this ), stateVal ),
10406					stateVal
10407				);
10408			} );
10409		}
10410
10411		if ( typeof stateVal === "boolean" && isValidValue ) {
10412			return stateVal ? this.addClass( value ) : this.removeClass( value );
10413		}
10414
10415		classNames = classesToArray( value );
10416
10417		return this.each( function() {
10418			if ( isValidValue ) {
10419
10420				// Toggle individual class names
10421				self = jQuery( this );
10422
10423				for ( i = 0; i < classNames.length; i++ ) {
10424					className = classNames[ i ];
10425
10426					// Check each className given, space separated list
10427					if ( self.hasClass( className ) ) {
10428						self.removeClass( className );
10429					} else {
10430						self.addClass( className );
10431					}
10432				}
10433
10434			// Toggle whole class name
10435			} else if ( value === undefined || type === "boolean" ) {
10436				className = getClass( this );
10437				if ( className ) {
10438
10439					// Store className if set
10440					dataPriv.set( this, "__className__", className );
10441				}
10442
10443				// If the element has a class name or if we're passed `false`,
10444				// then remove the whole classname (if there was one, the above saved it).
10445				// Otherwise bring back whatever was previously saved (if anything),
10446				// falling back to the empty string if nothing was stored.
10447				if ( this.setAttribute ) {
10448					this.setAttribute( "class",
10449						className || value === false ?
10450							"" :
10451							dataPriv.get( this, "__className__" ) || ""
10452					);
10453				}
10454			}
10455		} );
10456	},
10457
10458	hasClass: function( selector ) {
10459		var className, elem,
10460			i = 0;
10461
10462		className = " " + selector + " ";
10463		while ( ( elem = this[ i++ ] ) ) {
10464			if ( elem.nodeType === 1 &&
10465				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
10466				return true;
10467			}
10468		}
10469
10470		return false;
10471	}
10472} );
10473
10474
10475
10476
10477var rreturn = /\r/g;
10478
10479jQuery.fn.extend( {
10480	val: function( value ) {
10481		var hooks, ret, valueIsFunction,
10482			elem = this[ 0 ];
10483
10484		if ( !arguments.length ) {
10485			if ( elem ) {
10486				hooks = jQuery.valHooks[ elem.type ] ||
10487					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
10488
10489				if ( hooks &&
10490					"get" in hooks &&
10491					( ret = hooks.get( elem, "value" ) ) !== undefined
10492				) {
10493					return ret;
10494				}
10495
10496				ret = elem.value;
10497
10498				// Handle most common string cases
10499				if ( typeof ret === "string" ) {
10500					return ret.replace( rreturn, "" );
10501				}
10502
10503				// Handle cases where value is null/undef or number
10504				return ret == null ? "" : ret;
10505			}
10506
10507			return;
10508		}
10509
10510		valueIsFunction = isFunction( value );
10511
10512		return this.each( function( i ) {
10513			var val;
10514
10515			if ( this.nodeType !== 1 ) {
10516				return;
10517			}
10518
10519			if ( valueIsFunction ) {
10520				val = value.call( this, i, jQuery( this ).val() );
10521			} else {
10522				val = value;
10523			}
10524
10525			// Treat null/undefined as ""; convert numbers to string
10526			if ( val == null ) {
10527				val = "";
10528
10529			} else if ( typeof val === "number" ) {
10530				val += "";
10531
10532			} else if ( Array.isArray( val ) ) {
10533				val = jQuery.map( val, function( value ) {
10534					return value == null ? "" : value + "";
10535				} );
10536			}
10537
10538			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
10539
10540			// If set returns undefined, fall back to normal setting
10541			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
10542				this.value = val;
10543			}
10544		} );
10545	}
10546} );
10547
10548jQuery.extend( {
10549	valHooks: {
10550		option: {
10551			get: function( elem ) {
10552
10553				var val = jQuery.find.attr( elem, "value" );
10554				return val != null ?
10555					val :
10556
10557					// Support: IE <=10 - 11 only
10558					// option.text throws exceptions (trac-14686, trac-14858)
10559					// Strip and collapse whitespace
10560					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
10561					stripAndCollapse( jQuery.text( elem ) );
10562			}
10563		},
10564		select: {
10565			get: function( elem ) {
10566				var value, option, i,
10567					options = elem.options,
10568					index = elem.selectedIndex,
10569					one = elem.type === "select-one",
10570					values = one ? null : [],
10571					max = one ? index + 1 : options.length;
10572
10573				if ( index < 0 ) {
10574					i = max;
10575
10576				} else {
10577					i = one ? index : 0;
10578				}
10579
10580				// Loop through all the selected options
10581				for ( ; i < max; i++ ) {
10582					option = options[ i ];
10583
10584					// Support: IE <=9 only
10585					// IE8-9 doesn't update selected after form reset (trac-2551)
10586					if ( ( option.selected || i === index ) &&
10587
10588							// Don't return options that are disabled or in a disabled optgroup
10589							!option.disabled &&
10590							( !option.parentNode.disabled ||
10591								!nodeName( option.parentNode, "optgroup" ) ) ) {
10592
10593						// Get the specific value for the option
10594						value = jQuery( option ).val();
10595
10596						// We don't need an array for one selects
10597						if ( one ) {
10598							return value;
10599						}
10600
10601						// Multi-Selects return an array
10602						values.push( value );
10603					}
10604				}
10605
10606				return values;
10607			},
10608
10609			set: function( elem, value ) {
10610				var optionSet, option,
10611					options = elem.options,
10612					values = jQuery.makeArray( value ),
10613					i = options.length;
10614
10615				while ( i-- ) {
10616					option = options[ i ];
10617
10618					/* eslint-disable no-cond-assign */
10619
10620					if ( option.selected =
10621						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
10622					) {
10623						optionSet = true;
10624					}
10625
10626					/* eslint-enable no-cond-assign */
10627				}
10628
10629				// Force browsers to behave consistently when non-matching value is set
10630				if ( !optionSet ) {
10631					elem.selectedIndex = -1;
10632				}
10633				return values;
10634			}
10635		}
10636	}
10637} );
10638
10639// Radios and checkboxes getter/setter
10640jQuery.each( [ "radio", "checkbox" ], function() {
10641	jQuery.valHooks[ this ] = {
10642		set: function( elem, value ) {
10643			if ( Array.isArray( value ) ) {
10644				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
10645			}
10646		}
10647	};
10648	if ( !support.checkOn ) {
10649		jQuery.valHooks[ this ].get = function( elem ) {
10650			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
10651		};
10652	}
10653} );
10654
10655
10656
10657
10658// Return jQuery for attributes-only inclusion
10659var location = window.location;
10660
10661var nonce = { guid: Date.now() };
10662
10663var rquery = ( /\?/ );
10664
10665
10666
10667// Cross-browser xml parsing
10668jQuery.parseXML = function( data ) {
10669	var xml, parserErrorElem;
10670	if ( !data || typeof data !== "string" ) {
10671		return null;
10672	}
10673
10674	// Support: IE 9 - 11 only
10675	// IE throws on parseFromString with invalid input.
10676	try {
10677		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
10678	} catch ( e ) {}
10679
10680	parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ];
10681	if ( !xml || parserErrorElem ) {
10682		jQuery.error( "Invalid XML: " + (
10683			parserErrorElem ?
10684				jQuery.map( parserErrorElem.childNodes, function( el ) {
10685					return el.textContent;
10686				} ).join( "\n" ) :
10687				data
10688		) );
10689	}
10690	return xml;
10691};
10692
10693
10694var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
10695	stopPropagationCallback = function( e ) {
10696		e.stopPropagation();
10697	};
10698
10699jQuery.extend( jQuery.event, {
10700
10701	trigger: function( event, data, elem, onlyHandlers ) {
10702
10703		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
10704			eventPath = [ elem || document ],
10705			type = hasOwn.call( event, "type" ) ? event.type : event,
10706			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
10707
10708		cur = lastElement = tmp = elem = elem || document;
10709
10710		// Don't do events on text and comment nodes
10711		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
10712			return;
10713		}
10714
10715		// focus/blur morphs to focusin/out; ensure we're not firing them right now
10716		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
10717			return;
10718		}
10719
10720		if ( type.indexOf( "." ) > -1 ) {
10721
10722			// Namespaced trigger; create a regexp to match event type in handle()
10723			namespaces = type.split( "." );
10724			type = namespaces.shift();
10725			namespaces.sort();
10726		}
10727		ontype = type.indexOf( ":" ) < 0 && "on" + type;
10728
10729		// Caller can pass in a jQuery.Event object, Object, or just an event type string
10730		event = event[ jQuery.expando ] ?
10731			event :
10732			new jQuery.Event( type, typeof event === "object" && event );
10733
10734		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
10735		event.isTrigger = onlyHandlers ? 2 : 3;
10736		event.namespace = namespaces.join( "." );
10737		event.rnamespace = event.namespace ?
10738			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
10739			null;
10740
10741		// Clean up the event in case it is being reused
10742		event.result = undefined;
10743		if ( !event.target ) {
10744			event.target = elem;
10745		}
10746
10747		// Clone any incoming data and prepend the event, creating the handler arg list
10748		data = data == null ?
10749			[ event ] :
10750			jQuery.makeArray( data, [ event ] );
10751
10752		// Allow special events to draw outside the lines
10753		special = jQuery.event.special[ type ] || {};
10754		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
10755			return;
10756		}
10757
10758		// Determine event propagation path in advance, per W3C events spec (trac-9951)
10759		// Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
10760		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
10761
10762			bubbleType = special.delegateType || type;
10763			if ( !rfocusMorph.test( bubbleType + type ) ) {
10764				cur = cur.parentNode;
10765			}
10766			for ( ; cur; cur = cur.parentNode ) {
10767				eventPath.push( cur );
10768				tmp = cur;
10769			}
10770
10771			// Only add window if we got to document (e.g., not plain obj or detached DOM)
10772			if ( tmp === ( elem.ownerDocument || document ) ) {
10773				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
10774			}
10775		}
10776
10777		// Fire handlers on the event path
10778		i = 0;
10779		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
10780			lastElement = cur;
10781			event.type = i > 1 ?
10782				bubbleType :
10783				special.bindType || type;
10784
10785			// jQuery handler
10786			handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] &&
10787				dataPriv.get( cur, "handle" );
10788			if ( handle ) {
10789				handle.apply( cur, data );
10790			}
10791
10792			// Native handler
10793			handle = ontype && cur[ ontype ];
10794			if ( handle && handle.apply && acceptData( cur ) ) {
10795				event.result = handle.apply( cur, data );
10796				if ( event.result === false ) {
10797					event.preventDefault();
10798				}
10799			}
10800		}
10801		event.type = type;
10802
10803		// If nobody prevented the default action, do it now
10804		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
10805
10806			if ( ( !special._default ||
10807				special._default.apply( eventPath.pop(), data ) === false ) &&
10808				acceptData( elem ) ) {
10809
10810				// Call a native DOM method on the target with the same name as the event.
10811				// Don't do default actions on window, that's where global variables be (trac-6170)
10812				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
10813
10814					// Don't re-trigger an onFOO event when we call its FOO() method
10815					tmp = elem[ ontype ];
10816
10817					if ( tmp ) {
10818						elem[ ontype ] = null;
10819					}
10820
10821					// Prevent re-triggering of the same event, since we already bubbled it above
10822					jQuery.event.triggered = type;
10823
10824					if ( event.isPropagationStopped() ) {
10825						lastElement.addEventListener( type, stopPropagationCallback );
10826					}
10827
10828					elem[ type ]();
10829
10830					if ( event.isPropagationStopped() ) {
10831						lastElement.removeEventListener( type, stopPropagationCallback );
10832					}
10833
10834					jQuery.event.triggered = undefined;
10835
10836					if ( tmp ) {
10837						elem[ ontype ] = tmp;
10838					}
10839				}
10840			}
10841		}
10842
10843		return event.result;
10844	},
10845
10846	// Piggyback on a donor event to simulate a different one
10847	// Used only for `focus(in | out)` events
10848	simulate: function( type, elem, event ) {
10849		var e = jQuery.extend(
10850			new jQuery.Event(),
10851			event,
10852			{
10853				type: type,
10854				isSimulated: true
10855			}
10856		);
10857
10858		jQuery.event.trigger( e, null, elem );
10859	}
10860
10861} );
10862
10863jQuery.fn.extend( {
10864
10865	trigger: function( type, data ) {
10866		return this.each( function() {
10867			jQuery.event.trigger( type, data, this );
10868		} );
10869	},
10870	triggerHandler: function( type, data ) {
10871		var elem = this[ 0 ];
10872		if ( elem ) {
10873			return jQuery.event.trigger( type, data, elem, true );
10874		}
10875	}
10876} );
10877
10878
10879var
10880	rbracket = /\[\]$/,
10881	rCRLF = /\r?\n/g,
10882	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10883	rsubmittable = /^(?:input|select|textarea|keygen)/i;
10884
10885function buildParams( prefix, obj, traditional, add ) {
10886	var name;
10887
10888	if ( Array.isArray( obj ) ) {
10889
10890		// Serialize array item.
10891		jQuery.each( obj, function( i, v ) {
10892			if ( traditional || rbracket.test( prefix ) ) {
10893
10894				// Treat each array item as a scalar.
10895				add( prefix, v );
10896
10897			} else {
10898
10899				// Item is non-scalar (array or object), encode its numeric index.
10900				buildParams(
10901					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10902					v,
10903					traditional,
10904					add
10905				);
10906			}
10907		} );
10908
10909	} else if ( !traditional && toType( obj ) === "object" ) {
10910
10911		// Serialize object item.
10912		for ( name in obj ) {
10913			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10914		}
10915
10916	} else {
10917
10918		// Serialize scalar item.
10919		add( prefix, obj );
10920	}
10921}
10922
10923// Serialize an array of form elements or a set of
10924// key/values into a query string
10925jQuery.param = function( a, traditional ) {
10926	var prefix,
10927		s = [],
10928		add = function( key, valueOrFunction ) {
10929
10930			// If value is a function, invoke it and use its return value
10931			var value = isFunction( valueOrFunction ) ?
10932				valueOrFunction() :
10933				valueOrFunction;
10934
10935			s[ s.length ] = encodeURIComponent( key ) + "=" +
10936				encodeURIComponent( value == null ? "" : value );
10937		};
10938
10939	if ( a == null ) {
10940		return "";
10941	}
10942
10943	// If an array was passed in, assume that it is an array of form elements.
10944	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10945
10946		// Serialize the form elements
10947		jQuery.each( a, function() {
10948			add( this.name, this.value );
10949		} );
10950
10951	} else {
10952
10953		// If traditional, encode the "old" way (the way 1.3.2 or older
10954		// did it), otherwise encode params recursively.
10955		for ( prefix in a ) {
10956			buildParams( prefix, a[ prefix ], traditional, add );
10957		}
10958	}
10959
10960	// Return the resulting serialization
10961	return s.join( "&" );
10962};
10963
10964jQuery.fn.extend( {
10965	serialize: function() {
10966		return jQuery.param( this.serializeArray() );
10967	},
10968	serializeArray: function() {
10969		return this.map( function() {
10970
10971			// Can add propHook for "elements" to filter or add form elements
10972			var elements = jQuery.prop( this, "elements" );
10973			return elements ? jQuery.makeArray( elements ) : this;
10974		} ).filter( function() {
10975			var type = this.type;
10976
10977			// Use .is( ":disabled" ) so that fieldset[disabled] works
10978			return this.name && !jQuery( this ).is( ":disabled" ) &&
10979				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10980				( this.checked || !rcheckableType.test( type ) );
10981		} ).map( function( _i, elem ) {
10982			var val = jQuery( this ).val();
10983
10984			if ( val == null ) {
10985				return null;
10986			}
10987
10988			if ( Array.isArray( val ) ) {
10989				return jQuery.map( val, function( val ) {
10990					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10991				} );
10992			}
10993
10994			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10995		} ).get();
10996	}
10997} );
10998
10999
11000var
11001	r20 = /%20/g,
11002	rhash = /#.*$/,
11003	rantiCache = /([?&])_=[^&]*/,
11004	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
11005
11006	// trac-7653, trac-8125, trac-8152: local protocol detection
11007	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
11008	rnoContent = /^(?:GET|HEAD)$/,
11009	rprotocol = /^\/\//,
11010
11011	/* Prefilters
11012	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
11013	 * 2) These are called:
11014	 *    - BEFORE asking for a transport
11015	 *    - AFTER param serialization (s.data is a string if s.processData is true)
11016	 * 3) key is the dataType
11017	 * 4) the catchall symbol "*" can be used
11018	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
11019	 */
11020	prefilters = {},
11021
11022	/* Transports bindings
11023	 * 1) key is the dataType
11024	 * 2) the catchall symbol "*" can be used
11025	 * 3) selection will start with transport dataType and THEN go to "*" if needed
11026	 */
11027	transports = {},
11028
11029	// Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
11030	allTypes = "*/".concat( "*" ),
11031
11032	// Anchor tag for parsing the document origin
11033	originAnchor = document.createElement( "a" );
11034
11035originAnchor.href = location.href;
11036
11037// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
11038function addToPrefiltersOrTransports( structure ) {
11039
11040	// dataTypeExpression is optional and defaults to "*"
11041	return function( dataTypeExpression, func ) {
11042
11043		if ( typeof dataTypeExpression !== "string" ) {
11044			func = dataTypeExpression;
11045			dataTypeExpression = "*";
11046		}
11047
11048		var dataType,
11049			i = 0,
11050			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
11051
11052		if ( isFunction( func ) ) {
11053
11054			// For each dataType in the dataTypeExpression
11055			while ( ( dataType = dataTypes[ i++ ] ) ) {
11056
11057				// Prepend if requested
11058				if ( dataType[ 0 ] === "+" ) {
11059					dataType = dataType.slice( 1 ) || "*";
11060					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
11061
11062				// Otherwise append
11063				} else {
11064					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
11065				}
11066			}
11067		}
11068	};
11069}
11070
11071// Base inspection function for prefilters and transports
11072function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
11073
11074	var inspected = {},
11075		seekingTransport = ( structure === transports );
11076
11077	function inspect( dataType ) {
11078		var selected;
11079		inspected[ dataType ] = true;
11080		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
11081			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
11082			if ( typeof dataTypeOrTransport === "string" &&
11083				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
11084
11085				options.dataTypes.unshift( dataTypeOrTransport );
11086				inspect( dataTypeOrTransport );
11087				return false;
11088			} else if ( seekingTransport ) {
11089				return !( selected = dataTypeOrTransport );
11090			}
11091		} );
11092		return selected;
11093	}
11094
11095	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
11096}
11097
11098// A special extend for ajax options
11099// that takes "flat" options (not to be deep extended)
11100// Fixes trac-9887
11101function ajaxExtend( target, src ) {
11102	var key, deep,
11103		flatOptions = jQuery.ajaxSettings.flatOptions || {};
11104
11105	for ( key in src ) {
11106		if ( src[ key ] !== undefined ) {
11107			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
11108		}
11109	}
11110	if ( deep ) {
11111		jQuery.extend( true, target, deep );
11112	}
11113
11114	return target;
11115}
11116
11117/* Handles responses to an ajax request:
11118 * - finds the right dataType (mediates between content-type and expected dataType)
11119 * - returns the corresponding response
11120 */
11121function ajaxHandleResponses( s, jqXHR, responses ) {
11122
11123	var ct, type, finalDataType, firstDataType,
11124		contents = s.contents,
11125		dataTypes = s.dataTypes;
11126
11127	// Remove auto dataType and get content-type in the process
11128	while ( dataTypes[ 0 ] === "*" ) {
11129		dataTypes.shift();
11130		if ( ct === undefined ) {
11131			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
11132		}
11133	}
11134
11135	// Check if we're dealing with a known content-type
11136	if ( ct ) {
11137		for ( type in contents ) {
11138			if ( contents[ type ] && contents[ type ].test( ct ) ) {
11139				dataTypes.unshift( type );
11140				break;
11141			}
11142		}
11143	}
11144
11145	// Check to see if we have a response for the expected dataType
11146	if ( dataTypes[ 0 ] in responses ) {
11147		finalDataType = dataTypes[ 0 ];
11148	} else {
11149
11150		// Try convertible dataTypes
11151		for ( type in responses ) {
11152			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
11153				finalDataType = type;
11154				break;
11155			}
11156			if ( !firstDataType ) {
11157				firstDataType = type;
11158			}
11159		}
11160
11161		// Or just use first one
11162		finalDataType = finalDataType || firstDataType;
11163	}
11164
11165	// If we found a dataType
11166	// We add the dataType to the list if needed
11167	// and return the corresponding response
11168	if ( finalDataType ) {
11169		if ( finalDataType !== dataTypes[ 0 ] ) {
11170			dataTypes.unshift( finalDataType );
11171		}
11172		return responses[ finalDataType ];
11173	}
11174}
11175
11176/* Chain conversions given the request and the original response
11177 * Also sets the responseXXX fields on the jqXHR instance
11178 */
11179function ajaxConvert( s, response, jqXHR, isSuccess ) {
11180	var conv2, current, conv, tmp, prev,
11181		converters = {},
11182
11183		// Work with a copy of dataTypes in case we need to modify it for conversion
11184		dataTypes = s.dataTypes.slice();
11185
11186	// Create converters map with lowercased keys
11187	if ( dataTypes[ 1 ] ) {
11188		for ( conv in s.converters ) {
11189			converters[ conv.toLowerCase() ] = s.converters[ conv ];
11190		}
11191	}
11192
11193	current = dataTypes.shift();
11194
11195	// Convert to each sequential dataType
11196	while ( current ) {
11197
11198		if ( s.responseFields[ current ] ) {
11199			jqXHR[ s.responseFields[ current ] ] = response;
11200		}
11201
11202		// Apply the dataFilter if provided
11203		if ( !prev && isSuccess && s.dataFilter ) {
11204			response = s.dataFilter( response, s.dataType );
11205		}
11206
11207		prev = current;
11208		current = dataTypes.shift();
11209
11210		if ( current ) {
11211
11212			// There's only work to do if current dataType is non-auto
11213			if ( current === "*" ) {
11214
11215				current = prev;
11216
11217			// Convert response if prev dataType is non-auto and differs from current
11218			} else if ( prev !== "*" && prev !== current ) {
11219
11220				// Seek a direct converter
11221				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
11222
11223				// If none found, seek a pair
11224				if ( !conv ) {
11225					for ( conv2 in converters ) {
11226
11227						// If conv2 outputs current
11228						tmp = conv2.split( " " );
11229						if ( tmp[ 1 ] === current ) {
11230
11231							// If prev can be converted to accepted input
11232							conv = converters[ prev + " " + tmp[ 0 ] ] ||
11233								converters[ "* " + tmp[ 0 ] ];
11234							if ( conv ) {
11235
11236								// Condense equivalence converters
11237								if ( conv === true ) {
11238									conv = converters[ conv2 ];
11239
11240								// Otherwise, insert the intermediate dataType
11241								} else if ( converters[ conv2 ] !== true ) {
11242									current = tmp[ 0 ];
11243									dataTypes.unshift( tmp[ 1 ] );
11244								}
11245								break;
11246							}
11247						}
11248					}
11249				}
11250
11251				// Apply converter (if not an equivalence)
11252				if ( conv !== true ) {
11253
11254					// Unless errors are allowed to bubble, catch and return them
11255					if ( conv && s.throws ) {
11256						response = conv( response );
11257					} else {
11258						try {
11259							response = conv( response );
11260						} catch ( e ) {
11261							return {
11262								state: "parsererror",
11263								error: conv ? e : "No conversion from " + prev + " to " + current
11264							};
11265						}
11266					}
11267				}
11268			}
11269		}
11270	}
11271
11272	return { state: "success", data: response };
11273}
11274
11275jQuery.extend( {
11276
11277	// Counter for holding the number of active queries
11278	active: 0,
11279
11280	// Last-Modified header cache for next request
11281	lastModified: {},
11282	etag: {},
11283
11284	ajaxSettings: {
11285		url: location.href,
11286		type: "GET",
11287		isLocal: rlocalProtocol.test( location.protocol ),
11288		global: true,
11289		processData: true,
11290		async: true,
11291		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
11292
11293		/*
11294		timeout: 0,
11295		data: null,
11296		dataType: null,
11297		username: null,
11298		password: null,
11299		cache: null,
11300		throws: false,
11301		traditional: false,
11302		headers: {},
11303		*/
11304
11305		accepts: {
11306			"*": allTypes,
11307			text: "text/plain",
11308			html: "text/html",
11309			xml: "application/xml, text/xml",
11310			json: "application/json, text/javascript"
11311		},
11312
11313		contents: {
11314			xml: /\bxml\b/,
11315			html: /\bhtml/,
11316			json: /\bjson\b/
11317		},
11318
11319		responseFields: {
11320			xml: "responseXML",
11321			text: "responseText",
11322			json: "responseJSON"
11323		},
11324
11325		// Data converters
11326		// Keys separate source (or catchall "*") and destination types with a single space
11327		converters: {
11328
11329			// Convert anything to text
11330			"* text": String,
11331
11332			// Text to html (true = no transformation)
11333			"text html": true,
11334
11335			// Evaluate text as a json expression
11336			"text json": JSON.parse,
11337
11338			// Parse text as xml
11339			"text xml": jQuery.parseXML
11340		},
11341
11342		// For options that shouldn't be deep extended:
11343		// you can add your own custom options here if
11344		// and when you create one that shouldn't be
11345		// deep extended (see ajaxExtend)
11346		flatOptions: {
11347			url: true,
11348			context: true
11349		}
11350	},
11351
11352	// Creates a full fledged settings object into target
11353	// with both ajaxSettings and settings fields.
11354	// If target is omitted, writes into ajaxSettings.
11355	ajaxSetup: function( target, settings ) {
11356		return settings ?
11357
11358			// Building a settings object
11359			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
11360
11361			// Extending ajaxSettings
11362			ajaxExtend( jQuery.ajaxSettings, target );
11363	},
11364
11365	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
11366	ajaxTransport: addToPrefiltersOrTransports( transports ),
11367
11368	// Main method
11369	ajax: function( url, options ) {
11370
11371		// If url is an object, simulate pre-1.5 signature
11372		if ( typeof url === "object" ) {
11373			options = url;
11374			url = undefined;
11375		}
11376
11377		// Force options to be an object
11378		options = options || {};
11379
11380		var transport,
11381
11382			// URL without anti-cache param
11383			cacheURL,
11384
11385			// Response headers
11386			responseHeadersString,
11387			responseHeaders,
11388
11389			// timeout handle
11390			timeoutTimer,
11391
11392			// Url cleanup var
11393			urlAnchor,
11394
11395			// Request state (becomes false upon send and true upon completion)
11396			completed,
11397
11398			// To know if global events are to be dispatched
11399			fireGlobals,
11400
11401			// Loop variable
11402			i,
11403
11404			// uncached part of the url
11405			uncached,
11406
11407			// Create the final options object
11408			s = jQuery.ajaxSetup( {}, options ),
11409
11410			// Callbacks context
11411			callbackContext = s.context || s,
11412
11413			// Context for global events is callbackContext if it is a DOM node or jQuery collection
11414			globalEventContext = s.context &&
11415				( callbackContext.nodeType || callbackContext.jquery ) ?
11416				jQuery( callbackContext ) :
11417				jQuery.event,
11418
11419			// Deferreds
11420			deferred = jQuery.Deferred(),
11421			completeDeferred = jQuery.Callbacks( "once memory" ),
11422
11423			// Status-dependent callbacks
11424			statusCode = s.statusCode || {},
11425
11426			// Headers (they are sent all at once)
11427			requestHeaders = {},
11428			requestHeadersNames = {},
11429
11430			// Default abort message
11431			strAbort = "canceled",
11432
11433			// Fake xhr
11434			jqXHR = {
11435				readyState: 0,
11436
11437				// Builds headers hashtable if needed
11438				getResponseHeader: function( key ) {
11439					var match;
11440					if ( completed ) {
11441						if ( !responseHeaders ) {
11442							responseHeaders = {};
11443							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
11444								responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
11445									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
11446										.concat( match[ 2 ] );
11447							}
11448						}
11449						match = responseHeaders[ key.toLowerCase() + " " ];
11450					}
11451					return match == null ? null : match.join( ", " );
11452				},
11453
11454				// Raw string
11455				getAllResponseHeaders: function() {
11456					return completed ? responseHeadersString : null;
11457				},
11458
11459				// Caches the header
11460				setRequestHeader: function( name, value ) {
11461					if ( completed == null ) {
11462						name = requestHeadersNames[ name.toLowerCase() ] =
11463							requestHeadersNames[ name.toLowerCase() ] || name;
11464						requestHeaders[ name ] = value;
11465					}
11466					return this;
11467				},
11468
11469				// Overrides response content-type header
11470				overrideMimeType: function( type ) {
11471					if ( completed == null ) {
11472						s.mimeType = type;
11473					}
11474					return this;
11475				},
11476
11477				// Status-dependent callbacks
11478				statusCode: function( map ) {
11479					var code;
11480					if ( map ) {
11481						if ( completed ) {
11482
11483							// Execute the appropriate callbacks
11484							jqXHR.always( map[ jqXHR.status ] );
11485						} else {
11486
11487							// Lazy-add the new callbacks in a way that preserves old ones
11488							for ( code in map ) {
11489								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
11490							}
11491						}
11492					}
11493					return this;
11494				},
11495
11496				// Cancel the request
11497				abort: function( statusText ) {
11498					var finalText = statusText || strAbort;
11499					if ( transport ) {
11500						transport.abort( finalText );
11501					}
11502					done( 0, finalText );
11503					return this;
11504				}
11505			};
11506
11507		// Attach deferreds
11508		deferred.promise( jqXHR );
11509
11510		// Add protocol if not provided (prefilters might expect it)
11511		// Handle falsy url in the settings object (trac-10093: consistency with old signature)
11512		// We also use the url parameter if available
11513		s.url = ( ( url || s.url || location.href ) + "" )
11514			.replace( rprotocol, location.protocol + "//" );
11515
11516		// Alias method option to type as per ticket trac-12004
11517		s.type = options.method || options.type || s.method || s.type;
11518
11519		// Extract dataTypes list
11520		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
11521
11522		// A cross-domain request is in order when the origin doesn't match the current origin.
11523		if ( s.crossDomain == null ) {
11524			urlAnchor = document.createElement( "a" );
11525
11526			// Support: IE <=8 - 11, Edge 12 - 15
11527			// IE throws exception on accessing the href property if url is malformed,
11528			// e.g. http://example.com:80x/
11529			try {
11530				urlAnchor.href = s.url;
11531
11532				// Support: IE <=8 - 11 only
11533				// Anchor's host property isn't correctly set when s.url is relative
11534				urlAnchor.href = urlAnchor.href;
11535				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
11536					urlAnchor.protocol + "//" + urlAnchor.host;
11537			} catch ( e ) {
11538
11539				// If there is an error parsing the URL, assume it is crossDomain,
11540				// it can be rejected by the transport if it is invalid
11541				s.crossDomain = true;
11542			}
11543		}
11544
11545		// Convert data if not already a string
11546		if ( s.data && s.processData && typeof s.data !== "string" ) {
11547			s.data = jQuery.param( s.data, s.traditional );
11548		}
11549
11550		// Apply prefilters
11551		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
11552
11553		// If request was aborted inside a prefilter, stop there
11554		if ( completed ) {
11555			return jqXHR;
11556		}
11557
11558		// We can fire global events as of now if asked to
11559		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
11560		fireGlobals = jQuery.event && s.global;
11561
11562		// Watch for a new set of requests
11563		if ( fireGlobals && jQuery.active++ === 0 ) {
11564			jQuery.event.trigger( "ajaxStart" );
11565		}
11566
11567		// Uppercase the type
11568		s.type = s.type.toUpperCase();
11569
11570		// Determine if request has content
11571		s.hasContent = !rnoContent.test( s.type );
11572
11573		// Save the URL in case we're toying with the If-Modified-Since
11574		// and/or If-None-Match header later on
11575		// Remove hash to simplify url manipulation
11576		cacheURL = s.url.replace( rhash, "" );
11577
11578		// More options handling for requests with no content
11579		if ( !s.hasContent ) {
11580
11581			// Remember the hash so we can put it back
11582			uncached = s.url.slice( cacheURL.length );
11583
11584			// If data is available and should be processed, append data to url
11585			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
11586				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
11587
11588				// trac-9682: remove data so that it's not used in an eventual retry
11589				delete s.data;
11590			}
11591
11592			// Add or update anti-cache param if needed
11593			if ( s.cache === false ) {
11594				cacheURL = cacheURL.replace( rantiCache, "$1" );
11595				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
11596					uncached;
11597			}
11598
11599			// Put hash and anti-cache on the URL that will be requested (gh-1732)
11600			s.url = cacheURL + uncached;
11601
11602		// Change '%20' to '+' if this is encoded form body content (gh-2658)
11603		} else if ( s.data && s.processData &&
11604			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
11605			s.data = s.data.replace( r20, "+" );
11606		}
11607
11608		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
11609		if ( s.ifModified ) {
11610			if ( jQuery.lastModified[ cacheURL ] ) {
11611				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
11612			}
11613			if ( jQuery.etag[ cacheURL ] ) {
11614				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
11615			}
11616		}
11617
11618		// Set the correct header, if data is being sent
11619		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
11620			jqXHR.setRequestHeader( "Content-Type", s.contentType );
11621		}
11622
11623		// Set the Accepts header for the server, depending on the dataType
11624		jqXHR.setRequestHeader(
11625			"Accept",
11626			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
11627				s.accepts[ s.dataTypes[ 0 ] ] +
11628					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
11629				s.accepts[ "*" ]
11630		);
11631
11632		// Check for headers option
11633		for ( i in s.headers ) {
11634			jqXHR.setRequestHeader( i, s.headers[ i ] );
11635		}
11636
11637		// Allow custom headers/mimetypes and early abort
11638		if ( s.beforeSend &&
11639			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
11640
11641			// Abort if not done already and return
11642			return jqXHR.abort();
11643		}
11644
11645		// Aborting is no longer a cancellation
11646		strAbort = "abort";
11647
11648		// Install callbacks on deferreds
11649		completeDeferred.add( s.complete );
11650		jqXHR.done( s.success );
11651		jqXHR.fail( s.error );
11652
11653		// Get transport
11654		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
11655
11656		// If no transport, we auto-abort
11657		if ( !transport ) {
11658			done( -1, "No Transport" );
11659		} else {
11660			jqXHR.readyState = 1;
11661
11662			// Send global event
11663			if ( fireGlobals ) {
11664				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
11665			}
11666
11667			// If request was aborted inside ajaxSend, stop there
11668			if ( completed ) {
11669				return jqXHR;
11670			}
11671
11672			// Timeout
11673			if ( s.async && s.timeout > 0 ) {
11674				timeoutTimer = window.setTimeout( function() {
11675					jqXHR.abort( "timeout" );
11676				}, s.timeout );
11677			}
11678
11679			try {
11680				completed = false;
11681				transport.send( requestHeaders, done );
11682			} catch ( e ) {
11683
11684				// Rethrow post-completion exceptions
11685				if ( completed ) {
11686					throw e;
11687				}
11688
11689				// Propagate others as results
11690				done( -1, e );
11691			}
11692		}
11693
11694		// Callback for when everything is done
11695		function done( status, nativeStatusText, responses, headers ) {
11696			var isSuccess, success, error, response, modified,
11697				statusText = nativeStatusText;
11698
11699			// Ignore repeat invocations
11700			if ( completed ) {
11701				return;
11702			}
11703
11704			completed = true;
11705
11706			// Clear timeout if it exists
11707			if ( timeoutTimer ) {
11708				window.clearTimeout( timeoutTimer );
11709			}
11710
11711			// Dereference transport for early garbage collection
11712			// (no matter how long the jqXHR object will be used)
11713			transport = undefined;
11714
11715			// Cache response headers
11716			responseHeadersString = headers || "";
11717
11718			// Set readyState
11719			jqXHR.readyState = status > 0 ? 4 : 0;
11720
11721			// Determine if successful
11722			isSuccess = status >= 200 && status < 300 || status === 304;
11723
11724			// Get response data
11725			if ( responses ) {
11726				response = ajaxHandleResponses( s, jqXHR, responses );
11727			}
11728
11729			// Use a noop converter for missing script but not if jsonp
11730			if ( !isSuccess &&
11731				jQuery.inArray( "script", s.dataTypes ) > -1 &&
11732				jQuery.inArray( "json", s.dataTypes ) < 0 ) {
11733				s.converters[ "text script" ] = function() {};
11734			}
11735
11736			// Convert no matter what (that way responseXXX fields are always set)
11737			response = ajaxConvert( s, response, jqXHR, isSuccess );
11738
11739			// If successful, handle type chaining
11740			if ( isSuccess ) {
11741
11742				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
11743				if ( s.ifModified ) {
11744					modified = jqXHR.getResponseHeader( "Last-Modified" );
11745					if ( modified ) {
11746						jQuery.lastModified[ cacheURL ] = modified;
11747					}
11748					modified = jqXHR.getResponseHeader( "etag" );
11749					if ( modified ) {
11750						jQuery.etag[ cacheURL ] = modified;
11751					}
11752				}
11753
11754				// if no content
11755				if ( status === 204 || s.type === "HEAD" ) {
11756					statusText = "nocontent";
11757
11758				// if not modified
11759				} else if ( status === 304 ) {
11760					statusText = "notmodified";
11761
11762				// If we have data, let's convert it
11763				} else {
11764					statusText = response.state;
11765					success = response.data;
11766					error = response.error;
11767					isSuccess = !error;
11768				}
11769			} else {
11770
11771				// Extract error from statusText and normalize for non-aborts
11772				error = statusText;
11773				if ( status || !statusText ) {
11774					statusText = "error";
11775					if ( status < 0 ) {
11776						status = 0;
11777					}
11778				}
11779			}
11780
11781			// Set data for the fake xhr object
11782			jqXHR.status = status;
11783			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
11784
11785			// Success/Error
11786			if ( isSuccess ) {
11787				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
11788			} else {
11789				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
11790			}
11791
11792			// Status-dependent callbacks
11793			jqXHR.statusCode( statusCode );
11794			statusCode = undefined;
11795
11796			if ( fireGlobals ) {
11797				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
11798					[ jqXHR, s, isSuccess ? success : error ] );
11799			}
11800
11801			// Complete
11802			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
11803
11804			if ( fireGlobals ) {
11805				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
11806
11807				// Handle the global AJAX counter
11808				if ( !( --jQuery.active ) ) {
11809					jQuery.event.trigger( "ajaxStop" );
11810				}
11811			}
11812		}
11813
11814		return jqXHR;
11815	},
11816
11817	getJSON: function( url, data, callback ) {
11818		return jQuery.get( url, data, callback, "json" );
11819	},
11820
11821	getScript: function( url, callback ) {
11822		return jQuery.get( url, undefined, callback, "script" );
11823	}
11824} );
11825
11826jQuery.each( [ "get", "post" ], function( _i, method ) {
11827	jQuery[ method ] = function( url, data, callback, type ) {
11828
11829		// Shift arguments if data argument was omitted
11830		if ( isFunction( data ) ) {
11831			type = type || callback;
11832			callback = data;
11833			data = undefined;
11834		}
11835
11836		// The url can be an options object (which then must have .url)
11837		return jQuery.ajax( jQuery.extend( {
11838			url: url,
11839			type: method,
11840			dataType: type,
11841			data: data,
11842			success: callback
11843		}, jQuery.isPlainObject( url ) && url ) );
11844	};
11845} );
11846
11847jQuery.ajaxPrefilter( function( s ) {
11848	var i;
11849	for ( i in s.headers ) {
11850		if ( i.toLowerCase() === "content-type" ) {
11851			s.contentType = s.headers[ i ] || "";
11852		}
11853	}
11854} );
11855
11856
11857jQuery._evalUrl = function( url, options, doc ) {
11858	return jQuery.ajax( {
11859		url: url,
11860
11861		// Make this explicit, since user can override this through ajaxSetup (trac-11264)
11862		type: "GET",
11863		dataType: "script",
11864		cache: true,
11865		async: false,
11866		global: false,
11867
11868		// Only evaluate the response if it is successful (gh-4126)
11869		// dataFilter is not invoked for failure responses, so using it instead
11870		// of the default converter is kludgy but it works.
11871		converters: {
11872			"text script": function() {}
11873		},
11874		dataFilter: function( response ) {
11875			jQuery.globalEval( response, options, doc );
11876		}
11877	} );
11878};
11879
11880
11881jQuery.fn.extend( {
11882	wrapAll: function( html ) {
11883		var wrap;
11884
11885		if ( this[ 0 ] ) {
11886			if ( isFunction( html ) ) {
11887				html = html.call( this[ 0 ] );
11888			}
11889
11890			// The elements to wrap the target around
11891			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
11892
11893			if ( this[ 0 ].parentNode ) {
11894				wrap.insertBefore( this[ 0 ] );
11895			}
11896
11897			wrap.map( function() {
11898				var elem = this;
11899
11900				while ( elem.firstElementChild ) {
11901					elem = elem.firstElementChild;
11902				}
11903
11904				return elem;
11905			} ).append( this );
11906		}
11907
11908		return this;
11909	},
11910
11911	wrapInner: function( html ) {
11912		if ( isFunction( html ) ) {
11913			return this.each( function( i ) {
11914				jQuery( this ).wrapInner( html.call( this, i ) );
11915			} );
11916		}
11917
11918		return this.each( function() {
11919			var self = jQuery( this ),
11920				contents = self.contents();
11921
11922			if ( contents.length ) {
11923				contents.wrapAll( html );
11924
11925			} else {
11926				self.append( html );
11927			}
11928		} );
11929	},
11930
11931	wrap: function( html ) {
11932		var htmlIsFunction = isFunction( html );
11933
11934		return this.each( function( i ) {
11935			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
11936		} );
11937	},
11938
11939	unwrap: function( selector ) {
11940		this.parent( selector ).not( "body" ).each( function() {
11941			jQuery( this ).replaceWith( this.childNodes );
11942		} );
11943		return this;
11944	}
11945} );
11946
11947
11948jQuery.expr.pseudos.hidden = function( elem ) {
11949	return !jQuery.expr.pseudos.visible( elem );
11950};
11951jQuery.expr.pseudos.visible = function( elem ) {
11952	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
11953};
11954
11955
11956
11957
11958jQuery.ajaxSettings.xhr = function() {
11959	try {
11960		return new window.XMLHttpRequest();
11961	} catch ( e ) {}
11962};
11963
11964var xhrSuccessStatus = {
11965
11966		// File protocol always yields status code 0, assume 200
11967		0: 200,
11968
11969		// Support: IE <=9 only
11970		// trac-1450: sometimes IE returns 1223 when it should be 204
11971		1223: 204
11972	},
11973	xhrSupported = jQuery.ajaxSettings.xhr();
11974
11975support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
11976support.ajax = xhrSupported = !!xhrSupported;
11977
11978jQuery.ajaxTransport( function( options ) {
11979	var callback, errorCallback;
11980
11981	// Cross domain only allowed if supported through XMLHttpRequest
11982	if ( support.cors || xhrSupported && !options.crossDomain ) {
11983		return {
11984			send: function( headers, complete ) {
11985				var i,
11986					xhr = options.xhr();
11987
11988				xhr.open(
11989					options.type,
11990					options.url,
11991					options.async,
11992					options.username,
11993					options.password
11994				);
11995
11996				// Apply custom fields if provided
11997				if ( options.xhrFields ) {
11998					for ( i in options.xhrFields ) {
11999						xhr[ i ] = options.xhrFields[ i ];
12000					}
12001				}
12002
12003				// Override mime type if needed
12004				if ( options.mimeType && xhr.overrideMimeType ) {
12005					xhr.overrideMimeType( options.mimeType );
12006				}
12007
12008				// X-Requested-With header
12009				// For cross-domain requests, seeing as conditions for a preflight are
12010				// akin to a jigsaw puzzle, we simply never set it to be sure.
12011				// (it can always be set on a per-request basis or even using ajaxSetup)
12012				// For same-domain requests, won't change header if already provided.
12013				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
12014					headers[ "X-Requested-With" ] = "XMLHttpRequest";
12015				}
12016
12017				// Set headers
12018				for ( i in headers ) {
12019					xhr.setRequestHeader( i, headers[ i ] );
12020				}
12021
12022				// Callback
12023				callback = function( type ) {
12024					return function() {
12025						if ( callback ) {
12026							callback = errorCallback = xhr.onload =
12027								xhr.onerror = xhr.onabort = xhr.ontimeout =
12028									xhr.onreadystatechange = null;
12029
12030							if ( type === "abort" ) {
12031								xhr.abort();
12032							} else if ( type === "error" ) {
12033
12034								// Support: IE <=9 only
12035								// On a manual native abort, IE9 throws
12036								// errors on any property access that is not readyState
12037								if ( typeof xhr.status !== "number" ) {
12038									complete( 0, "error" );
12039								} else {
12040									complete(
12041
12042										// File: protocol always yields status 0; see trac-8605, trac-14207
12043										xhr.status,
12044										xhr.statusText
12045									);
12046								}
12047							} else {
12048								complete(
12049									xhrSuccessStatus[ xhr.status ] || xhr.status,
12050									xhr.statusText,
12051
12052									// Support: IE <=9 only
12053									// IE9 has no XHR2 but throws on binary (trac-11426)
12054									// For XHR2 non-text, let the caller handle it (gh-2498)
12055									( xhr.responseType || "text" ) !== "text"  ||
12056									typeof xhr.responseText !== "string" ?
12057										{ binary: xhr.response } :
12058										{ text: xhr.responseText },
12059									xhr.getAllResponseHeaders()
12060								);
12061							}
12062						}
12063					};
12064				};
12065
12066				// Listen to events
12067				xhr.onload = callback();
12068				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
12069
12070				// Support: IE 9 only
12071				// Use onreadystatechange to replace onabort
12072				// to handle uncaught aborts
12073				if ( xhr.onabort !== undefined ) {
12074					xhr.onabort = errorCallback;
12075				} else {
12076					xhr.onreadystatechange = function() {
12077
12078						// Check readyState before timeout as it changes
12079						if ( xhr.readyState === 4 ) {
12080
12081							// Allow onerror to be called first,
12082							// but that will not handle a native abort
12083							// Also, save errorCallback to a variable
12084							// as xhr.onerror cannot be accessed
12085							window.setTimeout( function() {
12086								if ( callback ) {
12087									errorCallback();
12088								}
12089							} );
12090						}
12091					};
12092				}
12093
12094				// Create the abort callback
12095				callback = callback( "abort" );
12096
12097				try {
12098
12099					// Do send the request (this may raise an exception)
12100					xhr.send( options.hasContent && options.data || null );
12101				} catch ( e ) {
12102
12103					// trac-14683: Only rethrow if this hasn't been notified as an error yet
12104					if ( callback ) {
12105						throw e;
12106					}
12107				}
12108			},
12109
12110			abort: function() {
12111				if ( callback ) {
12112					callback();
12113				}
12114			}
12115		};
12116	}
12117} );
12118
12119
12120
12121
12122// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
12123jQuery.ajaxPrefilter( function( s ) {
12124	if ( s.crossDomain ) {
12125		s.contents.script = false;
12126	}
12127} );
12128
12129// Install script dataType
12130jQuery.ajaxSetup( {
12131	accepts: {
12132		script: "text/javascript, application/javascript, " +
12133			"application/ecmascript, application/x-ecmascript"
12134	},
12135	contents: {
12136		script: /\b(?:java|ecma)script\b/
12137	},
12138	converters: {
12139		"text script": function( text ) {
12140			jQuery.globalEval( text );
12141			return text;
12142		}
12143	}
12144} );
12145
12146// Handle cache's special case and crossDomain
12147jQuery.ajaxPrefilter( "script", function( s ) {
12148	if ( s.cache === undefined ) {
12149		s.cache = false;
12150	}
12151	if ( s.crossDomain ) {
12152		s.type = "GET";
12153	}
12154} );
12155
12156// Bind script tag hack transport
12157jQuery.ajaxTransport( "script", function( s ) {
12158
12159	// This transport only deals with cross domain or forced-by-attrs requests
12160	if ( s.crossDomain || s.scriptAttrs ) {
12161		var script, callback;
12162		return {
12163			send: function( _, complete ) {
12164				script = jQuery( "<script>" )
12165					.attr( s.scriptAttrs || {} )
12166					.prop( { charset: s.scriptCharset, src: s.url } )
12167					.on( "load error", callback = function( evt ) {
12168						script.remove();
12169						callback = null;
12170						if ( evt ) {
12171							complete( evt.type === "error" ? 404 : 200, evt.type );
12172						}
12173					} );
12174
12175				// Use native DOM manipulation to avoid our domManip AJAX trickery
12176				document.head.appendChild( script[ 0 ] );
12177			},
12178			abort: function() {
12179				if ( callback ) {
12180					callback();
12181				}
12182			}
12183		};
12184	}
12185} );
12186
12187
12188
12189
12190var oldCallbacks = [],
12191	rjsonp = /(=)\?(?=&|$)|\?\?/;
12192
12193// Default jsonp settings
12194jQuery.ajaxSetup( {
12195	jsonp: "callback",
12196	jsonpCallback: function() {
12197		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
12198		this[ callback ] = true;
12199		return callback;
12200	}
12201} );
12202
12203// Detect, normalize options and install callbacks for jsonp requests
12204jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
12205
12206	var callbackName, overwritten, responseContainer,
12207		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
12208			"url" :
12209			typeof s.data === "string" &&
12210				( s.contentType || "" )
12211					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
12212				rjsonp.test( s.data ) && "data"
12213		);
12214
12215	// Handle iff the expected data type is "jsonp" or we have a parameter to set
12216	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
12217
12218		// Get callback name, remembering preexisting value associated with it
12219		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
12220			s.jsonpCallback() :
12221			s.jsonpCallback;
12222
12223		// Insert callback into url or form data
12224		if ( jsonProp ) {
12225			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
12226		} else if ( s.jsonp !== false ) {
12227			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
12228		}
12229
12230		// Use data converter to retrieve json after script execution
12231		s.converters[ "script json" ] = function() {
12232			if ( !responseContainer ) {
12233				jQuery.error( callbackName + " was not called" );
12234			}
12235			return responseContainer[ 0 ];
12236		};
12237
12238		// Force json dataType
12239		s.dataTypes[ 0 ] = "json";
12240
12241		// Install callback
12242		overwritten = window[ callbackName ];
12243		window[ callbackName ] = function() {
12244			responseContainer = arguments;
12245		};
12246
12247		// Clean-up function (fires after converters)
12248		jqXHR.always( function() {
12249
12250			// If previous value didn't exist - remove it
12251			if ( overwritten === undefined ) {
12252				jQuery( window ).removeProp( callbackName );
12253
12254			// Otherwise restore preexisting value
12255			} else {
12256				window[ callbackName ] = overwritten;
12257			}
12258
12259			// Save back as free
12260			if ( s[ callbackName ] ) {
12261
12262				// Make sure that re-using the options doesn't screw things around
12263				s.jsonpCallback = originalSettings.jsonpCallback;
12264
12265				// Save the callback name for future use
12266				oldCallbacks.push( callbackName );
12267			}
12268
12269			// Call if it was a function and we have a response
12270			if ( responseContainer && isFunction( overwritten ) ) {
12271				overwritten( responseContainer[ 0 ] );
12272			}
12273
12274			responseContainer = overwritten = undefined;
12275		} );
12276
12277		// Delegate to script
12278		return "script";
12279	}
12280} );
12281
12282
12283
12284
12285// Support: Safari 8 only
12286// In Safari 8 documents created via document.implementation.createHTMLDocument
12287// collapse sibling forms: the second one becomes a child of the first one.
12288// Because of that, this security measure has to be disabled in Safari 8.
12289// https://bugs.webkit.org/show_bug.cgi?id=137337
12290support.createHTMLDocument = ( function() {
12291	var body = document.implementation.createHTMLDocument( "" ).body;
12292	body.innerHTML = "<form></form><form></form>";
12293	return body.childNodes.length === 2;
12294} )();
12295
12296
12297// Argument "data" should be string of html
12298// context (optional): If specified, the fragment will be created in this context,
12299// defaults to document
12300// keepScripts (optional): If true, will include scripts passed in the html string
12301jQuery.parseHTML = function( data, context, keepScripts ) {
12302	if ( typeof data !== "string" ) {
12303		return [];
12304	}
12305	if ( typeof context === "boolean" ) {
12306		keepScripts = context;
12307		context = false;
12308	}
12309
12310	var base, parsed, scripts;
12311
12312	if ( !context ) {
12313
12314		// Stop scripts or inline event handlers from being executed immediately
12315		// by using document.implementation
12316		if ( support.createHTMLDocument ) {
12317			context = document.implementation.createHTMLDocument( "" );
12318
12319			// Set the base href for the created document
12320			// so any parsed elements with URLs
12321			// are based on the document's URL (gh-2965)
12322			base = context.createElement( "base" );
12323			base.href = document.location.href;
12324			context.head.appendChild( base );
12325		} else {
12326			context = document;
12327		}
12328	}
12329
12330	parsed = rsingleTag.exec( data );
12331	scripts = !keepScripts && [];
12332
12333	// Single tag
12334	if ( parsed ) {
12335		return [ context.createElement( parsed[ 1 ] ) ];
12336	}
12337
12338	parsed = buildFragment( [ data ], context, scripts );
12339
12340	if ( scripts && scripts.length ) {
12341		jQuery( scripts ).remove();
12342	}
12343
12344	return jQuery.merge( [], parsed.childNodes );
12345};
12346
12347
12348/**
12349 * Load a url into a page
12350 */
12351jQuery.fn.load = function( url, params, callback ) {
12352	var selector, type, response,
12353		self = this,
12354		off = url.indexOf( " " );
12355
12356	if ( off > -1 ) {
12357		selector = stripAndCollapse( url.slice( off ) );
12358		url = url.slice( 0, off );
12359	}
12360
12361	// If it's a function
12362	if ( isFunction( params ) ) {
12363
12364		// We assume that it's the callback
12365		callback = params;
12366		params = undefined;
12367
12368	// Otherwise, build a param string
12369	} else if ( params && typeof params === "object" ) {
12370		type = "POST";
12371	}
12372
12373	// If we have elements to modify, make the request
12374	if ( self.length > 0 ) {
12375		jQuery.ajax( {
12376			url: url,
12377
12378			// If "type" variable is undefined, then "GET" method will be used.
12379			// Make value of this field explicit since
12380			// user can override it through ajaxSetup method
12381			type: type || "GET",
12382			dataType: "html",
12383			data: params
12384		} ).done( function( responseText ) {
12385
12386			// Save response for use in complete callback
12387			response = arguments;
12388
12389			self.html( selector ?
12390
12391				// If a selector was specified, locate the right elements in a dummy div
12392				// Exclude scripts to avoid IE 'Permission Denied' errors
12393				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
12394
12395				// Otherwise use the full result
12396				responseText );
12397
12398		// If the request succeeds, this function gets "data", "status", "jqXHR"
12399		// but they are ignored because response was set above.
12400		// If it fails, this function gets "jqXHR", "status", "error"
12401		} ).always( callback && function( jqXHR, status ) {
12402			self.each( function() {
12403				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
12404			} );
12405		} );
12406	}
12407
12408	return this;
12409};
12410
12411
12412
12413
12414jQuery.expr.pseudos.animated = function( elem ) {
12415	return jQuery.grep( jQuery.timers, function( fn ) {
12416		return elem === fn.elem;
12417	} ).length;
12418};
12419
12420
12421
12422
12423jQuery.offset = {
12424	setOffset: function( elem, options, i ) {
12425		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
12426			position = jQuery.css( elem, "position" ),
12427			curElem = jQuery( elem ),
12428			props = {};
12429
12430		// Set position first, in-case top/left are set even on static elem
12431		if ( position === "static" ) {
12432			elem.style.position = "relative";
12433		}
12434
12435		curOffset = curElem.offset();
12436		curCSSTop = jQuery.css( elem, "top" );
12437		curCSSLeft = jQuery.css( elem, "left" );
12438		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
12439			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
12440
12441		// Need to be able to calculate position if either
12442		// top or left is auto and position is either absolute or fixed
12443		if ( calculatePosition ) {
12444			curPosition = curElem.position();
12445			curTop = curPosition.top;
12446			curLeft = curPosition.left;
12447
12448		} else {
12449			curTop = parseFloat( curCSSTop ) || 0;
12450			curLeft = parseFloat( curCSSLeft ) || 0;
12451		}
12452
12453		if ( isFunction( options ) ) {
12454
12455			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
12456			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
12457		}
12458
12459		if ( options.top != null ) {
12460			props.top = ( options.top - curOffset.top ) + curTop;
12461		}
12462		if ( options.left != null ) {
12463			props.left = ( options.left - curOffset.left ) + curLeft;
12464		}
12465
12466		if ( "using" in options ) {
12467			options.using.call( elem, props );
12468
12469		} else {
12470			curElem.css( props );
12471		}
12472	}
12473};
12474
12475jQuery.fn.extend( {
12476
12477	// offset() relates an element's border box to the document origin
12478	offset: function( options ) {
12479
12480		// Preserve chaining for setter
12481		if ( arguments.length ) {
12482			return options === undefined ?
12483				this :
12484				this.each( function( i ) {
12485					jQuery.offset.setOffset( this, options, i );
12486				} );
12487		}
12488
12489		var rect, win,
12490			elem = this[ 0 ];
12491
12492		if ( !elem ) {
12493			return;
12494		}
12495
12496		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
12497		// Support: IE <=11 only
12498		// Running getBoundingClientRect on a
12499		// disconnected node in IE throws an error
12500		if ( !elem.getClientRects().length ) {
12501			return { top: 0, left: 0 };
12502		}
12503
12504		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
12505		rect = elem.getBoundingClientRect();
12506		win = elem.ownerDocument.defaultView;
12507		return {
12508			top: rect.top + win.pageYOffset,
12509			left: rect.left + win.pageXOffset
12510		};
12511	},
12512
12513	// position() relates an element's margin box to its offset parent's padding box
12514	// This corresponds to the behavior of CSS absolute positioning
12515	position: function() {
12516		if ( !this[ 0 ] ) {
12517			return;
12518		}
12519
12520		var offsetParent, offset, doc,
12521			elem = this[ 0 ],
12522			parentOffset = { top: 0, left: 0 };
12523
12524		// position:fixed elements are offset from the viewport, which itself always has zero offset
12525		if ( jQuery.css( elem, "position" ) === "fixed" ) {
12526
12527			// Assume position:fixed implies availability of getBoundingClientRect
12528			offset = elem.getBoundingClientRect();
12529
12530		} else {
12531			offset = this.offset();
12532
12533			// Account for the *real* offset parent, which can be the document or its root element
12534			// when a statically positioned element is identified
12535			doc = elem.ownerDocument;
12536			offsetParent = elem.offsetParent || doc.documentElement;
12537			while ( offsetParent &&
12538				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
12539				jQuery.css( offsetParent, "position" ) === "static" ) {
12540
12541				offsetParent = offsetParent.parentNode;
12542			}
12543			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
12544
12545				// Incorporate borders into its offset, since they are outside its content origin
12546				parentOffset = jQuery( offsetParent ).offset();
12547				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
12548				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
12549			}
12550		}
12551
12552		// Subtract parent offsets and element margins
12553		return {
12554			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
12555			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
12556		};
12557	},
12558
12559	// This method will return documentElement in the following cases:
12560	// 1) For the element inside the iframe without offsetParent, this method will return
12561	//    documentElement of the parent window
12562	// 2) For the hidden or detached element
12563	// 3) For body or html element, i.e. in case of the html node - it will return itself
12564	//
12565	// but those exceptions were never presented as a real life use-cases
12566	// and might be considered as more preferable results.
12567	//
12568	// This logic, however, is not guaranteed and can change at any point in the future
12569	offsetParent: function() {
12570		return this.map( function() {
12571			var offsetParent = this.offsetParent;
12572
12573			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
12574				offsetParent = offsetParent.offsetParent;
12575			}
12576
12577			return offsetParent || documentElement;
12578		} );
12579	}
12580} );
12581
12582// Create scrollLeft and scrollTop methods
12583jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
12584	var top = "pageYOffset" === prop;
12585
12586	jQuery.fn[ method ] = function( val ) {
12587		return access( this, function( elem, method, val ) {
12588
12589			// Coalesce documents and windows
12590			var win;
12591			if ( isWindow( elem ) ) {
12592				win = elem;
12593			} else if ( elem.nodeType === 9 ) {
12594				win = elem.defaultView;
12595			}
12596
12597			if ( val === undefined ) {
12598				return win ? win[ prop ] : elem[ method ];
12599			}
12600
12601			if ( win ) {
12602				win.scrollTo(
12603					!top ? val : win.pageXOffset,
12604					top ? val : win.pageYOffset
12605				);
12606
12607			} else {
12608				elem[ method ] = val;
12609			}
12610		}, method, val, arguments.length );
12611	};
12612} );
12613
12614// Support: Safari <=7 - 9.1, Chrome <=37 - 49
12615// Add the top/left cssHooks using jQuery.fn.position
12616// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
12617// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
12618// getComputedStyle returns percent when specified for top/left/bottom/right;
12619// rather than make the css module depend on the offset module, just check for it here
12620jQuery.each( [ "top", "left" ], function( _i, prop ) {
12621	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
12622		function( elem, computed ) {
12623			if ( computed ) {
12624				computed = curCSS( elem, prop );
12625
12626				// If curCSS returns percentage, fallback to offset
12627				return rnumnonpx.test( computed ) ?
12628					jQuery( elem ).position()[ prop ] + "px" :
12629					computed;
12630			}
12631		}
12632	);
12633} );
12634
12635
12636// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
12637jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
12638	jQuery.each( {
12639		padding: "inner" + name,
12640		content: type,
12641		"": "outer" + name
12642	}, function( defaultExtra, funcName ) {
12643
12644		// Margin is only for outerHeight, outerWidth
12645		jQuery.fn[ funcName ] = function( margin, value ) {
12646			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
12647				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
12648
12649			return access( this, function( elem, type, value ) {
12650				var doc;
12651
12652				if ( isWindow( elem ) ) {
12653
12654					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
12655					return funcName.indexOf( "outer" ) === 0 ?
12656						elem[ "inner" + name ] :
12657						elem.document.documentElement[ "client" + name ];
12658				}
12659
12660				// Get document width or height
12661				if ( elem.nodeType === 9 ) {
12662					doc = elem.documentElement;
12663
12664					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
12665					// whichever is greatest
12666					return Math.max(
12667						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
12668						elem.body[ "offset" + name ], doc[ "offset" + name ],
12669						doc[ "client" + name ]
12670					);
12671				}
12672
12673				return value === undefined ?
12674
12675					// Get width or height on the element, requesting but not forcing parseFloat
12676					jQuery.css( elem, type, extra ) :
12677
12678					// Set width or height on the element
12679					jQuery.style( elem, type, value, extra );
12680			}, type, chainable ? margin : undefined, chainable );
12681		};
12682	} );
12683} );
12684
12685
12686jQuery.each( [
12687	"ajaxStart",
12688	"ajaxStop",
12689	"ajaxComplete",
12690	"ajaxError",
12691	"ajaxSuccess",
12692	"ajaxSend"
12693], function( _i, type ) {
12694	jQuery.fn[ type ] = function( fn ) {
12695		return this.on( type, fn );
12696	};
12697} );
12698
12699
12700
12701
12702jQuery.fn.extend( {
12703
12704	bind: function( types, data, fn ) {
12705		return this.on( types, null, data, fn );
12706	},
12707	unbind: function( types, fn ) {
12708		return this.off( types, null, fn );
12709	},
12710
12711	delegate: function( selector, types, data, fn ) {
12712		return this.on( types, selector, data, fn );
12713	},
12714	undelegate: function( selector, types, fn ) {
12715
12716		// ( namespace ) or ( selector, types [, fn] )
12717		return arguments.length === 1 ?
12718			this.off( selector, "**" ) :
12719			this.off( types, selector || "**", fn );
12720	},
12721
12722	hover: function( fnOver, fnOut ) {
12723		return this
12724			.on( "mouseenter", fnOver )
12725			.on( "mouseleave", fnOut || fnOver );
12726	}
12727} );
12728
12729jQuery.each(
12730	( "blur focus focusin focusout resize scroll click dblclick " +
12731	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
12732	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
12733	function( _i, name ) {
12734
12735		// Handle event binding
12736		jQuery.fn[ name ] = function( data, fn ) {
12737			return arguments.length > 0 ?
12738				this.on( name, null, data, fn ) :
12739				this.trigger( name );
12740		};
12741	}
12742);
12743
12744
12745
12746
12747// Support: Android <=4.0 only
12748// Make sure we trim BOM and NBSP
12749// Require that the "whitespace run" starts from a non-whitespace
12750// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
12751var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
12752
12753// Bind a function to a context, optionally partially applying any
12754// arguments.
12755// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
12756// However, it is not slated for removal any time soon
12757jQuery.proxy = function( fn, context ) {
12758	var tmp, args, proxy;
12759
12760	if ( typeof context === "string" ) {
12761		tmp = fn[ context ];
12762		context = fn;
12763		fn = tmp;
12764	}
12765
12766	// Quick check to determine if target is callable, in the spec
12767	// this throws a TypeError, but we will just return undefined.
12768	if ( !isFunction( fn ) ) {
12769		return undefined;
12770	}
12771
12772	// Simulated bind
12773	args = slice.call( arguments, 2 );
12774	proxy = function() {
12775		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
12776	};
12777
12778	// Set the guid of unique handler to the same of original handler, so it can be removed
12779	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
12780
12781	return proxy;
12782};
12783
12784jQuery.holdReady = function( hold ) {
12785	if ( hold ) {
12786		jQuery.readyWait++;
12787	} else {
12788		jQuery.ready( true );
12789	}
12790};
12791jQuery.isArray = Array.isArray;
12792jQuery.parseJSON = JSON.parse;
12793jQuery.nodeName = nodeName;
12794jQuery.isFunction = isFunction;
12795jQuery.isWindow = isWindow;
12796jQuery.camelCase = camelCase;
12797jQuery.type = toType;
12798
12799jQuery.now = Date.now;
12800
12801jQuery.isNumeric = function( obj ) {
12802
12803	// As of jQuery 3.0, isNumeric is limited to
12804	// strings and numbers (primitives or objects)
12805	// that can be coerced to finite numbers (gh-2662)
12806	var type = jQuery.type( obj );
12807	return ( type === "number" || type === "string" ) &&
12808
12809		// parseFloat NaNs numeric-cast false positives ("")
12810		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
12811		// subtraction forces infinities to NaN
12812		!isNaN( obj - parseFloat( obj ) );
12813};
12814
12815jQuery.trim = function( text ) {
12816	return text == null ?
12817		"" :
12818		( text + "" ).replace( rtrim, "$1" );
12819};
12820
12821
12822
12823// Register as a named AMD module, since jQuery can be concatenated with other
12824// files that may use define, but not via a proper concatenation script that
12825// understands anonymous AMD modules. A named AMD is safest and most robust
12826// way to register. Lowercase jquery is used because AMD module names are
12827// derived from file names, and jQuery is normally delivered in a lowercase
12828// file name. Do this after creating the global so that if an AMD module wants
12829// to call noConflict to hide this version of jQuery, it will work.
12830
12831// Note that for maximum portability, libraries that are not jQuery should
12832// declare themselves as anonymous modules, and avoid setting a global if an
12833// AMD loader is present. jQuery is a special case. For more information, see
12834// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
12835
12836if ( true ) {
12837	!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {
12838		return jQuery;
12839	}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
12840		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
12841}
12842
12843
12844
12845
12846var
12847
12848	// Map over jQuery in case of overwrite
12849	_jQuery = window.jQuery,
12850
12851	// Map over the $ in case of overwrite
12852	_$ = window.$;
12853
12854jQuery.noConflict = function( deep ) {
12855	if ( window.$ === jQuery ) {
12856		window.$ = _$;
12857	}
12858
12859	if ( deep && window.jQuery === jQuery ) {
12860		window.jQuery = _jQuery;
12861	}
12862
12863	return jQuery;
12864};
12865
12866// Expose jQuery and $ identifiers, even in AMD
12867// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
12868// and CommonJS for browser emulators (trac-13566)
12869if ( typeof noGlobal === "undefined" ) {
12870	window.jQuery = window.$ = jQuery;
12871}
12872
12873
12874
12875
12876return jQuery;
12877} );
12878
12879
12880/***/ })
12880
12881
12882/******/ 	});
12883/************************************************************************/
12884/******/ 	// The module cache
12885/******/ 	var __webpack_module_cache__ = {};
12886/******/ 	
12887/******/ 	// The require function
12888/******/ 	function __webpack_require__(moduleId) {
12889/******/ 		// Check if module is in cache
12890/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
12891/******/ 		if (cachedModule !== undefined) {
12892/******/ 			return cachedModule.exports;
12893/******/ 		}
12894/******/ 		// Create a new module (and put it into the cache)
12895/******/ 		var module = __webpack_module_cache__[moduleId] = {
12896/******/ 			// no module.id needed
12897/******/ 			// no module.loaded needed
12898/******/ 			exports: {}
12899/******/ 		};
12900/******/ 	
12901/******/ 		// Execute the module function
12902/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
12903/******/ 	
12904/******/ 		// Return the exports of the module
12905/******/ 		return module.exports;
12906/******/ 	}
12907/******/ 	
12908/************************************************************************/
12909var __webpack_exports__ = {};
12910// This entry need to be wrapped in an IIFE because it need to be in strict mode.
12911(() => {
12912"use strict";
12913var exports = __webpack_exports__;
12914/*!**********************************!*\
12915  !*** ./ts/dist/modules/forms.js ***!
12916  \**********************************/
12917
12918Object.defineProperty(exports, "__esModule", ({ value: true }));
12919var $ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js");
12920__webpack_require__(/*! jquery-validation */ "./node_modules/jquery-validation/dist/jquery.validate.js");
12921__webpack_require__(/*! jquery-validation-unobtrusive */ "./node_modules/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js");
12922////(function ($) {
12923////    $.validator.unobtrusive.parseDynamicContent = function (selector) {
12924////        //use the normal unobstrusive.parse method
12925////        $.validator.unobtrusive.parse(selector);
12926////        //get the relevant form
12927////        var form = $(selector).first().closest('form');
12928////        //get the collections of unobstrusive validators, and jquery validators
12929////        //and compare the two
12930////        var unobtrusiveValidation = form.data('unobtrusiveValidation');
12931////        var validator = form.validate();
12932////        $.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
12933////            if (validator.settings.rules[elname] == undefined) {
12934////                var args = {};
12935////                $.extend(args, elrules);
12936////                args.messages = unobtrusiveValidation.options.messages[elname];
12937////                //edit:use quoted strings for the name selector
12938////                $("[name='" + elname + "']").rules("add", args);
12939////            } else {
12940////                $.each(elrules, function (rulename, data) {
12941////                    if (validator.settings.rules[elname][rulename] == undefined) {
12942////                        var args = {};
12943////                        args[rulename] = data;
12944////                        args.messages = unobtrusiveValidation.options.messages[elname][rulename];
12945////                        //edit:use quoted strings for the name selector
12946////                        $("[name='" + elname + "']").rules("add", args);
12947////                    }
12948////                });
12949////            }
12950////        });
12951////    }
12952////})($);
12953document.addEventListener('DOMContentLoaded', function () {
12954    var maxMB = 10;
12955    var maximumSize = maxMB * 1024 * 1024; // In MegaBytes
12956    $.validator.addMethod('filesize', function (_value, element, param) {
12957        var FileElement = element;
12958        if (this.optional(element))
12959            return true;
12960        if (!FileElement.files)
12961            return true;
12962        var totalSize = Array.from(FileElement.files).reduce(function (sum, file) { return sum + file.size; }, 0);
12963        return totalSize <= param;
12964    });
12965    //$.validator.addMethod('filesize', function (value, element, arg) {
12966    //    var minsize = 1000; // min 1kb
12967    //    alert("value:" + value.files[0].size + "; minsize:" + minsize +";arg:"+arg);
12968    //    if ((value > minsize) && (value <= arg)) {
12969    //        return true;
12970    //    } else {
12971    //        return false;
12972    //    }
12973    //});
12974    //var form = $('#form163e38d633a5482fbde58a8357a17f90')
12975    //    .removeData("validator") /* added by the raw jquery.validate plugin */
12976    //    .removeData("unobtrusiveValidation");  /* added by the jquery unobtrusive plugin*/
12977    //$('.fileupload input[type="file"]').each(function () {
12978    //    //  alert($(this).attr('id'));
12979    //    $(this).rules("add",
12980    //        {
12981    //            filesize: maximumSize,
12982    //            messages: {
12983    //                filesize: "File size must be less than 10MB."
12984    //            }
12985    //        });
12986    //});
12987    // $.validator.unobtrusive.parse(form);
12988    var formlist = document.querySelectorAll('form');
12989    for (var f = 0; f < formlist.length; f++) {
12990        var formitem = formlist[f];
12991        var formid = formitem.id;
12992        $("#" + formid).validate({});
12993        $('.fileupload input[type="file"]').each(function () {
12994            //  alert($(this).attr('id'));
12995            $(this).rules("add", {
12996                filesize: maximumSize,
12997                messages: {
12998                    filesize: "The total size of your images together is over 10 MB.  There is a maximum limit on the total size of your files altogether of 10MB."
12999                }
13000            });
13001        });
13002        //if ($("#" + formid).data('validator')) {
13003        //        // validator exists
13004        //        alert('exists');
13005        //    }
13006        //    else { alert("NON"); };
13007    }
13008    // Character count for textarea fields with a maximum length set in Umbraco Forms
13009    var limitedTextareas = document.querySelectorAll('textarea[maxlength]');
13010    limitedTextareas.forEach(function (textarea) {
13011        var _a;
13012        var max = parseInt((_a = textarea.getAttribute('maxlength')) !== null && _a !== void 0 ? _a : '0', 10);
13013        if (!max)
13014            return;
13015        var counter = document.createElement('span');
13016        counter.className = 'umbraco-forms-char-count';
13017        counter.setAttribute('aria-live', 'polite');
13018        updateCharCount(counter, textarea.value.length, max);
13019        textarea.insertAdjacentElement('afterend', counter);
13020        textarea.addEventListener('input', function () {
13021            updateCharCount(counter, textarea.value.length, max);
13022        });
13023    });
13024    //$("#form163e38d633a5482fbde58a8357a17f90").validate({
13025    //    rules: {
13026    //                '8d3af0b6-91c7-43f2-d267-39e2321f0474': {
13027    //                    filesize: maximumSize
13028    //                }
13029    //            }, messages: {
13030    //                '8d3af0b6-91c7-43f2-d267-39e2321f0474': {
13031    //                    filesize: "File size must be less than 10MB."
13032    //                }
13033    //            },
13034    //    submitHandler: function (form) {
13035    //                form.submit();
13036    //            }
13037    //});
13038    //    $("#form96e424c5d8aa405aabd9c32f974d5359").validate({});
13039    //    //$('#8d3af0b6-91c7-43f2-d267-39e2321f0474').rules("add",
13040    //    //    {
13041    //    //        filesize: maximumSize,
13042    //    //        messages: {
13043    //    //            filesize: "File size must be less than 10MB."
13044    //    //        }
13045    //    //    });
13046    //    var form = $('#form676b6043ff0d48e281695f46867edaa7');
13047    //    if (form.data('validator')) {
13048    //        // validator exists    
13049    //        alert('exists');
13050    //    }
13051    //    else { alert("NON"); };
13052    ///*    $.validator.unobtrusive.parse(document);*/
13053    ////const formList = document.querySelectorAll('form');
13054    ////for (var f = 0; f < formList.length; f++) {
13055    ////    const formItem: HTMLFormElement = formList[f];
13056    ////    const formID = formItem.id;
13057    ////    alert(formID);
13058    ////    $("#" + formID).validate({
13059    ////        rules: {
13060    ////            file_upload: {
13061    ////                filesize: maximumSize   
13062    ////            }
13063    ////        }, messages: {
13064    ////            file_upload: {
13065    ////                filesize: "File size must be less than 10MB."
13066    ////            }
13067    ////        },
13068    ////        submitHandler: function (form) {
13069    ////            form.submit();
13070    ////        }
13071    ////    });
13072    ////}
13073    //////$("#myform").validate({
13074    //////    rules: {
13075    //////        file_upload: {
13076    //////           // required: true,
13077    //////         //   accept: "application/pdf,image/jpeg,image/png",
13078    //////            filesize: maximumSize   //max size 200 kb
13079    //////        }
13080    //////    }, messages: {
13081    //////        file_upload: {
13082    //////            filesize: " file size must be less than 10MB.",
13083    //////           // accept: "Please upload .jpg or .png or .pdf file of notice.",
13084    //////           // required: "Please upload file."
13085    //////        }
13086    //////    },
13087    //////    submitHandler: function (form) {
13088    //////        form.submit();
13089    //////    }
13090    //////});
13091    //   const maxMB = 10;
13092    //  const maximumSize = maxMB * 1024 * 1024 // In MegaBytes
13093    ////////    var fileUploadFields = document.getElementsByClassName("fileupload");
13094    ////////    for (var i = 0; i < fileUploadFields.length; i++) {
13095    ////////        const fileUploadInput: HTMLInputElement = fileUploadFields[i].querySelector('input[type=file]');
13096    ////////        const uploadFieldContainer: HTMLElement = fileUploadFields[i].querySelector('.umbraco-forms-field-wrapper');
13097    ////////        //const validSpan: HTMLElement = uploadFieldContainer.querySelector("[class ^= 'field-validation']");
13098    ////////        //const validSpan: HTMLElement = uploadFieldContainer.querySelector(".field-validation-valid");
13099    ////////        //   validSpan.textContent = "TOO LARGE";
13100    ////////        //alert(fileUploadInput.id);
13101    ////////        let errorSpan = document.createElement('span');
13102    ////////        fileUploadInput.addEventListener("change", function (e) {
13103    ////////            const files: File[] = Array.from(this.files);
13104    ////////            const approvedFiles = new Array;
13105    ////////            files.forEach((file: File) => {
13106    ////////                // if () {
13107    ////////                if (errorSpan.parentElement === uploadFieldContainer) {
13108    ////////                    uploadFieldContainer.removeChild(errorSpan);
13109    ////////                }
13110    ////////              //  }
13111    ////////             //       alert(file.size);
13112    ////////                if (file.size <= maximumSize) {
13113    ////////                    approvedFiles.push(file);
13114    ////////                    // alert("filesgood:" + file.size);
13115    ////////                    //if (validSpan.classList.contains('field-validation-error')){
13116    ////////                    //    validSpan.classList.add('field-validation-valid');
13117    ////////                    //    validSpan.classList.remove('field-validation-error');
13118    ////////                    //}
13119    ////////                    //validSpan.textContent = "";
13120    ////////                }
13121    ////////                else {
13122    ////////                    this.value = "";
13123    ////////                    let fileSizeMB = (file.size / (1024 * 1024)).toFixed(2);
13124    ////////                    //if (validSpan.classList.contains('field-validation-valid')) {
13125    ////////                    //    validSpan.classList.remove('field-validation-valid');
13126    ////////                    //    validSpan.classList.add('field-validation-error');
13127    ////////                    //}
13128    ////////                    //validSpan.textContent += "File size too large, file must be under " + maxMB + "MB;";
13129    ////////                    errorSpan.setAttribute('data-valmsg-for', fileUploadInput.id);
13130    ////////                    errorSpan.setAttribute('data-valmsg-replace', 'true');
13131    ////////                    errorSpan.classList.add("field-validation-error");
13132    ////////                    errorSpan.textContent = 'File must be under ' + maximumSize + 'MB;';
13133    ////////                    uploadFieldContainer.appendChild(errorSpan);
13134    ////////                    // alert("filesbad")
13135    ////////                   // this.setCustomValidity('File size too large: ' + file.size + ', file must be under ' + maximumSize + 'MB;');
13136    ////////                }
13137    ////////            });
13138    ////////;
13139    ////////        });
13140    ////////    }
13141    ////////    var newFieluploads = document.querySelectorAll('.umbraco-forms-field-wrapper > input[type=file]')
13142    // for (var i = 0; i < newFieluploads.length; i++) {
13143    //      alert(newFieluploads[i].id);
13144    // const fileUploadInput: HTMLInputElement = newFieluploads[i];
13145    //  const uploadFieldContainer: HTMLElement = fileUploads[i].parentNode;
13146    //  const validSpan: HTMLElement = uploadFieldContainer.getElementsByClassName("field-validation-valid")[0];
13147    //   validSpan.textContent = "TOO LARGE";
13148    //let errorSpan = document.createElement('span');
13149    //// let errorSpan = '<span class="field-validation-error" data-valmsg-for="' + fileUploadInput.id + '" data-valmsg-replace="true" role="alert">ACK. Too large.</span>';
13150    //errorSpan.setAttribute('role', 'alert');
13151    //errorSpan.setAttribute('data-valmsg-for', fileUploadInput.id);
13152    //errorSpan.setAttribute('data-valmsg-replace', 'true');
13153    //errorSpan.classList.add("field-validation-error");
13154    //errorSpan.textContent ="TOO LARGE";
13155    //uploadFieldContainer.appendChild(errorSpan);
13156    //   }
13157    //<span class="field-validation-error" data-valmsg-for="048d674c-520c-42c6-a6e3-9513d38bece2" data-valmsg-replace="true" role="alert">The file type (.usync) you tried to upload is not allowed.</span>
13158    ////////for (var i = 0; i < fileUploads.length; i++) {
13159    ////////    const fileUploadInput:HTMLInputElement = fileUploads[i].querySelector('.file-upload-input');
13160    ////////    const validationDiv:HTMLElement = fileUploads[i].querySelector('.file-upload-validation');
13161    ////////    fileUploadInput.addEventListener("change", function (e) {
13162    ////////        alert("PING");
13163    ////////        const files: File[] = Array.from(this.files)
13164    ////////        const approvedFiles = new Array
13165    ////////       // if (!files.length) return result.innerText = "No selected files"
13166    ////////       // alert(files);
13167    ////////        files.forEach((file: File) => {
13168    ////////        //    alert(file.size);
13169    ////////            if (file.size <= maximumSize) {
13170    ////////                approvedFiles.push(file);
13171    ////////                alert("filesgood:" + file.size);
13172    ////////                }
13173    ////////                else{
13174    ////////                validationDiv.innerText = "File size too large: " + file.size;
13175    ////////                // alert("filesbad")
13176    ////////                }
13177    ////////        });
13178    ////////        //for (const file: File of files) if (file.size <= maximumSize) approvedFiles.push(file)
13179    ////////        ////if (approvedFiles.length) result.innerText = `Approved files: ${approvedFiles.map(file => file.name).join(", ")}`
13180    ////////        ////else result.innerText = "No approved files"
13181    ////////    })
13182    ////////}
13183});
13184function updateCharCount(el, current, max) {
13185    el.textContent = "".concat(current, " of ").concat(max, " characters used");
13186    el.classList.toggle('umbraco-forms-char-count--warning', (max - current) <= 50);
13187}
13188//# sourceMappingURL=forms.js.map
13189})();
13190
13191/******/ })()
13192;
13193//# sourceMappingURL=forms.js.map

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.