PageSourceSearch

https://apps.cnio.es/js/jquery.validate-1.17.js?v=1.5

js cnio.es collected 2026-10-02 02:35:09 UTC 50,568 bytes, 1,606 lines download raw bytes

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

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.