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