PageSourceSearch

https://www.mansfieldfoundation.org/Client/Scripts/jquery/jquery.validate.js

js mansfieldfoundation.org collected 2026-10-06 05:44:57 UTC 54,110 bytes, 1,703 lines download raw bytes

vendor: 54,110 bytes, lines 1-1703
1/*!
2 * jQuery Validation Plugin v1.21.0
3 *
4 * https://jqueryvalidation.org/
5 *
6 * Copyright (c) 2024 Jörn Zaefferer
7 * Released under the MIT license
8 */
9(function (factory) {
10	if (typeof define === "function" && define.amd) {
11		define(["jquery"], factory);
12	} else if (typeof module === "object" && module.exports) {
13		module.exports = factory(require("jquery"));
14	} else {
15		factory(jQuery);
16	}
17}(function ($) {
18
19	$.extend($.fn, {
20
21		// https://jqueryvalidation.org/validate/
22		validate: function (options) {
23
24			// If nothing is selected, return nothing; can't chain anyway
25			if (!this.length) {
26				if (options && options.debug && window.console) {
27					console.warn("Nothing selected, can't validate, returning nothing.");
28				}
29				return;
30			}
31
32			// Check if a validator for this form was already created
33			var validator = $.data(this[0], "validator");
34			if (validator) {
35				return validator;
36			}
37
38			// Add novalidate tag if HTML5.
39			this.attr("novalidate", "novalidate");
40
41			validator = new $.validator(options, this[0]);
42			$.data(this[0], "validator", validator);
43
44			if (validator.settings.onsubmit) {
45
46				this.on("click.validate", ":submit", function (event) {
47
48					// Track the used submit button to properly handle scripted
49					// submits later.
50					validator.submitButton = event.currentTarget;
51
52					// Allow suppressing validation by adding a cancel class to the submit button
53					if ($(this).hasClass("cancel")) {
54						validator.cancelSubmit = true;
55					}
56
57					// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
58					if ($(this).attr("formnovalidate") !== undefined) {
59						validator.cancelSubmit = true;
60					}
61				});
62
63				// Validate the form on submit
64				this.on("submit.validate", function (event) {
65					if (validator.settings.debug) {
66
67						// Prevent form submit to be able to see console output
68						event.preventDefault();
69					}
70
71					function handle() {
72						var hidden, result;
73
74						// Insert a hidden input as a replacement for the missing submit button
75						// The hidden input is inserted in two cases:
76						//   - A user defined a `submitHandler`
77						//   - There was a pending request due to `remote` method and `stopRequest()`
78						//     was called to submit the form in case it's valid
79						if (validator.submitButton && (validator.settings.submitHandler || validator.formSubmitted)) {
80							hidden = $("<input type='hidden'/>")
81								.attr("name", validator.submitButton.name)
82								.val($(validator.submitButton).val())
83								.appendTo(validator.currentForm);
84						}
85
86						if (validator.settings.submitHandler && !validator.settings.debug) {
87							result = validator.settings.submitHandler.call(validator, validator.currentForm, event);
88							if (hidden) {
89
90								// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
91								hidden.remove();
92							}
93							if (result !== undefined) {
94								return result;
95							}
96							return false;
97						}
98						return true;
99					}
100
101					// Prevent submit for invalid forms or custom submit handlers
102					if (validator.cancelSubmit) {
103						validator.cancelSubmit = false;
104						return handle();
105					}
106					if (validator.form()) {
107						if (validator.pendingRequest) {
108							validator.formSubmitted = true;
109							return false;
110						}
111						return handle();
112					} else {
113						validator.focusInvalid();
114						return false;
115					}
116				});
117			}
118
119			return validator;
120		},
121
122		// https://jqueryvalidation.org/valid/
123		valid: function () {
124			var valid, validator, errorList;
125
126			if ($(this[0]).is("form")) {
127				valid = this.validate().form();
128			} else {
129				errorList = [];
130				valid = true;
131				validator = $(this[0].form).validate();
132				this.each(function () {
133					valid = validator.element(this) && valid;
134					if (!valid) {
135						errorList = errorList.concat(validator.errorList);
136					}
137				});
138				validator.errorList = errorList;
139			}
140			return valid;
141		},
142
143		// https://jqueryvalidation.org/rules/
144		rules: function (command, argument) {
145			var element = this[0],
146				isContentEditable = typeof this.attr("contenteditable") !== "undefined" && this.attr("contenteditable") !== "false",
147				settings, staticRules, existingRules, data, param, filtered;
148
149			// If nothing is selected, return empty object; can't chain anyway
150			if (element == null) {
151				return;
152			}
153
154			if (!element.form && isContentEditable) {
155				element.form = this.closest("form")[0];
156				element.name = this.attr("name");
157			}
158
159			if (element.form == null) {
160				return;
161			}
162
163			if (command) {
164				settings = $.data(element.form, "validator").settings;
165				staticRules = settings.rules;
166				existingRules = $.validator.staticRules(element);
167				switch (command) {
168					case "add":
169						$.extend(existingRules, $.validator.normalizeRule(argument));
170
171						// Remove messages from rules, but allow them to be set separately
172						delete existingRules.messages;
173						staticRules[element.name] = existingRules;
174						if (argument.messages) {
175							settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages);
176						}
177						break;
178					case "remove":
179						if (!argument) {
180							delete staticRules[element.name];
181							return existingRules;
182						}
183						filtered = {};
184						$.each(argument.split(/\s/), function (index, method) {
185							filtered[method] = existingRules[method];
186							delete existingRules[method];
187						});
188						return filtered;
189				}
190			}
191
192			data = $.validator.normalizeRules(
193				$.extend(
194					{},
195					$.validator.classRules(element),
196					$.validator.attributeRules(element),
197					$.validator.dataRules(element),
198					$.validator.staticRules(element)
199				), element);
200
201			// Make sure required is at front
202			if (data.required) {
203				param = data.required;
204				delete data.required;
205				data = $.extend({ required: param }, data);
206			}
207
208			// Make sure remote is at back
209			if (data.remote) {
210				param = data.remote;
211				delete data.remote;
212				data = $.extend(data, { remote: param });
213			}
214
215			return data;
216		}
217	});
218
219	// JQuery trim is deprecated, provide a trim method based on String.prototype.trim
220	var trim = function (str) {
221
222		// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim#Polyfill
223		return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
224	};
225
226	// Custom selectors
227	$.extend($.expr.pseudos || $.expr[":"], {		// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
228
229		// https://jqueryvalidation.org/blank-selector/
230		blank: function (a) {
231			return !trim("" + $(a).val());
232		},
233
234		// https://jqueryvalidation.org/filled-selector/
235		filled: function (a) {
236			var val = $(a).val();
237			return val !== null && !!trim("" + val);
238		},
239
240		// https://jqueryvalidation.org/unchecked-selector/
241		unchecked: function (a) {
242			return !$(a).prop("checked");
243		}
244	});
245
246	// Constructor for validator
247	$.validator = function (options, form) {
248		this.settings = $.extend(true, {}, $.validator.defaults, options);
249		this.currentForm = form;
250		this.init();
251	};
252
253	// https://jqueryvalidation.org/jQuery.validator.format/
254	$.validator.format = function (source, params) {
255		if (arguments.length === 1) {
256			return function () {
257				var args = $.makeArray(arguments);
258				args.unshift(source);
259				return $.validator.format.apply(this, args);
260			};
261		}
262		if (params === undefined) {
263			return source;
264		}
265		if (arguments.length > 2 && params.constructor !== Array) {
266			params = $.makeArray(arguments).slice(1);
267		}
268		if (params.constructor !== Array) {
269			params = [params];
270		}
271		$.each(params, function (i, n) {
272			source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () {
273				return n;
274			});
275		});
276		return source;
277	};
278
279	$.extend($.validator, {
280
281		defaults: {
282			messages: {},
283			groups: {},
284			rules: {},
285			errorClass: "error",
286			pendingClass: "pending",
287			validClass: "valid",
288			errorElement: "label",
289			focusCleanup: false,
290			focusInvalid: true,
291			errorContainer: $([]),
292			errorLabelContainer: $([]),
293			onsubmit: true,
294			ignore: ":hidden",
295			ignoreTitle: false,
296			customElements: [],
297			onfocusin: function (element) {
298				this.lastActive = element;
299
300				// Hide error label and remove error class on focus if enabled
301				if (this.settings.focusCleanup) {
302					if (this.settings.unhighlight) {
303						this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass);
304					}
305					this.hideThese(this.errorsFor(element));
306				}
307			},
308			onfocusout: function (element) {
309				if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) {
310					this.element(element);
311				}
312			},
313			onkeyup: function (element, event) {
314
315				// Avoid revalidate the field when pressing one of the following keys
316				// Shift       => 16
317				// Ctrl        => 17
318				// Alt         => 18
319				// Caps lock   => 20
320				// End         => 35
321				// Home        => 36
322				// Left arrow  => 37
323				// Up arrow    => 38
324				// Right arrow => 39
325				// Down arrow  => 40
326				// Insert      => 45
327				// Num lock    => 144
328				// AltGr key   => 225
329				var excludedKeys = [
330					16, 17, 18, 20, 35, 36, 37,
331					38, 39, 40, 45, 144, 225
332				];
333
334				if (event.which === 9 && this.elementValue(element) === "" || $.inArray(event.keyCode, excludedKeys) !== -1) {
335					return;
336				} else if (element.name in this.submitted || element.name in this.invalid) {
337					this.element(element);
338				}
339			},
340			onclick: function (element) {
341
342				// Click on selects, radiobuttons and checkboxes
343				if (element.name in this.submitted) {
344					this.element(element);
345
346					// Or option elements, check parent select in that case
347				} else if (element.parentNode.name in this.submitted) {
348					this.element(element.parentNode);
349				}
350			},
351			highlight: function (element, errorClass, validClass) {
352				if (element.type === "radio") {
353					this.findByName(element.name).addClass(errorClass).removeClass(validClass);
354				} else {
355					$(element).addClass(errorClass).removeClass(validClass);
356				}
357			},
358			unhighlight: function (element, errorClass, validClass) {
359				if (element.type === "radio") {
360					this.findByName(element.name).removeClass(errorClass).addClass(validClass);
361				} else {
362					$(element).removeClass(errorClass).addClass(validClass);
363				}
364			}
365		},
366
367		// https://jqueryvalidation.org/jQuery.validator.setDefaults/
368		setDefaults: function (settings) {
369			$.extend($.validator.defaults, settings);
370		},
371
372		messages: {
373			required: "This field is required.",
374			remote: "Please fix this field.",
375			email: "Please enter a valid email address.",
376			url: "Please enter a valid URL.",
377			date: "Please enter a valid date.",
378			dateISO: "Please enter a valid date (ISO).",
379			number: "Please enter a valid number.",
380			digits: "Please enter only digits.",
381			equalTo: "Please enter the same value again.",
382			maxlength: $.validator.format("Please enter no more than {0} characters."),
383			minlength: $.validator.format("Please enter at least {0} characters."),
384			rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
385			range: $.validator.format("Please enter a value between {0} and {1}."),
386			max: $.validator.format("Please enter a value less than or equal to {0}."),
387			min: $.validator.format("Please enter a value greater than or equal to {0}."),
388			step: $.validator.format("Please enter a multiple of {0}.")
389		},
390
391		autoCreateRanges: false,
392
393		prototype: {
394
395			init: function () {
396				this.labelContainer = $(this.settings.errorLabelContainer);
397				this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
398				this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer);
399				this.submitted = {};
400				this.valueCache = {};
401				this.pendingRequest = 0;
402				this.pending = {};
403				this.invalid = {};
404				this.reset();
405
406				var currentForm = this.currentForm,
407					groups = (this.groups = {}),
408					rules;
409				$.each(this.settings.groups, function (key, value) {
410					if (typeof value === "string") {
411						value = value.split(/\s/);
412					}
413					$.each(value, function (index, name) {
414						groups[name] = key;
415					});
416				});
417				rules = this.settings.rules;
418				$.each(rules, function (key, value) {
419					rules[key] = $.validator.normalizeRule(value);
420				});
421
422				function delegate(event) {
423					var isContentEditable = typeof $(this).attr("contenteditable") !== "undefined" && $(this).attr("contenteditable") !== "false";
424
425					// Set form expando on contenteditable
426					if (!this.form && isContentEditable) {
427						this.form = $(this).closest("form")[0];
428						this.name = $(this).attr("name");
429					}
430
431					// Ignore the element if it belongs to another form. This will happen mainly
432					// when setting the `form` attribute of an input to the id of another form.
433					if (currentForm !== this.form) {
434						return;
435					}
436
437					var validator = $.data(this.form, "validator"),
438						eventType = "on" + event.type.replace(/^validate/, ""),
439						settings = validator.settings;
440					if (settings[eventType] && !$(this).is(settings.ignore)) {
441						settings[eventType].call(validator, this, event);
442					}
443				}
444				var focusListeners = [":text", "[type='password']", "[type='file']", "select", "textarea", "[type='number']", "[type='search']",
445					"[type='tel']", "[type='url']", "[type='email']", "[type='datetime']", "[type='date']", "[type='month']",
446					"[type='week']", "[type='time']", "[type='datetime-local']", "[type='range']", "[type='color']",
447					"[type='radio']", "[type='checkbox']", "[contenteditable]", "[type='button']"];
448				var clickListeners = ["select", "option", "[type='radio']", "[type='checkbox']"];
449				$(this.currentForm)
450					.on("focusin.validate focusout.validate keyup.validate", focusListeners.concat(this.settings.customElements).join(", "), delegate)
451
452					// Support: Chrome, oldIE
453					// "select" is provided as event.target when clicking a option
454					.on("click.validate", clickListeners.concat(this.settings.customElements).join(", "), delegate);
455
456				if (this.settings.invalidHandler) {
457					$(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler);
458				}
459			},
460
461			// https://jqueryvalidation.org/Validator.form/
462			form: function () {
463				this.checkForm();
464				$.extend(this.submitted, this.errorMap);
465				this.invalid = $.extend({}, this.errorMap);
466				if (!this.valid()) {
467					$(this.currentForm).triggerHandler("invalid-form", [this]);
468				}
469				this.showErrors();
470				return this.valid();
471			},
472
473			checkForm: function () {
474				this.prepareForm();
475				for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) {
476					this.check(elements[i]);
477				}
478				return this.valid();
479			},
480
481			// https://jqueryvalidation.org/Validator.element/
482			element: function (element) {
483				var cleanElement = this.clean(element),
484					checkElement = this.validationTargetFor(cleanElement),
485					v = this,
486					result = true,
487					rs, group;
488
489				if (checkElement === undefined) {
490					delete this.invalid[cleanElement.name];
491				} else {
492					this.prepareElement(checkElement);
493					this.currentElements = $(checkElement);
494
495					// If this element is grouped, then validate all group elements already
496					// containing a value
497					group = this.groups[checkElement.name];
498					if (group) {
499						$.each(this.groups, function (name, testgroup) {
500							if (testgroup === group && name !== checkElement.name) {
501								cleanElement = v.validationTargetFor(v.clean(v.findByName(name)));
502								if (cleanElement && cleanElement.name in v.invalid) {
503									v.currentElements.push(cleanElement);
504									result = v.check(cleanElement) && result;
505								}
506							}
507						});
508					}
509
510					rs = this.check(checkElement) !== false;
511					result = result && rs;
512					if (rs) {
513						this.invalid[checkElement.name] = false;
514					} else {
515						this.invalid[checkElement.name] = true;
516					}
517
518					if (!this.numberOfInvalids()) {
519
520						// Hide error containers on last error
521						this.toHide = this.toHide.add(this.containers);
522					}
523					this.showErrors();
524
525					// Add aria-invalid status for screen readers
526					$(element).attr("aria-invalid", !rs);
527				}
528
529				return result;
530			},
531
532			// https://jqueryvalidation.org/Validator.showErrors/
533			showErrors: function (errors) {
534				if (errors) {
535					var validator = this;
536
537					// Add items to error list and map
538					$.extend(this.errorMap, errors);
539					this.errorList = $.map(this.errorMap, function (message, name) {
540						return {
541							message: message,
542							element: validator.findByName(name)[0]
543						};
544					});
545
546					// Remove items from success list
547					this.successList = $.grep(this.successList, function (element) {
548						return !(element.name in errors);
549					});
550				}
551				if (this.settings.showErrors) {
552					this.settings.showErrors.call(this, this.errorMap, this.errorList);
553				} else {
554					this.defaultShowErrors();
555				}
556			},
557
558			// https://jqueryvalidation.org/Validator.resetForm/
559			resetForm: function () {
560				if ($.fn.resetForm) {
561					$(this.currentForm).resetForm();
562				}
563				this.invalid = {};
564				this.submitted = {};
565				this.prepareForm();
566				this.hideErrors();
567				var elements = this.elements()
568					.removeData("previousValue")
569					.removeAttr("aria-invalid");
570
571				this.resetElements(elements);
572			},
573
574			resetElements: function (elements) {
575				var i;
576
577				if (this.settings.unhighlight) {
578					for (i = 0; elements[i]; i++) {
579						this.settings.unhighlight.call(this, elements[i],
580							this.settings.errorClass, "");
581						this.findByName(elements[i].name).removeClass(this.settings.validClass);
582					}
583				} else {
584					elements
585						.removeClass(this.settings.errorClass)
586						.removeClass(this.settings.validClass);
587				}
588			},
589
590			numberOfInvalids: function () {
591				return this.objectLength(this.invalid);
592			},
593
594			objectLength: function (obj) {
595				/* jshint unused: false */
596				var count = 0,
597					i;
598				for (i in obj) {
599
600					// This check allows counting elements with empty error
601					// message as invalid elements
602					if (obj[i] !== undefined && obj[i] !== null && obj[i] !== false) {
603						count++;
604					}
605				}
606				return count;
607			},
608
609			hideErrors: function () {
610				this.hideThese(this.toHide);
611			},
612
613			hideThese: function (errors) {
614				errors.not(this.containers).text("");
615				this.addWrapper(errors).hide();
616			},
617
618			valid: function () {
619				return this.size() === 0;
620			},
621
622			size: function () {
623				return this.errorList.length;
624			},
625
626			focusInvalid: function () {
627				if (this.settings.focusInvalid) {
628					try {
629						$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
630							.filter(":visible")
631							.trigger("focus")
632
633							// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
634							.trigger("focusin");
635					} catch (e) {
636
637						// Ignore IE throwing errors when focusing hidden elements
638					}
639				}
640			},
641
642			findLastActive: function () {
643				var lastActive = this.lastActive;
644				return lastActive && $.grep(this.errorList, function (n) {
645					return n.element.name === lastActive.name;
646				}).length === 1 && lastActive;
647			},
648
649			elements: function () {
650				var validator = this,
651					rulesCache = {},
652					selectors = ["input", "select", "textarea", "[contenteditable]"];
653
654				// Select all valid inputs inside the form (no submit or reset buttons)
655				return $(this.currentForm)
656					.find(selectors.concat(this.settings.customElements).join(", "))
657					.not(":submit, :reset, :image, :disabled")
658					.not(this.settings.ignore)
659					.filter(function () {
660						var name = this.name || $(this).attr("name"); // For contenteditable
661						var isContentEditable = typeof $(this).attr("contenteditable") !== "undefined" && $(this).attr("contenteditable") !== "false";
662
663						if (!name && validator.settings.debug && window.console) {
664							console.error("%o has no name assigned", this);
665						}
666
667						// Set form expando on contenteditable
668						if (isContentEditable) {
669							this.form = $(this).closest("form")[0];
670							this.name = name;
671						}
672
673						// Ignore elements that belong to other/nested forms
674						if (this.form !== validator.currentForm) {
675							return false;
676						}
677
678						// Select only the first element for each name, and only those with rules specified
679						if (name in rulesCache || !validator.objectLength($(this).rules())) {
680							return false;
681						}
682
683						rulesCache[name] = true;
684						return true;
685					});
686			},
687
688			clean: function (selector) {
689				return $(selector)[0];
690			},
691
692			errors: function () {
693				var errorClass = this.settings.errorClass.split(" ").join(".");
694				return $(this.settings.errorElement + "." + errorClass, this.errorContext);
695			},
696
697			resetInternals: function () {
698				this.successList = [];
699				this.errorList = [];
700				this.errorMap = {};
701				this.toShow = $([]);
702				this.toHide = $([]);
703			},
704
705			reset: function () {
706				this.resetInternals();
707				this.currentElements = $([]);
708			},
709
710			prepareForm: function () {
711				this.reset();
712				this.toHide = this.errors().add(this.containers);
713			},
714
715			prepareElement: function (element) {
716				this.reset();
717				this.toHide = this.errorsFor(element);
718			},
719
720			elementValue: function (element) {
721				var $element = $(element),
722					type = element.type,
723					isContentEditable = typeof $element.attr("contenteditable") !== "undefined" && $element.attr("contenteditable") !== "false",
724					val, idx;
725
726				if (type === "radio" || type === "checkbox") {
727					return this.findByName(element.name).filter(":checked").val();
728				} else if (type === "number" && typeof element.validity !== "undefined") {
729					return element.validity.badInput ? "NaN" : $element.val();
730				}
731
732				if (isContentEditable) {
733					val = $element.text();
734				} else {
735					val = $element.val();
736				}
737
738				if (type === "file") {
739
740					// Modern browser (chrome & safari)
741					if (val.substr(0, 12) === "C:\\fakepath\\") {
742						return val.substr(12);
743					}
744
745					// Legacy browsers
746					// Unix-based path
747					idx = val.lastIndexOf("/");
748					if (idx >= 0) {
749						return val.substr(idx + 1);
750					}
751
752					// Windows-based path
753					idx = val.lastIndexOf("\\");
754					if (idx >= 0) {
755						return val.substr(idx + 1);
756					}
757
758					// Just the file name
759					return val;
760				}
761
762				if (typeof val === "string") {
763					return val.replace(/\r/g, "");
764				}
765				return val;
766			},
767
768			check: function (element) {
769				element = this.validationTargetFor(this.clean(element));
770
771				var rules = $(element).rules(),
772					rulesCount = $.map(rules, function (n, i) {
773						return i;
774					}).length,
775					dependencyMismatch = false,
776					val = this.elementValue(element),
777					result, method, rule, normalizer;
778
779				// Abort any pending Ajax request from a previous call to this method.
780				this.abortRequest(element);
781
782				// Prioritize the local normalizer defined for this element over the global one
783				// if the former exists, otherwise user the global one in case it exists.
784				if (typeof rules.normalizer === "function") {
785					normalizer = rules.normalizer;
786				} else if (typeof this.settings.normalizer === "function") {
787					normalizer = this.settings.normalizer;
788				}
789
790				// If normalizer is defined, then call it to retreive the changed value instead
791				// of using the real one.
792				// Note that `this` in the normalizer is `element`.
793				if (normalizer) {
794					val = normalizer.call(element, val);
795
796					// Delete the normalizer from rules to avoid treating it as a pre-defined method.
797					delete rules.normalizer;
798				}
799
800				for (method in rules) {
801					rule = { method: method, parameters: rules[method] };
802					try {
803						result = $.validator.methods[method].call(this, val, element, rule.parameters);
804
805						// If a method indicates that the field is optional and therefore valid,
806						// don't mark it as valid when there are no other rules
807						if (result === "dependency-mismatch" && rulesCount === 1) {
808							dependencyMismatch = true;
809							continue;
810						}
811						dependencyMismatch = false;
812
813						if (result === "pending") {
814							this.toHide = this.toHide.not(this.errorsFor(element));
815							return;
816						}
817
818						if (!result) {
819							this.formatAndAdd(element, rule);
820							return false;
821						}
822					} catch (e) {
823						if (this.settings.debug && window.console) {
824							console.log("Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e);
825						}
826						if (e instanceof TypeError) {
827							e.message += ".  Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
828						}
829
830						throw e;
831					}
832				}
833				if (dependencyMismatch) {
834					return;
835				}
836				if (this.objectLength(rules)) {
837					this.successList.push(element);
838				}
839				return true;
840			},
841
842			// Return the custom message for the given element and validation method
843			// specified in the element's HTML5 data attribute
844			// return the generic message if present and no method specific message is present
845			customDataMessage: function (element, method) {
846				return $(element).data("msg" + method.charAt(0).toUpperCase() +
847					method.substring(1).toLowerCase()) || $(element).data("msg");
848			},
849
850			// Return the custom message for the given element name and validation method
851			customMessage: function (name, method) {
852				var m = this.settings.messages[name];
853				return m && (m.constructor === String ? m : m[method]);
854			},
855
856			// Return the first defined argument, allowing empty strings
857			findDefined: function () {
858				for (var i = 0; i < arguments.length; i++) {
859					if (arguments[i] !== undefined) {
860						return arguments[i];
861					}
862				}
863				return undefined;
864			},
865
866			// The second parameter 'rule' used to be a string, and extended to an object literal
867			// of the following form:
868			// rule = {
869			//     method: "method name",
870			//     parameters: "the given method parameters"
871			// }
872			//
873			// The old behavior still supported, kept to maintain backward compatibility with
874			// old code, and will be removed in the next major release.
875			defaultMessage: function (element, rule) {
876				if (typeof rule === "string") {
877					rule = { method: rule };
878				}
879
880				var message = this.findDefined(
881					this.customMessage(element.name, rule.method),
882					this.customDataMessage(element, rule.method),
883
884					// 'title' is never undefined, so handle empty string as undefined
885					!this.settings.ignoreTitle && element.title || undefined,
886					$.validator.messages[rule.method],
887					"<strong>Warning: No message defined for " + element.name + "</strong>"
888				),
889					theregex = /\$?\{(\d+)\}/g;
890				if (typeof message === "function") {
891					message = message.call(this, rule.parameters, element);
892				} else if (theregex.test(message)) {
893					message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
894				}
895
896				return message;
897			},
898
899			formatAndAdd: function (element, rule) {
900				var message = this.defaultMessage(element, rule);
901
902				this.errorList.push({
903					message: message,
904					element: element,
905					method: rule.method
906				});
907
908				this.errorMap[element.name] = message;
909				this.submitted[element.name] = message;
910			},
911
912			addWrapper: function (toToggle) {
913				if (this.settings.wrapper) {
914					toToggle = toToggle.add(toToggle.parent(this.settings.wrapper));
915				}
916				return toToggle;
917			},
918
919			defaultShowErrors: function () {
920				var i, elements, error;
921				for (i = 0; this.errorList[i]; i++) {
922					error = this.errorList[i];
923					if (this.settings.highlight) {
924						this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass);
925					}
926					this.showLabel(error.element, error.message);
927				}
928				if (this.errorList.length) {
929					this.toShow = this.toShow.add(this.containers);
930				}
931				if (this.settings.success) {
932					for (i = 0; this.successList[i]; i++) {
933						this.showLabel(this.successList[i]);
934					}
935				}
936				if (this.settings.unhighlight) {
937					for (i = 0, elements = this.validElements(); elements[i]; i++) {
938						this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass);
939					}
940				}
941				this.toHide = this.toHide.not(this.toShow);
942				this.hideErrors();
943				this.addWrapper(this.toShow).show();
944			},
945
946			validElements: function () {
947				return this.currentElements.not(this.invalidElements());
948			},
949
950			invalidElements: function () {
951				return $(this.errorList).map(function () {
952					return this.element;
953				});
954			},
955
956			showLabel: function (element, message) {
957				var place, group, errorID, v,
958					error = this.errorsFor(element),
959					elementID = this.idOrName(element),
960					describedBy = $(element).attr("aria-describedby");
961
962				if (error.length) {
963
964					// Refresh error/success class
965					error.removeClass(this.settings.validClass).addClass(this.settings.errorClass);
966
967					// Replace message on existing label
968					if (this.settings && this.settings.escapeHtml) {
969						error.text(message || "");
970					} else {
971						error.html(message || "");
972					}
973				} else {
974
975					// Create error element
976					error = $("<" + this.settings.errorElement + ">")
977						.attr("id", elementID + "-error")
978						.addClass(this.settings.errorClass);
979
980					if (this.settings && this.settings.escapeHtml) {
981						error.text(message || "");
982					} else {
983						error.html(message || "");
984					}
985
986					// Maintain reference to the element to be placed into the DOM
987					place = error;
988					if (this.settings.wrapper) {
989
990						// Make sure the element is visible, even in IE
991						// actually showing the wrapped element is handled elsewhere
992						place = error.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
993					}
994					if (this.labelContainer.length) {
995						this.labelContainer.append(place);
996					} else if (this.settings.errorPlacement) {
997						this.settings.errorPlacement.call(this, place, $(element));
998					} else {
999						place.insertAfter(element);
1000					}
1001
1002					// Link error back to the element
1003					if (error.is("label")) {
1004
1005						// If the error is a label, then associate using 'for'
1006						error.attr("for", elementID);
1007
1008						// If the element is not a child of an associated label, then it's necessary
1009						// to explicitly apply aria-describedby
1010					} else if (error.parents("label[for='" + this.escapeCssMeta(elementID) + "']").length === 0) {
1011						errorID = error.attr("id");
1012
1013						// Respect existing non-error aria-describedby
1014						if (!describedBy) {
1015							describedBy = errorID;
1016						} else if (!describedBy.match(new RegExp("\\b" + this.escapeCssMeta(errorID) + "\\b"))) {
1017
1018							// Add to end of list if not already present
1019							describedBy += " " + errorID;
1020						}
1021						$(element).attr("aria-describedby", describedBy);
1022
1023						// If this element is grouped, then assign to all elements in the same group
1024						group = this.groups[element.name];
1025						if (group) {
1026							v = this;
1027							$.each(v.groups, function (name, testgroup) {
1028								if (testgroup === group) {
1029									$("[name='" + v.escapeCssMeta(name) + "']", v.currentForm)
1030										.attr("aria-describedby", error.attr("id"));
1031								}
1032							});
1033						}
1034					}
1035				}
1036				if (!message && this.settings.success) {
1037					error.text("");
1038					if (typeof this.settings.success === "string") {
1039						error.addClass(this.settings.success);
1040					} else {
1041						this.settings.success(error, element);
1042					}
1043				}
1044				this.toShow = this.toShow.add(error);
1045			},
1046
1047			errorsFor: function (element) {
1048				var name = this.escapeCssMeta(this.idOrName(element)),
1049					describer = $(element).attr("aria-describedby"),
1050					selector = "label[for='" + name + "'], label[for='" + name + "'] *";
1051
1052				// 'aria-describedby' should directly reference the error element
1053				if (describer) {
1054					selector = selector + ", #" + this.escapeCssMeta(describer)
1055						.replace(/\s+/g, ", #");
1056				}
1057
1058				return this
1059					.errors()
1060					.filter(selector);
1061			},
1062
1063			// See https://api.jquery.com/category/selectors/, for CSS
1064			// meta-characters that should be escaped in order to be used with JQuery
1065			// as a literal part of a name/id or any selector.
1066			escapeCssMeta: function (string) {
1067				if (string === undefined) {
1068					return "";
1069				}
1070
1071				return string.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1");
1072			},
1073
1074			idOrName: function (element) {
1075				return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
1076			},
1077
1078			validationTargetFor: function (element) {
1079
1080				// If radio/checkbox, validate first element in group instead
1081				if (this.checkable(element)) {
1082					element = this.findByName(element.name);
1083				}
1084
1085				// Always apply ignore filter
1086				return $(element).not(this.settings.ignore)[0];
1087			},
1088
1089			checkable: function (element) {
1090				return (/radio|checkbox/i).test(element.type);
1091			},
1092
1093			findByName: function (name) {
1094				return $(this.currentForm).find("[name='" + this.escapeCssMeta(name) + "']");
1095			},
1096
1097			getLength: function (value, element) {
1098				switch (element.nodeName.toLowerCase()) {
1099					case "select":
1100						return $("option:selected", element).length;
1101					case "input":
1102						if (this.checkable(element)) {
1103							return this.findByName(element.name).filter(":checked").length;
1104						}
1105				}
1106				return value.length;
1107			},
1108
1109			depend: function (param, element) {
1110				return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
1111			},
1112
1113			dependTypes: {
1114				"boolean": function (param) {
1115					return param;
1116				},
1117				"string": function (param, element) {
1118					return !!$(param, element.form).length;
1119				},
1120				"function": function (param, element) {
1121					return param(element);
1122				}
1123			},
1124
1125			optional: function (element) {
1126				var val = this.elementValue(element);
1127				return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
1128			},
1129
1130			elementAjaxPort: function (element) {
1131				return "validate" + element.name;
1132			},
1133
1134			startRequest: function (element) {
1135				if (!this.pending[element.name]) {
1136					this.pendingRequest++;
1137					$(element).addClass(this.settings.pendingClass);
1138					this.pending[element.name] = true;
1139				}
1140			},
1141
1142			stopRequest: function (element, valid) {
1143				this.pendingRequest--;
1144
1145				// Sometimes synchronization fails, make sure pendingRequest is never < 0
1146				if (this.pendingRequest < 0) {
1147					this.pendingRequest = 0;
1148				}
1149				delete this.pending[element.name];
1150				$(element).removeClass(this.settings.pendingClass);
1151				if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0) {
1152					$(this.currentForm).trigger("submit");
1153
1154					// Remove the hidden input that was used as a replacement for the
1155					// missing submit button. The hidden input is added by `handle()`
1156					// to ensure that the value of the used submit button is passed on
1157					// for scripted submits triggered by this method
1158					if (this.submitButton) {
1159						$("input:hidden[name='" + this.submitButton.name + "']", this.currentForm).remove();
1160					}
1161
1162					this.formSubmitted = false;
1163				} else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
1164					$(this.currentForm).triggerHandler("invalid-form", [this]);
1165					this.formSubmitted = false;
1166				}
1167			},
1168
1169			abortRequest: function (element) {
1170				var port;
1171
1172				if (this.pending[element.name]) {
1173					port = this.elementAjaxPort(element);
1174					$.ajaxAbort(port);
1175
1176					this.pendingRequest--;
1177
1178					// Sometimes synchronization fails, make sure pendingRequest is never < 0
1179					if (this.pendingRequest < 0) {
1180						this.pendingRequest = 0;
1181					}
1182
1183					delete this.pending[element.name];
1184					$(element).removeClass(this.settings.pendingClass);
1185				}
1186			},
1187
1188			previousValue: function (element, method) {
1189				method = typeof method === "string" && method || "remote";
1190
1191				return $.data(element, "previousValue") || $.data(element, "previousValue", {
1192					old: null,
1193					valid: true,
1194					message: this.defaultMessage(element, { method: method })
1195				});
1196			},
1197
1198			// Cleans up all forms and elements, removes validator-specific events
1199			destroy: function () {
1200				this.resetForm();
1201
1202				$(this.currentForm)
1203					.off(".validate")
1204					.removeData("validator")
1205					.find(".validate-equalTo-blur")
1206					.off(".validate-equalTo")
1207					.removeClass("validate-equalTo-blur")
1208					.find(".validate-lessThan-blur")
1209					.off(".validate-lessThan")
1210					.removeClass("validate-lessThan-blur")
1211					.find(".validate-lessThanEqual-blur")
1212					.off(".validate-lessThanEqual")
1213					.removeClass("validate-lessThanEqual-blur")
1214					.find(".validate-greaterThanEqual-blur")
1215					.off(".validate-greaterThanEqual")
1216					.removeClass("validate-greaterThanEqual-blur")
1217					.find(".validate-greaterThan-blur")
1218					.off(".validate-greaterThan")
1219					.removeClass("validate-greaterThan-blur");
1220			}
1221
1222		},
1223
1224		classRuleSettings: {
1225			required: { required: true },
1226			email: { email: true },
1227			url: { url: true },
1228			date: { date: true },
1229			dateISO: { dateISO: true },
1230			number: { number: true },
1231			digits: { digits: true },
1232			creditcard: { creditcard: true }
1233		},
1234
1235		addClassRules: function (className, rules) {
1236			if (className.constructor === String) {
1237				this.classRuleSettings[className] = rules;
1238			} else {
1239				$.extend(this.classRuleSettings, className);
1240			}
1241		},
1242
1243		classRules: function (element) {
1244			var rules = {},
1245				classes = $(element).attr("class");
1246
1247			if (classes) {
1248				$.each(classes.split(" "), function () {
1249					if (this in $.validator.classRuleSettings) {
1250						$.extend(rules, $.validator.classRuleSettings[this]);
1251					}
1252				});
1253			}
1254			return rules;
1255		},
1256
1257		normalizeAttributeRule: function (rules, type, method, value) {
1258
1259			// Convert the value to a number for number inputs, and for text for backwards compability
1260			// allows type="date" and others to be compared as strings
1261			if (/min|max|step/.test(method) && (type === null || /number|range|text/.test(type))) {
1262				value = Number(value);
1263
1264				// Support Opera Mini, which returns NaN for undefined minlength
1265				if (isNaN(value)) {
1266					value = undefined;
1267				}
1268			}
1269
1270			if (value || value === 0) {
1271				rules[method] = value;
1272			} else if (type === method && type !== "range") {
1273
1274				// Exception: the jquery validate 'range' method
1275				// does not test for the html5 'range' type
1276				rules[type === "date" ? "dateISO" : method] = true;
1277			}
1278		},
1279
1280		attributeRules: function (element) {
1281			var rules = {},
1282				$element = $(element),
1283				type = element.getAttribute("type"),
1284				method, value;
1285
1286			for (method in $.validator.methods) {
1287
1288				// Support for <input required> in both html5 and older browsers
1289				if (method === "required") {
1290					value = element.getAttribute(method);
1291
1292					// Some browsers return an empty string for the required attribute
1293					// and non-HTML5 browsers might have required="" markup
1294					if (value === "") {
1295						value = true;
1296					}
1297
1298					// Force non-HTML5 browsers to return bool
1299					value = !!value;
1300				} else {
1301					value = $element.attr(method);
1302				}
1303
1304				this.normalizeAttributeRule(rules, type, method, value);
1305			}
1306
1307			// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
1308			if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
1309				delete rules.maxlength;
1310			}
1311
1312			return rules;
1313		},
1314
1315		dataRules: function (element) {
1316			var rules = {},
1317				$element = $(element),
1318				type = element.getAttribute("type"),
1319				method, value;
1320
1321			for (method in $.validator.methods) {
1322				value = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase());
1323
1324				// Cast empty attributes like `data-rule-required` to `true`
1325				if (value === "") {
1326					value = true;
1327				}
1328
1329				this.normalizeAttributeRule(rules, type, method, value);
1330			}
1331			return rules;
1332		},
1333
1334		staticRules: function (element) {
1335			var rules = {},
1336				validator = $.data(element.form, "validator");
1337
1338			if (validator.settings.rules) {
1339				rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
1340			}
1341			return rules;
1342		},
1343
1344		normalizeRules: function (rules, element) {
1345
1346			// Handle dependency check
1347			$.each(rules, function (prop, val) {
1348
1349				// Ignore rule when param is explicitly false, eg. required:false
1350				if (val === false) {
1351					delete rules[prop];
1352					return;
1353				}
1354				if (val.param || val.depends) {
1355					var keepRule = true;
1356					switch (typeof val.depends) {
1357						case "string":
1358							keepRule = !!$(val.depends, element.form).length;
1359							break;
1360						case "function":
1361							keepRule = val.depends.call(element, element);
1362							break;
1363					}
1364					if (keepRule) {
1365						rules[prop] = val.param !== undefined ? val.param : true;
1366					} else {
1367						$.data(element.form, "validator").resetElements($(element));
1368						delete rules[prop];
1369					}
1370				}
1371			});
1372
1373			// Evaluate parameters
1374			$.each(rules, function (rule, parameter) {
1375				rules[rule] = typeof parameter === "function" && rule !== "normalizer" ? parameter(element) : parameter;
1376			});
1377
1378			// Clean number parameters
1379			$.each(["minlength", "maxlength"], function () {
1380				if (rules[this]) {
1381					rules[this] = Number(rules[this]);
1382				}
1383			});
1384			$.each(["rangelength", "range"], function () {
1385				var parts;
1386				if (rules[this]) {
1387					if (Array.isArray(rules[this])) {
1388						rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
1389					} else if (typeof rules[this] === "string") {
1390						parts = rules[this].replace(/[\[\]]/g, "").split(/[\s,]+/);
1391						rules[this] = [Number(parts[0]), Number(parts[1])];
1392					}
1393				}
1394			});
1395
1396			if ($.validator.autoCreateRanges) {
1397
1398				// Auto-create ranges
1399				if (rules.min != null && rules.max != null) {
1400					rules.range = [rules.min, rules.max];
1401					delete rules.min;
1402					delete rules.max;
1403				}
1404				if (rules.minlength != null && rules.maxlength != null) {
1405					rules.rangelength = [rules.minlength, rules.maxlength];
1406					delete rules.minlength;
1407					delete rules.maxlength;
1408				}
1409			}
1410
1411			return rules;
1412		},
1413
1414		// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
1415		normalizeRule: function (data) {
1416			if (typeof data === "string") {
1417				var transformed = {};
1418				$.each(data.split(/\s/), function () {
1419					transformed[this] = true;
1420				});
1421				data = transformed;
1422			}
1423			return data;
1424		},
1425
1426		// https://jqueryvalidation.org/jQuery.validator.addMethod/
1427		addMethod: function (name, method, message) {
1428			$.validator.methods[name] = method;
1429			$.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
1430			if (method.length < 3) {
1431				$.validator.addClassRules(name, $.validator.normalizeRule(name));
1432			}
1433		},
1434
1435		// https://jqueryvalidation.org/jQuery.validator.methods/
1436		methods: {
1437
1438			// https://jqueryvalidation.org/required-method/
1439			required: function (value, element, param) {
1440
1441				// Check if dependency is met
1442				if (!this.depend(param, element)) {
1443					return "dependency-mismatch";
1444				}
1445				if (element.nodeName.toLowerCase() === "select") {
1446
1447					// Could be an array for select-multiple or a string, both are fine this way
1448					var val = $(element).val();
1449					return val && val.length > 0;
1450				}
1451				if (this.checkable(element)) {
1452					return this.getLength(value, element) > 0;
1453				}
1454				return value !== undefined && value !== null && value.length > 0;
1455			},
1456
1457			// https://jqueryvalidation.org/email-method/
1458			email: function (value, element) {
1459
1460				// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
1461				// Retrieved 2014-01-14
1462				// If you have a problem with this implementation, report a bug against the above spec
1463				// Or use custom methods to implement your own email validation
1464				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);
1465			},
1466
1467			// https://jqueryvalidation.org/url-method/
1468			url: function (value, element) {
1469
1470				// Copyright (c) 2010-2013 Diego Perini, MIT licensed
1471				// https://gist.github.com/dperini/729294
1472				// see also https://mathiasbynens.be/demo/url-regex
1473				// modified to allow protocol-relative URLs
1474				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);
1475			},
1476
1477			// https://jqueryvalidation.org/date-method/
1478			date: (function () {
1479				var called = false;
1480
1481				return function (value, element) {
1482					if (!called) {
1483						called = true;
1484						if (this.settings.debug && window.console) {
1485							console.warn(
1486								"The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
1487								"Please don't use it, since it relies on the Date constructor, which\n" +
1488								"behaves very differently across browsers and locales. Use `dateISO`\n" +
1489								"instead or one of the locale specific methods in `localizations/`\n" +
1490								"and `additional-methods.js`."
1491							);
1492						}
1493					}
1494
1495					return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1496				};
1497			}()),
1498
1499			// https://jqueryvalidation.org/dateISO-method/
1500			dateISO: function (value, element) {
1501				return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);
1502			},
1503
1504			// https://jqueryvalidation.org/number-method/
1505			number: function (value, element) {
1506				return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:-?\.\d+)?$/.test(value);
1507			},
1508
1509			// https://jqueryvalidation.org/digits-method/
1510			digits: function (value, element) {
1511				return this.optional(element) || /^\d+$/.test(value);
1512			},
1513
1514			// https://jqueryvalidation.org/minlength-method/
1515			minlength: function (value, element, param) {
1516				var length = Array.isArray(value) ? value.length : this.getLength(value, element);
1517				return this.optional(element) || length >= param;
1518			},
1519
1520			// https://jqueryvalidation.org/maxlength-method/
1521			maxlength: function (value, element, param) {
1522				var length = Array.isArray(value) ? value.length : this.getLength(value, element);
1523				return this.optional(element) || length <= param;
1524			},
1525
1526			// https://jqueryvalidation.org/rangelength-method/
1527			rangelength: function (value, element, param) {
1528				var length = Array.isArray(value) ? value.length : this.getLength(value, element);
1529				return this.optional(element) || (length >= param[0] && length <= param[1]);
1530			},
1531
1532			// https://jqueryvalidation.org/min-method/
1533			min: function (value, element, param) {
1534				return this.optional(element) || value >= param;
1535			},
1536
1537			// https://jqueryvalidation.org/max-method/
1538			max: function (value, element, param) {
1539				return this.optional(element) || value <= param;
1540			},
1541
1542			// https://jqueryvalidation.org/range-method/
1543			range: function (value, element, param) {
1544				return this.optional(element) || (value >= param[0] && value <= param[1]);
1545			},
1546
1547			// https://jqueryvalidation.org/step-method/
1548			step: function (value, element, param) {
1549				var type = $(element).attr("type"),
1550					errorMessage = "Step attribute on input type " + type + " is not supported.",
1551					supportedTypes = ["text", "number", "range"],
1552					re = new RegExp("\\b" + type + "\\b"),
1553					notSupported = type && !re.test(supportedTypes.join()),
1554					decimalPlaces = function (num) {
1555						var match = ("" + num).match(/(?:\.(\d+))?$/);
1556						if (!match) {
1557							return 0;
1558						}
1559
1560						// Number of digits right of decimal point.
1561						return match[1] ? match[1].length : 0;
1562					},
1563					toInt = function (num) {
1564						return Math.round(num * Math.pow(10, decimals));
1565					},
1566					valid = true,
1567					decimals;
1568
1569				// Works only for text, number and range input types
1570				// TODO find a way to support input types date, datetime, datetime-local, month, time and week
1571				if (notSupported) {
1572					throw new Error(errorMessage);
1573				}
1574
1575				decimals = decimalPlaces(param);
1576
1577				// Value can't have too many decimals
1578				if (decimalPlaces(value) > decimals || toInt(value) % toInt(param) !== 0) {
1579					valid = false;
1580				}
1581
1582				return this.optional(element) || valid;
1583			},
1584
1585			// https://jqueryvalidation.org/equalTo-method/
1586			equalTo: function (value, element, param) {
1587
1588				// Bind to the blur event of the target in order to revalidate whenever the target field is updated
1589				var target = $(param);
1590				if (this.settings.onfocusout && target.not(".validate-equalTo-blur").length) {
1591					target.addClass("validate-equalTo-blur").on("blur.validate-equalTo", function () {
1592						$(element).valid();
1593					});
1594				}
1595				return value === target.val();
1596			},
1597
1598			// https://jqueryvalidation.org/remote-method/
1599			remote: function (value, element, param, method) {
1600				if (this.optional(element)) {
1601					return "dependency-mismatch";
1602				}
1603
1604				method = typeof method === "string" && method || "remote";
1605
1606				var previous = this.previousValue(element, method),
1607					validator, data, optionDataString;
1608
1609				if (!this.settings.messages[element.name]) {
1610					this.settings.messages[element.name] = {};
1611				}
1612				previous.originalMessage = previous.originalMessage || this.settings.messages[element.name][method];
1613				this.settings.messages[element.name][method] = previous.message;
1614
1615				param = typeof param === "string" && { url: param } || param;
1616				optionDataString = $.param($.extend({ data: value }, param.data));
1617				if (previous.valid !== null && previous.old === optionDataString) {
1618					return previous.valid;
1619				}
1620
1621				previous.old = optionDataString;
1622				previous.valid = null;
1623				validator = this;
1624				this.startRequest(element);
1625				data = {};
1626				data[element.name] = value;
1627				$.ajax($.extend(true, {
1628					mode: "abort",
1629					port: this.elementAjaxPort(element),
1630					dataType: "json",
1631					data: data,
1632					context: validator.currentForm,
1633					success: function (response) {
1634						var valid = response === true || response === "true",
1635							errors, message, submitted;
1636
1637						validator.settings.messages[element.name][method] = previous.originalMessage;
1638						if (valid) {
1639							submitted = validator.formSubmitted;
1640							validator.toHide = validator.errorsFor(element);
1641							validator.formSubmitted = submitted;
1642							validator.successList.push(element);
1643							validator.invalid[element.name] = false;
1644							validator.showErrors();
1645						} else {
1646							errors = {};
1647							message = response || validator.defaultMessage(element, { method: method, parameters: value });
1648							errors[element.name] = previous.message = message;
1649							validator.invalid[element.name] = true;
1650							validator.showErrors(errors);
1651						}
1652						previous.valid = valid;
1653						validator.stopRequest(element, valid);
1654					}
1655				}, param));
1656				return "pending";
1657			}
1658		}
1659
1660	});
1661
1662	// Ajax mode: abort
1663	// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1664	//        $.ajaxAbort( port );
1665	// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1666
1667	var pendingRequests = {},
1668		ajax;
1669
1670	// Use a prefilter if available (1.5+)
1671	if ($.ajaxPrefilter) {
1672		$.ajaxPrefilter(function (settings, _, xhr) {
1673			var port = settings.port;
1674			if (settings.mode === "abort") {
1675				$.ajaxAbort(port);
1676				pendingRequests[port] = xhr;
1677			}
1678		});
1679	} else {
1680
1681		// Proxy ajax
1682		ajax = $.ajax;
1683		$.ajax = function (settings) {
1684			var mode = ("mode" in settings ? settings : $.ajaxSettings).mode,
1685				port = ("port" in settings ? settings : $.ajaxSettings).port;
1686			if (mode === "abort") {
1687				$.ajaxAbort(port);
1688				pendingRequests[port] = ajax.apply(this, arguments);
1689				return pendingRequests[port];
1690			}
1691			return ajax.apply(this, arguments);
1692		};
1693	}
1694
1695	// Abort the previous request without sending a new one
1696	$.ajaxAbort = function (port) {
1697		if (pendingRequests[port]) {
1698			pendingRequests[port].abort();
1699			delete pendingRequests[port];
1700		}
1701	};
1702	return $;
1703}));

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.