").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!c.settings.submitHandler||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&(!j.form&&j.hasAttribute("contenteditable")&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name"));var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=d),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);if("function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f){if(j=f.call(b,j),"string"!=typeof j)throw new TypeError("The normalizer should return a string value.");delete g.normalizer}for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[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(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?: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(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});
Apache Tomcat là gì? Định nghĩa, tính năng và hướng dẫn cài đặt
21/11/2023
Apache Tomcat – một trong những dự án phần mềm mã nguồn mở nổi tiếng, đóng vai trò quan trọng trong quá trình triển khai ứng dụng Java Servlet và JavaServer Pages (JSP). Để giúp bạn hiểu cách tích hợp và sử dụng một trong những container Servlet và JSP phổ biến nhất hiện có trên thị trường, Tothost sẽ giới thiệu cho bạn về Apache Tomcat và cách cài đặt chi tiết.
Mục lục
Mục lục
1. Định nghĩa về Apache Tomcat là gì?
Trước khi bắt đầu với Apache Tomcat, chúng ta cần nhắc lại về Apache: Apache là một web server sử dụng open source rất phổ biến hiện nay, nó phục vụ chủ yếu cho các trang web và ứng dụng web. Apache là một phần mềm máy chủ HTTP, có khả năng xử lý các yêu cầu HTTP từ máy tính của người dùng và gửi lại trang web hoặc dữ liệu tương ứng. Đọc thêm về Apache tại đây.
Tomcat hay Apache Tomcat là web server HTTP do Apache Software Foundation phát triển từ năm 1998. Tomcat được phát triển để thực hiện và quản lý các ứng dụng Java Servlet và trang web JavaServer Pages (JSP). Nó cung cấp một môi trường cho các ứng dụng Java, cho phép chúng hoạt động trên máy chủ web.
Tomcat là một phần quan trọng của dự án Apache và thường được sử dụng trong các ứng dụng web Java để thực hiện các nhiệm vụ liên quan đến Java Servlet và JSP cũng như xử lý các yêu cầu HTTP. Bởi vì nó nhẹ và linh hoạt, Tomcat được sử dụng rộng rãi trong cộng đồng phát triển ứng dụng web Java.
2. Tính năng của Apache Tomcat
Nhờ những tính năng quan trọng mà Apache Tomcat đã trở thành một máy chủ ứng dụng phổ biến trong cộng đồng phát triển web Java:
Hỗ trợ Servlet và JSP: Apache Tomcat là một máy chủ cho ứng dụng web Java EE cung cấp môi trường thực thi cho Servlet và JSP (JavaServer Pages).
Quản lý cấu hình dễ dàng: Tomcat cung cấp công cụ quản lý cấu hình dựa trên giao diện web, giúp người quản trị điều chỉnh thông số của máy chủ một cách dễ dàng.
Hỗ trợ SSL: Để đảm bảo a toàn cho việc truyền dữ liệu giữa khách hàng và máy chủ, Apache Tomcat hỗ trợ Layer Secure Sockets (SSL).
Quản lý người dùng và phân quyền: Các công cụ của Tomcat cho phép các nhà quản lý kiểm soát quyền truy cập của các ứng dụng và tài nguyên.
Thiết lập và quản lý trang quản trị: Trang quản trị web của máy chủ cung cấp giao diện quản trị, cho phép bạn theo dõi và quản lý các ứng dụng và cài đặt.
Hỗ trợ clustering: Tomcat hỗ trợ clustering, điều này cho phép triển khai các ứng dụng trên nhiều máy chủ, tăng độ tin cậy và khả năng mở rộng.
Quản lý tài nguyên: cung cấp các công cụ quản lý tài nguyên để theo dõi và quản lý việc sử dụng tài nguyên của máy chủ.
Hỗ trợ nhiều ngôn ngữ: Apache Tomcat hỗ trợ nhiều ngôn ngữ lập trình, giúp phát triển ứng dụng đa ngôn ngữ.
3. Ưu điểm và nhược điểm của Apache Tomcat là gì?
3.1. Ưu điểm
Cung cấp tính ổn định.
Có tất cả các tính năng mà các ứng dụng thương mại trực tuyến có thể có.
Đây là một phiên bản mã nguồn mở của Apache.
Một số chức năng khác của Tomcat bao gồm các ứng dụng Tomcat quản lý, triển khai vùng chuyên môn và Tomcat valves.
Hỗ trợ các hệ điều hành như Windows, Linux, Mac OS và BSD.
Các phiên bản của Apache Tomcat phù hợp với các đặc điểm kỹ thuật của Java Servlet hoặc Java Servlet API.
Cộng đồng mạnh mẽ.
3.2. Nhược điểm
Việc sử dụng Apache Tomcat có thể gặp phải một số vấn đề về hiệu năng của website với lượng truy cập lớn.
Có nguy cơ về bảo mật do có nhiều lựa chọn.
4. Hướng dẫn cách cài đặt Apache Tomcat chi tiết
4.1. Cài đặt Apache Tomcat trên Windows
Bước 1: Truy cập vào đường dẫn: https://tomcat.apache.org/ > Vào mục Download > Chọn phiên bản TomCat mong muốn > Chọn Binary Distributions > Chọn Core > Chọn “zip” package. Nếu bạn chưa biết phiên bản nào phù hợp hãy tham khảo tại: https://tomcat.apache.org/whichversion.html
Bước 2: Sau khi đã tải xuống Tomcat, giải nén tập tin và cài đặt vào ổ C:// (Vì source được xây dựng mặc định cho ổ C)
Bước 3: Khởi động Tomcat bằng cách đến thư mục bin trong d:myproject tomcat > chạy file startup.bat. Nếu không có lỗi nào xảy ra thì bạn đã cài đặt thành công.
Bước 4: Cấu hình: File cấu hình của Tomcat được lưu trữ tại thư mục conf, tại đây sẽ bao gồm 4 file phục vụ cho việc cấu hình: 1. xml: Gồm cấu hình cổng mặc định của TCP, cấu hình trong Tomcat là 8080. Bạn có thể thay đổi thông số này từ 1024 đến 65535. 2. web.xml. 3. context.xml. 4. tomcat-users.xml: Nó được sử dụng trong việc kích hoạt các tính năng quản lý của Tomcat. Để hoàn tất quá trình cấu hình, ta có thể tiến hành tắt Tomcat rồi khởi động nó lại bằng cách chạy 2 file sau: shutdown.bat và startup.bat.
4.2. Cài đặt Apache Tomcat trên Ubuntu
Đối với Ubuntu, bạn có thể làm theo các bước sau để cài đặt:
Bước 1: Cài đặt Java: Sử dụng command sau để kiểm tra đã cài đặt package Java Development Kit (Open JDK) chưa: sudo apt list --installed | grep jdk Nếu chưa cài đặt hãy sử dụng lệnh sau: sudo apt-get update sudo apt-get install default-jdk
Bước 2: Tạo tài khoản Tomcat: Vì một số lý do bảo mật, Tomcat cần được thiết lập để chạy như một người dùng không có đặc quyền (nghĩa là không phải root). Hãy làm như sau: + Tạo group Tomcat: sudo groupadd tomcat + Tạo user: sudo useradd-s bin/false -g tomcat -d/opt/tomcat tomcat Trong đó, -s bin/false có thể hiểu đơn giản là 1 dạng user không ai có thể truy cập vào được.
Bước 3: Cài đặt Apache Tomcat: Truy cập trang web chính thức của Apache Tomcat để tải xuống phiên bản mới nhất: https://tomcat.apache.org/. Sau đó, thao tác những lệnh sau: Chuyển tới thư mục tmp cd /tmp Download Apache Tomcat 9 (bạn hãy thay đổi theo phiên bản cài đặt của bạn nhé): wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.26/bin/apache-tomcat-9.0.26.zip Giải nén Tomcat 9 và thư mục cài đặt: sudo unzip apache-tomcat-9.0.26.zip -d /opt/tomcat Cập nhật lại quyền cho thư mục cài đặt Tomcat Chuyển đến thư mục /opt/tomcat: cd /opt/tomcat mv apache-tomcat-9.0.26/* Cấp quyền sở hữu thư mục cài đặt cho group “tomcat” sudo chgrp -R tomcat /opt/tomcat sudo sh -c 'chmod +x /opt/tomcat/bin/*.sh' sudo chown tomcat:tomcat -R /opt/tomcat Cấp quyền đọc và thực thi cho thư mục conf sudo chmod -R g+r conf sudo chmod g+x conf Cuối cùng cấp quyền sở hữu cho user “tomcat” mkdir -p webapps/work/temp/logs/ sudo chown -R tomcat webapps/work/temp/logs/
Bước 4: Thiết lập chạy Tomcat Tạo mới file /etc/systemd/system/tomcat.service có nội dung như sau:
Cần phải reload lại System Daemon để Systemd nhận dạng dịch vụ vừa tạo: sudo systemctl daemon-reload
Khởi động Apache Tomcat qua command sau: sudo systemctl start tomcat
Kiểm tra Tomcat đã được bật hay chưa: sudo systemtcl status tomcat
Bước 5: Kiểm tra hoạt động bằng cách nhập tên miền máy chủ hoặc địa chỉ IP theo cổng 8080: http://localhost:8080
Kết luận
Trong bài viết này, chúng ta đã tìm hiểu về Apache Tomcat – một công cụ hữu ích quan trọng cho việc triển khai ứng dụng web sử dụng Java Servlet và JSP. Tothost hy vọng rằng bạn đã hiểu rõ về Apache Tomcat, từ việc hiểu rõ về định nghĩa và chức năng của nó đến quá trình cài đặt.
Trong thời đại tự động hóa, việc kết nối các dịch vụ Google như Gmail, Google Sheets, Calendar... vào quy trình làm việc đang trở thành nhu cầu phổ biến với mọi cá nhân và tổ chức. Và tích hợp API Google với n8n - nền tảng workflow automation mã nguồn mở - sẽ giúp bạn xây dựng các quy trình tự động linh hoạt, tiết kiệm thời gian và giảm thiểu các tác vụ thủ công. Bài viết này sẽ hướng dẫn bạn từng bước kết nối API Google với n8n một cách chi tiết và an toàn, kể cả khi bạn chưa từng cấu hình OAuth 2.0 trước đây cũng có thể dễ dàng thực hiện thành công.
Quản lý nhiều tài khoản mạng xã hội và đăng bài thường xuyên thường tốn không ít thời gian. Bài viết này hướng dẫn bạn cách xây dựng hệ thống tự động hóa đăng bài (auto post) lên các nền tảng social media như Facebook, Twitter, LinkedIn bằng n8n – công cụ workflow automation mã nguồn mở, giúp tự động hóa quy trình, không cần thao tác thủ công hằng ngày mà vẫn đảm bảo sự hiện diện liên tục
Facebook chỉ hỗ trợ lên lịch đăng bài trên fanpage nhưng đăng bình luận thì không. Vì vậy, muốn comment vào những post đã lên lịch sẵn, chúng ta chỉ có cách canh giờ bài được đăng và vào bình luận thủ công. Làm thế nào tự động hóa toàn bộ? Trong bài viết này, TotHost sẽ hướng dẫn bạn cách xây dựng workflow trên n8n để có thể tự động comment cho các bài viết trên fanpage, kể các những bài mới chỉ có lịch đăng, chưa thực sự “lên sóng”.
Sử dụng VPS Forex để chạy nhiều tài khoản MT4/MT5 giao dịch hoặc copy trade là một lựa chọn thông minh và phổ biến. Vậy một VPS có thể chạy được bao nhiêu tài khoản cùng lúc? Cùng TotHost tìm câu trả lời trong bài viết này nhé.
Bạn có biết rằng một VPS được tối ưu đúng cách không chỉ giúp bạn khai thác tiền điện tử hiệu quả hơn mà còn tiết kiệm chi phí duy trì vận hành đáng kể? Trong bài viết này, chúng tôi sẽ hướng dẫn bạn những bí quyết thực tiễn nhất để khai thác tối đa hiệu suất của VPS – từ cách chọn cấu hình, nhà cung cấp cho đến triển khai công cụ phù hợp.
Tìm hiểu n8n - nền tảng workflow automation mã nguồn mở, linh hoạt, dễ dàng tùy biến, giúp tự động hóa quy trình marketing, CRM, IT chỉ trong vài bước đơn giản.