PageSourceSearch

https://www.backsplash.com/wp-content/plugins/woocommerce-tm-extra…/assets/js/jquery.validate.js?ver=1.19.0

js backsplash.com collected 2026-09-25 23:40:54 UTC 53,669 bytes, 1,665 lines download raw bytes

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

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.