2 lines
47 KiB
JavaScript
2 lines
47 KiB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@apigo.cc/state")):"function"==typeof define&&define.amd?define(["exports","@apigo.cc/state"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).ApigoBase=t.ApigoBase||{},t.ApigoState)}(this,function(t,e){"use strict";const i={get:({url:t,...e})=>i.request({url:t,method:"GET",...e}),post:({url:t,data:e,...s})=>i.request({url:t,method:"POST",data:e,...s}),put:({url:t,data:e,...s})=>i.request({url:t,method:"PUT",data:e,...s}),delete:({url:t,...e})=>i.request({url:t,method:"DELETE",...e}),head:({url:t,...e})=>i.request({url:t,method:"HEAD",...e}),request:async({url:t,method:e="POST",data:s,headers:a={},responseType:l,timeout:n=1e4})=>{var o;const r={method:e=e.toUpperCase(),signal:null==(o=AbortSignal.timeout)?void 0:o.call(AbortSignal,n)};if(void 0!==s&&"GET"!==e&&"HEAD"!==e){if(s instanceof HTMLFormElement&&(s=new FormData(s)),s&&"object"==typeof s&&!(s instanceof FormData)&&!(s instanceof ArrayBuffer||ArrayBuffer.isView(s))&&Object.values(s).some(t=>t instanceof File||t instanceof Blob||t instanceof FileList||Array.isArray(t)&&t.some(t=>t instanceof File||t instanceof Blob))){const t=new FormData;for(const[e,i]of Object.entries(s))i instanceof FileList||Array.isArray(i)?Array.from(i).forEach(i=>t.append(e,i)):null!=i&&t.append(e,i);s=t}s instanceof FormData?delete a["Content-Type"]:"string"==typeof s||s instanceof ArrayBuffer||ArrayBuffer.isView(s)||(s=JSON.stringify(s),a["Content-Type"]||(a["Content-Type"]="application/json")),r.body=s}for(const t of i.keepHeaders)i._keepHeadersCache[t]&&!a[t]&&(a[t]=i._keepHeadersCache[t]);Object.keys(a).length&&(r.headers=a);const d={error:null,ok:null,status:0,headers:{},responseType:"",result:null};try{const e=await fetch(t,r);Object.assign(d,{ok:e.ok,status:e.status,headers:Object.fromEntries(e.headers.entries())});for(const t of i.keepHeaders){const s=e.headers.get(t);if(s){i._keepHeadersCache[t]=s;try{localStorage.setItem("_http_keep_"+t,s)}catch(t){}}}if(!l){const t=e.headers.get("Content-Type")||"";l=t.includes("application/json")?"json":/image|video|audio|pdf|zip|octet-stream/.test(t)?"binary":"text",d.responseType=l}!1===d.ok&&(d.error=(d.statusText||"HTTP "+d.status+" error")+" for "+t),d.result="json"===l?await e.json():"binary"===l?await e.arrayBuffer():await e.text()}catch(t){Object.assign(d,{error:t.message||String(t),ok:!1})}return d},keepHeaders:["Session-Id","Device-Id"],_keepHeadersCache:{}};for(const t of i.keepHeaders)try{const e=localStorage.getItem("_http_keep_"+t);null!==e&&(i._keepHeadersCache[t]=e)}catch(t){}globalThis.HTTP=i;const s={};globalThis.Component.register("Toast",t=>{t.toast=new bootstrap.Toast(t,{autohide:t.state.delay>0}),globalThis.Util.copyFunction(t,t.toast,"show","hide"),t.addEventListener("show.bs.toast",()=>{if(t.state.delay>0){let e;const i=()=>{t.state.left=t.state.delay/1e3,e=setInterval(()=>{(!t.isConnected||--t.state.left<=0)&&clearInterval(e)},1e3)};i(),t.addEventListener("mouseenter",()=>{clearInterval(e),t.state.left=void 0}),t.addEventListener("mouseleave",i)}})},globalThis.Util.makeDom('\n<div class="toast align-items-center border-0 m-1">\n <div $class="toast-body rounded p-3 text-bg-${this.state?.type}">\n <div class="d-flex align-items-center">\n <div class="flex-grow-1">\n <span style="white-space:pre-wrap" class="fs-6" $text="this.state?.message"></span>\n <template $if="this.state?.left !== undefined">\n <span class="small text-dim ms-2" $text="${this.state?.left}s"></span>\n </template>\n </div>\n <button type="button" class="btn btn-link ms-3 bi bi-x-lg link-reset" style="color:inherit" data-bs-dismiss="toast"></button>\n </div>\n <div class="d-flex justify-content-end gap-3">\n <template $each="this.state?.buttons || [\'{#Close#}\']">\n <button type="button" $class="btn btn-sm btn-${this.state?.type} mt-2" data-bs-dismiss="toast" $onclick="this.result=index+1" $text="item"></button>\n </template>\n </div>\n </div>\n</div>\n'),globalThis.Util.makeDom('<div toast-container="default" class="position-fixed bottom-0 end-0 overflow-auto" style="z-index:3000;max-height:80%"></div>')),s.toast=function(t,e={}){const i=e.delay??5e3,s=document.createElement("Toast");s.state={delay:i,left:i?i/1e3:void 0,type:e.type||"primary",message:t,buttons:e.buttons||[]},globalThis.$(`[toast-container="${e.container||"default"}"]`).appendChild(s),Promise.resolve().then(()=>s.show())},s.toastConfirm=function(t,e={}){return new Promise(i=>s.toast(t,{buttons:["{#Confirm#}"],...e}).then(t=>i(1===t)).catch(()=>i(!1)))},globalThis.UI=s;const a=globalThis.Util.makeDom('\n<div class="auto-form-root">\n <form $class="${this.inline ? \'d-flex flex-wrap align-items-center gap-3\' : (this.vertical ? \'d-flex flex-column\' : (this.horizontal ? \'auto-grid-form forced-horizontal\' : \'auto-grid-form\'))}" $onsubmit="event.stopPropagation();event.preventDefault();this.submit()">\n \n <template $each="this.state.schema || []">\n <div style="display:contents" $if="this.checkIf(item)">\n <label $name="item.name" $class="${this.inline ? \'mb-0 text-muted text-nowrap\' : \'col-form-label text-muted\'}" $text="item.label"></label>\n <div control-wrapper $class="${this.inline ? \'d-flex align-items-center\' : \'mb-3 d-flex align-items-center\'}">\n <input $if="[\'text\', \'password\', \'email\', \'number\', \'date\', \'datetime\', \'file\'].includes(item.type)" $name="item.name" $type="item.type" $.="item.setting || {}" $bind="this.data[item.name]" $class="form-control ${item.type === \'number\' ? \'text-end\' : \'\'}">\n \n <select $if="item.type === \'select\'" $name="item.name" $.="item.setting || {}" $bind="this.data[item.name]" class="form-select">\n <option value="" $if="item.placeholder" $text="item.placeholder" disabled selected></option>\n <option $each="item.options" as="opt" $value="opt.value !== undefined ? opt.value : opt" $text="opt.label || opt"></option>\n </select>\n \n <div $if="[\'checkbox\', \'radio\'].includes(item.type)" class="d-flex align-items-center flex-wrap gap-3 h-100" style="padding: 0 0.75rem; min-height: calc(2.25rem + 2px);">\n <label $each="item.options || [item.text||item.label||item.name]" as="opt" class="form-check mb-0 d-flex align-items-center" style="padding-left:0; cursor:pointer;">\n <input $name="item.name" class="form-check-input m-0 me-2" style="float:none;" $type="item.type" $.="item.setting || {}" $value="item.options ? (opt.value !== undefined ? opt.value : opt) : \'on\'" $bind="this.data[item.name]">\n <span $if="!this.inline || (item.options && item.options.length > 0)" $text="opt.label || opt" class="form-check-label"></span>\n </label>\n </div>\n\n <div $if="item.type === \'switch\'" class="form-check form-switch fs-5 d-flex align-items-center m-0" style="padding: 0 0.75rem; min-height: calc(2.25rem + 2px); display:flex !important;">\n <input $name="item.name" class="form-check-input m-0" style="float:none; cursor:pointer" type="checkbox" $bind="this.data[item.name]">\n </div>\n \n <textarea $if="item.type === \'textarea\'" $name="item.name" class="form-control" $.="item.setting || {}" $bind="this.data[item.name]"></textarea>\n </div>\n </div>\n </template>\n\n <div $if="!this.nobutton" $class="${this.inline ? \'\' : \'d-flex justify-content-end align-items-baseline gap-3 mt-2\'}" $style="${this.inline ? \'\' : \'grid-column:1/-1\'}">\n <div slot-id="actions"></div>\n <button type="submit" class="btn btn-primary" $text="this.submitlabel || \'{#Submit#}\'"></button>\n </div>\n </form>\n</div>\n'),l=globalThis.Util.makeDom("<style>\n .auto-grid-form { display: block; }\n .auto-grid-form .col-form-label { text-align: left; margin-bottom: 0.25rem; padding-top: 0; }\n\n @media (min-width: 576px) { \n .auto-grid-form { display: grid; grid-template-columns: max-content 1fr; gap: 0 1.5rem; } \n .auto-grid-form .col-form-label { text-align: right; margin-bottom: 1rem; padding-right: 0; max-width: 200px; padding-top: calc(0.375rem + 1px); } \n .auto-grid-form [control-wrapper] { min-height: calc(2.25rem + 2px); }\n }\n\n .auto-grid-form.forced-horizontal { display: grid !important; grid-template-columns: max-content 1fr !important; gap: 0 1.5rem !important; }\n .auto-grid-form.forced-horizontal .col-form-label { text-align: right !important; margin-bottom: 1rem !important; padding-right: 0 !important; max-width: 200px !important; padding-top: calc(0.375rem + 1px) !important; }\n .auto-grid-form.forced-horizontal [control-wrapper] { min-height: calc(2.25rem + 2px) !important; }\n\n .auto-form-root .form-check-input { width: 1.2em; height: 1.2em; }\n .auto-form-root .form-switch .form-check-input { width: 2em; }\n</style>");globalThis.Component.register("AutoForm",t=>{t.state.schema||(t.state.schema=[]);const e=t=>t&&"object"==typeof t&&!t.__isProxy?globalThis.NewState(t):t;t.state.__watch("data",i=>t.data=e(i)),t.data=e(t.state.data||{}),t.vertical=t.hasAttribute("vertical"),t.horizontal=t.hasAttribute("horizontal"),t.inline=t.hasAttribute("inline"),t.nobutton=t.hasAttribute("nobutton"),t.request={method:"POST"},t.response={},t.result=null,t.form=globalThis.$(t,"form"),t.submit=(e={})=>{var i,s;if(!t.form.reportValidity())return null==(s=null==(i=globalThis.UI)?void 0:i.toast)?void 0:s.call(i,"{#verify failed#}",{type:"danger"});if(!t.dispatchEvent(new CustomEvent("submit",{detail:t.data,cancelable:!0,bubbles:!1})))return;const a={...t.request,data:t.data,noui:!0,...e};let l=null;if(t.api)l=t.api.do(a);else{if(!t.request.url)return console.warn("{#please config .api or .request.url to auto submit#}");l=globalThis.HTTP.request(a)}l.then(e=>{if(t.response=e,t.result=e.result,"object"==typeof e.result&&e.result.error)throw new Error(e.result.error);t.dispatchEvent(new CustomEvent("response",{detail:e,bubbles:!1}))}).catch(e=>{var i;(null==(i=globalThis.UI)?void 0:i.toast)&&globalThis.UI.toast(e.message,{type:"danger"}),t.dispatchEvent(new CustomEvent("error",{detail:e,bubbles:!0}))})},t.checkIf=e=>{if(!e.if)return!0;try{return new Function("Hash","LocalStorage","State","item","data","return "+e.if).call(t,globalThis.Hash,globalThis.LocalStorage,globalThis.State,e,t.data)}catch(t){return!1}}},a,l);const n=t=>{let e=t.querySelector("[control-wrapper]");if(e)return e;for(const i of t.querySelectorAll("template"))if(e=n(i.content),e)return e;return null},o={customTypes:[],register:(t,e)=>{const i=e||t;o.customTypes.find(e=>e.name===t)||(o.customTypes.push({name:t,typeName:i}),o._addAutoFormComponent(t,i))},_addAutoFormComponent:(t,e)=>{const i=n(a);if(i){const s=globalThis.Util.makeDom(`<${t} $if="item.type?.toLowerCase() === '${e.toLowerCase()}'" $name="item.name" $.="item.setting || {}" $bind="this.data[item.name]" class="w-100"></${t}>`);i.appendChild(s)}}};globalThis.AutoForm=o;const r=(t={})=>{const e=new Map,i=new Map;let s=1;const a=globalThis.Util.newAvg();let l=0,n=0,o=0,r=null,d=null,c=!1;const m=t.itemHeight||null;return{reset:(t,p)=>{if(c=!1,e.clear(),i.clear(),a.clear(),o=0,r=null,d=null,!(null==t?void 0:t.length))return[];const u=t.length;s=Math.ceil(Math.sqrt(u))||10;const h=window.getComputedStyle(p);l=parseFloat(h.paddingTop)||0,n=parseFloat(h.rowGap)||0;const b=Math.max(10,Math.ceil((p.clientHeight||100)/(m||32)));return t.slice(0,Math.min(3*b,u))},init:(t,l)=>{if(c)return;const n=t.length;let o=m||a.get()||32;n>0&&"object"==typeof t[0]&&null!==t[0]&&t[0]._itemHeight&&(o=t[0]._itemHeight),a.add(o),null===r&&(r=0,d=0);for(let i=0;i<n;i++)if(!e.has(i)){const s="object"==typeof t[i]&&null!==t[i]&&t[i]._itemHeight?t[i]._itemHeight:o;e.set(i,s)}for(let t=0;t<n;t+=s)i.set(t,Math.min(s,n-t)*o);c=!0,l()},update:(t,l)=>{if(0===l.offsetHeight)return;if(null===r){const t=window.getComputedStyle(l);r=parseFloat(t.marginTop)||0,d=parseFloat(t.marginBottom)||0}0!==t||o||(o=r);const c=l.offsetHeight+r+d+n,m=e.get(t);if(c!==m){e.set(t,c),a.add(c);const l=c-(m||0),n=t-t%s;i.has(n)&&i.set(n,i.get(n)+l)}},calc:(t,r)=>{if(!c||!r)return null;const d=r.length,m=Math.max(16,a.get()||32);let p=Math.max(10,Math.ceil((t.clientHeight||100)/m)),u=l+o+n,h=0,b=0,f=0,g=0,v=[];const y=t.scrollTop;let x=0;for(let t=0;t<d;t++){if(++x>2*d)throw new Error("VirtualScroll infinite loop");if(0===b){const a=i.get(t);if(a&&u+a<=y&&t+s<d)u+=a,t+=s-1;else{const i=e.get(t);if(u+i<=y&&t<d-1)u+=i;else{b=1;let i=Math.max(0,t);f=Math.max(0,i-p),g=Math.min(f+3*p,d),t=g-1,v=r.slice(f,g);for(let t=f;t<i;t++)u-=e.get(t)}}}else if(1===b){const a=i.get(t);a?(h+=a,t+=s-1):h+=e.get(t)}}return{prevHeight:Math.max(0,u-l-o-n-(f>0?n:0)),postHeight:h>0?Math.max(0,h-2*n):0,renderedList:v,listStartIndex:f}}}};globalThis.VirtualScroll=r;let d=!1,c={},m={};const p={start:(t,{onmousemove:e,onmouseup:i})=>{c={x:t.clientX,y:t.clientY,w:0,h:0},m={onmousemove:e,onmouseup:i},d=!0}};"undefined"!=typeof document&&(document.addEventListener("mouseup",t=>{var e;d&&(d=!1,null==(e=m.onmouseup)||e.call(m,{event:t,...c}))}),document.addEventListener("mousemove",t=>{var e;d&&(c.w=t.clientX-c.x,c.h=t.clientY-c.y,null==(e=m.onmousemove)||e.call(m,{event:t,...c}))})),globalThis.MouseMover=p;const u=globalThis.Component.register("API",t=>{const e=t.request&&"object"==typeof t.request?t.request:{},i=t.response&&"object"==typeof t.response?t.response:{},s=t.result&&"object"==typeof t.result?t.result:{};t.request=globalThis.NewState({url:"",method:"GET",headers:{},data:null,timeout:1e4,responseType:"",...e,headers:{...e.headers||{}}}),t.response=globalThis.NewState({loading:!1,ok:null,status:null,error:null,headers:{},responseType:"",result:null,...i,headers:{...i.headers||{}}}),t.result=globalThis.NewState(s),t.do=(e={})=>new Promise((i,s)=>{const a={...t.request,...e};if(!a.url)throw new Error(".url is required");a.headers={...t.request.headers,...e.headers},t.response.loading=!0,globalThis.HTTP.request(a).then(e=>{if(Object.keys(e).forEach(i=>{"result"!==i&&(t.response[i]=e[i])}),e.result&&"object"==typeof e.result&&t.result&&"object"==typeof t.result?Object.assign(t.result,e.result):t.result=e.result,t.response.loading=!1,!1===e.ok)throw new Error(e.error);if("object"==typeof e.result&&e.result.error)throw new Error(e.result.error);t.dispatchEvent(new CustomEvent("response",{detail:e,bubbles:!1})),i(e)}).catch(i=>{var a;!e.noui&&(null==(a=globalThis.UI)?void 0:a.toast)&&globalThis.UI.toast(i.message,{type:"danger"}),t.dispatchEvent(new CustomEvent("error",{detail:i,bubbles:!0})),s(i)})});let a=null;t.request.__watch(null,()=>{t.hasAttribute("auto")&&t.request.url&&(a||(a=Promise.resolve().then(()=>{t.do(),a=null})))})});globalThis.Component.register("Modal",t=>{t.modal=new bootstrap.Modal(t),t.addEventListener("bind",e=>{e.detail?t.modal.show():t.modal.hide()}),t.addEventListener("hide.bs.modal",()=>{var e;null==(e=document.activeElement)||e.blur(),t.dispatchEvent(new CustomEvent("change",{bubbles:!1,detail:!1}))}),globalThis.Util.copyFunction(t,t.modal,"show","hide")},globalThis.Util.makeDom('\n<div class="modal fade" data-bs-backdrop="static">\n <div class="modal-dialog modal-dialog-centered">\n <div $class="modal-content border-${this.state?.type || \'primary\'} border-2 shadow-lg">\n <div slot-id="header" class="modal-header py-2 px-3 bg-light">\n <h6 $class="modal-title fw-bold text-${this.state?.type || \'primary\'}" $text="this.state?.title"></h6>\n <button type="button" class="btn btn-link ms-2 bi bi-x-lg link-reset p-0" style="color:inherit; text-decoration:none" data-bs-dismiss="modal"></button>\n </div>\n <div slot-id="body" class="modal-body p-3"></div>\n <div slot-id="footer" class="modal-footer py-2 px-3 bg-light"></div>\n </div>\n </div>\n</div>\n')),globalThis.Component.register("Dialog",globalThis.Component.getSetupFunction("Modal"),globalThis.Util.makeDom('\n<div class="modal fade" data-bs-backdrop="static">\n <div class="modal-dialog modal-dialog-centered">\n <div $class="modal-content border-${this.state?.type || \'primary\'} border-2 shadow-lg">\n <template $if="this.state?.title">\n <div $class="modal-header py-2 px-3 bg-light fw-bold text-${this.state?.type || \'primary\'}" $text="this.state?.title"></div>\n </template>\n <div class="modal-body p-4 text-center">\n <div $text="this.state?.message" class="fs-5 text-secondary"></div>\n </div>\n <div class="modal-footer py-2 px-3 bg-light border-0 d-flex justify-content-center gap-3">\n <template $each="this.state?.buttons">\n <button type="button" $class="btn btn-${this.state?.type} px-4" data-bs-dismiss="modal" $onclick="this.result=index+1" $text="item"></button>\n </template>\n </div>\n </div>\n </div>\n</div>\n'));let h=0;globalThis.UI.showDialog=function({title:t="",message:e="",buttons:i=["{#Close#}"],type:s="body"}){const a=document.body.appendChild(document.createElement("Dialog"));return a.style.zIndex=2e3+ ++h,Promise.resolve().then(()=>{Object.assign(a.state,{message:e,title:t,type:s,buttons:i}),a.show()}),new Promise(t=>{a.addEventListener("change",e=>{h--,t(a.result||0),a.remove()})})},globalThis.UI.alert=function(t,e={}){return globalThis.UI.showDialog({message:t,...e})},globalThis.UI.confirm=function(t,e={}){return new Promise(i=>globalThis.UI.showDialog({message:t,buttons:["{#Cancel#}","{#Confirm#}"],...e}).then(t=>i(t>=2)).catch(()=>i(!1)))},globalThis.Component.register("TagsInput",t=>{t._thisObj=t,t.addEventListener("bind",e=>{t.state.tags=Array.isArray(e.detail)?e.detail:[]})},globalThis.Util.makeDom(`\n<div class="form-control d-flex flex-wrap gap-1 align-items-center" style="min-height:38px;cursor:text">\n <template $each="this.state.tags">\n <button type="button" class="btn btn-sm btn-outline-primary rounded-pill py-0 px-2" $onkeydown='${globalThis.Util.getFunctionBody(function(t){["Backspace","Delete"].includes(t.key)&&(t.preventDefault(),this.state.tags.splice(index,1),this.state.tags=this.state.tags,this.dispatchEvent(new CustomEvent("change",{bubbles:!1,detail:this.state.tags})),Promise.resolve().then(()=>{const t=globalThis.$$(this,"button");(t.length>0?t[index>0?index-1:0]:globalThis.$(this,"input")).focus()}))})}' $text="item"></button>\n </template>\n <input type="text" class="border-0 shadow-none py-0 px-2 flex-grow-1 bg-transparent" placeholder="{#new tag name#}" style="min-width:100px;width:0;outline:none" $onchange="event.stopPropagation()" $oninput="event.stopPropagation()" $onkeydown='${globalThis.Util.getFunctionBody(function(t){if(!t.isComposing&&["Enter",","," "].includes(t.key)){t.preventDefault();const e=thisNode.value.trim();e&&!this.state.tags.includes(e)&&(this.state.tags.push(e),this.state.tags=this.state.tags,this.dispatchEvent(new CustomEvent("change",{bubbles:!1,detail:this.state.tags}))),thisNode.value=""}})}'>\n</div>\n`),globalThis.Util.makeDom("<style>TagsInput button:focus {background-color:var(--bs-btn-hover-bg);color:var(--bs-btn-hover-color)}</style>")),globalThis.AutoForm&&globalThis.AutoForm.register("TagsInput"),globalThis.Component.register("DatePicker",t=>{t._thisObj=t,t.state=globalThis.NewState({start:"",end:""}),t.addEventListener("bind",e=>{var i,s,a;t.state.start=e.detail||"";const l=t.closest("AutoForm"),n=t.getAttribute("name"),o=null==(s=null==(i=null==l?void 0:l.state)?void 0:i.schema)?void 0:s.find(t=>t.name===n),r=(null==(a=null==o?void 0:o.setting)?void 0:a.rangeEnd)||t.rangeEnd;l&&r&&(t.state.end=l.data[r]||"")}),Object.defineProperty(t,"isRange",{get:()=>{var e,i,s;const a=t.closest("AutoForm"),l=t.getAttribute("name"),n=null==(i=null==(e=null==a?void 0:a.state)?void 0:e.schema)?void 0:i.find(t=>t.name===l);return!(!(null==(s=null==n?void 0:n.setting)?void 0:s.rangeEnd)&&!t.rangeEnd)}}),Object.defineProperty(t,"value",{get:()=>t.state.start,set:e=>{t.state.start=e||""}}),t.updateStart=e=>{t.state.start=e,t.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:e}))},t.updateEnd=e=>{var i,s,a;t.state.end=e;const l=t.closest("AutoForm"),n=t.getAttribute("name"),o=null==(s=null==(i=null==l?void 0:l.state)?void 0:i.schema)?void 0:s.find(t=>t.name===n),r=(null==(a=null==o?void 0:o.setting)?void 0:a.rangeEnd)||t.rangeEnd;l&&r&&(l.data[r]=e)}},globalThis.Util.makeDom('\n<div class="d-flex align-items-center gap-1 w-100">\n <input type="date" class="form-control h-100" $bind="this.state.start" $onchange="this.updateStart(thisNode.value)">\n <template $if="this.isRange">\n <span class="text-muted mx-1">-</span>\n <input type="date" class="form-control h-100" $bind="this.state.end" $onchange="this.updateEnd(thisNode.value)">\n </template>\n</div>\n')),globalThis.AutoForm&&globalThis.AutoForm.register("DatePicker"),globalThis.Component.register("ColorPicker",t=>{t._thisObj=t,t.state=globalThis.NewState({value:"#000000"}),t.addEventListener("bind",e=>{t.state.value=e.detail||"#000000"}),Object.defineProperty(t,"value",{get:()=>t.state.value,set:e=>{t.state.value=e||"#000000"}}),t.updateValue=e=>{t.state.value=e,t.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:e}))}},globalThis.Util.makeDom('\n<div class="d-flex align-items-center gap-2 w-100 h-100">\n <input type="color" class="form-control form-control-color flex-shrink-0" style="width: 3rem; padding: 0.25rem" $bind="this.state.value" $onchange="this.updateValue(thisNode.value)">\n <input type="text" class="form-control" $bind="this.state.value" $onchange="this.updateValue(thisNode.value)">\n</div>\n')),globalThis.AutoForm&&globalThis.AutoForm.register("ColorPicker");const b=["alarm","archive","arrow-left","arrow-right","bag","bank","basket","bell","bookmark","box","briefcase","calendar","camera","cart","chat","check","chevron-down","chevron-left","chevron-right","chevron-up","clock","cloud","code","collection","command","cpu","credit-card","cup","dash","database","display","door-closed","download","droplet","earbuds","edit","egg","eject","envelope","eraser","eye","file","filter","flag","folder","gear","gem","gift","graph-up","grid","hammer","hand-thumbs-up","heart","house","image","inbox","info-circle","journal","key","laptop","layers","layout-text-sidebar-reverse","lightbulb","link","list","lock","map","mic","moon","mouse","music-note","newspaper","palette","paperclip","pause","pencil","person","phone","pie-chart","play","plus","printer","puzzle","question-circle","reception-4","record","reply","rss","save","search","send","server","share","shield","shop","shuffle","skip-end","skip-start","slash","sliders","smartphone","speaker","speedometer","spellcheck","square","star","stickies","stop","stopwatch","suit-heart","sun","table","tag","tags","telephone","terminal","text-paragraph","thermometer","three-dots","ticket","tools","trash","trophy","truck","tv","umbrella","unlock","upload","vector-pen","wallet","watch","wifi","window","wrench","x","zoom-in","zoom-out","activity","at","award","backspace","badge-3d","badge-4k","badge-8k","badge-ad","badge-ar","badge-cc","badge-hd","badge-tm","badge-vo","badge-vr","badge-wc","bar-chart","battery","bicycle","binoculars","blockquote-left","blockquote-right","book","bookshelf","bootstrap","border-all","border-bottom","border-center","border-inner","border-left","border-middle","border-outer","border-right","border-style","border-top","border-width","bounding-box","box-arrow-down","box-arrow-in-down","box-arrow-in-left","box-arrow-in-right","box-arrow-in-up","box-arrow-left","box-arrow-right","box-arrow-up","box-seam","brightness-alt-high","brightness-alt-low","brightness-high","brightness-low","broadcast","brush","bucket","bug","building","bullseye","calculator","calendar-check","calendar-date","calendar-day","calendar-event","calendar-minus","calendar-month","calendar-plus","calendar-range","calendar-week","calendar-x","calendar2","calendar3","calendar4","camera-reels","camera-video","capslock","card-checklist","card-heading","card-image","card-list","card-text","caret-down","caret-left","caret-right","caret-up","cart-check","cart-dash","cart-plus","cart-x","cash","cash-stack","cast","chat-dots","chat-left","chat-quote","chat-right","chat-square","chat-text","check-all","check-circle","check-square","circle","clipboard","cloud-arrow-down","cloud-arrow-up","cloud-check","cloud-download","cloud-fog","cloud-hail","cloud-lightning","cloud-minus","cloud-moon","cloud-plus","cloud-rain","cloud-slash","cloud-snow","cloud-sun","cloud-upload","clouds","cloudy","code-slash","code-square","collection-play","columns","columns-gap","compass","cone","cone-striped","controller","credit-card-2-back","credit-card-2-front","crop","cup-straw","cursor","dash-circle","dash-square","diagram-2","diagram-3","diamond","dice-1","dice-2","dice-3","dice-4","dice-5","dice-6","disc","discord","distribute-horizontal","distribute-vertical","door-open","dot","droplet-half","easel","egg-fried","emoji-angry","emoji-dizzy","emoji-expressionless","emoji-frown","emoji-heart-eyes","emoji-laughing","emoji-neutral","emoji-smile","emoji-sunglasses","emoji-wink","envelope-open","exclamation","exclamation-circle","exclamation-diamond","exclamation-octagon","exclamation-square","exclamation-triangle","eye-slash","eyedropper","facebook","file-arrow-down","file-arrow-up","file-binary","file-break","file-check","file-code","file-diff","file-earmark","file-excel","file-image","file-lock","file-medical","file-minus","file-music","file-pdf","file-person","file-play","file-plus","file-post","file-ppt","file-richtext","file-slides","file-spreadsheet","file-text","file-word","file-zip","files","film","filter-circle","filter-left","filter-right","filter-square","fingerprint","flower1","flower2","flower3","folder-check","folder-minus","folder-plus","folder-symlink","folder-x","folder2-open","fonts","forward","front","fullscreen","fullscreen-exit","funnel","gear-wide","gender-female","gender-male","gender-trans","geo","geo-alt","github","globe","google","graph-down","grid-1x2","grid-3x2","grid-3x3","grip-horizontal","grip-vertical","hand-index","hand-thumbs-down","handbag","hash","headphones","headset","heart-half","heptagon","hourglass","hourglass-bottom","hourglass-split","hourglass-top","house-door","hr","hurricane","image-alt","images","infinity","input-cursor","instagram","intersect","journal-album","journal-arrow-down","journal-arrow-up","journal-bookmark","journal-check","journal-code","journal-medical","journal-minus","journal-plus","journal-richtext","journal-text","journal-x","journals","justify","kanban","keyboard","ladder","lamp","layers-half","layout-sidebar","layout-split","layout-three-columns","life-preserver","lightbulb-off","lightning","lightning-charge","link-45deg","linkedin","list-check","list-nested","list-ol","list-stars","list-task","list-ul","mailbox","markdown","mask","mastodon","megaphone","menu-app","menu-button","messenger","mic-mute","minecart","minecart-loaded","moisture","mouse2","mouse3","music-note-beamed","music-note-list","music-player","node-minus","node-plus","nut","octagon","option","outlet","paint-bucket","patch-check","patch-exclamation","patch-minus","patch-plus","patch-question","pause-btn","pause-circle","peace","pen","pencil-square","pentagon","person-badge","person-bounding-box","person-circle","person-lines-fill","phone-landscape","phone-vibrate","pie-chart-fill","pin","pin-angle","pin-fill","pin-map","pip","play-btn","play-circle","plug","plus-circle","plus-square","power","question","question-diamond","question-square","rainbow","receipt","receipt-cutoff","reception-0","reception-1","reception-2","reception-3","record-btn","record-circle","record2","recycle","reddit","reply-all","router","rulers","safe","save2","sd-card","segmented-nav","shield-check","shield-exclamation","shield-lock","shield-shaded","shield-slash","shift","signpost","signpost-2","signpost-split","sim","skip-backward","skip-forward","slack","slash-circle","slash-square","smartwatch","snow","snow2","snow3","sort-alpha-down","sort-alpha-up","sort-numeric-down","sort-numeric-up","soundwave","speedometer2","square-half","stack","star-half","stars","stop-btn","stop-circle","suit-club","suit-diamond","suit-spade","sunglasses","sunrise","sunset","symmetry-horizontal","symmetry-vertical","tablet","tablet-landscape","telegram","telephone-forward","telephone-inbound","telephone-outbound","telephone-plus","telephone-x","text-center","text-indent-left","text-indent-right","text-left","text-right","thermometer-half","thermometer-high","thermometer-low","thermometer-snow","thermometer-sun","three-dots-vertical","toggle-off","toggle-on","toggle2-off","toggle2-on","tornado","translate","trash2","tree","truck-flatbed","tsunami","type","type-bold","type-h1","type-h2","type-h3","type-italic","type-strikethrough","type-underline","ui-checks","ui-checks-grid","ui-radios","ui-radios-grid","union","upc","upc-scan","view-list","view-stacked","vinyl","voicemail","volume-down","volume-mute","volume-off","volume-up","vr","wallet2","water","whatsapp","wifi-1","wifi-2","wifi-off","wind","window-dock","window-sidebar","x-circle","x-diamond","x-octagon","x-square","youtube"];globalThis.Component.register("IconPicker",t=>{t._thisObj=t,t.state=globalThis.NewState({value:"",search:"",open:!1}),t.addEventListener("bind",e=>{t.state.value=e.detail||""}),Object.defineProperty(t,"value",{get:()=>t.state.value,set:e=>{t.state.value=e||""}}),Object.defineProperty(t,"filteredIcons",{get:()=>{var e;const i=(null==(e=t.state.search)?void 0:e.toLowerCase())||"";return b.filter(t=>t.includes(i))}}),t.selectIcon=e=>{t.state.value=e,t.state.open=!1,t.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:e}))},t.toggle=()=>{t.state.open=!t.state.open,t.state.open&&setTimeout(()=>{var e;null==(e=globalThis.$(t,"input"))||e.focus()},10)};const e=e=>{t.contains(e.target)||(t.state.open=!1)};window.addEventListener("click",e),t.addEventListener("remove",()=>window.removeEventListener("click",e))},globalThis.Util.makeDom('\n<div class="dropdown w-100 h-100">\n <button class="btn btn-outline-secondary dropdown-toggle w-100 h-100 d-flex align-items-center justify-content-between px-2" type="button" $onclick="this.toggle()">\n <span class="d-flex align-items-center overflow-hidden">\n <i $if="this.state.value" $class="bi bi-${this.state.value} me-2"></i>\n <span class="text-truncate" $text="this.state.value || \'{#Select Icon#}\'"></span>\n </span>\n </button>\n <div $class="dropdown-menu p-2 shadow ${this.state.open ? \'show\' : \'\'}" style="width: 300px; max-height: 350px; overflow-y: hidden; display: flex; flex-direction: column; z-index: 1050">\n <input type="text" class="form-control form-control-sm mb-2" placeholder="Search icons..." $bind="this.state.search" $onclick="event.stopPropagation()">\n <div class="d-flex flex-wrap gap-1 overflow-auto p-1" style="flex: 1" $onclick="event.stopPropagation()">\n <template $each="this.filteredIcons" as="icon">\n <button type="button" class="btn btn-sm btn-outline-light text-dark p-2 d-flex align-items-center justify-content-center" $onclick="this.selectIcon(icon)" $title="icon" style="width: 40px; height: 40px">\n <i $class="bi bi-${icon}"></i>\n </button>\n </template>\n <div $if="this.filteredIcons.length === 0" class="text-muted p-2 w-100 text-center">No icons found</div>\n </div>\n </div>\n</div>\n'),globalThis.Util.makeDom("<style>\n IconPicker { display: block; height: 100%; }\n IconPicker .dropdown-menu { left: 0; }\n IconPicker .btn-outline-light:hover { background-color: var(--bs-primary-bg-subtle); border-color: var(--bs-primary); }\n</style>")),globalThis.AutoForm&&globalThis.AutoForm.register("IconPicker"),globalThis.Component.register("List",t=>{t.mode=t.getAttribute("mode")||"normal",t.fast=t.hasAttribute("fast"),t.collapsible=t.hasAttribute("collapsible");const e=t.fast?t.querySelector(".vs-pad-top"):null,i=t.fast?t.querySelector(".vs-pad-bottom"):null,s={idfield:"id",labelfield:"label",summaryfield:"summary",groupidfield:"id",grouplabelfield:"label",groupsummaryfield:"summary",groupfield:"group",parentfield:"parent",groupicon:"folder",itemicon:"file"};t.collapsed=globalThis.NewState({}),t.state.renderedList=[];const a=()=>{var e;globalThis.Util.updateDefaults(t,s);let i=t.state.list||[];const a=t.state.filter,l=t.state.order;if(l)if("function"==typeof l)i=[...i].sort(l);else if("string"==typeof l){const t=l.trim().split(/\s+/),s=t[0],a="desc"===(null==(e=t[1])?void 0:e.toLowerCase())||s.startsWith("-"),n=s.startsWith("-")?s.slice(1):s;i=[...i].sort((t,e)=>{const i=t[n],s=e[n];return null==i?a?1:-1:null==s?a?-1:1:"string"==typeof i&&"string"==typeof s?a?s.localeCompare(i):i.localeCompare(s):a?s>i?1:-1:i>s?1:-1})}const n=[];if("group"===t.mode){let e=i;if(a)if("function"==typeof a)e=i.filter(a);else if("string"==typeof a){const s=a.trim().toLowerCase();s&&(e=i.filter(e=>{const i=String(e[t.labelfield]||"").toLowerCase(),a=String(e[t.summaryfield]||"").toLowerCase();return i.includes(s)||a.includes(s)}))}const s={};e.forEach(e=>{var i;return(s[i=e[t.groupfield]]??(s[i]=[])).push(e)}),(t.state.groups||[]).forEach(e=>{const i=s[e[t.groupidfield]],l=String(e[t.grouplabelfield]||"").toLowerCase(),o=String(e[t.groupsummaryfield]||"").toLowerCase(),r="string"==typeof a?a.trim().toLowerCase():"",d=!!r&&(l.includes(r)||o.includes(r));(i&&i.length>0||d||!a)&&(n.push({type:"group",...e}),i&&i.forEach(t=>n.push({type:"item",...t})))})}else if("tree"===t.mode){const e={};i.forEach(i=>{e[i[t.idfield]]=i});const s=new Set;i.forEach(e=>{let i=!1;if(a){if("function"==typeof a)i=a(e);else if("string"==typeof a){const s=a.trim().toLowerCase();if(s){const a=String(e[t.labelfield]||"").toLowerCase(),l=String(e[t.summaryfield]||"").toLowerCase();i=a.includes(s)||l.includes(s)}else i=!0}}else i=!0;i&&s.add(e[t.idfield])});const l=new Set(s);a&&s.forEach(i=>{let s=e[i];for(;s;){const i=s[t.parentfield];if(!i)break;if(l.has(i))break;l.add(i),s=e[i]}});const o={};i.forEach(e=>{if(!a||l.has(e[t.idfield])){const i=e[t.parentfield]||"";(o[i]??(o[i]=[])).push(e)}});const r=(e,i,s)=>e.forEach(e=>{var a;const l=e[t.idfield],d=!!(null==(a=o[l])?void 0:a.length),c=t.collapsed[l];n.push({type:"item",...e,_level:i,_hasChildren:d,_parents:s}),d&&!c&&r(o[l],i+1,[...s,l])});r(o[""]||[],0,[])}else{let e=i;if(a)if("function"==typeof a)e=i.filter(a);else if("string"==typeof a){const s=a.trim().toLowerCase();s&&(e=i.filter(e=>{const i=String(e[t.labelfield]||"").toLowerCase(),a=String(e[t.summaryfield]||"").toLowerCase();return i.includes(s)||a.includes(s)}))}e.forEach(t=>n.push({type:"item",...t}))}t.state.flatList=n};t.state.__watch("list",a),t.state.__watch("filter",a),t.state.__watch("order",a);const l=t.fast?globalThis.VirtualScroll():null;let n=!1;t.refresh=()=>{if(t.fast&&!n){n=!0;try{const s=l.calc(t,t.state.flatList);s&&(e&&(e.style.height=`${s.prevHeight}px`),i&&(i.style.height=`${s.postHeight}px`),t.state.listStartIndex=s.listStartIndex,t.state.renderedList=s.renderedList)}finally{setTimeout(()=>{n=!1},0)}}},t.onItemUpdate=(e,i)=>{t.fast&&l.update(e+(t.state.listStartIndex||0),i)},t.state.__watch("flatList",s=>{t.fast?(e&&(e.style.height="0px"),i&&(i.style.height="0px"),t.state.listStartIndex=0,t.state.renderedList=l.reset(s,t)||[],setTimeout(()=>{t.state.flatList===s&&l.init(s,t.refresh)})):t.state.renderedList=s}),t.selectItem=(e,i)=>{t.hasAttribute("auto-select")&&(t.state.selectedItem=t.state.selectedItem===e[t.idfield]?null:e[t.idfield]),t.dispatchEvent(new CustomEvent("itemclick",{bubbles:!1,detail:{item:e,index:i+(t.fast&&t.state.listStartIndex||0)}}))},t.selectGroup=(e,i)=>{t.hasAttribute("auto-select-group")&&(t.state.selectedGroup=t.state.selectedGroup===e[t.groupidfield]?null:e[t.groupidfield]),t.dispatchEvent(new CustomEvent("groupclick",{bubbles:!1,detail:{item:e,index:i}}))},t.toggleCollapse=e=>{t.collapsible&&e._hasChildren&&(t.collapsed[e[t.idfield]]=!t.collapsed[e[t.idfield]],a())},Object.defineProperty(t,"filter",{get:()=>t.state.filter,set:e=>{t.state.filter=e}}),Object.defineProperty(t,"order",{get:()=>t.state.order,set:e=>{t.state.order=e}});new MutationObserver(()=>{const e=t.getAttribute("filter");"function"!=typeof t.state.filter&&e!==t.state.filter&&(t.state.filter=e||void 0);const i=t.getAttribute("order");"function"!=typeof t.state.order&&i!==t.state.order&&(t.state.order=i||void 0)}).observe(t,{attributes:!0,attributeFilter:["filter","order"]}),t.state.filter=t.getAttribute("filter")||void 0,t.state.order=t.getAttribute("order")||void 0,a()},globalThis.Util.makeDom('\n<div class="list-group overflow-auto" onscroll="this.refresh()" style="overflow-anchor:none">\n <div class="vs-pad-top flex-shrink-0" style="height:0px;"></div>\n <template slot-id="item" $each="this.state.renderedList">\n <div $onupdate="this.onItemUpdate(index, thisNode)" $class="list-group-item d-inline-flex align-items-center pe-2 ${item.type===\'group\'?\'bg-body-tertiary fw-bold ps-2\':\'list-group-item-action \' + (this.mode===\'group\'?\'ps-4\':\'ps-2\')} ${item.type===\'group\'?(this.state?.selectedGroup===item[this.groupidfield]?\'active\':\'\'):(this.state?.selectedItem===item[this.idfield]?\'active\':\'\')}" $onclick="item.type===\'group\'?this.selectGroup(item,index):this.selectItem(item,index)">\n <template $if="item.type === \'group\'">\n <template $if="this.groupicon">\n <span $class="bi bi-${this.groupicon} text-body"></span>\n </template>\n <div class="flex-shrink-0 px-1" $text="${item[this.grouplabelfield]}"></div>\n <div class="text-muted small flex-fill text-end" $text="${item[this.groupsummaryfield]}"></div>\n <div slot-id="group-actions"></div>\n </template>\n <template $if="item.type === \'item\'">\n <template $if="this.mode === \'tree\'">\n <div $style="width:${item._level * 16 + (this.collapsible ? 16 : 0)}px; cursor:${this.collapsible ? \'pointer\' : \'default\'}" class="text-end text-muted flex-shrink-0" $onclick="event.stopPropagation(); this.toggleCollapse(item)">\n <template $if="this.collapsible && item._hasChildren">\n <i $class="bi ${this.collapsed[item[this.idfield]] ? \'bi-caret-right-fill\' : \'bi-caret-down-fill\'}"></i>\n </template>\n </div>\n </template>\n <template $if="this.mode === \'tree\'">\n <span $class="text-muted bi bi-${item._hasChildren ? this.groupicon : this.itemicon}"></span>\n </template>\n <template $if="this.mode !== \'tree\' && this.itemicon">\n <span $class="bi bi-${this.itemicon} text-body"></span>\n </template>\n <div class="flex-shrink-0 px-1" $text="${item[this.labelfield]}"></div>\n <div class="text-muted small flex-fill text-end" $text="${item[this.summaryfield]}"></div>\n <div slot-id="item-actions"></div>\n </template>\n </div>\n </template>\n <div class="vs-pad-bottom flex-shrink-0" style="height:0px;"></div>\n</div>\n')),globalThis.Component.register("Nav",t=>{t.vertical=t.hasAttribute("vertical"),t.state.openName=t.state.openName||null,t.click=(e,i)=>{e.noselect||i||(globalThis.Hash.nav=e.name),t.dispatchEvent(new CustomEvent("nav",{detail:{item:e},bubbles:!1}))},t.clickSubitem=e=>{t.dispatchEvent(new CustomEvent("nav",{detail:{item:e},bubbles:!1}))},t.toggleGroup=e=>{t.state.openName=t.state.openName===e.name?null:e.name,t.dispatchEvent(new CustomEvent("nav",{detail:{item:e,open:t.state.openName===e.name},bubbles:!1}))}},globalThis.Util.makeDom('\n<div $class="${this.vertical ? \'d-flex flex-column border-end h-100 align-self-stretch overflow-visible\' : \'navbar navbar-expand border-bottom\'} bg-body-secondary px-2 ${this.vertical ? \'py-3\' : \'py-0\'} align-items-center ${this.vertical ? \'align-items-start\' : \'\'}" $style="this.vertical ? \'min-height:0;\' : \'\'">\n\t<div class="d-flex align-items-center gap-2">\n <template $if="this.state?.brand?.image">\n <img $src="this.state.brand.image" $class="${this.vertical ? \'mb-2\' : \'mx-1\'}" style="height:30px;width:auto;max-width:300px">\n </template>\n <template $if="this.state?.brand?.icon">\n <i $class="bi bi-${this.state.brand.icon} ${this.vertical ? \'mb-2\' : \'mx-1\'}"></i>\n </template>\n <template $if="this.state?.brand?.label">\n <span $class="${this.vertical ? \'mb-2 fw-bold\' : \'mx-1\'}" style="transform: translateY(3px);" $text="this.state.brand.label"></span>\n </template>\n\t</div>\n\t<div $class="d-flex ${this.vertical ? \'w-100 flex-fill mt-2 flex-column\' : \'ms-2 align-items-center flex-fill\'}" $style="this.vertical ? \'min-height:0; overflow-y:auto; overflow-x:visible;\' : \'\'">\n\t\t<template $each="this.state?.list || []">\n\t\t\t<div $class="${this.vertical ? \'nav nav-pills flex-column w-100 position-relative\' : \'navbar-nav flex-row align-items-center\'} ${!this.vertical && item.type===\'fill\' ? \'flex-fill\' : \'\'}" style="transform: translateY(3px);">\n\t\t\t<template $if="item.type===\'label\'">\n\t\t\t\t<div $class="${this.vertical ? \'small text-uppercase text-body-secondary fw-semibold px-2 py-1 mt-2\' : \'navbar-text small text-uppercase text-body-secondary fw-semibold px-2\'} ${item.class || \'\'}" $text="item.label"></div>\n\t\t\t</template>\n\t\t\t<template $if="item.type===\'button\'">\n\t\t\t\t<button $class="nav-link ${Hash.nav===item.name?\'active\':\'\'} ${this.vertical ? \'w-100 text-start py-1 px-2\' : \'\'} ${item.class || \'\'}" $onclick="this.click(item)">\n\t\t\t\t\t\t<i $class="bi bi-${item.icon} me-2"></i><span $class="${this.vertical ? \'text-truncate\' : \'d-none d-\' + (this.state?.list?.length>5?\'lg\':\'md\') + \'-inline\'}" $text="item.label"></span>\n\t\t\t\t</button>\n\t\t\t\t</template>\n\t\t\t\t<template $if="item.type===\'dropdown\'">\n\t\t\t\t\t<template $if="this.vertical">\n\t\t\t\t\t\t<div class="w-100">\n\t\t\t\t\t\t\t<button type="button" $class="nav-link w-100 text-start py-1 px-2 d-flex align-items-center justify-content-between ${item.class || \'\'}" $onclick="this.toggleGroup(item)">\n\t\t\t\t\t\t\t\t<span class="d-inline-flex align-items-center">\n\t\t\t\t\t\t\t\t\t<i $class="bi bi-${item.icon} me-2"></i><span class="text-truncate" $text="item.label"></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<i $class="bi ${this.state.openName===item.name?\'bi-chevron-down\':\'bi-chevron-right\'} small ms-2"></i>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<template $if="this.state.openName===item.name">\n\t\t\t\t\t\t\t\t<div class="d-flex flex-column w-100 ps-2 mt-1">\n\t\t\t\t\t\t\t\t\t<template $each="item.list" as="subitem">\n\t\t\t\t\t\t\t\t\t\t<template $if="subitem.type===\'label\'">\n\t\t\t\t\t\t\t\t\t\t\t<div $class="small text-uppercase text-body-secondary fw-semibold px-2 py-1 ${subitem.class || \'\'}" $text="subitem.label"></div>\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t<template $if="subitem.type===\'button\'">\n\t\t\t\t\t\t\t\t\t\t\t<button $class="nav-link w-100 text-start py-1 px-2 ${subitem.class || \'\'}" $onclick="this.clickSubitem(subitem)">\n\t\t\t\t\t\t\t\t\t\t\t\t<i $class="bi bi-${subitem.icon} me-2 d-inline-block" style="width: 16px;"></i><span $text="subitem.label"></span>\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t\t<template $if="subitem.type===\'switch\'">\n\t\t\t\t\t\t\t\t\t\t\t<div $class="d-flex align-items-center px-2 py-2 ${subitem.class || \'\'}">\n\t\t\t\t\t\t\t\t\t\t\t\t<i $class="bi bi-${subitem.icon} me-2 d-inline-block" style="width: 16px;"></i><span $text="subitem.label"></span><div class="flex-fill"></div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class="form-switch ms-2"><input class="form-check-input" type="checkbox" $bind="subitem.bind[subitem.name]"></div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t\t<template $if="!this.vertical">\n\t\t\t\t\t\t<div class="dropdown">\n\t\t\t\t\t\t\t<button type="button" $class="nav-link dropdown-toggle ${item.class || \'\'}" data-bs-toggle="dropdown">\n\t\t\t\t\t\t\t\t<i $class="bi bi-${item.icon} me-2"></i><span $class="\'d-none d-\' + (this.state?.list?.length>5?\'lg\':\'md\') + \'-inline\'" $text="item.label"></span>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div class="dropdown-menu dropdown-menu-end p-2 bg-body-secondary shadow" $style="\'width: \' + (item.width || 250) + \'px;\'">\n\t\t\t\t\t\t\t\t<template $each="item.list" as="subitem">\n\t\t\t\t\t\t\t\t\t<template $if="subitem.type===\'label\'">\n\t\t\t\t\t\t\t\t\t\t<div $class="dropdown-header ${subitem.class || \'\'}" $text="subitem.label"></div>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t<template $if="subitem.type===\'button\'">\n\t\t\t\t\t\t\t\t\t\t<button $class="dropdown-item ${subitem.class || \'\'}" $onclick="this.clickSubitem(subitem)">\n\t\t\t\t\t\t\t\t\t\t\t<i $class="bi bi-${subitem.icon} me-2 d-inline-block" style="width: 16px;"></i><span $text="subitem.label"></span>\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t\t<template $if="subitem.type===\'switch\'">\n\t\t\t\t\t\t\t\t\t\t<div $class="d-flex align-items-center px-3 py-2 ${subitem.class || \'\'}">\n\t\t\t\t\t\t\t\t\t\t\t<i $class="bi bi-${subitem.icon} me-2 d-inline-block" style="width: 16px;"></i><span $text="subitem.label"></span><div class="flex-fill"></div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class="form-switch ms-2"><input class="form-check-input" type="checkbox" $bind="subitem.bind[subitem.name]"></div>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</template>\n\t\t\t\t</template>\n\t\t\t</div>\n\t\t</template>\n\t</div>\n</div>\n')),globalThis.Component.register("Resizer",t=>{t.isVertical=t.hasAttribute("vertical");const e=parseInt(t.getAttribute("min"))||10,i=parseInt(t.getAttribute("max"))||1e3,s=t.target||t.previousElementSibling;t.addEventListener("bind",e=>{void 0!==e.detail&&null!==e.detail&&(s.style[t.isVertical?"height":"width"]=e.detail+"px")});const a=(s,a,l)=>{const n=s+(t.isVertical?l:a);return n<e?e:n>i?i:n};t.addEventListener("mousedown",e=>{const i=t.isVertical?s.offsetHeight:s.offsetWidth;globalThis.MouseMover.start(e,{onmousemove:({w:e,h:l})=>{const n=a(i,e,l);s.style[t.isVertical?"height":"width"]=n+"px",t.dispatchEvent(new CustomEvent("resizing",{detail:{oldSize:i,newSize:n},bubbles:!1}))},onmouseup:({w:e,h:s})=>{const l=a(i,e,s);t.dispatchEvent(new CustomEvent("resize",{detail:{oldSize:i,newSize:l},bubbles:!1})),t.dispatchEvent(new CustomEvent("change",{detail:l,bubbles:!1}))}})})},globalThis.Util.makeDom("\n<div $class=\"border-${this.isVertical?'top':'start'} flex-shrink-0\" $style=\"${this.isVertical?'height':'width'}:3px;${!this.isVertical?'height':'width'}:100%;cursor:${this.isVertical?'row-resize':'col-resize'}\"></div>\n")),Object.defineProperty(t,"State",{enumerable:!0,get:()=>e.State}),t.APIComponent=u,t.AutoForm=o,t.HTTP=i,t.MouseMover=p,t.UI=s,t.VirtualScroll=r,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
|