PageSourceSearch

https://www.onlinejima.com/assets/js/extlib/validation/validation.js

js onlinejima.com collected 2026-10-08 04:36:54 UTC 39,634 bytes, 1,224 lines download raw bytes

1/**
2 * jQuery Validation Plugin 1.11.0pre
3 *
4 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5 * http://docs.jquery.com/Plugins/Validation
6 *
7 * Copyright 2013 Jörn Zaefferer
8 * Released under the MIT license:
9 *   http://www.opensource.org/licenses/mit-license.php
10 */
11
12(function($) {
13
14$.extend($.fn, {
15	// http://docs.jquery.com/Plugins/Validation/validate
16	validate: function( options ) {
17
18		// if nothing is selected, return nothing; can't chain anyway
19		if ( !this.length ) {
20			if ( options && options.debug && window.console ) {
21				console.warn( "Nothing selected, can't validate, returning nothing." );
22			}
23			return;
24		}
25
26		// check if a validator for this form was already created
27		var validator = $.data( this[0], "validator" );
28		if ( validator ) {
29			return validator;
30		}
31
32		// Add novalidate tag if HTML5.
33		this.attr( "novalidate", "novalidate" );
34
35		validator = new $.validator( options, this[0] );
36		$.data( this[0], "validator", validator );
37
38		if ( validator.settings.onsubmit ) {
39
40			this.validateDelegate( ":submit", "click", function( event ) {
41				if ( validator.settings.submitHandler ) {
42					validator.submitButton = event.target;
43				}
44				// allow suppressing validation by adding a cancel class to the submit button
45				if ( $(event.target).hasClass("cancel") ) {
46					validator.cancelSubmit = true;
47				}
48			});
49
50			// validate the form on submit
51			this.submit( function( event ) {
52				if ( validator.settings.debug ) {
53					// prevent form submit to be able to see console output
54					event.preventDefault();
55				}
56				function handle() {
57					var hidden;
58					if ( validator.settings.submitHandler ) {
59						if ( validator.submitButton ) {
60							// insert a hidden input as a replacement for the missing submit button
61							hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
62						}
63						validator.settings.submitHandler.call( validator, validator.currentForm, event );
64						if ( validator.submitButton ) {
65							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
66							hidden.remove();
67						}
68						return false;
69					}
70					return true;
71				}
72
73				// prevent submit for invalid forms or custom submit handlers
74				if ( validator.cancelSubmit ) {
75					validator.cancelSubmit = false;
76					return handle();
77				}
78				if ( validator.form() ) {
79					if ( validator.pendingRequest ) {
80						validator.formSubmitted = true;
81						return false;
82					}
83					return handle();
84				} else {
85					validator.focusInvalid();
86					return false;
87				}
88			});
89		}
90
91		return validator;
92	},
93	// http://docs.jquery.com/Plugins/Validation/valid
94	valid: function() {
95		if ( $(this[0]).is("form")) {
96			return this.validate().form();
97		} else {
98			var valid = true;
99			var validator = $(this[0].form).validate();
100			this.each(function() {
101				valid &= validator.element(this);
102			});
103			return valid;
104		}
105	},
106	// attributes: space seperated list of attributes to retrieve and remove
107	removeAttrs: function( attributes ) {
108		var result = {},
109			$element = this;
110		$.each(attributes.split(/\s/), function( index, value ) {
111			result[value] = $element.attr(value);
112			$element.removeAttr(value);
113		});
114		return result;
115	},
116	// http://docs.jquery.com/Plugins/Validation/rules
117	rules: function( command, argument ) {
118		var element = this[0];
119
120		if ( command ) {
121			var settings = $.data(element.form, "validator").settings;
122			var staticRules = settings.rules;
123			var existingRules = $.validator.staticRules(element);
124			switch(command) {
125			case "add":
126				$.extend(existingRules, $.validator.normalizeRule(argument));
127				staticRules[element.name] = existingRules;
128				if ( argument.messages ) {
129					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
130				}
131				break;
132			case "remove":
133				if ( !argument ) {
134					delete staticRules[element.name];
135					return existingRules;
136				}
137				var filtered = {};
138				$.each(argument.split(/\s/), function( index, method ) {
139					filtered[method] = existingRules[method];
140					delete existingRules[method];
141				});
142				return filtered;
143			}
144		}
145
146		var data = $.validator.normalizeRules(
147		$.extend(
148			{},
149			$.validator.classRules(element),
150			$.validator.attributeRules(element),
151			$.validator.dataRules(element),
152			$.validator.staticRules(element)
153		), element);
154
155		// make sure required is at front
156		if ( data.required ) {
157			var param = data.required;
158			delete data.required;
159			data = $.extend({required: param}, data);
160		}
161
162		return data;
163	}
164});
165
166// Custom selectors
167$.extend($.expr[":"], {
168	// http://docs.jquery.com/Plugins/Validation/blank
169	blank: function( a ) { return !$.trim("" + a.value); },
170	// http://docs.jquery.com/Plugins/Validation/filled
171	filled: function( a ) { return !!$.trim("" + a.value); },
172	// http://docs.jquery.com/Plugins/Validation/unchecked
173	unchecked: function( a ) { return !a.checked; }
174});
175
176// constructor for validator
177$.validator = function( options, form ) {
178	this.settings = $.extend( true, {}, $.validator.defaults, options );
179	this.currentForm = form;
180	this.init();
181};
182
183$.validator.format = function( source, params ) {
184	if ( arguments.length === 1 ) {
185		return function() {
186			var args = $.makeArray(arguments);
187			args.unshift(source);
188			return $.validator.format.apply( this, args );
189		};
190	}
191	if ( arguments.length > 2 && params.constructor !== Array  ) {
192		params = $.makeArray(arguments).slice(1);
193	}
194	if ( params.constructor !== Array ) {
195		params = [ params ];
196	}
197	$.each(params, function( i, n ) {
198		source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() {
199			return n;
200		});
201	});
202	return source;
203};
204
205$.extend($.validator, {
206
207	defaults: {
208		messages: {},
209		groups: {},
210		rules: {},
211		errorClass: "error",
212		validClass: "valid",
213		errorElement: "label",
214		focusInvalid: true,
215		errorContainer: $([]),
216		errorLabelContainer: $([]),
217		onsubmit: true,
218		ignore: ":hidden",
219		ignoreTitle: false,
220		onfocusin: function( element, event ) {
221			this.lastActive = element;
222
223			// hide error label and remove error class on focus if enabled
224			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
225				if ( this.settings.unhighlight ) {
226					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.val
226idClass );
227				}
228				this.addWrapper(this.errorsFor(element)).hide();
229			}
230		},
231		onfocusout: function( element, event ) {
232			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
233				this.element(element);
234			}
235		},
236		onkeyup: function( element, event ) {
237			if ( event.which === 9 && this.elementValue(element) === "" ) {
238				return;
239			} else if ( element.name in this.submitted || element === this.lastElement ) {
240				this.element(element);
241			}
242		},
243		onclick: function( element, event ) {
244			// click on selects, radiobuttons and checkboxes
245			if ( element.name in this.submitted ) {
246				this.element(element);
247			}
248			// or option elements, check parent select in that case
249			else if ( element.parentNode.name in this.submitted ) {
250				this.element(element.parentNode);
251			}
252		},
253		highlight: function( element, errorClass, validClass ) {
254			if ( element.type === "radio" ) {
255				this.findByName(element.name).addClass(errorClass).removeClass(validClass);
256			} else {
257				$(element).addClass(errorClass).removeClass(validClass);
258			}
259		},
260		unhighlight: function( element, errorClass, validClass ) {
261			if ( element.type === "radio" ) {
262				this.findByName(element.name).removeClass(errorClass).addClass(validClass);
263			} else {
264				$(element).removeClass(errorClass).addClass(validClass);
265			}
266		}
267	},
268
269	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
270	setDefaults: function( settings ) {
271		$.extend( $.validator.defaults, settings );
272	},
273
274	messages: {
275		required: "This field is required.",
276		remote: "Please fix this field.",
277		email: "Please enter a valid email address.",
278		url: "Please enter a valid URL.",
279		date: "Please enter a valid date.",
280		dateISO: "Please enter a valid date (ISO).",
281		number: "Please enter a valid number.",
282		digits: "Please enter only digits.",
283		creditcard: "Please enter a valid credit card number.",
284		equalTo: "Please enter the same value again.",
285		maxlength: $.validator.format("Please enter no more than {0} characters."),
286		minlength: $.validator.format("Please enter at least {0} characters."),
287		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
288		range: $.validator.format("Please enter a value between {0} and {1}."),
289		max: $.validator.format("Please enter a value less than or equal to {0}."),
290		min: $.validator.format("Please enter a value greater than or equal to {0}.")
291	},
292
293	autoCreateRanges: false,
294
295	prototype: {
296
297		init: function() {
298			this.labelContainer = $(this.settings.errorLabelContainer);
299			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
300			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
301			this.submitted = {};
302			this.valueCache = {};
303			this.pendingRequest = 0;
304			this.pending = {};
305			this.invalid = {};
306			this.reset();
307
308			var groups = (this.groups = {});
309			$.each(this.settings.groups, function( key, value ) {
310				if ( typeof value === "string" ) {
311					value = value.split(/\s/);
312				}
313				$.each(value, function( index, name ) {
314					groups[name] = key;
315				});
316			});
317			var rules = this.settings.rules;
318			$.each(rules, function( key, value ) {
319				rules[key] = $.validator.normalizeRule(value);
320			});
321
322			function delegate(event) {
323				var validator = $.data(this[0].form, "validator"),
324					eventType = "on" + event.type.replace(/^validate/, "");
325				if ( validator.settings[eventType] ) {
326					validator.settings[eventType].call(validator, this[0], event);
327				}
328			}
329			$(this.currentForm)
330				.validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
331					"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
332					"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
333					"[type='week'], [type='time'], [type='datetime-local'], " +
334					"[type='range'], [type='color'] ",
335					"focusin focusout keyup", delegate)
336				.validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
337
338			if ( this.settings.invalidHandler ) {
339				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
340			}
341		},
342
343		// http://docs.jquery.com/Plugins/Validation/Validator/form
344		form: function() {
345			this.checkForm();
346			$.extend(this.submitted, this.errorMap);
347			this.invalid = $.extend({}, this.errorMap);
348			if ( !this.valid() ) {
349				$(this.currentForm).triggerHandler("invalid-form", [this]);
350			}
351			this.showErrors();
352			return this.valid();
353		},
354
355		checkForm: function() {
356			this.prepareForm();
357			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
358				this.check( elements[i] );
359			}
360			return this.valid();
361		},
362
363		// http://docs.jquery.com/Plugins/Validation/Validator/element
364		element: function( element ) {
365			element = this.validationTargetFor( this.clean( element ) );
366			this.lastElement = element;
367			this.prepareElement( element );
368			this.currentElements = $(element);
369			var result = this.check( element ) !== false;
370			if ( result ) {
371				delete this.invalid[element.name];
372			} else {
373				this.invalid[element.name] = true;
374			}
375			if ( !this.numberOfInvalids() ) {
376				// Hide error containers on last error
377				this.toHide = this.toHide.add( this.containers );
378			}
379			this.showErrors();
380			return result;
381		},
382
383		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
384		showErrors: function( errors ) {
385			if ( errors ) {
386				// add items to error list and map
387				$.extend( this.errorMap, errors );
388				this.errorList = [];
389				for ( var name in errors ) {
390					this.errorList.push({
391						message: errors[name],
392						element: this.findByName(name)[0]
393					});
394				}
395				// remove items from success list
396				this.successList = $.grep( this.successList, function( element ) {
397					return !(element.name in errors);
398				});
399			}
400			if ( this.settings.showErrors ) {
401				this.settings.showErrors.call( this, this.errorMap, this.errorList );
402			} else {
403				this.defaultShowErrors();
404			}
405		},
406
407		// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
408		resetForm: function() {
409			if ( $.fn.resetForm ) {
410				$(this.currentForm).resetForm();
411			}
412			this.submitted = {};
413			this.lastElement = null;
414			this.prepareForm();
415			this.hideErrors();
416			this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
417		},
418
419		numberOfInvalids: function() {
420			return this.objectLength(this.invalid);
421		},
422
423		objectLength: function( obj ) {
424			var count = 0;
425			for ( var i in obj ) {
426				count++;
427			}
428			return count;
429		},
430
431		hideErrors: function() {
432			this.addWrapper( this.toHide ).hide();
433		},
434
435		valid: function() {
436			return this.size() === 0;
437		},
438
439		size: function() {
440			return this.errorList.length;
441		},
442
443		focusInvalid: function() {
444			if ( this.settings.focusInvalid ) {
445				try {
446					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
447					.filter(":visible")
448					.focus()
449					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
450					.trigger("focusin");
451				} catch(e) {
452					// ignore IE throwing errors when focusing hidden elements
453				}
454			}
455		},
456
457		findLastActive: function() {
458			var lastActive = this.lastActive;
459			return lastActive && $.grep(this.errorList, function( n ) {
460				return n.element.name === lastActive.name;
461			}).length === 1 && lastActive;
462		},
463
464		elements: function() {
465			var validator = this,
466				rulesCache = {};
467
468			// select all valid inputs inside the form (no submit or reset buttons)
469			return $(this.currentForm)
470			.find("input, select, textarea")
471			.not(":submit, :reset, :image, [disabled]")
472			.not( this.settings.ignore )
473			.filter(function() {
474				if ( !this.name ) {
475					if ( window.console ) {
476						console.error( "%o has no name assigned", this );
477					}
478					throw new Error( "Failed to validate, found an element with no name assigned. See console for element reference." );
479				}
480
481				// select only the first element for each name, and only those with rules specified
482				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
483					return false;
484				}
485
486				rulesCache[this.name] = true;
487				return true;
488			});
489		},
490
491		clean: function( selector ) {
492			return $(selector)[0];
493		},
494
495		errors: function() {
496			var errorClass = this.settings.errorClass.replace(" ", ".");
497			return $(this.settings.errorElement + "." + errorClass, this.errorContext);
498		},
499
500		reset: function() {
501			this.successList = [];
502			this.errorList = [];
503			this.errorMap = {};
504			this.toShow = $([]);
505			this.toHide = $([]);
506			this.currentElements = $([]);
507		},
508
509		prepareForm: function() {
510			this.reset();
511			this.toHide = this.errors().add( this.containers );
512		},
513
514		prepareElement: function( element ) {
515			this.reset();
516			this.toHide = this.errorsFor(element);
517		},
518
519		elementValue: function( element ) {
520			var type = $(element).attr("type"),
521				val = $(element).val();
522
523			if ( type === "radio" || type === "checkbox" ) {
524				return $("input[name='" + $(element).attr("name") + "']:checked").val();
525			}
526
527			if ( typeof val === "string" ) {
528				return val.replace(/\r/g, "");
529			}
530			return val;
531		},
532
533		check: function( element ) {
534			element = this.validationTargetFor( this.clean( element ) );
535
536			var rules = $(element).rules();
537			var dependencyMismatch = false;
538			var val = this.elementValue(element);
539			var result;
540
541			for (var method in rules ) {
542				var rule = { method: method, parameters: rules[method] };
543				try {
544
545					result = $.validator.methods[method].call( this, val, element, rule.parameters );
546
547					// if a method indicates that the field is optional and therefore valid,
548					// don't mark it as valid when there are no other rules
549					if ( result === "dependency-mismatch" ) {
550						dependencyMismatch = true;
551						continue;
552					}
553					dependencyMismatch = false;
554
555					if ( result === "pending" ) {
556						this.toHide = this.toHide.not( this.errorsFor(element) );
557						return;
558					}
559
560					if ( !result ) {
561						this.formatAndAdd( element, rule );
562						return false;
563					}
564				} catch(e) {
565					if ( this.settings.debug && window.console ) {
566						console.log( "Exception occured when checking element " + element.i
566d + ", check the '" + rule.method + "' method.", e );
567					}
568					throw e;
569				}
570			}
571			if ( dependencyMismatch ) {
572				return;
573			}
574			if ( this.objectLength(rules) ) {
575				this.successList.push(element);
576			}
577			return true;
578		},
579
580		// return the custom message for the given element and validation method
581		// specified in the element's HTML5 data attribute
582		customDataMessage: function( element, method ) {
583			return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
584		},
585
586		// return the custom message for the given element name and validation method
587		customMessage: function( name, method ) {
588			var m = this.settings.messages[name];
589			return m && (m.constructor === String ? m : m[method]);
590		},
591
592		// return the first defined argument, allowing empty strings
593		findDefined: function() {
594			for(var i = 0; i < arguments.length; i++) {
595				if ( arguments[i] !== undefined ) {
596					return arguments[i];
597				}
598			}
599			return undefined;
600		},
601
602		defaultMessage: function( element, method ) {
603			return this.findDefined(
604				this.customMessage( element.name, method ),
605				this.customDataMessage( element, method ),
606				// title is never undefined, so handle empty string as undefined
607				!this.settings.ignoreTitle && element.title || undefined,
608				$.validator.messages[method],
609				"<strong>Warning: No message defined for " + element.name + "</strong>"
610			);
611		},
612
613		formatAndAdd: function( element, rule ) {
614			var message = this.defaultMessage( element, rule.method ),
615				theregex = /\$?\{(\d+)\}/g;
616			if ( typeof message === "function" ) {
617				message = message.call(this, rule.parameters, element);
618			} else if (theregex.test(message)) {
619				message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
620			}
621			this.errorList.push({
622				message: message,
623				element: element
624			});
625
626			this.errorMap[element.name] = message;
627			this.submitted[element.name] = message;
628		},
629
630		addWrapper: function( toToggle ) {
631			if ( this.settings.wrapper ) {
632				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
633			}
634			return toToggle;
635		},
636
637		defaultShowErrors: function() {
638			var i, elements;
639			for ( i = 0; this.errorList[i]; i++ ) {
640				var error = this.errorList[i];
641				if ( this.settings.highlight ) {
642					this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
643				}
644				this.showLabel( error.element, error.message );
645			}
646			if ( this.errorList.length ) {
647				this.toShow = this.toShow.add( this.containers );
648			}
649			if ( this.settings.success ) {
650				for ( i = 0; this.successList[i]; i++ ) {
651					this.showLabel( this.successList[i] );
652				}
653			}
654			if ( this.settings.unhighlight ) {
655				for ( i = 0, elements = this.validElements(); elements[i]; i++ ) {
656					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
657				}
658			}
659			this.toHide = this.toHide.not( this.toShow );
660			this.hideErrors();
661			this.addWrapper( this.toShow ).show();
662		},
663
664		validElements: function() {
665			return this.currentElements.not(this.invalidElements());
666		},
667
668		invalidElements: function() {
669			return $(this.errorList).map(function() {
670				return this.element;
671			});
672		},
673
674		showLabel: function( element, message ) {
675			var label = this.errorsFor( element );
676			if ( label.length ) {
677				// refresh error/success class
678				label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
679
680				// check if we have a generated label, replace the message then
681				if ( label.attr("generated") ) {
682					label.html(message);
683				}
684			} else {
685				// create label
686				label = $("<" + this.settings.errorElement + "/>")
687					.attr({"for":  this.idOrName(element), generated: true})
688					.addClass(this.settings.errorClass)
689					.html(message || "");
690				if ( this.settings.wrapper ) {
691					// make sure the element is visible, even in IE
692					// actually showing the wrapped element is handled elsewhere
693					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
694				}
695				if ( !this.labelContainer.append(label).length ) {
696					if ( this.settings.errorPlacement ) {
697						this.settings.errorPlacement(label, $(element) );
698					} else {
699						label.insertAfter(element);
700					}
701				}
702			}
703			if ( !message && this.settings.success ) {
704				label.text("");
705				if ( typeof this.settings.success === "string" ) {
706					label.addClass( this.settings.success );
707				} else {
708					this.settings.success( label, element );
709				}
710			}
711			this.toShow = this.toShow.add(label);
712		},
713
714		errorsFor: function( element ) {
715			var name = this.idOrName(element);
716			return this.errors().filter(function() {
717				return $(this).attr("for") === name;
718			});
719		},
720
721		idOrName: function( element ) {
722			return this.groups[element.name] || (this.checkable(element) ? element.name : element.i
722d || element.name);
723		},
724
725		validationTargetFor: function( element ) {
726			// if radio/checkbox, validate first element in group instead
727			if ( this.checkable(element) ) {
728				element = this.findByName( element.name ).not(this.settings.ignore)[0];
729			}
730			return element;
731		},
732
733		checkable: function( element ) {
734			return (/radio|checkbox/i).test(element.type);
735		},
736
737		findByName: function( name ) {
738			return $(this.currentForm).find("[name='" + name + "']");
739		},
740
741		getLength: function( value, element ) {
742			switch( element.nodeName.toLowerCase() ) {
743			case "select":
744				return $("option:selected", element).length;
745			case "input":
746				if ( this.checkable( element) ) {
747					return this.findByName(element.name).filter(":checked").length;
748				}
749			}
750			return value.length;
751		},
752
753		depend: function( param, element ) {
754			return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
755		},
756
757		dependTypes: {
758			"boolean": function( param, element ) {
759				return param;
760			},
761			"string": function( param, element ) {
762				return !!$(param, element.form).length;
763			},
764			"function": function( param, element ) {
765				return param(element);
766			}
767		},
768
769		optional: function( element ) {
770			var val = this.elementValue(element);
771			return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
772		},
773
774		startRequest: function( element ) {
775			if ( !this.pending[element.name] ) {
776				this.pendingRequest++;
777				this.pending[element.name] = true;
778			}
779		},
780
781		stopRequest: function( element, valid ) {
782			this.pendingRequest--;
783			// sometimes synchronization fails, make sure pendingRequest is never < 0
784			if ( this.pendingRequest < 0 ) {
785				this.pendingRequest = 0;
786			}
787			delete this.pending[element.name];
788			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
789				$(this.currentForm).submit();
790				this.formSubmitted = false;
791			} else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
792				$(this.currentForm).triggerHandler("invalid-form", [this]);
793				this.formSubmitted = false;
794			}
795		},
796
797		previousValue: function( element ) {
798			return $.data(element, "previousValue") || $.data(element, "previousValue", {
799				old: null,
800				valid: true,
801				message: this.defaultMessage( element, "remote" )
802			});
803		}
804
805	},
806
807	classRuleSettings: {
808		required: {required: true},
809		email: {email: true},
810		url: {url: true},
811		date: {date: true},
812		dateISO: {dateISO: true},
813		number: {number: true},
814		digits: {digits: true},
815		creditcard: {creditcard: true}
816	},
817
818	addClassRules: function( className, rules ) {
819		if ( className.constructor === String ) {
820			this.classRuleSettings[className] = rules;
821		} else {
822			$.extend(this.classRuleSettings, className);
823		}
824	},
825
826	classRules: function( element ) {
827		var rules = {};
828		var classes = $(element).attr("class");
829		if ( classes ) {
830			$.each(classes.split(" "), function() {
831				if ( this in $.validator.classRuleSettings ) {
832					$.extend(rules, $.validator.classRuleSettings[this]);
833				}
834			});
835		}
836		return rules;
837	},
838
839	attributeRules: function( element ) {
840		var rules = {};
841		var $element = $(element);
842
843		for (var method in $.validator.methods) {
844			var value;
845
846			// support for <input required> in both html5 and older browsers
847			if ( method === "required" ) {
848				value = $element.get(0).getAttribute(method);
849				// Some browsers return an empty string for the required attribute
850				// and non-HTML5 browsers might have required="" markup
851				if ( value === "" ) {
852					value = true;
853				}
854				// force non-HTML5 browsers to return bool
855				value = !!value;
856			} else {
857				value = $element.attr(method);
858			}
859
860			if ( value ) {
861				rules[method] = value;
862			} else if ( $element[0].getAttribute("type") === method ) {
863				rules[method] = true;
864			}
865		}
866
867		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
868		if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) {
869			delete rules.maxlength;
870		}
871
872		return rules;
873	},
874
875	dataRules: function( element ) {
876		var method, value,
877			rules = {}, $element = $(element);
878		for (method in $.validator.methods) {
879			value = $element.data("rule-" + method.toLowerCase());
880			if ( value !== undefined ) {
881				rules[method] = value;
882			}
883		}
884		return rules;
885	},
886
887	staticRules: function( element ) {
888		var rules = {};
889		var validator = $.data(element.form, "validator");
890		if ( validator.settings.rules ) {
891			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
892		}
893		return rules;
894	},
895
896	normalizeRules: function( rules, element ) {
897		// handle dependency check
898		$.each(rules, function( prop, val ) {
899			// ignore rule when param is explicitly false, eg. required:false
900			if ( val === false ) {
901				delete rules[prop];
902				return;
903			}
904			if ( val.param || val.depends ) {
905				var keepRule = true;
906				switch (typeof val.depends) {
907				case "string":
908					keepRule = !!$(val.depends, element.form).length;
909					break;
910				case "function":
911					keepRule = val.depends.call(element, element);
912					break;
913				}
914				if ( keepRule ) {
915					rules[prop] = val.param !== undefined ? val.param : true;
916				} else {
917					delete rules[prop];
918				}
919			}
920		});
921
922		// evaluate parameters
923		$.each(rules, function( rule, parameter ) {
924			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
925		});
926
927		// clean number parameters
928		$.each(["minlength", "maxlength", "min", "max"], function() {
929			if ( rules[this] ) {
930				rules[this] = Number(rules[this]);
931			}
932		});
933		$.each(["rangelength", "range"], function() {
934			var parts;
935			if ( rules[this] ) {
936				if ( $.isArray(rules[this]) ) {
937					rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
938				} else if ( typeof rules[this] === "string" ) {
939					parts = rules[this].split(/[\s,]+/);
940					rules[this] = [Number(parts[0]), Number(parts[1])];
941				}
942			}
943		});
944
945		if ( $.validator.autoCreateRanges ) {
946			// auto-create ranges
947			if ( rules.min && rules.max ) {
948				rules.range = [rules.min, rules.max];
949				delete rules.min;
950				delete rules.max;
951			}
952			if ( rules.minlength && rules.maxlength ) {
953				rules.rangelength = [rules.minlength, rules.maxlength];
954				delete rules.minlength;
955				delete rules.maxlength;
956			}
957		}
958
959		return rules;
960	},
961
962	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
963	normalizeRule: function( data ) {
964		if ( typeof data === "string" ) {
965			var transformed = {};
966			$.each(data.split(/\s/), function() {
967				transformed[this] = true;
968			});
969			data = transformed;
970		}
971		return data;
972	},
973
974	// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
975	addMethod: function( name, method, message ) {
976		$.validator.methods[name] = method;
977		$.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
978		if ( method.length < 3 ) {
979			$.validator.addClassRules(name, $.validator.normalizeRule(name));
980		}
981	},
982
983	methods: {
984
985		// http://docs.jquery.com/Plugins/Validation/Methods/required
986		required: function( value, element, param ) {
987			// check if dependency is met
988			if ( !this.depend(param, element) ) {
989				return "dependency-mismatch";
990			}
991			if ( element.nodeName.toLowerCase() === "select" ) {
992				// could be an array for select-multiple or a string, both are fine this way
993				var val = $(element).val();
994				return val && val.length > 0;
995			}
996			if ( this.checkable(element) ) {
997				return this.getLength(value, element) > 0;
998			}
999			return $.trim(value).length > 0;
1000		},
1001
1002		// http://docs.jquery.com/Plugins/Validation/Methods/remote
1003		remote: function( value, element, param ) {
1004			if ( this.optional(element) ) {
1005				return "dependency-mismatch";
1006			}
1007
1008			var previous = this.previousValue(element);
1009			if (!this.settings.messages[element.name] ) {
1010				this.settings.messages[element.name] = {};
1011			}
1012			previous.originalMessage = this.settings.messages[element.name].remote;
1013			this.settings.messages[element.name].remote = previous.message;
1014
1015			param = typeof param === "string" && {url:param} || param;
1016
1017			if ( previous.old === value ) {
1018				return previous.valid;
1019			}
1020
1021			previous.old = value;
1022			var validator = this;
1023			this.startRequest(element);
1024			var data = {};
1025			data[element.name] = value;
1026			$.ajax($.extend(true, {
1027				url: param,
1028				mode: "abort",
1029				port: "validate" + element.name,
1030				dataType: "json",
1031				data: data,
1032				success: function( response ) {
1033					validator.settings.messages[element.name].remote = previous.originalMessage;
1034					var valid = response === true || response === "true";
1035					if ( valid ) {
1036						var submitted = validator.formSubmitted;
1037						validator.prepareElement(element);
1038						validator.formSubmitted = submitted;
1039						validator.successList.push(element);
1040						delete validator.invalid[element.name];
1041						validator.showErrors();
1042					} else {
1043						var errors = {};
1044						var message = response || validator.defaultMessage( element, "remote" );
1045						errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
1046						validator.invalid[element.name] = true;
1047						validator.showErrors(errors);
1048					}
1049					previous.valid = valid;
1050					validator.stopRequest(element, valid);
1051				}
1052			}, param));
1053			return "pending";
1054		},
1055
1056		// http://docs.jquery.com/Plugins/Validation/Methods/minlength
1057		minlength: function( value, element, param ) {
1058			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1059			return this.optional(element) || length >= param;
1060		},
1061
1062		// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1063		maxlength: function( value, element, param ) {
1064			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1065			return this.optional(element) || length <= param;
1066		},
1067
1068		// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1069		rangelength: function( value, element, param ) {
1070			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1071			return this.optional(element) || ( length >= param[0] && length <= param[1] );
1072		},
1073
1074
1075		// http://docs.jquery.com/Plugins/Validation/Methods/min
1076		min: function( value, element, param ) {
1077			return this.optional(element) || value >= param;
1078		},
1079
1080		// http://docs.jquery.com/Plugins/Validation/Methods/max
1081		max: function( value, element, param ) {
1082			return this.optional(element) || value <= param;
1083		},
1084
1085		// http://docs.jquery.com/Plugins/Validation/Methods/range
1086		range: function( value, element, param ) {
1087			return this.optional(element) || ( value >= param[0] && value <= param[1] );
1088		},
1089
1090		// http://docs.jquery.com/Plugins/Validation/Methods/email
1091		email: function( value, element ) {
1092			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1093			return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
1094		},
1095		
1096	
1097		
1098
1099		// http://docs.jquery.com/Plugins/Validation/Methods/url
1100		url: function( value, element ) {
1101			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1102			return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1103		},
1104
1105		// http://docs.jquery.com/Plugins/Validation/Methods/date
1106		date: function( value, element ) {
1107			return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1108		},
1109
1110		// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1111		dateISO: function( value, element ) {
1112			return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
1113		},
1114
1115		// http://docs.jquery.com/Plugins/Validation/Methods/number
1116		number: function( value, element ) {
1117			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1118		},
1119
1120		// http://docs.jquery.com/Plugins/Validation/Methods/digits
1121		digits: function( value, element ) {
1122			return this.optional(element) || /^\d+$/.test(value);
1123		},
1124
1125		// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1126		// based on http://en.wikipedia.org/wiki/Luhn
1127		creditcard: function( value, element ) {
1128			if ( this.optional(element) ) {
1129				return "dependency-mismatch";
1130			}
1131			// accept only spaces, digits and dashes
1132			if ( /[^0-9 \-]+/.test(value) ) {
1133				return false;
1134			}
1135			var nCheck = 0,
1136				nDigit = 0,
1137				bEven = false;
1138
1139			value = value.replace(/\D/g, "");
1140
1141			for (var n = value.length - 1; n >= 0; n--) {
1142				var cDigit = value.charAt(n);
1143				nDigit = parseInt(cDigit, 10);
1144				if ( bEven ) {
1145					if ( (nDigit *= 2) > 9 ) {
1146						nDigit -= 9;
1147					}
1148				}
1149				nCheck += nDigit;
1150				bEven = !bEven;
1151			}
1152
1153			return (nCheck % 10) === 0;
1154		},
1155
1156		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1157		equalTo: function( value, element, param ) {
1158			// bind to the blur event of the target in order to revalidate whenever the target field is updated
1159			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1160			var target = $(param);
1161			if ( this.settings.onfocusout ) {
1162				target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1163					$(element).valid();
1164				});
1165			}
1166			return value === target.val();
1167		}
1168
1169	}
1170
1171});
1172
1173// deprecated, use $.validator.format instead
1174$.format = $.validator.format;
1175
1176}(jQuery));
1177
1178// ajax mode: abort
1179// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1180// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1181(function($) {
1182	var pendingRequests = {};
1183	// Use a prefilter if available (1.5+)
1184	if ( $.ajaxPrefilter ) {
1185		$.ajaxPrefilter(function( settings, _, xhr ) {
1186			var port = settings.port;
1187			if ( settings.mode === "abort" ) {
1188				if ( pendingRequests[port] ) {
1189					pendingRequests[port].abort();
1190				}
1191				pendingRequests[port] = xhr;
1192			}
1193		});
1194	} else {
1195		// Proxy ajax
1196		var ajax = $.ajax;
1197		$.ajax = function( settings ) {
1198			var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1199				port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1200			if ( mode === "abort" ) {
1201				if ( pendingRequests[port] ) {
1202					pendingRequests[port].abort();
1203				}
1204				return (pendingRequests[port] = ajax.apply(this, arguments));
1205			}
1206			return ajax.apply(this, arguments);
1207		};
1208	}
1209}(jQuery));
1210
1211// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1212// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1213(function($) {
1214	$.extend($.fn, {
1215		validateDelegate: function( delegate, type, handler ) {
1216			return this.bind(type, function( event ) {
1217				var target = $(event.target);
1218				if ( target.is(delegate) ) {
1219					return handler.apply(target, arguments);
1220				}
1221			});
1222		}
1223	});
1224}(jQuery));// JavaScript Document

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.