var omniccu={};omniccu.ready=callback=>{if(document.readyState!="loading")callback();else document.addEventListener("DOMContentLoaded",callback)};omniccu.eventEmitter=class eventEmitter{constructor(){this.ev={}}on(eventName,listener){if(!this.ev[eventName]){this.ev[eventName]=[]}this.ev[eventName].push(listener)}off(eventName,listenerToRemove){if(!this.ev[eventName]){console.error(`No listeners exist for event "${eventName}"`)}else{const filterListeners=listener=>listener!==listenerToRemove;this.ev[eventName]=this.ev[eventName].filter(filterListeners)}}emit(eventName,data){if(eventName in this.ev){this.ev[eventName].forEach(c=>{c(data)})}}};const appEvents=new omniccu.eventEmitter;omniccu.processDOM=(selector=document)=>{const parentElement=typeof selector==="string"?document.querySelector(selector):selector;if(!parentElement){console.warn("Invalid selector or element provided to processDOM");return}parentElement.querySelectorAll(".form .form-group-textarea textarea").forEach(txa=>{txa.originalheight=txa.style.height=txa.scrollHeight;omniccu.textareaAutoheight(txa);setTimeout(function(){omniccu.textareaAutoheight(txa)},20);txa.addEventListener("input",function(e){omniccu.textareaAutoheight(this)});txa.addEventListener("scroll",function(e){omniccu.textareaLabelFade(this)})});parentElement.querySelectorAll(".form-floating.form-group-textarea textarea").forEach(txa=>{omniccu.textareaLabelFade(txa);txa.addEventListener("scroll",function(e){omniccu.textareaLabelFade(this)})});parentElement.querySelectorAll(".form-group-radiogroup input").forEach(rdio=>{rdio.oninvalid=function(){rdio.closest(".form-group-radiogroup").querySelector(".invalid-feedback").style.display="block"}});parentElement.querySelectorAll(".form-group input, .form-group select, .form-group textarea").forEach(el=>{let s2fix=el=>{if(el.classList.contains("select2")){setTimeout(function(){el.classList.add("select2-hidden-accessible");let s2grp=el.closest(".form-group-select2");let s2span=s2grp.querySelector("span.select2");s2span.style.width=s2grp.offsetWidth+"px"},0)}};el.oninvalid=function(){el.closest(".form-group").classList.add("invalid");s2fix(el)};el.onchange=function(){el.closest(".form-group").classList.remove("invalid");s2fix(el)}});parentElement.querySelectorAll(".form").forEach(el=>{el.onreset=function(){el.classList.remove("was-validated");Array.from(el.querySelectorAll(".form-group")).forEach(fg=>fg.classList.remove("invalid"))}});omniccu.initMasonry(parentElement);omniccu.initMaska(parentElement);omniccu.initValidchars(parentElement);omniccu.dateHelper(parentElement)};omniccu.ready(()=>omniccu.processDOM());omniccu.textareaAutoheight=function(txa){txa.style.removeProperty("height");let newheight=txa.originalheight>txa.scrollHeight?txa.originalheight+2:txa.scrollHeight+2;txa.style.height=newheight+"px";if(txa.scrollHeight>txa.clientHeight&&txa.scrollTop>0){txa.closest(".form-group").classList.add("fade-label")}else{txa.closest(".form-group").classList.remove("fade-label")}if(txa.style.height!==txa.originalheight+"px"){let masonryParent=txa.closest(".masonry");if(masonryParent&&masonryParent.msnry){appEvents.emit("redraw",masonryParent)}}};omniccu.textareaLabelFade=function(txa){if(txa.scrollHeight>txa.clientHeight&&txa.scrollTop>0){txa.closest(".form-group").classList.add("fade-label")}else{txa.closest(".form-group").classList.remove("fade-label")}};omniccu.triggerForm=function(formIdOrObject){let form=typeof formIdOrObject==="object"?formIdOrObject:document.getElementById(formIdOrObject);let fields=form.querySelectorAll("input,.form-control,select,textarea");Array.prototype.slice.call(fields).forEach(function(field){try{if(field.tagName==="SELECT"){field.dispatchEvent(new Event("change"))}}catch(error){console.error(error)}})};omniccu.prepareDynamicForm=function(form){form.addEventListener("submit",function(event){if(!form.checkValidity()){event.preventDefault();event.stopImmediatePropagation();event.stopPropagation()}else{omniccu.triggerForm(form.id)}if(!form.hasAttribute("novalidate")){form.classList.add("was-validated")}},false);form.addEventListener("reset",function(e){setTimeout(function(){omniccu.triggerForm(form.id);form.classList.remove("was-validated")},0)},false);form.addEventListener("keydown",function(event){if(event.key==="Enter"&&event.target.tagName==="INPUT"&&!["submit","button","reset","image"].includes(event.target.type)){const visibleControls=form.querySelectorAll('input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select');const visibleCount=Array.from(visibleControls).filter(el=>{return el.offsetParent!==null&&getComputedStyle(el).visibility!=="hidden"&&!el.disabled&&!el.readOnly}).length;if(visibleCount>1){event.preventDefault();event.stopPropagation()}}},false);let buttons=form.querySelectorAll(".needs-validation button,.needs-validation input[type='submit']");Array.prototype.slice.call(buttons).forEach(function(button){button.addEventListener("click",function(event){if(button.form){button.form.elements["_clicked"].value=event.target.id??event.target.name??""}},false)})};omniccu.initMasonry=(selector=document)=>{if(!selector){console.warn("No selector provided, defaulting to document");selector=document}const parentElement=typeof selector==="string"?document.querySelector(selector):selector;const masonryElements=parentElement.querySelectorAll(".masonry");if(masonryElements.length>0){if(typeof Masonry==="undefined"){const script=document.createElement("script");script.src="https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js";script.integrity="sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D";script.crossOrigin="anonymous";script.onload=()=>{omniccu.initMasonry(parentElement)};document.body.appendChild(script)}else{masonryElements.forEach(element=>{if(element.offsetParent!==null){if(!element.msnry){element.msnry=new Masonry(element,{percentPosition:true})}element.msnry.layout()}})}}};omniccu.initMaska=(selector=document)=>{if(typeof Maska!=="undefined"){const{Mask,MaskInput}=Maska;if(typeof window.maskaInitialized==="undefined"){window.maskaInitialized=true}const parentElement=typeof selector==="string"?document.querySelector(selector):selector;const childrenWithDataMaskaAttribute=parentElement.querySelectorAll("[data-maska]");if(childrenWithDataMaskaAttribute.length>0){new MaskInput("[data-maska]",{scope:parentElement})}}};omniccu.initValidchars=function(selector=document){const parentElement=typeof selector==="string"?document.querySelector(selector):selector;const inputs=parentElement.querySelectorAll("[data-validchars]");inputs.forEach(input=>{const keypressPattern=new RegExp(`[${input.dataset.validchars}]`);const cleanPattern=new RegExp(`[^${input.dataset.validchars}]`,"g");input.addEventListener("keypress",e=>{const char=String.fromCharCode(e.keyCode||e.which);if(!keypressPattern.test(char)){e.preventDefault()}});input.addEventListener("paste",e=>{const pastedText=e.clipboardData.getData("text");const cleanText=pastedText.replace(cleanPattern,"");if(pastedText!==cleanText){e.preventDefault();const start=input.selectionStart;const end=input.selectionEnd;input.value=input.value.slice(0,start)+cleanText+input.value.slice(end);input.setSelectionRange(start+cleanText.length,start+cleanText.length)}})})};omniccu.dateHelper=(selector=document)=>{if(typeof $==="undefined")return;const parentElement=typeof selector==="string"?document.querySelector(selector):selector;if(!parentElement)return;try{const childrenWithDaterangeClicks=$(parentElement.querySelectorAll(".form-group-daterange span.input-group-text"));if(!childrenWithDaterangeClicks.length)return;childrenWithDaterangeClicks.mousedown(function(e){const input=$(e.target).parent("div").find("input");const datepicker=input.data("daterangepicker");if(datepicker&&typeof datepicker.show==="function"&&!datepicker.isShowing){datepicker.show();e.preventDefault();e.stopPropagation()}})}catch(error){return}};omniccu.formatDateUS=(dateString=null)=>{if(!dateString)return null;const date=new Date(dateString);if(isNaN(date))return null;const formattedDate=(date.getMonth()+1).toString()+"/"+date.getDate().toString().padStart(2,"0")+"/"+date.getFullYear();if(dateString.length<=10||!dateString.includes(":")){return formattedDate}let hours=date.getHours();const minutes=date.getMinutes().toString().padStart(2,"0");const seconds=date.getSeconds().toString().padStart(2,"0");const ampm=hours>=12?"PM":"AM";hours=hours%12;hours=hours?hours:12;return`${formattedDate} ${hours}:${minutes}:${seconds} ${ampm}`};omniccu.webSafe=(text,expandSymbols=false)=>{if(!text)return"";let s=text.toLowerCase();if(expandSymbols){s=s.replace(/&/g,"-and-").replace(/#/g,"-number-").replace(/@/g,"-at-").replace(/%/g,"-percent-").replace(/\+/g,"-plus-").replace(/=/g,"-equals-")}return s.replace(/\s+/g,"-").replace(/[^a-z0-9\-]/g,"").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")};Object.deepAssign=function(...objects){const mergeTwo=(target,source)=>{if(!source)return target;if(!target)return source;for(const key in source){if(typeof source[key]==="object"&&source[key]!==null&&!Array.isArray(source[key])&&typeof target[key]==="object"&&target[key]!==null&&!Array.isArray(target[key])){target[key]=mergeTwo(target[key],source[key])}else{target[key]=source[key]}}return target};return objects.reduce((result,obj)=>mergeTwo(result,obj),{})};function getJSON(url,callback){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="json";xhr.onload=function(){var status=xhr.status;if(status===200){callback(xhr.response)}else{callback(xhr.response,status)}};xhr.send()}function copyText(txt){if(!navigator.clipboard){let tmp=$("<input class='d-none'>");$("body").append(tmp);tmp.val(txt).select();document.execCommand("copy");tmp.remove()}else{navigator.clipboard.writeText(txt).then(function(){console.log("text copied")}).catch(function(){console.error("copy text failed")})}}function parseDateRange(dateRange){const dashes=[...dateRange.matchAll(/-/g)].map(match=>match.index);const sepIndex=dashes[Math.floor(dashes.length/2)];let[from,to]=[dateRange.substring(0,sepIndex).trim(),dateRange.substring(sepIndex+1).trim()];const hasFromTime=from.includes(":")||/\b[ap]m\b/i.test(from);const hasToTime=to.includes(":")||/\b[ap]m\b/i.test(to);const fromDate=new Date(from);const toDate=new Date(to);return{from:!isNaN(fromDate.getTime())?(hasFromTime?fromDate.toLocaleString("en-CA").replace(",",""):fromDate.toLocaleDateString("en-CA")).replace("p.m.","PM").replace("a.m.","AM"):null,to:!isNaN(toDate.getTime())?(hasToTime?toDate.toLocaleString("en-CA").replace(",",""):toDate.toLocaleDateString("en-CA")).replace("p.m.","PM").replace("a.m.","AM"):null,type:"daterange"}}omniccu.initializeBootstrapFeatures=(selector=null)=>{if(!selector){selector=document}const parentElement=typeof selector==="string"?document.querySelector(selector):selector;if(!parentElement){console.warn("Invalid selector or element provided to initializeBootstrapFeatures");return}const forms=parentElement.querySelectorAll(".needs-validation");Array.prototype.slice.call(forms).forEach(function(form){omniccu.prepareDynamicForm(form)});const popoverTriggerList=Array.from(parentElement.querySelectorAll('[data-bs-toggle="popover"]'));const popoverList=popoverTriggerList.map(function(popoverTriggerEl){let po_pos=popoverTriggerEl.dataset.popover?popoverTriggerEl.dataset.popover:null;return new bootstrap.Popover(popoverTriggerEl,{placement:po_pos??"left",html:true,sanitize:false})});const tooltipTriggerList=Array.from(parentElement.querySelectorAll('[data-bs-toggle="tooltip"]'));const tooltipList=tooltipTriggerList.map(function(tooltipTriggerEl){let tt_pos=tooltipTriggerEl.dataset.tooltip?tooltipTriggerEl.dataset.tooltip:null;return new bootstrap.Tooltip(tooltipTriggerEl,{placement:tt_pos??"top",trigger:"hover",html:true,sanitize:false})});document.addEventListener("hide.bs.modal",function(event){const focusedElement=event.target.querySelector(":focus");if(focusedElement){focusedElement.blur()}})};omniccu.ready(()=>omniccu.initializeBootstrapFeatures());appEvents.on("redraw",target=>{if(target){omniccu.initializeBootstrapFeatures(target)}});window.addEventListener("load",()=>{document.querySelector("body").classList.add("loaded")});window.addEventListener("resize",function(){if(typeof echarts!=="undefined"){document.querySelectorAll(".echart").forEach(echart=>{echarts.getInstanceByDom(echart).resize()})}});omniccu.toastDispatcher=class toastDispatcher{constructor(){this.toastContainer=null}alert(body="",header="Alert",status_msg="",persistent=false,options={}){this.toast({msg:{header:header,body:body},autohide:!persistent})}notify(body="",header="Notification",status_msg="",persistent=false,options={}){this.toast({msg:{header:header,body:body,msg_status:status_msg},autohide:!persistent})}toast(msgObj){let msg=msgObj["msg"];let toasted=this.cook(msg);let tc=this.getToastContainer();tc.appendChild(toasted);let toastOptions=[];toastOptions.autohide=msgObj["autohide"]??true;let msgObjOptions=msgObj["options"]??null;if(msgObjOptions&&typeof msgObjOptions==="object"&&Object.keys(msgObjOptions).length>0){toastOptions.autohide=msgObjOptions["autohide"]??msgObj["autohide"]??true;toastOptions.animation=msgObjOptions["animation"]??true;toastOptions.delay=msgObjOptions["delay"]??5e3}let toastDomObj=new bootstrap.Toast(toasted,toastOptions);toastDomObj.show()}getToastContainer(){return document.getElementById("toasts")??this.toastContainer??this.createToastContainer()}createToastContainer(){let tc=document.createElement("div");tc.id="toasts";document.body.appendChild(tc);this.toastContainer=tc;return tc}cook(msg){let toastObj=document.createElement("div");toastObj.classList.add("toast");toastObj.setAttribute("role","alert");toastObj.setAttribute("aria-live","assertive");toastObj.setAttribute("aria-atomic","true");let toastHeader=document.createElement("div");toastHeader.classList.add("toast-header");if(typeof msg.header!=="undefined"){let msgStatus=typeof msg.status_msg!=="undefined"?"<small>"+msg.status_msg+"</small>":"";toastHeader.innerHTML='<strong class="me-auto">'+msg.header.trim()+"</strong>"+msgStatus+'<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>';toastObj.appendChild(toastHeader)}let toastBody=document.createElement("div");toastBody.classList.add("toast-body");toastBody.innerHTML=msg.body.trim();toastObj.appendChild(toastBody);return toastObj}};const toaster=new omniccu.toastDispatcher;omniccu.modal=(targetId,action,html)=>{let modalEl=document.getElementById(targetId);let modalObj=bootstrap.Modal.getInstance(modalEl)||new bootstrap.Modal(modalEl);switch(action){case"show":case"open":modalObj.show();break;case"hide":case"close":modalObj.hide();break;case"toggle":modalObj.toggle();break;default:if(html){let domObj={target:targetId,action:action,html:html};domObj.selector="#"+targetId+" .modal-body";if(action=="header"||action=="title"){domObj.selector="#"+targetId+" .modal-"+action}else{domObj.selector="#"+targetId+" .modal-body"}omniccu.updateDom(domObj)}}};omniccu.Drawer=class Drawer{static control(targetId,action,html){let drawerBody=document.getElementById(targetId).querySelector(".offcanvas-body");if(drawerBody&&html){let domObj={html:html};domObj.selector="#"+targetId+" .offcanvas-body";omniccu.updateDom(domObj)}if(action=="open"||action=="show"){this.open("#"+targetId)}else if(action=="close"||action=="hide"){this.close("#"+targetId)}else if(action=="toggle"){this.toggle("#"+targetId)}else{if(html){let domObj={html:html};if(action=="header"||action=="title"){domObj.selector="#"+targetId+" .offcanvas-"+action}else{domObj.selector="#"+targetId+" .offcanvas-body"}omniccu.updateDom(domObj)}}}static open(selector){let oc=document.querySelector(selector);if(!!oc){oc.classList.add("active","show");oc.style.visibility="visible";let ocClose=oc.querySelector("[data-bs-dismiss='offcanvas']");const closeOc=e=>{oc.classList.remove("active","show");setTimeout(()=>{oc.style.visibility="hidden";ocClose.removeEventListener("click",closeOc)},300)};ocClose.addEventListener("click",closeOc);document.querySelectorAll(".form .form-group-textarea textarea").forEach(txa=>{setTimeout(()=>{omniccu.textareaAutoheight(txa)},20)})}}static close(selector){let ocs=document.querySelectorAll(selector);let ocs_array=[...ocs];ocs_array.forEach(oc=>{oc.classList.remove("active","show");setTimeout(()=>{oc.style.visibility="hidden"},300)})}static toggle(selector){let oc=document.querySelector(selector);if(oc.classList.contains("active")){this.close(selector)}else{this.open(selector)}}};omniccu.drawer=(targetId,action,html)=>{omniccu.Drawer.control(targetId,action,html)};omniccu.responseHandler=class responseHandler{process(response){if(typeof response.data==="undefined"){return this.process({data:response})}const htmlError=this.htmlErrorData(response);if(htmlError)response.data=htmlError;const jsonError=this.jsonErrorData(response);if(jsonError)response.data=jsonError;if(Array.isArray(response.data.bundle)){response.data.bundle.forEach(r=>{this.process({data:r})})}let redir;if(redir=response.data.redirect){document.location.href=redir}let emit;if(emit=response.data.emit){appEvents.emit(emit.event,emit.data)}let toast;if(toast=response.data.toast){toaster.toast(response.data.toast)}let error;if(error=response.data.error){toaster.notify(response.data.error.message,"Error",response.data.error.code,true)}let run;if(run=response.data.run){try{eval(run)}catch(e){console.error(e)}}let valueUpdate;if(valueUpdate=response.data.value){let formId=valueUpdate.form??null;let fieldId=valueUpdate.field??null;let newValue=valueUpdate.value??null;omniccu.setFormValue(formId,fieldId,newValue)}let dom;if(dom=response.data.dom){omniccu.updateDom(dom)}let modal;if(modal=response.data.modal){omniccu.modal(modal.target,modal.action,modal.html)}let drawer;if(drawer=response.data.drawer){omniccu.drawer(drawer.target,drawer.action,drawer.html)}let datatable=response.data.datatable;if(datatable){if(datatable.target&&datatable.action=="reload"){const tableElement=document.getElementById(datatable.target);if(tableElement){if(typeof $.fn!=="undefined"&&$.fn.dataTable){$("#"+datatable.target).DataTable().ajax.reload()}else if(window.DataTable){window.DataTable("#"+datatable.target).ajax.reload()}else{const dtInstance=tableElement.querySelector(".dataTable");if(dtInstance&&dtInstance.DataTable){dtInstance.DataTable().ajax.reload()}}}}}let download;if(download=response.data.download){if(download.blob){const blob=new Blob([atob(download.blob)],{type:download.contentType||"application/octet-stream"});const downloadUrl=URL.createObjectURL(blob);const tempLink=document.createElement("a");tempLink.href=downloadUrl;tempLink.download=download.filename||"download";document.body.appendChild(tempLink);tempLink.click();document.body.removeChild(tempLink);setTimeout(()=>URL.revokeObjectURL(downloadUrl),100)}else if(download.url){if(download.showOverlay){globalOverlay.show()}axios({url:download.url,method:"GET",responseType:"blob",headers:{"X-Requested-With":"XMLHttpRequest"}}).then(response=>{const blob=new Blob([response.data],{type:response.headers["content-type"]});const downloadUrl=URL.createObjectURL(blob);const tempLink=document.createElement("a");tempLink.href=downloadUrl;tempLink.download=download.filename||"download";document.body.appendChild(tempLink);tempLink.click();document.body.removeChild(tempLink);setTimeout(()=>URL.revokeObjectURL(downloadUrl),100)}).catch(error=>{console.error("Download failed:",error);toaster.notify("Failed to download file. Please try again.","Error","",true)}).finally(()=>{if(download.showOverlay){globalOverlay.hide()}})}}}htmlErrorData(response){if(typeof response.data!=="string"||!response.data.includes("Whoops"))return null;const src=URL.createObjectURL(new Blob([response.data],{type:"text/html"}));const html=`<div id="notification_modal" class="modal fade"><div class="modal-dialog modal-xl modal-dialog-scrollable"><div class="modal-content"><div class="modal-header bg-danger text-white py-2"><strong class="me-auto">Server Error ${response.status}</strong><button class="btn-close btn-close-white" data-bs-dismiss="modal"></button></div><div class="modal-body p-0" style="height:75vh"><iframe src="${src}" style="width:100%;height:100%;border:0" onload="URL.revokeObjectURL(this.src)"></iframe></div></div></div></div>`;return{bundle:[{dom:{selector:"#notification_modal",action:"remove"}},{dom:{selector:"body",html:html,action:"append"}},{modal:{target:"notification_modal",action:"show"}}]}}jsonErrorData(response){if(!response.data?.exception)return null;const esc=s=>(s??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");const origin=[response.data.file,response.data.line].filter(Boolean).join(":");const trace=(response.data.trace??[]).map((l,i)=>{if(typeof l!=="object"||l===null)return`  #${i} ${l}`;const loc=l.file?`${l.file}(${l.line??"?"})`:"[internal]";const call=l.class?`${l.class}${l.type??"->"}${l.function??""}()`:l.function?`${l.function}()`:"";return`  #${i} ${loc}${call?": "+call:""}`}).join("\n");const body=`<pre style="max-height:65vh;overflow:auto;background:#1e1e1e;color:#d4d4d4;padding:12px;border-radius:4px;font-size:11px;white-space:pre-wrap;margin:0"><strong style="color:#f48771">${esc(response.data.exception)}</strong>: ${esc(response.data.message)}\n<span style="color:#9cdcfe">@ ${esc(origin)}</span>\n\n${esc(trace)}</pre>`;const html=`<div id="notification_modal" class="modal fade"><div class="modal-dialog modal-xl modal-dialog-scrollable"><div class="modal-content"><div class="modal-header bg-danger text-white py-2"><strong class="me-auto">Server Error ${response.status}: ${esc(response.data.exception)}</strong><button class="btn-close btn-close-white" data-bs-dismiss="modal"></button></div><div class="modal-body p-1">${body}</div></div></div></div>`;return{bundle:[{dom:{selector:"#notification_modal",action:"remove"}},{dom:{selector:"body",html:html,action:"append"}},{modal:{target:"notification_modal",action:"show"}}]}}};const receiver=new omniccu.responseHandler;omniccu.updateDom=dom=>{let target=document.querySelector(dom.selector);if(!target)return;let tempDiv=document.createElement("div");tempDiv.innerHTML=dom.html;const links=Array.from(tempDiv.getElementsByTagName("link"));links.forEach(link=>{if(link.rel!=="stylesheet")return;let newLink=document.createElement("link");newLink.rel=link.rel;newLink.href=link.href;if(link.type)newLink.type=link.type;if(document.querySelector(`link[href="${link.href}"]`)){link.remove();return}document.head.insertBefore(newLink,document.head.firstChild);link.remove()});const scripts=Array.from(tempDiv.getElementsByTagName("script"));const externalScripts=[];const inlineScripts=[];scripts.forEach(script=>{if(script.src){const existingScript=document.querySelector(`script[src="${script.src}"]`);if(!existingScript){externalScripts.push({src:script.src,type:script.type||"text/javascript"})}}else{inlineScripts.push({content:script.innerHTML,type:script.type||"text/javascript"})}script.remove()});const fragment=document.createDocumentFragment();while(tempDiv.firstChild){fragment.appendChild(tempDiv.firstChild)}switch(dom.action){case"replace":target.outerHTML=dom.html;break;case"append":target.appendChild(fragment);break;case"prepend":target.insertBefore(fragment,target.firstChild);break;case"before":target.parentNode.insertBefore(fragment,target);break;case"after":target.parentNode.insertBefore(fragment,target.nextSibling);break;case"clear":target.innerHTML="";break;case"remove":target.remove();break;case"hide":target.style.display="none";break;case"show":target.style.display=dom.display??"block";target.classList.remove("d-none","hidden","visually-hidden");break;case"toggle":target.style.display=target.style.display=="none"?dom.display??"block":"none";break;case"update":default:target.innerHTML="";target.appendChild(fragment);break}const loadScriptSequentially=(scripts,index=0)=>{if(index>=scripts.length){return Promise.resolve()}return new Promise(resolve=>{const script=document.createElement("script");script.type=scripts[index].type;if(scripts[index].src){script.onload=()=>{loadScriptSequentially(scripts,index+1).then(resolve)};script.src=scripts[index].src}else{script.textContent=scripts[index].content;loadScriptSequentially(scripts,index+1).then(resolve)}document.body.appendChild(script);if(!scripts[index].src){script.onload?.(new Event("load"))}})};loadScriptSequentially(externalScripts).then(()=>{loadScriptSequentially(inlineScripts).then(()=>{omniccu.processDOM(target);if(typeof appEvents!=="undefined"){appEvents.emit("redraw",target)}})});omniccu.initializeBootstrapFeatures(target)};appEvents.on("redraw",()=>setTimeout(()=>omniccu.initMasonry(),0));omniccu.refreshCsrf={async refresh(){const csrfResponse=await axios.get("/refresh-csrf");document.querySelector('meta[name="csrf-token"]').setAttribute("content",csrfResponse.data);return csrfResponse.data}};omniccu.vueFormElementMixins={};omniccu.vueFormMixins={};omniccu.vueFormMixin={created(){},mounted(){omniccu.prepareDynamicForm(document.getElementById(this._form));if(typeof appEvents!="undefined"){appEvents.on("loadVue",formData=>{this.loadData(formData)})}this.$nextTick(()=>{const form=document.getElementById(this._form);if(form){form.removeAttribute("data-vue");const tinyMCEFields=form.querySelectorAll("textarea.wysiwyg");tinyMCEFields.forEach(field=>{const fieldName=field.name;if(fieldName in this.$data){this.$watch(fieldName,newValue=>{const editorId=this._form+"_"+fieldName;const editor=tinymce.get(editorId);if(editor){const currentContent=editor.getContent();if(newValue!==currentContent){editor.setContent(newValue||"");editor.save()}}})}})}window.addEventListener("pageshow",event=>{if(event.persisted){this._loading=false;this._overlay=false}})})},watch:{_overlay:{handler(newVal,oldVal){if(newVal&&!oldVal){globalOverlay.show()}else if(!newVal&&oldVal){globalOverlay.hide()}},immediate:false}},methods:{jsonData(){let removeKeys=["validationErrors","_submitted","_loading","_overlay","_clicked","_syncKey","_dismissErrors","_debounceTimer","_debounceDelay"];let curated={};let k;let fieldExclusions=typeof this._excludeFields==="function"?this._excludeFields():[];for(k in this.$data){if(removeKeys.indexOf(k)==-1&&fieldExclusions.indexOf(k)==-1&&k.indexOf("xconfig_")!==0){curated[k]=this.$data[k]}}return curated},formData(){let removeKeys=["validationErrors","_submitted","_loading","_overlay","_syncKey","_dismissErrors","_debounceTimer","_debounceDelay"];let fdata=new FormData;let fieldExclusions=typeof this._excludeFields==="function"?this._excludeFields():[];const form=document.getElementById(this._form);if(!form){console.error("Form not found:",this._form);return fdata}for(let k in this.$data){if(removeKeys.indexOf(k)==-1&&fieldExclusions.indexOf(k)==-1&&k.indexOf("xconfig_")!==0){const value=this.$data[k];this.appendFormValue(fdata,k,value)}}let hiddenFields=form.querySelectorAll("input[type=hidden]");for(let i=0;i<hiddenFields.length;i++){if(hiddenFields[i].name.indexOf("_")!=0){if(!fdata.has(hiddenFields[i].name)){fdata.append(hiddenFields[i].name,hiddenFields[i].value)}}else{fdata.delete(hiddenFields[i].name)}}return typeof this.processFormData==="function"?this.processFormData(fdata):fdata},pruneFormData(formData,excludeKeys){if(!Array.isArray(excludeKeys)||excludeKeys.length===0){return formData}const keysToRemove=[];for(let pair of formData.entries()){const key=pair[0];for(let excludeKey of excludeKeys){if(key===excludeKey){keysToRemove.push(key);break}if(key.startsWith(excludeKey+"[")){keysToRemove.push(key);break}}}keysToRemove.forEach(key=>{formData.delete(key)});return formData},appendFormValue(fdata,key,value){if(value==null){fdata.append(key,"")}else if(typeof value=="object"){if(value instanceof Array){for(let i=0;i<value.length;i++){this.appendFormValue(fdata,key+"["+i+"]",value[i])}}else{if(document.getElementById(this._form+"_"+key)!=null&&document.getElementById(this._form+"_"+key).files&&document.getElementById(this._form+"_"+key).files.length>0){fdata.append(key,value)}else{try{JSON.stringify(value)}catch(e){return}for(let i in value){if(value.hasOwnProperty(i)){this.appendFormValue(fdata,key+"["+i+"]",value[i])}}}}}else{fdata.append(key,value)}},loadData(formData){if(typeof formData._form!=null&&formData._form==this._form){Object.assign(this.$data,formData);this.keepSynced()}},keepSynced(){this._syncKey++},syncKey(){return this._syncKey},resolveArrayFromName(name){const keys=name.split(".");let target=this;for(let i=0;i<keys.length-1;i++){const key=keys[i];if(key.includes("[")){const parts=key.match(/^([^\[]+)\[(\d+)\]$/);if(parts){const arrayName=parts[1];const index=parseInt(parts[2]);target=target[arrayName][index]}else{target=target[key]}}else{target=target[key]}}const lastKey=keys[keys.length-1];if(lastKey.includes("[")){const parts=lastKey.match(/^([^\[]+)\[(\d+)\]$/);if(parts){const arrayName=parts[1];const index=parseInt(parts[2]);return target[arrayName][index]}}return target[lastKey]},addRow(name,newRow,e){let array=this.resolveArrayFromName(name);array.push(newRow);appEvents.emit("repeaterAddRow",{name:name,newRow:newRow,array:array});e.stopPropagation()},removeRow(name,row,e){const lastSeparator=Math.max(name.lastIndexOf("["),name.lastIndexOf("."));if(lastSeparator===-1){let array=this[name];const index=array.indexOf(row);if(index>-1){array.splice(index,1)}}else{const parentPath=name.substring(0,lastSeparator);const parent=this.resolveArrayFromName(parentPath);const keyPart=name.substring(lastSeparator);if(keyPart.startsWith("[")){const index=parseInt(keyPart.match(/\[(\d+)\]/)[1]);parent.splice(index,1)}else{const key=keyPart.substring(1);const index=parent[key].indexOf(row);if(index>-1)parent[key].splice(index,1)}}e.stopPropagation()},fileChange(e){var files=e.target.files||e.dataTransfer.files;const fileInput=e.target;const fileInputParent=fileInput.parentNode;const existingImg=fileInputParent.querySelector(".file-preview-image");if(existingImg)existingImg.remove();if(!files.length)return;this[e.target.name]=files[0];if(e.target.dataset.action){let formAction=e.target.dataset.action;if(e.target.files.length>0){this._loading=true;let fdata=new FormData;fdata.append(e.target.name,this[e.target.name]);this.request(formAction,fdata)}}else{if(files[0].type.startsWith("image/")){const reader=new FileReader;reader.onload=event=>{const img=document.createElement("img");img.src=event.target.result;const previewDiv=document.createElement("div");previewDiv.classList.add("file-preview-image");previewDiv.appendChild(img);fileInputParent.appendChild(previewDiv)};reader.readAsDataURL(files[0])}}},syncRadiosAndChecks(form){form.querySelectorAll('input[type="radio"]:checked').forEach(radio=>{radio.dispatchEvent(new Event("change",{bubbles:true}))});form.querySelectorAll('input[type="checkbox"]').forEach(checkbox=>{checkbox.dispatchEvent(new Event("change",{bubbles:true}))})},submitForm(event){this._loading=true;this._dismissErrors=false;let domForm=document.getElementById(this._form);this.syncRadiosAndChecks(domForm);let noValidate=!domForm.classList.contains("needs-validation");let formValid=noValidate||domForm.checkValidity();if(!noValidate){domForm.classList.add("was-validated")}if(!formValid){this._loading=false;this._overlay=false;let firstInvalid=document.querySelector(".was-validated .form-control:invalid");if(firstInvalid){firstInvalid.scrollIntoView({behavior:"smooth",block:"center"})}if(event){event.preventDefault();event.stopImmediatePropagation();event.stopPropagation()}}else{let formAction=event?event.target.action??domForm.action:domForm.action;if(!!formAction){this.request(formAction,this.formData())}else{console.log("no form action defined");this._loading=false}}this._submitted=true;this.$forceUpdate()},resetForm(event){Object.assign(this.$data,this.$options.data.call(this));setTimeout(()=>{let domForm=document.getElementById(this._form);if(domForm){const fileInputs=domForm.querySelectorAll('input[type="file"]');fileInputs.forEach(fileInput=>{fileInput.value="";fileInput.dispatchEvent(new Event("change"))});omniccu.triggerForm(domForm);domForm.classList.remove("was-validated")}},0)},request(formAction,formData,useOverlay=true){if(useOverlay){this.queueOverlay()}const method=(document.getElementById(this._form)?.getAttribute("method")??"post").toLowerCase();const additionalHeaders={"X-Clicked-Button":this._clicked||"","X-Form-Id":this._form||""};const config={headers:{"X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').content,"X-Requested-With":"XMLHttpRequest","Content-Type":"multipart/form-data",...additionalHeaders},withCredentials:true};let preparedFormData=formData;if(method==="get"){if(formData instanceof FormData){preparedFormData={};for(let[key,value]of formData.entries()){preparedFormData[key]=value}}}const axiosRequest=["get","delete","head","options"].includes(method)?axios[method](formAction,{...config,params:preparedFormData}):axios[method](formAction,preparedFormData,config);return axiosRequest.then(response=>{this.validationErrors={};if(Array.isArray(response.data.bundle)){response.data.bundle.forEach(r=>{this.processResponse({data:r})})}else{this.processResponse(response)}}).catch(error=>{this._loading=false;this._overlay=false;try{if(error.response.status==422){this.validationErrors=error.response.data.errors;let vueWrap=document.getElementById(this._form+"_vue");if(vueWrap){vueWrap.scrollIntoView({behavior:"smooth",block:"start"})}}else if(error.response.data.message&&error.response.data.message==="CSRF token mismatch."){omniccu.refreshCsrf.refresh().then(()=>{this.request(formAction,formData)}).catch(error=>{this._overlay=false;console.log("double token error")})}else{if(Array.isArray(error.response.data.bundle)){error.response.data.bundle.forEach(r=>{this.processResponse({data:r})})}else{this.processResponse(error.response)}}}catch(e){console.log("caught");console.error(error)}})},processResponse(response){if(!response.data.redirect){this._loading=false;this._overlay=false}if(typeof response.data.reset!="undefined"){this.resetForm()}let reflect;if(reflect=response.data.reflect){appEvents.emit("formSubmit",this.jsonData())}let errors;if(errors=response.data.errors){document.getElementById(this._form).classList.remove("was-validated");this.validationErrors=response.data.errors}receiver.process(response)},buttonClick(event){if(event.target&&event.target.form){const formId=event.target.form.id;const targetId=event.target.id;this._clicked=targetId.startsWith(formId+"_")?targetId.replace(formId+"_",""):targetId||event.target.name;return}const closestForm=event.target.closest("form");if(closestForm){const formId=closestForm.id;const targetId=event.target.id;this._clicked=targetId.startsWith(formId+"_")?targetId.replace(formId+"_",""):targetId||event.target.name;return}this._clicked=event.target.id||event.target.name;if(!this._clicked){console.error("Failed to determine button identity",event.target)}},hasError(fieldName){this._syncKey;let domifiedFieldName=fieldName.replace(/\./g,"_").replace(/\[/g,"_").replace(/\]/g,"");if(document.querySelector(".was-validated #"+this._form+"_"+domifiedFieldName+":invalid")){return true}let wrap=document.querySelector(".was-validated #"+this._form+"_"+domifiedFieldName+"_wrap");if(wrap&&wrap.classList.contains("invalid")){return true}return fieldName in this.validationErrors},hasErrors(){return!this._dismissErrors&&(this.validationErrors["_summary"]&&this.validationErrors["_summary"].length>0||this.validationErrors["_"]&&this.validationErrors["_"].length>0)},getError(fieldName,defaultError="invalid"){if(typeof this.validationErrors[fieldName]!=="undefined"){try{document.getElementById(this._form).querySelector(`[name="${fieldName}"], [name="${fieldName}[]"]`).dispatchEvent(new Event("invalid"))}catch(e){}return typeof this.validationErrors[fieldName][0]!=="undefined"?this.validationErrors[fieldName][0]:defaultError}return defaultError},clearError(event){if(event.target.checkValidity()){delete this.validationErrors[event.target.name];if(this.validationErrors._summary){let summary_index=this.validationErrors._summary_key.indexOf(event.target.name);delete this.validationErrors._summary_key[summary_index];this.validationErrors._summary_key=this.validationErrors._summary_key.filter(n=>n);delete this.validationErrors._summary[summary_index];this.validationErrors._summary=this.validationErrors._summary.filter(n=>n)}}},dismissErrors(event){this._dismissErrors=true},wasValidated(){const form=document.getElementById(this._form);if(!form){return this._submitted}const novalidate=form.hasAttribute("novalidate");return!novalidate&&this._submitted},queueOverlay(){setTimeout(()=>this._overlay=this._loading,1e3);this._overlay=this._loading},refreshPage(){window.location.reload()},toast(message,type="info"){if(typeof toaster!=="undefined"){toaster.notify(message,"Approval System","",false)}else{alert(message)}},debounce(event,eventName="debounce"){clearTimeout(this._debounceTimer);this._debounceTimer=setTimeout(()=>{this.emitEvent(eventName,event)},this._debounceDelay)},emitEvent(eventName,event=null){appEvents.emit(eventName,event)}},computed:{isLoading(){return this._loading===true}}};omniccu.setFormValue=function(formId,fieldId,value){let formFieldElement;if(fieldId.startsWith(formId+"_")){formFieldElement=document.getElementById(fieldId)}else{formFieldElement=document.getElementById(`${formId}_${fieldId}`)}if(formFieldElement){formFieldElement.value=value}const formVueElement=document.getElementById(`${formId}_vue`);if(formVueElement&&formVueElement.__vue_app__){try{const app=formVueElement.__vue_app__;const instance=app._instance||app._container?._vnode?.component;if(instance&&instance.proxy&&fieldId in instance.proxy){instance.proxy[fieldId]=value;return true}}catch(error){console.warn("Could not access Vue instance in production mode:",error)}}return!!formFieldElement};window.TinyMCEManager=window.TinyMCEManager||{eventsInitialized:false,getThemeFromCookie:function(){return document.cookie.split("; ").find(row=>row.startsWith("theme="))?.split("=")[1]||"light"},defaults:{height:500,menubar:false,plugins:["advlist autolink lists link image charmap print preview anchor code","searchreplace visualblocks code fullscreen","insertdatetime media table paste code help wordcount"],toolbar:"undo redo | formatselect | "+"bold italic backcolor | alignleft aligncenter "+"alignright alignjustify | bullist numlist outdent indent | "+"removeformat | code | help",content_style:"body { font-family:Helvetica,Arial,sans-serif; font-size:14px }"},required:{setup:function(editor){function updateVue(){editor.save();const content=editor.getContent();const textarea=editor.getElement();const form=textarea.closest("form");const formId=form?form.getAttribute("id"):null;const fieldName=textarea.name;let vueUpdated=false;if(formId&&fieldName){const vueWrapper=document.getElementById(`${formId}_vue`);if(vueWrapper&&vueWrapper.__vue_app__){try{const app=vueWrapper.__vue_app__;const instance=app._instance||app._container?._vnode?.component;if(instance&&instance.proxy&&fieldName in instance.proxy.$data){instance.proxy.$data[fieldName]=content;if(typeof instance.proxy.keepSynced==="function"){instance.proxy.keepSynced()}vueUpdated=true}}catch(error){console.warn("Could not access Vue instance in production mode:",error)}}}textarea.value=content;const inputEvent=new Event("input",{bubbles:true,cancelable:false});textarea.dispatchEvent(inputEvent);const changeEvent=new Event("change",{bubbles:true,cancelable:false});textarea.dispatchEvent(changeEvent);return vueUpdated}editor.on("keyup",updateVue);editor.on("blur",updateVue);editor.on("change",updateVue);editor.on("init",function(){requestAnimationFrame(function(){const textarea=editor.getElement();const form=textarea.closest("form");const formId=form?form.getAttribute("id"):null;const fieldName=textarea.name;if(formId&&fieldName){const vueWrapper=document.getElementById(`${formId}_vue`);if(vueWrapper&&vueWrapper.__vue_app__){try{const app=vueWrapper.__vue_app__;const instance=app._instance||app._container?._vnode?.component;if(instance&&instance.proxy&&instance.proxy.$data&&instance.proxy.$data[fieldName]!==undefined){const vueContent=instance.proxy.$data[fieldName]||"";if(vueContent&&vueContent!==editor.getContent()){editor.setContent(vueContent);editor.save()}}}catch(error){console.warn("Could not access Vue instance in production mode:",error)}}}})})},deprecation_warnings:false},initTheme:function(){this.isDark=this.getThemeFromCookie()==="dark";this.themeConfig=this.isDark?{skin:"oxide-dark",content_css:"dark"}:{skin:"oxide",content_css:"default"}},switchTheme:function(){if(typeof tinymce==="undefined")return;this.initTheme();tinymce.remove("textarea.wysiwyg");tinymce.init({selector:"textarea.wysiwyg:not(.configured)",...this.defaults,...this.themeConfig,...this.required})},initDynamicEditors:function(){if(typeof tinymce==="undefined")return;requestAnimationFrame(()=>{const initConfiguredEditors=()=>{document.querySelectorAll("textarea.wysiwyg.configured").forEach(textarea=>{if(textarea.id&&!tinymce.get(textarea.id)){if(window.dynamicTinyMCEInitializers&&window.dynamicTinyMCEInitializers[textarea.id]){window.dynamicTinyMCEInitializers[textarea.id]()}}})};const initStandardEditors=()=>{const standardEditors=document.querySelectorAll("textarea.wysiwyg:not(.configured)");if(standardEditors.length>0){this.initTheme();tinymce.init({selector:"textarea.wysiwyg:not(.configured)",...this.defaults,...this.themeConfig,...this.required})}};initConfiguredEditors();initStandardEditors()})}};TinyMCEManager.initTheme();if(!TinyMCEManager.eventsInitialized){TinyMCEManager.eventsInitialized=true;document.addEventListener("themeChanged",()=>{TinyMCEManager.switchTheme()});if(typeof appEvents!=="undefined"){appEvents.on("redraw",()=>TinyMCEManager.initDynamicEditors())}}omniccu.ready(()=>{if(typeof tinymce!=="undefined"){TinyMCEManager.switchTheme()}});omniccu.asyncRequest=class AsyncRequest{constructor(route,options={}){this.route=route;this.target=options.target||null;this.method=(options.method||"get").toLowerCase();this.data=options.payload||{};this.init()}getHeaders(){return{"X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').content,"X-Requested-With":"XMLHttpRequest"}}async makeRequest(){try{const options={method:this.method,headers:this.getHeaders(),withCredentials:true};if(this.method==="get"){options.params=this.data}else{Object.assign(options,this.data)}const response=await axios(this.route,options);receiver.process(response)}catch(error){if(error.response.data.message&&error.response.data.message==="CSRF token mismatch."){try{await omniccu.refreshCsrf.refresh();const refreshedOptions={...options,headers:this.getHeaders()};const response=await axios(this.route,refreshedOptions);receiver.process(response)}catch(csrfError){console.error("Failed to refresh CSRF token:",csrfError)}}else{receiver.process(error.response)}console.error("Request error:",error)}}setupLazyLoad(){const observer=new IntersectionObserver(entries=>{entries.forEach(entry=>{if(entry.isIntersecting){this.makeRequest();observer.disconnect()}})});const observeElement=()=>{const element=document.getElementById(this.target);if(element)observer.observe(element)};if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",observeElement)}else{observeElement()}}init(){if(this.target){this.setupLazyLoad()}else{if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",()=>this.makeRequest())}else{this.makeRequest()}}}};omniccu.XAction=(selector=document)=>{const parentElement=typeof selector==="string"?document.querySelector(selector):selector;if(!parentElement){console.warn("Invalid selector or element provided to XAction");return}parentElement.querySelectorAll(".x-action").forEach(element=>{if(element.dataset.xactionInitialized)return;element.dataset.xactionInitialized="1";element.addEventListener("click",async event=>{event.preventDefault();globalOverlay.show();const options={method:element.dataset.method?.toLowerCase()||"get",headers:{"X-CSRF-TOKEN":document.querySelector('meta[name="csrf-token"]').content,"X-Requested-With":"XMLHttpRequest"},withCredentials:true};if(element.dataset.payload){try{const data=JSON.parse(element.dataset.payload);if(options.method==="get"){options.params=data}else{Object.assign(options,{data:data})}}catch(e){console.error("Invalid JSON in data-payload attribute:",e);globalOverlay.hide();return}}const endpoint=element.href||element.getAttribute("href")||element.dataset.endpoint;try{const response=await axios(endpoint,options);receiver.process(response)}catch(error){if(error.response.data.message&&error.response.data.message==="CSRF token mismatch."){omniccu.refreshCsrf.refresh().then(()=>{options.headers["X-CSRF-TOKEN"]=document.querySelector('meta[name="csrf-token"]').content;return axios(endpoint,options)}).then(response=>receiver.process(response)).catch(error=>{console.log("double token error")})}else{receiver.process(error.response);console.error("Request error:",error)}}finally{globalOverlay.hide()}})})};omniccu.ready(()=>omniccu.XAction());appEvents.on("redraw",target=>{if(target){omniccu.XAction(target)}});class AccordionManager{constructor(){this.initializeEventListeners();this.handleInitialHash()}closest(element,selector){if(!element)return null;return element.closest(selector)}children(element,selector){return element.querySelectorAll(`:scope > ${selector}`)}debug(message){}updateUrl(el){if(history.pushState){const newUrl=window.location.href.replace(window.location.hash,"").replace(/#$/,"");if(el.classList.contains("open")&&el.getAttribute("id")){history.pushState(null,null,newUrl+"#"+el.getAttribute("id"))}else{history.pushState(null,null,newUrl)}}}getScrollableParent(el){let parent=el.parentElement;while(parent&&parent!==document.body){const style=window.getComputedStyle(parent);const overflowY=style.overflowY;if((overflowY==="auto"||overflowY==="scroll")&&parent.scrollHeight>parent.clientHeight){return parent}parent=parent.parentElement}return null}isFullyVisible(element){const rect=element.getBoundingClientRect();const scrollableParent=this.getScrollableParent(element);if(scrollableParent){const containerRect=scrollableParent.getBoundingClientRect();this.debug(`Element top: ${rect.top}, bottom: ${rect.bottom}, container top: ${containerRect.top}, bottom: ${containerRect.bottom}`);return rect.top>=containerRect.top&&rect.bottom<=containerRect.bottom}const windowHeight=window.innerHeight||document.documentElement.clientHeight;this.debug(`Element top: ${rect.top}, bottom: ${rect.bottom}, window height: ${windowHeight}`);return rect.top>=0&&rect.bottom<=windowHeight}bringToViewport(el,isInitialLoad=false){this.debug("bringToViewport called");if(!el){this.debug("No element provided, exiting bringToViewport");return}if(typeof el==="string"){el=document.querySelector(el)}if(!el||!el.nodeType){this.debug("Invalid element, exiting bringToViewport");return}this.debug(`Checking visibility for element: ${el.id||"unnamed"}`);if(isInitialLoad||!this.isFullyVisible(el)){this.scrollToElement(el,isInitialLoad)}else{this.debug("Element fully visible, no scrolling needed")}}scrollToElement(el,isInitialLoad){const rect=el.getBoundingClientRect();const scrollableParent=this.getScrollableParent(el);if(scrollableParent){const containerRect=scrollableParent.getBoundingClientRect();const containerHeight=scrollableParent.clientHeight;const relativeTop=rect.top-containerRect.top;let scrollTopTarget;if(isInitialLoad||rect.height>containerHeight*.8){scrollTopTarget=scrollableParent.scrollTop+relativeTop-20}else{scrollTopTarget=scrollableParent.scrollTop+relativeTop-(containerHeight-rect.height)/2}this.debug(`Scrolling container to Y position: ${scrollTopTarget}`);scrollableParent.scrollTo({top:Math.max(0,scrollTopTarget),behavior:"smooth"})}else{const viewportHeight=window.innerHeight||document.documentElement.clientHeight;let scrollTopTarget;if(isInitialLoad){scrollTopTarget=window.pageYOffset+rect.top-20}else if(rect.height>viewportHeight*.8){scrollTopTarget=window.pageYOffset+rect.top-20}else{scrollTopTarget=window.pageYOffset+rect.top-(viewportHeight-rect.height)/2}this.debug(`Scrolling to Y position: ${scrollTopTarget}`);window.scrollTo({top:Math.max(0,scrollTopTarget),behavior:"smooth"})}}handleAccordionClick(event){const link=event.target.closest(".accordion-header a");if(!link)return;event.preventDefault();this.debug("Accordion click event");const panel=this.closest(link,".accordion-item");const wasOpen=panel.classList.contains("open");const panelContent=this.children(panel,".accordion-collapse")[0];const bsCollapse=new bootstrap.Collapse(panelContent,{toggle:true});if(wasOpen){panel.classList.remove("open");link.classList.add("collapsed");link.setAttribute("aria-expanded","false");bsCollapse.hide()}else{panel.classList.add("open");link.classList.remove("collapsed");link.setAttribute("aria-expanded","true");bsCollapse.show();const ab=this.children(panel,".accordion-header .accordion-button")[0];ab.classList.remove("collapsed");this.handleSingle(panel);panelContent.addEventListener("shown.bs.collapse",()=>{this.debug("Panel fully expanded, calling bringToViewport");this.bringToViewport(panel,false)},{once:true})}this.updateUrl(panel)}autoAccordion(hashString=null){hashString=hashString||window.location.hash;hashString="#"+hashString.replace(/^#/,"");this.debug(`autoAccordion hashString: ${hashString}`);if(hashString!=="#"){const targetElement=document.querySelector(".accordion "+hashString);const hasAccordionParent=this.closest(targetElement,".accordion");if(hasAccordionParent){if(targetElement){this.debug(`Found target element: ${hashString}`);const panel=this.closest(targetElement,".accordion-item");if(!panel.classList.contains("open")){const panelContent=this.children(panel,".accordion-collapse")[0];const bsCollapse=new bootstrap.Collapse(panelContent,{toggle:true});panel.classList.add("open");bsCollapse.show();const ab=this.children(panel,".accordion-header .accordion-button")[0];ab.classList.remove("collapsed");this.handleSingle(panel);panelContent.addEventListener("shown.bs.collapse",()=>{this.debug("Initial panel fully expanded, calling bringToViewport");this.bringToViewport(panel,true)},{once:true})}else{this.bringToViewport(panel,true)}}else{this.debug("No panel found for hash")}}}}handleSingle(panel){if(panel.closest(".accordion").classList.contains("single")){this.debug("single accordion. closing others.");this.children(panel.closest(".accordion"),".accordion-item").forEach(p=>{if(p!==panel&&p.classList.contains("open")){p.classList.remove("open");const pc=this.children(p,".accordion-collapse")[0];const bsc=new bootstrap.Collapse(pc,{toggle:true});const ab=this.children(p,".accordion-header .accordion-button")[0];ab.classList.add("collapsed");bsc.hide()}})}}handleJumpLink(event){const link=event.target.closest('a[href^="#"]:not([data-bs-toggle]):not([href="\\#"]):not([rel]):not(.accordion .accordion-header a)');if(!link)return;if(link.hash!==""){let targetElement=document.querySelector(".accordion "+link.hash);let targetAName=document.querySelector('.accordion a[name="'+link.hash.replace("#","")+'"]');let hasAccordionParent=this.closest(targetElement,".accordion")||this.closest(targetAName,".accordion");if(hasAccordionParent){this.debug("internal? "+link.hash);event.preventDefault();this.debug("trying to animate scroll to "+document.querySelector(link.hash).offsetTop);this.bringToViewport(link.hash,false)}}}handleHashLink(event){const link=event.target.closest('a[href*="#"]:not([href^="#"])');if(!link)return;this.autoAccordion(link.hash)}initializeEventListeners(){document.addEventListener("click",this.handleAccordionClick.bind(this));document.addEventListener("click",this.handleJumpLink.bind(this));document.addEventListener("click",this.handleHashLink.bind(this));document.querySelectorAll(".accordion").forEach(accordion=>{accordion.addEventListener("hide.bs.collapse",e=>{this.closest(e.target,".accordion-item").classList.remove("open")})})}handleInitialHash(){if(window.location.hash){this.debug("auto open");this.autoAccordion()}}}const accordionManager=new AccordionManager;omniccu.TextareaArray=class TextareaArray{constructor(textarea,options={}){this.textarea=textarea;this.charsPerLine=parseInt(textarea.dataset.chars||options.chars||40);this.breakChars=new Set([" ","-","+"]);this.processing=false;this.form=textarea.form;this.baseFieldName=this.textarea.name.replace("_display","");this.hiddenContainer=null;this.initialize()}initialize(){this.textarea.style.whiteSpace="pre";this.textarea.style.overflowX="hidden";this.textarea.style.width=`calc(${this.charsPerLine+3}ch)`;this.textarea.style.resize="vertical";this.textarea.style.overflow="hidden";this.textarea.style.fontFamily="monospace";this.textarea.style.fontSize="14px";this.hiddenContainer=document.querySelector(`#${this.baseFieldName}_hidden_container`);if(!this.hiddenContainer){this.hiddenContainer=document.createElement("div");this.hiddenContainer.id=`${this.baseFieldName}_hidden_container`;this.hiddenContainer.style.display="none";this.textarea.parentNode.insertBefore(this.hiddenContainer,this.textarea.nextSibling)}this.textarea.addEventListener("input",this.handleInput.bind(this));this.textarea.addEventListener("keydown",this.handleKeydown.bind(this));this.loadInitialContent()}loadInitialContent(){const vueApp=this.getVueApp();if(vueApp&&this.baseFieldName in vueApp){const lines=vueApp[this.baseFieldName];if(Array.isArray(lines)){this.textarea.value=lines.join("\n");this.updateHiddenFields(lines);return}}const hiddenFields=Array.from(this.form.querySelectorAll(`input[name^="${this.baseFieldName}["]`)).sort((a,b)=>{const aMatch=a.name.match(/\[(\d+)\]/);const bMatch=b.name.match(/\[(\d+)\]/);const indexA=aMatch?parseInt(aMatch[1]):0;const indexB=bMatch?parseInt(bMatch[1]):0;return indexA-indexB});if(hiddenFields.length>0){const lines=hiddenFields.map(field=>field.value);this.textarea.value=lines.join("\n");this.updateHiddenFields(lines)}}getVueApp(){if(!this.form.__vue_app__)return null;return this.form.__vue_app__._instance.proxy}handleKeydown(event){if(event.key==="Enter"){event.preventDefault();const cursorPos=this.textarea.selectionStart;const value=this.textarea.value;const before=value.substring(0,cursorPos);const after=value.substring(cursorPos);const newValue=before+"\n"+after;this.textarea.value=newValue;this.textarea.selectionStart=this.textarea.selectionEnd=cursorPos+1;this.processInput();return false}}handleInput(){if(this.processing)return;this.processInput()}processInput(){this.processing=true;try{const cursorPos=this.textarea.selectionStart;const currentLines=[];const rawLines=this.textarea.value.split("\n");let totalLength=0;for(let line of rawLines){while(line.length>this.charsPerLine){let breakPoint=this.charsPerLine;for(let i=this.charsPerLine-1;i>=0;i--){if(this.breakChars.has(line[i])){breakPoint=i+1;break}}const firstPart=line.substring(0,breakPoint).trimEnd();currentLines.push(firstPart);totalLength+=firstPart.length+1;line=line.substring(breakPoint).trimStart()}if(line!==undefined){currentLines.push(line);totalLength+=line.length+1}}const newContent=currentLines.join("\n");if(this.textarea.value!==newContent){this.textarea.value=newContent;if(cursorPos>=this.textarea.value.length-1){this.textarea.selectionStart=this.textarea.selectionEnd=this.textarea.value.length}else{this.textarea.selectionStart=this.textarea.selectionEnd=Math.min(cursorPos,this.textarea.value.length)+1}}this.updateHiddenFields(currentLines);const vueApp=this.getVueApp();if(vueApp&&this.baseFieldName in vueApp){vueApp[this.baseFieldName]=[...currentLines]}if(typeof omniccu.textareaAutoheight==="function"){omniccu.textareaAutoheight(this.textarea)}}finally{this.processing=false}}updateHiddenFields(lines){const existingFields=this.form.querySelectorAll(`input[name^="${this.baseFieldName}["]`);existingFields.forEach(field=>field.remove());lines.forEach((line,index)=>{const input=document.createElement("input");input.type="hidden";input.name=`${this.baseFieldName}[${index}]`;input.value=line;this.hiddenContainer.appendChild(input)});this.textarea.dispatchEvent(new Event("input",{bubbles:true}))}};omniccu.ready(()=>{document.querySelectorAll("textarea.textarea-array").forEach(textarea=>{new omniccu.TextareaArray(textarea)})});omniccu.globalOverlay=class GlobalOverlay{constructor(){this.counter=0;this.overlayElement=null;this.injected=false;this.debug=false}show(){this.counter++;if(this.debug){console.log(`[GlobalOverlay] show() called. Counter: ${this.counter}`)}if(!this.injected){this.injectOverlay()}if(this.counter===1){this.overlayElement.style.display="flex"}}hide(){this.counter=Math.max(0,this.counter-1);if(this.debug){console.log(`[GlobalOverlay] hide() called. Counter: ${this.counter}`)}if(this.counter===0&&this.overlayElement){this.overlayElement.style.display="none"}}injectOverlay(){if(this.injected)return;const overlayHTML=`
            <div class="overlay" style="display: none;">
                <div class="d-flex justify-content-center">
                    <div class="spinner-border" role="status">
                        <span class="visually-hidden">Loading...</span>
                    </div>
                </div>
                <div class="w-100 text-center">&nbsp;&nbsp;Loading...</div>
            </div>
        `;const tempDiv=document.createElement("div");tempDiv.innerHTML=overlayHTML;this.overlayElement=tempDiv.firstElementChild;document.body.appendChild(this.overlayElement);this.injected=true;if(this.debug){console.log("[GlobalOverlay] Overlay injected into DOM")}}isVisible(){return this.counter>0}getCounter(){return this.counter}};const globalOverlay=new omniccu.globalOverlay;omniccu.showOverlay=()=>globalOverlay.show();omniccu.hideOverlay=()=>globalOverlay.hide();omniccu.isOverlayVisible=()=>globalOverlay.isVisible();omniccu.getOverlayCounter=()=>globalOverlay.getCounter();omniccu.ready(()=>{globalOverlay.injectOverlay()});omniccu.initDownloadLinks=(selector=document)=>{const parentElement=typeof selector==="string"?document.querySelector(selector):selector;if(!parentElement){console.warn("Invalid selector or element provided to initDownloadLinks");return}const getFilenameFromContentDisposition=disposition=>{if(!disposition)return null;const filenameRegex=/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;const matches=filenameRegex.exec(disposition);if(matches&&matches[1]){return matches[1].replace(/['"]/g,"")}return null};parentElement.querySelectorAll("a.download, button.download").forEach(element=>{if(element.dataset.downloadInitialized)return;element.dataset.downloadInitialized="1";let loadingOverlay=element.querySelector(".loading-overlay");if(!loadingOverlay){loadingOverlay=document.createElement("span");loadingOverlay.className="loading-overlay";element.appendChild(loadingOverlay)}element.addEventListener("click",async event=>{event.preventDefault();element.disabled=true;if(element.tagName==="A"){element.style.pointerEvents="none"}element.classList.add("loading");if(element.classList.contains("with-overlay")){globalOverlay.show()}const url=element.tagName==="A"?element.href:element.dataset.url;const fallbackFilename=element.dataset.filename||url.split("/").pop()||"download";try{const response=await axios({url:url,method:"GET",responseType:"blob",headers:{"X-Requested-With":"XMLHttpRequest"}});const contentDisposition=response.headers["content-disposition"];const serverFilename=getFilenameFromContentDisposition(contentDisposition);const fileName=serverFilename||fallbackFilename;const blob=new Blob([response.data],{type:response.headers["content-type"]});const downloadUrl=URL.createObjectURL(blob);const tempLink=document.createElement("a");tempLink.href=downloadUrl;tempLink.download=fileName;document.body.appendChild(tempLink);tempLink.click();document.body.removeChild(tempLink);setTimeout(()=>URL.revokeObjectURL(downloadUrl),100)}catch(error){console.error("Download failed:",error);toaster.notify("Failed to download file. Please try again.","Error","",true)}finally{if(element.classList.contains("with-overlay")){globalOverlay.hide()}element.disabled=false;if(element.tagName==="A"){element.style.pointerEvents=""}element.classList.remove("loading")}})})};omniccu.ready(()=>omniccu.initDownloadLinks());appEvents.on("redraw",target=>{if(target){omniccu.initDownloadLinks(target)}});