1!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e("undefined"!=typeof jQuery?jQuery:window.Zepto)}(function(e){"use strict";function t(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(t.target).ajaxSubmit(r))}function r(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=this;if(i.clk=r,"image"==r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function a(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}var n={};n.fileapi=void 0!==e("<input type='file'/>").get(0).files,n.formdata=void 0!==window.FormData;var i=!!e.fn.prop;e.fn.attr2=function(){if(!i)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t){function r(r){var a,n,i=e.param(r,t.traditional).split("&"),o=i.length,s=[];for(a=0;a<o;a++)i[a]=i[a].replace(/\+/g," "),n=i[a].split("="),s.push([decodeURIComponent(n[0]),decodeURIComponent(n[1])]);return s}function o(a){for(var n=new FormData,i=0;i<a.length;i++)n.append(a[i].name,a[i].value);if(t.extraData){var o=r(t.extraData);for(i=0;i<o.length;i++)o[i]&&n.append(o[i][0],o[i][1])}t.data=null;var s=e.extend(!0,{},e.ajaxSettings,t,{contentType:!1,processData:!1,cache:!1,type:u||"POST"});t.uploadProgress&&(s.xhr=function(){var r=e.ajaxSettings.xhr();return r.upload&&r.upload.addEventListener("progress",function(e){var r=0,a=e.loaded||e.position,n=e.total;e.lengthComputable&&(r=Math.ceil(a/n*100)),t.uploadProgress(e,a,n,r)},!1),r}),s.data=null;var c=s.beforeSend;return s.beforeSend=function(e,r){t.formData?r.data=t.formData:r.data=n,c&&c.call(this,e,r)},e.ajax(s)}function s(r){function n(e){var t=null;try{e.contentWindow&&(t=e.contentWindow.document)}catch(e){a("cannot get iframe.contentWindow document: "+e)}if(t)return t;try{t=e.contentDocument?e.contentDocument:e.document}catch(r){a("cannot get iframe.contentDocument: "+r),t=e.document}return t}function o(){function t(){try{var e=n(g).readyState;a("state = "+e),e&&"uninitialized"==e.toLowerCase()&&setTimeout(t,50)}catch(e){a("Server abort: ",e," (",e.name,")"),s(k),j&&clearTimeout(j),j=void 0}}var r=f.attr2("target"),i=f.attr2("action");w.setAttribute("target",p),u&&!/post/i.test(u)||w.setAttribute("method","POST"),i!=d.url&&w.setAttribute("action",d.url),d.skipEncodingOverride||u&&!/post/i.test(u)||f.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),d.timeout&&(j=setTimeout(function(){T=!0,s(D)},d.timeout));var o=[];try{if(d.extraData)for(var c in d.extraData)d.extraData.hasOwnProperty(c)&&(e.isPlainObject(d.extraData[c])&&d.extraData[c].hasOwnProperty("name")&&d.extraData[c].hasOwnProperty("value")?o.push(e('<input type="hidden" name="'+d.extraData[c].name+'">').val(d.extraData[c].value).appendTo(w)[0]):o.push(e('<input type="hidden" name="'+c+'">').val(d.extraData[c]).appendTo(w)[0]));d.iframeTarget||v.appendTo("body"),g.attachEvent?g.attachEvent("onload",s):g.addEventListener("load",s,!1),setTimeout(t,15);try{w.submit()}catch(e){var l=document.createElement("form").submit;l.apply(w)}}finally{w.setAttribute("action",i),r?w.setAttribute("target",r):f.removeAttr("target"),e(o).remove()}}function s(t){if(!x.aborted&&!F){if(M=n(g),M||(a("cannot access response document"),t=k),t===D&&x)return x.abort("timeout"),void S.reject(x,"timeout");if(t==k&&x)return x.abort("server abort"),void S.reject(x,"error","server abort");if(M&&M.location.href!=d.iframeSrc||T){g.detachEvent?g.detachEvent("onload",s):g.removeEventListener("load",s,!1);var r,i="success";try{if(T)throw"timeout";var o="xml"==d.dataType||M.XMLDocument||e.isXMLDoc(M);if(a("isXml="+o),!o&&window.opera&&(null===M.body||!M.body.innerHTML)&&--O)return a("requeing onLoad callback, DOM not available"),void setTimeout(s,250);var u=M.body?M.body:M.documentElement;x.responseText=u?u.innerHTML:null,x.responseXML=M.XMLDocument?M.XMLDocument:M,o&&(d.dataType="xml"),x.getResponseHeader=function(e){var t={"content-type":d.dataType};return t[e.toLowerCase()]},u&&(x.status=Number(u.getAttribute("status"))||x.status,x.statusText=u.getAttribute("statusText")||x.statusText);var c=(d.dataType||"").toLowerCase(),l=/(json|script|text)/.test(c);if(l||d.textarea){var f=M.getElementsByTagName("textarea")[0];if(f)x.responseText=f.value,x.status=Number(f.getAttribute("status"))||x.status,x.statusText=f.getAttribute("statusText")||x.statusText;else if(l){var p=M.getElementsByTagName("pre")[0],h=M.getElementsByTagName("body")[0];p?x.responseText=p.textContent?p.textContent:p.innerText:h&&(x.responseText=h.textContent?h.textContent:h.innerText)}}else"xml"==c&&!x.responseXML&&x.responseText&&(x.responseXML=X(x.responseText));try{E=_(x,c,d)}catch(e){i="parsererror",x.error=r=e||i}}catch(e){a("error caught: ",e),i="error",x.error=r=e||i}x.aborted&&(a("upload aborted"),i=null),x.status&&(i=x.status>=200&&x.status<300||304===x.status?"success":"error"),"success"===i?(d.success&&d.success.call(
1d.context,E,"success",x),S.resolve(x.responseText,"success",x),m&&e.event.trigger("ajaxSuccess",[x,d])):i&&(void 0===r&&(r=x.statusText),d.error&&d.error.call(d.context,x,i,r),S.reject(x,"error",r),m&&e.event.trigger("ajaxError",[x,d,r])),m&&e.event.trigger("ajaxComplete",[x,d]),m&&!--e.active&&e.event.trigger("ajaxStop"),d.complete&&d.complete.call(d.context,x,i),F=!0,d.timeout&&clearTimeout(j),setTimeout(function(){d.iframeTarget?v.attr("src",d.iframeSrc):v.remove(),x.responseXML=null},100)}}}var c,l,d,m,p,v,g,x,y,b,T,j,w=f[0],S=e.Deferred();if(S.abort=function(e){x.abort(e)},r)for(l=0;l<h.length;l++)c=e(h[l]),i?c.prop("disabled",!1):c.removeAttr("disabled");if(d=e.extend(!0,{},e.ajaxSettings,t),d.context=d.context||d,p="jqFormIO"+(new Date).getTime(),d.iframeTarget?(v=e(d.iframeTarget),b=v.attr2("name"),b?p=b:v.attr2("name",p)):(v=e('<iframe name="'+p+'" src="'+d.iframeSrc+'" />'),v.css({position:"absolute",top:"-1000px",left:"-1000px"})),g=v[0],x={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(t){var r="timeout"===t?"timeout":"aborted";a("aborting upload... "+r),this.aborted=1;try{g.contentWindow.document.execCommand&&g.contentWindow.document.execCommand("Stop")}catch(e){}v.attr("src",d.iframeSrc),x.error=r,d.error&&d.error.call(d.context,x,r,t),m&&e.event.trigger("ajaxError",[x,d,r]),d.complete&&d.complete.call(d.context,x,r)}},m=d.global,m&&0===e.active++&&e.event.trigger("ajaxStart"),m&&e.event.trigger("ajaxSend",[x,d]),d.beforeSend&&d.beforeSend.call(d.context,x,d)===!1)return d.global&&e.active--,S.reject(),S;if(x.aborted)return S.reject(),S;y=w.clk,y&&(b=y.name,b&&!y.disabled&&(d.extraData=d.extraData||{},d.extraData[b]=y.value,"image"==y.type&&(d.extraData[b+".x"]=w.clk_x,d.extraData[b+".y"]=w.clk_y)));var D=1,k=2,A=e("meta[name=csrf-token]").attr("content"),L=e("meta[name=csrf-param]").attr("content");L&&A&&(d.extraData=d.extraData||{},d.extraData[L]=A),d.forceSync?o():setTimeout(o,10);var E,M,F,O=50,X=e.parseXML||function(e,t){return window.ActiveXObject?(t=new ActiveXObject("Microsoft.XMLDOM"),t.async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!=t.documentElement.nodeName?t:null},C=e.parseJSON||function(e){return window.eval("("+e+")")},_=function(t,r,a){var n=t.getResponseHeader("content-type")||"",i="xml"===r||!r&&n.indexOf("xml")>=0,o=i?t.responseXML:t.responseText;return i&&"parsererror"===o.documentElement.nodeName&&e.error&&e.error("parsererror"),a&&a.dataFilter&&(o=a.dataFilter(o,r)),"string"==typeof o&&("json"===r||!r&&n.indexOf("json")>=0?o=C(o):("script"===r||!r&&n.indexOf("javascript")>=0)&&e.globalEval(o)),o};return S}if(!this.length)return a("ajaxSubmit: skipping submit process - no element selected"),this;var u,c,l,f=this;"function"==typeof t?t={success:t}:void 0===t&&(t={}),u=t.type||this.attr2("method"),c=t.url||this.attr2("action"),l="string"==typeof c?e.trim(c):"",l=l||window.location.href||"",l&&(l=(l.match(/^([^#]+)/)||[])[1]),t=e.extend(!0,{url:l,success:e.ajaxSettings.success,type:u||e.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},t);var d={};if(this.trigger("form-pre-serialize",[this,t,d]),d.veto)return a("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(t.beforeSerialize&&t.beforeSerialize(this,t)===!1)return a("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var m=t.traditional;void 0===m&&(m=e.ajaxSettings.traditional);var p,h=[],v=this.formToArray(t.semantic,h);if(t.data&&(t.extraData=t.data,p=e.param(t.data,m)),t.beforeSubmit&&t.beforeSubmit(v,this,t)===!1)return a("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[v,this,t,d]),d.veto)return a("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var g=e.param(v,m);p&&(g=g?g+"&"+p:p),"GET"==t.type.toUpperCase()?(t.url+=(t.url.indexOf("?")>=0?"&":"?")+g,t.data=null):t.data=g;var x=[];if(t.resetForm&&x.push(function(){f.resetForm()}),t.clearForm&&x.push(function(){f.clearForm(t.includeHidden)}),!t.dataType&&t.target){var y=t.success||function(){};x.push(function(r){var a=t.replaceTarget?"replaceWith":"html";e(t.target)[a](r).each(y,arguments)})}else t.success&&x.push(t.success);if(t.success=function(e,r,a){for(var n=t.context||this,i=0,o=x.length;i<o;i++)x[i].apply(n,[e,r,a||f,f])},t.error){var b=t.error;t.error=function(e,r,a){var n=t.context||this;b.apply(n,[e,r,a,f])}}if(t.complete){var T=t.complete;t.complete=function(e,r){var a=t.context||this;T.apply(a,[e,r,f])}}var j=e("input[type=file]:enabled",this).filter(function(){return""!==e(this).val()}),w=j.length>0,S="multipart/form-data",D=f.attr("enctype")==S||f.attr("encoding")==S,k=n.fileapi&&n.formdata;a("fileAPI :"+k);var A,L=(w||D)&&!k;t.iframe!==!1&&(t.iframe||L)?t.closeKeepAlive?e.get(t.closeKeepAlive,function(){A=s(v)}):A=s(v):A=(w||D)&&k?o(v):e.ajax(t),f.removeData("jqxhr").data("jqxhr",A);for(var E=0;E<h.length;E++)h[E]=null;return this.trigger("form-submit-notify",[this,t]),this},e.fn.ajaxForm=function(n){if(n=n||{},n.delegation=n.delegation&&e.isFunction(e.fn.on),!n.delegation&&0===this.length){var i={s:this.selector,c:this.context};return!e.isReady&&i.s?(a("DOM not ready, queuing ajaxForm"),e(function(){e(i.s,i.c).ajaxForm(n)}),this):(a("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)")),this)}return n.delegation?(e(document).off("submit.form-plugin",this.selector,t).off("click.form-plugin",this.selector,r).on("submit.form-plugin",this.selector,n,t).on("click.form-plugin",this.selector,n,r),this):this.ajaxFormUnbind().bind("submit.form-plugin",n,t).bind("click.form-plugin",n,r)},e.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")},e.fn.formToArray=function(t,r){var a=[];if(0===this.length)return a;var i=this[0],o=t?i.getElementsByTagName("*"):i.elements;if(!o)return a;var s,u,c,l,f,d,m;for(s=0,d=o.length;s<d;s++)if(f=o[s],c=f.name,c&&!f.disabled)if(t&&i.clk&&"image"==f.type)i.clk==f&&(a.push({name:c,value:e(f).val(),type:f.type}),a.push({name:c+".x",value:i.clk_x},{name:c+".y",value:i.clk_y}));else if(l=e.fieldValue(f,!0),l&&l.constructor==Array)for(r&&r.push(f),u=0,m=l.length;u<m;
1u++)a.push({name:c,value:l[u]});else if(n.fileapi&&"file"==f.type){r&&r.push(f);var p=f.files;if(p.length)for(u=0;u<p.length;u++)a.push({name:c,value:p[u],type:f.type});else a.push({name:c,value:"",type:f.type})}else null!==l&&"undefined"!=typeof l&&(r&&r.push(f),a.push({name:c,value:l,type:f.type,required:f.required}));if(!t&&i.clk){var h=e(i.clk),v=h[0];c=v.name,c&&!v.disabled&&"image"==v.type&&(a.push({name:c,value:h.val()}),a.push({name:c+".x",value:i.clk_x},{name:c+".y",value:i.clk_y}))}return a},e.fn.formSerialize=function(t){return e.param(this.formToArray(t))},e.fn.fieldSerialize=function(t){var r=[];return this.each(function(){var a=this.name;if(a){var n=e.fieldValue(this,t);if(n&&n.constructor==Array)for(var i=0,o=n.length;i<o;i++)r.push({name:a,value:n[i]});else null!==n&&"undefined"!=typeof n&&r.push({name:this.name,value:n})}}),e.param(r)},e.fn.fieldValue=function(t){for(var r=[],a=0,n=this.length;a<n;a++){var i=this[a],o=e.fieldValue(i,t);null===o||"undefined"==typeof o||o.constructor==Array&&!o.length||(o.constructor==Array?e.merge(r,o):r.push(o))}return r},e.fieldValue=function(t,r){var a=t.name,n=t.type,i=t.tagName.toLowerCase();if(void 0===r&&(r=!0),r&&(!a||t.disabled||"reset"==n||"button"==n||("checkbox"==n||"radio"==n)&&!t.checked||("submit"==n||"image"==n)&&t.form&&t.form.clk!=t||"select"==i&&t.selectedIndex==-1))return null;if("select"==i){var o=t.selectedIndex;if(o<0)return null;for(var s=[],u=t.options,c="select-one"==n,l=c?o+1:u.length,f=c?o:0;f<l;f++){var d=u[f];if(d.selected){var m=d.value;if(m||(m=d.attributes&&d.attributes.value&&!d.attributes.value.specified?d.text:d.value),c)return m;s.push(m)}}return s}return e(t).val()},e.fn.clearForm=function(t){return this.each(function(){e("input,select,textarea",this).clearFields(t)})},e.fn.clearFields=e.fn.clearInputs=function(t){var r=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var a=this.type,n=this.tagName.toLowerCase();r.test(a)||"textarea"==n?this.value="":"checkbox"==a||"radio"==a?this.checked=!1:"select"==n?this.selectedIndex=-1:"file"==a?/MSIE/.test(navigator.userAgent)?e(this).replaceWith(e(this).clone(!0)):e(this).val(""):t&&(t===!0&&/hidden/.test(a)||"string"==typeof t&&e(this).is(t))&&(this.value="")})},e.fn.resetForm=function(){return this.each(function(){("function"==typeof this.reset||"object"==typeof this.reset&&!this.reset.nodeType)&&this.reset()})},e.fn.enable=function(e){return void 0===e&&(e=!0),this.each(function(){this.disabled=!e})},e.fn.selected=function(t){return void 0===t&&(t=!0),this.each(function(){var r=this.type;if("checkbox"==r||"radio"==r)this.checked=t;else if("option"==this.tagName.toLowerCase()){var a=e(this).parent("select");t&&a[0]&&"select-one"==a[0].type&&a.find("option").selected(!1),this.selected=t}})},e.fn.ajaxSubmit.debug=!1}); 2/*! 3 * jQuery Validation Plugin v1.14.0 4 * 5 * http://jqueryvalidation.org/ 6 * 7 * Copyright (c) 2015 Jörn Zaefferer 8 * Released under the MIT license 9 */ 10(function( factory ) { 11 if ( typeof define === "function" && define.amd ) { 12 define( ["jquery"], factory ); 13 } else { 14 factory( jQuery ); 15 } 16}(function( $ ) { 17 18$.extend($.fn, { 19 // http://jqueryvalidation.org/validate/ 20 validate: function( options ) { 21 22 // if nothing is selected, return nothing; can't chain anyway 23 if ( !this.length ) { 24 if ( options && options.debug && window.console ) { 25 console.warn( "Nothing selected, can't validate, returning nothing." ); 26 } 27 return; 28 } 29 30 // check if a validator for this form was already created 31 var validator = $.data( this[ 0 ], "validator" ); 32 if ( validator ) { 33 return validator; 34 } 35 36 // Add novalidate tag if HTML5. 37 this.attr( "novalidate", "novalidate" ); 38 39 validator = new $.validator( options, this[ 0 ] ); 40 $.data( this[ 0 ], "validator", validator ); 41 42 if ( validator.settings.onsubmit ) { 43 44 this.on( "click.validate", ":submit", function( event ) { 45 if ( validator.settings.submitHandler ) { 46 validator.submitButton = event.target; 47 } 48 49 // allow suppressing validation by adding a cancel class to the submit button 50 if ( $( this ).hasClass( "cancel" ) ) { 51 validator.cancelSubmit = true; 52 } 53 54 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 55 if ( $( this ).attr( "formnovalidate" ) !== undefined ) { 56 validator.cancelSubmit = true; 57 } 58 }); 59 60 // validate the form on submit 61 this.on( "submit.validate", function( event ) { 62 if ( validator.settings.debug ) { 63 // prevent form submit to be able to see console output 64 event.preventDefault(); 65 } 66 function handle() { 67 var hidden, result; 68 if ( validator.settings.submitHandler ) { 69 if ( validator.submitButton ) { 70 // insert a hidden input as a replacement for the missing submit button 71 hidden = $( "<input type='hidden'/>" ) 72 .attr( "name", validator.submitButton.name ) 73 .val( $( validator.submitButton ).val() ) 74 .appendTo( validator.currentForm ); 75 } 76 result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); 77 if ( validator.submitButton ) { 78 // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 79 hidden.remove(); 80 } 81 if ( result !== undefined ) { 82 return result; 83 } 84 return false;
85 } 86 return true; 87 } 88 89 // prevent submit for invalid forms or custom submit handlers 90 if ( validator.cancelSubmit ) { 91 validator.cancelSubmit = false; 92 return handle(); 93 } 94 if ( validator.form() ) { 95 if ( validator.pendingRequest ) { 96 validator.formSubmitted = true; 97 return false; 98 } 99 return handle(); 100 } else { 101 validator.focusInvalid(); 102 return false; 103 } 104 }); 105 } 106 107 return validator; 108 }, 109 // http://jqueryvalidation.org/valid/ 110 valid: function() { 111 var valid, validator, errorList; 112 113 if ( $( this[ 0 ] ).is( "form" ) ) { 114 valid = this.validate().form(); 115 } else { 116 errorList = []; 117 valid = true; 118 validator = $( this[ 0 ].form ).validate(); 119 this.each( function() { 120 valid = validator.element( this ) && valid; 121 errorList = errorList.concat( validator.errorList ); 122 }); 123 validator.errorList = errorList; 124 } 125 return valid; 126 }, 127 128 // http://jqueryvalidation.org/rules/ 129 rules: function( command, argument ) { 130 var element = this[ 0 ], 131 settings, staticRules, existingRules, data, param, filtered; 132 133 if ( command ) { 134 settings = $.data( element.form, "validator" ).settings; 135 staticRules = settings.rules; 136 existingRules = $.validator.staticRules( element ); 137 switch ( command ) { 138 case "add": 139 $.extend( existingRules, $.validator.normalizeRule( argument ) ); 140 // remove messages from rules, but allow them to be set separately 141 delete existingRules.messages; 142 staticRules[ element.name ] = existingRules; 143 if ( argument.messages ) { 144 settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); 145 } 146 break; 147 case "remove": 148 if ( !argument ) { 149 delete staticRules[ element.name ]; 150 return existingRules; 151 } 152 filtered = {}; 153 $.each( argument.split( /\s/ ), function( index, method ) { 154 filtered[ method ] = existingRules[ method ]; 155 delete existingRules[ method ]; 156 if ( method === "required" ) { 157 $( element ).removeAttr( "aria-required" ); 158 } 159 }); 160 return filtered; 161 } 162 } 163 164 data = $.validator.normalizeRules( 165 $.extend( 166 {}, 167 $.validator.classRules( element ), 168 $.validator.attributeRules( element ), 169 $.validator.dataRules( element ), 170 $.validator.staticRules( element ) 171 ), element ); 172 173 // make sure required is at front 174 if ( data.required ) { 175 param = data.required; 176 delete data.required; 177 data = $.extend( { required: param }, data ); 178 $( element ).attr( "aria-required", "true" ); 179 } 180 181 // make sure remote is at back 182 if ( data.remote ) { 183 param = data.remote; 184 delete data.remote; 185 data = $.extend( data, { remote: param }); 186 } 187 188 return data; 189 } 190}); 191 192// Custom selectors 193$.extend( $.expr[ ":" ], { 194 // http://jqueryvalidation.org/blank-selector/ 195 blank: function( a ) { 196 return !$.trim( "" + $( a ).val() ); 197 }, 198 // http://jqueryvalidation.org/filled-selector/ 199 filled: function( a ) { 200 return !!$.trim( "" + $( a ).val() ); 201 }, 202 // http://jqueryvalidation.org/unchecked-selector/ 203 unchecked: function( a ) { 204 return !$( a ).prop( "checked" ); 205 } 206}); 207 208// constructor for validator 209$.validator = function( options, form ) { 210 this.settings = $.extend( true, {}, $.validator.defaults, options ); 211 this.currentForm = form; 212 this.init(); 213}; 214 215// http://jqueryvalidation.org/jQuery.validator.format/ 216$.validator.format = function( source, params ) { 217 if ( arguments.length === 1 ) { 218 return function() { 219 var args = $.makeArray( arguments ); 220 args.unshift( source ); 221 return $.validator.format.apply( this, args ); 222 }; 223 } 224 if ( arguments.length > 2 && params.constructor !== Array ) { 225 params = $.makeArray( arguments ).slice( 1 ); 226 } 227 if ( params.constructor !== Array ) { 228 params = [ params ]; 229 } 230 $.each( params, function( i, n ) { 231 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { 232 return n; 233 }); 234 }); 235 return source; 236}; 237 238$.extend( $.validator, { 239 240 defaults: { 241 messages: {}, 242 groups: {}, 243 rules: {}, 244 errorClass: "error", 245 validClass: "valid", 246 errorElement: "label", 247 focusCleanup: false, 248 focusInvalid: true, 249 errorContainer: $( [] ), 250 errorLabelContainer: $( [] ), 251 onsubmit: true, 252 ignore: ":hidden", 253 ignoreTitle: false, 254 onfocusin: function( element ) { 255 this.lastActive = element; 256 257 // Hide error label and remove error class on focus if enabled 258 if ( this.settings.focusCleanup ) { 259 if ( this.settings.unhighlight ) { 260 this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.val
vendor: 4,643 bytes, lines 260-390
260idClass ); 261 } 262 this.hideThese( this.errorsFor( element ) ); 263 } 264 }, 265 onfocusout: function( element ) { 266 if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { 267 this.element( element ); 268 } 269 }, 270 onkeyup: function( element, event ) { 271 // Avoid revalidate the field when pressing one of the following keys 272 // Shift => 16 273 // Ctrl => 17 274 // Alt => 18 275 // Caps lock => 20 276 // End => 35 277 // Home => 36 278 // Left arrow => 37 279 // Up arrow => 38 280 // Right arrow => 39 281 // Down arrow => 40 282 // Insert => 45 283 // Num lock => 144 284 // AltGr key => 225 285 var excludedKeys = [ 286 16, 17, 18, 20, 35, 36, 37, 287 38, 39, 40, 45, 144, 225 288 ]; 289 290 if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) { 291 return; 292 } else if ( element.name in this.submitted || element === this.lastElement ) { 293 this.element( element ); 294 } 295 }, 296 onclick: function( element ) { 297 // click on selects, radiobuttons and checkboxes 298 if ( element.name in this.submitted ) { 299 this.element( element ); 300 301 // or option elements, check parent select in that case 302 } else if ( element.parentNode.name in this.submitted ) { 303 this.element( element.parentNode ); 304 } 305 }, 306 highlight: function( element, errorClass, validClass ) { 307 if ( element.type === "radio" ) { 308 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); 309 } else { 310 $( element ).addClass( errorClass ).removeClass( validClass ); 311 } 312 }, 313 unhighlight: function( element, errorClass, validClass ) { 314 if ( element.type === "radio" ) { 315 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); 316 } else { 317 $( element ).removeClass( errorClass ).addClass( validClass ); 318 } 319 } 320 }, 321 322 // http://jqueryvalidation.org/jQuery.validator.setDefaults/ 323 setDefaults: function( settings ) { 324 $.extend( $.validator.defaults, settings ); 325 }, 326 327 messages: { 328 required: "This field is required.", 329 remote: "Please fix this field.", 330 email: "Please enter a valid email address.", 331 url: "Please enter a valid URL.", 332 date: "Please enter a valid date.", 333 dateISO: "Please enter a valid date ( ISO ).", 334 number: "Please enter a valid number.", 335 digits: "Please enter only digits.", 336 creditcard: "Please enter a valid credit card number.", 337 equalTo: "Please enter the same value again.", 338 maxlength: $.validator.format( "Please enter no more than {0} characters." ), 339 minlength: $.validator.format( "Please enter at least {0} characters." ), 340 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), 341 range: $.validator.format( "Please enter a value between {0} and {1}." ), 342 max: $.validator.format( "Please enter a value less than or equal to {0}." ), 343 min: $.validator.format( "Please enter a value greater than or equal to {0}." ) 344 }, 345 346 autoCreateRanges: false, 347 348 prototype: { 349 350 init: function() { 351 this.labelContainer = $( this.settings.errorLabelContainer ); 352 this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); 353 this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); 354 this.submitted = {}; 355 this.valueCache = {}; 356 this.pendingRequest = 0; 357 this.pending = {}; 358 this.invalid = {}; 359 this.reset(); 360 361 var groups = ( this.groups = {} ), 362 rules; 363 $.each( this.settings.groups, function( key, value ) { 364 if ( typeof value === "string" ) { 365 value = value.split( /\s/ ); 366 } 367 $.each( value, function( index, name ) { 368 groups[ name ] = key; 369 }); 370 }); 371 rules = this.settings.rules; 372 $.each( rules, function( key, value ) { 373 rules[ key ] = $.validator.normalizeRule( value ); 374 }); 375 376 function delegate( event ) { 377 var validator = $.data( this.form, "validator" ), 378 eventType = "on" + event.type.replace( /^validate/, "" ), 379 settings = validator.settings; 380 if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) { 381 settings[ eventType ].call( validator, this, event ); 382 } 383 } 384 385 $( this.currentForm ) 386 .on( "focusin.validate focusout.validate keyup.validate", 387 ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + 388 "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + 389 "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + 390 "[type='radio'], [type='checkbox']", delegate)
391 // Support: Chrome, oldIE 392 // "select" is provided as event.target when clicking a option 393 .on("click.validate", "select, option, [type='radio'], [type='checkbox']", delegate); 394 395 if ( this.settings.invalidHandler ) { 396 $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler ); 397 } 398 399 // Add aria-required to any Static/Data/Class required fields before first validation 400 // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html 401 $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" ); 402 }, 403 404 // http://jqueryvalidation.org/Validator.form/ 405 form: function() { 406 this.checkForm(); 407 $.extend( this.submitted, this.errorMap ); 408 this.invalid = $.extend({}, this.errorMap ); 409 if ( !this.valid() ) { 410 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); 411 } 412 this.showErrors(); 413 return this.valid(); 414 }, 415 416 checkForm: function() { 417 this.prepareForm(); 418 for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { 419 this.check( elements[ i ] ); 420 } 421 return this.valid(); 422 }, 423 424 // http://jqueryvalidation.org/Validator.element/ 425 element: function( element ) { 426 var cleanElement = this.clean( element ), 427 checkElement = this.validationTargetFor( cleanElement ), 428 result = true; 429 430 this.lastElement = checkElement; 431 432 if ( checkElement === undefined ) { 433 delete this.invalid[ cleanElement.name ]; 434 } else { 435 this.prepareElement( checkElement ); 436 this.currentElements = $( checkElement ); 437 438 result = this.check( checkElement ) !== false; 439 if ( result ) { 440 delete this.invalid[ checkElement.name ]; 441 } else { 442 this.invalid[ checkElement.name ] = true; 443 } 444 } 445 // Add aria-invalid status for screen readers 446 $( element ).attr( "aria-invalid", !result ); 447 448 if ( !this.numberOfInvalids() ) { 449 // Hide error containers on last error 450 this.toHide = this.toHide.add( this.containers ); 451 } 452 this.showErrors(); 453 return result; 454 }, 455 456 // http://jqueryvalidation.org/Validator.showErrors/ 457 showErrors: function( errors ) { 458 if ( errors ) { 459 // add items to error list and map 460 $.extend( this.errorMap, errors ); 461 this.errorList = []; 462 for ( var name in errors ) { 463 this.errorList.push({ 464 message: errors[ name ], 465 element: this.findByName( name )[ 0 ] 466 }); 467 } 468 // remove items from success list 469 this.successList = $.grep( this.successList, function( element ) { 470 return !( element.name in errors ); 471 }); 472 } 473 if ( this.settings.showErrors ) { 474 this.settings.showErrors.call( this, this.errorMap, this.errorList ); 475 } else { 476 this.defaultShowErrors(); 477 } 478 }, 479 480 // http://jqueryvalidation.org/Validator.resetForm/ 481 resetForm: function() { 482 if ( $.fn.resetForm ) { 483 $( this.currentForm ).resetForm(); 484 } 485 this.submitted = {}; 486 this.lastElement = null; 487 this.prepareForm(); 488 this.hideErrors(); 489 var i, elements = this.elements() 490 .removeData( "previousValue" ) 491 .removeAttr( "aria-invalid" ); 492 493 if ( this.settings.unhighlight ) { 494 for ( i = 0; elements[ i ]; i++ ) { 495 this.settings.unhighlight.call( this, elements[ i ], 496 this.settings.errorClass, "" ); 497 } 498 } else { 499 elements.removeClass( this.settings.errorClass ); 500 } 501 }, 502 503 numberOfInvalids: function() { 504 return this.objectLength( this.invalid ); 505 }, 506 507 objectLength: function( obj ) { 508 /* jshint unused: false */ 509 var count = 0, 510 i; 511 for ( i in obj ) { 512 count++; 513 } 514 return count; 515 }, 516 517 hideErrors: function() { 518 this.hideThese( this.toHide ); 519 }, 520 521 hideThese: function( errors ) { 522 errors.not( this.containers ).text( "" ); 523 this.addWrapper( errors ).hide(); 524 }, 525 526 valid: function() { 527 return this.size() === 0; 528 }, 529 530 size: function() { 531 return this.errorList.length; 532 }, 533 534 focusInvalid: function() { 535 if ( this.settings.focusInvalid ) { 536 try { 537 $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || []) 538 .filter( ":visible" ) 539 .focus() 540 // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 541 .trigger( "focusin" ); 542 } catch ( e ) {
543 // ignore IE throwing errors when focusing hidden elements 544 } 545 } 546 }, 547 548 findLastActive: function() { 549 var lastActive = this.lastActive; 550 return lastActive && $.grep( this.errorList, function( n ) { 551 return n.element.name === lastActive.name; 552 }).length === 1 && lastActive; 553 }, 554 555 elements: function() { 556 var validator = this, 557 rulesCache = {}; 558 559 // select all valid inputs inside the form (no submit or reset buttons) 560 return $( this.currentForm ) 561 .find( "input, select, textarea" ) 562 .not( ":submit, :reset, :image, :disabled" ) 563 .not( this.settings.ignore ) 564 .filter( function() { 565 if ( !this.name && validator.settings.debug && window.console ) { 566 console.error( "%o has no name assigned", this ); 567 } 568 569 // select only the first element for each name, and only those with rules specified 570 if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { 571 return false; 572 } 573 574 rulesCache[ this.name ] = true; 575 return true; 576 }); 577 }, 578 579 clean: function( selector ) { 580 return $( selector )[ 0 ]; 581 }, 582 583 errors: function() { 584 var errorClass = this.settings.errorClass.split( " " ).join( "." ); 585 return $( this.settings.errorElement + "." + errorClass, this.errorContext ); 586 }, 587 588 reset: function() { 589 this.successList = []; 590 this.errorList = []; 591 this.errorMap = {}; 592 this.toShow = $( [] ); 593 this.toHide = $( [] ); 594 this.currentElements = $( [] ); 595 }, 596 597 prepareForm: function() { 598 this.reset(); 599 this.toHide = this.errors().add( this.containers ); 600 }, 601 602 prepareElement: function( element ) { 603 this.reset(); 604 this.toHide = this.errorsFor( element ); 605 }, 606 607 elementValue: function( element ) { 608 var val, 609 $element = $( element ), 610 type = element.type; 611 612 if ( type === "radio" || type === "checkbox" ) { 613 return this.findByName( element.name ).filter(":checked").val(); 614 } else if ( type === "number" && typeof element.validity !== "undefined" ) { 615 return element.validity.badInput ? false : $element.val(); 616 } 617 618 val = $element.val(); 619 if ( typeof val === "string" ) { 620 return val.replace(/\r/g, "" ); 621 } 622 return val; 623 }, 624 625 check: function( element ) { 626 element = this.validationTargetFor( this.clean( element ) ); 627 628 var rules = $( element ).rules(), 629 rulesCount = $.map( rules, function( n, i ) { 630 return i; 631 }).length, 632 dependencyMismatch = false, 633 val = this.elementValue( element ), 634 result, method, rule; 635 636 for ( method in rules ) { 637 rule = { method: method, parameters: rules[ method ] }; 638 try { 639 640 result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); 641 642 // if a method indicates that the field is optional and therefore valid, 643 // don't mark it as valid when there are no other rules 644 if ( result === "dependency-mismatch" && rulesCount === 1 ) { 645 dependencyMismatch = true; 646 continue; 647 } 648 dependencyMismatch = false; 649 650 if ( result === "pending" ) { 651 this.toHide = this.toHide.not( this.errorsFor( element ) ); 652 return; 653 } 654 655 if ( !result ) { 656 this.formatAndAdd( element, rule ); 657 return false; 658 } 659 } catch ( e ) { 660 if ( this.settings.debug && window.console ) { 661 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 662 } 663 if ( e instanceof TypeError ) { 664 e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method."; 665 } 666 667 throw e; 668 } 669 } 670 if ( dependencyMismatch ) { 671 return; 672 } 673 if ( this.objectLength( rules ) ) { 674 this.successList.push( element ); 675 } 676 return true; 677 }, 678 679 // return the custom message for the given element and validation method 680 // specified in the element's HTML5 data attribute 681 // return the generic message if present and no method specific message is present 682 customDataMessage: function( element, method ) { 683 return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + 684 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); 685 }, 686 687 // return the custom message for the given element name and validation method 688 customMessage: function( name, method ) { 689 var m = this.settings.messages[ name ]; 690 return m && ( m.constructor === String ? m : m[ method ]); 691 }, 692 693 // return the first defined argument, allowing empty strings 694 findDefined: function() { 695 for ( var i = 0; i < arguments.length; i++) { 696 if ( arguments[ i ] !== undefined ) { 697 return arguments[ i ]; 698 } 699 } 700 return undefined; 701 }, 702 703 defaultMessage: function( element, method ) { 704 return this.findDefined( 705 this.customMessage( element.name, method ), 706 this.customDataMessage( element, method ), 707 // title is never undefined, so handle empty string as undefined 708 !this.settings.ignoreTitle && element.title || undefined, 709 $.validator.messages[ method ], 710 "<strong>Warning: No message defined for " + element.name + "</strong>" 711 ); 712 }, 713 714 formatAndAdd: function( element, rule ) { 715 var message = this.defaultMessage( element, rule.method ), 716 theregex = /\$?\{(\d+)\}/g; 717 if ( typeof message === "function" ) { 718 message = message.call( this, rule.parameters, element ); 719 } else if ( theregex.test( message ) ) { 720 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); 721 } 722 this.errorList.push({ 723 message: message, 724 element: element, 725 method: rule.method 726 }); 727 728 this.errorMap[ element.name ] = message; 729 this.submitted[ element.name ] = message; 730 }, 731 732 addWrapper: function( toToggle ) { 733 if ( this.settings.wrapper ) { 734 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 735 } 736 return toToggle; 737 }, 738 739 defaultShowErrors: function() { 740 var i, elements, error; 741 for ( i = 0; this.errorList[ i ]; i++ ) { 742 error = this.errorList[ i ]; 743 if ( this.settings.highlight ) { 744 this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
744idClass ); 745 } 746 this.showLabel( error.element, error.message ); 747 } 748 if ( this.errorList.length ) { 749 this.toShow = this.toShow.add( this.containers ); 750 } 751 if ( this.settings.success ) { 752 for ( i = 0; this.successList[ i ]; i++ ) { 753 this.showLabel( this.successList[ i ] ); 754 } 755 } 756 if ( this.settings.unhighlight ) { 757 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { 758 this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass ); 759 } 760 } 761 this.toHide = this.toHide.not( this.toShow ); 762 this.hideErrors(); 763 this.addWrapper( this.toShow ).show(); 764 }, 765 766 validElements: function() { 767 return this.currentElements.not( this.invalidElements() ); 768 }, 769 770 invalidElements: function() { 771 return $( this.errorList ).map(function() { 772 return this.element; 773 }); 774 }, 775 776 showLabel: function( element, message ) { 777 var place, group, errorID, 778 error = this.errorsFor( element ), 779 elementID = this.idOrName( element ), 780 describedBy = $( element ).attr( "aria-describedby" ); 781 if ( error.length ) { 782 // refresh error/success class 783 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 784 // replace message on existing label 785 error.html( message ); 786 } else { 787 // create error element 788 error = $( "<" + this.settings.errorElement + ">" ) 789 .attr( "id", elementID + "-error" ) 790 .addClass( this.settings.errorClass ) 791 .html( message || "" ); 792 793 // Maintain reference to the element to be placed into the DOM 794 place = error; 795 if ( this.settings.wrapper ) { 796 // make sure the element is visible, even in IE 797 // actually showing the wrapped element is handled elsewhere 798 place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); 799 } 800 if ( this.labelContainer.length ) { 801 this.labelContainer.append( place ); 802 } else if ( this.settings.errorPlacement ) { 803 this.settings.errorPlacement( place, $( element ) ); 804 } else { 805 place.insertAfter( element ); 806 } 807 808 // Link error back to the element 809 if ( error.is( "label" ) ) { 810 // If the error is a label, then associate using 'for' 811 error.attr( "for", elementID ); 812 } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) { 813 // If the element is not a child of an associated label, then it's necessary 814 // to explicitly apply aria-describedby 815 816 errorID = error.attr( "id" ).replace( /(:|\.|\[|\]|\$)/g, "\\$1"); 817 // Respect existing non-error aria-describedby 818 if ( !describedBy ) { 819 describedBy = errorID; 820 } else if ( !describedBy.match( new RegExp( "\\b" + errorID + "\\b" ) ) ) { 821 // Add to end of list if not already present 822 describedBy += " " + errorID; 823 } 824 $( element ).attr( "aria-describedby", describedBy ); 825 826 // If this element is grouped, then assign to all elements in the same group 827 group = this.groups[ element.name ]; 828 if ( group ) { 829 $.each( this.groups, function( name, testgroup ) { 830 if ( testgroup === group ) { 831 $( "[name='" + name + "']", this.currentForm ) 832 .attr( "aria-describedby", error.attr( "id" ) ); 833 } 834 }); 835 } 836 } 837 } 838 if ( !message && this.settings.success ) { 839 error.text( "" ); 840 if ( typeof this.settings.success === "string" ) { 841 error.addClass( this.settings.success ); 842 } else { 843 this.settings.success( error, element ); 844 } 845 } 846 this.toShow = this.toShow.add( error ); 847 }, 848 849 errorsFor: function( element ) { 850 var name = this.idOrName( element ), 851 describer = $( element ).attr( "aria-describedby" ), 852 selector = "label[for='" + name + "'], label[for='" + name + "'] *"; 853 854 // aria-describedby should directly reference the error element 855 if ( describer ) { 856 selector = selector + ", #" + describer.replace( /\s+/g, ", #" ); 857 } 858 return this 859 .errors() 860 .filter( selector ); 861 }, 862 863 idOrName: function( element ) { 864 return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.i
vendor: 9,590 bytes, lines 864-1196
864d || element.name ); 865 }, 866 867 validationTargetFor: function( element ) { 868 869 // If radio/checkbox, validate first element in group instead 870 if ( this.checkable( element ) ) { 871 element = this.findByName( element.name ); 872 } 873 874 // Always apply ignore filter 875 return $( element ).not( this.settings.ignore )[ 0 ]; 876 }, 877 878 checkable: function( element ) { 879 return ( /radio|checkbox/i ).test( element.type ); 880 }, 881 882 findByName: function( name ) { 883 return $( this.currentForm ).find( "[name='" + name + "']" ); 884 }, 885 886 getLength: function( value, element ) { 887 switch ( element.nodeName.toLowerCase() ) { 888 case "select": 889 return $( "option:selected", element ).length; 890 case "input": 891 if ( this.checkable( element ) ) { 892 return this.findByName( element.name ).filter( ":checked" ).length; 893 } 894 } 895 return value.length; 896 }, 897 898 depend: function( param, element ) { 899 return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true; 900 }, 901 902 dependTypes: { 903 "boolean": function( param ) { 904 return param; 905 }, 906 "string": function( param, element ) { 907 return !!$( param, element.form ).length; 908 }, 909 "function": function( param, element ) { 910 return param( element ); 911 } 912 }, 913 914 optional: function( element ) { 915 var val = this.elementValue( element ); 916 return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; 917 }, 918 919 startRequest: function( element ) { 920 if ( !this.pending[ element.name ] ) { 921 this.pendingRequest++; 922 this.pending[ element.name ] = true; 923 } 924 }, 925 926 stopRequest: function( element, valid ) { 927 this.pendingRequest--; 928 // sometimes synchronization fails, make sure pendingRequest is never < 0 929 if ( this.pendingRequest < 0 ) { 930 this.pendingRequest = 0; 931 } 932 delete this.pending[ element.name ]; 933 if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 934 $( this.currentForm ).submit(); 935 this.formSubmitted = false; 936 } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) { 937 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); 938 this.formSubmitted = false; 939 } 940 }, 941 942 previousValue: function( element ) { 943 return $.data( element, "previousValue" ) || $.data( element, "previousValue", { 944 old: null, 945 valid: true, 946 message: this.defaultMessage( element, "remote" ) 947 }); 948 }, 949 950 // cleans up all forms and elements, removes validator-specific events 951 destroy: function() { 952 this.resetForm(); 953 954 $( this.currentForm ) 955 .off( ".validate" ) 956 .removeData( "validator" ); 957 } 958 959 }, 960 961 classRuleSettings: { 962 required: { required: true }, 963 email: { email: true }, 964 url: { url: true }, 965 date: { date: true }, 966 dateISO: { dateISO: true }, 967 number: { number: true }, 968 digits: { digits: true }, 969 creditcard: { creditcard: true } 970 }, 971 972 addClassRules: function( className, rules ) { 973 if ( className.constructor === String ) { 974 this.classRuleSettings[ className ] = rules; 975 } else { 976 $.extend( this.classRuleSettings, className ); 977 } 978 }, 979 980 classRules: function( element ) { 981 var rules = {}, 982 classes = $( element ).attr( "class" ); 983 984 if ( classes ) { 985 $.each( classes.split( " " ), function() { 986 if ( this in $.validator.classRuleSettings ) { 987 $.extend( rules, $.validator.classRuleSettings[ this ]); 988 } 989 }); 990 } 991 return rules; 992 }, 993 994 normalizeAttributeRule: function( rules, type, method, value ) { 995 996 // convert the value to a number for number inputs, and for text for backwards compability 997 // allows type="date" and others to be compared as strings 998 if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 999 value = Number( value ); 1000 1001 // Support Opera Mini, which returns NaN for undefined minlength 1002 if ( isNaN( value ) ) { 1003 value = undefined; 1004 } 1005 } 1006 1007 if ( value || value === 0 ) { 1008 rules[ method ] = value; 1009 } else if ( type === method && type !== "range" ) { 1010 1011 // exception: the jquery validate 'range' method 1012 // does not test for the html5 'range' type 1013 rules[ method ] = true; 1014 } 1015 }, 1016 1017 attributeRules: function( element ) { 1018 var rules = {}, 1019 $element = $( element ), 1020 type = element.getAttribute( "type" ), 1021 method, value; 1022 1023 for ( method in $.validator.methods ) { 1024 1025 // support for <input required> in both html5 and older browsers 1026 if ( method === "required" ) { 1027 value = element.getAttribute( method ); 1028 1029 // Some browsers return an empty string for the required attribute 1030 // and non-HTML5 browsers might have required="" markup 1031 if ( value === "" ) { 1032 value = true; 1033 } 1034 1035 // force non-HTML5 browsers to return bool 1036 value = !!value; 1037 } else { 1038 value = $element.attr( method ); 1039 } 1040 1041 this.normalizeAttributeRule( rules, type, method, value ); 1042 } 1043 1044 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs 1045 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { 1046 delete rules.maxlength; 1047 } 1048 1049 return rules; 1050 }, 1051 1052 dataRules: function( element ) { 1053 var rules = {}, 1054 $element = $( element ), 1055 type = element.getAttribute( "type" ), 1056 method, value; 1057 1058 for ( method in $.validator.methods ) { 1059 value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); 1060 this.normalizeAttributeRule( rules, type, method, value ); 1061 } 1062 return rules; 1063 }, 1064 1065 staticRules: function( element ) { 1066 var rules = {}, 1067 validator = $.data( element.form, "validator" ); 1068 1069 if ( validator.settings.rules ) { 1070 rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; 1071 } 1072 return rules; 1073 }, 1074 1075 normalizeRules: function( rules, element ) { 1076 // handle dependency check 1077 $.each( rules, function( prop, val ) { 1078 // ignore rule when param is explicitly false, eg. required:false 1079 if ( val === false ) { 1080 delete rules[ prop ]; 1081 return; 1082 } 1083 if ( val.param || val.depends ) { 1084 var keepRule = true; 1085 switch ( typeof val.depends ) { 1086 case "string": 1087 keepRule = !!$( val.depends, element.form ).length; 1088 break; 1089 case "function": 1090 keepRule = val.depends.call( element, element ); 1091 break; 1092 } 1093 if ( keepRule ) { 1094 rules[ prop ] = val.param !== undefined ? val.param : true; 1095 } else { 1096 delete rules[ prop ]; 1097 } 1098 } 1099 }); 1100 1101 // evaluate parameters 1102 $.each( rules, function( rule, parameter ) { 1103 rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter; 1104 }); 1105 1106 // clean number parameters 1107 $.each([ "minlength", "maxlength" ], function() { 1108 if ( rules[ this ] ) { 1109 rules[ this ] = Number( rules[ this ] ); 1110 } 1111 }); 1112 $.each([ "rangelength", "range" ], function() { 1113 var parts; 1114 if ( rules[ this ] ) { 1115 if ( $.isArray( rules[ this ] ) ) { 1116 rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ]; 1117 } else if ( typeof rules[ this ] === "string" ) { 1118 parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ ); 1119 rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ]; 1120 } 1121 } 1122 }); 1123 1124 if ( $.validator.autoCreateRanges ) { 1125 // auto-create ranges 1126 if ( rules.min != null && rules.max != null ) { 1127 rules.range = [ rules.min, rules.max ]; 1128 delete rules.min; 1129 delete rules.max; 1130 } 1131 if ( rules.minlength != null && rules.maxlength != null ) { 1132 rules.rangelength = [ rules.minlength, rules.maxlength ]; 1133 delete rules.minlength; 1134 delete rules.maxlength; 1135 } 1136 } 1137 1138 return rules; 1139 }, 1140 1141 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 1142 normalizeRule: function( data ) { 1143 if ( typeof data === "string" ) { 1144 var transformed = {}; 1145 $.each( data.split( /\s/ ), function() { 1146 transformed[ this ] = true; 1147 }); 1148 data = transformed; 1149 } 1150 return data; 1151 }, 1152 1153 // http://jqueryvalidation.org/jQuery.validator.addMethod/ 1154 addMethod: function( name, method, message ) { 1155 $.validator.methods[ name ] = method; 1156 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; 1157 if ( method.length < 3 ) { 1158 $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); 1159 } 1160 }, 1161 1162 methods: { 1163 1164 // http://jqueryvalidation.org/required-method/ 1165 required: function( value, element, param ) { 1166 // check if dependency is met 1167 if ( !this.depend( param, element ) ) { 1168 return "dependency-mismatch"; 1169 } 1170 if ( element.nodeName.toLowerCase() === "select" ) { 1171 // could be an array for select-multiple or a string, both are fine this way 1172 var val = $( element ).val(); 1173 return val && val.length > 0; 1174 } 1175 if ( this.checkable( element ) ) { 1176 return this.getLength( value, element ) > 0; 1177 } 1178 return value.length > 0; 1179 }, 1180 1181 // http://jqueryvalidation.org/email-method/ 1182 email: function( value, element ) { 1183 // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address 1184 // Retrieved 2014-01-14 1185 // If you have a problem with this implementation, report a bug against the above spec 1186 // Or use custom methods to implement your own email validation 1187 return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); 1188 }, 1189 1190 // http://jqueryvalidation.org/url-method/ 1191 url: function( value, element ) { 1192 1193 // Copyright (c) 2010-2013 Diego Perini, MIT licensed 1194 // https://gist.github.com/dperini/729294 1195 // see also https://mathiasbynens.be/demo/url-regex 1196 // modified to allow protocol-relative URLs
1197 return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); 1198 }, 1199 1200 // http://jqueryvalidation.org/date-method/ 1201 date: function( value, element ) { 1202 return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); 1203 }, 1204 1205 // http://jqueryvalidation.org/dateISO-method/ 1206 dateISO: function( value, element ) { 1207 return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); 1208 }, 1209 1210 // http://jqueryvalidation.org/number-method/ 1211 number: function( value, element ) { 1212 return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); 1213 }, 1214 1215 // http://jqueryvalidation.org/digits-method/ 1216 digits: function( value, element ) { 1217 return this.optional( element ) || /^\d+$/.test( value ); 1218 }, 1219 1220 // http://jqueryvalidation.org/creditcard-method/ 1221 // based on http://en.wikipedia.org/wiki/Luhn_algorithm 1222 creditcard: function( value, element ) { 1223 if ( this.optional( element ) ) { 1224 return "dependency-mismatch"; 1225 } 1226 // accept only spaces, digits and dashes 1227 if ( /[^0-9 \-]+/.test( value ) ) { 1228 return false; 1229 } 1230 var nCheck = 0, 1231 nDigit = 0, 1232 bEven = false, 1233 n, cDigit; 1234 1235 value = value.replace( /\D/g, "" ); 1236 1237 // Basing min and max length on 1238 // http://developer.ean.com/general_info/Valid_Credit_Card_Types 1239 if ( value.length < 13 || value.length > 19 ) { 1240 return false; 1241 } 1242 1243 for ( n = value.length - 1; n >= 0; n--) { 1244 cDigit = value.charAt( n ); 1245 nDigit = parseInt( cDigit, 10 ); 1246 if ( bEven ) { 1247 if ( ( nDigit *= 2 ) > 9 ) { 1248 nDigit -= 9; 1249 } 1250 } 1251 nCheck += nDigit; 1252 bEven = !bEven; 1253 } 1254 1255 return ( nCheck % 10 ) === 0; 1256 }, 1257 1258 // http://jqueryvalidation.org/minlength-method/ 1259 minlength: function( value, element, param ) { 1260 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1261 return this.optional( element ) || length >= param; 1262 }, 1263 1264 // http://jqueryvalidation.org/maxlength-method/ 1265 maxlength: function( value, element, param ) { 1266 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1267 return this.optional( element ) || length <= param; 1268 }, 1269 1270 // http://jqueryvalidation.org/rangelength-method/ 1271 rangelength: function( value, element, param ) { 1272 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1273 return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); 1274 }, 1275 1276 // http://jqueryvalidation.org/min-method/ 1277 min: function( value, element, param ) { 1278 return this.optional( element ) || value >= param; 1279 }, 1280 1281 // http://jqueryvalidation.org/max-method/ 1282 max: function( value, element, param ) { 1283 return this.optional( element ) || value <= param; 1284 }, 1285 1286 // http://jqueryvalidation.org/range-method/ 1287 range: function( value, element, param ) { 1288 return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); 1289 }, 1290 1291 // http://jqueryvalidation.org/equalTo-method/ 1292 equalTo: function( value, element, param ) {
1293 // bind to the blur event of the target in order to revalidate whenever the target field is updated 1294 // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 1295 var target = $( param ); 1296 if ( this.settings.onfocusout ) { 1297 target.off( ".validate-equalTo" ).on( "blur.validate-equalTo", function() { 1298 $( element ).valid(); 1299 }); 1300 } 1301 return value === target.val(); 1302 }, 1303 1304 // http://jqueryvalidation.org/remote-method/ 1305 remote: function( value, element, param ) { 1306 if ( this.optional( element ) ) { 1307 return "dependency-mismatch"; 1308 } 1309 1310 var previous = this.previousValue( element ), 1311 validator, data; 1312 1313 if (!this.settings.messages[ element.name ] ) { 1314 this.settings.messages[ element.name ] = {}; 1315 } 1316 previous.originalMessage = this.settings.messages[ element.name ].remote; 1317 this.settings.messages[ element.name ].remote = previous.message; 1318 1319 param = typeof param === "string" && { url: param } || param; 1320 1321 if ( previous.old === value ) { 1322 return previous.valid; 1323 } 1324 1325 previous.old = value; 1326 validator = this; 1327 this.startRequest( element ); 1328 data = {}; 1329 data[ element.name ] = value; 1330 $.ajax( $.extend( true, { 1331 mode: "abort", 1332 port: "validate" + element.name, 1333 dataType: "json", 1334 data: data, 1335 context: validator.currentForm, 1336 success: function( response ) { 1337 var valid = response === true || response === "true", 1338 errors, message, submitted; 1339 1340 validator.settings.messages[ element.name ].remote = previous.originalMessage; 1341 if ( valid ) { 1342 submitted = validator.formSubmitted; 1343 validator.prepareElement( element ); 1344 validator.formSubmitted = submitted; 1345 validator.successList.push( element ); 1346 delete validator.invalid[ element.name ]; 1347 validator.showErrors(); 1348 } else { 1349 errors = {}; 1350 message = response || validator.defaultMessage( element, "remote" ); 1351 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message; 1352 validator.invalid[ element.name ] = true; 1353 validator.showErrors( errors ); 1354 } 1355 previous.valid = valid; 1356 validator.stopRequest( element, valid ); 1357 } 1358 }, param ) ); 1359 return "pending"; 1360 } 1361 } 1362 1363}); 1364 1365// ajax mode: abort 1366// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1367// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1368 1369var pendingRequests = {}, 1370 ajax; 1371// Use a prefilter if available (1.5+) 1372if ( $.ajaxPrefilter ) { 1373 $.ajaxPrefilter(function( settings, _, xhr ) { 1374 var port = settings.port; 1375 if ( settings.mode === "abort" ) { 1376 if ( pendingRequests[port] ) { 1377 pendingRequests[port].abort(); 1378 } 1379 pendingRequests[port] = xhr; 1380 } 1381 }); 1382} else { 1383 // Proxy ajax 1384 ajax = $.ajax; 1385 $.ajax = function( settings ) { 1386 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 1387 port = ( "port" in settings ? settings : $.ajaxSettings ).port; 1388 if ( mode === "abort" ) { 1389 if ( pendingRequests[port] ) { 1390 pendingRequests[port].abort(); 1391 } 1392 pendingRequests[port] = ajax.apply(this, arguments); 1393 return pendingRequests[port]; 1394 } 1395 return ajax.apply(this, arguments); 1396 }; 1397} 1398 1399})); 1400"use strict";window.RepToLink=function(e){function r(e){var r=e||{};this.queryTag=r.queryTag||"span",this.queryClass=r.queryClass||'[data-rel="nofollow"]'}function n(r,n){var t=void 0,i=r.parentNode;if(void 0===this)throw new Error("[RepToLink] Missing context in convertTag()");t=e.createElement("a");for(var o in n)n.hasOwnProperty(o)&&(t[o]=n[o]);t.innerHTML=r.innerHTML,t.className=r.className,i.replaceChild(t,r)}function t(){var r=void 0;if(void 0===this)throw new Error("[RepToLink] Missing context in getElements()");return r=e.querySelectorAll(this.queryTag+this.queryClass),void 0!==r[0]&&(r=[].slice.call(r))}return r.prototype.convertToLinks=function(){var e=this,r=t.apply(this);if(r===!1)throw new Error('[RepToLink] Bad request, no search result(s)(<tag>: "'+this.queryTag+'", <class>: "'+this.queryClass+'"');if(!(r instanceof Array))throw new TypeError('[RepToLink] Element(s) must be "Array"');r.forEach(function(r){n.call(e,r,r.dataset)})},r}(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.