formique 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/formique.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}module.exports=class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{if(this.formMarkUp+=this.renderFormElement(),this.renderForm(),this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formId}`).addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this))}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}};
1
+ "use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}module.exports=class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{this.formMarkUp+=this.renderFormElement();const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e;const n=this.formSchema.find((e=>"submit"===e[0]));if(n){const[e,t,i,s,l={}]=n,r=l.id||t;let a=this.submitButtonClass;"class"in l&&(a=l.class);let o="";for(const[e,n]of Object.entries(l))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);this.formMarkUp+=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n </div>\n <input type="submit" id="${r}" class="${a}" value="${i}"${o}>\n `}this.renderFormHTML();const t=document.getElementById(`${this.formId}`);if(t?t.addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this)):console.error(`Form with ID ${this.formId} not found after rendering. Event listener could not be attached.`),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId)}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderSubmitButtonElement(){const e=this.formSchema.find((e=>"submit"===e[0]));if(e){const[n,t,i,s,l={}]=e,r=l.id||t;let a=this.submitButtonClass;"class"in l&&(a=l.class);let o="";for(const[e,n]of Object.entries(l))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);return`\n<div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n<input type="submit" id="${r}" class="${a}" value="${i}"${o}>\n `.trim()}return""}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r=this.submitButtonClass;"class"in s&&(r=s.class);let a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);return`<input type="${e}" id="${l}" class="${r}" value="${t}"${a}>`}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);"class"in s&&(o=s.class),"color"===e&&(o+=" form-color-input");let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n \x3c!--<label for="${d}">${t} \n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label> --\x3e\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight","src","alt","width","height"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";const o=s?.binding;if("bind:value"===o&&n&&(a=`bind:value="${n}"\n`),"string"==typeof o&&o.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),o&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="image"===e&&"submit"===n?`\n <input \n type="image"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n src="${s.src||"img_submit.gif"}"\n alt="${s.alt||"Submit"}"\n width="${s.width||"48"}"\n height="${s.height||"48"}"\n ${$}\n ${r}\n />`:`\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n ${$}\n ${r}\n />`;let p=`\n <div class="${this.divClass}" id="${c+"-block"}">\n ${"image"===e&&"submit"===n?"":`<label for="${c}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>`}\n ${d}\n </div>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));return p=p.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),p}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){console.log("Within");const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}};
package/formique.mjs CHANGED
@@ -1 +1 @@
1
- class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}class n extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{if(this.formMarkUp+=this.renderFormElement(),this.renderForm(),this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formId}`).addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this))}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}export{n as default};
1
+ class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}class n extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{this.formMarkUp+=this.renderFormElement();const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e;const n=this.formSchema.find((e=>"submit"===e[0]));if(n){const[e,t,i,s,l={}]=n,r=l.id||t;let a=this.submitButtonClass;"class"in l&&(a=l.class);let o="";for(const[e,n]of Object.entries(l))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);this.formMarkUp+=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n </div>\n <input type="submit" id="${r}" class="${a}" value="${i}"${o}>\n `}this.renderFormHTML();const t=document.getElementById(`${this.formId}`);if(t?t.addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this)):console.error(`Form with ID ${this.formId} not found after rendering. Event listener could not be attached.`),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId)}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderSubmitButtonElement(){const e=this.formSchema.find((e=>"submit"===e[0]));if(e){const[n,t,i,s,l={}]=e,r=l.id||t;let a=this.submitButtonClass;"class"in l&&(a=l.class);let o="";for(const[e,n]of Object.entries(l))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);return`\n<div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n<input type="submit" id="${r}" class="${a}" value="${i}"${o}>\n `.trim()}return""}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r=this.submitButtonClass;"class"in s&&(r=s.class);let a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);return`<input type="${e}" id="${l}" class="${r}" value="${t}"${a}>`}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);"class"in s&&(o=s.class),"color"===e&&(o+=" form-color-input");let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n \x3c!--<label for="${d}">${t} \n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label> --\x3e\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight","src","alt","width","height"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";const o=s?.binding;if("bind:value"===o&&n&&(a=`bind:value="${n}"\n`),"string"==typeof o&&o.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),o&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="image"===e&&"submit"===n?`\n <input \n type="image"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n src="${s.src||"img_submit.gif"}"\n alt="${s.alt||"Submit"}"\n width="${s.width||"48"}"\n height="${s.height||"48"}"\n ${$}\n ${r}\n />`:`\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n ${$}\n ${r}\n />`;let p=`\n <div class="${this.divClass}" id="${c+"-block"}">\n ${"image"===e&&"submit"===n?"":`<label for="${c}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>`}\n ${d}\n </div>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));return p=p.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),p}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){console.log("Within");const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}export{n as default};
package/formique.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).Formique=n()}(this,(function(){"use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}return class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","light","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{if(this.formMarkUp+=this.renderFormElement(),this.renderForm(),this.renderFormHTML(),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId);document.getElementById(`${this.formId}`).addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this))}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,textarea:this.renderTextAreaField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(("bind:value"===s.binding||s.binding.startsWith("::")&&n)&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s.binding&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"accept"===t?r+=`accept="${i}"\n`:["required","minwidth","maxwidth","minheight","maxheight"].includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||s.binding.startsWith("::"))&&(a=` bind:value="${n}"`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+=`${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";("bind:value"===s.binding||bindingSyntax.startsWith("::"))&&(a=`bind:value="${n}"\n`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}}));
1
+ !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).Formique=n()}(this,(function(){"use strict";class e{renderField(e,n,t,i,s,l){throw new Error("Method renderField must be implemented")}}return class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{this.formMarkUp+=this.renderFormElement();const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e;const n=this.formSchema.find((e=>"submit"===e[0]));if(n){const[e,t,i,s,l={}]=n,r=l.id||t;let a=this.submitButtonClass;"class"in l&&(a=l.class);let o="";for(const[e,n]of Object.entries(l))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);this.formMarkUp+=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n </div>\n <input type="submit" id="${r}" class="${a}" value="${i}"${o}>\n `}this.renderFormHTML();const t=document.getElementById(`${this.formId}`);if(t?t.addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this)):console.error(`Form with ID ${this.formId} not found after rendering. Event listener could not be attached.`),this.initDependencyGraph(),this.registerObservers(),this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId)}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&(this.dependencyGraph[r]=l.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[r].push({state:null}),this.attachInputChangeListener(r)),l.dependents&&l.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);i&&(i.style.display="none")}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,l={}]=e,r=l.id||t;l.dependents&&l.dependents.forEach((e=>{if(this.dependencyGraph[r]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[r].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),l=document.getElementById(n);if(l){l.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,l.parentNode.insertBefore(t,l)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,l={},r]=e;return this.renderField(n,t,i,s,l,r)})).join("");this.formMarkUp+=e}renderSubmitButtonElement(){const e=this.formSchema.find((e=>"submit"===e[0]));if(e){const[n,t,i,s,l={}]=e,r=l.id||t;let a=this.submitButtonClass;"class"in l&&(a=l.class);let o="";for(const[e,n]of Object.entries(l))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);return`\n<div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n<input type="submit" id="${r}" class="${a}" value="${i}"${o}>\n `.trim()}return""}renderField(e,n,t,i,s,l){const r={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return r?r.call(this,e,n,t,i,s,l):(console.warn(`Unsupported field type '${e}' encountered.`),"")}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r=this.submitButtonClass;"class"in s&&(r=s.class);let a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);return`<input type="${e}" id="${l}" class="${r}" value="${t}"${a}>`}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",l="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const r=n.toLowerCase();("email"===r||r.includes("email"))&&(s=e),("name"===r||r.includes("name"))&&(i=e),("subject"===r||r.includes("subject"))&&(l=e)})),t.metadata.subject=l||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const l=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${l}`),this.showSuccessMessage(l)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength","multiple"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength","pattern"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${r}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const l=["required","pattern","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const l=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"step":r+=` ${e}="${t}"\n`;break;default:l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const l=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else switch(t){case"min":case"max":case"step":r+=` ${t}="${i}"\n`;break;default:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const l=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)r+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":r+=` ${e}="${t}"\n`;break;default:l.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const l=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{if(l.includes(t))if("boolean"==typeof i&&i)r+=` ${t}\n`;else if("pattern"===t)r+=` ${t}="${i}"\n`;else l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const l=["required","readonly","disabled","autocomplete","inputmode","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);"class"in s&&(o=s.class),"color"===e&&(o+=" form-color-input");let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const l=["required","accept","multiple","disabled","title"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"boolean"==typeof i&&i?r+=` ${t}\n`:l.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const l=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)&&"boolean"==typeof i&&i?r+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n \x3c!--<label for="${d}">${t} \n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label> --\x3e\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${r}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const l=["accept","required","minwidth","maxwidth","minheight","maxheight","src","alt","width","height"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";const o=s?.binding;if("bind:value"===o&&n&&(a=`bind:value="${n}"\n`),"string"==typeof o&&o.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),o&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="image"===e&&"submit"===n?`\n <input \n type="image"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n src="${s.src||"img_submit.gif"}"\n alt="${s.alt||"Submit"}"\n width="${s.width||"48"}"\n height="${s.height||"48"}"\n ${$}\n ${r}\n />`:`\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n ${$}\n ${r}\n />`;let p=`\n <div class="${this.divClass}" id="${c+"-block"}">\n ${"image"===e&&"submit"===n?"":`<label for="${c}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>`}\n ${d}\n </div>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));return p=p.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),p}renderTextAreaField(e,n,t,i,s){const l=["required","minlength","maxlength"];let r="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?r+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";l&&l.length&&(p=l.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,l){const r=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(l)&&(p=l.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,l){const r=l.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=l;this.renderSingleSelectField(e,n,t,i,s,r,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,l,r,a){console.log("Within");const o=["required"];let d="";i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let c="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(c=` bind:value="${n}" `);let $=s.id||n,p="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;p+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?p+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(p+=` ${e.replace(/_/g,"-")}="${n}"\n`);let m="";Array.isArray(l)&&(m+='\n <option value="">Choose an option</option>\n ',m+=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let u=s.class||this.inputClass;const f="dynamicSingleSelect"===a&&r?' onchange="handleDynamicSingleSelect(this.value,id)"':"";let h,g;if("dynamicSingleSelect"===a&&r)if(t.includes("-")){const[e]=t.split("-");h=e,g=t}else h=t,g=t;else h=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${$+"-block"}">\n <legend>${h} \n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${$}"> Select ${h} \n <select name="${n}"\n ${c}\n \n id="${$}"\n class="${u}"\n ${p}\n ${d}\n ${f} \n >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&r){const e=document.getElementById(this.formContainerId);let t=s.id||n;if(e){const n=document.createElement("script");n.textContent='\n window.handleDynamicSingleSelect = function(category, fieldsetid) {\n //console.log("HERE", fieldsetid);\n\n // Hide all subcategory fields\n document.querySelectorAll(`[class*="${fieldsetid}"]`).forEach(div => {\n div.style.display = "none";\n });\n\n // Show the selected category\n const selectedCategoryFieldset = document.getElementById(category + \'-options\');\n if (selectedCategoryFieldset) {\n selectedCategoryFieldset.style.display = "block";\n }\n }\n',e.appendChild(n)}else console.error(`Target div with id "${this.formContainerId}" not found.`);r.forEach((e=>{const{id:n,label:i,options:s}=e,l=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let r,a;console.log("Label:",g),r=g.includes("-")?g.split("-")?.[1]+" Options":"options",a="options"!==r?g.split("-")?.[1]+" Option":r;let o=`\n <fieldset class="${this.selectGroupClass} ${t}" id="${n}-options" style="display: none;">\n <legend> ${i} ${r} ${this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${n}"> Select ${i} ${a} \n </label>\n <select name="${n}"\n ${c}\n \n id="${n+"-block"}"\n class="${u}"\n ${p}\n ${d}\n >\n <option value="">Choose an option</option>\n ${l}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,l){const r=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(l)&&($=l.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const l=["required","min","max","step"];let r="";i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)?r+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${r.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${r}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const l=s.id||n;let r,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);r="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${l+"-block"}"\n class="${r}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "formique",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Formique Declarative Form Syntax JavaScript Library",
5
5
  "main": "formique.umd.js",
6
6
  "module": "formique.mjs",